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-累计标示符