(opencv + python) Избавление от перекрывающихся линий при использовании вероятностного преобразования линии hough

Добрый день! Я все еще очень новичок в python. Я разрабатываю программу, которая будет обнаруживать пешеходные линии. Моя проблема в том, что при использовании вероятностного преобразования Хафа линии обнаруживаются, но они перекрывают друг друга. Как избавиться от перекрывающихся линий? Вот мой код:

import cv2
import numpy as np
import math
from matplotlib import pyplot as plt
from calibrate import undist

def auto_canny(img, sigma = 0.5):
    v = np.median(img)

    lower = int(max(0,(1.0-sigma)*v))
    upper = int(min(255,(1.0+sigma)*v))
    edged = cv2.Canny(img, lower, upper)
    edged = cv2.dilate(edged, None, iterations=1)
    edged = cv2.erode(edged, None, iterations=1)

    return edged

img  = cv2.imread('sample.jpg')
img.shape
green = img[:,:,1]
blurred = cv2.GaussianBlur(green, (5,5), 0)

autoEdges = auto_canny(blurred)

minLineLength = img.shape[1]-10000
lines = cv2.HoughLinesP(image=autoEdges,rho=1,theta=np.pi/500,threshold=10,lines=np.array([]),minLineLength=minLineLength,maxLineGap=90)

a,b,c = lines.shape
for i in range(a):
    xst=lines[i][0][0]
    yst=lines[i][0][1]
    xnd=lines[i][0][2]
    ynd=lines[i][0][3]
    cv2.line(img,(xst, yst), (xnd, ynd), (0,0,255), 1, cv2.LINE_AA)
    l = math.sqrt(((abs(xnd-xst))^2) + ((abs(ynd-yst))^2))
    rho = (xst*ynd - xnd*yst)/l
    dist = abs(rho)
    m = (ynd - yst)/(xnd-xst)   
    print (dist,m)


cv2.imshow('result',img)
cv2.imshow('canny',autoEdges)

k = cv2.waitKey(0)
if k == 27:
    cv2.destroyAllWindows()
elif k == ord('a'):
    cv2.imwrite('OUTPUTCANNY.png',autoEdges)
    cv2.imwrite('OUTPUTCANNYWITHHOUGH.png',img)
    cv2.destroyAllWindows()

Это выходные значения (rho, наклон) для каждой линии:

(2138.987461393825, 0)

(9352.1609578182488, 0)

(2786.3685089632231, 0)

(459.45861938801005, 0)

(74.176540269582901, 0)

(7768.377424418768, 0)

(4323.5582400556614, 0)

(1457.9223924831122, 0)

(4029.5491996504829, 0)

(353.1785277501566, 0)

(3429.0843443517056, 0)

(687.44444444444446, 0)

(1001.540320481475, 0)

(4891.3687385623834, 0)

(6324.1371540947503, 0)

(5782.5260784389111, 0)

(2142.4394280125407, 0)

(3419.373032213327, 0)

(79.606923443428798, 0)

(4081.4477628728268, 0)

(2548.076237638998, 0)

(2075.2538668232146, 0)

(96.599999999999994, 0)

(28.918275651682048, 0)

(457.23808531952665, 0)

(563.81287237538288, 0)

(4522.6641535572326, 0)

(21.582043818522273, 0)

(2072.2164335243606, 0)

(446.51735688548547, 0)

(4145.9017474324037, 0)

(181.84369168362207, 0)

(2232.0294867294269, 0)

(2003.5982177527055, 0)

(5148.1880307541214, 0)

(654.14939315987181, 0)

(114.49162997063731, 0)

(1256.9505554297596, 0)

(1765.2144695745915, 0)

(835.27600228906385, 0)

(331.66247903554, 0)

(433.90321501459283, 0)

(80.786267723119749, 0)

(678.50865875094041, 0)

(75.599999999999994, 0)

(1698.1082622291476, 0)

(4893.1250194343038, 0)

(870.45171061088456, 0)

(714.65656087382285, 0)

(605.84788121475981, 0)

(2227.8458409210211, 0)

(475.17575695735991, 0)

(6150.4292926708586, 0)

(2489.7061482035415, 0)

(75.894663844041105, 0)

(603.33333333333337, 0)

(973.49884437527714, 0)

Предположительно, должно быть обнаружено 14 линий (ребер), но всего было обнаружено 72 линии, как показано в данных выше (ро, наклон). Может ли кто-нибудь предложить способ устранения этих ненужных строк? Спасибо.


person Dawn Rabor    schedule 20.10.2017    source источник
comment
Результатом является rho, theta, а не rho, slope --- это важно отметить, поскольку theta на самом деле перпендикулярно углу линии. В любом случае, не могли бы вы выложить несколько фотографий? Есть много способов справиться с этой проблемой; например, вы можете увеличить rho в вызове HoughLinesP(), вы можете проредить линии перед обнаружением линий или вы можете объединить линии вместе (например, сегментировать и взять медиану или что-то в этом роде). Все они являются жизнеспособными вариантами для большинства изображений. Если вы попробуете один из них и потом столкнетесь с проблемами, вы быстрее получите ответ на вопрос :). Добро пожаловать в Стек!   -  person alkasm    schedule 21.10.2017
comment
Благодарю за ваш ответ. Каковы способы слияния строк вместе?   -  person Dawn Rabor    schedule 21.10.2017


Ответы (1)


Для такого рода проблем не думайте, что это зависит от языка.

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

Это было мое исходное изображение: original_image

Когда я использовал HoughLinesP, я получил такой результат: houghlinep_result
I был бы рад увидеть только две строки, но я получил список похожих строк, например:

[[[  0  59 104   3]]
 [[  2  59  56  32]]
 [[ 96   3 174  57]]
 [[  4  59  49  36]]
 [[125  25 174  58]]
 [[ 53  34  99   7]]
 [[111  12 165  50]]]

Моя цель состоит в том, чтобы иметь две строки: better_result

[[  0  59 104   3]
 [ 96   3 174  57]]

Это то, что я хотел, потому что они были на одной линии с разной длиной и очень похожими углами.

Если вам нужно это решение моей проблемы, вы можете найти угол между двумя точками и проверить, существует ли уже подобный угол.

Небольшой кусочек примера:

lines = cv2.HoughLinesP(img, rho, theta, threshold, np.array([]), min_line_length, max_line_gap)
cleans = np.empty(shape=[0,4], dtype=np.int32)

for l in lines:
        alfa = degrees(atan2(l[0][2]-l[0][0], l[0][3]-l[0][1]))

        if len(cleans) == 0:
            cleans = np.append(cleans, [l[0]], axis=0)
            continue

        similar = False
        for c in cleans:
            beta = degrees(atan2(c[2]-c[0], c[3]-c[1]))
            if abs(alfa-beta) <= 3.5:
                similar = True
                break

        if not similar:
            cleans = np.append(cleans, [l[0]], axis=0)

    print(cleans)

    for line in [cleans]:
        for x1,y1,x2,y2 in line:
            cv2.line(img,(x1,y1),(x2,y2),255,2)

Он находит угол между двумя точками с помощью функции atan2.
Пожалуйста, помните, код не оптимизирован.
Он сравнивает углы с >threshold, в примере 3.5.
Если ниже порога, то считает, что это аналогичная строка и не добавляет в чистый массив.

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

person lotdcotw    schedule 18.02.2021