原文链接:http://blog.csdn.net/xiaowei_cqu/article/details/7600666
如有疑问或者版权问题,请移步原作者或者告知本人。
灰度直方图是数字图像中最简单且有用的工具,这一篇主要总结OpenCV中直方图CvHistogram的结构和应用。
typedef struct CvHistogram { int type; CvArr* bins; //存放每个灰度级数目的数组指针 float thresh[CV_MAX_DIM][2]; //均匀直方图 float** thresh2; //非均匀直方图 CvMatND mat; //直方图数组的内部数据结构 } CvHistogram;
CvHistogram* cvCreateHist( int dims, //直方图维数 int* sizes,//直翻图维数尺寸 int type, //直方图的表示格式 float** ranges=NULL, //图中方块范围的数组 int uniform=1 //归一化标识 );
void cvCalcHist( IplImage** image, //输入图像(也可用CvMat**) CvHistogram* hist, //直方图指针 int accumulate=0, //累计标识。如果设置,则直方图在开始时不被清零。 const CvArr* mask=NULL //操作 mask, 确定输入图像的哪个象素被计数 );
int main( ) { IplImage * src= cvLoadImage("baboon.jpg"); IplImage* gray_plane = cvCreateImage(cvGetSize(src),8,1); cvCvtColor(src,gray_plane,CV_BGR2GRAY); int hist_size = 256; //直方图尺寸 int hist_height = 256; float range[] = {0,255}; //灰度级的范围 float* ranges[]={range}; //创建一维直方图,统计图像在[0 255]像素的均匀分布 CvHistogram* gray_hist = cvCreateHist(1,&hist_size,CV_HIST_ARRAY,ranges,1); //计算灰度图像的一维直方图 cvCalcHist(&gray_plane,gray_hist,0,0); //归一化直方图 cvNormalizeHist(gray_hist,1.0); int scale = 2; //创建一张一维直方图的“图”,横坐标为灰度级,纵坐标为像素个数(*scale) IplImage* hist_image = cvCreateImage(cvSize(hist_size*scale,hist_height),8,3); cvZero(hist_image); //统计直方图中的最大直方块 float max_value = 0; cvGetMinMaxHistValue(gray_hist, 0,&max_value,0,0); //分别将每个直方块的值绘制到图中 for(int i=0;i<hist_size;i++) { float bin_val = cvQueryHistValue_1D(gray_hist,i); //像素i的概率 int intensity = cvRound(bin_val*hist_height/max_value); //要绘制的高度 cvRectangle(hist_image, cvPoint(i*scale,hist_height-1), cvPoint((i+1)*scale - 1, hist_height - intensity), CV_RGB(255,255,255)); } cvNamedWindow( "GraySource", 1 ); cvShowImage("GraySource",gray_plane); cvNamedWindow( "H-S Histogram", 1 ); cvShowImage( "H-S Histogram", hist_image ); cvWaitKey(0); }
IplImage* r_plane = cvCreateImage( cvGetSize(src), 8, 1 ); IplImage* g_plane = cvCreateImage( cvGetSize(src), 8, 1 ); IplImage* b_plane = cvCreateImage( cvGetSize(src), 8, 1 ); IplImage* planes[] = { r_plane, g_plane }; //将HSV图像分离到不同的通道中 cvCvtPixToPlane( src, b_plane, g_plane, r_plane, 0 ); // 生成二维直方图数据结构 int r_bins =256, b_bins = 256; CvHistogram* hist; { int hist_size[] = { r_bins, b_bins }; float r_ranges[] = { 0, 255 }; // hue is [0,180] float b_ranges[] = { 0, 255 }; float* ranges[] = { r_ranges,b_ranges }; hist = cvCreateHist( 2, hist_size, CV_HIST_ARRAY, ranges, 1); } //计算一张或多张单通道图像image(s) 的直方图 cvCalcHist( planes, hist, 0, 0 );
for( int h = 0; h < r_bins; h++ ) { for( int s = 0; s < b_bins; s++ ) { float bin_val = cvQueryHistValue_2D( hist, h, s ); //查询直方块的值 int intensity = cvRound( bin_val * 255 / max_value ); cvRectangle( hist_img, cvPoint( h*scale, s*scale ), cvPoint( (h+1)*scale - 1, (s+1)*scale - 1), CV_RGB(intensity,intensity,intensity), CV_FILLED); } }