Vscode で OpenCV 画像処理 1 (しきい値処理、形態学的操作 [接続性、侵食と拡張、開閉操作、トップハットとブラックハット、カーネル]) を学習しています。

1. 閾値処理

阈值:指的是某一个范围内,不可逾越,不能低于的值。

たとえば、しきい値を 127 に設定すると、次のようになります。
 127 より大きい値を持つ画像内のすべてのピクセルの値を 255 に設定します。
 ピクセル値が 127 以下の画像内のすべてのピクセルの値を 0 に設定します。

ここに画像の説明を挿入します

1.1 OpenCV は、しきい値処理を実装するための関数 cv2.threshold()および関数 cv2.adaptiveThreshold(),を提供します

cv2.threshold() と cv2.adaptiveThreshold() は、OpenCV でしきい値処理を実装するために使用される 2 つの関数であり、それらの違いは次のとおりです。

1.1.1. cv2.threshold():

この関数は、グローバルなしきい値処理方法です。入力イメージをバイナリ イメージに変換し、ピクセル値をユーザーが指定したしきい値と比較し、比較に基づいてピクセルを指定の最大値または最小値に設定します。構文は次のとおりです。

retval, threshold_image = cv2.threshold(src, threshold_value, max_value, threshold_type)

で:

  • retval は返されたしきい値を表します。
  • Threshold_image は、元の画像と同じサイズとタイプを持つ閾値分割結果画像を表します。
  • src: 入力イメージ、シングルチャネル グレースケール イメージ、8 ビットまたは 32 ビット浮動小数点値。
  • Threshold_value: ピクセル値を比較するためのしきい値。
  • max_value: ピクセル値がしきい値より大きい場合に設定されるピクセル値。
  • Threshold_type: しきい値のタイプ。しきい値の処理方法を指定するために使用されます。

ここに画像の説明を挿入します

(1) 関数cv2.threshold()では、パラメータthreshold_typeで閾値処理方法を指定します。次のオプションのしきい値タイプがあります:
  • cv2.THRESH_BINARY: ピクセル値がしきい値より大きい場合は最大値に設定され、それ以外の場合は 0 に設定されます。

8 ビット イメージの最大値は 255 です。したがって、8 ビット グレースケール画像を 2 値化する場合、しきい値が 127 に設定されている場合、次のようになります。  127 を超えるすべてのピクセルは 255 として処理されます。  残りの値は 0 として扱われます。


  • cv2.THRESH_BINARY_INV: cv2.THRESH_BINARY とは逆に、ピクセル値がしきい値より大きい場合は 0 に設定され、それ以外の場合は最大値に設定されます。

ピクセルの二値化防止しきい値処理方法は次のとおりです。
 グレー値がしきい値より大きいピクセルの場合、その値を 0 に設定します。
 グレー値がしきい値以下のピクセルの場合、その値を 255 に設定します。

  • cv2.THRESH_TRUNC: ピクセル値がしきい値より大きい場合はしきい値に設定し、それ以外の場合は変更しないままにします。

切り捨てしきい値処理:
たとえば、しきい値が 127 として選択されている場合、切り捨てしきい値処理中は次のようになります。
 ピクセル値を持つピクセルの場合127 ポイントより大きい場合、そのピクセル値は 127 に設定されます。
 ピクセル値が 127 以下のピクセルの場合、ピクセル値は変更されたままになります。

  • cv2.THRESH_TOZERO: ピクセル値がしきい値より大きい場合は変更しないままにし、それ以外の場合は 0 に設定します。

低しきい値のゼロ処理
たとえば、しきい値が 127 として選択されている場合、次のようになります。
 ピクセル値が 127 より大きいピクセルの場合、ピクセル値は変化し続けます。
 ピクセル値が 127 以下のピクセルの場合、ピクセル値は 0 に設定されます。

  • cv2.THRESH_TOZERO_INV: cv2.THRESH_TOZERO とは異なり、ピクセル値がしきい値より大きい場合は 0 に設定され、それ以外の場合は変更されません。

スーパーしきい値ゼロ処理
たとえば、しきい値が 127 として選択されている場合、次のようになります。
 ピクセル値が 127 より大きいピクセルの場合、それらの値は 0 に設定されます。
 ピクセル値が 127 以下のピクセルの場合、その値は変更されたままになります。

これらのしきい値タイプは、特定のアプリケーション要件に基づいて選択できます。たとえば、画像をバイナリ イメージ (白黒画像) に変換する場合は、cv2.THRESH_BINARY または cv2.THRESH_BINARY_INV を使用できます。画像の明るい部分だけを残し、残りを黒くしたい場合は、cv2.THRESH_TRUNC を使用します。

(2)コード
# 二值化阈值处理会将原始图像处理为仅有两个值的二值图像,
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt

x=np.random.randint(0,256,size=(4,4),dtype=np.uint8)
x

ここに画像の説明を挿入します

ret,dst=cv.threshold(x,thresh=127,maxval=255,type=cv.THRESH_BINARY)
ret=127.0
dst

ここに画像の説明を挿入します

(3)画像部分

ここに画像の説明を挿入します

ここに画像の説明を挿入します
ここに画像の説明を挿入します
逆バイナリ値
ここに画像の説明を挿入します

1.1.2. cv2.adaptiveThreshold():

この機能は適応型しきい値処理方式です。画像のさまざまな領域の統計的特性に基づいて、ピクセル セグメンテーションのしきい値を適応的に選択します。構文は次のとおりです。

このアプローチにより、画像の異なる領域で異なるしきい値を使用できるようになり、局所的な変化への適応性が向上します。

threshold_image = cv2.adaptiveThreshold(src, max_value, adaptive_method, threshold_type, block_size, constant)

で:

  • src: 入力画像、単一チャネルのグレースケール画像。
  • max_value: ピクセル値がしきい値より大きい場合に設定されるピクセル値。
  • adaptive_method: 適応しきい値アルゴリズム、オプションの値には cv2.ADAPTIVE_THRESH_MEAN_C および cv2.ADAPTIVE_THRESH_GAUSSIAN_C が含まれます。
  • Threshold_type: しきい値のタイプ。しきい値の処理方法を指定するために使用されます。
  • block_size: 閾値を計算する際に使用されるピクセル領域のサイズ。
  • 定数: 計算された平均または加重平均から減算される定数。

 cv2.ADAPTIVE_THRESH_MEAN_C: 近傍内のすべてのピクセルの重み値は一貫しています。
 cv2.ADAPTIVE_THRESH_GAUSSIAN_C: 近傍の各ピクセル ポイントから中心点までの距離に関連します。各ポイントの重み値は
を通じて取得されます。ガウス方程式。
概要:

  • cv2.threshold() は、画像内のほとんどの領域に適用されるグローバルなしきい値処理メソッドです。画像全体に同じ閾値を適用します。
  • cv2.adaptiveThreshold() は、照明条件やコントラストが異なる画像内のさまざまな領域に適した適応型しきい値処理方法です。画像の局所的な特性に基づいてしきい値を選択します。

1.2 Otsu 处理

画像処理におけるしきい値処理は、グレースケール イメージをバイナリ イメージに変換するプロセスであり、ピクセルは特定のしきい値に基づいて背景と前景の 2 つのカテゴリに分類されます。通常、二値化のしきい値は手動で選択できます。ただし、画像が異なると、適切なしきい値を選択することが困難になる場合があります。

Otsu 処理は、クラス内の分散を最小化し、クラス間の分散を最大化することにより、最適なしきい値を自動的に決定します。画像のヒストグラム情報を使用して、前景と背景を最もよく区別するしきい値を見つけます。これにより、Otsu 処理がさまざまな画像の特性にうまく適応し、より正確な結果を生成できるようになります。

OpenCV の cv2.THRESH_OTSU フラグを使用すると、Otsu 処理を簡単に適用して、画像の最適なしきい値を決定し、画像を 2 値化できます。

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('Pic/cc.jpg', 0)

# 使用Otsu's方法进行阈值处理
ret, otsu_thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

# 使用cv2.THRESH_BINARY进行阈值处理
_, binary_thresh = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)

# 使用cv2.THRESH_TRUNC进行阈值处理
_, trunc_thresh = cv2.threshold(img, 127, 255, cv2.THRESH_TRUNC)

# 使用cv2.THRESH_TOZERO进行阈值处理
_, tozero_thresh = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO)

# 绘制结果图像
plt.subplot(221), plt.imshow(img, cmap='gray')
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplot(222), plt.imshow(binary_thresh, cmap='gray')
plt.title('cv2.THRESH_BINARY'), plt.xticks([]), plt.yticks([])
plt.subplot(223), plt.imshow(otsu_thresh, cmap='gray')
plt.title('cv2.THRESH_BINARY + cv2.THRESH_OTSU'), plt.xticks([]), plt.yticks([])
plt.subplot(224), plt.imshow(tozero_thresh, cmap='gray')
plt.title('cv2.THRESH_TOZERO'), plt.xticks([]), plt.yticks([])

plt.show()

ここに画像の説明を挿入します

2. 形態素操作

形態学のカテゴリー (英語 morphology、ドイツ語 morphologie) は、ギリシャ語の morphe に由来します。ゲーテが生物学の研究で最初にこの概念を提唱しました。ゲーテがこの考えを思いついたのは、過度の合理的な分析に不満があったからです。自然科学の傾向、計画と構想。
[「形状」または「構造」を意味します。画像処理およびコンピュータ ビジョンの分野では、形態学は一般に、画像内のオブジェクトの形状と構造を分析および処理するための一連の数学的手法を指します。 】

形態学的操作の目的は、ノイズの除去、オブジェクトの接続、オブジェクトの分離など、画像の形状と構造を変更することで重要な情報を抽出することです。形態学的操作は、画像内の一連の理論的および位相的概念に基づいており、形状と構造は「構造要素」と呼ばれるテンプレートを通じて操作されます。構造要素は、フィルターに似た、事前定義された小さな形状であり、画像上で移動され、画像の対応する部分と比較されます。

形態学的演算は、画像処理、特に画像のセグメンテーション、特徴抽出、オブジェクト認識などのタスクに幅広く応用できます。侵食と膨張は形態学的操作の基本的な構成要素であり、一方、開閉操作はこれらの基本操作の組み合わせであり、より複雑な問題を解決するために使用されます。形態学的勾配演算、トップハット演算(トップハット演算)、ブラックハット演算などのさまざまな演算形式もあります。これらの操作は、さまざまな形状、サイズ、向きのオブジェクトを含む画像を処理する場合に役立ちます。

形態学的処理は、視覚検出、テキスト認識、医療画像処理、画像圧縮およびコーディングなどの分野で非常に重要な用途があります。

2.1 接続性

画像処理とコンピュータ ビジョンでは、「接続性」とはピクセル間の接続性または相互接続性を指します。これには、画像内の領域、オブジェクト、またはピクセルの集合間の接続関係が関係します。

2 つのピクセルが接続されているかどうかを判断するための条件:
(1)隣接する位置: 2 つのピクセルが存在する必要があります。つまり、画像内の位置が隣接していることになります。
(2) グレースケール値は同じまたは類似しています: グレースケール イメージの場合、グレースケール値は2 つのピクセルは通常、同じか類似している必要があります。

2.1.1 近傍種

画像において、ピクセルは分割できない最小単位であるとよく言われるからです。これは画像の特定の領域の情報を表し、そこに含まれる情報は色やグレー値に関連しており、これらの小さな正方形の配置がコンピューター ビジョンで見る「情報」を構成します。

  1. 4 隣接:
    4 隣接では、ピクセルの隣接ピクセルには上下左右の方向が含まれます。ピクセル数。これは、ピクセルが上下左右の 4 つの隣接ピクセルに隣接していることを意味します。

    像素p(x,y)的4邻域是: (x+1,y); (x-1,y); (x,y+1); (x,y-1),
    	用N4(p)表示像素p的4邻接
    
0  1  0
1  x  1   (x表示中心像素)
0  1  0
  1. 8-邻接

8隣接では、ある画素の隣接する画素には、上下左右の4方向の画素と、斜め方向の4つの画素が含まれる。これは、ピクセルが上、下、左、右、斜めに隣接する 8 つのピクセルと隣接していることを意味します。

像素p(x,y)的8邻域是: 4邻域的点 +D邻域的点,
	用Ng(p)表示像素p的8邻域连通性是描述区域和边界的重要概念
1  1  1
1  x  1   (x表示中心像素)
1  1  1
  1. 「D隣接」

通常、斜め隣接、つまり画素を中心とした上下左右の4方向に加え、斜め方向の4方向も含むものを指す。これは、上下左右および斜め方向の隣接ピクセルを同時に考慮する 8 隣接とは異なります。一方、D 隣接は特に斜め方向を指します。

像素pix,y)的D邻域是:对角上的点(x+1,y+1); (x+1,y-1); (x-1,y+1); (x-1,y-1),
	用Np(p)表示像素p的D邻域

D 隣接では、ピクセルの隣接ピクセルには次の 8 つの方向が含まれます。

1  0  1
0  x  0   (x表示中心像素)
1  0  1

2.1.2 接続の種類(3種類)

  1. 4-connected: 2 つのピクセル p と q は、q が p の 4 近傍 (上、下、左、右) にある場合、4-connected であると言われます。 。

  2. 8 連結: 2 つのピクセル p と q は、q が p の 8 近傍 (対角方向を含む) にある場合、8 連結であると言われます。

  3. m 接続: m 接続はハイブリッド接続の定義です。次の条件のいずれかが当てはまる場合、2 つのピクセル p と q は m 接続されていると言われます。

    • q は p の 4 近傍にあります (4 接続条件)。
    • q は p の D 近傍にあり、p の 4 近傍は q の 4 近傍と交差しません (つまり、共通のピクセルがないか、2 つの間に値 V を持つピクセルがありません)。

このハイブリッド接続の定義により、2 つのピクセルが 4 接続と 8 接続の条件を通じて接続されているかどうかを判断できるようになりますが、接続が有効であることを確認するために他のいくつかの制限が導入されます。一部の画像処理タスクでは、m-connectivity の定義がより柔軟になる場合があり、より大きな柔軟性が可能になります。

2.2 腐食と膨張

これら 2 つの操作は次のように理解できます。

侵食: 海岸の海水が砂の山をゆっくりと侵食して砂山を小さくするのと同じです。
拡張: 砂の山に砂を加えて大きくするようなものです。

侵食と膨張は形態学的操作の 2 つの基本操作であり、画像処理で前景と背景を調整したり、オブジェクトの形状や構造を変更したりするためによく使用されます。通常、どちらの操作も構造化要素で使用されます。

2.2.1 拡張:cv2.dilate

  • 動作原理: 構造要素をスライドさせると、画像内のハイライトされた領域が拡大され、レンダリング内のハイライトされた領域が元の画像よりも大きくなります。
  • 効果: 隣接するハイライト領域を接続し、小さなギャップを埋め、画像内の白い領域を増やします。
  • 本質: は極大値を見つける操作です。
(1) 関数のプロトタイプと使い方
cv.dilate(src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]])

cv.dilate画像の膨張に使用される OpenCV ライブラリの関数の 1 つです。膨張は、画像内のすべてのピクセル上で構造要素 (カーネルまたはカーネルとも呼ばれる) を移動して、ピクセル値をその近傍内の最大値に設定する形態学的操作の一種です。これは、オブジェクトを拡大し、オブジェクトの切断された部分を接続し、オブジェクトのエッジを強調するのに役立ちます。

次に、cv.dilate 関数の一般的な形式とパラメータの説明を示します。

  • src: 入力画像。通常はグレースケール画像です。
  • kernel: 構造要素 (カーネル)。画像上を移動する小さな行列です。長方形、楕円、十字などの形状にすることができます。 cv.getStructuringElement() を使用して、さまざまな形状やサイズの構造要素を作成できます。
  • dst: 入力画像と同じタイプおよびサイズの出力画像。指定しない場合、関数は元の画像を変更します。
  • anchor: 構造要素のアンカー ポイント。構造要素の中心位置を示し、通常は構造要素の中心です。デフォルト値は (-1, -1) で、アンカー ポイントが構造要素の中心にあることを意味します。
  • iterations: 展開の反復回数。デフォルトは 1 です。
  • borderType: 画像境界処理タイプ。デフォルトは cv.BORDER_CONSTANT で、境界を定数で埋めることを意味します。 cv.BORDER_REPLICATEcv.BORDER_REFLECT などの他のオプションも利用できます。
  • borderValue: 境界を定数でパディングするときに使用する定数値。デフォルトは 0 です。

簡単な例を次に示します。

import cv2 as cv
import numpy as np

# 读取图像
image = cv.imread('example.jpg', cv.IMREAD_GRAYSCALE)

# 创建一个 3x3 的矩形结构元素
kernel = np.ones((3, 3), np.uint8)

# 进行膨胀操作
dilated_image = cv.dilate(image, kernel, iterations=1)

# 显示原始图像和膨胀后的图像
cv.imshow('Original Image', image)
cv.imshow('Dilated Image', dilated_image)
cv.waitKey(0)
cv.destroyAllWindows()

この例では、cv.dilate 関数は、3x3 の長方形の構造要素を使用して入力画像に対して膨張操作を実行します。構造要素のサイズと形状、反復回数を調整して、必要に応じてさまざまな効果を実現できます。

(2) Pyでよく使われる3つのパラメータ
import cv2 as cv
cv.dilate(img,kernel,iterations)

カーネル - コア構造
反復 - 拡張の数、デフォルトは 1

(3) 拡張の効果を理解する

拡張操作は腐食の逆です。オブジェクトの境界を外側に一定の距離だけ拡張し、オブジェクトと接触している背景の点をオブジェクトに結合します。
オブジェクトのサイズを大きくするには、ターゲットを設定し、ターゲットの穴を埋めます。

	增大目标并添补孔洞:膨胀操作可以填充物体中的小孔洞或细小空洞。
当物体内部存在一些细小的空隙或孔洞时,膨胀操作会使物体的边界向外膨胀,将与这些孔洞相邻的背景像素合并到物体中,从而填补这些孔洞,使得目标变得更大且更完整
	将背景点合并到物体中:膨胀操作会扩张物体边界,使物体的边界向外延伸一定的距离。
在这个过程中,原本与物体接触的背景区域的像素会被合并到物体中。这意味着物体的边界会变得更加光滑,原本与背景接触的一些像素点会被认为是物体的一部分,从而扩大了物体的尺寸。

2.2.2 腐食:cv2.erode

  • 動作原理: 構造要素をスライドさせると、画像内のハイライトされた領域が縮小され、レンダリング内のハイライトされた領域が元の画像より小さくなります。
  • 効果: 小さなオブジェクト、細かい構造、ノイズを除去し、画像内の白い領域を減らします。
  • 本質: は極小値を見つける操作です。
(1) 関数のプロトタイプと使い方

cv.erode(src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]])

エロージョンは、構造要素 (コアまたはカーネルとも呼ばれる) を画像上のすべてのピクセル上で移動し、ピクセル値をその近傍内の最小値に配置する形態学的操作です。これは、画像内の小さなオブジェクトを削除し、オブジェクトの境界を滑らかにし、オブジェクトを縮小または削除するのに役立ちます。

次に、cv.erode 関数の一般的な形式とパラメータの説明を示します。

cv.erode(src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]])
  • src: 入力画像。通常はグレースケール画像です。
  • kernel: 構造要素 (カーネル)。画像上を移動する小さな行列です。長方形、楕円、十字などの形状にすることができます。 cv.getStructuringElement() を使用して、さまざまな形状やサイズの構造要素を作成できます。
  • dst: 入力画像と同じタイプおよびサイズの出力画像。指定しない場合、関数は元の画像を変更します。
  • anchor: 構造要素のアンカー ポイント。構造要素の中心位置を示し、通常は構造要素の中心です。デフォルト値は (-1, -1) で、アンカー ポイントが構造要素の中心にあることを意味します。
  • iterations: 腐食の反復回数。デフォルトは 1 です。
  • borderType: 画像境界処理タイプ。デフォルトは cv.BORDER_CONSTANT で、境界を定数で埋めることを意味します。 cv.BORDER_REPLICATEcv.BORDER_REFLECT などの他のオプションも利用できます。
  • borderValue: 境界を定数でパディングするときに使用する定数値。デフォルトは 0 です。
import cv2 as cv
import numpy as np

# 读取图像
image = cv.imread('example.jpg', cv.IMREAD_GRAYSCALE)

# 创建一个 3x3 的矩形结构元素
kernel = np.ones((3, 3), np.uint8)

# 进行腐蚀操作
eroded_image = cv.erode(image, kernel, iterations=1)

# 显示原始图像和腐蚀后的图像
cv.imshow('Original Image', image)
cv.imshow('Eroded Image', eroded_image)
cv.waitKey(0)
cv.destroyAllWindows()

この例では、cv.erode 関数は、3x3 の長方形の構造要素を使用して入力画像に対して侵食操作を実行します。構造要素のサイズと形状、反復回数を調整して、必要に応じてさまざまな効果を実現できます。

(2) Pyでよく使われる3つのパラメータ
import cv2 as cv
cv.erode(img,kernel,iterations)

カーネル - コア構造
反復 - 腐食の数、デフォルトは 1

(3) 腐食の影響を理解する
	消除边界点:腐蚀操作会将物体边界的像素“侵蚀”,也就是将物体边界向内部缩小一定的距离。
这会导致物体边界的像素被消除或减少,从而使物体整体变小。
	缩小目标:可以通过腐蚀来减小物体的大小以去除不必要的细节。
	消除小噪声点:小的噪声点会被消除掉,因为它们被看作是物体边界的一部分,随着边界的腐蚀而消失。

2.2.3 腐食および拡張コードと画像のデモンストレーション

(1) 普通

ここに画像の説明を挿入します


import numpy as  np
import cv2 as cv
import matplotlib.pyplot as plt

#1.读取图像

img = cv.imread("img/test_img.jpg")
#2.Kernel 核结构
kernel = np.ones((5, 5), np.uint8)
#3.图像的腐蚀和膨胀
erpsion = cv.erode(img, kernel)
dilate = cv.dilate(img, kernel)

fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(10, 8), dpi=100)
axes[0].imshow(img[:, :, ::-1])
axes[0].set_title("原图")

axes[1].imshow(erpsion[:, :, ::-1])
axes[1].set_title("腐蚀")

axes[2].imshow(dilate[:, :, ::-1])
axes[2].set_title("膨胀")

plt.show()

(2) 写真3枚

これらは比較用の 3 つの異なる写真で、丸で囲んだものは OpenCV のアノテーションではなく、比較のために自分で作成したマークです。
ここに画像の説明を挿入します
ここに画像の説明を挿入します
ここに画像の説明を挿入します


import numpy as  np
import cv2 as cv
import matplotlib.pyplot as plt

#1.读取图像

img = cv.imread("img/work1127.jpg")
## 腐蚀和膨胀针对于高亮区域进行的                                                                          
# img = cv.imread("img/useCvOpenxx.jpg")
# img = cv.imread("img/usecvClose.jpg")
#2.Kernel 核结构
kernel = np.ones((5, 5), np.uint8)
#3.图像的腐蚀和膨胀
erpsion = cv.erode(img, kernel)
dilate = cv.dilate(img, kernel)

fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(10, 8), dpi=100)
axes[0].imshow(img[:, :, ::-1])
axes[0].set_title("原图")

axes[1].imshow(erpsion[:, :, ::-1])
axes[1].set_title("腐蚀")

axes[2].imshow(dilate[:, :, ::-1])
axes[2].set_title("膨胀")

plt.show()

2.2.4 形態勾配: 膨張と腐食の違い

ここに画像の説明を挿入します

import numpy as  np
import cv2 as cv
import matplotlib.pyplot as plt
#1.读取图像
## 腐蚀和膨胀针对于高亮区域进行的                                                                          
img = cv.imread("img/usecvClose.jpg")
#2.Kernel 核结构
kernel = np.ones((5, 5), np.uint8)
#3.图像的腐蚀和膨胀
erpsion = cv.erode(img, kernel)
dilate = cv.dilate(img, kernel)

plt.imshow(dilate-erpsion)
plt.show()

または関数

形態学的勾配演算は、関数 cv2.morphologyEx() の演算タイプ パラメーター op を "cv2.MORPH_GRADIENT" に設定することで実装できます。その文法構造は次のとおりです。

result = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)

ここに画像の説明を挿入します

2.3 開閉動作

開閉操作は、腐食と膨張を特定の順序で処理します。ただし、この 2 つは可逆的ではありません。つまり、最初に開いてから閉じると、元のイメージを取得することはできません。

2.3.1 オープン操作

開口操作では、まず侵食し、次に拡張します。その機能は、オブジェクトを分離し、小さな領域を削除することです。特徴: 元の画像に影響を与えることなく、ノイズを除去し、小さな干渉ブロックを除去します。

オープン操作: 最初に腐食、次に拡張。元の画像の構造に影響を与えることなく、小さなノイズや干渉を除去し、オブジェクトを分離することができます
。この操作は、小さなオブジェクトの削除、境界の滑らかさ、細かい部分の削減に特に役立ちます

2.3.2 クローズ操作 クローズ

閉じる操作は開く操作の逆です。最初に膨張し、次に腐食します。
その機能は、「閉じた」オブジェクトの穴を除去することです。
特徴: 閉じた領域を埋めることができます。

クローズド操作: 最初に膨張、次に腐食。クロージャ操作は、オブジェクト内の穴を埋めたり、オブジェクト間の不連続性を接続したりするためによく使用されます。
オブジェクト内の小さな穴を塞ぎ、閉じた領域を埋めて、オブジェクトの全体的な形状を維持することができます

2.3.3 一般的な形態学的機能

(1) よく使用されるパラメータ:
import cv2 as cv
cv.morphologyEx(src, op, kernel)

src: 処理対象の画像
op: 処理方法: オープニング操作を行う場合は cv.MORPH_OPEN、クローズ操作を行う場合は
操作が実行され、 cv.MORPH_CLOSE
カーネル: コア構造 に設定されます。

(2) 完了

モルフォロジー演算は画像処理における基本的な演算であり、収縮、拡張、オープニング演算、クロージング演算などが含まれます。 OpenCV には、一般的なモルフォロジー操作関数 cv.morphologyEx があり、腐食、拡張、オープニング操作、クロージング操作など、さまざまな形式のモルフォロジー操作を実行できます。

cv.morphologyEx(src, op, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]])
  • src: 入力画像。通常はグレースケール画像です。

  • op: 形態素演算のタイプ。次のいずれかになります。

    • cv.MORPH_ERODE: 腐食
    • cv.MORPH_DILATE: 拡大
    • cv.MORPH_OPEN:オープン動作
    • cv.MORPH_CLOSE: クローズド動作
    • cv.MORPH_GRADIENT: 勾配演算
    • cv.MORPH_TOPHAT: シルクハット作戦
    • cv.MORPH_BLACKHAT:ブラックハット作戦
  • kernel: 構造要素 (カーネル)。画像上を移動する小さな行列です。 cv.getStructuringElement() を使用して、さまざまな形状やサイズの構造要素を作成できます。

  • dst: 入力画像と同じタイプおよびサイズの出力画像。指定しない場合、関数は元の画像を変更します。

  • anchor: 構造要素のアンカー ポイント。構造要素の中心位置を示し、通常は構造要素の中心です。デフォルト値は (-1, -1) で、アンカー ポイントが構造要素の中心にあることを意味します。

  • iterations: 操作の反復回数。デフォルトは 1 です。

  • borderType: 画像境界処理タイプ。デフォルトは cv.BORDER_CONSTANT で、境界を定数で埋めることを意味します。 cv.BORDER_REPLICATEcv.BORDER_REFLECT などの他のオプションも利用できます。

  • borderValue: 境界を定数でパディングするときに使用する定数値。デフォルトは 0 です。

次に、cv.morphologyEx 関数を使用して開く操作を実行する方法を示す簡単な例を示します。

import cv2 as cv
import numpy as np

# 读取图像
image = cv.imread('example.jpg', cv.IMREAD_GRAYSCALE)

# 创建一个 3x3 的矩形结构元素
kernel = np.ones((3, 3), np.uint8)

# 进行开运算
opened_image = cv.morphologyEx(image, cv.MORPH_OPEN, kernel)

# 显示原始图像和开运算后的图像
cv.imshow('Original Image', image)
cv.imshow('Opened Image', opened_image)
cv.waitKey(0)
cv.destroyAllWindows()

操作の種類と構造要素を調整することで、拡張、閉じる操作などの他の形態学的操作を実行できます。

(3) 注意事項

ここに画像の説明を挿入します

この例では、2 回の反復によるオープン操作 (#MORPH_OPEN) は、次のように順番に適用するのと同じです。
侵食 -> 侵食 -> 拡張 -> 拡張 (その間侵食→拡大→侵食→拡大ではありません)。

2.3.4 コードとデモ

ここに画像の説明を挿入します

import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt

# 读取两张图像
imgCvOpen = cv.imread("img/useCvOpenxx.jpg")
imgCvClose = cv.imread("img/usecvClose.jpg")

# 创建核结构(这里创建了一个10x10的全为1的二维数组,作为形态学运算的核结构)
kernel = np.ones((10, 10), np.uint8)

# 执行开运算和闭运算
# 开运算:消除周围的噪点
cvOpen = cv.morphologyEx(imgCvOpen, cv.MORPH_OPEN, kernel)
# 闭运算:填充闭合区域的孔洞
cvClose = cv.morphologyEx(imgCvClose, cv.MORPH_CLOSE, kernel)

# 使用 Matplotlib 显示图像
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(10, 8))

# 显示原始图像和处理后的图像
axes[0, 0].imshow(imgCvOpen[:, :, ::-1])
axes[0, 0].set_title("imgCvOpen原图Img")
axes[0, 1].imshow(cvOpen[:, :, ::-1])
axes[0, 1].set_title("cvOpenImg")

axes[1, 0].imshow(imgCvClose[:, :, ::-1])
axes[1, 0].set_title("imgCvClose原图Img")
axes[1, 1].imshow(cvClose[:, :, ::-1])
axes[1, 1].set_title("cvCloseImg")

plt.show()

2.4 シルクハットとブラックハット

トップ ハット演算とブラック ハット演算は、形態素演算の 2 つの特殊な形式であり、通常、画像の細部の強調とオブジェクトの検出に使用されます。

2.4.1 トップハット変換

「オープン操作」の元画像と結果画像の違い

dst=tophat(src,element)=src-open(src,element)

ここに画像の説明を挿入します

トップハット演算は、元の画像とオープニング演算の差であり、通常、画像内のノイズを除去するために使用されます。トップハット操作は、画像内の小さな明るい領域を強調表示し、細部を強調するのに役立ちます。

礼帽运算是原始图像与开运算结果之差的操作,

の数式は dst = tophat(src, element) = src - open(src, element) です。
元の画像の周囲の領域よりも明るい領域を強調表示します。
画像内のエッジや明るさの変化が小さい領域を強調します。
背景が比較的明るく、小さなアイテムや特定の領域が暗い場合、トップハット演算を使用すると、これらの小さな暗い領域を抽出するのに役立ちます。
この演算は次の条件に依存します。選択したコア サイズ。

2.4.2 ブラックハット変換

「クローズド操作」の結果画像と元の画像の差分です。

dst=blackhat(src,element)=close(src,element)-src

ここに画像の説明を挿入します
ブラック ハット操作は、閉じた操作と元の画像の違いであり、通常、閉じた操作は画像の穴を埋めるために使用されます。ブラック ハット操作は、画像内の小さな暗い領域を強調表示し、細部を強調するのに役立ちます。

黑帽运算是闭运算结果与原始图像之差的操作,

数式は、dst = blackhat(src, element) = close(src, element) - src です。
元の画像の周囲の領域より暗い領域を強調表示し、画像内のエッジや小さな暗い領域の存在を強調します。
背景が比較的暗いが、小さな暗い領域やノイズがある場合、ブラック ハット演算を使用すると、これらの暗い領域を分離するのに役立ちます。
同様に、この演算は選択したコア サイズに依存するのと同じです。

2.4.3 コードと画像のデモ


import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt

imgOpen=cv.imread("img/useCvOpenxx.jpg")
imgClose=cv.imread("img/usecvClose.jpg")

#核结构
kernel=np.ones((10,10),dtype=np.uint8)

#礼帽和黑帽
cvOpen1=cv.morphologyEx(imgOpen,cv.MORPH_TOPHAT,kernel)
cvClose1=cv.morphologyEx(imgClose,cv.MORPH_BLACKHAT,kernel)

# 显示
fig,axes=plt.subplots(nrows=2,ncols=3,figsize=(10,8))
axes[0,0].imshow(imgOpen)
axes[0,0].set_title("imgOpen")
axes[0, 1].imshow(cvOpen[:, :, ::-1])
axes[0, 1].set_title("cvOpenImg")
axes[0,2].imshow(cvOpen1)
axes[0,2].set_title("cvOpen1")

axes[1,0].imshow(cvClose1)
axes[1,0].set_title("imgClose1")
axes[1, 1].imshow(cvClose[:, :, ::-1])
axes[1, 1].set_title("cvCloseImg")
axes[1,2].imshow(cvClose1)
axes[1,2].set_title("cvClose1")
plt.show()

ここに画像の説明を挿入します

2.5 カーネル機能

形態学的演算では、カーネル関数 (構造要素またはカーネルとも呼ばれる) は、形態学的演算の形状とサイズを定義する小さな行列です。カーネル関数が異なれば生成される効果も異なるため、目的の形態学的効果を得るには、適切なカーネル関数を選択することが非常に重要です。

OpenCV では、cv.getStructuringElement() 関数を使用して、さまざまな形状やサイズのカーネル関数を作成できます。この関数は、形態学的演算のカーネル関数として使用するために、指定された形状とサイズのバイナリ行列を返します。

次に、cv.getStructuringElement() 関数の一般的な形式を示します。

cv.getStructuringElement(shape, ksize[, anchor])
  • shape: 構造要素の形状。次のいずれかになります。
    • cv.MORPH_RECT: 長方形の構造要素
    • cv.MORPH_CROSS: 十字型構造要素
    • cv.MORPH_ELLIPSE: 楕円形の構造要素
  • ksize: 構造要素のサイズ。通常は行と列の数を指定するタプル (rows, cols) です。
  • anchor: 構造要素のアンカー ポイント。構造要素の中心位置を示し、通常は構造要素の中心です。デフォルト値は (-1, -1) で、アンカー ポイントが構造要素の中心にあることを意味します。

さまざまな形状とサイズのカーネルを作成する方法の例をいくつか示します。

import cv2 as cv
import numpy as np

# 创建一个 3x3 的矩形结构元素
rect_kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))

# 创建一个 5x5 的十字形结构元素
cross_kernel = cv.getStructuringElement(cv.MORPH_CROSS, (5, 5))

# 创建一个 7x7 的椭圆形结构元素
ellipse_kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, (7, 7))

これらのカーネル関数は、侵食、拡張、オープン操作、クローズ操作などの形態学的操作に使用できます。たとえば、これらのカーネル関数を cv.erodecv.dilatecv.morphologyEx などの関数内の kernel

微妙な変化

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties

# 读取图像
image = cv.imread('img/useCvOpenxx.jpg', cv.IMREAD_GRAYSCALE)

# 创建不同形状和大小的核函数
rect_kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))
cross_kernel = cv.getStructuringElement(cv.MORPH_CROSS, (5, 5))
ellipse_kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, (7, 7))

# 进行腐蚀操作
eroded_rect = cv.erode(image, rect_kernel)
eroded_cross = cv.erode(image, cross_kernel)
eroded_ellipse = cv.erode(image, ellipse_kernel)

# 进行膨胀操作
dilated_rect = cv.dilate(image, rect_kernel)
dilated_cross = cv.dilate(image, cross_kernel)
dilated_ellipse = cv.dilate(image, ellipse_kernel)

# 设置中文字体
font = FontProperties(fname=r"C:\Windows\Fonts\simsun.ttc", size=12)

# 显示原始图像和不同核函数下的腐蚀结果和膨胀结果
plt.figure(figsize=(12, 8))

plt.subplot(3, 3, 1), plt.imshow(image, cmap='gray'), plt.title('原始图像', fontproperties=font)

plt.subplot(3, 3, 2), plt.imshow(eroded_rect, cmap='gray'), plt.title('矩形核腐蚀', fontproperties=font)
plt.subplot(3, 3, 3), plt.imshow(dilated_rect, cmap='gray'), plt.title('矩形核膨胀', fontproperties=font)

plt.subplot(3, 3, 5), plt.imshow(eroded_cross, cmap='gray'), plt.title('十字核腐蚀', fontproperties=font)
plt.subplot(3, 3, 6), plt.imshow(dilated_cross, cmap='gray'), plt.title('十字核膨胀', fontproperties=font)

plt.subplot(3, 3, 8), plt.imshow(eroded_ellipse, cmap='gray'), plt.title('椭圆核腐蚀', fontproperties=font)
plt.subplot(3, 3, 9), plt.imshow(dilated_ellipse, cmap='gray'), plt.title('椭圆核膨胀', fontproperties=font)

plt.show()

ここに画像の説明を挿入します

おすすめ

転載: blog.csdn.net/m0_74154295/article/details/134608609