本文的形态学仅考虑对二值图像的处理。处理多灰度级图形,使用灰度级形态学,本文不讲。
基本操作
-
二值图像: Z 2 Z^2 Z2的子集,集合元素是二元组 ( x , y ) (x,y) (x,y)
-
反射: B ^ = { w ∣ w = − b , b ∈ B } \hat B = \{ w|w=-b,\, b\in B \} B^={w∣w=−b,b∈B},就是关于原点旋转 180 ° 180 \degree 180°
-
平移: ( B ) z = { c ∣ c = b + z , b ∈ B } (B)_z = \{ c|c=b+z,\, b \in B \} (B)z={c∣c=b+z,b∈B}
-
补集: B c = { b ∣ b ∉ B } B^c = \{ b| b \not \in B \} Bc={b∣b∈B}
-
结构元 (SE):一个小集合。一般以结构重心为原点,用0表示该位置不属于SE,用1表示该位置属于SE,用-1表示该位置属于不属于SE不关心。一般的,要将结构元填充至最小矩形,例如,
[ − 1 1 − 1 1 1 1 − 1 1 − 1 ] , [ 1 − 1 − 1 1 0 − 1 1 − 1 − 1 ] , [ 0 0 0 − 1 1 − 1 1 1 1 ] \begin{bmatrix} -1 & 1 & -1\\ 1 & 1 & 1\\ -1 & 1 & -1\\ \end{bmatrix} ,\, \begin{bmatrix} 1 & -1 & -1\\ 1 & 0 & -1\\ 1 & -1 & -1\\ \end{bmatrix} ,\, \begin{bmatrix} 0 & 0 & 0\\ -1 & 1 & -1\\ 1 & 1 & 1\\ \end{bmatrix} ⎣⎡−11−1111−11−1⎦⎤,⎣⎡111−10−1−1−1−1⎦⎤,⎣⎡0−110110−11⎦⎤ -
腐蚀: A ⊖ B = { z ∣ ( B ) z ⊆ A } = { z ∣ ( B ) z ∩ A c = ∅ } A \ominus B = \{ z|(B)_z \sube A \} =\{ z|(B)_z \cap A^c = \emptyset \} A⊖B={z∣(B)z⊆A}={z∣(B)z∩Ac=∅}
对二值图形做收缩、细化。
[ 0 0 0 0 0 0 1 1 1 0 0 1 1 1 0 0 1 1 1 0 0 0 0 0 0 ] ⊕ [ 1 − 1 − 1 1 1 − 1 1 1 − 1 ] = [ 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 ] \begin{aligned} \left[ \begin{array}{cc|c|cc} 0 & 0 & 0 & 0 & 0\\ 0 & 1 & 1 & 1 & 0\\ \hline 0 & 1 & 1 & 1 & 0\\ \hline 0 & 1 & 1 & 1 & 0\\ 0 & 0 & 0 & 0 & 0\\ \end{array} \right] \oplus \begin{bmatrix} 1 & -1 & -1\\ 1 & 1 & -1\\ 1 & 1 & -1\\ \end{bmatrix} \\= \left[ \begin{array}{cc|c|cc} 0 & 0 & 0 & 0 & 0\\ 0 & 0 & 0 & 0 & 0\\ \hline 0 & 0 & 1 & 1 & 0\\ \hline 0 & 0 & 0 & 0 & 0\\ 0 & 0 & 0 & 0 & 0\\ \end{array} \right] \end{aligned} ⎣⎢⎢⎢⎢⎡0000001110011100111000000⎦⎥⎥⎥⎥⎤⊕⎣⎡111−111−1−1−1⎦⎤=⎣⎢⎢⎢⎢⎡0000000000001000010000000⎦⎥⎥⎥⎥⎤
腐蚀,仅保留完全匹配SE的位置。 -
膨胀: A ⊕ B = { z ∣ [ ( B ^ ) z ∩ A ] ⊆ A } = { z ∣ ( B ^ ) z ∩ A ≠ ∅ } A \oplus B = \{ z|[(\hat B)_z \cap A] \sube A \} = \{ z|(\hat B)_z \cap A \not = \emptyset \} A⊕B={z∣[(B^)z∩A]⊆A}={z∣(B^)z∩A=∅} (注意做了反射)
对二值图形做增长、粗化。
[ 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 ] ⊕ [ 1 − 1 − 1 1 1 − 1 1 1 − 1 ] = [ 0 0 0 0 0 0 1 0 0 0 0 1 1 0 0 0 1 1 0 0 0 0 0 0 0 ] \begin{aligned} \left[ \begin{array}{cc|c|cc} 0 & 0 & 0 & 0 & 0\\ 0 & 0 & 0 & 0 & 0\\ \hline 0 & 0 & 1 & 0 & 0\\ \hline 0 & 0 & 0 & 0 & 0\\ 0 & 0 & 0 & 0 & 0\\ \end{array} \right] \oplus \begin{bmatrix} 1 & -1 & -1\\ 1 & 1 & -1\\ 1 & 1 & -1\\ \end{bmatrix} \\= \left[ \begin{array}{cc|c|cc} 0 & 0 & 0 & 0 & 0\\ 0 & 1 & 0 & 0 & 0\\ \hline 0 & 1 & 1 & 0 & 0\\ \hline 0 & 1 & 1 & 0 & 0\\ 0 & 0 & 0 & 0 & 0\\ \end{array} \right] \end{aligned} ⎣⎢⎢⎢⎢⎡0000000000001000000000000⎦⎥⎥⎥⎥⎤⊕⎣⎡111−111−1−1−1⎦⎤=⎣⎢⎢⎢⎢⎡0000001110001100000000000⎦⎥⎥⎥⎥⎤
膨胀,在孤立点附近得到与SE相同的结构。 -
对偶性: ( A ⊖ B ) c = A c ⊕ B ^ (A \ominus B)^c = A^c \oplus \hat B (A⊖B)c=Ac⊕B^, ( A ⊕ B ) c = A c ⊖ B ^ (A \oplus B)^c = A^c \ominus \hat B (A⊕B)c=Ac⊖B^
-
在做运算之前,都需要在 A A A上下左右填充至少 B B B宽度的背景,保证结果正确。
高级操作
-
开操作: A ∘ B = ( A ⊖ B ) ⊕ B A \circ B = (A \ominus B) \oplus B A∘B=(A⊖B)⊕B,先腐蚀后膨胀
将结构元B视作圆球,那么开操作就是圆球B在图形A内部边界滚动所能达到的所有位置的内部: A ∘ B = ∪ z { ( B ) z ∣ ( B ) z ⊆ A } A \circ B = \cup_z \{ (B)_z|(B)_z \sube A \} A∘B=∪z{(B)z∣(B)z⊆A}
-
闭操作: A ∙ B = ( A ⊕ B ) ⊖ B A \bullet B = (A \oplus B) \ominus B A∙B=(A⊕B)⊖B,先膨胀后腐蚀
将结构元B视作圆球,那么闭操作就是圆球B在图形A外部边界滚动所能达到的所有位置的内部: A ∘ B = ∪ z { ( B ) z ∣ ( B ) z ∩ A ≠ ∅ } A \circ B = \cup_z \{ (B)_z|(B)_z \cap A \not = \empty \} A∘B=∪z{(B)z∣(B)z∩A=∅}
-
开操作,断开直径小于结构元直径的桥接,去除背景里的亮噪声,让凸棱角圆滑
-
闭操作,弥合距离小于结构元直径的间隙,去除图形里的暗噪声,让凹棱角圆滑
-
先执行开操作,再执行闭操作:去除二值图像里的椒盐噪声 (同时会稍微破坏原始图形)
-
若结构元是不含0的方块,性质:
- A ∘ B ⊆ A ⊆ A ∙ B A \circ B \sube A \sube A \bullet B A∘B⊆A⊆A∙B
- 若 C ⊆ D C \sube D C⊆D,那么: C ∘ B ⊆ D ∘ B , C ∙ B ⊆ D ∙ B C \circ B \sube D \circ B,\, C \bullet B\sube D \bullet B C∘B⊆D∘B,C∙B⊆D∙B
- ( A ∘ B ) ∘ B = A ∘ B (A \circ B) \circ B = A \circ B (A∘B)∘B=A∘B, ( A ∙ B ) ∙ B = A ∙ B (A \bullet B) \bullet B = A \bullet B (A∙B)∙B=A∙B
-
A − A ∘ B A - A \circ B A−A∘B,就是宽度小于 B B B直径的桥接、亮噪声、凸棱角。
-
A ∙ B − A A \bullet B - A A∙B−A,就是宽度小于 B B B直径的间隙、暗噪声、凹棱角。
-
击中或击不中变换 (hit or miss): A ⊛ B = ( A ⊖ B 1 ) ∩ ( A c ⊖ B 2 ) A \circledast B = (A \ominus B_1) \cap (A^c \ominus B_2) A⊛B=(A⊖B1)∩(Ac⊖B2),其中 B = ( B 1 , B 2 ) , B 1 ∩ B 2 = ∅ B=(B_1,B_2),\, B_1 \cap B_2 = \empty B=(B1,B2),B1∩B2=∅
也就是说, B 1 B_1 B1完全命中 A A A,同时 B 2 B_2 B2完全不命中 A A A
-
假如 B 2 = W − B 1 B_2 = W-B_1 B2=W−B1, W W W是略大于 B 1 B_1 B1的小窗口,则 A ⊗ B A \otimes B A⊗B在 A A A中定位出 B 1 B_1 B1图形的位置 (要求每个图形都被1像素宽的背景包围)。
-
一般我们仅对结构元的模式匹配感兴趣,而不考虑背景运算。令 B 2 = ∅ B_2 = \empty B2=∅,则 A ⊛ B A \circledast B A⊛B弱化为 A ⊖ B 1 A \ominus B_1 A⊖B1,只有击中 (匹配前景),没有不击中 (匹配背景)。
-
根据对偶性, A ⊛ B = ( A ⊖ B 1 ) ∩ ( A ⊕ B ^ 2 ) c A \circledast B = (A \ominus B_1) \cap (A \oplus \hat B_2)^c A⊛B=(A⊖B1)∩(A⊕B^2)c
形态学算法
-
边界提取: β ( A ) = A − ( A ⊖ B ) \beta(A) = A-(A \ominus B) β(A)=A−(A⊖B),用腐蚀掉的部分作为边界
-
孔洞填充: X 0 X_0 X0是所有待填充孔洞中的某一点,做带约束的膨胀 X k = ( X k − 1 ⊕ B ) ∩ A c X_k = (X_{k-1}\oplus B) \cap A^c Xk=(Xk−1⊕B)∩Ac,迭代到 X k = X k − 1 X_k=X_{k-1} Xk=Xk−1 (填满所有的孔洞),结果为 X k ∪ A X_k \cup A Xk∪A
-
提取连通分量: X 0 X_0 X0是所有待提取连通分量中的某一点,做带约束的膨胀 X k = ( X k − 1 ⊕ B ) ∩ A X_k = (X_{k-1}\oplus B) \cap A Xk=(Xk−1⊕B)∩A,迭代到 X k = X k − 1 X_k=X_{k-1} Xk=Xk−1 (包含所提取的连通分量),结果为 X k X_k Xk
-
若集合 A A A内任意两点间的直线段都在 A A A内部,则称 A A A是凸形的。任意集合 S S S的凸壳 H H H是包含 S S S的最小凸集, H − S H-S H−S叫做凸缺。
-
生成凸壳:做关于4个结构元的迭代, X k i = ( X k i ⊛ B i ) ∪ A , X 0 i = A X_k^i = (X_k^i \circledast B^i) \cup A,\,X_0^i=A Xki=(Xki⊛Bi)∪A,X0i=A,迭代到 X k i = X k − 1 i X_k^i=X_{k-1}^i Xki=Xk−1i
其中的击中或不击中变换 ⊛ \circledast ⊛仅对前景做匹配。
结构元为:
B 1 = [ 1 − 1 − 1 1 0 − 1 1 − 1 − 1 ] ( 让 图 形 A 向 右 凸 出 ) \begin{aligned} B^1 = \begin{bmatrix} 1 & -1 & -1\\ 1 & 0 & -1\\ 1 & -1 & -1\\ \end{bmatrix} (让图形A向右凸出) \end{aligned} B1=⎣⎡111−10−1−1−1−1⎦⎤(让图形A向右凸出)
以及它的 90 ° , 180 ° , 270 ° 90\degree,180\degree,270\degree 90°,180°,270°旋转。
凸壳近似为: C ( A ) = ( ∪ i X k i ) ∩ H C(A) = (\cup_i X_k^i) \cap H C(A)=(∪iXki)∩H,其中 H H H是包含 A A A的最小矩形。 -
细化: A ⊗ B = A − ( A ⊛ B ) = A ∩ ( A ⊛ B ) c A \otimes B = A-(A \circledast B) = A \cap (A \circledast B)^c A⊗B=A−(A⊛B)=A∩(A⊛B)c;对于结构元序列,令 A ⊗ { B i } = A ⊗ B 1 ⊗ ⋯ ⊗ B n A \otimes \{B^i\} = A \otimes B^1 \otimes \cdots \otimes B^n A⊗{Bi}=A⊗B1⊗⋯⊗Bn
其中的击中或不击中变换 ⊛ \circledast ⊛仅对前景做匹配。
常用的8个结构元为:
B 1 = [ 0 0 0 − 1 1 − 1 1 1 1 ] ( 匹 配 图 形 A 上 方 的 厚 边 界 ) B 2 = [ − 1 0 0 1 1 0 1 1 − 1 ] ( 匹 配 图 形 A 右 上 的 厚 边 界 ) \begin{aligned} B^1 = \begin{bmatrix} 0 & 0 & 0\\ -1 & 1 & -1\\ 1 & 1 & 1\\ \end{bmatrix} (匹配图形A上方的厚边界) \\ B^2 = \begin{bmatrix} -1 & 0 & 0\\ 1 & 1 & 0\\ 1 & 1 & -1\\ \end{bmatrix} (匹配图形A右上的厚边界) \end{aligned} B1=⎣⎡0−110110−11⎦⎤(匹配图形A上方的厚边界)B2=⎣⎡−11101100−1⎦⎤(匹配图形A右上的厚边界)
以及它们的 90 ° , 180 ° , 270 ° 90\degree,180\degree,270\degree 90°,180°,270°旋转。X 0 = A , X k = X k − 1 ⊗ { B i } X_0 = A,\,X_k = X_{k-1} \otimes \{B^i\} X0=A,Xk=Xk−1⊗{Bi},迭代到 X k = X k − 1 X_k = X_{k-1} Xk=Xk−1,细化结果为 X k X_k Xk,它不含 2 × 2 2 \times 2 2×2的全1方块,并保持连通性不变。
-
粗化: A ⊙ B = A + ( A ⊛ B ) = A ∪ ( A ⊛ B ) A \odot B = A + (A \circledast B) = A \cup (A \circledast B) A⊙B=A+(A⊛B)=A∪(A⊛B);对于结构元序列,令 A ⊙ { B i } = A ⊙ B 1 ⊙ ⋯ ⊙ B n A \odot \{B^i\} = A \odot B^1 \odot \cdots \odot B^n A⊙{Bi}=A⊙B1⊙⋯⊙Bn
常用的8个结构元为:
B 1 = [ 1 1 1 − 1 0 − 1 0 0 0 ] ( 匹 配 图 形 A 下 方 的 细 边 界 ) B 2 = [ − 1 1 1 0 0 1 0 0 − 1 ] ( 匹 配 图 形 A 左 下 的 细 边 界 ) \begin{aligned} B^1 = \begin{bmatrix} 1 & 1 & 1\\ -1 & 0 & -1\\ 0 & 0 & 0\\ \end{bmatrix} (匹配图形A下方的细边界) \\ B^2 = \begin{bmatrix} -1 & 1 & 1\\ 0 & 0 & 1\\ 0 & 0 & -1\\ \end{bmatrix} (匹配图形A左下的细边界) \end{aligned} B1=⎣⎡1−101001−10⎦⎤(匹配图形A下方的细边界)B2=⎣⎡−10010011−1⎦⎤(匹配图形A左下的细边界)
以及它们的 90 ° , 180 ° , 270 ° 90\degree,180\degree,270\degree 90°,180°,270°旋转。X 0 = A , X k = X k − 1 ⊙ { B i } X_0 = A,\,X_k = X_{k-1} \odot \{B^i\} X0=A,Xk=Xk−1⊙{Bi},迭代到 X k = X k − 1 X_k = X_{k-1} Xk=Xk−1,粗化结果为 X k X_k Xk
-
用细化实现粗化:对 A c A^c Ac做细化,把细化结果求补,再去掉孤立点,作为粗化结果。
-
骨架:令 S k ( A ) = ( A ⊖ k B ) − ( A ⊖ k B ) ∘ B S_k(A) = (A \ominus kB) - (A \ominus kB) \circ B Sk(A)=(A⊖kB)−(A⊖kB)∘B, A ⊖ k B A \ominus kB A⊖kB表示连续腐蚀。 K = max { k ∣ ( A ⊖ k B ) ≠ ∅ } K = \max\{k|(A \ominus kB) \not = \empty\} K=max{k∣(A⊖kB)=∅},骨架为 S ( A ) = ∪ k = 0 K S k ( A ) S(A) = \cup_{k=0}^K S_k(A) S(A)=∪k=0KSk(A)
-
可以从骨架完全恢复图形: A = ∪ k = 0 K [ S k ( A ) ⊕ k B ] A = \cup_{k=0}^K [S_k(A) \oplus kB] A=∪k=0K[Sk(A)⊕kB]
-
端点检测: X i = A ⊛ B i X^i = A \circledast B^i Xi=A⊛Bi,其中 A A A是某图形的细化结果。
常用的8个结构元为:
B 1 = [ − 1 0 0 1 1 0 − 1 0 0 ] ( 匹 配 图 形 A 的 右 侧 端 点 ) B 2 = [ 1 0 0 0 1 0 0 0 0 ] ( 匹 配 图 形 A 的 右 下 端 点 ) \begin{aligned} B^1 = \begin{bmatrix} -1 & 0 & 0\\ 1 & 1 & 0\\ -1 & 0 & 0\\ \end{bmatrix} (匹配图形A的右侧端点) \\ B^2 = \begin{bmatrix} 1 & 0 & 0\\ 0 & 1 & 0\\ 0 & 0 & 0\\ \end{bmatrix} (匹配图形A的右下端点) \end{aligned} B1=⎣⎡−11−1010000⎦⎤(匹配图形A的右侧端点)B2=⎣⎡100010000⎦⎤(匹配图形A的右下端点)
以及它们的 90 ° , 180 ° , 270 ° 90\degree,180\degree,270\degree 90°,180°,270°旋转。 -
测地膨胀:对于二值图像 F ⊆ G F \sube G F⊆G,选取 B B B,定义为 D G 1 ( F ) : = ( F ⊕ B ) ∩ G D_G^1(F) := (F \oplus B) \cap G DG1(F):=(F⊕B)∩G, D G n ( F ) : = D G 1 ( D G n − 1 ( F ) ) D_G^n(F) := D_G^1(D_G^{n-1}(F)) DGn(F):=DG1(DGn−1(F));膨胀结果不大于 G G G; G G G拥有若干连通分量。
-
测地腐蚀:对于二值图像 F , G F,\,G F,G,选取 B B B,定义为 E G 1 ( F ) : = ( F ⊖ B ) ∪ G E_G^1(F) := (F \ominus B) \cup G EG1(F):=(F⊖B)∪G, E G n ( F ) : = E G 1 ( E G n − 1 ( F ) ) E_G^n(F) := E_G^1(E_G^{n-1}(F)) EGn(F):=EG1(EGn−1(F));腐蚀结果不小于 G G G
-
裁剪:对于某图形的细化结果 A A A,令 X 1 = A ⊗ k { B i } X_1 = A \otimes k\{B^i\} X1=A⊗k{Bi},使用端点检测的结构元序列 { B i } \{B^i\} {Bi},做 k k k次细化,可将长度小于等于 k k k的毛刺消除,但也消除了长度大于 k k k的线段的线头部分。令 X 2 = ∩ i [ X 1 ⊛ B i ] X_2 = \cap_i [X_1 \circledast B^i] X2=∩i[X1⊛Bi],可得到所有的端点。再 X 3 = D A k ( X 2 ) X_3 = D_A^k(X_2) X3=DAk(X2),从端点开始进行 k k k次测地膨胀,以恢复长度大于 k k k的线段的线头部分。最后的裁剪结果为 X 1 ∪ X 3 X_1 \cup X_3 X1∪X3,去除了毛刺,也保留了主要线段。
-
形态学重建:
膨胀的形态学重建: R G D ( F ) : = D G k ( F ) , D G k ( F ) = D G k + 1 ( F ) R_G^D(F):=D_G^k(F),\,D_G^k(F)=D_G^{k+1}(F) RGD(F):=DGk(F),DGk(F)=DGk+1(F)
腐蚀的形态学重建: R G E ( F ) : = E G k ( F ) , E G k ( F ) = E G k + 1 ( F ) R_G^E(F):=E_G^k(F),\,E_G^k(F)=E_G^{k+1}(F) RGE(F):=EGk(F),EGk(F)=EGk+1(F)
-
重建开操作: O R n ( F ) = R F D ( F ⊖ n B ) O_R^n(F) = R_F^D(F \ominus nB) ORn(F)=RFD(F⊖nB);先n次腐蚀,再测地膨胀到稳定状态。用途:提取包含长竖线的英文字母 (L,B,P,T,…), B B B是长竖线形状的全1阵列。
-
重建闭操作: C R n ( F ) = R F E ( F ⊕ n B ) C_R^n(F) = R_F^E(F \oplus nB) CRn(F)=RFE(F⊕nB);先n次膨胀,再测地腐蚀到稳定状态。用途: B B B是全1方阵,弥合图形内的小于 B B B直径的小孔洞,并保持大于 B B B直径的孔洞轮廓以及图形外轮廓。
-
提取边界图形:二值图像 F F F,那么 H = R F D ( E ) H = R_F^D(E) H=RFD(E)就是所有触碰到图像边缘的连通分量,其中 E E E是 F F F最外侧轮廓 (非外侧轮廓的位置都为0)
-
自适应的孔洞填充:包含孔洞的二值图像 F F F,那么 H = [ R F c D ( E ) ] c H=[R_{F^c}^D(E)]^c H=[RFcD(E)]c就是填充结果,其中 E E E是 F F F最外侧轮廓的补 (非外侧轮廓的位置都为0)
-
粒度检测:对于包含若干不同直径圆形的图像,我们使用直径从小到大的结构元 { B i } \{B^i\} {Bi},对图像做开操作 X i = A ∘ B i X^i = A \circ B^i Xi=A∘Bi,计算 X i X^i Xi的灰度和 (开操作的灰度和,称作表面区域,随结构元增大而减小)。做出"结构元直径-表面区域"的图像,然后计算它的一阶差分的图像;一阶差分中的峰值处,对应图像里的主要粒度。