opencv 灰度直方图 一维直方图

<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));

dims:直方图包含的维数  灰度直方图为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);
}

opencv 灰度直方图 一维直方图_第1张图片



##########################################################


程序:生成多通道一维颜色直方图

//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);
}

opencv 灰度直方图 一维直方图_第2张图片


参考:http://blog.csdn.net/morewindows/article/details/8364656

http://blog.csdn.net/xiaowei_cqu/article/details/7600666


你可能感兴趣的:(opencv,图像处理)