Comment faites-vous la carte Kinect de données sur la profondeur de sa couleur RVB?
Je travaille avec un dataset à l'aide d'OpenCV, sans Kinect à mes côtés. Et je voudrais carte de la profondeur des données RVB homologue (afin que je puisse obtenir la couleur réelle et la profondeur)
Depuis que je suis en utilisant OpenCV et C++, et ne possède pas de Kinect, malheureusement je ne peux pas utiliser MapDepthFrameToColorFrame méthode de l'officiel Kinect API.
À partir de la donnée des caméras intrinsèques et de la distorsion des coefficients, j'ai pu la carte de la profondeur de coordonnées du monde, et à l'arrière de RVB basé sur l'algorithme fourni ici
Vec3f depthToW( int x, int y, float depth ){
Vec3f result;
result[0] = (float) (x - depthCX) * depth /depthFX;
result[1] = (float) (y - depthCY) * depth /depthFY;
result[2] = (float) depth;
return result;
}
Vec2i wToRGB( const Vec3f & point ) {
Mat p3d( point );
p3d = extRotation * p3d + extTranslation;
float x = p3d.at<float>(0, 0);
float y = p3d.at<float>(1, 0);
float z = p3d.at<float>(2, 0);
Vec2i result;
result[0] = (int) round( (x * rgbFX /z) + rgbCX );
result[1] = (int) round( (y * rgbFY /z) + rgbCY );
return result;
}
void map( Mat& rgb, Mat& depth ) {
/* intrinsics are focal points and centers of camera */
undistort( rgb, rgb, rgbIntrinsic, rgbDistortion );
undistort( depth, depth, depthIntrinsic, depthDistortion );
Mat color = Mat( depth.size(), CV_8UC3, Scalar(0) );
ushort * raw_image_ptr;
for( int y = 0; y < depth.rows; y++ ) {
raw_image_ptr = depth.ptr<ushort>( y );
for( int x = 0; x < depth.cols; x++ ) {
if( raw_image_ptr[x] >= 2047 || raw_image_ptr[x] <= 0 )
continue;
float depth_value = depthMeters[ raw_image_ptr[x] ];
Vec3f depth_coord = depthToW( y, x, depth_value );
Vec2i rgb_coord = wToRGB( depth_coord );
color.at<Vec3b>(y, x) = rgb.at<Vec3b>(rgb_coord[0], rgb_coord[1]);
}
}
Mais le résultat semble être alignés. Je ne peux pas définir manuellement les traductions, depuis le jeu de données est obtenu à partir de 3 différentes Kinects, et chacun d'eux ne sont pas alignés dans la même direction. Vous pouvez voir l'un de ci-dessous (à Gauche: non faussée RVB, Moyen: non faussée Profondeur, à Droite: mappé RVB de Profondeur)
Ma question est, que dois-je faire à ce stade ? Ai-je raté une étape, tout en essayant de projet, que ce soit la profondeur du monde, du monde ou de retour en RGB ? Peut quelqu'un qui a expérimenté avec la caméra stéréo signaler mes erreurs ?
Je vous remercie beaucoup à l'avance !
Malheureusement pas. Seulement OpenCV
Je suggère, vous devez utiliser OpenNI pour récupérer les données à partir de Kinect. Il y a une fonction intégrée de fonction dans OpenNI qui peut le faire pour vous.
Les données n'a pas l'air mal alignées dans la troisième image. Il semble correct si mes hypothèses sont correctes. Le blanc des données semble être de zéro de données, ou des données que la profondeur de la caméra ne peut pas reconnaître que dans la gamme. Par conséquent, la combinaison des deux devrait avoir tout à zéro des données éliminé comme il n'y a pas de profondeur de données qui peuvent être liés à elle, de la création de la 'null zones" comme vous le voyez dans l'image de trois.
OriginalL'auteur sub_o | 2013-06-09
Vous devez vous connecter pour publier un commentaire.
Je suppose que vous devez étalonner le capteur de profondeur avec les données RVB de la même manière que vous le feriez calibrer une chaîne stéréo caméras. OpenCV a certaines fonctions (et tutoriels) que vous pouvez être en mesure de l'effet de levier.
Quelques autres choses qui peuvent être utiles
Il contient un livre sur la façon de le faire.
OriginalL'auteur Bull
OpenCV n'a pas de fonctions pour l'alignement de la profondeur de flux de couleur flux vidéo. Mais je sais qu'il y a fonction spéciale nommé
MapDepthFrameToColorFrame
dans "Kinect pour Windows SDK".Je n'ai pas de code pour l'exemple, mais nous espérons que c'est un bon point de départ.
Upd:
Voici même exemple de cartographie de la couleur de l'image de profondeur à l'aide de KinectSDK avec l'interface d'OpenCV (pas mon code).
OriginalL'auteur brotherofken
Il semble que vous ne sont pas à considérer dans votre solution de la extrinsics entre les deux caméras.
OriginalL'auteur Pablo Iñigo Blasco
Oui, vous n'avez pas envisager la transformation entre RVB et de la Profondeur.
Mais vous pouvez calculer cette matrice à l'aide de cvStereoCalibrate() méthode qui vient de passer les séquences d'images de format RVB et en Profondeur avec damier coins.
Le détail vous pouvez trouver dans OpecvCV de la documentation:
http://docs.opencv.org/2.4/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html#double stereoCalibrate(InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints1, InputArrayOfArrays imagePoints2, InputOutputArray cameraMatrix1, InputOutputArray distCoeffs1, InputOutputArray cameraMatrix2, InputOutputArray distCoeffs2, Taille-image, OutputArray R, OutputArray T, OutputArray E, OutputArray F, TermCriteria critères, int flags)
Et l'ensemble de la méthode de l'idée derrière cela est:
couleur uv < couleur de normaliser <- espace de couleur <- DtoC transformation <- profondeur de l'espace <- profondeur de normaliser < profondeur uv
(uc,vc) <- <- ExtrCol * (pc) <- stéréo calibrer MAT <- ExtrDep^-1 * (pd) <- <(ud - cx)*d /fx, (vd-cy)*d/af, d> <- (ud, vd)
Si vous voulez ajouter un effet de distorsion sur RGB, il vous suffit de suivre l'étape de:
http://docs.opencv.org/2.4/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html
OriginalL'auteur EdwinDebuger