2011-01-21 10 views
5

Estoy jugando con el controlador Kinect, CL NUI y tratando de obtener la profundidad relativa de los elementos.Usando los controladores CL NUI Kinect, convierta el color de profundidad a la distancia relativa real

La biblioteca proporciona una forma de obtener una imagen que representa la profundidad de un objeto en la pantalla. Aquí hay un ejemplo:
Kinect Depth Image

¿Existe alguna manera fácil de convertir el color del píxel a la profundidad de las imágenes? Por ejemplo, el color más cercano podría ser la profundidad de 0, y el color más alejado podría ser la profundidad de 1.

¿Alguien sabe cómo hacer eso?

He encontrado estos cacluations sobre cómo convertir los datos de profundidad de color, lo que quiero es la inversa:

float RawDepthToMeters(int depthValue) 
{ 
    if (depthValue < 2047) 
    { 
     return float(1.0/(double(depthValue) * -0.0030711016 + 3.3309495161)); 
    } 
    return 0.0f; 
} 

Vec3f DepthToWorld(int x, int y, int depthValue) 
{ 
    static const double fx_d = 1.0/5.9421434211923247e+02; 
    static const double fy_d = 1.0/5.9104053696870778e+02; 
    static const double cx_d = 3.3930780975300314e+02; 
    static const double cy_d = 2.4273913761751615e+02; 

    Vec3f result; 
    const double depth = RawDepthToMeters(depthValue); 
    result.x = float((x - cx_d) * depth * fx_d); 
    result.y = float((y - cy_d) * depth * fy_d); 
    result.z = float(depth); 
    return result; 
} 

Vec2i WorldToColor(const Vec3f &pt) 
{ 
    static const Matrix4 rotationMatrix(
          Vec3f(9.9984628826577793e-01f, 1.2635359098409581e-03f, -1.7487233004436643e-02f), 
          Vec3f(-1.4779096108364480e-03f, 9.9992385683542895e-01f, -1.2251380107679535e-02f), 
          Vec3f(1.7470421412464927e-02f, 1.2275341476520762e-02f, 9.9977202419716948e-01f)); 
    static const Vec3f translation(1.9985242312092553e-02f, -7.4423738761617583e-04f, -1.0916736334336222e-02f); 
    static const Matrix4 finalMatrix = rotationMatrix.Transpose() * Matrix4::Translation(-translation); 

    static const double fx_rgb = 5.2921508098293293e+02; 
    static const double fy_rgb = 5.2556393630057437e+02; 
    static const double cx_rgb = 3.2894272028759258e+02; 
    static const double cy_rgb = 2.6748068171871557e+02; 

    const Vec3f transformedPos = finalMatrix.TransformPoint(pt); 
    const float invZ = 1.0f/transformedPos.z; 

    Vec2i result; 
    result.x = Utility::Bound(Math::Round((transformedPos.x * fx_rgb * invZ) + cx_rgb), 0, 639); 
    result.y = Utility::Bound(Math::Round((transformedPos.y * fy_rgb * invZ) + cy_rgb), 0, 479); 
    return result; 
} 

Mi matriz matemática es débil, y no estoy seguro de cómo revertir los cálculos.

Respuesta

3

he encontrado la solución.

El valor de profundidad se almacena en la imagen CLNUIDevice.GetCameraDepthFrameRAW. El color de esta imagen se crea a partir del valor de profundidad de once bits. ES DECIR. tiene 24 bits para el color RGB (32 si es ARGB). Para obtener la profundidad, es necesario truncar los bits innecesarios como esto:

private int colorToDepth(Color c) { 
     int colorInt = c.ToArgb(); 

     return (colorInt << 16) >> 16; 
    } 

Se utilizan 16, ya que el número de 11 bits es 0 acolchado para el lugar 16 bits. ES DECIR. tiene un número que se ve así: 1111 1111 0000 0 ### #### #### donde el 1 es el canal alfa, los ceros son el relleno, y el '#' es el valor real. Bitshifting a la izquierda 16 te deja con 0000 0 ### #### #### 0000 0000, que deseas retrasar mi cambio a la derecha 16 veces: 0000 0000 0000 0 ### #### #####

+0

Bitwise Y con 0x7FF – CWMan

0

Corregirme si me equivoco pero por lo que entiendo su código recibe una matriz de profundidad del Kinect, la convierte en objetos "mundiales" (con coordenadas x, y, z) usando DepthToWorld, luego la convierte en una color 2D array usando WorldToColor. A partir de eso, intenta recuperar la distancia (en metros) de cada píxel en relación con Kinect. ¿Derecha?

¿Por qué no solo toma la matriz de profundidad inicial que obtiene de Kinect, y llama a la función RawDepthToMeters en cada uno de los píxeles?

inversing las operaciones realizadas por el código justo antes es una enorme pérdida de rendimiento ...

+0

Eso está dentro de la biblioteca, solo obtengo la salida de color. – Malfist

Cuestiones relacionadas