OpenCV 拡張

Salman Mehmood 2024年2月15日
OpenCV 拡張

この記事では、OpenCV の画像内の特定のオブジェクトの境界にピクセルを追加および削除するために使用する、侵食や膨張などの形態変換の概念について説明します。

OpenCV で侵食と膨張を使用して画像に形態変換を適用する

形態変換は、バイナリイメージで実行されるイメージベースの操作です。2つの入力が必要です。1つは元のイメージで、もう 1つはカーネルです。

カーネルが操作の性質を決定します。2つの基本的な形態学的演算子は、侵食と拡張です。また、開閉などのバリエーションもあります。

例を使用して、侵食と膨張について理解しましょう。

侵食と膨張

侵食は土壌侵食と同じです。前景オブジェクトの境界を侵食します。この L の画像を考えてみましょう。ここで、白い部分は 1 番であり、OpenCV 標準の観点からは 255 番として扱うこともできます。

侵食により、特定の画像内のオブジェクトの境界にあるピクセルが削除されます。画像内のこのオブジェクト L の境界を削除した後、これは侵食を適用した後に薄くなります。

カーネルは、技術用語では 2D コンボリューションのように画像をスライドします。元の画像の 1 または 0 のピクセルは、カーネルの下のすべてのピクセルが 1 である場合にのみ、1 と見なされます。そうしないと、侵食されるかゼロになり、カーネルのサイズに応じて境界が破棄されます。

拡張は侵食の反対です。指定された画像のオブジェクトの境界にピクセルを追加します。画像の L またはオブジェクト L の境界は、拡張後に厚くなることがわかります。

技術的には、カーネルの下の少なくとも 1つのピクセルが 1 の場合、ピクセル要素は 1 であり、その結果、画像の白い領域または前景オブジェクトのサイズが増加します。

したがって、ノイズを除去したい画像がある場合は、最初に侵食操作を適用してから拡張を適用できます。これは、侵食によって白いノイズが除去されるだけでなく、オブジェクトが縮小されるためです。そのため、拡張を行い、元の画像を保持します。オブジェクトの壊れた部分を結合する場合にも役立ちます。

侵食と膨張の変動

形態学的変換には、開閉などのバリエーションがあります。オープニングは、侵食とそれに続く拡張を適用するプロセスです。クロージングは​​正反対で、拡張とそれに続く侵食を適用します。

OpenCV を使用していくつかの操作を実装しましょう。必要なライブラリをインポートする必要があります。

この行では、imread() 関数を使用して画像を読み取り、画像のパスを引数として指定し、それを imagedata_original という変数に格納しています。

imagedata_original = cv2.imread("input.png")

このコードでは、numpy``ones() 関数を使用して 5x5 ピクセルのカーネルを定義し、カーネルのデータタイプは符号なし int です。

kernel = np.ones((5, 5), np.uint8)

erode() 関数を使用して、次の行で侵食を適用します。元のイメージ、カーネル、反復など、いくつかの引数が必要です。

iterations は、侵食プロセスを実行する回数を示します。この数を増やすと、侵食の影響が大きくなります。

erosion_op = cv2.erode(imagedata_original, kernel, iterations=1)

dilate() 関数を使用して、画像オブジェクトに拡張を適用します。引数は、erode() 関数で定義されているものと似ています。

dilation_op = cv2.dilate(imagedata_original, kernel, iterations=1)

次に、morphologyEx() 関数を使用して、開く操作を適用します。この関数は、適用されるオープニング操作を示す入力イメージ MORPH_OPEN や、上記で定義したカーネルなどの引数を取ります。

opening_op = cv2.morphologyEx(imagedata_original, cv2.MORPH_OPEN, kernel)

morphologyEx() 関数に閉じる操作を適用するための次の命令を与えています。

closing_op = cv2.morphologyEx(imagedata_original, cv2.MORPH_CLOSE, kernel)

完全なソースコード:

import cv2
import numpy as np
import matplotlib.pyplot as plot

FIG = plot.figure(figsize=(6, 5))

imagedata_original = cv2.imread("input.png")

FIG.add_subplot(2, 3, 1)
plot.imshow(imagedata_original)
plot.axis("off")
plot.title("original imagge")

kernel = np.ones((5, 5), np.uint8)

erosion_op = cv2.erode(imagedata_original, kernel, iterations=1)
FIG.add_subplot(2, 3, 2)
plot.imshow(erosion_op)
plot.axis("off")
plot.title("Erossion operatiopn")

dilation_op = cv2.dilate(imagedata_original, kernel, iterations=1)
FIG.add_subplot(2, 3, 3)
plot.imshow(dilation_op)
plot.axis("off")
plot.title("Dilation operatiopn")

opening_op = cv2.morphologyEx(imagedata_original, cv2.MORPH_OPEN, kernel)
FIG.add_subplot(2, 3, 4)
plot.imshow(opening_op)
plot.axis("off")
plot.title("Opening operatiopn")

closing_op = cv2.morphologyEx(imagedata_original, cv2.MORPH_CLOSE, kernel)
FIG.add_subplot(2, 3, 5)
plot.imshow(closing_op)
plot.axis("off")
plot.title("Clossing operatiopn")

plot.tight_layout()
plot.show()

matplotlib を使用して、画像内のさまざまな操作でさまざまな出力を実行して確認してみましょう。

侵食と膨張の異なる出力

ほとんどの人は、境界からピクセルを削除したときに、侵食された画像のテキストが太く見えた理由を混乱させる可能性がありますか?オブジェクトの境界にピクセルを追加すると、拡張された画像のテキストが薄く表示される理由。

これは、OpenCV が、画像内の黒いテキストをオブジェクトとして扱うのではなく、白い部分をオブジェクト自体として扱ったためです。したがって、侵食操作を適用すると、黒の境界から白のピクセルが削除されます。これが、黒のテキストの境界が厚くなる理由です。

拡張操作は、白いピクセルを黒いテキストの境界に追加します。そのため、黒いテキストが薄くなります。

著者: Salman Mehmood
Salman Mehmood avatar Salman Mehmood avatar

Hello! I am Salman Bin Mehmood(Baum), a software developer and I help organizations, address complex problems. My expertise lies within back-end, data science and machine learning. I am a lifelong learner, currently working on metaverse, and enrolled in a course building an AI application with python. I love solving problems and developing bug-free software for people. I write content related to python and hot Technologies.

LinkedIn

関連記事 - Python OpenCV