2009年1月1日 星期四

Equalization using VC

專案屬性組態屬性連結器輸入其他相依性 加入 gdiplus.dll

按 Enter 會依序出現












← 一開始顯示測試原圖













← 顯示原圖的灰階影像













← 經過亮度均化後的灰階影像













← 將修改過後的YIQ轉回RGB













← 直接對RGB做亮度均化,出現色偏


===========================================================
Header File

#include <windows.h>
#include <gdiplus.h>

using namespace Gdiplus;

#ifndef _CVE_H_
#define _CVE_H_

Graphics* graphics;
Image* image;
Pen* pen;

/* RGB layers of the image */
int** i_R;
int** i_G;
int** i_B;
/* RGB layers of the image */
int** i_Red;
int** i_Green;
int** i_Blue;
/* YIQ layers of the image */
int** iY_Gray;
int** iI_Gray;
int** iQ_Gray;
/* calculation of RGB layers */
int* num_R;
int* num_G;
int* num_B;
/* probability of RGB layers */
double* pro_R;
double* pro_G;
double* pro_B;
/* probability of gray level */
double* pro_Gray;
/* calculation of gray level */
int* num_Gray;

/* decide to take which processing action */
int flag;
/* image height and width */
int i_Height, i_Width;
/* total pixels */
double i_Pixels;

#endif
===========================================================
CPP FILE

#include "CVE.h"

using namespace Gdiplus;

/* function prototype */
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void Clear();
void myKeys(HWND);
void OnPaint(HDC);
void Setup1();
void Setup2(HDC);

/* WinMain , the program entry point */
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, int iCmdShow)
{
 HWND hWnd;
 MSG msg;
 WNDCLASS wndClass;
 GdiplusStartupInput gdiplusStartupInput;
 ULONG_PTR gdiplusToken;

 /* initilize the flag to show the original image at first */
 flag = 1;

 /* Initialize GDI+. */
 GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

 wndClass.style = CS_HREDRAW | CS_VREDRAW;
 wndClass.lpfnWndProc = WndProc;
 wndClass.cbClsExtra = 0;
 wndClass.cbWndExtra = 0;
 wndClass.hInstance = hInstance;
 wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
 wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
 wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
 wndClass.lpszMenuName = NULL;
 wndClass.lpszClassName = TEXT("Equalization");

 RegisterClass(&wndClass);
 Setup1();

 hWnd = CreateWindow(
  TEXT("Equalization"),       // window class name
  TEXT("CVHW Equalization"),     // window caption
  WS_OVERLAPPEDWINDOW,   // window style
  CW_USEDEFAULT,       // initial x position
  CW_USEDEFAULT,         // initial y position
  i_Width * 2,               // initial x size
  i_Height * 2,               // initial y size
  NULL,              // parent window handle
  NULL,              // window menu handle
  hInstance,             // program instance handle
  NULL);              // creation parameters

 HDC hdc = GetDC(hWnd);
 Setup2(hdc);

 ShowWindow(hWnd, iCmdShow);
 UpdateWindow(hWnd);

 while(1)
 {
  if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  {
   if (msg.message == WM_QUIT)
    break;
   TranslateMessage(&msg);
   DispatchMessage(&msg);
  }
  else
   myKeys(hWnd);
 }

 GdiplusShutdown(gdiplusToken);
 Clear();
 return (int)msg.wParam;
}

/* WndProc */
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
 HDC hdc;
 PAINTSTRUCT ps;

 switch(message)
 {
  case WM_PAINT:
   hdc = BeginPaint(hWnd, &ps);
   OnPaint(hdc);
   EndPaint(hWnd, &ps);
   return 0;
  case WM_DESTROY:
   PostQuitMessage(0);
   return 0;
  default:
   return DefWindowProc(hWnd, message, wParam, lParam);
 }
}

/* free memory */
void Clear()
{
 delete i_Red;
 delete i_Green;
 delete i_Blue;
 delete i_R;
 delete i_G;
 delete i_B;
 delete iY_Gray;
 delete iI_Gray;
 delete iQ_Gray;

 delete [] num_Gray;
 delete [] pro_Gray;
 delete [] num_R;
 delete [] num_G;
 delete [] num_B;
 delete [] pro_R;
 delete [] pro_G;
 delete [] pro_B;
}

/* keyboard events */
void myKeys(HWND hwnd)
{
 static int count=2;

 /* press ESC to exit program */
 if(GetKeyState(27) & 0x80)
  exit(0);

 /* press enter to continue the next image */
 if(GetKeyState(13) & 0x80)
 {
  flag = (count%=7)++;
  InvalidateRect(hwnd, NULL, FALSE);
 }
}

/* initialize_1 */
void Setup1()
{
 image = new Image(L"test.jpg");
 if(image->GetHeight() == 0 && image->GetWidth() == 0)
  image = new Image(L"test.bmp");
 i_Height = image->GetHeight();
 i_Width = image->GetWidth();
}

/* initialize_2 */
void Setup2(HDC hdc)
{
 graphics = new Graphics(hdc);

 pen = new Pen(Color(0,0,255), 3);

 i_Pixels = (double)(i_Height * i_Width);

 num_Gray = new int[256];
 pro_Gray = new double[256];
 num_R = new int[256];
 num_G = new int[256];
 num_B = new int[256];
 pro_R = new double[256];
 pro_G = new double[256];
 pro_B = new double[256];

 for(int i = 0; i < 256; i++)
 {
  num_Gray[i] = 0;
  pro_Gray[i] = 0;
  num_R[i] = 0;
  num_G[i] = 0;
  num_B[i] = 0;
  pro_R[i] = 0;
  pro_G[i] = 0;
  pro_B[i] = 0;
 }

 i_Red = new int*[i_Height];
 i_Green = new int*[i_Height];
 i_Blue = new int*[i_Height];
 iY_Gray = new int*[i_Height];
 iI_Gray = new int*[i_Height];
 iQ_Gray = new int*[i_Height];
 i_R = new int*[i_Height];
 i_G = new int*[i_Height];
 i_B = new int*[i_Height];

 for(int i = 0; i < i_Height;i++)
 {
  i_Red[i] = new int[i_Width];
  i_Green[i] = new int[i_Width];
  i_Blue[i] = new int[i_Width];
  iY_Gray[i] = new int[i_Width];
  iI_Gray[i] = new int[i_Width];
  iQ_Gray[i] = new int[i_Width];
  i_R[i] = new int[i_Width];
  i_G[i] = new int[i_Width];
  i_B[i] = new int[i_Width];
 }
}

/* image processing */
void OnPaint(HDC hdc)
{
 COLORREF color;
 switch(flag)
 {
  /* show the original image */
  case 1:
   graphics->DrawImage(image, 0, 0, i_Width, i_Height);
   break;
  /* show the gray level of the image */
  case 2:
   for(int i = 0; i < i_Height; i++)
    for(int j = 0; j < i_Width; j++)
    {
     color = GetPixel(hdc, j ,i);

     i_Red[i][j] = i_R[i][j] = GetRValue(color);
     i_Green[i][j] = i_G[i][j] = GetGValue(color);
     i_Blue[i][j] = i_B[i][j] = GetBValue(color);

     iY_Gray[i][j] = (int)(0.299 * i_Red[i][j] + 0.587 * i_Green[i][j] + 0.114 * i_Blue[i][j]);
     iI_Gray[i][j] = (int)(0.596 * i_Red[i][j] - 0.274 * i_Green[i][j] - 0.322 * i_Blue[i][j]);
     iQ_Gray[i][j] = (int)(0.211 * i_Red[i][j] - 0.522 * i_Green[i][j] + 0.311 * i_Blue[i][j]);

     num_Gray[iY_Gray[i][j]]++;
     num_R[i_R[i][j]]++;
     num_G[i_G[i][j]]++;
     num_B[i_B[i][j]]++;

     color = RGB(iY_Gray[i][j], iY_Gray[i][j], iY_Gray[i][j]);
     SetPixel(hdc, j + i_Width, i, color);
    }
   break;
  /* show the gray level of the image after equalizing */
  case 3:
   for(int i = 1; i < 256; i++)
   {
    num_Gray[i] += num_Gray[i-1];
    num_R[i]+=num_R[i-1];
    num_G[i]+=num_G[i-1];
    num_B[i]+=num_B[i-1];
   }

   for(int i = 0; i < 256; i++)
   {
    pro_Gray[i] = double(num_Gray[i]) / i_Pixels;
    pro_R[i] = double(num_R[i]) / i_Pixels;
    pro_G[i] = double(num_G[i]) / i_Pixels;
    pro_B[i] = double(num_B[i]) / i_Pixels;
   }

   for(int i = 0; i < i_Height; i++)
    for(int j = 0; j < i_Width; j++)
    {
     iY_Gray[i][j] = (int)(pro_Gray[iY_Gray[i][j]] * 255);
     i_R[i][j] = (int)(pro_R[i_R[i][j]] * 255);
     i_G[i][j] = (int)(pro_G[i_G[i][j]] * 255);
     i_B[i][j] = (int)(pro_B[i_B[i][j]] * 255);

     color = RGB(iY_Gray[i][j], iY_Gray[i][j], iY_Gray[i][j]);
     SetPixel(hdc, j, i + i_Height, color);
    }
   break;
  /* YIQ→RGB */
  case 4:
   for(int i = 0; i < i_Height; i++)
    for(int j = 0; j < i_Width; j++)
    {
     i_Red[i][j] = (int)(1 * iY_Gray[i][j] + 0.956 * iI_Gray[i][j] + 0.632 * iQ_Gray[i][j]);
     if(i_Red[i][j]>255)
      i_Red[i][j]=255;
     else if(i_Red[i][j]<0)
      i_Red[i][j]=0;

     i_Green[i][j]= (int)(1 * iY_Gray[i][j] - 0.272 * iI_Gray[i][j] - 0.648 * iQ_Gray[i][j]);
     if(i_Green[i][j]>255)
      i_Green[i][j]=255;
     else if(i_Green[i][j]<0)
      i_Green[i][j]=0;

     i_Blue[i][j]= (int)(1 * iY_Gray[i][j] - 1.105 * iI_Gray[i][j] + 0.705 * iQ_Gray[i][j]);
     if(i_Blue[i][j]>255)
      i_Blue[i][j]=255;
     else if(i_Blue[i][j]<0)
      i_Blue[i][j]=0;
     color = RGB(i_Red[i][j], i_Green[i][j], i_Blue[i][j]);
     SetPixel(hdc, j + i_Width, i + i_Height, color);
    }
   break;
  /* equalize directly to each R, G, B layer */
  case 5:
   for(int i = 0; i < i_Height; i++)
    for(int j = 0; j < i_Width; j++)
    {
     color = RGB(i_R[i][j], i_G[i][j], i_B[i][j]);
     SetPixel(hdc, j, i, color);
    }
   break;
  default:
   break;
 }
}
===========================================================

沒有留言: