rgbd_util.cpp
Go to the documentation of this file.
00001 
00024 #include "ccny_rgbd/rgbd_util.h"
00025 
00026 namespace ccny_rgbd {
00027 
00028 void getTfDifference(const tf::Transform& motion, double& dist, double& angle)
00029 {
00030   dist = motion.getOrigin().length();
00031   double trace = motion.getBasis()[0][0] + motion.getBasis()[1][1] + motion.getBasis()[2][2];
00032   angle = acos(std::min(1.0, std::max(-1.0, (trace - 1.0)/2.0)));
00033 }
00034 
00035 void getTfDifference(const tf::Transform& a, const tf::Transform b, double& dist, double& angle)
00036 {
00037   tf::Transform motion = a.inverse() * b;
00038   getTfDifference(motion, dist, angle);
00039 }
00040 
00041 tf::Transform tfFromEigen(Eigen::Matrix4f trans)
00042 {
00043   tf::Matrix3x3 btm;
00044   btm.setValue(trans(0,0),trans(0,1),trans(0,2),
00045             trans(1,0),trans(1,1),trans(1,2),
00046             trans(2,0),trans(2,1),trans(2,2));
00047   tf::Transform ret;
00048   ret.setOrigin(tf::Vector3(trans(0,3),trans(1,3),trans(2,3)));
00049   ret.setBasis(btm);
00050   return ret;
00051 }
00052 
00053 Eigen::Matrix4f eigenFromTf(const tf::Transform& tf)
00054 {
00055    Eigen::Matrix4f out_mat;
00056 
00057    double mv[12];
00058    tf.getBasis().getOpenGLSubMatrix(mv);
00059 
00060    tf::Vector3 origin = tf.getOrigin();
00061 
00062    out_mat (0, 0) = mv[0]; out_mat (0, 1) = mv[4]; out_mat (0, 2) = mv[8];
00063    out_mat (1, 0) = mv[1]; out_mat (1, 1) = mv[5]; out_mat (1, 2) = mv[9];
00064    out_mat (2, 0) = mv[2]; out_mat (2, 1) = mv[6]; out_mat (2, 2) = mv[10];
00065 
00066    out_mat (3, 0) = out_mat (3, 1) = out_mat (3, 2) = 0; out_mat (3, 3) = 1;
00067    out_mat (0, 3) = origin.x ();
00068    out_mat (1, 3) = origin.y ();
00069    out_mat (2, 3) = origin.z ();
00070 
00071    return out_mat;
00072 }
00073 
00074 void tfToXYZRPY(
00075   const tf::Transform& t,
00076   double& x,    double& y,     double& z,
00077   double& roll, double& pitch, double& yaw)
00078 {
00079   x = t.getOrigin().getX();
00080   y = t.getOrigin().getY();
00081   z = t.getOrigin().getZ();
00082 
00083   tf::Matrix3x3  m(t.getRotation());
00084   m.getRPY(roll, pitch, yaw);
00085 }
00086 
00087 bool tfGreaterThan(const tf::Transform& tf, double dist, double angle)
00088 {
00089   double d = tf.getOrigin().length();
00090   
00091   if (d >= dist) return true;
00092 
00093   double trace = tf.getBasis()[0][0] + tf.getBasis()[1][1] + tf.getBasis()[2][2];
00094   double a = acos(std::min(1.0, std::max(-1.0, (trace - 1.0)/2.0)));
00095 
00096   if (a > angle) return true;
00097   
00098   return false;
00099 }
00100 
00101 double getMsDuration(const ros::WallTime& start)
00102 {
00103   return (ros::WallTime::now() - start).toSec() * 1000.0;
00104 }
00105 
00106 void removeInvalidMeans(
00107   const Vector3fVector& means,
00108   const BoolVector& valid,
00109   Vector3fVector& means_f)
00110 {
00111   unsigned int size = valid.size(); 
00112   for(unsigned int i = 0; i < size; ++i)
00113   {
00114     if (valid[i])
00115     {
00116       const Vector3f& mean = means[i];
00117       means_f.push_back(mean);
00118     }
00119   }
00120 }
00121 
00122 void removeInvalidDistributions(
00123   const Vector3fVector& means,
00124   const Matrix3fVector& covariances,
00125   const BoolVector& valid,
00126   Vector3fVector& means_f,
00127   Matrix3fVector& covariances_f)
00128 {
00129   unsigned int size = valid.size(); 
00130   for(unsigned int i = 0; i < size; ++i)
00131   {
00132     if (valid[i])
00133     {
00134       const Vector3f& mean = means[i];
00135       const Matrix3f& cov  = covariances[i];
00136 
00137       means_f.push_back(mean);
00138       covariances_f.push_back(cov);
00139     }
00140   }
00141 }
00142 
00143 void tfToEigenRt(
00144   const tf::Transform& tf, 
00145   Matrix3f& R, 
00146   Vector3f& t)
00147 {
00148    double mv[12];
00149    tf.getBasis().getOpenGLSubMatrix(mv);
00150 
00151    tf::Vector3 origin = tf.getOrigin();
00152 
00153    R(0, 0) = mv[0]; R(0, 1) = mv[4]; R(0, 2) = mv[8];
00154    R(1, 0) = mv[1]; R(1, 1) = mv[5]; R(1, 2) = mv[9];
00155    R(2, 0) = mv[2]; R(2, 1) = mv[6]; R(2, 2) = mv[10];
00156 
00157    t(0, 0) = origin.x();
00158    t(1, 0) = origin.y();
00159    t(2, 0) = origin.z();
00160 }
00161 
00162 void tfToOpenCVRt(
00163   const tf::Transform& transform,
00164   cv::Mat& R,
00165   cv::Mat& t)
00166 {
00167   // extract translation
00168   tf::Vector3 translation_tf = transform.getOrigin();
00169   t = cv::Mat(3, 1, CV_64F);
00170   t.at<double>(0,0) = translation_tf.getX();
00171   t.at<double>(1,0) = translation_tf.getY();
00172   t.at<double>(2,0) = translation_tf.getZ();
00173 
00174   // extract rotation
00175   tf::Matrix3x3 rotation_tf(transform.getRotation());
00176   R = cv::Mat(3, 3, CV_64F);
00177   for(int i = 0; i < 3; ++i)
00178   for(int j = 0; j < 3; ++j)     
00179     R.at<double>(j,i) = rotation_tf[j][i];
00180 }
00181 
00182 void openCVRtToTf(
00183   const cv::Mat& R,
00184   const cv::Mat& t,
00185   tf::Transform& transform)
00186 {
00187   tf::Vector3 translation_tf(
00188     t.at<double>(0,0),
00189     t.at<double>(1,0),
00190     t.at<double>(2,0));
00191 
00192   tf::Matrix3x3 rotation_tf;
00193   for(int i = 0; i < 3; ++i)
00194   for(int j = 0; j < 3; ++j)     
00195     rotation_tf[j][i] = R.at<double>(j,i);
00196 
00197   transform.setOrigin(translation_tf);
00198   transform.setBasis(rotation_tf);
00199 }
00200 
00201 void convertCameraInfoToMats(
00202   const CameraInfoMsg::ConstPtr camera_info_msg,
00203   cv::Mat& intr,
00204   cv::Mat& dist)
00205 {
00206   // set intrinsic matrix from K vector
00207   intr = cv::Mat(3, 3, CV_64FC1);
00208   for (int idx = 0; idx < 9; ++idx)
00209   {
00210     int i = idx % 3;
00211     int j = idx / 3;
00212     intr.at<double>(j, i) = camera_info_msg->K[idx];
00213   }
00214   
00215   // set distortion matrix from D vector
00216   int d_size = camera_info_msg->D.size();
00217   dist = cv::Mat(1, d_size, CV_64FC1);
00218   for (int idx = 0; idx < d_size; ++idx)
00219   {
00220     dist.at<double>(0, idx) = camera_info_msg->D[idx];   
00221   }
00222 }
00223 
00224 void convertMatToCameraInfo(
00225   const cv::Mat& intr,
00226   CameraInfoMsg& camera_info_msg)
00227 {
00228   // set D matrix to 0
00229   camera_info_msg.D.resize(5);
00230   std::fill(camera_info_msg.D.begin(), camera_info_msg.D.end(), 0.0);
00231   
00232   // set K matrix to optimal new camera matrix
00233   for (int i = 0; i < 3; ++i)
00234   for (int j = 0; j < 3; ++j)
00235     camera_info_msg.K[j*3 + i] = intr.at<double>(j,i);
00236   
00237   // set R matrix to identity
00238   std::fill(camera_info_msg.R.begin(), camera_info_msg.R.end(), 0.0);  
00239   camera_info_msg.R[0*3 + 0] = 1.0;
00240   camera_info_msg.R[1*3 + 1] = 1.0;
00241   camera_info_msg.R[2*3 + 2] = 1.0;
00242     
00243   //set P matrix to K
00244   std::fill(camera_info_msg.P.begin(), camera_info_msg.P.end(), 0.0);  
00245   for (int i = 0; i < 3; ++i)
00246   for (int j = 0; j < 3; ++j)
00247     camera_info_msg.P[j*4 + i] = intr.at<double>(j,i);
00248 }
00249 
00250 void transformMeans(
00251   Vector3fVector& means,
00252   const tf::Transform& transform)
00253 {
00254   Matrix3f R;
00255   Vector3f t;
00256   tfToEigenRt(transform, R, t);
00257   
00258   unsigned int size = means.size(); 
00259   for(unsigned int i = 0; i < size; ++i)
00260   {
00261     Vector3f& m = means[i];
00262     m = R * m + t;
00263   }  
00264 }
00265 
00266 void transformDistributions(
00267   Vector3fVector& means,
00268   Matrix3fVector& covariances,
00269   const tf::Transform& transform)
00270 {
00271   Matrix3f R;
00272   Vector3f t;
00273   tfToEigenRt(transform, R, t);
00274   Matrix3f R_T = R.transpose();
00275   
00276   unsigned int size = means.size(); 
00277   for(unsigned int i = 0; i < size; ++i)
00278   {
00279     Vector3f& m = means[i];
00280     Matrix3f& c = covariances[i];
00281     m = R * m + t;
00282     c = R * c * R_T;
00283   }
00284 }
00285 
00286 void pointCloudFromMeans(
00287   const Vector3fVector& means,
00288   PointCloudFeature& cloud)
00289 {
00290   unsigned int size = means.size(); 
00291   cloud.points.resize(size);
00292   for(unsigned int i = 0; i < size; ++i)
00293   {
00294     const Vector3f& m = means[i];
00295     PointFeature& p = cloud.points[i];
00296 
00297     p.x = m(0,0);
00298     p.y = m(1,0);
00299     p.z = m(2,0);
00300   }
00301   
00302   cloud.height = 1;
00303   cloud.width = size;
00304   cloud.is_dense = true;
00305 }
00306 
00307 
00308 void buildPointCloud(
00309   const cv::Mat& depth_img_rect,
00310   const cv::Mat& intr_rect_ir,
00311   PointCloudT& cloud)
00312 {
00313   int w = depth_img_rect.cols;
00314   int h = depth_img_rect.rows;
00315   
00316   double cx = intr_rect_ir.at<double>(0,2);
00317   double cy = intr_rect_ir.at<double>(1,2);
00318   double fx_inv = 1.0 / intr_rect_ir.at<double>(0,0);
00319   double fy_inv = 1.0 / intr_rect_ir.at<double>(1,1);
00320 
00321   cloud.resize(w*h);
00322 
00323   for (int u = 0; u < w; ++u)
00324   for (int v = 0; v < h; ++v)
00325   {
00326     uint16_t z = depth_img_rect.at<uint16_t>(v, u);   
00327     PointT& pt = cloud.points[v*w + u];
00328     
00329     if (z != 0)
00330     {  
00331       double z_metric = z * 0.001;
00332              
00333       pt.x = z_metric * ((u - cx) * fx_inv);
00334       pt.y = z_metric * ((v - cy) * fy_inv);
00335       pt.z = z_metric;  
00336     }
00337     else
00338     {
00339       pt.x = pt.y = pt.z = std::numeric_limits<float>::quiet_NaN();
00340     }
00341   }  
00342   
00343   cloud.width = w;
00344   cloud.height = h;
00345   cloud.is_dense = true;
00346 }
00347 
00348 void buildPointCloud(
00349   const cv::Mat& depth_img_rect_reg,
00350   const cv::Mat& rgb_img_rect,
00351   const cv::Mat& intr_rect_rgb,
00352   PointCloudT& cloud)
00353 {
00354   int w = rgb_img_rect.cols;
00355   int h = rgb_img_rect.rows;
00356   
00357   double cx = intr_rect_rgb.at<double>(0,2);
00358   double cy = intr_rect_rgb.at<double>(1,2);
00359   double fx_inv = 1.0 / intr_rect_rgb.at<double>(0,0);
00360   double fy_inv = 1.0 / intr_rect_rgb.at<double>(1,1);
00361 
00362   cloud.resize(w*h);
00363   
00364   for (int u = 0; u < w; ++u)
00365   for (int v = 0; v < h; ++v)
00366   {
00367     uint16_t z = depth_img_rect_reg.at<uint16_t>(v, u);
00368     const cv::Vec3b& c = rgb_img_rect.at<cv::Vec3b>(v, u);
00369     
00370     PointT& pt = cloud.points[v*w + u];
00371     
00372     if (z != 0)
00373     {  
00374       double z_metric = z * 0.001;
00375              
00376       pt.x = z_metric * ((u - cx) * fx_inv);
00377       pt.y = z_metric * ((v - cy) * fy_inv);
00378       pt.z = z_metric;
00379   
00380       pt.r = c[2];
00381       pt.g = c[1];
00382       pt.b = c[0];
00383     }
00384     else
00385     {
00386       pt.x = pt.y = pt.z = std::numeric_limits<float>::quiet_NaN();
00387     }
00388   }  
00389   
00390   cloud.width = w;
00391   cloud.height = h;
00392   cloud.is_dense = true;
00393 }
00394 
00395 void buildRegisteredDepthImage(
00396   const cv::Mat& intr_rect_ir,
00397   const cv::Mat& intr_rect_rgb,
00398   const cv::Mat& ir2rgb,
00399   const cv::Mat& depth_img_rect,
00400         cv::Mat& depth_img_rect_reg)
00401 {  
00402   int w = depth_img_rect.cols;
00403   int h = depth_img_rect.rows;
00404       
00405   depth_img_rect_reg = cv::Mat::zeros(h, w, CV_16UC1); 
00406   
00407   cv::Mat intr_rect_ir_inv = intr_rect_ir.inv();
00408   
00409   // Eigen intr_rect_rgb (3x3)
00410   Eigen::Matrix<double, 3, 3> intr_rect_rgb_eigen;  
00411   for (int u = 0; u < 3; ++u)
00412   for (int v = 0; v < 3; ++v)
00413     intr_rect_rgb_eigen(v,u) =  intr_rect_rgb.at<double>(v, u); 
00414   
00415   // Eigen rgb2ir_eigen (3x4)
00416   Eigen::Matrix<double, 3, 4> ir2rgb_eigen;
00417   for (int u = 0; u < 4; ++u)
00418   for (int v = 0; v < 3; ++v)
00419     ir2rgb_eigen(v,u) =  ir2rgb.at<double>(v, u);
00420    
00421   // Eigen intr_rect_ir_inv (4x4)
00422   Eigen::Matrix4d intr_rect_ir_inv_eigen;  
00423   for (int v = 0; v < 3; ++v)
00424   for (int u = 0; u < 3; ++u)
00425     intr_rect_ir_inv_eigen(v,u) = intr_rect_ir_inv.at<double>(v,u);
00426   
00427   intr_rect_ir_inv_eigen(0, 3) = 0;
00428   intr_rect_ir_inv_eigen(1, 3) = 0;
00429   intr_rect_ir_inv_eigen(2, 3) = 0;
00430   intr_rect_ir_inv_eigen(3, 0) = 0;
00431   intr_rect_ir_inv_eigen(3, 1) = 0;
00432   intr_rect_ir_inv_eigen(3, 2) = 0;
00433   intr_rect_ir_inv_eigen(3, 3) = 1;
00434     
00435   // multiply into single (3x4) matrix
00436   Eigen::Matrix<double, 3, 4> H_eigen = 
00437     intr_rect_rgb_eigen * (ir2rgb_eigen * intr_rect_ir_inv_eigen);
00438 
00439   // *** reproject  
00440   
00441   Eigen::Vector3d p_rgb;
00442   Eigen::Vector4d p_depth;
00443   
00444   for (int v = 0; v < h; ++v)
00445   for (int u = 0; u < w; ++u)
00446   {
00447     uint16_t z = depth_img_rect.at<uint16_t>(v,u);
00448     
00449     if (z != 0)
00450     {    
00451       p_depth(0,0) = u * z;
00452       p_depth(1,0) = v * z;
00453       p_depth(2,0) = z;
00454       p_depth(3,0) = 1.0; 
00455       p_rgb = H_eigen * p_depth;
00456          
00457       double px = p_rgb(0,0);
00458       double py = p_rgb(1,0);
00459       double pz = p_rgb(2,0);
00460             
00461       int qu = (int)(px / pz);
00462       int qv = (int)(py / pz);  
00463         
00464       // skip outside of image 
00465       if (qu < 0 || qu >= w || qv < 0 || qv >= h) continue;
00466     
00467       uint16_t& val = depth_img_rect_reg.at<uint16_t>(qv, qu);
00468     
00469       // z buffering
00470       if (val == 0 || val > pz) val = pz;
00471     }
00472   }
00473 }
00474 
00475 void depthImageFloatTo16bit(
00476   const cv::Mat& depth_image_in,
00477   cv::Mat& depth_image_out)
00478 {
00479   depth_image_in.convertTo(depth_image_out, CV_16UC1, 1000.0);
00480 }
00481 
00482 } //namespace ccny_rgbd
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends


ccny_rgbd
Author(s): Ivan Dryanovski
autogenerated on Fri Apr 12 2013 20:38:48