直方图均衡化 cv::equalizeHist()

什么是图像直方图#

直方图是图像中像素强度(即像素值大小)分布的图形表达方式

  • 横轴 intensity 表示强度,由低到高
  • 纵轴 pixels 表示像素个数,即对应强度值的像素个数

在灰度图像中,直方图表示的强度为像素的灰度

在RGB图像中,直方图则分别表示各通道的灰度

绘制灰度图像的直方图#

关于绘制灰度图像的直方图可以参考这个这个函数

/**
* @brief 绘制灰度直方图
* @param frame 输入单通道图像
*/
Mat drawHist(Mat &frame) {
Mat hist_img;
Mat normalize_img;
const int hist_size = 255; //定义灰度级数量
float hist_r[] = { 0,255 }; //定义每个灰度级下取值范围
const float *hist_range = hist_r;
//计算直方图
calcHist(&frame, 1, 0, Mat(), hist_img, 1, &hist_size, &hist_range, true, false);
//直方图归一化到范围[0,histSize]
normalize(hist_img, normalize_img, 0, hist_size, NORM_MINMAX, -1, Mat());
//创建直方图画布
Mat hist_img_show(hist_size, hist_r[1], CV_8UC3, Scalar(0, 0, 0));
for (int i = 0; i<hist_size; i++)
{
line(hist_img_show, Point(i, hist_r[1]), Point(i, hist_r[1] - cvRound(normalize_img.at<float>(i))), Scalar::all(255), 1, 8, 0);
}
return hist_img_show;
}

直方图均衡化#

直方图均衡化是通过调整直方图的分布来提高图片的对比度

例入下面这个直方图

直方图均衡化有效的分散出现最频繁的强度,通常会提高许多图像的整体对比度

在图像中的效果#

我们选取一张非常暗的图片作为输入

输入并转变成灰度图像,并绘制直方图#

Mat src_img = imread("example.jpg", 0);
resize(src_img, src_img, Size(640, 480));
Mat hist_img_src = drawHist(src_img);
imshow("src_img", src_img);
imshow("hist_img_src", hist_img_src);

进行直方图均衡化,并绘制直方图#

Mat dst_img;
equalizeHist(src_img, dst_img);
Mat hist_img_dst = drawHist(dst_img);
imshow("equalized img", dst_img);
imshow("hist_img_dst", hist_img_dst);

  • 可以看到直方图被很明显的分散,图像的对比度被提高

  • 完整代码以及python版本实现可以参考「先假装有链接」

参考#