使用 python CPD 处理大型数据集的内存问题

时间:2021-07-21 23:59:33

标签: python numpy memory point-clouds

我目前正在研究点云配准问题,以确定 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数组上使用了几个点积。

我的问题是,我的猜测是否正确,是否有任何可能的解决方案来解决这个问题。任何帮助将不胜感激。

0 个答案:

没有答案