#python #opencv #image-processing #hough-transform
#python #opencv #обработка изображений #хаф-преобразование
Вопрос:
Я закончил учебник по OpenCV для поиска дорожек, и я пытаюсь применить его для поиска куска ленты на полу. Я запустил код и установил область интереса, но он находит только несколько краев ленты. Я думаю, что это связано с толщиной, но я не уверен на 100%. Любая помощь будет оценена.
import cv2
import numpy as np
import matplotlib.pyplot as plt
def canny(image):
gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
blur = cv2.GaussianBlur(gray, (5,5), 0)
canny = cv2.Canny(blur, 50, 150)
return canny
def display_lines(image, lines):
line_image = np.zeros_like(image)
if lines is not None:
for line in lines:
x1, y1, x2, y2 = line.reshape(4)
cv2.line(line_image, (x1, y1), (x2, y2), (255, 0, 0), 10)
return line_image
def region_of_interest(image):
height = image.shape[0]
polygons = np.array([
[(200, height), (400, height), (355, 0)]
])
mask = np.zeros_like(image)
cv2.fillPoly(mask, polygons, 255)
masked_image = cv2.bitwise_and(image, mask)
return masked_image
image = cv2.imread('tape3.jpg')
lane_image = np.copy(image)
canny_image = canny(image)
cropped_image = region_of_interest(canny_image)
lines = cv2.HoughLinesP(cropped_image, 2, np.pi/180, 100, np.array([]), minLineLength=40, maxLineGap=5)
line_image = display_lines(lane_image, lines)
combo_image = cv2.addWeighted(lane_image, 0.8, line_image, 1, 1)
# cv2 print image
print(region_of_interest(image))
cv2.imshow("result", combo_image)
cv2.waitKey(0)
Комментарии:
1. Всегда ли полоса будет черной лентой? Что касается интересующей области, не могли бы вы выполнить простой анализ цвета пороговое значение, чтобы определить, где находится лента?
2. В конце концов, это будет черная лента с красными полосами на ней (красные полосы горизонтальны), поэтому я действительно не знаю, будет ли для этого хорошо работать пороговое значение.
3. Hough lines использует детектор Canny edge. Проверьте, правильно ли изображение canny находит край на всей ленте. Лента не совсем прямая, поэтому вы не сможете определить всю границу как один отрезок строки. Вам нужно будет точно настроить пороговые значения и параметры, чтобы получить правильный результат.
4. @SembeiNorimaki Я обновлю код, чтобы включить функцию canny, которую я использовал.
5. Спасибо за обновление. Пожалуйста, обновите свой пост, чтобы предоставить образцы изображений для начала, середины и конца дорожки. Одного изображения недостаточно, чтобы убедить нас в том, что то, что мы предлагаем, будет работать.
Ответ №1:
Возможно, это не ответ на ваш первоначальный вопрос, но это может быть альтернативным способом достижения того, что вы ищете.
Я начал с порогового значения оттенков серого изображения, чтобы попытаться изолировать ленту
Затем я использовал findContours opencv для получения точек сегментации каждого белого двоичного объекта
Используемый мной метод определения порога чувствителен к свету и тени, поэтому вам, возможно, придется найти какой-то другой метод определения порога, если это не является работоспособным ограничением. Если беспокоит лента другого цвета, вы можете отключить другие значения (преобразовать в HSV или LAB и отключить каналы H или B соответственно, чтобы искать красный).
Редактировать:
Если вы все еще хотите использовать HoughLinesP, вот рабочий пример с вашим изображением.
Сначала я применил canny:
Затем я использовал функцию HoughLinesP:
Я никогда раньше не использовал HoughLinesP, поэтому я не уверен в потенциальных подводных камнях, но, похоже, это работает, хотя на самом деле создает кучу перекрывающихся строк с этими параметрами, вам придется немного поиграть с этим.
Соответствующий код:
# canny
canned = cv2.Canny(gray, 591, 269);
# dilate
kernel = np.ones((3,3), np.uint8);
canned = cv2.dilate(canned, kernel, iterations = 1);
# hough
lines = cv2.HoughLinesP(canned, rho = 1, theta = 1*np.pi/180, threshold = 30, minLineLength = 10, maxLineGap = 20);
Правка 2:
Я просмотрел документацию к функции, и третий параметр (theta) относится к разрешению угла. Я думаю, что это могло не сработать в вашем коде, потому что вы не запустили расширение изображения после Canny. При разрешении поиска в один градус нетрудно представить, что мы можем пропустить очень тонкую грань, которую возвращает canny. Возможно, даже стоит расширить линии больше, чем я сделал в примере, используя ядро большего размера (или расширяя его несколько раз).