Как найти крайние точки на линиях с помощью java и opencv

В настоящее время я разрабатываю программу обнаружения полос движения, и мне нужно заполнить область между несколькими строками. Как мне найти крайние точки (самая высокая точка справа и слева + самые низкие точки справа и слева). Вот изображение, с которым я сейчас работаю (изображение).

В качестве примечания: изображение можно рассматривать как координатную плоскость, поскольку все линии имеют начальную и конечную точки, и я могу получить их координаты.

Вот что мне нужно (крайние точки синего цвета): изображение

Спасибо за вашу помощь.


person Adam Frank    schedule 08.08.2017    source источник
comment
Добро пожаловать в Stack Overflow! Что означают красные метки в коде? контуры, линии (начальная точка, конечная точка)...? Вы нашли строки с HoughLinesP?   -  person Elouarn Laine    schedule 09.08.2017
comment
Красные метки на изображении — это линии, созданные HoughLinesP @ElouarnLaine.   -  person Adam Frank    schedule 09.08.2017
comment
Вы пробовали мой подход? Это сработало для вашей проблемы?   -  person Elouarn Laine    schedule 18.08.2017


Ответы (1)


Согласно предоставленной информации и образцам изображений, вот как я подошел бы к этой проблеме:

Предпосылка

Красные метки — это строки, созданные HoughLinesP. , у вас есть следующая информация о каждой строке: (x1, y1, x2, y2) где (x1, y1) — начальная точка, а (x2, < em>y2) конечная точка линии.

Для тестирования я создал 3 строки:

3 строки для тестирования

Трубопровод

  1. Создайте список точек (contour в моем коде), содержащий начальные и конечные точки каждой линии.
  2. Вычислите выпуклую оболочку списка точек, используя convexHull.

На данный момент вы получите что-то в этом вкусе:

Зеленая выпуклая оболочка без аппроксимации

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

  1. Упростите корпус с помощью approxPolyDP
  2. Оставшиеся 4 точки корпуса должны быть аппроксимацией крайних точек.

Здесь вы можете увидеть окончательный результат с приблизительным корпусом зеленым цветом и 4 крайними точками желтым цветом:

конечный результат, крайние точки выделены желтым цветом

Код Python

Наконец, в качестве справки, вот код Python, который я использовал (его не должно быть сложно портировать на Java):

import numpy as np
import cv2

input_img = np.zeros((400,400,3), np.uint8)
# 3 lines added for testing purpose
lines = []
lines.append(((350,350),(250,200))) # (start point, end point)
lines.append(((50,350),(55,330)))
lines.append(((60,250),(80,200)))

contour = [] #in Java you'd use a List of Points

for line in lines:
    # we create a contour with the start and end points of each line
    contour.append(line[0])
    contour.append(line[1])
    # we draw the lines (in your case, detected by HoughLinesP)
    cv2.line(input_img,line[0],line[1],(0,0,255),3)

contour = np.array(contour)
hull = cv2.convexHull(contour) # we compute the convex hull of our contour

epsilon = 0.05*cv2.arcLength(hull,True) # epsilon may need to be tweaked
approx_hull = cv2.approxPolyDP(hull,epsilon,True)

# we check that there are only 4 points left in the approximate hull (if there are more, then you'd need to increase epsilon
if(len(approx_hull) == 4): 
    for final_point in approx_hull :
        # we draw the 4 points contained in the approximate hull 
        cv2.circle(input_img, (final_point[0][0], final_point[0][1]),5,(0,242,255),2)

cv2.drawContours(input_img, [approx_hull], 0, (0,255,0),1)
cv2.imshow("result",input_img)

Альтернатива

Я думаю, что это решение от @YvesDaoust также может сработать. У меня не было времени проверить это, поэтому, пожалуйста, держите меня в курсе, если вы это сделаете. :)

person Elouarn Laine    schedule 10.08.2017
comment
Насколько я мог видеть, контуры будут List‹MatOfPoint›, а convexHull принимает один, так как же это работает? - person mirzak; 23.03.2019