記事ディレクトリ
1: 形態学の基礎
形態学: 画像処理の基本的な手法であり、画像内の形状と構造を分析して処理するために使用されます。形態学は数学的形態学の理論に基づいており、構造要素と形態学的操作を使用して、画像内の形状、境界、テクスチャなどの特徴を変更および抽出します。
形態学的操作: 画像の分析と認識の目的を達成するために、構造要素を使用して画像コレクションを操作し、画像のさまざまな部分間の関係を観察し、分析と説明に役立つ特徴を抽出します。以下は一般的な形態学的演算です。
- 拡張
- 侵食
- オープニング
- 閉鎖
- 当たり外れのある変換
(1) 構成要素
構造要素: 形態素演算における重要な概念であり、形態素演算において画像との畳み込み演算に使用される小さな固定形状のテンプレートまたはウィンドウです。構造要素は、長方形、円、十字などのさまざまな形状にすることができ、どの形状を選択するかは、必要な操作とアプリケーションのシナリオによって異なります。構造要素のサイズと形状は、形態学的演算の結果に重要な影響を与えます。構造要素が小さいほど、画像内の詳細や小規模な特徴をより適切に捉えることができますが、構造要素が大きいほど、より大きなターゲットを含む操作に適しています。通常、構造要素はバイナリ イメージとして定義され、前景ピクセルは構造要素の形状を表し、背景ピクセルは構造要素の外部を表します。
構造要素を選択するときは、次の原則に従う必要があります。
- 構造要素の幾何学的構造は、元の画像よりも単純で境界があり、サイズはターゲット画像のサイズよりも大幅に小さくなります。
- 構造要素の形状は、ある程度の凸部を有することが好ましい。
- 構造要素ごとに、形態学的操作に参加する構造要素の「基準点」として原点が指定されます。
すべての形態学的処理は、構造要素を埋めるという概念に基づいています。いわゆる塗りつぶしは、さまざまな方法を使用して元の画像内に構造要素を配置し、構造要素の塗りつぶしにおいて一連の画像特性を誘導します。異なる構造要素と異なる形態学的変換により、異なる画像処理結果が生成される可能性があります。
(2) 手順
以下のように: ダイヤモンド型の構造要素を生成します。
MATLAB の実装:
strel
関数とは、形態画像処理の演算に使用される構造要素を作成するために使用される関数です。構造要素はstrel
、指定された形状とサイズに従って関数によって作成され、拡張、収縮、開く操作、閉じる操作などの形態学的操作に使用できます。その構文形式は次のとおりです
se = strel(shape, parameters)
パラメータ
-
shape
パラメータは構造要素の形状を指定し、次の形式のいずれかになります。'square'
: 正方形の構造要素'rectangle'
: 長方形の構造要素'disk'
: 円形構造要素'line'
:線状構造要素
-
parameters
パラメータはオプションであり、選択した形状に応じて、構造要素のサイズまたはその他の特定のパラメータを指定します。
strel
se
この関数は、画像に対して形態学的操作を実行するために使用できる構造要素オブジェクトを返します。構造要素オブジェクトには、拡張 ( dilate
)、収縮 ( erode
)、開始操作 ( open
)、終了操作 ( close
) などの一般的に使用されるメソッドがいくつかあります。これらのメソッドを呼び出して、対応する形態学的操作を実行できます。
SE = strel('diamond',3);
GN=getnhood(SE)%获取结构元素的邻域
figure,imshow(GN,[]);
Python の実装:
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 创建一个菱形结构元素
SE = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3))
GN = SE # 获取结构元素的邻域
# 显示邻域图像
plt.imshow(GN, cmap='gray', vmin=0, vmax=1)
plt.axis('off')
plt.show()
2: バイナリモルフォロジーの基本操作
(1) 基本的なフォーム変換
A: 拡張操作
①:概要
膨張操作: 形態学的操作の基本的な操作であり、画像内の明るい領域を拡大したり、オブジェクトのサイズを大きくしたりするために使用されます。拡張操作は、構造要素を画像と畳み込むことによって実装できます。コレクションXX_X は構造要素SSS はX ⊕ S \boldsymbol{X} \oplus \boldsymbol{S}として展開されます。バツ⊕S
X ⊕ S = { x ∣ [ ( S ^ ) x ∩ X ] ≠ ∅ } \boldsymbol{X} \oplus \boldsymbol{S}=\left\{\boldsymbol{x} \mid\left[(\widehat{ \boldsymbol{S}})_{\boldsymbol{x}} \cap \boldsymbol{X}\right] \neq \varnothing\right\}バツ⊕S={ ×∣[ (S )×∩× ]=∅ }
その意味は次のとおりです: 構造要素SSの場合Sは原点を中心にマッピングされ、結果のマッピング変換はxxx 、 ( S ^ ) x (\widehat{\boldsymbol{S}})_{\boldsymbol{x}}として新しいセットを形成(S )×、セットXX付きX が交差し空集合ではないSSSの参照点の集合はXXXはSSだったSを拡張して得られる集合
拡張操作のプロセスは次のとおりです
- 構造要素SSを配置しますSの中心は画像 X のピクセル位置に配置されます
- 構造要素SS用Sの各要素XX対応する位置にゼロ以外の値 (つまり、白いピクセル) がある場合、
- 構造要素SSまでステップ 1 と 2 を繰り返します。S は画像全体をカバーしますバツ
- 最終結果の画像は画像XXを表します構造要素SSを含むXのすべての要素Sの交差ピクセルの和集合
拡張操作の効果は、画像内の境界を拡張して穴を埋め、ターゲットのサイズを大きくすることです。小さなノイズの除去、途切れた境界線の接続、画像のエッジを滑らかにするなどの用途に使用できます。
拡張オペレーションコードは次のように実装されます。
Image=imread('menu.bmp'); %打开图像
BW=im2bw(Image); %转换为二值图像
figure,imshow(BW);
[h w]=size(BW); %获取图像尺寸
result=zeros(h,w); %定义输出图像,初始化为0
for x=2:w-1
for y=2:h-1 %扫描图像每一点,即结构元素移动到每一个位置
for m=-1:1
for n=-1:1 %当前点周围3×3范围,即结构元素为3×3大小
if BW(y+n,x+m) %结构元素所覆盖3×3范围内有像素点为1,即交集不为空
result(y,x)=1; %将参考点记录为前景点
break;
end
end
end
end
end
figure,imshow(result);title('二值图像膨胀');
SE=strel('square',3); %创建结构元素
result1=imdilate(BW,SE); %膨胀运算
figure,imshow(result1);title('二值图像imdilate');
②:例
例 1 : 図 (a) は 2 値画像で、暗い「1」の部分がターゲット セットXXです× ._ 図(b)の濃い「1」の部分が構造要素SSS(「+」が付いた箇所が原点、構造要素の基準点)X ⊕ S \boldsymbol{X} \oplus \boldsymbol{S}を見つけますバツ⊕S
解決策: 図 © の暗い「1」の部分が構造要素SSです。マッピングS ^ \widehat{S} of SS 。(d)の濃い部分、このうち薄い灰色の「1」の部分が集合XXを表します。X ; 濃い灰色の「1」の部分が拡張(拡張)部分を表します。すると、暗い影の部分全体が集合X ⊕ S \boldsymbol{X} \oplus \boldsymbol{S} にバツ⊕S
例2:図(a)の濃い「1」の部分がターゲットセットXXですX、図 (b) の暗い「1」の部分は構造要素SSS。 求X ⊕ S \boldsymbol{X} \oplus \boldsymbol{S}バツ⊕S
解決策: (c) SSを変更するS はS ^ \widehat{S}にマップされますS
、S ^ \widehat{S}になりますS
XX年にX上に移動し、交差点が空でない場合の構造要素の基準点の位置を記録します (d) に示す濃い網掛けの部分が展開後の結果です。ターゲット セットの拡張後、領域が拡張されるだけでなく、隣接する 2 つの孤立したコンポーネントが接続されることがわかります。
③:プログラム
次のように
MATLAB の実装:
Image=imread('menu.bmp');
BW=im2bw(Image);
SE=strel('square',3); %创建结构元素
result=imdilate(BW,SE); %膨胀运算
figure,imshow(result);
Pythonの実装:
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 读取图像
Image = cv2.imread('menu.bmp', 0)
# 二值化处理
ret, BW = cv2.threshold(Image, 127, 255, cv2.THRESH_BINARY)
# 创建一个3x3的正方形结构元素
SE = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
# 膨胀运算
result = cv2.dilate(BW, SE)
# 显示结果图像
plt.imshow(result, cmap='gray')
plt.axis('off')
plt.show()
B: 腐食動作
①:概要
腐食操作: これは形態学的画像処理の基本的な操作であり、画像内の境界やオブジェクトの詳細を削減または除去するために使用されます。コレクションXX_X は構造要素SSSによる腐食はX ⊖ SX \ominus Sとして記録されます。バツ⊖S
X ⊖ S = { x ∣ ( S ) x ⊆ X } \boldsymbol{X} \ominus \boldsymbol{S}=\left\{\boldsymbol{x} \mid(\boldsymbol{S})_{\boldsymbol{ x}} \subseteq \boldsymbol{X}\right\}バツ⊖S={
×∣( S )×⊆X }
意味は次のとおりです: 構造要素SSスパンxx_xがコレクションXXた後XでSSを記録Sの参照点の位置、結果のセットはSS腐食XX __Xの結果
腐食オペレーションコードは次のように実装されます。
Image=imread('menu.bmp'); %打开图像
BW=im2bw(Image); %转换为二值图像
figure,imshow(BW);
[h w]=size(BW); %获取图像尺寸
result=ones(h,w); %定义输出图像,初始化为1
for x=2:w-1
for y=2:h-1 %扫描图像每一点,即结构元素移动到每一个位置
for m=-1:1
for n=-1:1 %当前点周围3×3范围,即3×3结构元素所覆盖范围
if BW(y+n,x+m)==0 %该范围内有像素点为0,即该位置不能完全包含结构元素
result(y,x)=0; %将参考点记录为背景点,即腐蚀掉
break;
end
end
end
end
end
figure,imshow(result); title('二值图像腐蚀');
SE=strel('square',3); %创建结构元素
result=imerode(BW,SE); %腐蚀运算
figure,imshow(result); title('二值图像imerode');
②:例
例:図(a)は二値画像で、濃い「1」の部分がターゲットセットXX× ._ 図(b)の濃い「1」の部分が構造要素SSS。求X ⊖ S \boldsymbol{X} \ominus \boldsymbol{S}バツ⊖S
解決策:SSの場合S基準点が図(c)の赤枠「1」内にある場合、( S ) x ⊆ (S)_x\subseteq( S )×⊆ X、次にX ⊖ SX \ominus Sバツ⊖Sは図 (d) の濃い灰色の「1」の部分です。白い「0」の部分が腐食が消えた部分です
③:プログラム
次のように
MATLAB の実装:
Image=imread('menu.bmp');
BW=im2bw(Image);
SE=strel('square',3); %创建结构元素
result=imerode(BW,SE); %腐蚀运算
figure,imshow(result);
Pythonの実装:
import cv2
import matplotlib.pyplot as plt
# 读取图像
image = cv2.imread('menu.bmp', cv2.IMREAD_GRAYSCALE)
# 二值化
ret, bw = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY)
# 创建结构元素
se = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
# 腐蚀运算
result = cv2.erode(bw, se)
# 显示结果图像
plt.imshow(result, cmap='gray')
plt.show()
膨張性と腐食性
特性 1 : 拡張操作と収縮操作は集合補数マップに関する双対関係です
( X Θ S ) c = X c ⊕ S ^ ( X ⊕ S ) c = X c S ^ \begin{array}{l}(X \Theta \boldsymbol{S})^{\boldsymbol{c}}= X^{\boldsymbol{c}} \oplus \hat{\boldsymbol{S}} \\(X \oplus \boldsymbol{S})^{\boldsymbol{c}}=X^{\boldsymbol{c}} \boldsymbol{\hat { S }}\end{配列}( X Θ S )c=バツc⊕S^( X⊕さ)c=バツcS^
特性 2 : 拡張操作は互換性がありますが、腐食操作は互換性がありません。
( X ⊕ S 1 ) ⊕ S 2 = ( X ⊕ S 2 ) ⊕ S 1 \left(X \oplus S_{1}\right) \oplus S_{2}=\left(X \oplus S_{2}\右) \oplus S_{1}( X⊕S1)⊕S2=( X⊕S2)⊕S1
特性 3 : 展開操作は結合的です
S = S 1 ⊕ S 2 の場合: X ⊕ S = X ⊕ ( S 1 ⊕ S 2 ) = ( 次のようになります: X \oplus S=X \oplus\left(S_{1} \oplus S_{2} \right)=\left(X \oplus S_{1}\right) \oplus S_{2}Sの場合=S1⊕S2、それからあります:バツ⊕S=バツ⊕( S1⊕S2)=( X⊕S1)⊕S2
特性 4 : 拡張操作と侵食操作には成長特性がある
X ⊆ Y ⇒ ( X ⊕ S ) ⊆ ( Y ⊕ S ) X ⊆ Y ⇒ ( X ⊖ S ) ⊆ ( Y ⊖ S ) \begin{array}{l}X \subseteq Y \Rightarrow(X \oplus S) \subseteq(Y \oplus S) \\X \subseteq Y \Rightarrow(X \ominus S) \subseteq(Y \ominus S)\end{配列}バツ⊆Y⇒( X⊕さ)⊆( Y⊕さ)バツ⊆Y⇒( X⊖さ)⊆( Y⊖さ)
(2) 複合形態変換
一般に、膨張と腐食は互いに逆の作用ではありません。膨張と腐食はカスケード的に使用され、新しい形態学的変化、つまり開いたり閉じたりします。
A: 開閉動作の定義
オープニング操作: 構造要素を使用して最初に画像を侵食し、次に画像を拡張します
X ∘ S = ( X ⊖ S ) ⊕ S \boldsymbol{X} \circ \boldsymbol{S}=(\boldsymbol{X} \ominus \boldsymbol{S}) \oplus \boldsymbol{S}バツ○S=( X⊖さ)⊕S
クローズド操作: 構造要素を使用して最初に画像を拡張し、次に画像を侵食します。
X ⋅ S = ( X ⊕ S ) ⊖ S \boldsymbol{X} \cdot \boldsymbol{S}=(\boldsymbol{X} \oplus \boldsymbol{S}) \ominus \boldsymbol{S}バツ⋅S=( X⊕さ)⊖S
B:開閉動作効果
オープン操作の効果:
- 小さな物体を取り除く(スパイクをフィルタリングする)
- 分離のためにオブジェクトを小さなオブジェクトに分割します (細い重なり部分を切り取ります)。
- 大きなオブジェクトの領域を大きく変えることなく境界を滑らかにします (画像の輪郭を滑らかにします)。
閉じた動作の効果:
- 物体の亀裂や穴を埋める
- 同様のオブジェクトを接続すること(短い不連続部分が重なり合う)は、接続とパッチの役割を果たします。
- 大きなオブジェクトの領域を大きく変えることなく境界を滑らかにします (画像の輪郭を滑らかにします)。
C: 開閉操作のプロパティ
特性 1 : 開始操作と終了操作の両方に成長特性がある
X ⊆ Y ⇒ { ( X ∘ S ) ⊆ Y ( X ⋅ S ) ⊆ YX \subseteq Y \Rightarrow\left\{\begin{array}{l}(X \circ S) \subseteq Y \\(X \ cdot S) \subseteq Y\end{配列}\right。バツ⊆Y⇒{ ( X○さ)⊆Y( X⋅さ)⊆や
特性 2 : 開く操作は非伸展的ですが、閉じる操作は伸展的です
X ∘ S ⊆ XX ⊆ X ⋅ S \begin{array}{l}\boldsymbol{X} \circ \boldsymbol{S} \subseteq \boldsymbol{X} \\\boldsymbol{X} \subseteq \boldsymbol{X} \cdot \boldsymbol{S}\end{配列}バツ○S⊆バツバツ⊆バツ⋅S
プロパティ 3 : 開く操作と閉じる操作は両方とも同じ優先順位を持ちます。
( X ∘ S ) ∘ S = X ∘ S ( X ⋅ S ) ⋅ S = X ⋅ S \begin{array}{l}(X \circ S) \circ S=X \circ S \\(X \cdot S) \cdot S=X \cdot S\end{配列}( X○さ)○S=バツ○S( X⋅さ)⋅S=バツ⋅S
特性 4 : 開く動作と閉じる動作の両方に二重性がある
( X ∘ S ) c = X c ⋅ S ^ ( X ⋅ S ) c = X c ∘ S ^ \begin{array}{l}(X \circ S)^{c}=X^{c} \cdot \widehat{S} \\(X \cdot S)^{c}=X^{c} \circ \widehat{S}\end{array}( X○さ)c=バツc⋅S ( X⋅さ)c=バツc○S
D:プログラム
次のように:
MATLAB の実装:
Image=imread('A.bmp');
BW=im2bw(Image);
SE=strel('square',3);
result1=imopen (BW,SE),SE);
result2=imclose(BW,SE),SE);
figure,imshow(result1) ;title('开运算');
figure,imshow(result2); ;title('闭运算');
Pythonの実装:
import cv2
import matplotlib.pyplot as plt
# 读取图像
image = cv2.imread('A.bmp', cv2.IMREAD_GRAYSCALE)
# 二值化
ret, bw = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY)
# 创建结构元素
se = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
# 开运算
result1 = cv2.morphologyEx(bw, cv2.MORPH_OPEN, se)
# 闭运算
result2 = cv2.morphologyEx(bw, cv2.MORPH_CLOSE, se)
# 显示结果图像
plt.subplot(1, 2, 1)
plt.imshow(result1, cmap='gray')
plt.title('开运算')
plt.subplot(1, 2, 2)
plt.imshow(result2, cmap='gray')
plt.title('闭运算')
plt.show()