opencv 关于 cvCalcHist的含义

代码演示:

#include <iostream>
#include <cv.h>
#include <highgui.h>
#include <cxcore.h>

using namespace std;

int main()
{
	IplImage *src = cvLoadImage("f:\\images\\lena.jpg");
	cout<<"total_pixel : "<<src->width*src->height<<endl;
	assert(src);
	IplImage *hsv = cvCreateImage(cvGetSize(src),8,3);
	cvCvtColor(src,hsv,CV_BGR2HSV);

	IplImage *h_plane = cvCreateImage(cvGetSize(src),8,1);
	IplImage *s_plane = cvCreateImage(cvGetSize(src),8,1);
	IplImage *v_plane = cvCreateImage(cvGetSize(src),8,1);
	IplImage *planes[] = {h_plane,s_plane};
	cvCvtPixToPlane(hsv,h_plane,s_plane,v_plane,0);

	//build the histogram and compute its contents 
	int h_bins = 30 ,s_bins = 36;
	int hist_size[] = {h_bins,s_bins};
	float h_ranges [ ] = {0,256};
	//saturation varies frome 0 to 255( pure spectrum color 
	float s_ranges[] = {0,256};
	float *ranges[] = {h_ranges,s_ranges};
	int scale = 10;
	IplImage *hist_img = 
		cvCreateImage(cvSize(h_bins*scale,s_bins*scale),8,3);
	CvHistogram *hist;
	float max_value = 0;
	int h,s;

	hist = cvCreateHist(2,hist_size,CV_HIST_ARRAY,ranges,1);
	cvCalcHist(planes,hist,0,0);
	cvGetMinMaxHistValue(hist,0,&max_value,0,0);
	cvZero(hist_img);

	float cnt = 0;
	for(h = 0;h<h_bins;h++){
		for(s = 0;s<s_bins;s++){
			float bin_val = cvQueryHistValue_2D(hist,h,s);
			cnt += bin_val;
			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,0,0),
				CV_FILLED);
		}
	}
	cout<<"cnt = "<<cnt<<endl;

	cvShowImage("h_s histogram " ,hist_img);
	cvShowImage("src",src);
	cvWaitKey();
	
	cvReleaseHist(&hist);
	cvReleaseImage(&src);
	cvReleaseImage(&hist_img);
	cvDestroyAllWindows();
}

结果 得出: 

total_pixel = cnt ;

先来看看:

CVAPI(CvHistogram*)  cvCreateHist( int dims, int* sizes, int type,
                                   float** ranges CV_DEFAULT(NULL),
                                   int uniform CV_DEFAULT(1));

//这里ranges表示的是直方图的范围 , 某一维度d ,   ranges 在uniform下为[0,256]  ,  且size[d] 为10 ,即将此维分成4份 

则[0,64)  , [64,128) ,  [128,192)  ,  [192,256)   包含左边,不包含右边


CV_INLINE  void  cvCalcHist( IplImage** image, CvHistogram* hist,
                             int accumulate CV_DEFAULT(0),
                             const CvArr* mask CV_DEFAULT(NULL) );

image 传入的图像指针,若用cvCreateHist 生成的hist有 dims 个维度, 则传入的图像就得有dims个   ,图像数组  IplImage *image = {h_plane , s_plane} (包含两张图像)

!且图像的大小一样(width ,height)

hist  即一般用cvCreateHist 生成的

accumulate 若为0 ,则在计算此图像的直方图前,将hist先清零 .. 若非0, 则在原来的基础上累加

mask  掩码  , , mask的必须为8位无符号整型 ,单通道图像IplImage 或者CvMat结构 ,将mask看成二值图,非零的地方即为使用(统计)的地方  ,  为0时对应的地方不参与运算操作


cvCalcHist  即为统计图像的像素点 ,, 

拿上面的程序来说,就是比第一幅图在 第i个bin 内 且第二幅图在第j 个bin内 ,同时满足时即为hist在 (i,j)处的值(像素个数)


如对于RGB图像,我们可心通过求RGB三个通道的图像,求其在 50<=R<100 且0<=G<30且20<=B<80的像素个数 ,

此时只要选取3个维度,每个维度的size 都为1 ,  int size[] = { 1 , 1 ,1  },将uniform设置为0 ,  设置float *ranges[3] = {50 100;

0 30;

20 80}

再调用cvCalcHist 即可

然后用

cvQueryHistValue_2D(hist,0,0)取得结果


你可能感兴趣的:(image,null,float)