Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "ros/ros.h"
00034 #include "sensor_msgs/LaserScan.h"
00035 #include <sensor_msgs/PointCloud.h>
00036 #include <pcl/io/pcd_io.h>
00037 #include <pcl/point_types.h>
00038
00039 #include <opencv/highgui.h>
00040 #include <opencv/cv.h>
00041
00042 #include "laser_points_colouration/point3d.h"
00043 #include "laser_points_colouration/point_color.h"
00044
00045 #include <vector>
00046 #include <fstream>
00047 #include <cmath>
00048
00049 #define nWidth 1280
00050 #define nHeight 960
00051
00052 class VisionToLaser
00053 {
00054 public:
00055 VisionToLaser ();
00056 ~VisionToLaser ();
00057 public:
00058 void loadParameters ();
00059 void loadLaserPoints (char *_filename);
00060 void loadVisionImage ();
00061 void visionToLaser ();
00062 bool saveData ();
00063 void getSceneNum (int scene_num_);
00064 void getImageMovedDegree ();
00065 private:
00066 ros::NodeHandle nh_;
00067 private:
00068 CvMat * intrinsic_M_;
00069 CvMat *rotation_M_;
00070 CvMat *translate_V_;
00071 CvMat *target_V_;
00072 CvMat *far_left_point_;
00073 CvMat *far_right_point_;
00074
00075 float left_bound_;
00076 float right_bound_;
00077 float upper_bound_;
00078 float lower_bound_;
00079 float front_bound_;
00080 float back_bound_;
00081
00082 std::vector < std::vector < CPoint3d > >laser_data_vec_;
00083 std::vector < std::vector < CPoint3d > >laser_data_raw_vec_;
00084 std::vector < std::vector < CPointColor > >data_color_vec_;
00085 IplImage *image[8];
00086
00087 double image_moved_degree_[8];
00088
00089 int n_scene_num_;
00090 };
00091
00092 VisionToLaser::VisionToLaser ()
00093 {
00094 intrinsic_M_ = cvCreateMat (3, 3, CV_32FC1);
00095 rotation_M_ = cvCreateMat (3, 3, CV_32FC1);
00096 translate_V_ = cvCreateMat (3, 1, CV_32FC1);
00097 target_V_ = cvCreateMat (3, 1, CV_32FC1);
00098
00099 far_left_point_ = cvCreateMat (3, 1, CV_32FC1);
00100 far_right_point_ = cvCreateMat (3, 1, CV_32FC1);
00101
00102 left_bound_ = 0.0;
00103 right_bound_ = 0.0;
00104 upper_bound_ = 0.0;
00105 lower_bound_ = 0.0;
00106 front_bound_ = 0.0;
00107 back_bound_ = 0.0;
00108
00109 laser_data_vec_.reserve (2000);
00110 data_color_vec_.resize (2000);
00111 laser_data_raw_vec_.reserve (2000);
00112
00113 for (int i = 0; i < 8; i++)
00114 {
00115 image[i] = NULL;
00116 }
00117
00118 n_scene_num_ = 0;
00119 }
00120
00121 VisionToLaser::~VisionToLaser ()
00122 {
00123 cvReleaseMat (&intrinsic_M_);
00124 cvReleaseMat (&rotation_M_);
00125 cvReleaseMat (&translate_V_);
00126 cvReleaseMat (&target_V_);
00127 cvReleaseMat (&far_left_point_);
00128 cvReleaseMat (&far_right_point_);
00129 }
00130
00131 void VisionToLaser::loadParameters ()
00132 {
00133 intrinsic_M_ = (CvMat *) cvLoad ("Intrinsics.xml");
00134 translate_V_ = (CvMat *) cvLoad ("translation.xml");
00135 rotation_M_ = (CvMat *) cvLoad ("rotation.xml");
00136
00137 left_bound_ = 50.0;
00138 right_bound_ = -50.0;
00139 upper_bound_ = 50.0;
00140 lower_bound_ = -50.0;
00141 front_bound_ = 0.5;
00142 back_bound_ = 50.0;
00143
00144 }
00145
00146 void VisionToLaser::loadLaserPoints (char *_filename)
00147 {
00148 pcl::PointCloud < pcl::PointXYZ >::Ptr cloud (new pcl::PointCloud < pcl::PointXYZ >);
00149
00150 if (pcl::io::loadPCDFile < pcl::PointXYZ > (_filename, *cloud) == -1)
00151 {
00152 PCL_ERROR ("Couldn't read file \n");
00153 return;
00154 }
00155 else
00156 printf ("points number = %d\n", cloud->width * cloud->height);
00157
00158 std::vector < CPoint3d > vec_laserdata;
00159 vec_laserdata.reserve (361);
00160 CPoint3d p;
00161 for (unsigned int j = 0; j < cloud->points.size () / 361; j++)
00162 {
00163 for (unsigned int i = 0; i < 361; i++)
00164 {
00165 p.x = cloud->points[j * 361 + i].x;
00166 p.y = cloud->points[j * 361 + i].y;
00167 p.z = cloud->points[j * 361 + i].z;
00168 vec_laserdata.push_back (p);
00169 }
00170 laser_data_raw_vec_.push_back (vec_laserdata);
00171 vec_laserdata.clear ();
00172 }
00173 ROS_INFO ("Read the laser data successfully!");
00174 }
00175
00176 void VisionToLaser::loadVisionImage ()
00177 {
00178 char _imagename[50];
00179 for (int _imagenum = 0; _imagenum < 8; _imagenum++)
00180 {
00181 bzero (_imagename, sizeof (_imagename));
00182 sprintf (_imagename, "image%d.bmp", _imagenum + 1);
00183 image[_imagenum] = cvLoadImage (_imagename, CV_LOAD_IMAGE_COLOR);
00184 }
00185 }
00186
00187 void VisionToLaser::getSceneNum (int scene_num_)
00188 {
00189 n_scene_num_ = scene_num_;
00190 }
00191
00192 void VisionToLaser::getImageMovedDegree ()
00193 {
00194 std::ifstream mr_imgtime ("imagetimestamp.txt");
00195 double imgtime[9];
00196 std::ifstream mr_motortime ("motortimestamp.txt");
00197 double motortime;
00198 if (mr_imgtime.is_open ())
00199 {
00200 ROS_INFO ("Start read the image timestamp!");
00201 for (int i = 0; i < 9; i++)
00202 {
00203 mr_imgtime >> imgtime[i];
00204 }
00205 }
00206 else
00207 {
00208 ROS_INFO ("Read the image timestamp fail");
00209
00210 return;
00211 }
00212 mr_imgtime.close ();
00213 if (mr_motortime.is_open ())
00214 {
00215 ROS_INFO ("Start read the motor timestamp!");
00216 mr_motortime >> motortime;
00217 }
00218 else
00219 {
00220 ROS_INFO ("Read the motor timestamp fail");
00221
00222 return;
00223 }
00224 mr_motortime.close ();
00225 image_moved_degree_[0] = 0.0;
00226 for (int j = 1; j < 8; j++)
00227 {
00228 image_moved_degree_[j] = (imgtime[j + 1] - motortime - 0.2) * 9.0 / 180.0 * 3.1415;
00229 }
00230 }
00231
00232 void VisionToLaser::visionToLaser ()
00233 {
00234 size_t laserHeight = laser_data_raw_vec_.size ();
00235 size_t laserWidth = 361;
00236 data_color_vec_.resize (laserHeight);
00237 for (size_t j = 0; j < laserHeight; j++)
00238 data_color_vec_[j].resize (laserWidth);
00239
00240 size_t totalPointsNum = laserHeight * laserWidth;
00241 CvMat *regionPoints = cvCreateMat ((int) totalPointsNum, 3, CV_32FC1);
00242 CvMat *pointIndex = cvCreateMat ((int) totalPointsNum, 1, CV_32SC1);
00243
00244 float *regionPtr = NULL;
00245 int *pointIndexPtr = NULL;
00246
00247 float x, y, z;
00248 size_t counter;
00249 size_t regionPointsNum;
00250
00251 unsigned char *img_data;
00252 int img_step = 0;
00253 int img_channels = 0;
00254
00255 int inRangeX;
00256 int inRangeY;
00257 size_t reducedPointsNum = 0;
00258
00259 size_t laser_Index = 0;
00260
00261 std::vector < CPoint3d > vec_data;
00262 vec_data.reserve (361);
00263 CPoint3d p;
00264 for (int scenecount = 0; scenecount < 8; scenecount++)
00265 {
00266 for (int j = 0; j < (int) laser_data_raw_vec_.size (); j++)
00267 {
00268 for (int i = 0; i < 361; i++)
00269 {
00270 float x = laser_data_raw_vec_[j][i].x;
00271 float y = laser_data_raw_vec_[j][i].y;
00272 float z = laser_data_raw_vec_[j][i].z;
00273
00274 p.x = x * cos (image_moved_degree_[scenecount]) - y * sin (image_moved_degree_[scenecount]);
00275 p.y = x * sin (image_moved_degree_[scenecount]) + y * cos (image_moved_degree_[scenecount]);
00276 p.z = z;
00277
00278 vec_data.push_back (p);
00279 }
00280 laser_data_vec_.push_back (vec_data);
00281 vec_data.clear ();
00282 }
00283
00284 regionPtr = regionPoints->data.fl;
00285 pointIndexPtr = pointIndex->data.i;
00286
00287 counter = 0;
00288 regionPointsNum = 0;
00289 while (counter < totalPointsNum)
00290 {
00291 x = laser_data_vec_[counter / laserWidth][counter % laserWidth].x;
00292 y = laser_data_vec_[counter / laserWidth][counter % laserWidth].y;
00293 z = laser_data_vec_[counter / laserWidth][counter % laserWidth].z;
00294 counter++;
00295 if (y > left_bound_ || y < right_bound_)
00296 {
00297 continue;
00298 }
00299 else if (z > upper_bound_ || z < lower_bound_)
00300 {
00301 continue;
00302 }
00303 else if (x > back_bound_ || x < front_bound_)
00304 {
00305 continue;
00306 }
00307 else
00308 {
00309 regionPtr[regionPointsNum * 3 + 0] = x;
00310 regionPtr[regionPointsNum * 3 + 1] = y;
00311 regionPtr[regionPointsNum * 3 + 2] = z;
00312 pointIndexPtr[regionPointsNum] = (int) (counter - 1);
00313 regionPointsNum++;
00314 }
00315
00316 }
00317 ROS_INFO ("regionPointsNum = %d", regionPointsNum);
00318 img_data = (unsigned char *) image[scenecount]->imageData;
00319 img_step = image[scenecount]->widthStep;
00320 img_channels = image[scenecount]->nChannels;
00321
00322 reducedPointsNum = 0;
00323 counter = 0;
00324 laser_Index = 0;
00325
00326 while (counter < regionPointsNum)
00327 {
00328 target_V_->data.fl[0] = x = regionPtr[counter * 3];
00329 target_V_->data.fl[1] = y = regionPtr[counter * 3 + 1];
00330 target_V_->data.fl[2] = z = regionPtr[counter * 3 + 2];
00331 counter++;
00332
00333 cvGEMM (rotation_M_, target_V_, 1.0, translate_V_, 1.0, target_V_, 0);
00334 cvGEMM (intrinsic_M_, target_V_, 1.0, NULL, 0.0, target_V_, 0);
00335
00336 inRangeX = int (target_V_->data.fl[0] / target_V_->data.fl[2] + 0.5);
00337 if (inRangeX < 0 || inRangeX >= nWidth)
00338 {
00339 continue;
00340 }
00341 inRangeY = int (target_V_->data.fl[1] / target_V_->data.fl[2] + 0.5);
00342 if (inRangeY < 0 || inRangeY >= nHeight)
00343 {
00344 continue;
00345 }
00346
00347 laser_Index = pointIndexPtr[counter - 1];
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360 data_color_vec_[laser_Index / laserWidth][laser_Index % laserWidth].r =
00361 img_data[inRangeY * img_step + inRangeX * img_channels + 2] / 255.0;
00362 data_color_vec_[laser_Index / laserWidth][laser_Index % laserWidth].g =
00363 img_data[inRangeY * img_step + inRangeX * img_channels + 1] / 255.0;
00364 data_color_vec_[laser_Index / laserWidth][laser_Index % laserWidth].b =
00365 img_data[inRangeY * img_step + inRangeX * img_channels] / 255.0;
00366 data_color_vec_[laser_Index / laserWidth][laser_Index % laserWidth].bIsColored = true;
00367 reducedPointsNum++;
00368 }
00369 ROS_INFO ("This is the %d scenes", scenecount);
00370 laser_data_vec_.clear ();
00371 }
00372
00373 cvReleaseMat (®ionPoints);
00374 cvReleaseMat (&pointIndex);
00375 }
00376
00377 bool VisionToLaser::saveData ()
00378 {
00379 std::ofstream m_w ("colordata.txt");
00380 if (!m_w.is_open ())
00381 {
00382 ROS_INFO ("Open the file colordata.txt fail\n");
00383
00384 return false;
00385 }
00386 else
00387 {
00388 ROS_INFO ("Open the file ok,and write the colored points to this file!");
00389 for (int j = 0; j < (int) laser_data_raw_vec_.size (); j++)
00390 for (int i = 0; i < 361; i++)
00391 {
00392 m_w << laser_data_raw_vec_[j][i].x << " " << laser_data_raw_vec_[j][i].y << " " << laser_data_raw_vec_[j][i].
00393 z << " " << data_color_vec_[j][i].r << " " << data_color_vec_[j][i].g << " " << data_color_vec_[j][i].
00394 b << " " << data_color_vec_[j][i].bIsColored << "\n";
00395 }
00396 m_w.close ();
00397
00398 return true;
00399 }
00400 }
00401
00402 int main (int argc, char **argv)
00403 {
00404 char *pointcloud_name = argv[1];
00405
00406 ros::init (argc, argv, "colouration");
00407
00408 VisionToLaser m_vtl;
00409
00410 m_vtl.loadParameters ();
00411 m_vtl.loadLaserPoints (pointcloud_name);
00412 m_vtl.getImageMovedDegree ();
00413
00414 m_vtl.loadVisionImage ();
00415 m_vtl.visionToLaser ();
00416
00417 bool isSaved = m_vtl.saveData ();
00418 if (isSaved)
00419 {
00420 ROS_INFO ("Save the colored data successfully!");
00421 }
00422 else
00423 {
00424 ROS_INFO ("Save the colored data fail!");
00425
00426 return -1;
00427 }
00428
00429 return 0;
00430 }