Opencv灰度直方图

灰度直方图是一个帮助分析图像很有力的工具

  灰度直方图这个程序主要有几个函数和结构体先说一下:

  1.  CreateHIst

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

          dims代表直方图是几维的,本程序是一个一维直方图,即bins只由x坐标索引

         sizes 代表有多少个bins

         type有两种类型一是稠密数组CV_HIST_ARRAY和稀疏数组CV_HIST_TREE,这里由于是一维直方图我们选择稠密数组

         ranges代表了bins中值得取值范围,这里我们的灰度值为0-255,所以选取0-255

         uniform归一化标识,默认为1,标识x方向被等分为sizes个bins

  2. CalcHist

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

代码如下:

#include"stdio.h"
#include<iostream>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>

#define cvQueryHistValue_1D( hist, idx0 )  ((float)cvGetReal1D( (hist)->bins, (idx0)))  

IplImage* DrowHist(CvHistogram* hist,float scaleX = 1,float scaleY = 1)
{
	float Max = 0;
	cvGetMinMaxHistValue(hist,0,&Max,0,0); //获得最大值
	

	IplImage* imghist = cvCreateImage(cvSize(256*scaleX,64*scaleY),8,1);  //根据屏幕大小自动调整
	cvZero(imghist); 

	for(int i = 0;i<255;i++)
	{
		float histValue = cvQueryHistValue_1D(hist,i);  //取值
		float nextValue = cvQueryHistValue_1D(hist,i+1);

		//以4个点来描边
		CvPoint pt1 = cvPoint(i*scaleX,64*scaleY);
		CvPoint pt2 = cvPoint((i+1)*scaleX,64*scaleY);
		CvPoint pt3 = cvPoint((i+1)*scaleX,64*scaleY-(nextValue/Max)*64*scaleY);
		CvPoint pt4 = cvPoint(i*scaleX,64*scaleY-(histValue/Max)*64*scaleY);

		int numPts = 5;
		CvPoint pts[5];
		pts[0] = pt1;
		pts[1] = pt2;
		pts[2] = pt3;
		pts[3] = pt4;
		pts[4] = pt1;

		cvFillConvexPoly(imghist,pts,numPts,cvScalar(255));//多边形填充
		 
	}
	return imghist;
}
int main()
{
	IplImage* img = cvLoadImage("E:\\1.bmp");
	cvNamedWindow("1");
	cvShowImage("1",img);
	

	int dims = 1;
	int size = 256;
	float b_range[] = {0,255};
	float *ranges[] = {b_range};
	//二维可用下面方式表示
	//float r_range[] = {0,255};
	//float * ranges[] = {b_range,r_range};

	CvHistogram* hist ; //创建直方图
	hist = cvCreateHist(dims,&size,CV_HIST_ARRAY,ranges,1);//dims表示几维,size表示要观察的像素最大值,CV..表示密集型 ranges表示每个通道的范围 ,0表示均等分配
	
	cvClearHist(hist);//防止系统分配的随机值影响

	IplImage* imgR = cvCreateImage(cvGetSize(img),8,1);
	IplImage* imgG = cvCreateImage(cvGetSize(img),8,1);
	IplImage* imgB = cvCreateImage(cvGetSize(img),8,1);

	cvSplit(img,imgB,imgG,imgR,NULL);//把图像按bgr方式分割

	cvCalcHist(&imgB,hist,0,0); //统计图像的像素点 
	IplImage* histB = DrowHist(hist); //画直方图
	cvClearHist(hist);
	

	cvCalcHist(&imgG,hist,0,0);
	IplImage* histG =  DrowHist(hist);   
	cvClearHist(hist);

	cvCalcHist(&imgR,hist,0,0);
	IplImage* histR = DrowHist(hist); 
	cvClearHist(hist);

	cvNamedWindow("b");
	cvShowImage("b",histB);

	cvNamedWindow("g");
	cvShowImage("g",histG);

	cvNamedWindow("r");
	cvShowImage("r",histR);

	cvWaitKey(0);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/sm16111/article/details/81389965