OpenCV での画像セグメンテーション
-
Python で
opencv
を使用した画像セグメンテーション -
opencv
を使用した画像セグメンテーションにはGrabCut
アルゴリズムを使用する -
opencv
を使用した画像セグメンテーションに色検出を使用 - まとめ
画像処理は、コンピュータビジョンタスクの重要なステップです。Python では、opencv
ライブラリを使用して、さまざまなオブジェクトやメソッドを使用していくつかの画像処理技術を実装できます。
このチュートリアルでは、Python で opencv
を使用して画像セグメンテーションを実行する方法を示します。
Python で opencv
を使用した画像セグメンテーション
画像セグメンテーションとは、特定の画像をいくつかの部分に分割するプロセスを指します。
セグメント化されたパーツの境界に沿ってポイントを結合するカーブを追加します。これらの曲線は等高線と呼ばれます。
画像セグメンテーションはコンピュータビジョンで非常に役立ち、多くの実際のアプリケーションがあります。この手法を使用して、画像の一部をセグメント化し、さまざまなオブジェクトを分類できます。
Python で opencv
を使用した画像セグメンテーションには、利用可能ないくつかの方法を使用できます。
すべての画像セグメンテーション手法で異なる主な方法は、通常、セグメント化された画像の基準に基づいています。いくつかの色の検出、Watershed アルゴリズムなどの事前定義されたアルゴリズム、エッジ検出、さらにはユーザー入力に基づいてセグメント化された部分の選択に基づいて、画像のセグメンテーションを行うことができます。
これらの方法のいくつかについては、次のセクションで説明します。
opencv
を使用した画像セグメンテーションには GrabCut
アルゴリズムを使用する
この方法では、ユーザーがマウスとキーボードを操作する必要があります。組み込みの opencv
ライブラリには、マウスとキーボードからユーザー入力を読み取ることができるオブジェクトとメソッドがあります。
GrabCut
アルゴリズムは、画像セグメンテーションのための非常にシンプルで便利なツールです。この手法では、ユーザー入力を使用して、特定の画像の一部の領域を選択します。
このアルゴリズムは、セグメント化された部分の前景と背景を自動的に検出し、それらを表示できます。
opencv
ライブラリの grabCut()
関数を使用して、このアルゴリズムを実装できます。画像セグメンテーションのために、この関数内の選択された領域のボックスと一緒に画像を渡します。
例については、次のコードを参照してください。
import cv2
import numpy as np
def algo_grabcut(img, bounding_box):
seg = np.zeros(img.shape[:2], np.uint8)
x, y, width, height = bounding_box
seg[y : y + height, x : x + width] = 1
background_mdl = np.zeros((1, 65), np.float64)
foreground_mdl = np.zeros((1, 65), np.float64)
cv2.grabCut(
img, seg, bounding_box, background_mdl, foreground_mdl, 5, cv2.GC_INIT_WITH_RECT
)
mask_new = np.where((seg == 2) | (seg == 0), 0, 1).astype("uint8")
img = img * mask_new[:, :, np.newaxis]
cv2.imshow("Output", img)
def box_draw(click, x, y, flag_param, parameters):
global x_pt, y_pt, drawing, topleft_pt, bottomright_pt, img
if click == cv2.EVENT_LBUTTONDOWN:
drawing = True
x_pt, y_pt = x, y
elif click == cv2.EVENT_MOUSEMOVE:
if drawing:
topleft_pt, bottomright_pt = (x_pt, y_pt), (x, y)
image[y_pt:y, x_pt:x] = 255 - img[y_pt:y, x_pt:x]
cv2.rectangle(image, topleft_pt, bottomright_pt, (0, 255, 0), 2)
elif click == cv2.EVENT_LBUTTONUP:
drawing = False
topleft_pt, bottomright_pt = (x_pt, y_pt), (x, y)
image[y_pt:y, x_pt:x] = 255 - image[y_pt:y, x_pt:x]
cv2.rectangle(image, topleft_pt, bottomright_pt, (0, 255, 0), 2)
bounding_box = (x_pt, y_pt, x - x_pt, y - y_pt)
algo_grabcut(img, bounding_box)
drawing = False
topleft_pt, bottomright_pt = (-1, -1), (-1, -1)
img = cv2.imread("img4.jpg")
img = cv2.resize(img, (500, 500))
image = img.copy()
cv2.namedWindow("Frame")
cv2.setMouseCallback("Frame", box_draw)
while True:
cv2.imshow("Frame", image)
ch = cv2.waitKey(1)
if ch == 32:
break
cv2.destroyAllWindows()
出力:
上記の例で何が起こっているのかを理解しましょう。
box_draw()
関数は、マウスとのユーザーインタラクションを読み取り、画像セグメンテーションの領域を選択します。ボックスと画像は、画像を取得してセグメント化された画像のバイナリマスクを作成する algo_grabcut()
関数に渡されます。
このマスクを使用して、セグメント化された部分の前景を表示します。
opencv
を使用した画像セグメンテーションに色検出を使用
Python では、色の検出に opencv
を使用できます。画像がその色を表すために使用できるさまざまな色空間があります。
この場合、HSV 色空間を使用して、特定の色の範囲を決定します。
画像のセグメンテーションには異なる色を使用します。特定の色の範囲を作成し、opencv
ライブラリの inRange()
関数を使用して、この色に一致するオブジェクトを検出します。
これにより、バイナリマスクが返されます。次に、このマスクを改良し、この検出された部分に輪郭を追加します。
前に説明したように、輪郭はセグメント化されたパーツの境界上の曲線です。findContours()
関数を使用して、作成したマスクを使用して境界線を見つけ、drawContours()
関数を使用してこれらの輪郭を描画します。
以下のコードを参照してください。
import cv2
import numpy as np
img = cv2.imread("img4.jpg")
hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
bound_lower = np.array([36, 25, 25])
bound_upper = np.array([70, 255, 255])
mask_green = cv2.inRange(hsv_img, bound_lower, bound_upper)
kernel = np.ones((7, 7), np.uint8)
mask_green = cv2.morphologyEx(mask_green, cv2.MORPH_CLOSE, kernel)
mask_green = cv2.morphologyEx(mask_green, cv2.MORPH_OPEN, kernel)
seg_img = cv2.bitwise_and(img, img, mask=mask_green)
contours, hier = cv2.findContours(
mask_green.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
)
output = cv2.drawContours(seg_img, contours, -1, (0, 0, 255), 3)
cv2.imshow("Result", seg_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
出力:
上記のコードでは、特定の画像から緑色のオブジェクトをセグメント化します。まず、cvtColor
関数を使用して画像を HSV 色空間に変換します。
次に、検出された色を保存するマスクの作成に進みます。このマスクからも不要なノイズを取り除きます。
次に、検出されたセグメントに輪郭を描画して表示します。waitKey()
関数は、画像ウィンドウが自動的に閉じるのを防ぎます。
ユーザーがキーを押してから閉じるのを待ちます。
まとめ
このチュートリアルでは、Python の opencv
ライブラリを使用した画像セグメンテーションについて説明しました。このためにいくつかの手法も実装しましたが、さらに多くの手法が可能です。
画像セグメンテーションの背後にある基本と、すべての方法でのアプローチと最終結果について説明しました。
2つの方法について詳しく説明しました。まず、GrabCut
アルゴリズムを実装しました。
このアルゴリズムでは、ユーザーはセグメンテーションに使用する領域を選択します。この部分から、前景オブジェクトを検出して表示します。
2 番目の手法では、色検出を使用しました。緑色の物体を検出しました。
このタイプのセグメンテーションでは、画像を指定された色空間に変換し、このモデルの色範囲を使用して、inRange()
関数を使用して色を検出します。このマスクを使用して、画像のセグメンテーションとエッジの周りの輪郭の描画を行います。
Manav is a IT Professional who has a lot of experience as a core developer in many live projects. He is an avid learner who enjoys learning new things and sharing his findings whenever possible.
LinkedIn