¿Cómo convertir los puntos en el espacio de profundidad al espacio de color en Kinect sin usar las funciones del SDK de Kinect?

Estoy haciendo una aplicación de realidad aumentada con objetos 3D superpuestos sobre el video en color del usuario. Se utiliza Kinect versión 1.7 y la representación de objetos virtuales se realiza en OpenGL. Me las arreglé para superponer objetos 3D en video de profundidad con éxito simplemente usando las constantes intrínsecas para la cámara de profundidad del encabezado NuiSensor.h y calcular una matriz de proyección basada en la fórmula que he encontrado enhttp://ksimek.github.io/2013/06/03/calibrated_cameras_in_opengl/. Los objetos 3D renderizados con esta matriz de proyección se superponen exactamente con los puntos esqueléticos 2D en el espacio de profundidad. Esto no es sorprendente, ya que los puntos 3D esqueléticos se calculan desde el espacio de profundidad y me dan la confianza de que la matriz de proyección calculada fuera de Kinect SDK funciona.

Aquí hay algunos códigos para el cálculo de la matriz de proyección a partir de constantes intrínsecas y cómo se utiliza:

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.

Así es como se dibujan los puntos 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

Seguido por puntos 3D:

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

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

Sin embargo, la superposición de objetos virtuales sobre el video en color no es tan inmediato. Parece que hay alguna traslación, escalado o incluso ligera rotación entre el color y el espacio de profundidad. Sé que hay una función SDK para convertir el punto de esqueleto en un punto de color, pero esto no se puede usar fácilmente para la representación de OpenGL; Necesito una matriz de transformación que asigne puntos de esqueleto 3D en el espacio de coordenadas de esqueleto en puntos 3D con la cámara de color como origen. ¿Alguien sabe cómo hacer para calcular esta matriz de transformación? ¿Dónde puedo encontrar más información sobre cómo hacer esto?

Respuestas a la pregunta(0)

Su respuesta a la pregunta