在特定颜色上查找并绘制 opencv 中的最大轮廓(Python)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/44588279/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Find and draw the largest contour in opencv on a specific color (Python)
提问by Zaptimist
Im trying to get the largest contour of a red book. I've got a little problem with the code because its getting the contours of the smallest objects (blobs) instead of the largest one and I can't seem to figure out why this is happening
我试图获得一本红书的最大轮廓。我的代码有一个小问题,因为它获得了最小对象(斑点)的轮廓而不是最大的轮廓,我似乎无法弄清楚为什么会发生这种情况
The code I use:
我使用的代码:
camera = cv2.VideoCapture(0)
kernel = np.ones((2,2),np.uint8)
while True:
#Loading Camera
ret, frame = camera.read()
blurred = cv2.pyrMeanShiftFiltering(frame, 3, 3)
hsv = cv2.cvtColor(blurred, cv2.COLOR_BGR2HSV)
lower_range = np.array([150, 10, 10])
upper_range = np.array([180, 255, 255])
mask = cv2.inRange(hsv, lower_range, upper_range)
dilation = cv2.dilate(mask,kernel,iterations = 1)
closing = cv2.morphologyEx(dilation, cv2.MORPH_GRADIENT, kernel)
closing = cv2.morphologyEx(dilation, cv2.MORPH_CLOSE, kernel)
#Getting the edge of morphology
edge = cv2.Canny(closing, 175, 175)
_, contours,hierarchy = cv2.findContours(edge, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# Find the index of the largest contour
areas = [cv2.contourArea(c) for c in contours]
max_index = np.argmax(areas)
cnt=contours[max_index]
x,y,w,h = cv2.boundingRect(cnt)
cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),2)
cv2.imshow('threshold', frame)
cv2.imshow('edge', edge)
if cv2.waitKey(1) == 27:
break
camera.release()
cv2.destroyAllWindows()
As you can see on this picture
Hopefully there is someone who can help
希望有人可以提供帮助
回答by Jo?o Cartucho
You can start by defining a maskin the range of the redtones of the book you are looking for.
您可以首先在您要查找的书的红色调范围内定义一个蒙版。
Then you can just find the contour with the biggest areaand draw the rectangular shape of the book.
然后你就可以找到面积最大的轮廓并画出书的矩形形状。
import numpy as np
import cv2
# load the image
image = cv2.imread("path_to_your_image.png", 1)
# red color boundaries [B, G, R]
lower = [1, 0, 20]
upper = [60, 40, 220]
# create NumPy arrays from the boundaries
lower = np.array(lower, dtype="uint8")
upper = np.array(upper, dtype="uint8")
# find the colors within the specified boundaries and apply
# the mask
mask = cv2.inRange(image, lower, upper)
output = cv2.bitwise_and(image, image, mask=mask)
ret,thresh = cv2.threshold(mask, 40, 255, 0)
if (cv2.__version__[0] > 3):
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
else:
im2, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
if len(contours) != 0:
# draw in blue the contours that were founded
cv2.drawContours(output, contours, -1, 255, 3)
# find the biggest countour (c) by the area
c = max(contours, key = cv2.contourArea)
x,y,w,h = cv2.boundingRect(c)
# draw the biggest contour (c) in green
cv2.rectangle(output,(x,y),(x+w,y+h),(0,255,0),2)
# show the images
cv2.imshow("Result", np.hstack([image, output]))
cv2.waitKey(0)
Using your image:
使用您的图像:
If you want the book to rotate you can use rect = cv2.minAreaRect(cnt)
as you can find it here.
如果您希望这本书旋转,您可以使用,rect = cv2.minAreaRect(cnt)
因为您可以在此处找到它。
Edit:
编辑:
You should also consider other colour spaces beside the RGB, as the HSV or HLS. Usually, people use the HSV since the H channel stays fairly consistent in shadow or excessive brightness. In other words, you should get better results if you use the HSV colourspace.
您还应该考虑除 RGB 之外的其他颜色空间,如 HSV 或 HLS。通常,人们使用 HSV,因为 H 通道在阴影或过度亮度方面保持相当一致。换句话说,如果您使用 HSV 颜色空间,您应该获得更好的结果。
In specific, in OpenCV the Hue range is [0,179]
. In the following figure (made by @Knight), you can find a 2D slice of that cylinder, in V = 255
, where the horizontal axis is the H
and the vertical axis the S
. As you can see from that figure to capture the red you need both to include the lower (e.g., H=0 to H=10) and upper region (e.g., H=170 to H=179) of the Hue values.
具体来说,在 OpenCV 中,色调范围是[0,179]
. 在下图中(由@Knight 制作),您可以在 中找到该圆柱体的 2D 切片V = 255
,其中水平轴是H
,垂直轴是S
。从该图中可以看出,要捕捉红色,您需要同时包含色调值的较低(例如,H=0 到 H=10)和较高的区域(例如,H=170 到 H=179)。