00001
00024 #include "ccny_rgbd/util.h"
00025
00026 namespace ccny_rgbd {
00027 int getmaxheight(PathMsg path_msg)
00028 {
00029 int max = -1000;
00030 for (u_int i = 0;i<path_msg.poses.size();i++)
00031 {
00032 tf::Pose pose_tf;
00033 tf::poseMsgToTF(path_msg.poses[i].pose, pose_tf);
00034
00035 if(pose_tf.getOrigin().z() > max)
00036 max = pose_tf.getOrigin().z();
00037 }
00038 return max;
00039 }
00040 int getminheight(PathMsg path_msg)
00041 {
00042 int min = 1000;
00043 for (u_int i = 0;i<path_msg.poses.size();i++)
00044 {
00045 tf::Pose pose_tf;
00046 tf::poseMsgToTF(path_msg.poses[i].pose, pose_tf);
00047
00048 if(pose_tf.getOrigin().z() < min)
00049 min = pose_tf.getOrigin().z();
00050 }
00051 return min;
00052 }
00053 void getTfDifference(const tf::Transform& motion, double& dist, double& angle)
00054 {
00055 dist = motion.getOrigin().length();
00056 double trace = motion.getBasis()[0][0] + motion.getBasis()[1][1] + motion.getBasis()[2][2];
00057 angle = acos(std::min(1.0, std::max(-1.0, (trace - 1.0)/2.0)));
00058 }
00059
00060 void getTfDifference(const tf::Transform& a, const tf::Transform b, double& dist, double& angle)
00061 {
00062 tf::Transform motion = a.inverse() * b;
00063 getTfDifference(motion, dist, angle);
00064 }
00065
00066 tf::Transform tfFromEigen(Eigen::Matrix4f t)
00067 {
00068 tf::Transform tf;
00069
00070 tf::Matrix3x3 m;
00071 m.setValue(t(0,0),t(0,1),t(0,2),
00072 t(1,0),t(1,1),t(1,2),
00073 t(2,0),t(2,1),t(2,2));
00074 tf.setBasis(m);
00075
00076 tf.setOrigin(tf::Vector3(t(0,3),t(1,3),t(2,3)));
00077
00078 return tf;
00079 }
00080
00081 Eigen::Matrix4f eigenFromTf(const tf::Transform& tf)
00082 {
00083 Eigen::Matrix4f out_mat;
00084
00085 double mv[12];
00086 tf.getBasis().getOpenGLSubMatrix(mv);
00087
00088 tf::Vector3 origin = tf.getOrigin();
00089
00090 out_mat(0, 0) = mv[0]; out_mat(0, 1) = mv[4]; out_mat(0, 2) = mv[8];
00091 out_mat(1, 0) = mv[1]; out_mat(1, 1) = mv[5]; out_mat(1, 2) = mv[9];
00092 out_mat(2, 0) = mv[2]; out_mat(2, 1) = mv[6]; out_mat(2, 2) = mv[10];
00093
00094 out_mat(3, 0) = out_mat(3, 1) = out_mat(3, 2) = 0; out_mat(3, 3) = 1;
00095 out_mat(0, 3) = origin.x();
00096 out_mat(1, 3) = origin.y();
00097 out_mat(2, 3) = origin.z();
00098
00099 return out_mat;
00100 }
00101
00102
00103 tf::Transform tfFromEigenAffine(const AffineTransform& t)
00104 {
00105 tf::Transform tf;
00106
00107 tf::Matrix3x3 m;
00108 m.setValue(t(0,0),t(0,1),t(0,2),
00109 t(1,0),t(1,1),t(1,2),
00110 t(2,0),t(2,1),t(2,2));
00111 tf.setBasis(m);
00112
00113 tf.setOrigin(tf::Vector3(t(0,3),t(1,3),t(2,3)));
00114
00115 return tf;
00116 }
00117
00118 AffineTransform eigenAffineFromTf(const tf::Transform& tf)
00119 {
00120 AffineTransform affine;
00121
00122 double mv[12];
00123 tf.getBasis().getOpenGLSubMatrix(mv);
00124
00125 tf::Vector3 origin = tf.getOrigin();
00126
00127 affine(0, 0) = mv[0]; affine(0, 1) = mv[4]; affine (0, 2) = mv[8];
00128 affine(1, 0) = mv[1]; affine(1, 1) = mv[5]; affine (1, 2) = mv[9];
00129 affine(2, 0) = mv[2]; affine(2, 1) = mv[6]; affine (2, 2) = mv[10];
00130
00131 affine(3, 0) = affine(3, 1) = affine(3, 2) = 0; affine(3, 3) = 1;
00132 affine(0, 3) = origin.x();
00133 affine(1, 3) = origin.y();
00134 affine(2, 3) = origin.z();
00135
00136 return affine;
00137 }
00138
00139 void tfToXYZRPY(
00140 const tf::Transform& t,
00141 double& x, double& y, double& z,
00142 double& roll, double& pitch, double& yaw)
00143 {
00144 x = t.getOrigin().getX();
00145 y = t.getOrigin().getY();
00146 z = t.getOrigin().getZ();
00147
00148 tf::Matrix3x3 m(t.getRotation());
00149 m.getRPY(roll, pitch, yaw);
00150 }
00151
00152 bool tfGreaterThan(const tf::Transform& tf, double dist, double angle)
00153 {
00154 double d = tf.getOrigin().length();
00155
00156 if (d >= dist) return true;
00157
00158 double trace = tf.getBasis()[0][0] + tf.getBasis()[1][1] + tf.getBasis()[2][2];
00159 double a = acos(std::min(1.0, std::max(-1.0, (trace - 1.0)/2.0)));
00160
00161 if (a > angle) return true;
00162
00163 return false;
00164 }
00165
00166 double getMsDuration(const ros::WallTime& start)
00167 {
00168 return (ros::WallTime::now() - start).toSec() * 1000.0;
00169 }
00170
00171 void removeInvalidMeans(
00172 const Vector3fVector& means,
00173 const BoolVector& valid,
00174 Vector3fVector& means_f)
00175 {
00176 unsigned int size = valid.size();
00177 for(unsigned int i = 0; i < size; ++i)
00178 {
00179 if (valid[i])
00180 {
00181 const Vector3f& mean = means[i];
00182 means_f.push_back(mean);
00183 }
00184 }
00185 }
00186
00187 void removeInvalidDistributions(
00188 const Vector3fVector& means,
00189 const Matrix3fVector& covariances,
00190 const BoolVector& valid,
00191 Vector3fVector& means_f,
00192 Matrix3fVector& covariances_f)
00193 {
00194 unsigned int size = valid.size();
00195 for(unsigned int i = 0; i < size; ++i)
00196 {
00197 if (valid[i])
00198 {
00199 const Vector3f& mean = means[i];
00200 const Matrix3f& cov = covariances[i];
00201
00202 means_f.push_back(mean);
00203 covariances_f.push_back(cov);
00204 }
00205 }
00206 }
00207
00208 void tfToEigenRt(
00209 const tf::Transform& tf,
00210 Matrix3f& R,
00211 Vector3f& t)
00212 {
00213 double mv[12];
00214 tf.getBasis().getOpenGLSubMatrix(mv);
00215
00216 tf::Vector3 origin = tf.getOrigin();
00217
00218 R(0, 0) = mv[0]; R(0, 1) = mv[4]; R(0, 2) = mv[8];
00219 R(1, 0) = mv[1]; R(1, 1) = mv[5]; R(1, 2) = mv[9];
00220 R(2, 0) = mv[2]; R(2, 1) = mv[6]; R(2, 2) = mv[10];
00221
00222 t(0, 0) = origin.x();
00223 t(1, 0) = origin.y();
00224 t(2, 0) = origin.z();
00225 }
00226
00227 void tfToOpenCVRt(
00228 const tf::Transform& transform,
00229 cv::Mat& R,
00230 cv::Mat& t)
00231 {
00232
00233 tf::Vector3 translation_tf = transform.getOrigin();
00234 t = cv::Mat(3, 1, CV_64F);
00235 t.at<double>(0,0) = translation_tf.getX();
00236 t.at<double>(1,0) = translation_tf.getY();
00237 t.at<double>(2,0) = translation_tf.getZ();
00238
00239
00240 tf::Matrix3x3 rotation_tf(transform.getRotation());
00241 R = cv::Mat(3, 3, CV_64F);
00242 for(int i = 0; i < 3; ++i)
00243 for(int j = 0; j < 3; ++j)
00244 R.at<double>(j,i) = rotation_tf[j][i];
00245 }
00246
00247 void openCVRtToTf(
00248 const cv::Mat& R,
00249 const cv::Mat& t,
00250 tf::Transform& transform)
00251 {
00252 tf::Vector3 translation_tf(
00253 t.at<double>(0,0),
00254 t.at<double>(1,0),
00255 t.at<double>(2,0));
00256
00257 tf::Matrix3x3 rotation_tf;
00258 for(int i = 0; i < 3; ++i)
00259 for(int j = 0; j < 3; ++j)
00260 rotation_tf[j][i] = R.at<double>(j,i);
00261
00262 transform.setOrigin(translation_tf);
00263 transform.setBasis(rotation_tf);
00264 }
00265
00266 void convertCameraInfoToMats(
00267 const CameraInfoMsg::ConstPtr camera_info_msg,
00268 cv::Mat& intr,
00269 cv::Mat& dist)
00270 {
00271
00272 intr = cv::Mat(3, 3, CV_64FC1);
00273 for (int idx = 0; idx < 9; ++idx)
00274 {
00275 int i = idx % 3;
00276 int j = idx / 3;
00277 intr.at<double>(j, i) = camera_info_msg->K[idx];
00278 }
00279
00280
00281 int d_size = camera_info_msg->D.size();
00282 dist = cv::Mat(1, d_size, CV_64FC1);
00283 for (int idx = 0; idx < d_size; ++idx)
00284 {
00285 dist.at<double>(0, idx) = camera_info_msg->D[idx];
00286 }
00287 }
00288
00289 void convertMatToCameraInfo(
00290 const cv::Mat& intr,
00291 CameraInfoMsg& camera_info_msg)
00292 {
00293
00294 camera_info_msg.D.resize(5);
00295 std::fill(camera_info_msg.D.begin(), camera_info_msg.D.end(), 0.0);
00296
00297
00298 for (int i = 0; i < 3; ++i)
00299 for (int j = 0; j < 3; ++j)
00300 camera_info_msg.K[j*3 + i] = intr.at<double>(j,i);
00301
00302
00303 std::fill(camera_info_msg.R.begin(), camera_info_msg.R.end(), 0.0);
00304 camera_info_msg.R[0*3 + 0] = 1.0;
00305 camera_info_msg.R[1*3 + 1] = 1.0;
00306 camera_info_msg.R[2*3 + 2] = 1.0;
00307
00308
00309 std::fill(camera_info_msg.P.begin(), camera_info_msg.P.end(), 0.0);
00310 for (int i = 0; i < 3; ++i)
00311 for (int j = 0; j < 3; ++j)
00312 camera_info_msg.P[j*4 + i] = intr.at<double>(j,i);
00313 }
00314
00315 void createRGBDFrameFromROSMessages(
00316 const ImageMsg::ConstPtr& rgb_msg,
00317 const ImageMsg::ConstPtr& depth_msg,
00318 const CameraInfoMsg::ConstPtr& info_msg,
00319 rgbdtools::RGBDFrame& frame)
00320 {
00321
00322 cv::Mat rgb_img = cv_bridge::toCvShare(rgb_msg)->image;
00323
00324
00325
00326
00327 cv::Mat depth_img;
00328
00329 const std::string& enc = depth_msg->encoding;
00330 if (enc.compare("16UC1") == 0)
00331 depth_img = cv_bridge::toCvShare(depth_msg)->image;
00332 else if (enc.compare("32FC1") == 0)
00333 rgbdtools::depthImageFloatTo16bit(cv_bridge::toCvShare(depth_msg)->image, depth_img);
00334
00335
00336 cv::Mat intr, dist;
00337 convertCameraInfoToMats(info_msg, intr, dist);
00339
00340
00341 rgbdtools::Header header;
00342
00343 header.seq = rgb_msg->header.seq;
00344 header.frame_id = rgb_msg->header.frame_id;
00345 header.stamp.sec = rgb_msg->header.stamp.sec;
00346 header.stamp.nsec = rgb_msg->header.stamp.nsec;
00347
00348
00349 frame = rgbdtools::RGBDFrame(rgb_img, depth_img, intr,dist, header);
00350 }
00351
00352 void pathEigenAffineToROS(
00353 const AffineTransformVector& path,
00354 PathMsg& path_msg)
00355 {
00356 assert(path.size() == path_msg.poses.size());
00357
00358 for (u_int idx = 0; idx < path.size(); ++idx)
00359 {
00360 tf::Transform pose_tf = tfFromEigenAffine(path[idx]);
00361 tf::poseTFToMsg(pose_tf, path_msg.poses[idx].pose);
00362 }
00363 }
00364
00365 void pathROSToEigenAffine(
00366 const PathMsg& path_msg,
00367 AffineTransformVector& path)
00368 {
00369 path.clear();
00370 path.resize(path_msg.poses.size());
00371
00372 for (u_int idx = 0; idx < path.size(); ++idx)
00373 {
00374 tf::Transform pose_tf;
00375 tf::poseMsgToTF(path_msg.poses[idx].pose, pose_tf);
00376 path[idx] = eigenAffineFromTf(pose_tf);
00377 }
00378 }
00379
00380 }