3D坐标系转换(X,Y,Z)到(X',Y',Z')

时间:2014-07-31 21:47:53

标签: c++ opencv geometry kinect coordinate-transformation

我正在使用新的Kinect v2作为参考,我有一个适用于给定帧的工作坐标系,坐标(x,y,z)以mm为单位。我想要做的是排列,转换或关联Kinect相机的坐标系和它正在看的对象的坐标系。

此对象具有自己的坐标系,仅在x,y和z轴上移动。 kinect跟踪对象,返回世界x,y,z坐标与原点的kinect。但是,我也可以在同一坐标系中指定一个新的原点,只需要考虑x,y和z偏移。

我在想,如果我的对象从一个起源相同的位置开始,我就可以弄清楚如何翻译它的x',y'和z'使用kinect给定坐标的运动。

你可以通过这个(糟糕的)绘图看到我在这里谈论的内容。

Bad Drawing

有一种方法可以设置一个坐标系,给定一组新的x',y'和z'值? 我们说我在对象框架和kinect框架中有3组坐标。

那么,如果我知道 3对的初始值,我怎样才能将(x,y,z)翻译成(x',y',z')帧? strong>(x,y,z)和(x',y',z')。

1 个答案:

答案 0 :(得分:2)

我实际上使用简单的更改基础方法解决了我自己的问题。由于两个坐标系都是 orthonormal ,并且具有相同的原点,因此它就像构造基础变换矩阵一样简单,并使用它来自一个协调系统到另一个。

这是我的代码,以防有人正在研究如何使用c ++ / opencv执行此操作。我使用cv::Mat来进行矩阵操作。

// Object coordinate frame with orthonormal basis vectors u,v,w.
// Each basis vector has components x,y,z.

float U[3] = { ux, uy, uz };
float V[3] = { vx, vy, vz };
float W[3] = { wx, wy, wz };

// Create lenghts to normalize the vectors.
float ulength = sqrt(ux*ux + uy*uy + uz*uz);
float vlength = sqrt(vx*vx + vy*vy + vz*vz);
float wlength = sqrt(wx*wx + wy*wy + wz*wz);

// Setting up the change of basis matrix.
float data[3][3] = { { ux / ulength, uy / ulength, uz / ulength },
{ vx / vlength, vy / vlength, vz / vlength },
{ wx / wlength, wy / wlength, wz / wlength } };

// Store array into cv::Mat
cv::Mat M = cv::Mat(3, 3, CV_32FC1, &data);

// Create vector Mat of coordinates in kinect frame.
float kinectcoords[3] = { x, y, z};
cv::Mat D = cv::Mat(3, 1, CV_32FC1, &kinectcoords);

// Find coordinates in object frame.

// If D is the coordinate vector in the kinect frame, P is the coordinate vector
// in the object frame, and M is the change of basis matrix, then the method is
// P = Minv * D. cv::Mat objectcoords is my 'P' vector.

cv::Mat Minv = M.inv();
cv::Mat objectcoords = Minv * D;

float objx = objectcoords.at<float>(0);
float objy = objectcoords.at<float>(1);
float objz = objectcoords.at<float>(2);