當圖像灰度級范圍較小時,會造成圖像對比度較低的問題。而圖像增強則是通過把圖像的灰度級范圍進行擴大,從而使圖像細節看起來更加清晰。下面我們一步一步進行說明。
灰度直方圖
直方圖是對灰度圖像上的灰度值進行統計得到的關于灰度值的函數,用來描述每個灰度值在圖像矩陣的像素個數或占有率。以下面的植物圖片為例:
import
cv2
import
matplotlib
.
pyplot
as
plt
# 繪制圖像灰度直方圖
def
deaw_gray_hist
(
gray_img
)
:
'''
:param gray_img大小為[h, w]灰度圖像
'''
# 獲取圖像大小
h
,
w
=
gray_img
.
shape
gray_hist
=
np
.
zeros
(
[
256
]
)
for
i
in
range
(
h
)
:
for
j
in
range
(
w
)
:
gray_hist
[
gray_img
[
i
]
[
j
]
]
+=
1
x
=
np
.
arange
(
256
)
# 繪制灰度直方圖
plt
.
bar
(
x
,
gray_hist
)
plt
.
xlabel
(
"gray Label"
)
plt
.
ylabel
(
"number of pixels"
)
plt
.
show
(
)
# 讀取圖片
img
=
cv2
.
imread
(
img_path
)
# 這里需要指定一個 img_path
deaw_gray_hist
(
img
[
:
,
:
,
0
]
)
cv2
.
imshow
(
'ori_img'
,
img
)
cv2
.
waitKey
(
)
如下所示,左邊為植物圖片,右邊為其對應的灰度直方圖。從直方圖可以看出其灰度值主要聚集在范圍很小的一個區域里,所以導致植物圖片對比度較低,不太清晰。
線性變換
我們把圖像的灰度直方圖看做是關于圖像灰度值的一個函數,即每張圖片都可以得到一個關于其灰度值的分布函數。我們可以通過線性變換讓其灰度值的范圍變大。
假設圖片上某點的像素值為
i i
i
,經過線性變換后得到的像素值為
o o
o
,
a , b a , b
a
,
b
為線性變換的參數則:
o = a ? i + b o = a*i +b
o
=
a
?
i
+
b
其中當
a > 0 a>0
a
>
0
時,圖片的對比度會增大;當
0 < a < 1 0<a<1
0
<
a
<
1
時,圖片的對比度會減小。當
b > 0 b>0
b
>
0
時,圖片的亮度會增大;當
b < 0 b<0
b
<
0
時,圖片的亮度會減小。
# 對圖像進行 線性變換
def
linear_transform
(
img
,
a
,
b
)
:
'''
:param img: [h, w, 3] 彩色圖像
:param a: float 這里需要是浮點數,把圖片uint8類型的數據強制轉成float64
:param b: float
:return: out = a * img + b
'''
out
=
a
*
img
+
b
out
[
out
>
255
]
=
255
out
=
np
.
around
(
out
)
out
=
out
.
astype
(
np
.
uint8
)
return
out
# a = 2, b=10
img
=
linear_transform
(
img
,
2.0
,
10
)
deaw_gray_hist
(
img
[
:
,
:
,
0
]
)
cv2
.
imshow
(
'linear_img'
,
img
)
cv2
.
waitKey
(
)
直方圖正規化
設圖片
I I
I
的灰度值范圍為
[ I m i n , I m a x ] [I_{min}, I_{max}]
[
I
m
i
n
?
,
I
m
a
x
?
]
,而輸出圖片
O O
O
的灰度值范圍
[ O m i n , O m a x ] [O_{min},O_{max}]
[
O
m
i
n
?
,
O
m
a
x
?
]
,當前圖片第
r r
r
行第
c c
c
列的灰度值表示為
I r , c I_{r,c}
I
r
,
c
?
,同樣輸出圖片對應位置的灰度值表示為
O r , c O_{r,c}
O
r
,
c
?
,它們之間的映射關系為:
O r , c ? O m i n I r , c ? I m i n = O m a x ? O m i n I m a x ? I m i n \frac{O_{r,c}-O_{min}}{I_{r,c}-I_{min}} = \frac{O_{max}-O_{min}}{I_{max}-I_{min}}
I
r
,
c
?
?
I
m
i
n
?
O
r
,
c
?
?
O
m
i
n
?
?
=
I
m
a
x
?
?
I
m
i
n
?
O
m
a
x
?
?
O
m
i
n
?
?
該式子可以轉換為:
O r , c = O m a x ? O m i n I m a x ? I m i n ? ( I r , c ? I m i n ) + O m i n = ( O m a x ? O m i n I m a x ? I m i n ) ? I r , c + ( O m i n ? O m a x ? O m i n I m a x ? I m i n ? I m i n ) O_{r,c} = \frac{O_{max}-O_{min}}{I_{max}-I_{min}} * (I_{r,c}-I_{min}) + O_{min} \\=(\frac{O_{max}-O_{min}}{I_{max}-I_{min}})*I_{r,c}+( O_{min}-\frac{O_{max}-O_{min}}{I_{max}-I_{min}}*I_{min})
O
r
,
c
?
=
I
m
a
x
?
?
I
m
i
n
?
O
m
a
x
?
?
O
m
i
n
?
?
?
(
I
r
,
c
?
?
I
m
i
n
?
)
+
O
m
i
n
?
=
(
I
m
a
x
?
?
I
m
i
n
?
O
m
a
x
?
?
O
m
i
n
?
?
)
?
I
r
,
c
?
+
(
O
m
i
n
?
?
I
m
a
x
?
?
I
m
i
n
?
O
m
a
x
?
?
O
m
i
n
?
?
?
I
m
i
n
?
)
該式子最后可以轉換成線性變換的形式,直方圖正規化是一種自動選擇a和b值的一種線性變換方法。
def
normalize_transform
(
gray_img
)
:
'''
:param gray_img:
:return:
'''
Imin
,
Imax
=
cv
.
minMaxLoc
(
gray_img
)
[
:
2
]
Omin
,
Omax
=
0
,
255
# 計算a和b的值
a
=
float
(
Omax
-
Omin
)
/
(
Imax
-
Imin
)
b
=
Omin
-
a
*
Imin
out
=
a
*
gray_img
+
b
out
=
out
.
astype
(
np
.
uint8
)
return
out
b
=
img
[
:
,
:
,
0
]
g
=
img
[
:
,
:
,
1
]
r
=
img
[
:
,
:
,
2
]
b_out
=
normalize_transform
(
b
)
g_out
=
normalize_transform
(
g
)
r_out
=
normalize_transform
(
r
)
nor_out
=
np
.
stack
(
(
b_out
,
g_out
,
r_out
)
,
axis
=
-
1
)
deaw_gray_hist
(
nor_out
[
:
,
:
,
0
]
)
cv
.
imshow
(
'nor_out'
,
nor_out
)
cv2
.
waitKey
(
)
因為植物原圖本身的灰度值范圍就很接近 [ 0 , 255 ] [0, 255] [ 0 , 2 5 5 ] ,所以經過直方圖正規化后效果并不明顯。
直方圖均衡
直方圖均衡步驟如下:
- 計算圖像的灰度直方圖
- 計算灰度直方圖的累加直方圖
- 得到輸入灰度級和輸出灰度級之間的映射關系
設輸入的灰度級為
p p
p
,輸出的灰度級為
q q
q
。
q + 1 256 = ∑ k = 0 p h i s t k H ? W \frac{q+1}{256}=\frac{\sum_{k=0}^phist_{k}}{H*W}
2
5
6
q
+
1
?
=
H
?
W
∑
k
=
0
p
?
h
i
s
t
k
?
?
# 對圖像進行 均衡化
def
equalize_transfrom
(
gray_img
)
:
return
cv
.
equalizeHist
(
gray_img
)
b
=
img
[
:
,
:
,
0
]
g
=
img
[
:
,
:
,
1
]
r
=
img
[
:
,
:
,
2
]
b_out
=
equalize_transfrom
(
b
)
g_out
=
equalize_transfrom
(
g
)
r_out
=
equalize_transfrom
(
r
)
equa_out
=
np
.
stack
(
(
b_out
,
g_out
,
r_out
)
,
axis
=
-
1
)
deaw_gray_hist
(
equa_out
[
:
,
:
,
0
]
)
cv
.
imshow
(
'equa_out'
,
equa_out
)
cv2
.
waitKey
(
)
)
參考鏈接:
OpenCV–Python 圖像增強
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
