阅读(567) (9)

Opencv直方图同等化(Equalization)

2017-09-18 10:55:51 更新

目标

在本教程中,您将学习:

  • 图像直方图是什么,为什么它是有用的
  • 通过使用OpenCV函数cv :: equalizeHist来均衡图像的直方图

理论

什么是图像直方图(Histogram)?

  • 它是图像的强度分布的图形表示。
  • 它量化所考虑的每个强度值的像素数。

Opencv直方图同等化

什么是直方图Equalization

  • 这是一种改善图像对比度的方法,以扩展强度范围。
  • 为了使之更清晰,从上图可以看出像素似乎聚集在可用的强度范围的中间。什么直方图均衡是伸展这个范围。看下图:绿色圆圈表示人口密度低下。应用均衡后,我们得到一个像中心的直方图。产生的图像显示在右图所示。

Opencv直方图同等化

它是如何工作的?

  • 均衡意味着将一个分布(给定直方图)映射到另一个分布(强度值的更宽和更均匀的分布),因此强度值在整个范围内扩展。
  • 为了实现均衡效果,重映射应该是累积分布函数(cdf)(更多细节参考学习OpenCV)。对于直方图 H(i),其累积分布 H′(i) 为:

Opencv直方图同等化

为了将其用作重映射功能,我们必须使H“(i )统一化,使得最大值为255(或图像的强度的最大值)。从上面的例子,累积函数是:

Opencv直方图同等化

最后,我们使用简单的重新映射程序来获得均衡图像的强度值:

Opencv直方图同等化

Code

  • 这个程序是做什么的?加载图像将原始图像转换为灰度通过使用OpenCV函数cv :: equalizeHist来平衡直方图在窗口中显示源和均衡图像。
  • 可下载的代码:点击这里
  • 代码一览:
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main( int, char** argv )
{
  Mat src, dst;
  const char* source_window = "Source image";
  const char* equalized_window = "Equalized Image";
  src = imread( argv[1], IMREAD_COLOR );
  if( src.empty() )
    { cout<<"Usage: ./EqualizeHist_Demo <path_to_image>"<<endl;
      return -1;
    }
  cvtColor( src, src, COLOR_BGR2GRAY );
  equalizeHist( src, dst );
  namedWindow( source_window, WINDOW_AUTOSIZE );
  namedWindow( equalized_window, WINDOW_AUTOSIZE );
  imshow( source_window, src );
  imshow( equalized_window, dst );
  waitKey(0);
  return 0;
}

说明

  • 声明源和目标图像以及窗口名称:
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, COLOR_BGR2GRAY );
equalizeHist( src, dst );

因为可以很容易地看到,唯一的参数是原始图像和输出(均衡)图像。

  • 显示两个图像(原始和均衡):
namedWindow( source_window, WINDOW_AUTOSIZE );
namedWindow( equalized_window, WINDOW_AUTOSIZE );
imshow( source_window, src );
imshow( equalized_window, dst );
  • 等待用户存在程序
waitKey(0);
return 0;

结果

  • 为了更好地了解均衡的结果,我们来介绍一个没有太大对比度的图像,比如:

Opencv直方图同等化

顺便说一下,这个直方图:

Opencv直方图同等化

注意像素围绕直方图的中心聚集。

  • 在我们的程序应用均衡后,我们得到这个结果:

直方图同等化

这个形象肯定有更多的对比。查看它的新直方图,如下所示:

直方图同等化

  • 注意像素的数量如何在强度范围内更多地分布。

注意
你想知道我们如何画出上面显示的直方图数字?看看下面的教程!