直方图可以用来描述各种不同的事物,如物体的色彩分布、物体边缘梯度模板,以及表示目标位置的当前假设。
简单的说,直方图就是对数据进行统计,将统计值组织到一系列事先定义好的bin中。bin中的数值是从数据中计算出特征的统计量,这些数据可以是诸如梯度、方向、色彩或者任何其他特征。无论如何,直方图获得的是数据分布的统计图。通常直方图的维数要低于原始数据。
具体可参见:
下面参考《Learning OpenCV》一个例子。根据输入的图像计算出一个色相饱和度的2维直方图。
/**
* file:参考《learning OpenCV》P227
* author: Jacky_Liu
* date: 2013-12-06
*/ #include <QtCore/QCoreApplication>
#include <cv.h>
#include <highgui.h> int main(int argc, char *argv[])
{
// QCoreApplication a(argc, argv);
// return a.exec(); IplImage *src = NULL; if(argc != || (src = cvLoadImage(argv[], )) == )
{
printf("The number of the arguments is wrong, or the fail to load image.");
return ;
} //转换颜色空间
IplImage *hsv = cvCreateImage(cvGetSize(src), , );
cvCvtColor(src, hsv, CV_BGR2HSV); //分割到3个独立通道的图像
IplImage *h_plane = cvCreateImage( cvGetSize(src), , );
IplImage *s_plane = cvCreateImage( cvGetSize(src), , );
IplImage *v_plane = cvCreateImage( cvGetSize(src), , ); IplImage *planes[] = {h_plane, s_plane};
cvCvtPixToPlane(hsv, h_plane, s_plane, v_plane, ); //建立直方图结构,并计算
int h_bins = , s_bins = ;
CvHistogram *hist = NULL; //数组每一个元素对应直方图对应维数的bin的个数
int hist_size[] = {h_bins, s_bins};
//hue范围[0,180]
float h_ranges[] = {, };
float s_ranges[] = {, };
float *ranges[] = {h_ranges, s_ranges}; hist = cvCreateHist(, //直方图维数为2维
hist_size, //直方图每一维对应的bin数
CV_HIST_ARRAY, //稠密矩阵存储
ranges, //直方图每一维的维数
); //均匀直方图
//计算直方图
cvCalcHist(planes, hist, , ); //显示2维直方图
int scale = ;
IplImage *hist_img = cvCreateImage(cvSize(h_bins * scale, s_bins * scale),
, );
cvZero( hist_img ); float max_value = ;
cvGetMinMaxHistValue(hist, , &max_value, , ); for(int h = ; h < h_bins; h++)
{
for(int s = ; s < s_bins; s++)
{
//获取bin对应的最大值
float bin_val = cvQueryHistValue_2D(hist, h, s);
//颜色归一化到[0,255]显示
int intensity = cvRound( bin_val * / max_value);
//显示
cvRectangle(
hist_img,
cvPoint( h*scale, s*scale),
cvPoint( (h+)*scale - , (s+)*scale - ),
CV_RGB(intensity,intensity, intensity),
CV_FILLED
);
}
}
cvNamedWindow("Source", );
cvShowImage("Source", src); cvNamedWindow("H-S Histogram", );
cvShowImage("H-S Histogram", hist_img);
cvWaitKey(); return ;
}