<span style="font-family: Arial, Helvetica, sans-serif;">typedef struct CvHistogram</span>
{ int type; CvArr* bins; float thresh[CV_MAX_DIM][2]; /* For uniform histograms. */ float** thresh2; /* For non-uniform histograms. */ CvMatND mat; /* Embedded matrix header for array histograms. */ } CvHistogram;
/* Creates new histogram */ CVAPI(CvHistogram*) cvCreateHist( int dims, int* sizes, int type, float** ranges CV_DEFAULT(NULL), int uniform CV_DEFAULT(1));
sizes:size数组的长度为dims,每个数表示分配给对应维数的bin的个数。如dims=3,则size中用[s1,s2,s3]分别指定每维bin的个数。
type:CV_HIST_ARRAY(默认),用来表示使用密集多维矩阵结构(如CvMatND)存储多维直方图;CV_HIST_SPARSE
ranges:取值范围
CV_INLINE void cvCalcHist( IplImage** image, CvHistogram* hist, int accumulate CV_DEFAULT(0), const CvArr* mask CV_DEFAULT(NULL) )计算直方图
/* Normalizes histogram by dividing all bins by sum of the bins, multiplied by <factor>. After that sum of histogram bins is equal to <factor> */ CVAPI(void) cvNormalizeHist( CvHistogram* hist, double factor );
归一化直方图
factor表示直方图归一化后的数值(通常情况下设为1)/* Finds indices and values of minimum and maximum histogram bins */ CVAPI(void) cvGetMinMaxHistValue( const CvHistogram* hist, float* min_value, float* max_value, int* min_idx CV_DEFAULT(NULL), int* max_idx CV_DEFAULT(NULL));输出直方图中找到的最小值和最大值
/* Retrieves value of the particular bin of x-dimensional (x=1,2,3,...) histogram */ #define cvQueryHistValue_1D( hist, idx0 ) \ ((float)cvGetReal1D( (hist)->bins, (idx0))) #define cvQueryHistValue_2D( hist, idx0, idx1 ) \ ((float)cvGetReal2D( (hist)->bins, (idx0), (idx1))) #define cvQueryHistValue_3D( hist, idx0, idx1, idx2 ) \ ((float)cvGetReal3D( (hist)->bins, (idx0), (idx1), (idx2))) #define cvQueryHistValue_nD( hist, idx ) \ ((float)cvGetRealND( (hist)->bins, (idx)))访问直方图数据 每个函数都返回相应bin中的值的浮点数
##################################################
程序:生成灰度直方图
//Draw a grayImage histogram // void drawGrayImage(void) { IplImage *img=cvLoadImage("lena.jpg", CV_LOAD_IMAGE_GRAYSCALE); if (img == NULL) exit(0); int dims=1; //创建一维直方图 int sizes[]={256}; //共有256个取值范围 int type=CV_HIST_ARRAY; //表示使用密集多维矩阵结构 float range[]={0, 255}; //取值范围为0-255 float *ranges[]={range}; CvHistogram *hist=NULL;//创建直方图的空指针结构 hist=cvCreateHist(dims, sizes, type, ranges, 1);//创建直方图 cvCalcHist(&img, hist, 0, NULL); //统计直方图 cvNormalizeHist(hist, 1.0); //归一化直方图 int hist_height=256; //直方图高度 int hist_size=256; //直方图尺寸 int scale=2; //创建一张一维直方图的“图”,横坐标为灰度级,纵坐标为像素个数(*scale) 彩色图像 IplImage *hist_image=cvCreateImage(cvSize((hist_size*scale), hist_height), IPL_DEPTH_8U, 3); if (hist_image == NULL) exit(0); cvZero(hist_image); float max=0; //直方图中的最大值 cvGetMinMaxHistValue(hist, 0, &max, NULL, NULL); for (int i=0; i<hist_size; i++) { float val=cvQueryHistValue_1D(hist, i); int intensity=cvRound(hist_height*val/max); cvRectangle(hist_image, cvPoint(i*scale, hist_height-1), cvPoint((i+1)*scale-1, hist_height-intensity-1), CV_RGB(255, 255, 255), -1, 8, 0); } cvNamedWindow("img"); cvNamedWindow("hist_image"); cvShowImage("img", img); cvShowImage("hist_image", hist_image); cvWaitKey(0); cvDestroyAllWindows(); cvReleaseImage(&img); cvReleaseImage(&hist_image); }
##########################################################
程序:生成多通道一维颜色直方图
//draw multi channels hist image // void drawHistImage(void) { IplImage *img=cvLoadImage("lena.jpg"); IplImage *channel_1=cvCreateImage(cvGetSize(img), img->depth, 1); IplImage *channel_2=cvCreateImage(cvGetSize(img), img->depth, 1); IplImage *channel_3=cvCreateImage(cvGetSize(img), img->depth, 1); if (NULL == img || NULL == channel_1 || NULL == channel_2 || NULL == channel_3) exit(0); cvSplit(img, channel_1, channel_2, channel_3, NULL); int dims=1; int sizes[]={256}; int type=CV_HIST_ARRAY; float range[]={0, 255}; float *ranges[]={range}; CvHistogram *hist1=NULL; CvHistogram *hist2=NULL; CvHistogram *hist3=NULL; CvHistogram *hist4=NULL; hist1=cvCreateHist(dims, sizes, type, ranges, 1); hist2=cvCreateHist(dims, sizes, type, ranges, 1); hist3=cvCreateHist(dims, sizes, type, ranges, 1); cvCalcHist(&channel_1, hist1, 0, NULL); cvCalcHist(&channel_2, hist2, 0, NULL); cvCalcHist(&channel_3, hist3, 0, NULL); cvNormalizeHist(hist1, 1.0); cvNormalizeHist(hist2, 1.0); cvNormalizeHist(hist3, 1.0); int scale=1; int hist_size=256; int hist_height=256; IplImage *hist_image=cvCreateImage(cvSize(hist_size*scale*3, hist_height), IPL_DEPTH_8U, 3); if (hist_image == NULL) exit(0); cvZero(hist_image); float max1=0; float max2=0; float max3=0; cvGetMinMaxHistValue(hist1, 0, &max1, NULL, NULL); cvGetMinMaxHistValue(hist2, 0, &max2, NULL, NULL); cvGetMinMaxHistValue(hist3, 0, &max3, NULL, NULL); for (int i=0; i<hist_size; i++) { float val1=cvQueryHistValue_1D(hist1, i); float val2=cvQueryHistValue_1D(hist2, i); float val3=cvQueryHistValue_1D(hist3, i); int intensity1=cvRound(val1*hist_height/max1); int intensity2=cvRound(val2*hist_height/max2); int intensity3=cvRound(val3*hist_height/max3); cvRectangle(hist_image, cvPoint(i*scale, hist_height-1), cvPoint((i+1)*scale-1, hist_height-1-intensity3), CV_RGB(255, 0, 0), -1, 8, 0); cvRectangle(hist_image, cvPoint(i*scale+hist_size, hist_height-1), cvPoint((i+1)*scale-1+hist_size, hist_height-1-intensity2), CV_RGB(0, 255, 0), -1, 8, 0); cvRectangle(hist_image, cvPoint(i*scale+hist_size*2, hist_height-1), cvPoint((i+1)*scale-1+hist_size*2, hist_height-1-intensity1), CV_RGB(0, 0, 255), -1, 8, 0); } cvNamedWindow("channel1", 0); cvNamedWindow("channel2", 0); cvNamedWindow("channel3", 0); cvResizeWindow("channel1", 200, 200); cvResizeWindow("channel2", 200, 200); cvResizeWindow("channel3", 200, 200); cvNamedWindow("hist_image"); cvShowImage("channel3", channel_1); cvShowImage("channel2", channel_2); cvShowImage("channel1", channel_3); cvShowImage("hist_image", hist_image); cvWaitKey(0); }
参考:http://blog.csdn.net/morewindows/article/details/8364656
http://blog.csdn.net/xiaowei_cqu/article/details/7600666