Ок, после всех ответов, решение одно - применять нейронку. Спасибо за рекомендации. Добрый день, давно мучаю этот алгоритм для распознавания светящихся светофоров, после использовая маски для определения цвета, можно четко увидеть цветовые области, есть ли мудрый способ добавить параметры интересующих меня областей и опеределить светофоры, по например по частоте миганий? Output:
https://drive.google.com/file/d/19u7zLxgRP0pAYezArqk9hO9VWNes8824/view?usp=sharing светофоры выделенные в paint: https://drive.google.com/file/d/1JSyB9MDhDr7PA2uhHx9e0GSBXtnzVNIU/view?usp=sharing результат поиска по цвету для горящих светофоров почти работает, но мешают обьекты которые не являються светофорами: https://drive.google.com/file/d/1_bFduuoMsh0E4cEJW3mhF-Xj_v4qQ2Rc/view?usp=sharing
_, frame = cap.read()
hsv = cv2.cvtColor(frame, cv2.COLOR_RGB2HSV)
red = np.zeros_like(frame, np.uint8)
red1 = cv2.inRange(hsv, (0, 70, 50), (10, 255, 255))
red2 = cv2.inRange(hsv, (170, 70, 50), (180, 255, 255))
mask_red1 = red > 0
mask_red2 = red2 > 0
red[mask_red1] = frame[mask_red1]
red[mask_red2] = frame[mask_red2]
im = frame.copy()
gray = cv2.cvtColor(red, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 1, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(image=thresh, mode=cv2.RETR_TREE, method=cv2.CHAIN_APPROX_NONE)
for c in contours:
approx = cv2.approxPolyDP(c, 0.04 * cv2.arcLength(c, True), True)
area = cv2.contourArea(c)
if 500 < area < 2000:
cv2.drawContours(image=im, contours=contours, contourIdx=-1, color=(0, 0, 255), thickness=-1,
lineType=cv2.LINE_AA)
cv2.imshow("im", im)
mask1 = cv2.inRange(hsv, (0, 0, 0), (179, 255, 70)) # detecting of black(mixed filter)
image_copy1 = frame.copy()
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (7, 7))
opening = cv2.morphologyEx(mask1, cv2.MORPH_OPEN, kernel, iterations=1)
close = cv2.morphologyEx(opening, cv2.MORPH_CLOSE, kernel, iterations=2) # monchrome image
circles = cv2.HoughtCircles = (frame, cv2.HOUGH_GRADIENT, 1, 300, np.array([]), 10, 30, 60, 300)
contours, h = cv2.findContours(close, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
final = np.zeros(hsv.shape, np.uint8)
mask = np.zeros(hsv.shape[:2], np.uint8)
for c in contours:
approx = cv2.approxPolyDP(c, 0.04 * cv2.arcLength(c, True), True)
area = cv2.contourArea(c)
if 1000 < area < 25000:
cv2.drawContours(image_copy1, [c], -1, (0, 255, 0), -1)
cv2.imshow("blue", image_copy1)
for i in range(0, len(contours)):
cv2.drawContours(image_copy1, contours, i, (0, 255, 0), -1)
mask[...] = 0
cv2.drawContours(mask, contours, i, 255, -1) # contours
averagecolor = cv2.mean(frame, mask)
draw_arerage_color = cv2.drawContours(final, contours, i, averagecolor, -1) # final result
cv2.imshow('final', final)
У меня мало идей как это решить… Возможно можно найти самый яркий цвет с averagecolor = cv2.mean(frame, mask), ну опять таки если программа работает все время, то нужно что то вроде if colormax < averagecolor: colormax == averagecolor, averagecolor у меня собой пердставляет что то вроде (57.26470588235294, 58.205882352941174, 60.205882352941174, 0.0), честно говоря я не до конца понимаю, что это за данные… И на счет сужения области поиска: image[a:a+height, b:b+width] где a,b =0,0, так можно обрезать картинку, но я не знаю как сделать эту область, областью для поиска…
Хотелось бы обьеденить черный и красный фильтры и получить желаемый результат. Заранее спасибо!