Histogram Equalization
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
// Read the image file
Mat image = imread("/home/CORPUSERS/xp025362/Pictures/1.png");
// Check for failure
if (image.empty())
{
cout << "Could not open or find the image" << endl;
cin.get(); //wait for any key press
return -1;
}
//Convert the image from BGR to YCrCb color space
Mat hist_equalized_image;
cvtColor(image, hist_equalized_image, COLOR_BGR2YCrCb);
//Split the image into 3 channels; Y, Cr and Cb channels respectively and store it in a std::vector
vector<Mat> vec_channels;
split(hist_equalized_image, vec_channels);
//Equalize the histogram of only the Y channel
equalizeHist(vec_channels[0], vec_channels[0]);
//Merge 3 channels in the vector to form the color image in YCrCB color space.
merge(vec_channels, hist_equalized_image);
//Convert the histogram equalized image from YCrCb to BGR color space again
cvtColor(hist_equalized_image, hist_equalized_image, COLOR_YCrCb2BGR);
//Define the names of windows
String windowNameOfOriginalImage = "Original Image";
String windowNameOfHistogramEqualized = "Histogram Equalized Color Image";
// Create windows with the above names
namedWindow(windowNameOfOriginalImage, WINDOW_NORMAL);
namedWindow(windowNameOfHistogramEqualized, WINDOW_NORMAL);
// Show images inside the created windows.
imshow(windowNameOfOriginalImage, image);
imshow(windowNameOfHistogramEqualized, hist_equalized_image);
waitKey(0); // Wait for any keystroke in any one of the windows
destroyAllWindows(); //Destroy all opened windows
return 0;
}
关于RGB 、YUV、HSV这几种不同的color space可以参考下面的链接:
RGB、YUV和HSV颜色空间模型
那么什么是Histogram Equalization,为什么要做这个step?
直方图均衡化是图像处理领域中利用图像直方图对对比度进行调整的方法。通过这种方法,亮度可以更好地在直方图上分布。这样就可以用于增强局部的对比度而不影响整体的对比度,直方图均衡化通过有效地扩展常用的亮度来实现这种功能。
官方的解释不太好懂,但是可以看出两点:
1、这是一种增强对比度的方法,且不影响原来整体的对比度,也就是说对于一幅灰阶图较亮的区域,依旧是较亮的,较暗依旧暗,只是对比度增大,不能明暗颠倒; 当然了以八位图像,那么像素映射以后的值域应在0和255之间的,不能越界
2、这种方法针对Y channel(明亮度)是很有效的,这也就是为什么上面的代码,首先将BGR->YCrCb,然后单独对Y做了equalizeHist。如果对具有三个分量的彩色图像,通过简单的对R、G、B三幅子图像分别均衡及合并, 会使均衡后的图像出现严重的色彩失真现象。
关于原理解释部分,由于本人对Matlab较熟悉,我看的是:https://blog.youkuaiyun.com/piaoxuezhong/article/details/78269439
网上blog有很多解释,大家可以自行查阅。
看下效果图:
最后简单的说下个人理解为什么Histogram Equalization可以提高对比度呢(不一定对!)?
以灰阶图来说,假如是看起来一副比较暗的img,那么肯定是组成它的大部分pixel是小于128的值,如图左侧的头像;反之比较亮的img,大部分pixel是比较大的值大于128;那么为了让画面看起来明暗细节一样多,即对比效果很明显,是不是就要使落在每个灰阶上的pixel的数目一样多呢?