Подтвердить что ты не робот

Python и OpenCV - Улучшение алгоритма обнаружения полосы движения

Мне нужно будет определить дорожную полосу из видео. Вот мой способ сделать это.

  • Определите область интереса (ROI), нарезая изображение (сфокусируйте среднюю часть)
  • Оттенки шкалы ROI
  • Уравнили рендеринг рендеринга с сечением cv2.equalizeHist
  • Применить гауссовское размытие к (3)
  • Порог (4) с помощью cv2.adaptiveThreshold
  • Скелетонизировать (5) с помощью skimage.morphology.skeletonize
  • Примените cv2.HoughLines к (6)

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

  • Если rho положительно (это означает, что прямая линия наклонена вправо (снизу вверх), она будет рисовать линию только в том случае, если она находится под определенными углами (я устанавливаю диапазон угла))
  • Если 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, я считаю, что будет сделано много ненужных строк.

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

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

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

Уравниваемая гистограмма, пороговое и скелетонизированное изображение ROI: Уравниваемая гистограмма, пороговая и скелетонированная

Конечный результат: Конечный результат

4b9b3361

Ответ 1

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

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

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

РЕДАКТИРОВАТЬ: Что касается деталей строчки сегмента, это зависит от того, что вы хотите выполнить. Если вы просто хотите отобразить дорогу, и вы удовлетворены наличием некоторых промежутков между сегментами линии, вам может не понадобиться делать какие-либо строчки - просто отобразите все сегменты линий. В моем приложении мне нужно было определить кривизну полосы, поэтому я сделал несколько строчек, чтобы создать модель каждой дорожной полосы, которая включала бы средний наклон полосы, который использовался в качестве входного сигнала для модуля, ответственного за управление серво для перемещения колес соответственно.

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