Как преобразовать точки в пространстве глубины в цветовое пространство в Kinect без использования функций Kinect SDK?

Я делаю приложение дополненной реальности с наложением 3D-объектов поверх цветного видео пользователя. Используется Kinect версии 1.7, а рендеринг виртуальных объектов выполняется в OpenGL. Мне удалось успешно наложить 3D-объекты на видео глубины, просто используя встроенные константы для камеры глубины из заголовка NuiSensor.h и вычислив матрицу проекции на основе формулы, которую я нашел на http://ksimek.github.io/2013/06/03/calilated_cameras_in_opengl/. 3D-объекты, визуализированные с помощью этой проекционной матрицы, точно накладываются на точки 2D-скелета в пространстве глубины. Это неудивительно, поскольку скелетные 3D-точки вычисляются из пространства глубины и дают мне уверенность в том, что матрица проекций, вычисленная вне Kinect SDK, работает.

Вот несколько кодов для вычисления проекционной матрицы из внутренних констант и того, как она используется:

glm::mat4 GetOpenGLProjectionMatrixFromCameraIntrinsics(float alpha, float beta, float skew, float u0, float v0, 
    int img_width, int img_height, float near_clip, float far_clip ) 
{
    float L = 0;
    float R = (float)img_width;
    float B = 0;
    float T = (float)img_height;
    float N = near_clip;
    float F = far_clip;

    glm::mat4 ortho = glm::mat4(0);
    glm::mat4  proj = glm::mat4(0);

    //Using column major convention 
    ortho[0][0] =  2.0f/(R-L); 
    ortho[0][3] = -(R+L)/(R-L);     
    ortho[1][1] =  2.0f/(T-B); 
    ortho[1][3] = -(T+B)/(T-B);     
    ortho[2][2] = -2.0f/(F-N); 
    ortho[2][3] = -(F+N)/(F-N); 
    ortho[3][3] = 1; 

    proj[0][0] = alpha;     proj[0][1] = skew;  proj[0][2] = -u0;
    proj[1][1] = beta;  proj[1][2] = -v0;
    proj[2][2] = (N+F); proj[2][3] = (N*F);
    proj[3][2] = -1;

    //since glm is row major, we left multiply the two matrices
    //and then transpose the result to pass it to opengl which needs
    //the matrix in column major format
    return glm::transpose(proj*ortho);   
}

//Compute projection matrix of Kinect camera    
    m_3DProjectionMatrix = GetOpenGLProjectionMatrixFromCameraIntrinsics(m_fx, m_fy, m_skew, m_PPx0, m_PPy0, WIN_WIDTH, WIN_HEIGHT, 0.01f, 10);

//where the input variables are 1142.52, 1142.52, 0.00, 640.00, 480.00, 1280, 960 respectively for m_fx, m_fy, m_skew, m_PPx0, m_PPy0, WIN_WIDTH, WIN_HEIGHT. These numbers are derived from NuiImageCamera.h for depth camera.

Вот как рисуются 2D-точки:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();   
glOrtho(0, WIN_WIDTH, WIN_HEIGHT, 0, 0.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

Draw2DSkeletonRGBPoints();//Uses NuiTransformSkeletonToDepthImage() followed by NuiImageGetColorPixelCoordinatesFromDepthPixel()
Draw2DSkeletonDepthPoints();//Uses NuiTransformSkeletonToDepthImage() only

Далее идут 3D точки:

glMatrixMode(GL_PROJECTION);
glLoadMatrixf(glm::value_ptr(m_3DProjectionMatrix));
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

Draw3DSkeletonPoints();//The Skeleton 3D coordinates from Kinect

Однако наложение виртуальных объектов поверх цветного видео получается не так уж и просто. Кажется, есть какой-то перевод, масштабирование или даже небольшое вращение между цветом и пространством глубины. Я знаю, что есть функция SDK для преобразования точки скелета в точку цвета, но ее нельзя легко использовать для рендеринга OpenGL; Мне нужна матрица преобразования, которая отображает точки 3D-скелета в координатном пространстве скелета в 3D-точки с цветной камерой в качестве источника. Кто-нибудь знает, как вычислить эту матрицу преобразования? Где я могу найти дополнительную информацию о том, как это сделать?


person ksming    schedule 23.01.2014    source источник
comment
Возродив мой вопрос с комментарием, мне удалось в некоторой степени достичь своей цели, оценив относительную внешнюю матрицу (камера глубины относительно цветной камеры) с использованием методов ручного сопоставления, а затем применив эту матрицу к точкам 3D-скелета, заданным Kinect. Есть ли какие-либо обновления в API, чтобы я мог получить эту матрицу непосредственно из Kinect?   -  person ksming    schedule 24.06.2014