image - simple - Kinect: Conversión de Coordenadas RGB a Coordenadas de Profundidad
simple openni (2)
Estoy usando Windows Kinect SDK para obtener imágenes de profundidad y RGB del sensor.
Dado que la imagen de profundidad y las imágenes RGB no se alinean, me gustaría encontrar una forma de convertir las coordenadas de la imagen RGB a la de la imagen de profundidad, ya que quiero usar una máscara de imagen en la imagen de profundidad que he obtenido de algo de procesamiento en la imagen RGB.
Ya existe un método para convertir las coordenadas de profundidad a las coordenadas de espacio de color:
NuiImageGetColorPixelCoordinatesFromDepthPixel
desafortunadamente, lo contrario no existe. Solo hay una llamada arcana en INUICoordinateMapper:
HRESULT MapColorFrameToDepthFrame(
NUI_IMAGE_RESOLUTION eColorResolution,
NUI_IMAGE_RESOLUTION eDepthResolution,
DWORD cDepthPixels,
NUI_DEPTH_IMAGE_PIXEL *pDepthPixels,
DWORD cDepthPoints,
NUI_DEPTH_IMAGE_POINT *pDepthPoints
)
Cómo funciona este método no está muy bien documentado. Alguien lo ha usado antes?
Estoy a punto de realizar una calibración manual para calcular una matriz de transformación, por lo que estaría muy feliz de tener una solución.
Gracias al commenter horristic, obtuve un enlace a msdn con información útil (gracias también a T. Chen en msdn por ayudarme con la API). Extraído de la publicación de T. Chen, aquí está el código que realizará la asignación de RGB al espacio de coordenadas de profundidad:
INuiCoordinateMapper* pMapper;
mNuiSensor->NuiGetCoordinateMapper(&pMapper);
pMapper->MapColorFrameToDepthFrame(
NUI_IMAGE_TYPE_COLOR,
NUI_IMAGE_RESOLUTION_640x480,
NUI_IMAGE_RESOLUTION_640x480,
640 * 480,
(NUI_DEPTH_IMAGE_PIXEL*)LockedRect.pBits,
640 * 480,
depthPoints);
Nota: el sensor debe inicializarse y un cuadro de profundidad bloqueado para que funcione.
Las coordenadas transformadas pueden, por ejemplo, consultarse de la siguiente manera:
/// transform RGB coordinate point to a depth coordinate point
cv::Point TransformRGBtoDepthCoords(cv::Point rgb_coords, NUI_DEPTH_IMAGE_POINT * depthPoints)
{
long index = rgb_coords.y * 640 + rgb_coords.x;
NUI_DEPTH_IMAGE_POINT depthPointAtIndex = depthPoints[index];
return cv::Point(depthPointAtIndex.x, depthPointAtIndex.y);
}
Hasta donde puedo decir, MapColorFrameToDepthFrame
ejecuta efectivamente la conversión del sistema de coordenadas en cada píxel de tu imagen RGB, almacenando las coordenadas de la imagen de profundidad resultantes de la conversión y el valor de profundidad resultante en la matriz NUI_DEPTH_IMAGE_POINT
salida. La definición de esa estructura está aquí: http://msdn.microsoft.com/en-us/library/nuiimagecamera.nui_depth_image_point.aspx
Posiblemente esto sea excesivo para sus necesidades, sin embargo, y no tengo idea de qué tan rápido es ese método. Los desarrolladores de XBOX Kinect tienen una implementación muy rápida de esa función que se ejecuta en la GPU a una velocidad de cuadro, ¡los desarrolladores de Windows pueden no ser tan afortunados!