Преобразование трехмерной системы координат (X, Y, Z) в (X ‘, Y’, Z ‘)

Я работаю с новым Kinect v2 для справки, и у меня есть рабочая система координат для данного кадра с координатами (x, y, z) в мм. Я пытаюсь выровнять, преобразовать или связать системы координат камеры Kinect и системы координат объекта, на который она смотрит.

Этот объект имеет свою собственную систему координат и перемещается только по осям x, y и z. Кинект отслеживает объект, возвращая координаты мира x, y, z с кинектом в начале координат. Тем не менее, я также могу указать новый источник в том же координатном кадре, просто принимая во внимание смещения x, y и z.

Я думал, что если бы у меня был объект, начинающийся в позиции с тем же происхождением, я мог бы выяснить, как перевести его движения x ‘, y’ и z ‘, используя заданные kinect координаты.

Вы можете видеть то, о чем я говорю, с этим (плохим) рисунком.

Плохой рисунок

Есть ли способ, которым я могу установить координатную рамку, учитывая новый набор значений x ‘, y’ и z ‘? Допустим, у меня есть 3 набора координат ОБА и рамки объекта, и рамки кинекта.

Итак, как я могу перевести (x, y, z) в (x ‘, y’, z ‘) фрейм, если я ЗНАЮ начальные значения 3 пары (x, y, z) и (x ‘, y’, z ‘).

2

Решение

Я на самом деле решил свою проблему здесь с помощью простого изменение базового метода. Поскольку обе системы координат являются ортонормированный, и иметь того же происхождения, это было так же просто, как построить матрицу изменения базиса и использовать ее для перехода от одной системы координат к другой.

Вот мой код, на случай, если кто-нибудь ищет, как это сделать с помощью 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);
2

Другие решения