版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/Gordon_Wei/article/details/70215529
OpenCV 2.4.13
calcHist 通过图像计算直方图
函数声明如下:
void calcHist( 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 );
//1.输入的图像数组 2.输入数组的个数 3.通道数 4.掩码 5.直方图
//6.直方图维度 7.直方图每个维度的尺寸数组 8.每一维数组的范围 9.直方图是否是均匀 10.配置阶段不清零
1.图像数组
2.图像数组个数
3.图像的通道数
4.图像掩码
5.计算得到的直方图
6.直方图的维度(灰度直方图为1维)
7.直方图每一维度上的数组个数(bin 的个数)
8.每一维进行直方图统计的数组的范围 范围如 0~256 表示统计 0~255的数组 这里注意 (0,256) 包含0而不包含256 包含的是256-1
9.是否均匀的统计(个人理解为是否统计的每个bin包含相同的灰度级 可能理解有误)
10.这个还真不明白 待学习。。。
以下做个了计算直方图的例子 并进行直方图的显示
#include <opencv2/opencv.hpp>
int main()
{
cv::Mat src = imread("image.jpg", cv::IMREAD_GRAYSCALE); //读取灰度图像
cv::Mat hist; //将要获得的直方图
int imgNum = 1;//图像数
int histDim = 1;//直方图维度
int histSize = 256; //直方图每一维度bin个数
float range[] = { 0, 256 };//每一维度的统计范围
const float* histRange = { range };//因为我们计算1维直方图所以 只有一个rang
bool uniform = true;//
bool accumulate = false;//
cv::calcHist(&src, imgNum, 0, cv::Mat(), hist, histDim, &histSize, &histRange, uniform, accumulate);
int scale = 2;//控制图像的宽大小
cv::Mat histImg(cv::Size(histSize*scale, histSize), CV_8UC1);//用于显示直方图
uchar* pImg = nullptr;
for (size_t i = 0; i < histImg.rows; i++) //初始化图像为全黑
{
pImg = histImg.ptr<uchar>(i);
for (size_t j = 0; j < histImg.cols; j++)
{
pImg[j] = 0;
}
}
double maxValue = 0; //直方图中最大的bin的值
cv::minMaxLoc(hist, 0, &maxValue, 0, 0); //minMaxLoc可以计算最大值最小值以及其对应的位置 这里求最大值
int histHeight = 256; //要绘制直方图的最大高度
float* p = hist.ptr<float>(0);
for (size_t i = 0; i < histSize; i++)//进行直方图的绘制
{
float bin_val = p[i];
int intensity = cvRound(bin_val*histHeight / maxValue); //要绘制的高度
for (size_t j = 0; j < scale; j++) //绘制直线 这里用每scale条直线代表一个bin
{
cv::line(histImg, cv::Point(i*scale + j , histHeight - intensity), cv::Point(i*scale + j, histHeight - 1), 255);
}
//cv::rectangle(histImg, cv::Point(i*scale, histHeight - intensity), cv::Point((i + 1)*scale, histHeight - 1), 255); //利用矩形代表bin
}
cv::namedWindow("直方图");
cv::imshow("直方图", histImg);
cv::waitKey(0);
cv::destroyWindow("直方图");
//cv::destroyAllWindows();
return 0;
}