使用Python和&找到红色OpenCV的
我正在尝试从图像中提取红色。我有代码应用阈值只保留指定范围内的值:
I am trying to extract red color from an image. I have code that applies threshold to leave only values from specified range:
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)
但是,正如我检查的那样,红色可以在范围内具有Hue值,假设从0到10,以及在170到180之间。因此,我想留下这两个范围中的任何一个的值。我尝试将阈值从10设置为170并使用cv2.bitwise_not函数,但随后我也获得了所有白色。我认为最好的选择是为每个范围创建一个掩码并使用它们,所以我不得不在继续之前将它们连接在一起。
But, as i checked, red can have Hue value in range, let's say from 0 to 10, as well as in range from 170 to 180. Therefore, i would like to leave values from any of those two ranges. I tried setting threshold from 10 to 170 and using cv2.bitwise_not function, but then i get all the white color as well. I think the best option would be to create a mask for each range and use them both, so I somehow have to join them together before proceeding.
有没有办法可以使用OpenCV加入两个掩码?或者还有其他方法可以实现我的目标吗?
Is there a way I could join two masks using OpenCV? Or is there some other way I could achieve my goal?
编辑。我来的不是很优雅,但工作解决方案:
Edit. I came with not much elegant, but working solution:
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的功能可能几乎完全相同,但如果有更好的方法(使用一些专用函数和写少量代码)请与我分享。 :)
It pretty much satisfies my needs, and OpenCV's functions probably do pretty much the same, but if there's a better way to do that(using some dedicated function and writing less code) please share it with me. :)
我只是将面具添加到一起,并使用 np.where
掩盖原始图像。
I would just add the masks together, and use np.where
to mask the original image.
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
这应该比l更快,更可读浏览图像的每个像素。
This should be much faster and much more readable than looping through each pixel of your image.