我想用直方图确定我的图像的平均块。假设我的图像有64乘64维,我需要将其分成4乘4块,然后确定每个块的平均值(换句话说,现在我将有4个块)。
使用opencv,我如何利用我的IplImage来确定使用直方图箱的块平均值?
下面的代码是opencv histogram,以确定整个图像的意思:
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");
提前非常感谢。
答案 0 :(得分:0)
你可以通过直方图来做到这一点,但更有效的方法是做一个完整的图像,几乎可以做你想要的。
在此处阅读http://en.wikipedia.org/wiki/Summed_area_table,然后使用它来计算每个块中所有像素的总和。然后除以每个块中的像素数(4x4 = 16)。不是很好吗?
OpenCV具有计算积分图像的功能,其难度为cv :: integral()
更简单的方法就是简单的调整大小()。
调用调整大小(image64_64,image_16_16,大小(16,16),INTER_AREA),结果将是一个较小的图像,其像素值具有您正在寻找的值。不是很棒吗?
请不要忘记INTER_AREA标志。它确定了要使用的正确算法。