OpenCV でのイメージ マスキング

Sahil Bhosale 2024年2月15日
OpenCV でのイメージ マスキング

画像の一部を除外してから、この除外された部分を別の画像と結合したい場合、これはマスキングを使用して行うことができます。 OpenCV では、ビット単位の AND 演算子を使用して、2つの異なる画像を 1つに結合したり、ある画像の一部を別の画像に結合したりできます。

ビット単位の AND は、通常、2つの配列/スカラー/画像の要素ごとにビット単位の論理結合を計算します。 この記事では、OpenCV ライブラリの Bitwise AND 演算子を使用して画像にマスキングを適用する方法を説明します。

ビットごとの AND 演算子を使用して OpenCV でマスキングを実行する

OpenCV ではビット単位の演算子が使用されているため、画像の一部を抽出またはフィルター処理して、画像を描写し、非四角形の ROI (関心領域) で操作できます。 OpenCV でビットごとの AND 操作を実行するには、bitwise_and() メソッドを使用します。

bitwise_and() の構文は次のとおりです。

cv.bitwise_and(img_array_1, img_array_2, destination_array, masking)

bitwise_and() メソッドは 4つの引数を取ります。

  1. img_array_1: 配列形式の画像 1 のデータ。
  2. img_array_2: 配列形式の画像 2 のデータ。
  3. destination_array: 入力配列と同じサイズとタイプの出力画像。 これはオプションのパラメーターです。
  4. マスキング: これは、結果の画像に対して実行されるマスク操作です。 これはオプションのパラメーターです。

以下の例を参考に、bitwise_and() を使用してマスキングがどのように機能するかを見てみましょう。

ロゴの画像と車の画像の 2つの画像があり、車の画像の左上にロゴを追加する必要があるとします。 したがって、これを実現するために、OpenCV を使用して Python で以下のコードを記述します。

まず、logocar の両方の画像を読み取り、それらをそれぞれ img1 変数と img2 変数に割り当てる必要があります。 マスキングにより、ROI を使用して、車の画像の左上にロゴを適用または表示します。

このために、ロゴの img2 から rowcols、および channels データを抽出します。 このロゴを車の画像の左上隅に配置したいので、以下に示すように、img1 (0,0) 座標に img2rowscols を適用します。

コードスニペット:

# import opencv
import cv2 as cv

# Loading images
img1 = cv.imread("car.jpg")
img2 = cv.imread("logo.png")

# We want to put the logo on the top-left corner, so we create ROI
rows, cols, channels = img2.shape
roi = img1[0:rows, 0:cols]

# Now create a mask of the logo and create its inverse mask, also
img2gray = cv.cvtColor(img2, cv.COLOR_BGR2GRAY)
ret, mask = cv.threshold(img2gray, 10, 255, cv.THRESH_BINARY)
mask_inv = cv.bitwise_not(mask)

# Now black out the area of the logo in ROI
img1_bg = cv.bitwise_and(roi, roi, mask=mask_inv)

# Take only the region of the logo from the logo image.
img2_fg = cv.bitwise_and(img2, img2, mask=mask)

# Put logo in ROI and modify the main image
dst = cv.add(img1_bg, img2_fg)
img1[0:rows, 0:cols] = dst

cv.imshow("mask", mask)
cv.imshow("inv_mask", mask_inv)
cv.imshow("img1_bg", img1_bg)
cv.imshow("img2_fg", img2_fg)
cv.imshow("Final image", img1)
cv.waitKey(0)
cv.destroyAllWindows()

この後、ロゴのマスクと反転マスクを作成する必要があります。 このために、最初にロゴの背景色を灰色に変更し、これを使用してマスクと逆マスク イメージを maskmask_inv として作成しました。

画像の背景色を変更するには、cvtColor() メソッドを使用し、マスクを作成するには、threshold() メソッドを使用します。 最後に、bitwise_not() を使用して画像を反転します。

mask および mask_inv 画像に対して imshow() 関数を使用して、マスキング中に何が変更されたかを調べることもできます。

次に、ROI のロゴの領域を黒く塗りつぶし、bitwise_and() を実行して、ロゴの背景、つまり img2 を取得します。 同様に、ロゴ画像からロゴのみを取得し、bitwise_and() を実行して、車の画像の前景、つまり img1 を取得します。

ここで、img1 (車の画像) と img2 (ロゴの画像) の画像に対して imshow() 関数を使用して、どの部分が変更されたかを確認することもできます。

ここで、img1img2 の両方を追加して、ROI に車の背景を持つロゴを取得します。 次に、この出力画像を dst に入れます。

出力:

OpenCV 最終出力でのイメージ マスキング

後で車の画像全体に dst を追加し、imshow() を使用して最終出力を取得します。 これが、ROI を使用して画像の特定の部分を取得し、それを別の画像に追加して最終的な画像を取得する方法です。

著者: Sahil Bhosale
Sahil Bhosale avatar Sahil Bhosale avatar

Sahil is a full-stack developer who loves to build software. He likes to share his knowledge by writing technical articles and helping clients by working with them as freelance software engineer and technical writer on Upwork.

LinkedIn

関連記事 - Python OpenCV