目标
这个教程包含以下内容:
- 什么是图像的直方图和为什么图像的直方图很有用;
- 用OpenCV函数equalizeHist对图像进行直方图均衡化。
原理
1. 图像的直方图是什么?
- 直方图是图像中像素强度分布的图形表达方式。
-
它统计了每一个强度值所具有的像素个数。
图像及其直方图
2. 直方图均衡化是什么?
- 直方图均衡化是通过拉伸像素强度分布范围来【增强图像对比度】的一种方法.
- 说得更清楚一些, 以上面的直方图为例, 您可以看到像素主要集中在中间的一些强度值上. 直方图均衡化要做的就是 拉伸 这个范围. 见下面左图: 绿圈圈出了 少有像素分布其上的 强度值. 对其应用均衡化后, 得到了中间图所示的直方图. 均衡化的图像见下面右图.
直方图均衡化效果
3. 直方图均衡化是怎样做到的?
- 均衡化指的是把一个分布 (给定的直方图) 映射 到另一个分布 (一个更宽更统一的强度值分布), 所以强度值分布会在整个范围内展开.
- 要想实现均衡化的效果, 映射函数应该是一个 累积分布函数 (cdf) (更多细节, 参考学习OpenCV). 对于直方图
, 它的 累积分布
是:
要使用其作为映射函数, 我们必须对最大值为255 (或者用图像的最大强度值) 的累积分布
进行归一化. 同上例, 累积分布函数的图像为:
累积分布函数的图像
- 最后, 我们使用一个简单的映射过程来获得均衡化后像素的强度值:
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
注意到像素大多集中在直方图中间的强度上.
-
使用例程进行均衡化后, 我们得到下面的结果:
AFTER
这幅图片显然对比度更强. 再验证一下均衡化后图片的直方图:
AFTER
注意到现在像素在整个强度范围内均衡分布.
[注明:收录于17/2/2020,原文参见 https://www.cnblogs.com/xuqq/p/3997062.html]