web-dev-qa-db-ja.com

Python&OpenCVを使用して赤色を見つける

画像から赤い色を抽出しようとしています。指定した範囲の値のみを残すためにしきい値を適用するコードがあります:

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の関数はおそらくほぼ同じですが、それを行うためのより良い方法があれば(専用関数を使用して、より少ないコードを書く)私と共有してください。 :)

16
yolo77

マスクを一緒に追加して、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

これは、画像の各ピクセルをループするよりもはるかに高速で読みやすいはずです。

20
derricw

これで遊ぶ。

#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()
0
dxVxb