专栏首页深度学习和计算机视觉【从零学习OpenCV 4】图像直方图绘制

【从零学习OpenCV 4】图像直方图绘制

经过几个月的努力,小白终于完成了市面上第一本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 <opencv2\opencv.hpp>
2.  #include <iostream>
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.  }

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

本文分享自微信公众号 - 小白学视觉(NoobCV),作者:小白

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-12-10

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 数字图像处理基本知识

    数字图像,又称为数码图像或数位图像,是二维图像用有限数字数值像素的表示。数字图像是由模拟图像数字化得到的、以像素为基本元素的、可以用数字计算机或数字电路存储和处...

    小白学视觉
  • 【从零学习OpenCV 4】直方图匹配

    经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门书籍《从零学习OpenCV 4》。为了更让小伙伴更早的了解最新版的OpenCV 4,小白与出版社...

    小白学视觉
  • 创建合成CT图像数据

    本文我们描述了一种从一组小样本中创建合成医学图像的方法,我们的方法基于随机部分变形,因此无需深度学习(不需要GANs)。

    小白学视觉
  • 【图像处理一】:直方图

    从这章开始,我们将从最基础的图像处理讲起,并且探索其中的一些算法在FPGA上的实现。第一章讲一个最基本的概念:直方图。直方图在图像灰度增强中是一个很重要的量,它...

    AI加速
  • 灰度直方图的统计

    灰度直方图是关于灰度级分布的函数,是对图像中灰度级分布的统计。灰度直方图是将数字图像中的所有像素,按照灰度值的大小,统计其出现的频率。灰度直方图是灰度级的函数,...

    FPGA开源工作室
  • 图像的灰度直方图、直方图均衡化、直方图规定化(匹配)

    一幅图像由不同灰度值的像素组成,图像中灰度的分布情况是该图像的一个重要特征。图像的灰度直方图就描述了图像中灰度分布情况,能够很直观的展示出图像中各个灰度级所占的...

    233333
  • C++ OpenCV直方图均衡化

    图像直方图由于其计算代价较小,且具有图像平移、旋转、缩放不变性等众多优点,广泛地应用于图像处理的各个领域,特别是灰度图像的阈值分割、基于颜色的图像检索以及图像分...

    Vaccae
  • 数字图像处理灰度变换之灰度直方图及python实现

    灰度直方图是图像灰度级的函数,用来描述每个灰度级在图像矩阵中的像素个数或者占有率。直方图显示图像数据时会以左暗右亮的分布曲线形式呈现出来。横坐标是灰度级,纵坐标...

    Minerva
  • flash读取XML 背景自动适应大小

    var bg = new Object(); bg.bgdoc_xml = new XML(); bg.parse_XML = function() {    ...

    用户1172164
  • 传统特征:SIFT算子的原理

    SIFT,一种检测局部特征算法,该算法通过求一幅图中的特征点(及其有关scale 和 orientation 的描述子得到特征并进行图像特征点匹配,SIFT特征...

    AI深度学习求索

扫码关注云+社区

领取腾讯云代金券