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つの引数を取ります。
img_array_1
: 配列形式の画像 1 のデータ。img_array_2
: 配列形式の画像 2 のデータ。destination_array
: 入力配列と同じサイズとタイプの出力画像。 これはオプションのパラメーターです。マスキング
: これは、結果の画像に対して実行されるマスク操作です。 これはオプションのパラメーターです。
以下の例を参考に、bitwise_and()
を使用してマスキングがどのように機能するかを見てみましょう。
ロゴの画像と車の画像の 2つの画像があり、車の画像の左上にロゴを追加する必要があるとします。 したがって、これを実現するために、OpenCV を使用して Python で以下のコードを記述します。
まず、logo
と car
の両方の画像を読み取り、それらをそれぞれ img1
変数と img2
変数に割り当てる必要があります。 マスキングにより、ROI を使用して、車の画像の左上にロゴを適用または表示します。
このために、ロゴの img2
から row
、cols
、および channels
データを抽出します。 このロゴを車の画像の左上隅に配置したいので、以下に示すように、img1
(0,0) 座標に img2
の rows
と cols
を適用します。
コードスニペット:
# 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()
この後、ロゴのマスクと反転マスクを作成する必要があります。 このために、最初にロゴの背景色を灰色に変更し、これを使用してマスクと逆マスク イメージを mask
と mask_inv
として作成しました。
画像の背景色を変更するには、cvtColor()
メソッドを使用し、マスクを作成するには、threshold()
メソッドを使用します。 最後に、bitwise_not()
を使用して画像を反転します。
mask
および mask_inv
画像に対して imshow()
関数を使用して、マスキング中に何が変更されたかを調べることもできます。
次に、ROI のロゴの領域を黒く塗りつぶし、bitwise_and()
を実行して、ロゴの背景、つまり img2
を取得します。 同様に、ロゴ画像からロゴのみを取得し、bitwise_and()
を実行して、車の画像の前景、つまり img1
を取得します。
ここで、img1
(車の画像) と img2
(ロゴの画像) の画像に対して imshow()
関数を使用して、どの部分が変更されたかを確認することもできます。
ここで、img1
と img2
の両方を追加して、ROI に車の背景を持つロゴを取得します。 次に、この出力画像を dst
に入れます。
出力:
後で車の画像全体に dst
を追加し、imshow()
を使用して最終出力を取得します。 これが、ROI を使用して画像の特定の部分を取得し、それを別の画像に追加して最終的な画像を取得する方法です。
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