OpenGL de プログラミング - ヒストグラムの均一化
現在地 >> メニュー >> サンプルコード::OpenCV >> ヒストグラムの均一化

問題


以下の画像をグレイスケールとして読み込んで、ヒストグラムを均一化せよ。

その他条件:
 わかりやすいように、
  もともとの「グレイスケール画像」と「ヒストグラム」、
  均一化した後の「グレイスケール画像」と「ヒストグラム」
 の4つを表示せよ。

画像

答え


#include <iostream>
#include <cstdio>

#include <cv.h>
#include <highgui.h>


IplImage *MAKE_HIST(IplImage *imgA);


using namespace std;


int main( int argc, char **argv)
{

IplImage *imgA = cvLoadImage( "test2.jpg", CV_LOAD_IMAGE_GRAYSCALE);
if(imgA ==NULL)
{
cout<<"Can't Load Image ." << endl;
exit(0);
}


/*もともとのヒストグラム*/
IplImage *Hist;
Hist = MAKE_HIST(imgA);

cvNamedWindow("ORIGINAL IMAGE",CV_WINDOW_AUTOSIZE);
cvShowImage("ORIGINAL IMAGE",imgA);

cvNamedWindow ("ORIGINAL", CV_WINDOW_AUTOSIZE);
cvShowImage ("ORIGINAL", Hist);




/*均一化*/
cvEqualizeHist (imgA, imgA);
Hist = MAKE_HIST(imgA);


cvNamedWindow("EQUALIZE IMAGE",CV_WINDOW_AUTOSIZE);
cvShowImage("EQUALIZE IMAGE",imgA);


cvNamedWindow ("EQUALIZE", CV_WINDOW_AUTOSIZE);
cvShowImage ("EQUALIZE", Hist);



cvWaitKey(0);


cvReleaseImage( &Hist );
cvReleaseImage( &imgA );

cvDestroyWindow("EQUALIZE");
cvDestroyWindow("ORIGINAL");

cvDestroyWindow("ORIGINAL IMAGE");
cvDestroyWindow("EQUALIZE IMAGE");

return 0;
}



IplImage *MAKE_HIST(IplImage *imgA)
{

int hist_size = 256;
float range_data[] = { 0, 256 };
float *range[] = { range_data };

/*ヒストグラム作成*/
CvHistogram *hist;
hist = cvCreateHist (1, &hist_size, CV_HIST_ARRAY, range, 1);


/*ヒストグラム出力用画像作成*/
int hist_width = 260;
IplImage *hist_img;
hist_img=cvCreateImage (cvSize (hist_width, 200), IPL_DEPTH_8U, 3);
cvSet (hist_img, cvScalarAll (255), 0);



/*計算して、描画用にスケール変換*/
float max_value = 0;
cvCalcHist (&imgA, hist, 0, NULL);
cvGetMinMaxHistValue (hist, 0, &max_value, 0, 0);
cvScale (hist->bins, hist->bins, ((double) hist_img->height) / max_value, 0);


/*棒グラフの横幅決定(今回は1)*/
int bin_width;
bin_width = cvRound ((double) hist_width / hist_size);



/*ヒストグラム描画*/
CvScalar color={0,100,100};
for (int j = 0; j < hist_size; j++)
{
cvRectangle(hist_img, cvPoint(j * bin_width , hist_img->height),
cvPoint ((j + 1) * bin_width ,
hist_img->height - cvRound (cvGetReal1D (hist->bins, j))),
color, CV_FILLED, 8, 0);
}

cvReleaseHist(&hist);

return (hist_img);

}

メモ


最初に用意した、「IplImage *imgA」と「IplImage *Hist」を上書きしている。