【从零学习OpenCV 4】直方图归一化

重磅干货,第一时间送达

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

前面我们完成了对一张图像像素灰度值的统计,并成功绘制了图像的直方图。但是由于绘制直方图的图像高度小于某些灰度值统计的数目,因此我们在绘制直方图时将所有的数据都缩小为原来的二十分之一之后再进行绘制,目的就是为了能够将直方图完整的绘制在图像中。如果换一张图像的直方图统计结果或者将直方图绘制到一个尺寸更小的图像中时,可能需要将统计数据缩小为原来的三十分之一、五十分之一甚至更低。数据缩小比例与统计结果、将要绘制直方图图像的尺寸相关,因此每次绘制时都需要计算数据缩小的比例。另外,由于像素灰度值统计的数目与图像的尺寸具有直接关系,如果以灰度值数目作为最终统计结果,那么一张图像经过尺寸放缩后的两张图像的直方图将会有巨大的差异,然而直方图可以用来表示图像的明亮程度,从理论上讲通过缩放的两张图像将具有大致相似的直方图分布特性,因此用灰度值的数目作为统计结果具有一定的局限性。

图像的像素灰度值统计结果主要目的之一就是查看某个灰度值在所有像素中所占的比例,因此可以用每个灰度值像素的数目占一幅图像中所有像素数目的比例来表示某个灰度值数目的多少,即将统计结果再除以图像中像素个数。这种方式可以保证每个灰度值的统计结果都是0到100%之间的数据,实现统计结果的归一化,但是这种方式也存在一个弊端,就是再CV_8U类型的图像中,灰度值有256个等级,平均每个像素的灰度值所占比例为0.39%,这个比例非常低,因此为了更直观的绘制图像直方图,常需要将比例扩大一定的倍数后再绘制图像。另一种常用的归一化方式是寻找统计结果中最大数值,把所有结果除以这个最大的数值,以实现将所有数据都缩放到0到1之间。

针对上面这两种归一化方式,OpenCV 4提供了normalize()函数实现多种形式的归一化功能,该函数的函数原型在代码清单4-3中给出。

代码清单4-3 normalize()函数原型
1.  void cv::normalize(InputArray src,
2.                         InputOutputArray dst,
3.                         double  alpha = 1,
4.                         double   beta = 0,
5.                         int  norm_type = NORM_L2,
6.                         int  dtype = -1,
7.                         InputArray mask = noArray()
8.                         )
  • src:输入数组矩阵。

  • dst:输入与src相同大小的数组矩阵。

  • alpha:在范围归一化的情况下,归一化到下限边界的标准值

  • beta:范围归一化时的上限范围,它不用于标准规范化。

  • norm_type:归一化过程中数据范数种类标志,常用可选择参数在表4-1中给出

  • dtype:输出数据类型选择标志,如果为负数,则输出数据与src拥有相同的类型,否则与src具有相同的通道数和数据类型。

  • mask:掩码矩阵。

该函数输入一个存放数据的矩阵,通过参数alpha设置将数据缩放到的最大范围,然后通过norm_type参数选择计算范数的种类,之后将输入矩阵中的每个数据分别除以求取的范数数值,最后得到缩放的结果。输出结果是一个CV_32F类型的矩阵,可以将输入矩阵作为输出矩阵,或者重新定义一个新的矩阵用于存放输出结果。该函数的第五个参数用于选择计算数据范数的种类,常用的可选择参数以及计算范数的公式都在表4-1中给出。计算不同的范数,最后的结果也不相同,例如选择NORM_L1标志,输出结果为每个灰度值所占的比例;选择NORM_INF参数,输出结果为除以数据中最大值,将所有的数据归一化到0到1之间。

表4-1 normalize()函数归一化常用标志参数

标志参数

简记

作用

原理

NORM_INF

1

无穷范数,向量最大值

NORM_L1

2

L1范数,绝对值之和

NORM_L2

4

L2范数,平方和之根

NORM_L2SQR

5

L2范数平方

为了了解归一化函数normalize()的作用,在代码清单4-4中给出了通过不同方式归一化数组的计算结果,并且分别用灰度值所占比例和除以数据最大值的方式对图像直方图进行归一化操作。为了更加直观的展现归一化后的结果,我们将每个灰度值所占比例放大了30倍,并将绘制直方图的图像高度作为1进行绘制直方图,最终结果在图4-3给出,根据结果显示,无论是否进行归一化,或者采用那种归一化方法,直方图的分布特性都不会改变。

代码清单4-4 myNormalize.cpp直方图归一化操作
1.  #include <opencv2\opencv.hpp>
2.  #include <iostream>
3.  
4.  using namespace cv;
5.  using namespace std;
6.  
7.  int main() 
8. {
9.    system("color F0"); //更改输出界面颜色
10.    vector<double> positiveData = { 2.0, 8.0, 10.0 };
11.    vector<double> normalized_L1, normalized_L2, normalized_Inf, normalized_L2SQR;
12.    //测试不同归一化方法
13.    normalize(positiveData, normalized_L1, 1.0, 0.0, NORM_L1); //绝对值求和归一化
14.    cout <<"normalized_L1=["<< normalized_L1[0]<<", "
15.      << normalized_L1[1]<<", "<< normalized_L1[2] <<"]"<< endl;
16.    normalize(positiveData, normalized_L2, 1.0, 0.0, NORM_L2); //模长归一化
17.    cout << "normalized_L2=[" << normalized_L2[0] << ", "
18.      << normalized_L2[1] << ", " << normalized_L2[2] << "]" << endl;
19.    normalize(positiveData, normalized_Inf, 1.0, 0.0, NORM_INF); //最大值归一化
20.    cout << "normalized_Inf=[" << normalized_Inf[0] << ", "
21.      << normalized_Inf[1] << ", " << normalized_Inf[2] << "]" << endl;
22.    normalize(positiveData, normalized_L2SQR, 1.0, 0.0, NORM_MINMAX); //偏移归一化
23.    cout << "normalized_MINMAX=[" << normalized_L2SQR[0] << ", "
24.      << normalized_L2SQR[1] << ", " << normalized_L2SQR[2] << "]" << endl;
25.    //将图像直方图归一化
26.    Mat img = imread("apple.jpg");
27.    if (img.empty())
28.    {
29.      cout << "请确认图像文件名称是否正确" << endl;
30.      return -1;
31.    }
32.    Mat gray,hist;
33.    cvtColor(img, gray, COLOR_BGR2GRAY);
34.    const int channels[1] = { 0 };
35.    float inRanges[2] = { 0,255 };
36.    const float* ranges[1] = { inRanges };
37.    const int bins[1] = { 256 };
38.    calcHist(&gray, 1, channels, Mat(), hist, 1, bins, ranges);
39.    int hist_w = 512;
40.    int hist_h = 400;
41.    int width = 2;
42.    Mat histImage_L1 = Mat::zeros(hist_h, hist_w, CV_8UC3);
43.    Mat histImage_Inf = Mat::zeros(hist_h, hist_w, CV_8UC3);
44.    Mat hist_L1, hist_Inf;
45.    normalize(hist, hist_L1, 1, 0, NORM_L1,-1, Mat());
46.    for (int i = 1; i <= hist_L1.rows; i++)
47.    {
48.      rectangle(histImage_L1, Point(width*(i - 1), hist_h - 1),
49.        Point(width*i - 1, hist_h - cvRound(30*hist_h*hist_L1.at<float>(i-1))-1),
50.        Scalar(255, 255, 255), -1);
51.    }
52.    normalize(hist, hist_Inf, 1, 0, NORM_INF, -1, Mat());
53.    for (int i = 1; i <= hist_Inf.rows; i++)
54.    {
55.      rectangle(histImage_Inf, Point(width*(i - 1), hist_h - 1),
56.        Point(width*i - 1, hist_h - cvRound(hist_h*hist_Inf.at<float>(i-1)) - 1),
57.        Scalar(255, 255, 255), -1);
58.    }
59.    imshow("histImage_L1", histImage_L1);
60.    imshow("histImage_Inf", histImage_Inf);
61.    waitKey(0);
62.    return 0;
63.  }

图4-2 myNormalize.cpp程序中对数组归一化结果

图4-3 myNormalize.cpp程序对图像直方图的归一化结果

(0)

相关推荐

  • 【OpenCV 4开发详解】直方图应用

    直方图不仅能够表示图像像素的统计特性,应用统计的直方图结果也可以增强图像的对比度,在图像中寻找相似区域等.本节中将重点介绍如果通过调整直方图分布提高图像的对比度.利用直方图反向投影寻找相同区域以及将图 ...

  • 你了解HOG特征吗?

    作者:晟 沚 前  言 HOG特征在很多任务中都有应用,如行人检测,首先对输入的图片进行预处理,然后计算像素点的梯度值,然后形成梯度直方图,然后对blocks进行normalize,最后收集到HOG ...

  • python+opencv图像处理(十四)

    图像直方图 1.灰度图像的直方图 灰度图像的直方图是灰度级和这种灰度级的概率之间关系的图形. 直接看图,下图中左侧是原图,右图为其直方图. 完整代码如下: import cv2 as cv impor ...

  • 关于OpenCV中rectangle函数的使用 统计直方图

    最近在学习OpenCV3.0左右的版本,在学习直方图的时候,笔者发现了一个问题,在看官方的文档说明,也就是opencv_tutorials时候,在看imgproc module这个板块的实例说明的时候 ...

  • R绘图笔记 | 二维散点图与统计直方图组合

    前面介绍了散点图.柱状图.直方图和核密度估计图,有时候散点图不能很直观的看的出数据的分布情况,这里介绍散点图与统计直方图组合绘制. 一.方法1 利用ggpubr包的ggscatterhist()函数进 ...

  • python+opencv图像处理(十五)

    直方图均衡 直方图均衡化是通过对图像的直方图进行修正来获得图像增强效果的方法,主要是进行对比度增强,就是让亮的更亮,暗的更亮. 1.灰度图像的直方图均衡 先上图看效果. 如图上标题所示,第一张是原图, ...

  • 【从零学习OpenCV 4】直方图匹配

    重磅干货,第一时间送达 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门书籍<从零学习OpenCV 4>.为了更让小伙伴更早的了解最新版的OpenCV 4,小白与出版社沟通 ...

  • 【从零学习OpenCV 4】直方图均衡化

    重磅干货,第一时间送达 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门书籍<从零学习OpenCV 4>.为了更让小伙伴更早的了解最新版的OpenCV 4,小白与出版社沟通 ...

  • 【从零学习OpenCV 4】直方图比较

    重磅干货,第一时间送达 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门书籍<从零学习OpenCV 4>.为了更让小伙伴更早的了解最新版的OpenCV 4,小白与出版社沟通 ...

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

    重磅干货,第一时间送达 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门书籍<从零学习OpenCV 4>.为了更让小伙伴更早的了解最新版的OpenCV 4,小白与出版社沟通 ...

  • 【从零学习OpenCV 4】深度神经网络应用实例

    重磅干货,第一时间送达 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门书籍<OpenCV 4开发详解>.为了更让小伙伴更早的了解最新版的OpenCV 4,小白与出版社沟通 ...

  • 【从零学习OpenCV 4】图像修复

    重磅干货,第一时间送达 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门书籍<OpenCV 4开发详解>.为了更让小伙伴更早的了解最新版的OpenCV 4,小白与出版社沟通 ...

  • 【从零学习OpenCV 4】分割图像——Mean-Shift分割算法

    重磅干货,第一时间送达 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门书籍<从零学习OpenCV 4>.为了更让小伙伴更早的了解最新版的OpenCV 4,小白与出版社沟通 ...

  • 【从零学习OpenCV 4】分割图像——Grabcut图像分割

    重磅干货,第一时间送达 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门书籍<OpenCV 4开发详解>.为了更让小伙伴更早的了解最新版的OpenCV 4,小白与出版社沟通 ...

  • 【从零学习OpenCV 4】分割图像——分水岭法

    重磅干货,第一时间送达 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门书籍<OpenCV 4开发详解>.为了更让小伙伴更早的了解最新版的OpenCV 4,小白与出版社沟通 ...