一旦我获得一些3D点坐标,我使用什么算法来匹配最佳圆柱体并获得中心轴的方向载体和半径?
我之前的 idea 是将圆柱体分成层,随着层数的增加,点形成的图形越来越接近圆柱体,但在这种情况下我无法得到圆柱体的确切半径.(中心轴是通过每个层的圆的中心来获得的)
一旦我获得一些3D点坐标,我使用什么算法来匹配最佳圆柱体并获得中心轴的方向载体和半径?
我之前的 idea 是将圆柱体分成层,随着层数的增加,点形成的图形越来越接近圆柱体,但在这种情况下我无法得到圆柱体的确切半径.(中心轴是通过每个层的圆的中心来获得的)
这是一个MCVE,用于回归由p0
和p1
(载体)以及半径R
(纯量)定义的轴.
首先我们创建一些虚拟数据集:
import numpy as np
import matplotlib.pyplot as plt
from scipy import optimize
from scipy.spatial.transform import Rotation
def cylinder(n=60, m=20, r=2, h=5):
t = np.linspace(0, m * 2 * np.pi, m * n)
z = np.linspace(0, h, m * n)
x = r * np.cos(t)
y = r * np.sin(t)
return np.stack([x, y, z]).T
X = cylinder()
rot = Rotation.from_rotvec(np.array([-1, 2, 0.5]))
x0 = np.array([1., 2., 0.])
X = rot.apply(X)
X = X + x0
这创建了一个通用用例,包括起源转移.
现在,只需将几何方程(参见equation 10)写成剩余并通过最小平方将其最小化即可.
def residuals(p, xyz):
return np.power(np.linalg.norm(np.cross((xyz - p[0:3]), (xyz - p[3:6])), axis=1) / np.linalg.norm((p[3:6] - p[0:3])), 2) - p[6] ** 2
p, res = optimize.leastsq(residuals, x0=[0., 0., 0., 1., 1., 1., 0.], args=(X,), full_output=False)
在这种情况下返回:
# array([ -1.8283916 , -1.65918186, 3.29901757, # p0
# 20.31455462, 26.98786514, -22.52837088, # p1
# 2. ]) # R
从图形上看,它会导致: