简体   繁体   English

给定vNormal和地面点,将3d点云旋转到地面的偏移角度

[英]rotate 3d point cloud to offset angle of floor plane given vNormal and floor point

I'm working with kinect and ofxopeni. 我正在使用kinect和ofxopeni。 I have a point cloud in real world coordinates but I need rotate those points to offset the tilt of the camera. 我在现实世界坐标中有一个点云,但我需要旋转这些点以抵消相机的倾斜。 The floor plane should give me all the information I need but I can't work out how to calculate the axis and angle of rotation. 地板应该给我所有我需要的信息,但是我无法解决如何计算旋转轴和旋转角度。

my initial idea was... 我最初的想法是

ofVec3f target_normal(0,1,0);
ofVec3f vNormal; //set this from Xn3DPlane floorPlane (not shown here)
ofVec3f ptPoint; //as above

float rot_angle = target_normal.angle(vNormal);

for(int i = 0; i < numPoints; i++){

   cloudPoints[i].rotate(rot_angle, vNormal, ptPoint); //align my points to normal is (0 1 0)                               

}

This it seems was too simplistic by far. 到目前为止,这似乎太简单了。 I've been fishing through various articles and can see that it most probably involves a quarterion or rotation matrix but I can't work out where to start. 我浏览了很多文章,可以看到它很可能涉及到四分之一或旋转矩阵,但是我无法确定从哪里开始。 I'd be really grateful for any pointers to relevant articles or what is the best technique to get an axis and angle of rotation ? 我真的很感谢任何指向相关文章的指针,或者什么是获得旋转轴和旋转角度的最佳技术? I'm imagining it can be done quite easily using ofQuarterion or an openni function but I can't work out how to implement. 我想可以使用ofQuarterion或openni函数很容易地做到这一点,但我不知道如何实现。

best 最好

Simon 西蒙

I've never used ofxopeni, but this is the best mathematical explanation I can give. 我从未使用过xopeni,但这是我能给出的最佳数学解释。

You can rotate any set of data from one axis set to another using a TBN matrix,(tangent, bitangent, normal), where TB and N are your new set of axis. 您可以使用TBN矩阵(切线,双切线,法线)将任何一组数据从一个轴集旋转到另一个轴,其中TB和N是您的新轴集。 So, you already have the data for the normal, but you need to find a tangent. 因此,您已经有了法线的数据,但是您需要找到一个切线。 I'm not sure if your Xn3DPlane provides a tangent, but if it does, use that. 我不确定您的Xn3DPlane是否提供切线,但是如果提供,则使用该切线。

The bitangent is given by the cross-product of the normal and the tangent: 切线由法线和切线的叉积给出:

 B = T x N

A TBN looks like this: TBN看起来像这样:

TBN = { Tx ,Ty ,Tz,
        Bx, By, Bz,
        Nx, Ny, Nz }

This will rotate your data on a new set of axis, but your plane also has an origin point, so we through in a translation: 这将使您的数据在一组新的轴上旋转,但是您的平面也有一个原点,因此我们进行平移:

A = {1 , 0 , 0, 0,    { Tx , Ty , Tz , 0,   
     0,  1,  0, 0,      Bx , By , Bz , 0,    
     0,  0,  1, 0,  x   Nx , Ny , Nz , 0, 
     -Px,-Py,-Pz,1}      0 ,  0 ,  0 , 1}    

// The multiply the vertex, v, to change it's coordinate system.
v = v * A

If you can get things to this stage, you can transform all your points to the new coordinate system. 如果可以解决这个问题,则可以将所有点转换为新的坐标系。 One thing to note, the normal is now aligned with the z axis, if you want it to be aligned with the y, swap N and B in the TBN matrix. 注意,法线现在与z轴对齐,如果希望它与y对齐,请在TBN矩阵中交换N和B。

EDIT: Final matrix calculation was slightly wrong. 编辑:最终矩阵计算略有错误。 Fixed. 固定。

TBN calculation. TBN计算。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM