Como converter pontos no espaço de profundidade em espaço de cores no Kinect sem usar as funções do SDK do Kinect?

Estou fazendo um aplicativo de realidade aumentada com objetos 3D sobrepostos sobre o vídeo colorido do usuário. O Kinect versão 1.7 é usado e a renderização de objetos virtuais é feita no OpenGL. Eu consegui sobrepor objetos 3D em profundidade de vídeo com sucesso simplesmente usando as constantes intrínsecas para a câmera de profundidade do cabeçalho NuiSensor.h e calcular uma matriz de projeção com base na fórmula encontrada emhttp://ksimek.github.io/2013/06/03/03/calibrated_cameras_in_opengl/. Os objetos 3D renderizados com essa matriz de projeção se sobrepõem exatamente aos pontos esqueléticos 2D no espaço profundo. Isso não é surpreendente, pois os pontos 3D esqueléticos são computados do espaço profundo e me dão confiança de que a matriz de projeção computada fora do Kinect SDK funciona.

Aqui estão alguns códigos para o cálculo da matriz de projeção a partir de constantes intrínsecas e como ela é usada:

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.

Aqui está como os pontos 2D são desenhados:

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

Seguido por pontos 3D:

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

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

No entanto, a sobreposição de objetos virtuais sobre o vídeo colorido não é tão imediata. Parece haver alguma tradução, redimensionamento ou até uma leve rotação entre o espaço de cores e profundidade. Eu sei que existe uma função SDK para converter ponto de esqueleto em ponto de cor, mas isso não pode ser usado facilmente para renderização OpenGL; Eu preciso de uma matriz de transformação que mapeie os pontos do esqueleto 3D no espaço de coordenadas do esqueleto em pontos 3D com a câmera colorida como origem. Alguém sabe como calcular esta matriz de transformação? Onde posso encontrar mais informações sobre como fazer isso?

questionAnswers(0)

yourAnswerToTheQuestion