首页 > 编程知识 正文

坐标点乘法计算方法,空间向量法如何求点的坐标

时间:2023-05-03 14:53:10 阅读:272761 作者:2701

PCA对点云平面处理后,返回三个特征向量,分别是平面自身坐标系的X轴,Y轴和Z轴在点云全局坐标系中的向量。其中Z轴信息最少,就是平面的法向量。要想把点云从全局坐标系下转化到XoY的二维平面,只需把点按照旋转矩阵R变换后,PCA返回的三个向量就组成了3X3的旋转矩阵R。


换句话说,PCA对平面点云的变换,就是把点转换到三个特征向量组成的新的XYZ坐标系下,新坐标系的原点和全局原点是相同的。


首先import相关库:

from sklearn.decomposition import PCAfrom sklearn import preprocessingimport numpy as np

平面方程为 aX + bY + cZ + d = 0

下面我们自己随机生成一个平面的4个参数(3维法向量[a,b,c]和平面离原点的距离d),并生成1000点:

def create_plain_data():model = np.random.randint(1,100,4).astype('float64')model[:3] = preprocessing.normalize(np.array([model[:3]]), norm='l2')x_range = (100,110)y_range = (1000, 1010)data = np.zeros((1000,3), dtype='float64')data[:,0] = np.random.randint(x_range[0],x_range[1],data.shape[0])data[:,1] = np.random.randint(y_range[0],y_range[1],data.shape[0])data[:,2] = -( data[:,0] * model[0] + data[:,1] * model[1] + model[3] ) / model[2]return model, data


下面调用上面的函数,生成平面点和参数model,其中红色的就是随机生成的法向量:

if __name__ == '__main__':model, data = create_plain_data()print "model: ", modelprint "data:"print data>model:  [  0.59223344   0.41456341   0.69093902  92.        ]data:[[  103.          1007.          -825.63784149] [  101.          1004.          -822.12355578] [  107.          1001.          -825.46641292] ...,  [  107.          1007.          -829.06641292] [  108.          1004.          -828.12355578] [  109.          1006.          -830.18069863]]
接下来我们用PCA分析出3个特征向量(pca.components_), 并打印旋转后的平面点


pca = PCA(n_components=3)pca.fit(data)print "variance_ratio: ", pca.explained_variance_ratio_ print "components_", pca.components_print "Transformed points in 3 components' coordinate"print pca.fit_transform(data)>variance_ratio: [ 6.84766389e-01 3.15233611e-01 1.19653080e-26]components_ [[ 0.55240657 0.4153701 -0.7227134 ] [ 0.58660594 -0.8096943 -0.01698851] [-0.59223344 -0.41456341 -0.69093902]]Transformed points in 3 components' coordinate[[ 6.16324398e-01 -2.80846397e+00 6.11165344e-13] [ -4.27442042e+00 -1.61229542e+00 6.22402823e-13] [ 2.09836384e-01 4.39321328e+00 4.99872091e-13] ..., [ 5.30382521e+00 -4.03793897e-01 5.06568841e-13] [ 3.92870600e+00 2.59587721e+00 6.45553024e-13] [ 6.79857748e+00 1.59804234e+00 4.62417997e-13]]可以看到最后一个特征向量的信息量(variance_ratio[2])非常少1.19653080e-26,说明点的坐标在这个特征向量的方向上计划是没有区分度的,所以它pca.components_[2]就是点平面的法向量。我们对比前面的model输出(红色的)发现它们的确是相等的。而且,转换后点的Z值都为0.

那pca.fit_transform(data)这样的PCA变换具体做的什么事情呢,它就是把所有点旋转到pca.components_[0]和pca.components_[1]组成的坐标平面,然后把原点移动到点云的中心点。下面我们验证一下:

rotated_data = np.dot(data, pca.components_.T)mean_data = rotated_data - np.mean(rotated_data, axis=0)print "manual transformed ponts"print mean_data>manual transformed ponts[[ 6.16324398e-01 -2.80846397e+00 -4.68958206e-13] [ -4.27442042e+00 -1.61229542e+00 -5.68434189e-13] [ 2.09836384e-01 4.39321328e+00 -5.96855898e-13] ..., [ 5.30382521e+00 -4.03793897e-01 -6.25277607e-13] [ 3.92870600e+00 2.59587721e+00 -4.68958206e-13] [ 6.79857748e+00 1.59804234e+00 -6.53699317e-13]]对比上下两组蓝色数据,的确是一样的。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。