質量聲明:原創文章,內容質量問題請評論吐槽。如對您產生干擾,可私信刪除。
主要參考:(美)拉斐爾·C.岡薩雷斯. 數字圖像處理 第3版[M]. 阮秋琦,譯. 北京:電子工業出版社, 2017: 633.
形態學重建
形態學重建涉及兩幅圖像和一個結構元:
- Marker 圖像 :包含變換的起點,將被連續膨脹,直至收斂
- Mask 圖像 :用來約束膨脹結果,即 Mask >= Marker
- 結構單元 (Structuring Element,SE):定義連通性
數學迭代式:
M a r k e r = ( M a r k e r ⊕ S E ) ∩ M a s k Marker = (Marker \oplus SE) \cap Mask
M
a
r
k
e
r
=
(
M
a
r
k
e
r
⊕
S
E
)
∩
M
a
s
k
代碼示例:
def
imreconstruct
(
marker
,
mask
,
SE
=
np
.
ones
(
[
3
,
3
]
)
)
:
"""
描述:以mask為約束,連續膨脹marker,實現形態學重建,其中mask >= marker
參數:
- marker 標記圖像,單通道/三通道圖像
- mask 模板圖像,與marker同型
- conn 聯通性重建結構元,參照matlab::imreconstruct::conn參數,默認為8聯通
"""
while
True
:
marker_pre
=
marker
dilation
=
cv
.
dilate
(
marker
,
kernel
=
SE
)
marker
=
np
.
min
(
(
dilation
,
mask
)
,
axis
=
0
)
if
(
marker_pre
==
marker
)
.
all
(
)
:
break
return
marker
孔洞填充
孔洞定義:被前景(白色)連通域包圍的封閉的背景(黑色)區域,不限于圓形。如圖所示。
原理:
以原圖像的補集作為Mask,用來限制膨脹結果;以帶有白色邊框的黑色圖像為初始Marker,用SE對其進行連續膨脹,直至收斂;最后對Marker取補即得到最終圖像,與原圖相減可得到填充圖像。
M a r k e r ( x , y ) = { 255 , ( x , y ) ∈ B o u n d a r y 0 , o t h e r s Marker(x, y) = \left\{\begin{matrix} 255 & , & (x,y) \in Boundary\\ 0 & , & others \end{matrix}\right. M a r k e r ( x , y ) = { 2 5 5 0 ? , , ? ( x , y ) ∈ B o u n d a r y o t h e r s ?
代碼示例:
import
numpy
as
np
import
cv2
as
cv
from
matplotlib
import
pyplot
as
plt
img
=
cv
.
imread
(
"text.jpg"
)
# 二值化
imgray
=
cv
.
cvtColor
(
img
,
cv
.
COLOR_BGR2GRAY
)
imgray
[
imgray
<
100
]
=
0
imgray
[
imgray
>=
100
]
=
255
# 原圖取補得到MASK圖像
mask
=
255
-
imgray
# 構造Marker圖像
marker
=
np
.
zeros_like
(
imgray
)
marker
[
0
,
:
]
=
255
marker
[
-
1
,
:
]
=
255
marker
[
:
,
0
]
=
255
marker
[
:
,
-
1
]
=
255
marker_0
=
marker
.
copy
(
)
# 形態學重建
SE
=
cv
.
getStructuringElement
(
shape
=
cv
.
MORPH_CROSS
,
ksize
=
(
3
,
3
)
)
while
True
:
marker_pre
=
marker
dilation
=
cv
.
dilate
(
marker
,
kernel
=
SE
)
marker
=
np
.
min
(
(
dilation
,
mask
)
,
axis
=
0
)
if
(
marker_pre
==
marker
)
.
all
(
)
:
break
dst
=
255
-
marker
filling
=
dst
-
imgray
# 顯示
plt
.
figure
(
figsize
=
(
12
,
6
)
)
# width * height
plt
.
subplot
(
2
,
3
,
1
)
,
plt
.
imshow
(
imgray
,
cmap
=
'gray'
)
,
plt
.
title
(
'src'
)
,
plt
.
axis
(
"off"
)
plt
.
subplot
(
2
,
3
,
2
)
,
plt
.
imshow
(
mask
,
cmap
=
'gray'
)
,
plt
.
title
(
'Mask'
)
,
plt
.
axis
(
"off"
)
plt
.
subplot
(
2
,
3
,
3
)
,
plt
.
imshow
(
marker_0
,
cmap
=
'gray'
)
,
plt
.
title
(
'Marker 0'
)
,
plt
.
axis
(
"off"
)
plt
.
subplot
(
2
,
3
,
4
)
,
plt
.
imshow
(
marker
,
cmap
=
'gray'
)
,
plt
.
title
(
'Marker'
)
,
plt
.
axis
(
"off"
)
plt
.
subplot
(
2
,
3
,
5
)
,
plt
.
imshow
(
dst
,
cmap
=
'gray'
)
,
plt
.
title
(
'dst'
)
,
plt
.
axis
(
"off"
)
plt
.
subplot
(
2
,
3
,
6
)
,
plt
.
imshow
(
filling
,
cmap
=
'gray'
)
,
plt
.
title
(
'Holes'
)
,
plt
.
axis
(
"off"
)
plt
.
show
(
)
選用不同尺寸的SE,進行填充對比:ksize=3x3(左),ksize=7x7(右)
由此可見, 如果選擇的結構單元過大,膨脹操作會越過邊界,膨脹到孔洞中,導致部分孔洞填充失敗。就本例來看3x3的SE可以做到準確填充。
并且,對于大小不一的孔洞,3x3的SE同樣可以做到準確填充。如圖所示:
注: 關于孔洞填充的其他問題,可以參考博文 形態學填充孔洞的幾個問題
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

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