我使用霍夫变换来检测足球场中的线。以下是检测到的行的示例(总共 61行):
所有行都是cv2.HoughLinesP
函数的输出,并以以下格式显示为numpy-array
:
[x1, y1, x2, y2]
我要分类3个不同的线组。 goal_line
,goal_area_line
和penalty_area_line
。图像上可见的第四行是由广告牌引起的,我想忽略这一行。
我正在努力选择群集数量 k 。这是因为当球从中线移向球门区域时,我们首先仅看到1条线,即penalty_area_line
。当球进一步向左移动时,相机可能会跟随,我们将看到更多的线条。我使用以下方法计算每条线的渐变和截距:
def gradient_intercept(x1, y1, x2, y2):
dx = x2 - x1
dy = y2 - y1
radius = math.atan2(-dy, dx)
radius %= 2 * math.pi
gradient = -math.degrees(radius)
if gradient <= -180:
gradient = gradient + 180
gradient = gradient + 90
intercept = y1 - gradient * x1
return gradient, intercept
接下来,我为所有线条创建一个2d数组,并使用它来计算距离矩阵。
import numpy as np
import scipy.spatial as ss
def distance_matrix(lines):
xy = np.empty((0, 2), int)
try:
for line in lines:
for x1, y1, x2, y2 in line:
gradient, intercept = gradient_intercept(x1, y1, x2, y2)
xy = np.append(xy, [[0, gradient]], axis=0)
except Exception as e:
print(str(e))
if len(xy) > 2:
distance_matrix = ss.distance_matrix(xy, xy)
该函数产生以下输出:
[[0. 6.10702413 5.12577724 ... 1.11858265 0.02889456 2.02399679]
[6.10702413 0. 0.98124689 ... 7.22560678 6.07812957 4.08302733]
[5.12577724 0.98124689 0. ... 6.24435989 5.09688267 3.10178044]
...
[1.11858265 7.22560678 6.24435989 ... 0. 1.14747721 3.14257944]
[0.02889456 6.07812957 5.09688267 ... 1.14747721 0. 1.99510223]
[2.02399679 4.08302733 3.10178044 ... 3.14257944 1.99510223 0. ]]
接下来,我需要根据它们的截距将它们聚集在一起。 我假设(对于4个可见的簇)
intercept_billboards > intercept_goal_line > intercept_goal_area_line > intercept_penalty_area_line
通过SO搜索,我认为DBSCAN
适合我的情况
from sklearn.cluster import DBSCAN
db = DBSCAN(eps=0.2,min_samples=2) # minimum of two lines in order to be considered a cluster
db.fit_predict(distance_matrix)
labels = db.labels_
n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0)
检查n_clusters_
有时会看到值为5或6。问题:eps
到底是什么?那是什么规模?在我的情况下,什么是合适的值?
第二个问题:我的方法(拦截-> distance_matrix)是否正确?
预先感谢