利用OpenCV的函数equalizeHist()对图像作直方图均衡化处理
如果一幅图像的灰度值集中在某个比较窄的区域,则图像的对比度会显得比较小,不便于对图像的分析和处理。
图像的直方图均衡化可以实现将原图像的灰度值范围扩大,这样图像的对比度就得到了提高,从而方便对图像进行后续的分析和处理。
文字说明比较抽象,对于图像的直方图均衡化,大家看下面的两幅截图会有更直观的认识。
![](http://pic1.hhai.cc/pic1/2023/2023-02/001/06.png)
![](http://pic1.hhai.cc/pic1/2023/2023-02/001/07.png)
从上面两幅的截图中我们发现,将直方图均衡化算法应用于左侧亮图、对比度不同的各个图像后,得到了右侧直方图大致相同的图像,这体现了直方图均衡化在图像增强方面的自适应性。
当原始图像的直方图不同而图像结构性内容相同时,直方图均衡化所得到的结果在视觉上几乎是完全于致的。这样的处理效果对于在进行图像分析和比较之前将图像转化为统一的形式是十分有益。
算法原理如下:
⑴根据原图像的灰度累计分布构建重映射表;
⑵通过重映射表,对原图像进行重映射,得到经直方图均衡化后的图像。
具体的算法实现步骤如下:
⑴统计图像中各灰度级的出现次数,存储在大小为256的数组hist_sz中,比如 hist_sz[200]=2 代表灰度值为200的像素点出现次数为2。
⑵初始化图像直方图均衡化映射表数组lut中,比如 lut[200]=204 代表把原图像灰度值为200的像素的灰度值重新映射为204。
⑶建立映射表,具体方法如下:
这里以求灰度值3映射为多少灰度值为例说明这个问题。
①统计小于等于某一级的像素的点有多少个,并存储于变量sum中。比如灰度值小于等于2的像素点的个数有8个,灰度值为3的像素点个数有3个,则灰度值小于等于3的像素点个数为8+3=11(个),此时sum变量的值为11。
②利用下面两个语句计算得到映射目标值,并将映射目标值存储在数组lut中:
scale=255/(height*width);
val=sum*scale;
③利用存储在lut数组中的映射表把源图像的像素值作一个新的映射,例如语句“dst(y,x)=lut(1,src_y_x);”。
从上面具体的实现过程,我们可以看出,均衡化实际上就是按图像灰度值的出现频率去重新调整整幅图的灰度值,这样就使得对比度不同但内容相同的图像看起来一致了。
OpnCV提供了函数equalizeHist()对图像进行直方图均衡化。
函数equalizeHist()的原型如下:
- void cv::equalizeHist(InputArray src,
- OutputArray dst )
复制代码
函数equalizeHist()的使用示例代码如下:
代码中用到的图片的下载链接如下:
https://pan.baidu.com/s/1n2TEJl-K_Ug3ZPmraaQ6Ig?pwd=rpum
[C++] 纯文本查看 复制代码 //出处:昊虹AI笔记网(hhai.cc)
//用心记录计算机视觉和AI技术
//博主微信/QQ 2487872782
//QQ群 271891601
//欢迎技术交流与咨询
//OpenCV版本 OpenCV3.0
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{
cv::Mat srcImage = cv::imread("E:/material/images/2023/2023-01/he01.png", 0);
if( !srcImage.data )
return 1;
cv::imshow("srcImage", srcImage);
// 直方图均衡化
cv::Mat heqResult;
cv::equalizeHist(srcImage, heqResult);
cv::imshow("heqResult", heqResult);
cv::waitKey(0);
return 0;
}
运行结果如下:
![](http://pic1.hhai.cc/pic1/2023/2023-02/001/08.png)
|