2009年1月14日 星期三

She's like the Swallow - Williams College Elizabethans



以前在合唱團有唱過這首,同樣是STAB混聲四部,

好懷念,希望可以復團,好想唱歌。

2009年1月11日 星期日

Yesterday Once More - 木匠兄妹



When I was young I'd listen to the radio.當我還是小女還時,我常聽收音機。
Waiting for my favorite songs.等待著我心愛的歌。
When they played I'd sing along.當它們播放出來的時候,我會跟著唱。
It make me smile.這令我笑容滿面。

Those were such happy times and not so long ago.不久前的回憶那真是段美好的時光。
How I wondered where they'd gone.我不知道那段美好時光怎麼消失了。
But they're back again just like a long lost friend.現在它們就像久無音信的老朋友又回來了。
All the songs I love so well.所有的歌都是我所喜歡的。
Every shalala every wo'wo still shines ! 每一個紗啦啦,每一個哦哦依舊閃耀!

Every shing-a-ling-a-ling that they're starting to sing.他們開始唱的每一個昕鈴鈴-
So fine ! 都如此美妙!

When they get to the part.當他們唱到那段-
Where he's breaking her heart.男孩使女孩傷心的部分時。
It can really make me cry.也讓我流下了眼淚。
Just like before.就像昔日一樣。
It's yesterday once more ! 仿佛昨日重現!
(Shoobie do lang lang)
(Shoobie do lang lang)
Looking back on how it was in years gone by. 回首過去的幾年。
And the good times that had.以及我曾擁有的好時光。
Makes today seem rather sad.使今日更加傷感。
So much has changed ! 太多的轉變!

It was songs of love that I would sing to them.那些舊日跟唱過的舊情歌。
And I'd memorise each word.我仍然記得沒一句歌詞。
Those old melodies still sound so good to me.那些舊旋律聽起來仍然那麼悅耳。
As they melt the years away.它們使歲月消融!
Every shalala every wo'wo still shines ! 每一個紗啦啦,每一個哦哦依舊閃耀!

Every shing-a-ling-a-ling that they're starting to sing.他們開始唱的每一個昕鈴鈴-
So fine ! 都如此美妙!
All my best memorise come back clearly to me.所有美好的回憶都在我腦海裡清晰的浮現!
Some can even make me cry.有些甚至令我淚流滿脈面。

Just like before.就象昔日一樣。
It's yesterday once more ! 仿佛昨日重現!
(Shoobie do lang lang)
Every shalala every wo'wo still shines ! 每一個紗啦啦,每一個哦哦依舊閃耀!
Every shing-a-ling-a-ling that they're starting to sing.他們開始唱的每一個昕鈴鈴-
So fine ! 都如此美妙!
Every shalala every wo'wo still shines ! 每一個紗啦啦,每一個哦哦依舊閃耀!
Every shing-a-ling-a-ling that they're starting to sing.他們開始唱的每一個昕鈴鈴-
So fine ! 都如此美妙!

Love Is All Around - Wet Wet Wet



Love Is All Around

I feel it in my fingers, I feel it in my toes
Love is all around me and so the feeling grows
It's written on the wind, it's everywhere I go
So if you really love me, come on and let it show
You know I love you I always will
My mind's made up by the way that I feel
There's no beginning, there'll be no end
'Cause on my love you can depend
I see your face before me, as I lay on my bed
I kinda get to thinking of all the things we said
You gave a promise to me, and I gave mine to you
I need someone beside me in everything I do
You know I love you I always will
My mind's made up by the way that I feel
There's no beginning, there'll be no end
'Cause on my love you can depend
It's written on the wind, it's everywhere I go
So if you really love me, come on and let it show
Come on and let it show

2009年1月6日 星期二

Matrix

CvArr → CvMat → IplImage ( 繼承關係 )
Even though OpenCV is implemented in C, the structures used in OpenCV have an object-oriented design; in effect, IplImage is derived from CvMat, which is derived from CvArr

1.
When CvArr* appears, it is acceptable to pass CvMat* or IplImage* to the routine.

可以用 CvArr * 去接 CvMat 或是 IplImage

上層往下指,上層的每一個成員下層也一定都有,所以一定都會對滿

反之,下層有的上層不見得有,所以下層的指標有些會接不到東西,就錯誤

故可以用上層的指標去接下層的成員函式。

2.
CvArr, can be thought of as an abstract base class from which CvMat is itself derived.

抽象基礎類別

是把最底層的class成員函數都宣告成virtual,本身的class沒辦法實體化

只提供該有哪些function的功能

實體的使用內容卻是由衍生出來的class去各自設計

也就是提供類似模組或樣版

第二點的參考資料來源:奇摩知識+

萍聚

選擇 - 林子祥 葉蒨文

是否 - 葉蒨文



當初我的合唱團老師也有唱過此首的男聲獨唱版

可惜沒找到來源,也很好聽!!

2009年1月5日 星期一

重病

經過了一個周末的煎熬

加上昨晚全身發冷似乎還發燒了 Orz

今天終於去看了校醫

症狀:喉嚨吞嚥會痛、脖子很緊、全身無力、身體發冷

沒想到竟然是扁桃腺發炎加上喉嚨有痰,哭哭

好像好久沒有生這麼重的病了吧

記得高中以來也沒有這樣過

偏偏又發生在期末考前,考試掰掰 = =... 睡覺重要 XD?

校醫還說要開抗生素給我吃= = 偏偏學校的抗生素又只有一種

如果吃了兩天還是有發燒到39度以上或是吞嚥會痛,

就要住院 = =~~~ 很無奈,學校都提供免費的校醫了

醫療資源也不順便升級一些,嘖嘖~~ 有貪污吧 =口=+

A Not-So-Simple Transformation











左為cvPyrDown()兩次的結果,
  右為cvCanny()一次的結果。

// Example 2-5. Using cvPyrDown() to create a new image that is half the width and height of the input image

// Example 2-6. The Canny edge detector writes its output to a single channel (grayscale) image
// Example 2-7. Combining the pyramid down operator (twice) and the Canny subroutine in a simple image pipeline
// Example 2-8. Simplifying the image pipeline of Example 2-7 by making the individual stages release their intermediate memory allocations

#include "highgui.h"
#include "cv.h"

IplImage *doPyrDown( IplImage * , int );
IplImage *doCanny( IplImage * , double , double , double );

int main( int argc , char **argv )
{
 cvNamedWindow( "Input" , CV_WINDOW_AUTOSIZE );
 cvNamedWindow( "Output1" , CV_WINDOW_AUTOSIZE );
 //cvNamedWindow( "Output2" , CV_WINDOW_AUTOSIZE );
 //cvNamedWindow( "Output3" , CV_WINDOW_AUTOSIZE );

 IplImage *image = cvLoadImage( argv[1] , 0);
 IplImage *out1 = doPyrDown( image , IPL_GAUSSIAN_5x5 );
 //IplImage *out2 = doPyrDown( out1 , IPL_GAUSSIAN_5x5 );
 //IplImage *out3 = doCanny( out2 , 10 , 100 , 3 );
 out1 = doPyrDown( out1 , IPL_GAUSSIAN_5x5 );
 cvShowImage( "Input" , out1 );
 out1 = doCanny( out1 , 10 , 100 , 3 );

 //cvShowImage( "Input" , image );
 cvShowImage( "Output1" , out1 );
 //cvShowImage( "Output2" , out2 );
 //cvShowImage( "Output3" , out3 );

 cvWaitKey( 0 );

 cvReleaseImage( &image );
 cvReleaseImage( &out1 );
 //cvReleaseImage( &out2 );
 //cvReleaseImage( &out3 );

 cvDestroyWindow( "Input" );
 cvDestroyWindow( "Output1" );
 //cvDestroyWindow( "Output2" );
 //cvDestroyWindow( "Output3" );
 return 0;
}

// Example 2-5.
IplImage *doPyrDown( IplImage *in , int filter )
{
 // Best to make sure input image is divisible by two.
 //
 assert( in->width%2 == 0 && in->height%2 == 0 );

 IplImage *out = cvCreateImage( cvSize( in->width/2 , in->height/2 ) , in->depth , in->nChannels );
 cvPyrDown( in , out , filter );
 return out;
}

// Example 2-6.
IplImage *doCanny( IplImage *in , double lowThresh , double highThresh , double aperture )
{
 if( in->nChannels != 1 )
  return 0; // Canny only handles gray scale iamges

 IplImage *out = cvCreateImage( cvGetSize( in ) , IPL_DEPTH_8U , 1 );
 cvCanny( in , out , lowThresh , highThresh , aperture );
 return out;
}

2009年1月4日 星期日

Equalization using VB













←開檔













←依序為原圖、灰階、灰階均化、轉回彩色















←存檔


' 背景需要先拉入OpenFileDialog與SaveFileDialog物件

' RGB 轉成 YIQ 並且顯示灰階
  Dim i, j, r, g, b, Y, imgW, imgH As Integer
  Dim bmp As New Bitmap(PictureBox1.Image)
  imgW = bmp.Width
  imgH = bmp.Height
  Dim bmp1 As New Bitmap(imgW, imgH)

  For i = 0 To imgW - 1
   For j = 0 To imgH - 1
    r = bmp.GetPixel(i, j).R
    g = bmp.GetPixel(i, j).G
    b = bmp.GetPixel(i, j).B
    Y = (0.299 * r + 0.587 * g + 0.114 * b)
    If Y < 0 Then
     Y = 0
    ElseIf Y > 255 Then
     Y = 255
    End If
    bmp1.SetPixel(i, j, Color.FromArgb(Y, Y, Y))
   Next
  Next

  PictureBox2.SizeMode = PictureBox1.SizeMode
  PictureBox2.Image = bmp1

' 對灰階影像做亮度均化
  Dim imgW, imgH, i, j, Y As Integer
  Dim bmp As New Bitmap(PictureBox2.Image)

  imgW = bmp.Width
  imgH = bmp.Height
  Dim bmp1 As New Bitmap(imgW, imgH)
  Dim N(255) As Integer

  For i = 0 To imgW - 1
   For j = 0 To imgH - 1
    Y = bmp.GetPixel(i, j).R
    N(Y) = N(Y) + 1
   Next
  Next

  For i = 1 To 255
   N(i) = N(i - 1) + N(i)
  Next

  j = imgW * imgH

  For i = 0 To 255
   ' 四捨五入
   If (N(i) * 255 / j * 10) Mod 10 < 5 Then
    N(i) = N(i) * 255 / j
   Else
    N(i) = N(i) * 255 / j + 1
   End If
   If N(i) > 255 Then
    N(i) = 255
   ElseIf N(i) < 0 Then
   N(i) = 0
   End If
  Next

  For i = 0 To imgW - 1
   For j = 0 To imgH - 1
    Y = N(bmp.GetPixel(i, j).R)
    bmp1.SetPixel(i, j, Color.FromArgb(Y, Y, Y))
   Next
  Next

  PictureBox3.SizeMode = PictureBox2.SizeMode
  PictureBox3.Image = bmp1

' 將均化過的Y與沒變的IQ轉回RGB
  Dim i, j, r, g, b, Y, AI, Q, imgW, imgH As Integer
  Dim bmp As New Bitmap(PictureBox1.Image)
  Dim bmp1 As New Bitmap(PictureBox3.Image)
  imgW = bmp.Width
  imgH = bmp.Height
  Dim bmp2 As New Bitmap(imgW, imgH)

  For i = 0 To imgW - 1
   For j = 0 To imgH - 1
    r = bmp.GetPixel(i, j).R
    g = bmp.GetPixel(i, j).G
    b = bmp.GetPixel(i, j).B
    Y = bmp1.GetPixel(i, j).R
    AI = (0.596 * r - 0.274 * g - 0.322 * b)
    Q = (0.211 * r - 0.522 * g + 0.311 * b)

    r = (1 * Y + 0.956 * AI + 0.632 * Q)
    If r < 0 Then
     r = 0
    ElseIf r > 255 Then
     r = 255
    End If
    g = (1 * Y - 0.272 * AI - 0.648 * Q)
    If g < 0 Then
     g = 0
    ElseIf g > 255 Then
     g = 255
    End If
    b = (1 * Y - 1.105 * AI + 0.705 * Q)
    If b < 0 Then
     b = 0
    ElseIf b > 255 Then
     b = 255
    End If
    bmp2.SetPixel(i, j, Color.FromArgb(r, g, b))
   Next
  Next

  PictureBox4.SizeMode = PictureBox3.SizeMode
  PictureBox4.Image = bmp2

' 讀檔
  Dim openFileDialog1 As New OpenFileDialog()
  openFileDialog1.Filter = "Bmp Files|*.bmp"
  openFileDialog1.Title = "Select a Bitmap File"

  If openFileDialog1.ShowDialog() = DialogResult.OK Then
   PictureBox1.Image = Image.FromFile(openFileDialog1.FileName)
   Button1.Enabled = True
   Label1.Visible = True
  End If

' 存檔
  Dim saveFileDialog1 As New SaveFileDialog()
  saveFileDialog1.Filter = "Bitmap Image|*.bmp"
  saveFileDialog1.Title = "Save an Bitmap File"
  saveFileDialog1.ShowDialog()

  ' If the file name is not an empty string open it for saving.
  If saveFileDialog1.FileName <> "" Then
   ' Saves the Image via a FileStream created by the OpenFile method.
   Dim fs As System.IO.FileStream = CType _ (saveFileDialog1.OpenFile(), System.IO.FileStream)
   ' Saves the Image in the appropriate ImageFormat based upon the
   ' file type selected in the dialog box.
   ' NOTE that the FilterIndex property is one-based.
   Me.PictureBox2.Image.Save(fs, _ System.Drawing.Imaging.ImageFormat.Bmp)

   fs.Close()
  End If

A Simple Transformation

// If the resource is not from bitmap file but from avi file, then each frame of the output
// will up-side down, I still not find out what reason.

// Example 2-4. Loading and then smoothing an image before it is displayed on the screen


#include "cv.h"
#include "highgui.h"

void example2_4( IplImage *);

int main(int argc,char **argv)
{
 IplImage *image = cvLoadImage( argv[1] );
 example2_4( image );
 cvReleaseImage( &image );
 return 0;
}

void example2_4( IplImage *image )
{
 // Create some windows to show the input
 // and output image in.
 //
 cvNamedWindow( "Example4-in" );
 cvNamedWindow( "Example4-out" );

 // Create a window to show our input image
 //
 cvShowImage( "Example4-in" , image );

 // Create an image to hold the smoothed output
 //
 IplImage *out = cvCreateImage( cvGetSize(image) , IPL_DEPTH_8U , 3 );

 // Do the smoothing
 //
 cvSmooth( image , out , CV_GAUSSIAN , 31 , 31);

 // Show the smoothed image in the output window
 //
 cvShowImage( "Example4-out" , out );

 //Be tidy
 //
 cvReleaseImage( &out );

 // Wait for the user to hit a key, then clean up the windows
 //
 cvWaitKey( 0 );
 cvDestroyWindow( "Example4-in" );
 cvDestroyWindow( "Example4-out" );
}

Trackbar Slider

// Example 2-3. Program to add a trackbar slider to the basic viewr window: when the slider is
// moved, the function onTrackbarSlide() is called and then passed to the slider's new value

#include "cv.h"
#include "highgui.h"

void onTrackbarSlide(int);

int g_slider_position = 0;
CvCapture *g_capture = NULL;

int main(int argc, char **argv)
{
 cvNamedWindow("Example3",CV_WINDOW_AUTOSIZE);
 g_capture = cvCreateFileCapture(argv[1]);

 // we use it when we want to query some data from the CvCapture structure
 // it will return how many frames are in the video
 int frames = (int)cvGetCaptureProperty(g_capture,CV_CAP_PROP_FRAME_COUNT);
 IplImage *frame;
 if(frames!=0)
  for(;;g_slider_position++)
  {
   // the last parameter is a callback function that reset the position of trackbar slider
   cvCreateTrackbar("Position","Example3",&g_slider_position,frames,onTrackbarSlide);
   frame = cvQueryFrame( g_capture );
   if( !frame )
    break;
   cvShowImage("Example3",frame);
   char c = cvWaitKey(33);
   if( c==27 )
    break;
   while((c=='p')||(c=='P'))
   {
    c = cvWaitKey(0);
    if( c==27 )
    {
     cvReleaseCapture( &g_capture );
     cvDestroyWindow("Example3");
     return 0;
    }
    if( (c=='c')||(c=='C')||(c==13) )
     break;
    else
     c='p';
   }
  }
 cvReleaseCapture( &g_capture );
 cvDestroyWindow("Example3");
 return 0;
}

void onTrackbarSlide(int pos)
{
 cvSetCaptureProperty(g_capture,CV_CAP_PROP_POS_FRAMES,pos);
}

AVI Video

// Example 2-2. A simple OpenCV program for playing a video file from disk

#include "highgui.h"

int main(int argc, char **argv)
{
 cvNamedWindow("Example2",CV_WINDOW_AUTOSIZE);
 // it will also allocate a memory for the image
 CvCapture *capture = cvCreateFileCapture(argv[1]);
 IplImage *frame;
 while(1)
 {
  frame = cvQueryFrame( capture );
  if( !frame )
   break;
  cvShowImage( "Example2", frame );
  // 30 frames per second = 30 frames / 1000 ms = 1 frame / 33 ms
  // if no stdin then it will return -1

  char c = cvWaitKey(33);
  if(c==27)
   break;
  // pause while pressing p or P
  while((c=='p')||(c=='P'))
  {
   c = cvWaitKey(0);
   if(c==27)
   {
    cvReleaseCapture( &capture );
    cvDestroyWindow( "Example" );
    return 0;
   }
   // continue the video while pressing c, C or enter
   if((c=='c')||(c=='C')||(c==13))
    break;
   else
    c='p';
  }
 }
 // it will also called "cvReleaseImage()" for the "frame" pointer
 cvReleaseCapture( &capture );
 cvDestroyWindow( "Example2" );
 return 0;
}

Babylon - Gregorian Chants

2009年1月2日 星期五

二零零八跨年

今年依舊是在詠寧家跨年

成員:我、Angie、丁丁、左左、殺手、詠寧、啾啾

好不容易熬玩歷史課回家匆匆洗了個澡便趕往中壢

抵達目的地後不久沒想到意外的來了神秘嘉賓:聰明人跟宅豪











←右手邊的看起來不只宅,還呆呆的 XD"


好不容易大家都到齊了,舟車勞苦之後都飢腸轆轆,

便東西先放在一旁沒整頓就整群先去中原夜市覓食了,

找來找去都沒找到詠寧哥哥說的"傻蛋的窩",只好作罷,

走著走著倒是意外的發現了一家"塞納河"的義大利麵店,

感覺裝潢得很溫馨,裡面的服務生也很親切,給人感覺很舒服,

出餐雖然頗久 ( XD" 吃了快兩個小時吧 ) 但是卻是平常所感受不到的悠哉,

跟米卡果然不能比 = =+ 應該說米卡真的是太不好吃了,

大推這家店的手工蛋糕,在中原夜市的三井電腦斜對面巷子進去,











←巧克力部分超美味,吃起來很綿密不會膩


有機會可以再去吃吃看,為了美食到處奔波阿 XDDDD

回去的途中還順手夾了一個長頸鹿充氣娃娃,不過卻花了五十元,

感覺是被騙錢了 =口=... 不過大家卻玩得莫名很high...XD?












←啾啾的牙突











←被小惡魔硬是戴上去的丁丁,可憐的應該是長頸鹿...

中間就是倒數跨年啦,其間還打了蠻久的桌球 XD"

沒辦法,誰叫有一半都是系桌的,哈哈哈

大家都老了 =.=.... 沒辦法通霄到天亮,

不過也可能是因為宵夜吃鐵板燒加上冰火的關係吧,天氣太冷,

/* 家樂福買的澳洲培根肉串,結果是羊肉 = = 黑店 大家以後不要去阿...不爽 */

酒足飯飽之後喝完酒暖暖地好舒服超想睡 XD

隔天中午吃了到中壢一定要吃的牛肉麵!

之前吃過了永川、老師傅牛肉麵之後,這次主打:老三牛肉麵

坦白說,我覺得比老師傅差,且又忘記弄我們點的東西,

讓我們等超久 = =... 不開心~~~~~ 不推! 還是老師傅好吃!

計畫中的重頭戲就是巧克力火鍋啦! 今年突發奇想,繼去年豆漿火鍋之後,

今年特別一點,不過因為有一半的人有事先走,QQ

所以剩下一半的人吃了幾乎全部的東西,吃的超飽,可能一段時間不會吃甜食了吧我猜~










←啾啾(左)跟我(右)的傑作,啾咪跟囧 XDDD 超可愛的啦,棉花糖+巧克力醬愛不釋手












←蘋果麵包做地,也很好吃 >///<














←離開前的KUSO~ 倒掛金鉤 XD" 感覺很蠢 哈哈哈


Ps. 番外篇 ~ 到三峽吃完晚餐之後騎車回宿舍,沒想到紅燈左轉被抓到了 XD
      哭哭,騎車以來第一張紅單,沒想到在元旦來臨了
      XD 噴1,800...唉 Orz 以後的日子怎麼過阿 QQ

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;
 }
}
===========================================================