使用Hough变换,OpenCV和python进行平行线检测

时间:2018-02-08 03:44:10

标签: python algorithm opencv image-processing hough-transform

我需要帮助我一直在使用的算法。我试图检测阈值图像中的所有行,检测所有行,然后仅输出那些并行的行。阈值图像输出我感兴趣的对象,然后我通过canny边缘检测器过滤此图像。然后,该边缘图像通过概率霍夫变换。现在,我希望算法能够检测任何图像中的平行线。我想通过尝试检测所有线的坐标并计算它们的斜率(然后是角度)来做到这一点。平行线必须具有相同或几乎相同的角度,这样我才能输出具有相同角度的线。我可以在图像中绘制一条虚线,然后将其用作图像中所有检测到的线条的参考?我只是不了解如何使用通过函数cv2.HoughLinesP()检测到的所有行的坐标。这个函数的文档说输出是一个4D数组,这对我来说很困惑。这是我的代码的一部分:

通过概率Hough变换进行线检测

rho_res = .1 # [pixels]

theta_res = np.pi / 180. # [radians]

threshold = 50 # [# votes]

min_line_length = 100 # [pixels]

max_line_gap = 40 # [pixels]

lines = cv2.HoughLinesP(edge_image, rho_res, theta_res, threshold, np.array([]),

                        minLineLength=min_line_length, maxLineGap=max_line_gap)

画线

    if lines is not None:
                for i in range(0, len(linesP)):
                    coords = lines[i][0]
                    slope = (float(coords[3]) - coords[1]) / (float(coords[2]) - coords[0])
                    cv2.line(img, (coords[0], coords[1]), (coords[2], coords[3]), (0,0,255), 2, cv2.LINE_AA)

有关如何推断所有检测到的线然后仅输出那些并行线的任何想法?我在线尝试了一些算法,但似乎都没有。同样,我的问题是理解并使用函数cv2.HoughLinesP()的输出变量。我还找到了一个应该计算斜率的代码。我试过这个,但只是给了我一个值(一个斜率)。我想要图像中所有线条的斜率。

3 个答案:

答案 0 :(得分:0)

使用0..Pi函数计算范围atan2中所有行的斜率(角度)。要按正角度限制范围,请将Pi添加到否定结果中。

按坡度排序结果。遍历排序列表,使联合值接近 - 这些线接近平行。请注意,对于稍微不同的邻居值,您可能会有很长的序列,但系列的开头和结尾可能会有很大不同。因此,使用一些(角度)阈值来打破系列运行。

答案 1 :(得分:0)

将霍夫变换投影到角度轴上。这为您提供了作为theta函数的1D信号,该信号与该方向中的“线量”成比例。该信号中的峰值表示具有许多平行线的方向。找到最大的峰值,它会给你一个theta。

现在回到霍夫变换图像,并用这个θ值检测峰值(可能允许一点点摆动)。现在,您将拥有此方向的所有平行线。

抱歉,我无法提供适用于library(dplyr) datatable <- read.table(text = 'Ppt Region nitem 1 "fffword8" 93 1 "word8" 93 1 "fffword9" 93 1 "word2" 122 1 "fffword3" 122 1 "word3" 122 1 "word6" 122 1 "fffword7" 122 1 "word7" 122 1 "fffword8" 122 1 "word8" 122 54 "fffword8" 4 54 "word8" 4 54 "fffword9" 4 54 "word2" 4 54 "fffword2" 10 54 "word4" 10 54 "word6" 10 54 "fffword23" 10 54 "word23" 10 54 "fffword24" 5 #54 "word24" 5 ', header = T, stringsAsFactors = F) datatable %>% group_by(Ppt, nitem) %>% mutate(Output = ifelse(grepl("^fffword",Region), ifelse(is.na(lead(Region)),1L, ifelse((gsub("fffword([0-9]+).*","\\1",Region)) == (gsub("word([0-9]+).*","\\1",lead(Region))), 0L,1L)), ifelse(is.na(lag(Region)),1L, ifelse((gsub("word([0-9]+).*","\\1",Region)) == (gsub("fffword([0-9]+).*","\\1",lag(Region))), 0L,1L)) )) %>% as.data.frame() #Result Ppt Region nitem Output 1 1 fffword8 93 0 2 1 word8 93 0 3 1 fffword9 93 1 4 1 word2 122 1 5 1 fffword3 122 0 6 1 word3 122 0 7 1 word6 122 1 8 1 fffword7 122 0 9 1 word7 122 0 10 1 fffword8 122 0 11 1 word8 122 0 12 54 fffword8 4 0 13 54 word8 4 0 14 54 fffword9 4 1 15 54 word2 4 1 16 54 fffword2 10 1 17 54 word4 10 1 18 54 word6 10 1 19 54 fffword23 10 0 20 54 word23 10 0 21 54 fffword24 5 1 的代码,我不知道这个功能。我希望这个描述能给你一个起点。

答案 2 :(得分:0)

<块引用>

我只是不明白如何使用通过函数 cv2.HoughLinesP() 检测到的所有线的坐标。这个函数的文档说输出是一个 4D 数组,这让我很困惑。

4D 数组只是检测到的线的输出向量。每条线由一个 4 元素向量 (x1, y1, x2, y2) 表示,其中 (x1,y1) 和 (x2, y2) 是每个检测到的线段的终点。

请参阅所附图片以了解这些含义。请记住,那些协调的在图像空间中。

Detected Lines