2013-04-10 5 views
18

Je travaille avec le capteur Kinect et j'essaie d'aligner les trames de profondeur et de couleur afin de pouvoir les enregistrer comme des images qui s'intègrent l'une dans l'autre. J'ai passé beaucoup de temps à parcourir les forums msdn et la documentation modeste de Kinect SDK et je ne reçois absolument nulle part.Kinect SDK: aligner les trames de profondeur et de couleur

Sur la base de cette réponse: Kinect: Converting from RGB Coordinates to Depth Coordinates

I ont la fonction suivante, où depthData et colorData sont obtenus à partir NUI_LOCKED_RECT.pBits et mappedData est la sortie contenant nouvelle trame de couleur, mis en correspondance avec des coordonnées de profondeur:

bool mapColorFrameToDepthFrame(unsigned char *depthData, unsigned char* colorData, unsigned char* mappedData) 
{ 
    INuiCoordinateMapper* coordMapper; 

    // Get coordinate mapper 
    m_pSensor->NuiGetCoordinateMapper(&coordMapper); 

    NUI_DEPTH_IMAGE_POINT* depthPoints = new NUI_DEPTH_IMAGE_POINT[640 * 480]; 

    HRESULT result = coordMapper->MapColorFrameToDepthFrame(NUI_IMAGE_TYPE_COLOR, NUI_IMAGE_RESOLUTION_640x480, NUI_IMAGE_RESOLUTION_640x480, 640 * 480, reinterpret_cast<NUI_DEPTH_IMAGE_PIXEL*>(depthData), 640 * 480, depthPoints); 
    if (FAILED(result)) 
    { 
     return false; 
    }  

    int pos = 0; 
    int* colorRun = reinterpret_cast<int*>(colorData); 
    int* mappedRun = reinterpret_cast<int*>(mappedData); 

    // For each pixel of new color frame 
    for (int i = 0; i < 640 * 480; ++i) 
    { 
     // Find the corresponding pixel in original color frame from depthPoints 
     pos = (depthPoints[i].y * 640) + depthPoints[i].x; 

     // Set pixel value if it's within frame boundaries 
     if (pos < 640 * 480) 
     { 
      mappedRun[i] = colorRun[pos]; 
     } 
    } 

    return true; 
} 

Tout ce que je reçois lors de l'exécution de ce code est un cadre de couleur inchangé avec tous les pixels (blancs) supprimés où depthFrame n'avait aucune information.

+0

Avez-vous vérifié l'exemple d'écran vert dans le Kinect pour des exemples de codage de Windows? http://kinectforwindows.codeplex.com/. Il aligne la couleur et la profondeur. –

+0

Oui, j'ai. Il n'utilise pas le nouveau 'INuiCoordinateMapper', mais une ancienne méthode' INuiSensor :: NuiImageGetColorPixelCoordinateFrameFromDepthPixelFrameAtResolution'. Je l'ai essayé et ça ne marche pas non plus pour moi (j'obtiens toute l'image blanche). D'une certaine façon, le tableau de valeurs de profondeur qu'ils obtiennent est USHORT (16 bits) et le mien est de 32 bits, avec la raison possible que j'initialise mon capteur Kinect avec différents paramètres (profondeur seulement aucun index de joueur). Même si je crée un tableau de valeurs de profondeur de 16 bits à partir du bit 32, la fonction ne fonctionne pas pour moi. – jaho

+0

chose similaire a été résolu ici: http://stackoverflow.com/a/19905805/2521214 Kinect SDK a des fonctions pour alligner les images, mais ils n'ont pas fonctionné pour moi du tout (ont une très ancienne version de Kinect) donc je l'ai fait moi-même ... dans ce lien est mes données d'étalonnage kinect pour le vôtre, vous devez le mesurer vous-même – Spektre

Répondre

2

Avec le framework OpenNI il existe une option d'enregistrement d'appel.

IMAGE_REGISTRATION_DEPTH_TO_IMAGE - L'image de profondeur est transformée pour avoir le même point de vue apparent que l'image RVB. OpenNI 2.0 et Nite 2.0 fonctionnent très bien pour capturer des informations Kinect et il y a beaucoup de tutoriels.

Vous pouvez jeter un oeil à ceci:

Kinect with OpenNI

Et OpenNI un exemple dans SimplerViewer que la fusion et la profondeur de couleur peut-être vous pouvez simplement regarder cela et essayer.

0

Cela peut ne pas être la réponse rapide que vous espérez, mais cette transformation est effectuée avec succès dans l'addon ofxKinectNui pour openFrameworks (see here). Il ressemble à ofxKinectNui délégués à la fonction GetColorPixelCoordinatesFromDepthPixel définie here.

0

Je pense que le problème est que vous appelez MapColorFrameToDepthFrame, alors que vous devriez appeler MapDepthFrameToColorFrame.

Le pistolet fumant est cette ligne de code:

mappedRun[i] = colorRun[pos]; 

lecture de pos et de l'écriture à i est en arrière, puisque pos = depthPoints[i] représente la profondeur des coordonnées correspondant à la couleur les coordonnées à i. Vous voulez réellement itérer sur l'écriture de toutes les coordonnées profondeur et lire à partir de l'image couleur d'entrée aux coordonnées couleur correspondant.

+0

Ces fonctions sont-elles interchangeables de cette manière? –

0

Je pense que dans votre code, il y a différentes lignes incorrectes.

Tout d'abord, quel type de carte de profondeur passez-vous à votre fonction?

données de profondeur est storred en utilisant deux octets pour chaque valeur, cela signifie que le type correct du pointeur que vous devez utiliser pour vos données de profondeur est court non signé.

Deuxième point est que d'après ce que je comprends, vous voulez mapper cadre de profondeur sur le cadre de couleur, de sorte que la fonction correcte que vous avez appeler de sdk kinect est MapDepthFrameToColorFrame au lieu de MapColorFrameToDepthFrame.

Enfin, la fonction retournera une carte du point où, pour chaque donnée de profondeur à la position [i], vous avez la position x et la position y où ce point doit être mappé.
Pour cela, vous n'avez pas besoin de colorData pointeur.

Ainsi, votre fonction doit être modifié comme suit:

/** Method used to build a depth map aligned to color frame 
    @param [in] depthData : pointer to your data; 
    @param [out] mappedData : pointer to your aligned depth map; 
    @return true if is all ok : false whene something wrong 
*/ 

bool DeviceManager::mapColorFrameToDepthFrame(unsigned short *depthData, unsigned short* mappedData){ 
    INuiCoordinateMapper* coordMapper; 
    NUI_COLOR_IMAGE_POINT* colorPoints = new NUI_COLOR_IMAGE_POINT[640 * 480]; //color points 
    NUI_DEPTH_IMAGE_PIXEL* depthPoints = new NUI_DEPTH_IMAGE_PIXEL[640 * 480]; // depth pixel 

    /** BE sURE THAT YOU ARE WORKING WITH THE RIGHT HEIGHT AND WIDTH*/ 
    unsigned long refWidth = 0; 
    unsigned long refHeight = 0; 
    NuiImageResolutionToSize(NUI_IMAGE_RESOLUTION_640x480, refWidth, refHeight); 
    int width = static_cast<int>(refWidth ); //get the image width in a right way 
    int height = static_cast<int>(refHeight); //get the image height in a right way 

    m_pSensor>NuiGetCoordinateMapper(&coordMapper); // get the coord mapper 
    //Map your frame; 
    HRESULT result = coordMapper->MapDepthFrameToColorFrame(NUI_IMAGE_RESOLUTION_640x480, width * height, depthPoints, NUI_IMAGE_TYPE_COLOR, NUI_IMAGE_RESOLUTION_640x480, width * height, colorPoints); 
    if (FAILED(result)) 
     return false; 

    // apply map in terms of x and y (image coordinates); 
    for (int i = 0; i < width * height; i++) 
     if (colorPoints[i].x >0 && colorPoints[i].x < width && colorPoints[i].y>0 && colorPoints[i].y < height) 
      *(mappedData + colorPoints[i].x + colorPoints[i].y*width) = *(depthData + i); 

    // free your memory!!! 
    delete colorPoints; 
    delete depthPoints; 
    return true; 
} 



Assurez-vous que votre mappedData a été initialisé de manière correcte, par exemple comme suit.

mappedData = (USHORT*)calloc(width*height, sizeof(ushort)); 


Rappelez-vous que sdk kinect ne fournit pas une fonction d'alignement précis entre les couleurs et les données de profondeur.

Si vous souhaitez un alignement précis entre deux images, vous devez utiliser un modèle d'étalonnage. Dans ce cas, je vous suggère d'utiliser la boîte à outils de calibrage Kinect, basée sur le modèle d'étalonnage Heikkilä. Vous pouvez le trouver dans le lien suivant:

-1

Tout d'abord, vous devez calibrer votre appareil. Cela signifie que vous devez calibrer le capteur RVB et le capteur IR, puis trouver la transformation entre RVB et IR. Une fois que vous connaissez ces informations, vous pouvez appliquer la fonction:

RGBPoint = RotationMatrix * DepthPoint + TranslationVector 

Vérifier OpenCV ou projets EOR pour plus de détails à ce sujet.

Extrinsic Calibration

Intrinsic Calibration

+0

où puis-je trouver l'information concernant la transformation? – ThunderWiring

+0

@ThunderWiring ici vous trouverez plus de détails: http://wiki.ros.org/openni_launch/Tutorials/IntrinsicCalibration et ici: http://wiki.ros.org/openni_launch/Tutorials/ExtrinsicCalibration – madduci

Questions connexes