17/02/2020 【OpenCV】图像的直方图 和 直方图平衡操作

目标

这个教程包含以下内容:

  • 什么是图像的直方图和为什么图像的直方图很有用;
  • 用OpenCV函数equalizeHist对图像进行直方图均衡化。

原理

1. 图像的直方图是什么?

  • 直方图是图像中像素强度分布的图形表达方式。
  • 它统计了每一个强度值所具有的像素个数。


    图像及其直方图

2. 直方图均衡化是什么?

  • 直方图均衡化是通过拉伸像素强度分布范围来【增强图像对比度】的一种方法.
  • 说得更清楚一些, 以上面的直方图为例, 您可以看到像素主要集中在中间的一些强度值上. 直方图均衡化要做的就是 拉伸 这个范围. 见下面左图: 绿圈圈出了 少有像素分布其上的 强度值. 对其应用均衡化后, 得到了中间图所示的直方图. 均衡化的图像见下面右图.
    直方图均衡化效果

3. 直方图均衡化是怎样做到的?

  • 均衡化指的是把一个分布 (给定的直方图) 映射 到另一个分布 (一个更宽更统一的强度值分布), 所以强度值分布会在整个范围内展开.
  • 要想实现均衡化的效果, 映射函数应该是一个 累积分布函数 (cdf) (更多细节, 参考学习OpenCV). 对于直方图H(i), 它的 累积分布 H^{'}(i)是:H^{'}(i) = \sum_{0 \le j < i} H(j)。要使用其作为映射函数, 我们必须对最大值为255 (或者用图像的最大强度值) 的累积分布 H^{'}(i) | max(i) = 255进行归一化. 同上例, 累积分布函数的图像为:
    累积分布函数的图像
  • 最后, 我们使用一个简单的映射过程来获得均衡化后像素的强度值:
    equalized( x, y ) = H^{'}( src(x,y) )

4. 例程

  • 这个例程是用来干嘛的?

    • 加载源图像
    • 把源图像转为灰度图
    • 使用OpenCV函数 EqualizeHist 对直方图均衡化
    • 在窗体中显示源图像和均衡化后图像.
  • 下载例程: 点击 这里

  • 例程一瞥:

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>

using namespace cv;
using namespace std;

/**  @function main */
int main( int argc, char** argv )
{
  Mat src, dst;

  char* source_window = "Source image";
  char* equalized_window = "Equalized Image";

  /// 加载源图像
  src = imread( argv[1], 1 );

  if( !src.data )
    { cout<<"Usage: ./Histogram_Demo <path_to_image>"<<endl;
      return -1;}

  /// 转为灰度图
  cvtColor( src, src, CV_BGR2GRAY );

  /// 应用直方图均衡化
  equalizeHist( src, dst );

  /// 显示结果
  namedWindow( source_window, CV_WINDOW_AUTOSIZE );
  namedWindow( equalized_window, CV_WINDOW_AUTOSIZE );

  imshow( source_window, src );
  imshow( equalized_window, dst );

  /// 等待用户按键退出程序
  waitKey(0);

  return 0;
} </pre>

5. 程式说明

(1) 声明原图和目标图以及窗体名称:

    char* source_window = "Source image";
    char* equalized_window = "Equalized Image"; 

(2) 加载源图像:

    if( !src.data )  {
        cout<<"Usage: ./Histogram_Demo <path_to_image>"<<endl;
        return -1;
    }

(3) 转为灰度图:

    cvtColor( src, src, CV_BGR2GRAY ); 

(4) 利用函数 equalizeHist 对上面灰度图做直方图均衡化:

    equalizeHist( src, dst ); 

可以看到, 这个操作的参数只有源图像和目标 (均衡化后) 图像.

(5) 显示这两个图像 (源图像和均衡化后图像) :

    namedWindow( source_window, CV_WINDOW_AUTOSIZE );
    namedWindow( equalized_window, CV_WINDOW_AUTOSIZE );

    imshow( source_window, src );
    imshow( equalized_window, dst ); 

(6) 等待用户案件退出程序

    waitKey(0);
    return 0;

6. 结果

(1) 为了更好地观察直方图均衡化的效果, 我们使用一张对比度不强的图片作为源图像输入, 如下图:

BEFORE

它的直方图为:
BEFORE

注意到像素大多集中在直方图中间的强度上.

  1. 使用例程进行均衡化后, 我们得到下面的结果:


    AFTER

    这幅图片显然对比度更强. 再验证一下均衡化后图片的直方图:


    AFTER

    注意到现在像素在整个强度范围内均衡分布.

[注明:收录于17/2/2020,原文参见 https://www.cnblogs.com/xuqq/p/3997062.html]

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 本章包括以下内容: 计算图像直方图; 利用查找表修改图像外观; 直方图均衡化; 反向投影直方图检测特定图像内容; ...
    sumpig阅读 2,506评论 0 1
  • 灰度直方图 灰度直方图: 图像灰度直方图描述的是图像各个灰度级的统计特性,横坐标表示各级灰度值,纵坐标表示各级灰度...
    W__hisky阅读 7,035评论 0 3
  • 直方图均衡化Histogram Equalization 理论Theory 图像的直方图是什么What is an...
    baixiaoshuai阅读 3,074评论 1 3
  • 直方图变换 灰度变换 点运算 几何变换 直方图变换 1.灰度直方图 灰度直方图:数字图像中每一灰度级像素出现的频次...
    hyfine阅读 4,832评论 0 0
  • 东尼·博赞,思维导图的创始人,在他的《思维导图》一书中,这样说到“思维导图日记是你对自己生活核心记忆的外化。它将每...
    伊丽莎白安阅读 798评论 0 1