画像から赤い色を抽出しようとしています。指定した範囲の値のみを残すためにしきい値を適用するコードがあります:
img=cv2.imread('img.bmp')
img_hsv=cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower_red = np.array([0,50,50]) #example value
upper_red = np.array([10,255,255]) #example value
mask = cv2.inRange(img_hsv, lower_red, upper_red)
img_result = cv2.bitwise_and(img, img, mask=mask)
しかし、私がチェックしたように、赤は範囲、たとえば0〜10、および170〜180の範囲のHue値を持つことができます。したがって、これら2つの範囲のいずれかの値を残します。しきい値を10から170に設定し、cv2.bitwise_not関数を使用してみましたが、すべての白色も取得できます。最善のオプションは、各範囲のマスクを作成し、両方を使用することだと思うので、先に進む前にどうにかしてそれらを結合する必要があります。
OpenCVを使用して2つのマスクを結合する方法はありますか?または、目標を達成できる他の方法はありますか?
編集。あまりエレガントではありませんが、実用的なソリューションが付属しています:
image_result = np.zeros((image_height,image_width,3),np.uint8)
for i in range(image_height): #those are set elsewhere
for j in range(image_width): #those are set elsewhere
if img_hsv[i][j][1]>=50 \
and img_hsv[i][j][2]>=50 \
and (img_hsv[i][j][0] <= 10 or img_hsv[i][j][0]>=170):
image_result[i][j]=img_hsv[i][j]
それは私のニーズをほぼ満たし、OpenCVの関数はおそらくほぼ同じですが、それを行うためのより良い方法があれば(専用関数を使用して、より少ないコードを書く)私と共有してください。 :)
マスクを一緒に追加して、np.where
元の画像をマスクします。
img=cv2.imread("img.bmp")
img_hsv=cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# lower mask (0-10)
lower_red = np.array([0,50,50])
upper_red = np.array([10,255,255])
mask0 = cv2.inRange(img_hsv, lower_red, upper_red)
# upper mask (170-180)
lower_red = np.array([170,50,50])
upper_red = np.array([180,255,255])
mask1 = cv2.inRange(img_hsv, lower_red, upper_red)
# join my masks
mask = mask0+mask1
# set my output img to zero everywhere except my mask
output_img = img.copy()
output_img[np.where(mask==0)] = 0
# or your HSV image, which I *believe* is what you want
output_hsv = img_hsv.copy()
output_hsv[np.where(mask==0)] = 0
これは、画像の各ピクセルをループするよりもはるかに高速で読みやすいはずです。
これで遊ぶ。
#blurring and smoothin
img1=cv2.imread('marathon.png',1)
hsv = cv2.cvtColor(img1,cv2.COLOR_BGR2HSV)
#lower red
lower_red = np.array([0,50,50])
upper_red = np.array([10,255,255])
#upper red
lower_red2 = np.array([170,50,50])
upper_red2 = np.array([180,255,255])
mask = cv2.inRange(hsv, lower_red, upper_red)
res = cv2.bitwise_and(img1,img1, mask= mask)
mask2 = cv2.inRange(hsv, lower_red2, upper_red2)
res2 = cv2.bitwise_and(img1,img1, mask= mask2)
img3 = res+res2
img4 = cv2.add(res,res2)
img5 = cv2.addWeighted(res,0.5,res2,0.5,0)
kernel = np.ones((15,15),np.float32)/225
smoothed = cv2.filter2D(res,-1,kernel)
smoothed2 = cv2.filter2D(img3,-1,kernel)
cv2.imshow('Original',img1)
cv2.imshow('Averaging',smoothed)
cv2.imshow('mask',mask)
cv2.imshow('res',res)
cv2.imshow('mask2',mask2)
cv2.imshow('res2',res2)
cv2.imshow('res3',img3)
cv2.imshow('res4',img4)
cv2.imshow('res5',img5)
cv2.imshow('smooth2',smoothed2)
cv2.waitKey(0)
cv2.destroyAllWindows()