灰度直方图是一个帮助分析图像很有力的工具
灰度直方图这个程序主要有几个函数和结构体先说一下:
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;
}