首先说明一点,对于直方图的概念需要清除,要知道什么是bin 以及直方图反映的是什么信息。
1) 直方图反映的是统计的信息,它反映了图像中像素值在特定范围(ranges)内的像素个数(bin)。
来看一下 创建直方图的函数原型:
cvCreateHist( int dims, //直方图的维数
int* sizes, int type, // size 是直方图有多少块 , type 一般是默认的CV_HIST_ARRY
float** ranges CV_DEFAULT(NULL), //ranges 是直方图的范围
int uniform CV_DEFAULT(1));
2)直方图的用法
首先是获得要建立直方图的图像,然后设置直方图参数,计算直方图
3)代码演示实例:(对3通道的图像建立H-S 二维直方图)
/* 函数功能:返回一个直方图*/ CvHistogram *MakeUpHist(IplImage * src) { int h_bits = 8, s_bits = 9; //将h通道0-180的范围分成8个bin, 将s通道的0-255范围分成9个bin IplImage *srcHSV = cvCreateImage(cvGetSize(src),8,3);cvZero(srcHSV); IplImage *srcH = cvCreateImage(cvGetSize(src),8,1);cvZero(srcH); IplImage *srcS = cvCreateImage(cvGetSize(src),8,1);cvZero(srcS); IplImage *srcV = cvCreateImage(cvGetSize(src),8,1);cvZero(srcV); cvCvtColor(src,srcHSV,CV_BGR2HSV); cvSplit(srcHSV,srcH,srcS,srcV,0); IplImage *planes_src[] = {srcH,srcS}; //对H和S通道建立二维直方图 CvHistogram *hist; { int hist_size[] = {h_bits,s_bits}; float h_ranges[] = {0,180}; float s_ranges[] = {0,255}; float *ranges[] = {h_ranges,s_ranges}; hist = cvCreateHist(2 , hist_size , CV_HIST_ARRAY , ranges , 1); } cvCalcHist(planes_src,hist,0,0); // 计算直方图 return hist; //返回直方图 }
这样就获得了一个直方图的数据。当然也可以将这个直方图显示出来。/* 显示直方图的函数 IplImage * showHist(CvHistogram *hist) { float max_value; cvGetMinMaxHistValue( hist, 0, &max_value, 0, 0 ); int scale = 10; //创建直方图图像 int height = 240; int width = (h_bins*s_bins*3); IplImage* hist_img = cvCreateImage( cvSize(width,height), 8, 3 );cvZero( hist_img ); IplImage * hsv_color = cvCreateImage(cvSize(1,1),8,3); IplImage * rgb_color = cvCreateImage(cvSize(1,1),8,3); int bin_w = width / (h_bins * s_bins); for(int h = 0; h < h_bins; h++) { for(int s = 0; s < s_bins; s++) { int i = h*s_bins + s; // i=0 的时候为黑色,有的时候分析不需要 float bin_val = cvQueryHistValue_2D( hist, h, s ); int intensity = cvRound(bin_val*height/max_value); cvSet2D(hsv_color,0,0,cvScalar(h*180.f / h_bins,s*255.f/s_bins,250,0)); cvCvtColor(hsv_color,rgb_color,CV_HSV2BGR); CvScalar color = cvGet2D(rgb_color,0,0); cvRectangle( hist_img, cvPoint(i*bin_w,height), cvPoint((i+1)*bin_w,height - intensity), color, -1, 8, 0 ); } } cvReleaseImage(&hsv_color); cvReleaseImage(&rgb_color); return hist_img; }
去掉直方图中的黑色成分,然后将直方图归一化
float *ptr = cvGetHistValue_2D(hist, 0,0); *ptr = 0.f; // 对直方图中的 0,0 位置的bin 赋值为 0 cvNormalizeHist(hist,1.0); // 将去掉黑色的直方图归一化操作