2011-10-28 14 views
0

ヒストグラムを使用して画像の平均ブロックを決定したいと考えています。私のイメージが64×64次元であるとしましょう。私はそれを4×4ブロックに分割し、各ブロックの平均を決定する必要があります(言い換えれば、今は4ブロックになります)。opencvヒストグラムを使用してイメージブロックの平均を決める方法

opencvを使用して、IplImageを使用してヒストグラムビンを使用してブロック平均を決定する方法を教えてください。事前に

int i, hist_size = 256; 
float max_value,min_value; 
float min_idx,max_idx; 
float bin_w; 
float mean =0, low_mean =0, high_mean =0, variance =0; 

float range_0[]={0,256}; 
float *ranges[]={range_0}; 

IplImage* im = cvLoadImage("killerbee.jpg"); 
//Create a single planed image of the same size as the original 
IplImage* grayImage = cvCreateImage(cvSize(im->width,im->height),IPL_DEPTH_8U, 1); 
//convert the original image to gray 
cvCvtColor(im, grayImage, CV_BGR2GRAY); 

/* Remark this, since wanna evaluate whole area. 
    //create a rectangular area to evaluate 
    CvRect rect = cvRect(0, 0, 500, 600); 
    //apply the rectangle to the image and establish a region of interest 
    cvSetImageROI(grayImage, rect); 
End remark*/ 

//create an image to hold the histogram 
IplImage* histImage = cvCreateImage(cvSize(320,200), 8, 1); 
//create a histogram to store the information from the image 
CvHistogram* hist = cvCreateHist(1, &hist_size, CV_HIST_ARRAY, ranges, 1); 
//calculate the histogram and apply to hist 
cvCalcHist(&grayImage, hist, 0, NULL); 

//grab the min and max values and their indeces 
cvGetMinMaxHistValue(hist, &min_value, &max_value, 0, 0); 
//scale the bin values so that they will fit in the image representation 
cvScale(hist->bins, hist->bins, ((double)histImage->height)/max_value, 0); 

//set all histogram values to 255 
cvSet(histImage, cvScalarAll(255), 0); 
//create a factor for scaling along the width 
bin_w = cvRound((double)histImage->width/hist_size); 

for(i = 0; i < hist_size; i++) { 
    //draw the histogram data onto the histogram image 
    cvRectangle(histImage, cvPoint(i*bin_w, histImage->height),cvPoint((i+1)*bin_w,histImage->height - cvRound(cvGetReal1D(hist->bins,i))),cvScalarAll(0), -1, 8, 0); 
    //get the value at the current histogram bucket 
    float* bins = cvGetHistValue_1D(hist,i); 
    //increment the mean value 
    mean += bins[0]; 
} 
//finish mean calculation 
mean /= hist_size; 

//display mean value onto output window 
cout<<"MEAN VALUE of THIS IMAGE : "<<mean<<"\n"; 

//go back through now that mean has been calculated in order to calculate variance 
for(i = 0; i < hist_size; i++) { 
    float* bins = cvGetHistValue_1D(hist,i); 
    variance += pow((bins[0] - mean),2); 
} 
//finish variance calculation 
variance /= hist_size; 
cvNamedWindow("Original", 0); 
cvShowImage("Original", im); 

cvNamedWindow("Gray", 0); 
cvShowImage("Gray", grayImage); 

cvNamedWindow("Histogram", 0); 
cvShowImage("Histogram", histImage); 

//hold the images until a key is pressed 
cvWaitKey(0); 

//clean up images 
cvReleaseImage(&histImage); 
cvReleaseImage(&grayImage); 
cvReleaseImage(&im); 

//remove windows 
cvDestroyWindow("Original"); 
cvDestroyWindow("Gray"); 
cvDestroyWindow("Histogram"); 

本当に感謝:

以下のコードは、画像全体の平均値を決定するために、OpenCVのヒストグラムです。

答えて

0

これはヒストグラムで行うことができますが、これを行うにははるかに効果的な方法は、あなたが望むほぼ何もしない積分画像です。

ここをクリックしてhttp://en.wikipedia.org/wiki/Summed_area_tableを読み取り、それを使ってすべてのブロックのすべてのピクセルの合計を計算します。次に、各ブロックのピクセル数で除算します(4x4 = 16)。いいじゃない?

OpenCVの積分難しい名前のCV ::()

そして、それは謙虚リサイズで行うためのより簡単な方法で、積分画像を計算する機能を有しています()。

サイズ変更(image64_64、image_16_16、サイズ(16,16)、INTER_AREA)を呼び出すと、結果はピクセル値が探している値と正確に一致する小さな画像になります。それは素晴らしいことではありませんか?

INTER_AREAフラグを忘れないでください。それは、使用される正しいアルゴリズムを決定する。

+0

あなたの応答と洞察力のおかげで、私はヒストグラムをさらに目的に使う必要があるので、私はまだヒストグラムを使うことをお勧めします。ブロック平均を決定するためにヒストグラムを使用し続ける考えはありますか? –

関連する問題