opencv - Detection of color with a trackbar and finding the contour of the desired color
问题描述
I want to use a trackbar to select the desired color and than get the contour with the x and y coordinates of it. When i run the code i get the next error:
contours, _ = cv2.findContours(bin, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cv2.error: OpenCV(4.2.0) C:\projects\opencv-python\opencv\modules\imgproc\src\contours.cpp:197: error:
(-210:Unsupported format or combination of formats) [Start]FindContours supports only CV_8UC1 images when mode != CV_RETR_FLOODFILL otherwise supports CV_32SC1 images only in function 'cvStartFindContours_Impl'
The input image for detecting the contour is binary so i dont know what im doing wrong here. And this is the code im using:
import cv2
import numpy as np
def nothing(x):
pass
cv2.namedWindow("Tracking")
cv2.createTrackbar("LH", "Tracking", 0, 255, nothing)
cv2.createTrackbar("LS", "Tracking", 0, 255, nothing)
cv2.createTrackbar("LV", "Tracking", 0, 255, nothing)
cv2.createTrackbar("UH", "Tracking", 255, 255, nothing)
cv2.createTrackbar("US", "Tracking", 255, 255, nothing)
cv2.createTrackbar("UV", "Tracking", 255, 255, nothing)
while True:
frame = cv2.imread('3blobs.jpg',1)
font = cv2.FONT_HERSHEY_COMPLEX
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
l_h = cv2.getTrackbarPos("LH", "Tracking")
l_s = cv2.getTrackbarPos("LS", "Tracking")
l_v = cv2.getTrackbarPos("LV", "Tracking")
u_h = cv2.getTrackbarPos("UH", "Tracking")
u_s = cv2.getTrackbarPos("US", "Tracking")
u_v = cv2.getTrackbarPos("UV", "Tracking")
l_b = np.array([l_h, l_s, l_v])
u_b = np.array([u_h, u_s, u_v])
mask = cv2.inRange(hsv, l_b, u_b)
res = cv2.bitwise_and(frame, frame, mask=mask)
trash, bin = cv2.threshold(res, 227, 255, 1, cv2.THRESH_BINARY)
# Detecting contours in image.
contours, _ = cv2.findContours(bin, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# Going through every contours found in the image.
for cnt in contours:
approx = cv2.approxPolyDP(cnt, 0.009 * cv2.arcLength(cnt, True), True)
# draws boundary of contours.
cv2.drawContours(frame, [approx], 0, (0, 0, 255), 2)
# Used to flatted the array containing
# the co-ordinates of the vertices.
n = approx.ravel()
i = 0
for j in n:
if (i % 2 == 0):
x = n[i]
y = n[i + 1]
# String containing the co-ordinates.
string = str(x) + " " + str(y)
if (i == 0):
# text on topmost co-ordinate.
cv2.putText(frame, "Arrow tip", (x, y),
font, 0.5, (255, 0, 0))
else:
# text on remaining co-ordinates.
cv2.putText(frame, string, (x, y),
font, 0.5, (0, 255, 0))
i += 1
#cv2.imshow("frame", frame)
#cv2.imshow("mask", mask)
cv2.imshow("res", res)
cv2.imshow("bin", bin)
key = cv2.waitKey(1)
if key == 27:
break
cv2.destroyAllWindows()
Can someone help me with this issue thanks a lot!
解决方案
问题是您没有将灰色图像传递给 findCountours,这是必需的。要解决它,您必须在 bitwise_and 操作后将 res 转换为灰度:
<!-- language: python -->
gray = cv2.cvtColor(res, cv2.COLOR_BGR2GRAY)
trash, bin = cv2.threshold(gray, 227, 255, 1, cv2.THRESH_BINARY)
完整代码:
import cv2
import numpy as np
def nothing(x):
pass
cv2.namedWindow("Tracking")
cv2.createTrackbar("LH", "Tracking", 0, 255, nothing)
cv2.createTrackbar("LS", "Tracking", 0, 255, nothing)
cv2.createTrackbar("LV", "Tracking", 0, 255, nothing)
cv2.createTrackbar("UH", "Tracking", 255, 255, nothing)
cv2.createTrackbar("US", "Tracking", 255, 255, nothing)
cv2.createTrackbar("UV", "Tracking", 255, 255, nothing)
while True:
frame = cv2.imread('3Blobs.jpg', 1)
font = cv2.FONT_HERSHEY_COMPLEX
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
l_h = cv2.getTrackbarPos("LH", "Tracking")
l_s = cv2.getTrackbarPos("LS", "Tracking")
l_v = cv2.getTrackbarPos("LV", "Tracking")
u_h = cv2.getTrackbarPos("UH", "Tracking")
u_s = cv2.getTrackbarPos("US", "Tracking")
u_v = cv2.getTrackbarPos("UV", "Tracking")
l_b = np.array([l_h, l_s, l_v])
u_b = np.array([u_h, u_s, u_v])
mask = cv2.inRange(hsv, l_b, u_b)
res = cv2.bitwise_and(frame, frame, mask=mask)
gray = cv2.cvtColor(res, cv2.COLOR_BGR2GRAY)
trash, bin = cv2.threshold(gray, 227, 255, 1, cv2.THRESH_BINARY)
# Detecting contours in image.
contours, _ = cv2.findContours(bin, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# Going through every contours found in the image.
for cnt in contours:
approx = cv2.approxPolyDP(cnt, 0.009 * cv2.arcLength(cnt, True), True)
# draws boundary of contours.
cv2.drawContours(frame, [approx], 0, (0, 0, 255), 2)
# Used to flatted the array containing
# the co-ordinates of the vertices.
n = approx.ravel()
i = 0
for j in n:
if (i % 2 == 0):
x = n[i]
y = n[i + 1]
# String containing the co-ordinates.
string = str(x) + " " + str(y)
if (i == 0):
# text on topmost co-ordinate.
cv2.putText(frame, "Arrow tip", (x, y),
font, 0.5, (255, 0, 0))
else:
# text on remaining co-ordinates.
cv2.putText(frame, string, (x, y),
font, 0.5, (0, 255, 0))
i += 1
# cv2.imshow("frame", frame)
# cv2.imshow("mask", mask)
cv2.namedWindow('res', cv2.WINDOW_NORMAL)
cv2.namedWindow('bin', cv2.WINDOW_NORMAL)
cv2.imshow("res", res)
cv2.imshow("bin", bin)
key = cv2.waitKey(1)
if key == 27:
break
cv2.destroyAllWindows()
结果:
推荐阅读
- python - nested list comprehension to achieve nested lists
- asp.net - IIS 中的 ASP.NET 模拟
- c++ - 下面的代码,是格式错误的 NDR 还是格式正确?
- ansible - Ansible 中用于端口转发的多个 ssh 命令
- python - 在 Windows 上在后台线程上接收 zmq 消息失败
- ios - How to stop navigation bar title from changing color when moving from controller to controller
- php - 更改语法 ul、li、span
- javascript - 如何解决 postgres 中的散列问题
- sms - Jasmin:MT 路由到 http api
- django - django 过滤器 - 如何从 3 列中搜索电话号码