直方图均衡
1 原理
首先定义几个变量,其实这几个变量在前面几篇关于直方图变换的文章中同样应该定义。
变量 | 意义 |
---|---|
n k n_k nk | 灰度级为 r k r_k rk的像素的个数 |
r k r_k rk | 第 k k k级灰度 |
h ( r k ) h(r_k) h(rk) | 灰度级为 r k r_k rk的像素的个数 |
P ( r k ) P(r_k) P(rk) | 灰度级为 r k r_k rk的概率估计值 |
n n n | 总像素数 |
由此可见:
h
(
r
k
)
=
n
k
h(r_k)=n_k
h(rk)=nk
P
(
r
k
)
=
n
k
n
P(r_k)=\frac{n_k}{n}
P(rk)=nnk
直方图均衡化是一种灰度变换,经过该变换之后,图像的直方图分布基本符合均匀分布。
设变换的输出为灰度
s
s
s,那么直方图均衡的变换可以表达为:
s
=
T
(
r
k
)
s = T(r_k)
s=T(rk)
每一个灰度级经过函数
T
(
r
)
T(r)
T(r)变换之后都对应一个输出灰度级
s
s
s,同时
T
(
r
)
T(r)
T(r)满足两个条件:
- T ( r ) T(r) T(r)在区间 [ 0 , 1 ] [0,1] [0,1]上是单值且单调递增函数;
- 当 0 ≤ r ≤ L − 1 0\leq r \leq L-1 0≤r≤L−1时, 0 ≤ T ( r ) ≤ L − 1 0 \leq T(r) \leq L-1 0≤T(r)≤L−1;
第一条约束要求输入越高的灰度级,变换之后仍然是越高的灰度级,不会出现亮暗翻转的情况。第二条约束要求变换之后,灰度级仍然在有效范围之内。
用
P
r
(
r
)
P_{r}(r)
Pr(r)和
P
s
(
s
)
P_{s}(s)
Ps(s)表示灰度级为
r
r
r和
s
s
s的概率密度,
s
=
T
(
r
)
=
(
L
−
1
)
∫
0
r
p
r
(
w
)
d
w
s=T(r)=(L-1)\int_{0}^{r}{p_{r}(w)dw}
s=T(r)=(L−1)∫0rpr(w)dw
其中
w
w
w是积分变量。公式右边是概率密度函数的积分,总为正,因此满足条件一,当到达积分上限
L
−
1
L-1
L−1时,函数的值为1,满足条件二。
p
s
(
s
)
=
p
r
(
r
)
∣
d
r
d
s
∣
p_{s}(s)=p_{r}(r)|\frac{dr}{ds}|
ps(s)=pr(r)∣dsdr∣
d
s
d
r
=
d
T
(
r
)
d
r
=
(
L
−
1
)
d
d
r
[
∫
0
r
p
r
(
w
)
d
w
]
=
(
L
−
1
)
p
r
(
r
)
\frac{ds}{dr}=\frac{dT(r)}{dr}=(L-1)\frac{d}{dr}[\int_{0}^{r}{p_{r}(w)dw}]=(L-1)p_{r}(r)
drds=drdT(r)=(L−1)drd[∫0rpr(w)dw]=(L−1)pr(r)
p
s
(
s
)
=
p
r
(
r
)
∣
d
r
d
s
∣
=
p
r
(
r
)
∣
1
(
L
−
1
)
p
r
(
r
)
∣
=
1
L
−
1
,
0
≤
s
≤
L
−
1
p_{s}(s)=p_{r}(r)|\frac{dr}{ds}|=p_{r}(r)|\frac{1}{(L-1)p_{r}(r)}|=\frac{1}{L-1},0 \leq s \leq L-1
ps(s)=pr(r)∣dsdr∣=pr(r)∣(L−1)pr(r)1∣=L−11,0≤s≤L−1
这就说明了经过变换之后,输出灰度级
s
s
s在
[
0
,
L
−
1
]
[0,L-1]
[0,L−1]上服从均匀分布。
将变换离散化之后,得到离散形式下的变换关系:
s
k
=
T
(
r
k
)
=
(
L
−
1
)
∑
j
=
0
k
p
r
(
r
j
)
=
L
−
1
M
N
∑
j
=
0
k
n
j
,
k
=
0
,
1
,
2
,
…
,
L
−
1
s_k=T(r_{k})=(L-1)\sum_{j=0}^{k}p_{r}(r_{j})=\frac{L-1}{MN}\sum_{j=0}^{k}n_{j}, k=0,1,2, \dots ,L-1
sk=T(rk)=(L−1)j=0∑kpr(rj)=MNL−1j=0∑knj,k=0,1,2,…,L−1
其中,
M
,
N
M,N
M,N为图像的宽高,
L
L
L为图像的总灰度级。
2 Matlab实现
2.1 Matlab已有函数
Matlab中使用函数histeq
进行直方图均衡化。注意,histeq
默认情况下,直方图均衡时灰度等级会被划分到64个子级中,这导致直接使用默认参数调用时结果的直方图与手动计算的结果差异较大。
2.2 手动实现
clc;
clear;
close all;
% 对灰度图进行灰度线性变换
ori_img = imread('../images/18.jpg');
ori_img1 = rgb2gray(ori_img);
[oriHist,oriX] = imhist(ori_img1);
p = oriHist;
all = sum(oriHist);
for i=1:1:256
p(i) = sum(oriHist(1:i));
end
% p = 255*p;
% p = uint8(p);
[width,height] = size( ori_img1);
gray1 = ori_img1;
for i=1:1:width
for j = 1:1:height
gray1(i,j) = 255*p(gray1(i,j)+1)/all;
end
end
[g1Hist,g1X] = imhist(gray1);
g2 = histeq(ori_img1,256);
[g2Hist,g2X] = imhist(g2);
figure(1),subplot(1,3,1),imshow(ori_img1),title('原图');subplot(1,3,2),imshow(gray1),title('手动实现直方图均衡化');subplot(1,3,3),imshow(g2),title('histeq');
figure(3),subplot(1,3,1),stem(oriX,oriHist),title('原图直方图');subplot(1,3,2),stem(g1X,g1Hist),title('手动实现直方图均衡化');subplot(1,3,3),stem(g2X,g2Hist),title('histeq');
3 OpenCV实现
3.1 OpenCV已有函数
直方图均衡化在OpenCV
中使用函数equalizeHist
函数完成。
/** @brief Equalizes the histogram of a grayscale image.
The function equalizes the histogram of the input image using the following algorithm:
- Calculate the histogram \f$H\f$ for src .
- Normalize the histogram so that the sum of histogram bins is 255.
- Compute the integral of the histogram:
\f[H'_i = \sum _{0 \le j < i} H(j)\f]
- Transform the image using \f$H'\f$ as a look-up table: \f$\texttt{dst}(x,y) = H'(\texttt{src}(x,y))\f$
The algorithm normalizes the brightness and increases the contrast of the image.
@param src Source 8-bit single channel image.
@param dst Destination image of the same size and type as src .
*/
CV_EXPORTS_W void equalizeHist( InputArray src, OutputArray dst );
3.2 C++ 手动实现
创建灰度映射表,具体变换过程使用opencv的LUT函数执行。
void CreateHELT(cv::Mat& hist, cv::Mat&lut)
{
cv::Mat data(1,256,CV_32FC1,cv::Scalar(0));
lut = cv::Mat(1, 256, CV_8UC1);
for (int i = 0; i < data.cols; i++)
{
if (i == 0)
{
data.at<float>(i) = hist.at<float>(i);
}
else
{
data.at<float>(i) = data.at<float>(i-1)+hist.at<float>(i);
}
float f = 255 * data.at<float>(i);
if (f < 0)
f = 0;
else if (f > 255)
f = 255;
lut.at<uchar>(i) = (uchar)(f);
}
}
4 效果图
histeq
使用256级灰度时的结果:
histeq
使用默认参数调用时的计算结果:
从结果可以看出,histeq的灰度级明显少。
5 参考
https://blog.csdn.net/timeless_2014/article/details/80389433
https://www.cnblogs.com/whw19818/p/5790680.html