c++ 绘制函数图像_【从零学习OpenCV 4】图像直方图绘制

点击上方“小白学视觉”,选择“星标”公众号

重磅干货,第一时间送达

2ac26db695b135aa5c4c732e78a5f660.png

经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门书籍《从零学习OpenCV 4》。为了更让小伙伴更早的了解最新版的OpenCV 4,小白与出版社沟通,提前在公众号上连载部分内容,请持续关注小白。

图像直方图是图像处理中非常重要的像素统计结果,图像直方图不再表征任何的图像纹理信息,而是对图像像素的统计。由于同一物体无论是旋转还是平移在图像中都具有相同的灰度值,因此直方图具有平移不变性、放缩不变性等优点,因此可以用来查看图像整体的变化形式,例如图像是否过暗、图像像素灰度值主要集中在哪些范围等,在特定的条件下也可以利用图像直方图进行图像的识别,例如对数字的识别。

图像直方图简单来说就是统计图像中每个灰度值的个数,之后将图像灰度值作为横轴,以灰度值个数或者灰度值所占比率作为纵轴绘制的统计图。通过直方图可以看出图像中哪些灰度值数目较多,哪些较少,可以通过一定的方法将灰度值较为集中的区域映射到较为稀疏的区域,从而使得图像在像素灰度值上分布更加符合期望状态。通常情况下,像素灰度值代表亮暗程度,因此通过图像直方图可以分析图像亮暗对比度,并调整图像的亮暗程度。

在OpenCV 4中只提供了图像直方图的统计函数calcHist(),该函数能够统计出图像中每个灰度值的个数,但是对于直方图的绘制需要使用者自行绘制。我们首先学习统计灰度值数目的函数calcHist()的使用,该函数的原型在代码清单4-1中给出。

代码清单4-1 calcHist()函数原型
1.  void cv::calcHist(const Mat * images,
2.                        int  nimages,
3.                        const int * channels,
4.                        InputArray mask,
5.                        OutputArray hist,
6.                        int  dims,
7.                        const int * histSize,
8.                        const float ** ranges,
9.                        bool  uniform = true,
10.                        bool  accumulate = false 
11.                        )
  • images:待统计直方图的图像数组,数组中所有的图像应具有相同的尺寸和数据类型,并且数据类型只能是CV_8U、CV_16U和CV_32F三种中的一种,但是不同图像的通道数可以不同。

  • nimages:输入的图像数量

  • channels:需要统计的通道索引数组,第一个图像的通道索引从0到images[0].channels()-1,第二个图像通道索引从images[0].channels()到images[0].channels()+ images[1].channels()-1,以此类推。

  • mask:可选的操作掩码,如果是空矩阵则表示图像中所有位置的像素都计入直方图中,如果矩阵不为空,则必须与输入图像尺寸相同且数据类型为CV_8U。

  • hist:输出的统计直方图结果,是一个dims维度的数组。

  • dims:需要计算直方图的维度,必须是整数,并且不能大于CV_MAX_DIMS,在OpenCV 4.0和OpenCV 4.1版本中为32。

  • histSize:存放每个维度直方图的数组的尺寸。

  • ranges:每个图像通道中灰度值的取值范围。

  • uniform:直方图是否均匀的标志符,默认状态下为均匀(true)。

  • accumulate:是否累积统计直方图的标志,如果累积(true),则统计新图像的直方图时之前图像的统计结果不会被清除,该同能主要用于统计多个图像整体的直方图。

该函数用于统计图像中每个灰度值像素的个数,例如统计一张CV_8UC1的图像,需要统计灰度值从0到255中每一个灰度值在图像中的像素个数,如果某个灰度值在图像中没有,那么该灰度值的统计结果就是0。由于该函数具有较多的参数,并且每个参数都较为复杂,因此作者建议读者在使用该函数时只统计单通道图像的灰度值分布,对于多通道图像可以将图像每个通道分离后再进行统计。

为了使读者更加了解函数的使用方法,我们在代码清单4-2中提供了绘制灰度图像的图像直方图的示例程序。在程序中我们首先使用calcHist()函数统计灰度图像里面每个灰度值的数目,之后通过不断绘制矩形的方式实现直方图的绘制。由于图像中部分灰度值像素数目较多,因此我们将每个灰度值数目缩小了20倍后再进行绘制,绘制的直方图在图4-1中所示。在程序中我们使用了OpenCV 4提供的四舍五入的取整函数cvRound(),该函数输入参数为double类型的变量,返回值为对该变量四舍五入后的int型数值。

代码清单4-2 myCalHist.cpp绘制图像直方图
1.  #include 
2.  #include 
3.  
4.  using namespace cv;
5.  using namespace std;
6.  
7.  int main()
8. {
9.    Mat img = imread("apple.jpg");
10.    if (img.empty())
11.    {
12.      cout << "请确认图像文件名称是否正确" << endl;
13.      return -1;
14.    }
15.    Mat gray;
16.    cvtColor(img, gray, COLOR_BGR2GRAY);
17.    //设置提取直方图的相关变量
18.    Mat hist; //用于存放直方图计算结果
19.    const int channels[1] = { 0 }; //通道索引
20.    float inRanges[2] = { 0,255 };
21.    const float* ranges[1] = { inRanges }; //像素灰度值范围
22.    const int bins[1] = { 256 }; //直方图的维度,其实就是像素灰度值的最大值
23.    calcHist(&img, 1, channels, Mat(), hist, 1, bins, ranges); //计算图像直方图
24.    //准备绘制直方图
25.    int hist_w = 512;
26.    int hist_h = 400;
27.    int width = 2;
28.    Mat histImage = Mat::zeros(hist_h, hist_w, CV_8UC3);
29.    for (int i = 1; i <= hist.rows; i++)
30.    {
31.      rectangle(histImage, Point(width*(i - 1), hist_h - 1),
32.        Point(width*i - 1, hist_h - cvRound(hist.at<float>(i - 1) / 20)),
33.        Scalar(255, 255, 255), -1);
34.    }
35.    namedWindow("histImage", WINDOW_AUTOSIZE);
36.    imshow("histImage", histImage);
37.    imshow("gray", gray);
38.    waitKey(0);
39.    return 0;
40.  }

56512d7a81d227066a1e826152a9738e.png

图4-1 myCalHist.cpp程序运行结果

从零学习OpenCV 4往期推荐

【从零学习OpenCV 4】Windows系统中安装OpenCV 4

【从零学习OpenCV 4】Ubuntu系统中安装OpenCV 4

【从零学习OpenCV 4】opencv_contrib扩展模块的安装

【从零学习OpenCV 4】Mat类介绍

【从零学习OpenCV 4】Mat类构造与赋值

【从零学习OpenCV 4】Mat类支持的运算

【从零学习OpenCV 4】这4种读取Mat类元素的的方法你都知道么?

【从零学习OpenCV 4】namedWindow函数&imshow函数的使用

【从零学习OpenCV 4】颜色模型与转换

【从零学习OpenCV 4】多通道分离与合并

【从零学习OpenCV 4】图像像素统计

【从零学习OpenCV 4】两图像间的像素操作

【从零学习OpenCV 4】图像二值化

【从零学习OpenCV 4】LUT查找表

【从零学习OpenCV 4】图像仿射变换

【从零学习OpenCV 4】图像透视变换

【从零学习OpenCV 4】极坐标变换

【从零学习OpenCV 4】绘制几何图形

【从零学习OpenCV 4】图像金字塔

【从零学习OpenCV 4】创建图像窗口滑动条

【从零学习OpenCV 4】鼠标响应

  ……

经过几个月的努力,市面上第一本OpenCV 4入门书籍《从零学习OpenCV 4》将于今年12月左右由人民邮电出版社发行。如果小伙伴觉得内容有帮助,希望到时候多多支持!

关注小白的小伙伴可以提前看到书中的内容,我们创建了学习交流群,欢迎各位小伙伴添加小白微信加入交流群,添加小白时请备注“学习OpenCV 4”。

56b009f1fa9cc6e5d47a434949c0d6e4.png

fb2dcdf3d3001b9347babfa4d0233852.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值