我尝试使用openCV和hough变换检测网球场的线路。我想找到水平线和垂直线,以找到交叉点,最后检测到网球场的角落。
这里是原始图片。
但我有一些问题。
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
结果如下: Result of 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)
结果如下: Result of houghLine
在第一种情况下,我只有很少的线条,我想要延长它们,但我没有找到...我尝试使用fitLine但它只适用于查找轮廓(findContours方法在这张图片中很糟糕)
在第二种情况下,它运作良好,但我有很多线,几乎相同,在右下方,我没有任何交叉点,以便检测角落......
也许我的方向不对......
你有什么想法可以有用吗?最后,我想只关注网球场的兴趣点。
ps:我做了一个计算水平线和垂直线之间交点的方法。
非常感谢,
答案 0 :(得分:4)
看起来行HougLines输出包含你想要的行。您只需要过滤掉异常值。
为此,您可以使用您的网球场模型。你知道的是你有:
例如,您可以尝试从您必须过滤掉异常值的模型中获利。有些方法,如RANSAC,就是为此而制定的。基本思想是采用随机点,计算模型并检查数据是否合适。经过一些迭代后,最合适的是你寻找的模型。这是一种众所周知的方法(由Fischler于1986年首次发布),因此您可以找到很多文档。让我们采用一个可以为您工作的简单示例算法(可能有适应性):
在线交叉点内取4个随机点。计算将这些点映射到该字段的顶视图的透视投影P.您可以使用OpenCV的getPerspectiveTransform。现在,您可以在顶视图中找到该字段的模型。
由于你有一个场地模型(根据网球规则),你可以说出线的其他交叉点(服务线与走廊线,服务广场......)应该在哪里顶视图。如果对这些点应用透视变换P ^ { - 1}的反转,则可以在图像空间中使用它们。
检查是否达成共识:查找图像空间中线条与模型的最近交点。在这里,您应该有一个指标:距离小于x像素的线的交点数,或SSD。您将使用此指标对不同的模型进行评级。
为您的模型评分:如果您定义的指标小于之前找到的最佳指标,那么现在这是您当前的最佳模型
迭代。您所做的迭代次数与最终选择好模型的概率直接相关。查看Fischler和Bolls的开创性工作,以设置迭代次数。
在迭代结束时,您将找到最适合您数据的模型,即描述网球场的内点和不适合的异常值。请注意,此方法对于大量异常值(超过50%)是稳健的,但是获得良好结果的可能性仅是统计的(您可以通过调整迭代次数来设置结果的预期质量)。
希望这有帮助,
本