在给定 vNormal 和地板点的情况下,旋转 3d 点云以偏移地板平面的角度

发布于 2024-11-29 21:57:10 字数 662 浏览 0 评论 0原文

我正在使用 kinect 和 ofxopeni。我在现实世界坐标中有一个点云,但我需要旋转这些点以抵消相机的倾斜。地板平面应该为我提供所需的所有信息,但我不知道如何计算轴和旋转角度。

我最初的想法是......

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)                               

}

到目前为止这似乎太简单了。我一直在浏览各种文章,发现它很可能涉及四分之一或旋转矩阵,但我不知道从哪里开始。我真的很感激任何相关文章的指示,或者获得轴和旋转角度的最佳技术是什么?我想使用 ofQuarterion 或 openni 函数可以很容易地完成它,但我不知道如何实现。

最好的

西蒙

I'm working with kinect and 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.

best

Simon

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

樱娆 2024-12-06 21:57:10

我从未使用过 ofxopeni,但这是我能给出的最好的数学解释。

您可以使用 TBN 矩阵(切线、双切线、法线)将任何数据集从一个轴集旋转到另一个轴集,其中 TB 和 N 是新的轴集。因此,您已经有了法线的数据,但您需要找到切线。我不确定您的 Xn3DPlane 是否提供切线,但如果提供,请使用它。

双切线由法线和切线的叉积给出:

 B = T x N

TBN 如下所示:

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

这将在一组新轴上旋转您的数据,但您的平面也有一个原点,因此我们进行平移:

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

如果你能做到这一点,你就可以将所有点转换到新的坐标系。需要注意的一件事是,法线现在与 z 轴对齐,如果您希望它与 y 轴对齐,请交换 TBN 矩阵中的 N 和 B。

编辑:最终的矩阵计算略有错误。固定的。

TBN 计算。

I've never used ofxopeni, but this is the best mathematical explanation I can give.

You can rotate any set of data from one axis set to another using a TBN matrix,(tangent, bitangent, normal), where T B and N are your new set of axis. 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.

The bitangent is given by the cross-product of the normal and the tangent:

 B = T x N

A TBN looks like this:

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.

EDIT: Final matrix calculation was slightly wrong. Fixed.

TBN calculation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文