最新のpythonバインディング(cv2)でカラーイメージにマスクを適用するにはどうすればよいですか?以前のPythonバインディングでは、最も簡単な方法はcv.Copy
です。OpenCV - マスクをカラーイメージに適用する
cv.Copy(dst, src, mask)
しかし、この機能は結合CV2では使用できません。ボイラープレートコードを使用しないで回避策はありますか?
最新のpythonバインディング(cv2)でカラーイメージにマスクを適用するにはどうすればよいですか?以前のPythonバインディングでは、最も簡単な方法はcv.Copy
です。OpenCV - マスクをカラーイメージに適用する
cv.Copy(dst, src, mask)
しかし、この機能は結合CV2では使用できません。ボイラープレートコードを使用しないで回避策はありますか?
ここでは、既にマスク画像がある場合はcv2.bitwise_and
機能を使用できます。
img = cv2.imread('lena.jpg')
mask = cv2.imread('mask.png',0)
res = cv2.bitwise_and(img,img,mask = mask)
レナ画像に対して、矩形マスクのために次のように出力は次のようになります。以下のコードをチェックするため
。 ABIDラーマンKによって与え
私は同様のことをやろうとしています。マスクは黒または白でなければなりませんか?基本的な質問を申し訳ありません、私はopencvの初心者です。ありがとう –
雅、あなたは正しいです、マスクは白黒とシングルチャンネルでなければなりません。画像のどの領域を処理したいかによって、マスク内の領域は白でなければなりません。その他はすべて黒です。そして、あなたはこの質問をしても大変申し訳ありません。誰もが初心者です。 –
ありがとうAbid!私が帰ってきた今夜、私はそれを試してみるでしょう。私はいくつかの領域に画像を分割し、このプロセスをいくつかの画像に繰り返す必要があります。よろしく! –
回答は完全に正しくありません。私もそれを試して、非常に有用だが、立ち往生した。
これは、特定のマスクで画像をコピーする方法です。
x, y = np.where(mask!=0)
pts = zip(x, y)
# Assuming dst and src are of same sizes
for pt in pts:
dst[pt] = src[pt]
これは少し遅いですが、正しい結果が得られます。
編集:
Pythonic way。
idx = (mask!=0)
dst[idx] = src[idx]
Abidの答えは間違っていますか? –
cv2の "bitwise_and"メソッドが100%尋ねられたように動作するとき、ここでホイールを再作成する必要はありません。それだけでなく、それが何をするのかは非常に明白です。 –
バックグラウンドを黒色以外の色にしたい場合のソリューションです。マスクを反転して、同じサイズの背景画像に適用する必要があります。背景と前景の両方を結合します。この解決方法のプロは、背景が何か(他の画像さえも)である可能性があるということです。
この例は、Hough Circle Transformから変更されています。最初の画像はOpenCVロゴ、2番目は元のマスク、3番目はバックグラウンド+フォアグラウンドを組み合わせたものです。
# http://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_houghcircles/py_houghcircles.html
import cv2
import numpy as np
# load the image
img = cv2.imread('E:\\FOTOS\\opencv\\opencv_logo.png')
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# detect circles
gray = cv2.medianBlur(cv2.cvtColor(img, cv2.COLOR_RGB2GRAY), 5)
circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1, 20, param1=50, param2=50, minRadius=0, maxRadius=0)
circles = np.uint16(np.around(circles))
# draw mask
mask = np.full((img.shape[0], img.shape[1]), 0, dtype=np.uint8) # mask is only
for i in circles[0, :]:
cv2.circle(mask, (i[0], i[1]), i[2], (255, 255, 255), -1)
# get first masked value (foreground)
fg = cv2.bitwise_or(img, img, mask=mask)
# get second masked value (background) mask must be inverted
mask = cv2.bitwise_not(mask)
background = np.full(img.shape, 255, dtype=np.uint8)
bk = cv2.bitwise_or(background, background, mask=mask)
# combine foreground+background
final = cv2.bitwise_or(fg, bk)
注:それは彼らが最適化されているので、OpenCVのメソッドを使用することをお勧めします。
説明した他の方法は、バイナリマスクを前提としています。あなたが(例えば、アルファチャンネルから)、次の3つのチャンネルにそれを展開し、補間のためにそれを使用することができますマスクとして実数値シングルチャンネルのグレースケール画像を使用したい場合:
assert len(mask.shape) == 2 and issubclass(mask.dtype.type, np.floating)
assert len(foreground_rgb.shape) == 3
assert len(background_rgb.shape) == 3
alpha3 = np.stack([mask]*3, axis=2)
blended = alpha3 * foreground_rgb + (1. - alpha3) * background_rgb
注mask
必要があること操作が成功するためには範囲0..1
にあること。また、1.0
はフォアグラウンドのみをエンコードし、0.0
はバックグラウンドのみを保持することを意味します。
マスクは形状(h, w, 1)
を持っている可能性がある場合は、このことができます:それは(h, w)
あるとnp.squeeze(...)
が(h, w, 3, 1)
から(h, w, 3)
に結果を再形成する場合はここで
alpha3 = np.squeeze(np.stack([np.atleast_3d(mask)]*3, axis=2))
np.atleast_3d(mask)
は、マスク(h, w, 1)
になります。
あなたは何をしようとしていますか? numpyのサポートがあるので、numpyの関数を使うことができます。 –
私は元の画像にHSV色空間でいくつかのフィルタリングを行っています – pzo