原理
图片的直方图
直方图的横坐标是图片的强度值(颜色值),纵坐标是每个强度值对应的像素的个数;因此坐标系上的每个方形图就代表了整张图片中其强度值等于该方形图对应强度值的像素的频数。
如下图,居于黑白之间的灰色最多,所以直方图横坐标的中间位置对应的像素数量越多:
直方图均衡化
直方图均衡化是指一种提高图片对比度的方法。
拿上面的图来举例子。直方图均衡化就是将中间强度值最集中的部分拉宽,如下图所示。绿色圈内的部分是频数较低的颜色值区域。在应用均衡化之后,直方图变成中间的样子,而原图也变成了右边的样子:
实现方法
均衡化的方法可以看成将一个分布(原有直方图)映射成另一种分布(均衡化后的直方图),从而使得强度值在整个值域内均衡分布。
要实现直方图均衡化,重映射方法应该是一个累积分布函数(cumulative distribution function, cdf)。比如,直方图
H
(
i
)
H(i)
H(i)的累计分布函数
H
′
(
i
)
H'(i)
H′(i)是:
H
′
(
i
)
=
∑
0
≤
j
<
i
H
(
j
)
H'(i)=\sum_{0 \leq j < i}H(j)
H′(i)=0≤j<i∑H(j)
上例中的直方图的累积分布函数的图像如下:
另外还要对
H
′
(
i
)
H'(i)
H′(i)进行归一化,使其最大值为255(或者为图片强度值的最大值)。经过归一化之后,频率相近的强度值会被转换成相同的值,这样就实现了一个更均衡的分布。累积分布图也变成了均衡直方图,即均衡化后的效果。
因此,均衡化的过程可以概括为:
e
q
u
a
l
i
z
e
d
(
x
,
y
)
)
=
H
′
(
s
r
c
(
x
,
y
)
)
equalized(x,y))=H'(src(x,y))
equalized(x,y))=H′(src(x,y))
API
在OpenCV中,有专门进行直方图均衡化的函数equalizeHist()
,其原型如下:
void cv::equalizedHist( InputArray src,
OutputArray sdt,)
- 原图必须是8位单通道的图片,即灰度图片
- 输出图与原图具有相同的尺寸和类型
示例
本示例将著名的lena.jpg
先转换成灰度图片,然后进行均衡化操作,代码如下:
#include <opencv2/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
int main() {
Mat src{ imread("lena.jpg") };
Mat gray;
cvtColor(src, gray, COLOR_BGR2GRAY);
Mat dst;
equalizeHist(gray, dst);
imshow("灰度图", gray);
imshow("均衡化", dst);
waitKey(0);
}
运行结果如下(左边为原始灰度图,右边为均衡化后的效果):
本站资源均来自互联网,仅供研究学习,禁止违法使用和商用,产生法律纠纷本站概不负责!如果侵犯了您的权益请与我们联系!
转载请注明出处: 免费源码网-免费的源码资源网站 » 【OpenCV C++20 学习笔记】直方图均衡化-Histogram Equalization
发表评论 取消回复