Python/OpenCV - 在 OpenCV 中使用两种不同的霍夫线方法检测网球场中的线 - 获得不同的结果

lil*_*uch 5 python opencv transformation

我正在尝试使用 openCV 和霍夫变换检测网球场中的线条。我想找到水平线和垂直线,以便找到交点并最终检测网球场的角落。

这里是原始图像。 在此处输入图片说明

但我有一些问题。

1)我尝试使用 HoughLineP 。这里的代码:

gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

edges = cv2.Canny(gray,100,200,apertureSize = 3)
lines = cv2.HoughLinesP(edges, 1, np.pi/2, 6, None, 50, 10);
for line in lines[0]:
    pt1 = (line[0],line[1])
    pt2 = (line[2],line[3])
    cv2.line(img, pt1, pt2, (0,0,255), 2)
cv2.imshow('dst',img)

return res
Run Code Online (Sandbox Code Playgroud)

这里的结果: houghLineP 的结果

2)我尝试使用 HoughLines 这里的代码

gray=cv2.cvtColor(res,cv2.COLOR_BGR2GRAY)

edges = cv2.Canny(gray,100,200,apertureSize = 3)


#Lignes
lines = cv2.HoughLines(edges,1,np.pi/70,110)
for rho,theta in lines[0]:
    if (np.pi/70 <= theta <= np.pi/7) or (2.056 < theta < 4.970) or (1.570 <= theta <= 1.600): #(2,6 <=theta <= 26) or (theta >118 and theta <= 285)

        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(res,(x1,y1),(x2,y2),(0,0,255),1)
Run Code Online (Sandbox Code Playgroud)

这里的结果: houghLine 的结果

在第一种情况下,我只有很少的线条,我想延长它们但我没有找到......我尝试使用 fitLine 但它只适用于查找轮廓(这张图片中的 findContours 方法很糟糕)

在第二种情况下,它运行良好,但我有很多线,几乎相同并且在右下角,我没有任何交叉点来检测角落......

也许我走错了路...

你有什么想法或可行的方法吗?最后,我只想要关于网球场的兴趣点。

ps:我做了一个方法来计算水平线和垂直线之间的交点。 在此处输入图片说明

非常感谢,

Ben*_*Ben 5

看起来行 HougLines 输出包含您想要的行。您只需要过滤掉异常值。

为此,您可以使用网球场的模型。您所知道的是,您拥有:

  • 场的外部界限,由一个大矩形表示
  • 两条走廊,由两条线表示,在两侧切割矩形
  • 发球区,同样由两条线表示,一条平行于发球线,另一条平行于边

例如,您可以尝试从必须过滤掉异常值的模型中获利。一些方法,如RANSAC,就是为此而设计的。基本思想是取随机点,计算模型并检查数据是否合适。经过一些迭代,最合适的很可能就是您要寻找的模型。这是一种众所周知的方法(由 Fischler 于 1986 年首次发布),因此您可以找到大量有关它的文档。让我们举一个简单的示例算法,它可以为您工作(可能需要调整):

  1. 在线交叉点内随机取 4 个点。计算将这些点映射到场顶视图的透视投影 P。您可以为此使用 OpenCV 的 getPerspectiveTransform。您现在在顶视图中拥有了该领域的模型。

  2. 由于您拥有场地模型(基于网球规则),您可以确定其他线的交叉点(服务线与走廊线、服务广场 ..)应该在顶视图上的位置。如果对这些点应用透视变换 P^{-1} 的逆变换,则它们在图像空间中。

  3. 检查一致性:在图像空间中寻找最接近您模型的线的交叉点。在这里,您应该有一个指标:距离小于 x 像素或 SSD 的线的交叉点数。您将使用此指标对不同的模型进行评分。

  4. 为您的模型评分:如果您定义的指标低于之前找到的最佳指标,那么这就是您当前的最佳模型

  5. 迭代。你所做的迭代次数直接关系到最终选择一个好的模型的概率。查看 Fischler 和 Bolls 的开创性工作,了解如何设置迭代次数。

在这里,在迭代结束时,您将找到最适合您的数据的模型,即描述网球场地的内点和不适合的离群点。请注意,此方法对大量异常值(超过 50%)具有鲁棒性,但获得良好结果的机会只是统计数据(不过,您可以通过调整迭代次数来设置结果的预期质量)。

希望这可以帮助,