记录学习opencv中有关图像直方图绘制的方法
图像直方图是对图像的像素进行统计,不受到图像的旋转和平移等效果。
图像直方图具有平移不变性、放缩不变性等优点,可以用来查看图像整体的变化形式,比如图像是否过暗、图像像素灰度值主要集中在哪些范围。同时在对数字的识别当中,图像直方图也会发挥显著的作用。
图像直方图的横轴为图像的灰度值作为横轴,以灰度值的个数和比例作为纵轴去绘制统计图。
灰度值的分布一般反应了图像的亮暗对比度,可以依据直方图的结果去调增亮暗对比度,并依此调整图像的亮暗程度。
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)
images:待统计直方图的图像数组,数组中所有的图像应具有相同的尺寸和数据类型,并且数据类型只能是CV_8U、CV_16U和CV_32F这3种中的一种
nimages:输入图像的数量
channels:需要统计的通道索引数组,第一个图像的通道索引从0到images[0].channels()-1
mask:可选的操作掩码。如果是空矩阵,那么表示图像中所有位置的像素都计入直方图中
hist:输出的统计直方图结果,是一个dims维度的数组
dims:需要计算直方图的维度,必须是整数,并且不能大于CV_MAX_DIMS
hitsSize:存放每个维度直方图的数组的尺寸
ranges:每个图像通道中灰度值的取值范围
uniform:直方图是否均匀的标志符,默认状态下为均匀(true)
accumulate:是否累积统计直方图的,累积为true
示例程序:
#include //加载OpenCV4的头文件
#include
#include
using namespace std;
using namespace cv; //OpenCV命名空间
int main()
{
Mat img = imread("apple.jpg");
if (img.empty())
{
cout << "请确认图像文件名称是否正确" << endl;
return -1;
}
Mat gray;
cvtColor(img, gray, COLOR_RGB2GRAY);
//设置提取直方图的相关变量
Mat hist; //用于存放直方图计算结果
const int channels[1] = { 0 }; //通道索引
float inRanges[2] = { 0,255 };
const float* ranges[1] = { inRanges }; //像素灰度值范围
const int bins[1] = { 256 }; //直方图的维度,其实就是像素灰度值的最大值
calcHist(&gray, 1, channels, Mat(), hist, 1, bins, ranges); //计算图像直方图
//准备绘制直方图
int hist_w = 512;
int hist_h = 400;
int width = 2;
Mat histImage = Mat::zeros(hist_h, hist_w, CV_8UC3);
for (int i = 1; i <= hist.rows; i++)
{
rectangle(histImage, Point(width*(i - 1), hist_h - 1), Point(width*i - 1, hist_h - cvRound(hist.at<float>(i - 1) / 15)), Scalar(255, 255, 255), -1);
}
namedWindow("histImage", WINDOW_AUTOSIZE);
imshow("histImage", histImage);
imshow("gray", gray);
waitKey(0);
return 0; //程序结束
}
histImage:
apple.img:
参考书籍:Opencv4快速入门
感谢阅读!也欢迎大家关注小白博主,多多鼓励一下!