opencv提供了calcHist()函数来计算图像直方图。不像在Matlab中一样,调用一个函数就可以画出图像的直方图。opencv的calcHist()仅仅计算出图像的直方图,如果要看直方图,需要自己画出。
//--------------画一维直方图程序---------------------
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
//载入原图并显示
Mat srcImage = imread("1.jpg", 0);
imshow("src",srcImage);
if(!srcImage.data) {cout << "Can not load image" << endl; return 0;}
//定义直方图的属性
MatND dstHist; // typedef Mat MatND;
int dims = 1; //直方图的维数
float hranges[] = {0, 255};
const float *ranges[] = {hranges}; //每一维度的取值范围,RGB图像一般为0~255
int histSize = 25; //histSize划分HIST的个数,越高越精确
int channels = 0; //计算直方图的通道
//计算图像的直方图
calcHist(&srcImage, //输入的图像,可以是多幅图像,每一副图像可以有多个通道
1, //输入图像的个数
&channels,//计算指定通道的直方图
Mat(), //掩码,它的大小的和images的大小相同,值为1的点将用来计算直方图
dstHist, //输出的目标直方图
dims, //直方图的维数
&histSize, //每个维度的直方图 长条的个数
ranges); //每一维度的取值范围
Mat dstImage(200, 200, CV_8UC3, Scalar(0)); //创建直方图
//获取最大值和最小值
double minValue = 0;
double maxValue = 0;
minMaxLoc(dstHist,&minValue, &maxValue, 0, 0); // 获取最大值和最小值
//绘制出直方图
int bin_w=200/histSize; //
for(int i = 0; i < 25; i++)
{
float binValue = dstHist.at<float>(i); // 注:hist中是float类型
float realValue = binValue*dstImage.rows/maxValue;//归一化
rectangle(dstImage,
Point(i*bin_w, dstImage.rows),
Point((i+1)*bin_w, dstImage.rows-realValue),
Scalar(255,0,0));
}
imshow("一维直方图", dstImage);
waitKey(0);
return 0;
}
calcHist函数用法:
C++: voidcalcHist(const Mat* images,
int nimages,
const int* channels,
InputArray mask,
OutputArray hist,
int dims,
const int* histSize,
const float** ranges,
bool uniform=true,
bool accumulate=false )
images-输入的图像,可以是多幅图像,每一副图像可以有多个通道,但是每幅图像必须有同样的深度(CV_8U or CV_32F)
nimages-输入图像的个数
channels-计算直方图的通道
mask-掩码,必须是一个8位(CV_8U)的数组,并且它的大小的和images的大小相同,值为1的点将用来计算直方图
hist-输出的目标直方图
dims-直方图的维数
histSize-在每一维上直方图的个数。简单把直方图看作一个一个的竖条的话,就是每一维上竖条的数
ranges-每一维度的取值范围
uniform-直方图是否均匀
accumulate-累计标示符