我目前正在研究点云配准问题,以确定 2 个点云之间的刚性和非刚性变换。这是我认为导致内存问题的 CPD 算法的 M 步的实现。
import numpy as np
def MStep(X, Y, P):
s, R, t, A, XX = updateTransform(X, Y, P, P1, Np)
sigma2 = updateVariance(R, A, XX, Np, D)
def updateTransform(X, Y, P):
muX = np.divide(np.sum(np.dot(P, X), axis=0), Np)
muY = np.divide(np.sum(np.dot(np.transpose(P), Y), axis=0), Np)
XX = X - np.tile(muX, (N, 1))
YY = Y - np.tile(muY, (M, 1))
A = np.dot(np.transpose(XX), np.transpose(P))
A = np.dot(A, YY)
U, _, V = np.linalg.svd(A, full_matrices=True)
C = np.ones((D, ))
C[D-1] = np.linalg.det(np.dot(U, V))
R = np.dot(np.dot(U, np.diag(C)), V)
YPY = np.dot(np.transpose(P1), np.sum(np.multiply(YY, YY), axis=1))
s = np.trace(np.dot(np.transpose(A), R)) / YPY
t = np.transpose(muX) - s * np.dot(R, np.transpose(muY))
return s, R, t, A, XX
def updateVariance(R, A, XX, Np, D):
trAR = np.trace(np.dot(A, np.transpose(R)))
xPx = np.dot(np.transpose(Pt1), np.sum(np.multiply(XX, XX), axis =1))
sigma2 = (xPx - s * trAR) / (Np * D)
return sigma2
示例(刚性变换)siavashk 的实现提供的数据集中有 182 个点,这是一个相对较小的点。但是,我使用的数据集有 27000+ 个点,这会导致内存问题。
这是我的尝试。首先我尝试了我的测试机的限制,这是结果。
4000 数据集:132.37069296836853 秒
5000 数据集:206.02958345413208 秒
6000 数据集:298.2869338989258 秒
7000 数据集:405.55420875549316 秒
12000 数据集:1200.0092532634735 秒
15000/ 17000 数据集:进程被杀死
20000 数据集:Numpy 数组太大(无法为形状为 (20000, 20000, 3) 且数据类型为 float64 的数组分配 8.94 GiB)
从我对这个结果的解释来看,我想在使用大数据集尝试这个算法时有两个问题。首先,当数据集大约为 20000 个点时,Numpy 没有足够的空间来生成 (20000,20000,3) 形状数组。其次,当数据集在 15000 点左右时,由于内存不足,实现被终止。经过研究代码,问题是因为算法在(n, n, 3)形状的Numpy数组上使用了几个点积。
我的问题是,我的猜测是否正确,是否有任何可能的解决方案来解决这个问题。任何帮助将不胜感激。