大家好,我目前正在研究不同的算法,这些算法可以为我提供对齐单元格组内的直线模式。
让我解释:
假设我们有一个 XY 平面,它是 200(x)/30(y)。
我得到了一堆标记单元格中心的点(在 xy 坐标中),我的任务是获得通过这些单元格形成直线的点的模式。
模式必须是一组 8 个点:[[point1],[point2],[point3],...[point8]] 或一组 4 个(如果没有可配对的组)。
直线只能有 -50º 到 50º 的梯度。
例如:
命中的 Y 坐标:
[0.65, 0.65, 0.65, 0.65, 0.65, 1.9500000000000002, 1.9500000000000002, 1.9500000000000002, 1.9500000000000002, 3.25, 3.25, 3.25, 3.25, 3.25, 4.550000000000001, 4.550000000000001, 4.550000000000001, 4.550000000000001]
命中的 X 坐标:
[77.7, 107.1, 191.1, 195.3, 123.9, 79.80000000000001, 109.2, 193.2, 126.00000000000001, 77.7, 111.3, 195.3, 123.9, 128.1, 79.80000000000001, 109.2, 197.4, 126.00000000000001]
点将是 [77.7,0.65],[107.1,0.65]
...等
所以我的第一个想法是实现某种霍夫变换,它会给我一个累加器,其中包含更多“票”的点的 rho 和 theta 值。
这是代码:
puntos_y=[0.65, 0.65, 0.65, 0.65, 0.65, 1.9500000000000002, 1.9500000000000002, 1.9500000000000002, 1.9500000000000002, 3.25, 3.25, 3.25, 3.25, 3.25, 4.550000000000001, 4.550000000000001, 4.550000000000001, 4.550000000000001]
puntos_x=[77.7, 107.1, 191.1, 195.3, 123.9, 79.80000000000001, 109.2, 193.2, 126.00000000000001, 77.7, 111.3, 195.3, 123.9, 128.1, 79.80000000000001, 109.2, 197.4, 126.00000000000001]
#ANGLE VALUES (50º MAX )
thetas = np.deg2rad(np.arange(-50,50))
#PLANE WIDTH,HEIGHT XY
width, height = 200,30
#DIAG FOR ACCUMULATOR
diag_len = float(np.ceil(np.sqrt(width * width + height * height))) # max_dist
#LINSPACE DE RHOS
rhos = np.linspace(-diag_len, diag_len, int(2*diag_len))
# STORE SOME VALUES
cos_t = np.cos(thetas)
sin_t = np.sin(thetas)
num_thetas = len(thetas)
num_rhos = len(rhos)
# ACcumulador (ARRAY THETA VS RHO)
accumulator = np.zeros((int(2*diag_len), num_thetas))
#POINTS
y_idxs, x_idxs = puntos_y, puntos_x
# ACCUMULATOR VOTES
for i in range(len(x_idxs)):
x = x_idxs[i]
y = y_idxs[i]
for t_idx in range(num_thetas):
# START CALCULATING RHO VALUES. DIAG_LEN FOR POSITIVE INDEX
rho = round(x * cos_t[t_idx] + y * sin_t[t_idx] + diag_len )
accumulator[int(rho), int(t_idx)] += 1
def votos_max(accumulator, thetas, rhos):
#FINDS MAX VOTES IN ACCUMULATOR
idx = np.argmax(accumulator)
rho = rhos[int(idx / accumulator.shape[1])]
theta = thetas[idx % accumulator.shape[1]]
return idx, theta, rho
#FINDS GRADIENT FOR A THETA
def sacar_pendiente(theta):
return np.cos(theta) / np.sin(theta)
#FINDS Y WHEN X=0
def sacar_n(theta, rho):
return rho / np.sin(theta)
这段代码给了我一个累加器数组,其中包含列表中每个点的 senoids。这些点相交的地方是每组点的直线梯度相同的地方。
问题是:如您所见,点并不能形成精确的直线。它们排列在 xy 平面上几乎对齐但不完全对齐,这就是为什么您可以在累加器中看到各种高票点,而不是每 2 组点中只有一个。
因此,当我以这样的图形方式看到它时,我可以想象这种模式:
我很想找到一些改进这个累加器的方法,也许是改变阈值的一些方法,所以在累加器中,每组点都被视为一个大点(我不知道我是否解释得很好)就像你是个孩子,把点变大了,这样线就可以适应了。
考虑到每组 4 个点,就像它们完全对齐一样,将直线的精度降低到程序点的某种方法当然会导致在累加器中只有一个“投票最多”(RHO,THETA)点数组,然后我将能够提取其坐标并轻松创建模式。
有什么办法可以改善这一点吗?也许我应该尝试其他类型的算法作为点和直线的模式识别器?
PD:对不起,如果我没有正确解释自己。