(opencv + python)使用概率hough线变换时摆脱重叠的线条

时间:2017-10-20 08:56:39

标签: python opencv hough-transform

美好的一天!我仍然是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,slope):

  

(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.58204381​​8522273,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条线(rho,斜率)。任何人都可以建议消除这些不必要的线路吗?谢谢。

1 个答案:

答案 0 :(得分:0)

对于这类问题,不要考虑语言特定的问题。

让我先澄清你的问题。我举一个我之前的实验的例子。
(我创建了一个新帐户,因此我的声誉很低并且图像显示为链接)

这是我的原图: original_image

当我使用 HoughLinesP 时,我得到了这样的结果:houghlinep_result
我很高兴看到只有两行,但我得到了类似这样的行的列表:

[[[  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函数求两点之间的角度。
请记住,代码没有优化。
它将角度与示例中的 阈值3.5 进行比较。
如果低于阈值,则认为是相似线,不加入clean数组。

在您的问题中,如果您有超过 2 条线并且可能在不同坐标中具有相似的角度,则您必须进行额外检查,可能使用网格大小。
如果是这种情况,请分享几个屏幕截图。