概念:在分析图像、物体、视频信息的过程中,我们常常把眼中的看到的物体用直方图(histogram)表示。
应用:直方图可以用来描述各种不同的事情,如物体的彩色分布、物体边缘梯度模板、以及表示物体目标位置的当前假设的概率分布。
直方图可以用来进行快速姿态识别、检测视频中的场景变换。
原理:直方图就是对数据进行统计,将统计值组织到一系列实现定义好的bin中。bin中的数值是从数据中计算出的特征的统计量,这些数据可以是梯度、方向、色彩或者任何其它特征。
直方图示例用法,取自《学习OpenCV》P227
该程序的作用是计算输入图像的色相饱和度(hue-saturation)直方图。
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
using namespace std;
using namespace cv;
#define cvQueryHistValue_2D( hist, idx0, idx1 ) cvGetReal2D( (hist)->bins, (idx0), (idx1) )
int main(int argc, const char * argv[]) {
/*1、载入一个图像*/
const char filename[] = "/Users/linwang/Downloads/Lena.jpg";
IplImage * src = cvLoadImage(filename,1);
/*2、创建hsv并进行色彩空间转换*/
IplImage * hsv = cvCreateImage(cvGetSize(src), src->depth, src->nChannels);
cvCvtColor(src, hsv, CV_RGB2HSV);
/*3、分别创建h、s、v单个颜色通道*/
IplImage * h_plane = cvCreateImage(cvGetSize(src), src->depth, 1);
IplImage * s_plane = cvCreateImage(cvGetSize(src), src->depth, 1);
IplImage * v_plane = cvCreateImage(cvGetSize(src), src->depth, 1);
IplImage * planes[] = { h_plane , s_plane}; //指针数组,指向两个图片矩阵
cvSplit(hsv, h_plane, s_plane, v_plane, 0); //分离通道
/*4、构建hist结构*/
int h_bins = 30;
int s_bins = 32;
CvHistogram * hist;
int hist_size[] = {h_bins , s_bins} ; //数组 , 大小和维度保持一致
float h_ranges[] = {0, 180};
float s_ranges[] = {0, 255};
float * ranges[] = { h_ranges , s_ranges };
hist = cvCreateHist(2, hist_size, CV_HIST_ARRAY , ranges , 1); //稠密矩阵,并且ranges是均匀分布的
/*5、从图像中计算直方图*/
cvCalcHist(planes, hist); //参数一是一个IplImage类型的指针
/*6、归一化*/
cvNormalizeHist(hist, 1.0);
/*7、创建一个图片*/
int scale = 10;
IplImage * hist_img = cvCreateImage(cvSize(h_bins * scale, s_bins * scale), 8, 3);
cvSetZero(hist_img);
/*8、进行可视化操作*/
float max_value = 0;
cvGetMinMaxHistValue(hist, 0, &max_value,0,0); //获取直方图最大值和最小值
for(int h = 0;h<h_bins;h++)
{
for(int s = 0;s<s_bins;s++)
{
float bin_val = cvQueryHistValue_2D(hist, h , s);
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,intensity,intensity),CV_FILLED);
}
}
cvShowImage("Source", src);
cvShowImage("Hist_Img", hist_img);
cvWaitKey(0);
cvReleaseImage(&src);
cvReleaseHist(&hist);
cvReleaseImage(&hist_img);
return 0;
}