Jak przekonwertować przestrzeń w głębi na przestrzeń kolorów w Kinect bez użycia funkcji Kinect SDK?

Robię aplikację rzeczywistości rozszerzonej z nakładką obiektów 3D na kolorowym wideo użytkownika. Używana jest wersja Kinect 1.7, a renderowanie wirtualnych obiektów odbywa się w OpenGL. Udało mi się z powodzeniem nałożyć obiekty 3D na wideo głębi, po prostu używając wewnętrznych stałych dla kamery głębi z nagłówka NuiSensor.h i obliczając macierz projekcji na podstawie wzoru, który znalazłem nahttp://ksimek.github.io/2013/06/03/calibrated_cameras_in_opengl/. Obiekty 3D renderowane za pomocą tej nakładki macierzy rzutowania dokładnie z punktami szkieletu 2D w przestrzeni głębokości. Nie jest to zaskakujące, ponieważ punkty 3D szkieletu są obliczane z przestrzeni głębi i dają mi pewność, że macierz projekcji obliczona poza SDK Kinect działa.

Oto kilka kodów do obliczania macierzy rzutowania ze stałych wewnętrznych i sposobu ich użycia:

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.

Oto jak rysowane są punkty 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

Następują punkty 3D:

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

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

Jednak nakładanie wirtualnych obiektów na kolorowe wideo nie jest takie od razu. Wydaje się, że istnieje pewne tłumaczenie, skalowanie lub nawet niewielka rotacja między kolorem a przestrzenią głębi. Wiem, że istnieje funkcja SDK do konwersji punktu szkieletu na punkt koloru, ale nie można tego łatwo użyć do renderowania OpenGL; Potrzebuję macierzy transformacji, która odwzorowuje punkty szkieletu 3D w przestrzeni współrzędnych szkieletu w punkty 3D za pomocą kamery Kolor jako źródła. Czy ktoś wie, jak obliczyć tę macierz transformacji? Gdzie mogę znaleźć więcej informacji na ten temat?

questionAnswers(0)

yourAnswerToTheQuestion