矩形格适合噪声坐标

时间:2019-06-27 12:34:16

标签: python numpy optimization coordinates lattice

我有以下问题。成像您有一组以某种规律组织的坐标,如下图所示。 enter image description here

我想做的是自动提取坐标,以便它们从左到右,从上到下排序。另外,坐标的总数应尽可能大,但仅包括坐标,以使提取的坐标位于近似矩形的网格上(即使坐标具有不同的对称性,例如六边形)。我一直想提取遵循矩形晶胞结构的坐标。

对于上面显示的示例,包含此类正交排列集的最大数字将是8 x 8坐标(以下称此尺寸:m x n),如红色矩形所示。

问题在于给定坐标嘈杂且失真。 我的方法是生成一个人造晶格,并考虑到晶格的某些旋转,移动和简单变形,将给定坐标的差异最小化。然而,事实证明,定义一个涵盖问题复杂性的成本函数是棘手的,即最小化给定坐标和拟合晶格之间的差异,同时最大化网格分量m x n。

如果有人有一个聪明的主意如何解决这个问题,也许还有机器学习算法,我将非常感激。

这是我到目前为止使用的代码: 生成具有m x n坐标的人造晶格的函数,这些坐标在“ n”和“ m”方向上被a和b隔开。角度θ允许晶格旋转。

def lattice(m, n, a, b, theta):
    coords = []
    for j in range(m):
        for i in range(n):
            coords.append([np.sin(theta)*a*i + np.cos(theta)*b*j, np.cos(theta)*a*i - np.sin(theta)*b*j])
    return np.array(coords)

我使用以下函数来测量点之间的平均最小距离,这是拟合的良好起点:

def mean_min_distance(coords):
    from scipy.spatial import distance
    cd = distance.cdist(coords, coords)
    cd_1 = np.where(cd == 0, np.nan, cd)
    return np.mean(np.nanmin(cd_1, axis=1))

以下函数提供了理论上适合坐标长度的m x n的所有可能组合,假定其排列方式未知。已经包含将其限制为最小值和最大值的功能:

def get_all_mxn(l, min_m=2, min_n=2, max_m=None, max_n=None):
    poss = []
    if max_m is None:
        max_m = l + 1
    if max_n is None:
        max_n = l +1
    for i in range(min_m, max_m):
        for j in range(min_n, max_n):
            if i * j <= l:
                poss.append([i, j])
    return np.array(poss)

我使用的成本函数的定义(对于一组特定的m x n)。因此,我首先想对某种m x n的布置非常合适。

def cost(x0):
    a, b, theta, shift_a, shift_b, dd1 = x0
    # generate lattice
    l = lattice(m, n, a, b, theta) 
    # distort lattice by affine transformation
    distortion_matr = np.array([[1, dd1], [0, 1]]) 
    l = np.dot(distortion_matr, l.T).T
    # shift lattice 
    l = l + np.array((shift_b, shift_a))

    # Some padding to make the lists the same length
    len_diff = coords.shape[0] - l.shape[0]
    l = np.append(l, (1e3, 1e3)*len_diff).reshape((l.shape[0] + len_diff, 2))

    # calculate all distances between all points
    cd = distance.cdist(coords, l)
    minimum distance between each artificial lattice point and all coords
    cd_min = np.min(cd[:, :coords.shape[0] - len_diff], axis=0)

    # returns root mean square difference of all minimal distances
    return np.sqrt(np.sum(np.abs(cd_min) ** 2) )

然后运行最小化:

md = mean_min_distance(coords) 
# initial guess
x0 = np.array((md, md, np.deg2rad(-3.), 3, 1, 0.12))
res = minimize(cost, x0)

但是,结果非常依赖于初始参数x0,我什至没有包含m和n的拟合。

0 个答案:

没有答案