理论
什么是图像直方图?
- 它是图像强度分布的图形表示。
- 它量化了所考虑的每个强度值的像素数。
什么是直方图均衡?
- 这是一种改善图像对比度的方法,以拉伸强度范围。
- 为了更清楚,从上面的图像中,您可以看到像素似乎聚集在可用的强度范围的中间。 直方图均衡的作用是延伸此范围。
它如何工作?
- 均衡意味着将一个分布(给定的直方图)映射到另一个分布(更宽和更均匀的强度值分布),因此强度值在整个范围内扩展。
- 要实现均衡效果,重映射应该是累积分布函数(cdf)。 对于直方图H(i),其累积分布H'(i)是:
- 要将其用作重新映射函数,我们必须对H'(i)进行归一化,使得最大值为255(或图像强度的最大值)。 从上面的例子中,累积函数是:
- 最后,我们使用简单的重新映射程序来获得均衡图像的强度值:
代码
程序的工作原理
- 加载图像
- 将原始图像转换为灰度
- 使用OpenCV函数cv :: equalizeHist均衡直方图
- 在窗口中显示源图像和均衡图像。
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
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], 1 );
if( src.empty() )
{ 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;
}
解释
- 声明源图像和目标图像以及窗口名称:
- 加载源图像:
- 将其转换为灰度:
- 使用函数cv :: equalizeHist应用直方图均衡:
- 显示两个图像(原始图像和均衡图像):
- 等到用户退出程序
效果
- 为了更好地理解均衡的结果,让我们介绍一个对比度不大的图像,例如:
- 顺便说一下,这个直方图:
- 在我们的程序中应用均衡后,我们得到了这个结果:
- 这个形象肯定有更多的对比。 看看它的新直方图如下: