Обнаружение цвета с помощью трекбара и нахождение контура желаемого цвета
Я хочу использовать трекбар, чтобы выбрать желаемый цвет, а затем получить контур с его координатами x и y. Когда я запускаю код, я получаю следующую ошибку:
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'
Входное изображение для определения контура двоичное, поэтому я не знаю, что я здесь делаю не так. И это код, который я использую:
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()
Может ли кто-нибудь помочь мне с этой проблемой, большое спасибо!
1 ответ
Проблема в том, что вы не передаете серое изображение в findCountours, которое требуется. Чтобы решить эту проблему, вы должны преобразовать res после операции bitwise_and в оттенки серого:
<!-- 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()
Результат: