2016-04-13 2 views
12

Мне нужно будет определить дорожную полосу из видео. Вот мой способ сделать это.Python и OpenCV - Улучшение алгоритма обнаружения полосы движения

  1. Определить области интереса (ROI), нарезая изображение (фокус в средней части)
  2. Grayscale КОРОЛЬ
  3. сравняли оттенками серого ROI с cv2.equalizeHist
  4. Применить Гауссово размывание (3)
  5. Порог (4) с помощью cv2.adaptiveThreshold
  6. скелетируют (5) с помощью skimage.morphology.skeletonize
  7. Применить cv2.HoughLines на (6)

Для cv2.HoughLines я настроен так, что:

  1. Если rho является положительным (что означает, что прямая линия имеет наклон вправо (снизу вверх), то это будет только нарисовать линию, если она находится под определенными углами (я установил диапазон угла))
  2. Если rho отрицательный (прямая линия наклонена влево (снизу вверх), она будет рисовать линию только в том случае, если она находится под определенными углами)

Это мой код для рисования линий:

lines = cv2.HoughLines(image_bin, 1, np.pi/180, 50) 
    try: 
     range = lines.shape[0] 
    except AttributeError: 
     range = 0 

    for i in xrange(range): 
     for rho, theta in lines[i]: 
      if rho > 0 and (np.pi*1/10 < theta < np.pi*4/10): 
       a = np.cos(theta) 
       b = np.sin(theta) 
       x0 = a * rho 
       y0 = b * rho 
       x1 = int(x0 + 1000 * (-b)) 
       y1 = int(y0 + 1000 * (a)) 
       x2 = int(x0 - 1000 * (-b)) 
       y2 = int(y0 - 1000 * (a)) 

       cv2.line(roi, (x1, y1), (x2, y2), (0, 255, 0)) 

      if rho < 0 and (np.pi*7/10 < theta < np.pi*9/10): 
       a = np.cos(theta) 
       b = np.sin(theta) 
       x0 = a * rho 
       y0 = b * rho 
       x1 = int(x0 + 1000 * (-b)) 
       y1 = int(y0 + 1000 * (a)) 
       x2 = int(x0 - 1000 * (-b)) 
       y2 = int(y0 - 1000 * (a)) 

       cv2.line(roi, (x1, y1), (x2, y2), (0, 255, 0)) 

Если бы я не сделал то, что я только что сделал выше для функции cv2.HoughLines, я считаю, что будет много ненужных линий, нарисованных.

После настройки параметров и т. Д., Я получил неплохой результат, но это всего лишь одно изображение. Я не думаю, что это будет хорошо для видео, которое будет меняться. Что беспокоит меня больше всего о моем алгоритме для рисования необходимых линий (это дорожная полоса). Есть ли лучший способ? По крайней мере, лучше, чем у меня.

Это мой результат:

Исходное изображение: The original image

корректирующая гистограмма, порогами и каркасный образ ROI: Equalized Histogram, thresholded, and skeletonized

Окончательный результат: Final result

ответ

6

Я бы посоветовал рассмотреть возможность использования вероятностного преобразования линии хака для вашего приложения на. В Python API OpenCV он реализован в функции, cv2.HoughLinesP. Это фактически даст вам сегменты линий, поэтому вам не нужно будет вычислять конечные точки. Это также намного быстрее, чем стандартное преобразование линии Hough.

Однако есть несколько компромиссов. Например, вам может потребоваться добавить логику для сшивания сегментов линии. С другой стороны, я обнаружил, что это не очень плохо. Один из моих игрушечных проектов (самонаводящийся миниатюрный автобус), использовал этот подход и имел отдельные сегменты линии, чтобы сшить вместе, упростил работу с изогнутыми дорогами, в которых стандартное преобразование линии hough не даст вам никаких линий вообще ,

Надеюсь, что это поможет.

EDIT: Что касается деталей линейного сегмента «сшивание», это зависит от того, что вы хотите выполнить. Если вы просто хотите отобразить дорогу, и вы удовлетворены наличием некоторых промежутков между сегментами линии, вам может не понадобиться делать какие-либо строчки - просто отобразите все сегменты линий. В моем приложении мне нужно было определить кривизну полосы, поэтому я сделал несколько строчек, чтобы создать модель каждой дорожной полосы, которая включала бы средний наклон полосы, который использовался в качестве входного сигнала для модуля, ответственного за управление серво для перемещения колес соответственно.

«Сшивание» Я не имею в виду ничего особо сложного, но я не знаю каких-либо конкретных функций OpenCV для его выполнения. Мне просто нужен способ связанных сегментов линии, которые были частью одной и той же полосы. Поэтому я обработал сегменты линий, возвращенные с HoughLinesP, с верхней части изображения, работающего вниз, и использовали наклон каждого сегмента линии и y-перехват, чтобы определить, где пересекаются сегменты линии.

+0

Как я могу «прошивать» линии? Извините, но все же новичок в программировании и обработке изображений. – Hilman

+0

Я добавил несколько заметок. Извините за отсутствие кода. Это на C++, и конкретная реализация сильно отличается от вашей - в основном, у меня просто нет времени, чтобы адаптировать ее для вашего приложения. – Aenimated1

Смежные вопросы