形態学的処理
一般的に使用される形態学的処理方法には、腐食、膨張、開操作、閉操作、トップハット操作、ボトムハット操作があり、その中で腐食と膨張が最も基本的な方法であり、他の方法はこの2つの組み合わせによって生成されます。
腐食
構造要素:平滑化操作と同様に、長方形の近傍が平滑化操作で使用され、近傍は、形態学的処理で長方形の構造、または楕円形または十字形の構造にすることができます。また、アンカーポイントを指定する必要があります。
腐食作業では、構造要素の最小値がアンカーポイントの値として使用されます。腐食操作は、グレースケール画像またはバイナリ画像で実行できます。次の図を例として取り上げます(すべて中心点をアンカーポイントとします)。
上の3つの図の近傍の最小値はそれぞれ11、21、21です。これらの最小値は画像のアンカーポイント位置に出力され、構造を移動することで完全な出力画像を取得できます。要素などは他の位置にあります。
上の図からわかるように、各場所の近傍の最小値が取られているため、腐食後の出力画像の全体的な明るさの平均値は、元の画像のそれよりも低くなります。画像の明るい領域は小さくなり、さらには消えます。暗い領域の領域は増加します。
画像が腐食した後、輝度領域の領域が減少するため、しきい値セグメンテーション後の前景の白いバイナリ画像の場合、元の画像と腐食した画像を差し引くことで前景の境界を取得できます。
OpenCV機能
// 腐蚀
// C++
void cv::erode(InputArray src,
OutputArray dst,
InputArray kernel,
Point anchor = Point(-1,-1),
int iterations = 1,
int borderType = BORDER_CONSTANT,
const Scalar & borderValue = morphologyDefaultBorderValue()
)
// Python
dst=cv.erode(src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]])
パラメータの説明:
パラメータ | 説明 |
---|---|
src | 入力行列、グレースケール画像またはバイナリ画像 |
dst | 出力行列 |
カーネル | 構造要素。getStructuringElement関数で取得できます。 |
アンカー | アンカーポイントの位置。デフォルト値(-1、-1)は、アンカーポイントが構造要素の中心にあることを意味します。 |
反復 | 腐食の数 |
borderType | 境界拡張タイプ |
borderValue | 境界の拡張 |
一般的に使用されるborderTypesは、BORDER_CONSTANT、BORDER_REPLICATE、およびBORDER_REFLECTです。BORDER_CONSTANTは定数拡張、BORDER_REPLICATEは境界複製拡張、BORDER_REFLECTはミラー拡張です。
GetStructuringElement関数の公式アドレス
// 获取结构元
// C++
Mat cv::getStructuringElement(int shape,
Size ksize,
Point anchor = Point(-1,-1)
)
// Python:
retval = cv.getStructuringElement( shape, ksize[, anchor])
パラメータ | 説明 |
---|---|
形状 | 構造要素の形状 |
ksize | 構造要素のサイズ |
アンカー | 構造要素アンカー |
構造要素の形状
-
MORPH_RECT
構造要素
-
MORPH_CROSS
構造要素
-
MORPH_ELLIPSE
楕円形の構造要素
Pythonの例
import cv2 as cv
if __name__ == '__main__':
img_src = cv.imread("img2.jpg", 0)
# 创建矩形结构元
kernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5))
# 腐蚀图像
img_erode = cv.erode(img_src, kernel)
# 边界提取
img_edge = img_src - img_erode
cv.imwrite("./images/img2_src.jpg", img_src)
cv.imwrite("./images/img2_erode.jpg", img_erode)
cv.imwrite("./images/img2_edge.jpg", img_edge)
バイナリグラフの腐食
しきい値セグメンテーション後の画像には、必然的に散発的なホワイトノイズが多く含まれ、腐食によって除去される可能性があります。上の図からわかるように、腐食した構造要素が大きいほど、ターゲットオブジェクトの領域(白い領域)は小さくなります。画像が繰り返し腐食すると、ターゲットオブジェクト全体が削除されます。
グレースケールへの腐食
グレースケール画像の腐食、構造要素のサイズが大きくなると、暗いグレースケール領域の面積も大きくなり、明るいグレースケール領域の面積が小さくなり、処理後の効果が漠然と見えます。構造要素、つまり、モザイク効果のように見える多くの重なり合う長方形の。楕円または十字形の構造要素が侵食に使用される場合、同様の楕円または十字形も表示されます。
うねり
拡張操作では、構造要素の最大値がアンカーポイントの値として使用されます。グレースケールまたはバイナリイメージに対して拡張操作を実行できます。拡大後、出力画像の全体的な明るさの平均値は元の画像と比較して増加し、画像の明るい領域の領域は大きくなり、暗い領域の領域は減少します。
OpenCV機能
// 膨胀
// C++
void cv::dilate(InputArray src,
OutputArray dst,
InputArray kernel,
Point anchor = Point(-1,-1),
int iterations = 1,
int borderType = BORDER_CONSTANT,
const Scalar & borderValue = morphologyDefaultBorderValue()
)
// Python:
dst =cv.dilate(src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]])
パラメータは腐食操作のパラメータと同じです。
Pythonの例
次に、プログレスバーを使用して構造の半径を調整し、構造要素のサイズが形態学的処理に与える影響を観察します。
import cv2 as cv
def change_dilate_r(r):
# 创建结构元
kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, (2 * r + 1, 2 * r + 1))
# 腐蚀图像
img_dilate = cv.dilate(img_src, kernel)
# 显示膨胀效果
cv.imshow('dilate', img_dilate)
if __name__ == '__main__':
img_src = cv.imread("img5.jpg", 0)
# 显示原图
cv.imshow("src", img_src)
# 结构元半径
r = 1
max_r = 20
# 显示膨胀效果的窗口
cv.namedWindow('dilate', 1)
# 调节结构元半径
cv.createTrackbar('r', 'dilate', r, max_r, change_dilate_r)
change_dilate_r(0)
cv.waitKey(0)
開操作と閉操作
オープン操作拡張前の腐食はオープン操作と呼ばれ、明るさの高い小さな領域を除去し、デリケートなポイントでオブジェクトを分離し、領域を大幅に変更することなく大きなオブジェクトの境界を滑らかにする機能があります。
閉じた操作は、最初に拡張してから腐食し、閉じた操作と呼ばれます。白いオブジェクトの小さなブラックホールを埋め、隣接するオブジェクト、同じ構造要素を接続し、複数の反復を行い、領域を大幅に変更せずに境界を平滑化する機能があります。
開操作と閉操作は膨張と腐食の組み合わせであり、侵食と膨張の機能を使用して実行できます。OpenCVは直接使用する機能も提供します。
OpenCV機能
// C++
void cv::morphologyEx(InputArray src,
OutputArray dst,
int op,
InputArray kernel,
Point anchor = Point(-1,-1),
int iterations = 1,
int borderType = BORDER_CONSTANT,
const Scalar & borderValue = morphologyDefaultBorderValue()
)
// Python:
dst =cv.morphologyEx(src, op, kernel[,dst[,anchor[,iterations[,borderType[, borderValue]]]]])
パラメータ | 説明 |
---|---|
オン | 形態学的操作の種類 |
カーネル | 構造要素。getStructuringElement関数で取得できます。 |
アンカー | アンカーポイントの位置。デフォルト値(-1、-1)は、アンカーポイントが構造要素の中心にあることを意味します。 |
反復 | 反復回数 |
borderType | 境界拡張のタイプ。腐食を参照してください。 |
borderValue | 境界膨張値、腐食を参照 |
形態学的操作のopタイプ
- MORPH_ERODE腐蚀侵食
- MORPH_DILATE拡張
- MORPH_OPENオープン操作(最初に腐食、次に膨張)
- MORPH_CLOSEクローズ操作(展開してから腐食)
- MORPH_GRADIENT形態学的勾配
- MORPH_TOPHATシルクハットの計算
- MORPH_BLACKHATボトムハットの計算
Pythonの例
プログレスバーを使用して、構造の半径と反復回数を調整し、構造要素のサイズが形態学的処理に与える影響を観察します。
import cv2 as cv
def nothing(*args):
pass
if __name__ == '__main__':
img_src = cv.imread("img1.jpg", 0)
r, i = 1, 1
max_r, max_i = 20, 20
cv.namedWindow('morphology', 1)
cv.createTrackbar('r', 'morphology', r, max_r, nothing)
cv.createTrackbar('i', 'morphology', i, max_i, nothing)
while True:
r = cv.getTrackbarPos('r', 'morphology')
i = cv.getTrackbarPos('i', 'morphology')
kernel = cv.getStructuringElement(cv.MORPH_RECT, (2*r+1, 2*r+1))
# img_open = cv.morphologyEx(img_src, cv.MORPH_OPEN, kernel, iterations=i)
# cv.imshow('morphology', img_open)
img_erode = cv.erode(img_src, kernel, iterations=i)
cv.imshow('morphology', img_erode)
ch = cv.waitKey(5)
if ch==27:
break
elif ch==115:
# cv.imwrite(f'./images/img1_{i}.jpg', img_open)
cv.imwrite(f'./images/img1_{i}.jpg', img_erode)
cv.destroyAllWindows()
上の図は、バイナリグラフでの開操作(上流)と腐食(下流)の処理効果を示しています.3x3の長方形構造要素を使用して、1、5、および20回の反復を順番に実行します。反復回数が増えると、開く操作によって白いオブジェクトの周りの小さくて明るい領域が削除され、白いオブジェクトの領域は大幅に変化せず、境界は局所的に滑らかになります。ただし、腐食操作を行うと、オブジェクトの面積が小さくなるか、消えることさえあります。拡張操作を複数回使用すると、白いオブジェクトの面積が徐々に増加します。
オープン操作には、非常に重要な機能もあります。暗い背景の下の明るい領域を削除します。下の図に示すように、目的は、黒いボールの領域を変更せずに、ボールの白い領域を削除することです。腐食操作はボールの面積を増やし、開操作はボールの面積が増えるのを防ぐことができます。
下の図に示すように、閉じた操作の目的は、サイコロの黒い領域を削除することです。拡張と閉鎖の両方の操作を行うことができますが、拡張はサイコロの面積を増やしますが、閉鎖操作はできません。
トップハット変換、ボトムハット変換および形態学的勾配
トップハット変換とボトムハット変換は、それぞれオープン操作とクローズ操作に基づいています
トップハット変換オープン操作の結果から元の画像が差し引かれます。開く操作では、暗い背景の下の明るい領域を削除できるため、元の画像から開いた操作の結果を差し引くと、元の画像の明るいグレースケール領域が得られるため、ホワイトトップハットとも呼ばれます。変換。不均一な照明を修正できます。
ボトムハットは、閉じる操作の結果を差し引くことにより、元の画像を変換します。閉じた操作では、明るい背景の下の暗い領域が削除される可能性があるため、閉じた操作の結果を元の画像から差し引くと、元の画像の暗いグレースケール領域を取得できるため、黒とも呼ばれます帽子の変形。
形態学的勾配膨張の結果から腐食の結果を差し引いたもの。膨張は近傍で最大値を取り、高輝度領域の面積を増やすことであり、腐食は近傍で最小値を取り、高輝度領域領域。したがって、結果の画像は画像内のオブジェクトの境界になります。
Pythonの例
import cv2 as cv
def nothing(*args):
pass
if __name__ == '__main__':
img_src = cv.imread("/img5.jpg", 0)
r, i = 1, 1
max_r, max_i = 20, 20
type = 0
max_type = 2
cv.namedWindow("morphology", 1)
cv.createTrackbar('r', 'morphology', r, max_r, nothing)
cv.createTrackbar('i', 'morphology', i, max_i, nothing)
cv.createTrackbar('t', 'morphology', type, max_type, nothing)
m_type = cv.MORPH_TOPHAT
while True:
r = cv.getTrackbarPos('r', 'morphology')
i = cv.getTrackbarPos('i', 'morphology')
t = cv.getTrackbarPos('t', 'morphology')
if t==0:
m_type = cv.MORPH_TOPHAT
elif t==1:
m_type = cv.MORPH_BLACKHAT
else:
m_type = cv.MORPH_GRADIENT
kernel = cv.getStructuringElement(cv.MORPH_RECT, (2*r+1, 2*r+1))
img_mor = cv.morphologyEx(img_src, m_type, kernel, iterations=i)
cv.imshow('morphology', img_mor)
ch = cv.waitKey(5)
if ch == 27:
break
elif ch == 115:
cv.imwrite(f'./images/img_{t}.jpg', img_mor)
cv.destroyAllWindows()
次の図は、3x3の長方形構造要素を使用した12回のシルクハット操作の結果、3x3の長方形構造要素を使用した10回のボトムハット操作の結果、および形態学的勾配操作の結果を示しています。