Advertisement
Guest User

kinectRef2IMPEPRef.cc

a guest
Aug 13th, 2013
330
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.99 KB | None | 0 0
  1. //C++ related includes.
  2. #include <cstdio>
  3. #include <cmath>
  4.  
  5. //ROS related includes.
  6. #include <ros/ros.h>
  7. #include <sensor_msgs/PointCloud2.h>
  8. #include <tf/transform_listener.h>
  9.  
  10. //PCL related includes.
  11. #include <pcl/ros/conversions.h>
  12. #include <pcl/point_cloud.h>
  13. #include <pcl/point_types.h>
  14. #include <pcl_ros/transforms.h>
  15.  
  16. //OpenCV related includes.
  17. #include <cv_bridge/cv_bridge.h>
  18. #include <opencv2/imgproc/imgproc.hpp>
  19. #include <opencv2/highgui/highgui.hpp>
  20.  
  21. //Self defined includes.
  22. #include "IMPEP/PointDTPRGB.hh"
  23.  
  24. //Debug defines.
  25. //#define DEBUG_CLOUD_TF
  26.  
  27. //Function declarations.
  28. void tfPointCloud(const sensor_msgs::PointCloud2ConstPtr & );
  29.  
  30. //Global variable declarations.
  31. ros::Publisher pub_pc; //point cloud
  32. ros::Publisher pub_di; //depth image
  33. ros::Publisher pub_sc; //spherical coordinates
  34. tf::TransformListener *tf_list;
  35.  
  36. int main(int argc, char *argv[])
  37. {
  38.     //The node's name.
  39.     std::string name = "kinectRef2IMPEPref";
  40.  
  41.     //Initialize ROS.
  42.     ros::init(argc, argv, name);
  43.     ros::NodeHandle node;
  44.  
  45.     //Initialize the Transform Listener.
  46.     tf_list = new tf::TransformListener();
  47.  
  48.     //Subscribe to /camera/depth_registered/points (registered point cloud).
  49.     ros::Subscriber sub = node.subscribe<sensor_msgs::PointCloud2>("/camera/depth_registered/points", 1000, tfPointCloud);
  50.  
  51.     //Publish to '/camera/impep_depth_registered/points' (point cloud registered
  52.     //to IMPEP's referential).
  53.     pub_pc = node.advertise<sensor_msgs::PointCloud2>("/camera/impep_depth_registered/points", 1000);
  54.  
  55.     //Publish to '/camera/impep_depth_registered/image' (depth image registered
  56.     //to IMPEP's referential).
  57.     pub_di = node.advertise<sensor_msgs::Image>("/camera/impep_depth_registered/image", 1000);
  58.  
  59.     //Publish to '/camera/impep_depth_registered/points_spherical' (point cloud
  60.     //using spherical coordinates registered to IMPEP's referential).
  61.     pub_sc = node.advertise<sensor_msgs::PointCloud2>("/camera/impep_depth_registered/points_spherical", 1000);
  62.  
  63.     ros::spin();
  64.  
  65.     delete tf_list;
  66.  
  67.     return 0;
  68. }
  69.  
  70. ////
  71. // This function reads point clouds from the '/camera/depth_registered/points'
  72. // topic, transforms them from Kinect's referential to IMPEP's referential
  73. // and publishes the new point clouds to '/camera/impep_depth_registered/points'.
  74. // Then, it uses this new point clouds to generate a new depth image and publish
  75. // it to '/camera/impep_depth_registered/image'.
  76. // It also uses the new point clouds to generate a point cloud using spherical
  77. // coordinates instead of cartesian coordinates.
  78. void tfPointCloud(const sensor_msgs::PointCloud2ConstPtr& msg)
  79. {
  80.     bool hasTF = false;
  81.  
  82.     ////
  83.     // Transform point cloud.
  84.     sensor_msgs::PointCloud2 out_pc = sensor_msgs::PointCloud2();
  85.  
  86.     while(!hasTF)
  87.         hasTF = tf_list->waitForTransform("/camera_rgb_optical_frame", "/impep_frame", ros::Time::now(), ros::Duration(3.0));
  88.     pcl_ros::transformPointCloud("/impep_frame", *msg, out_pc, *tf_list);
  89.  
  90.     //Publish point cloud to '/camera/impep_depth_registered/points'.
  91.     pub_pc.publish(out_pc);
  92.  
  93.  
  94. #ifdef DEBUG_CLOUD_TF
  95.     //http://answers.ros.org/question/10947/reading-float-from-float32-data-from-kinect-pointcloud2/?answer=16165#post-id-16165
  96.  
  97.     pcl::PointCloud< pcl::PointXYZ > pc2;
  98.  
  99.     pcl::fromROSMsg(*msg, pc2);
  100.     std::cout << "[BEFORE] (x,y,z) = " << pc2.points[0] << std::endl;
  101.  
  102.     pcl::fromROSMsg(out, pc2);
  103.     std::cout << "[AFTER] (x,y,z) = " << pc2.points[0] << std::endl;
  104. #endif
  105.  
  106.     ////
  107.     // Use new point cloud to generate depth image.
  108.     sensor_msgs::Image out_di;
  109.     pcl::PointCloud< pcl::PointXYZRGB > pc;
  110.  
  111.     out_di = sensor_msgs::Image();
  112.     pcl::fromROSMsg(*msg, pc);
  113.  
  114.     cv::Mat img = cv::Mat(480, 640, CV_32FC1);
  115.  
  116.     //Create each pixel from the coordinates of each point in the cloud.
  117.     for(unsigned int i=0; i < pc.height; i++)
  118.     {
  119.         for(unsigned int j=0; j < pc.width; j++)
  120.         {
  121.             int index = i*pc.width + j;
  122.  
  123.             int x = pc.points[index].x;
  124.             int y = pc.points[index].y;
  125.             int z = pc.points[index].z;
  126.  
  127.             int depth = sqrt(x*x + y*y + z*z);
  128.             img.at<float>(i, j) = depth;
  129.         }
  130.     }
  131.  
  132.     //Convert the 'cv::Mat' to 'sensor_msgs::Image'.
  133.     cv_bridge::CvImage cv_di = cv_bridge::CvImage(out_di.header, "32FC1", img);
  134.     cv_di.toImageMsg(out_di);
  135.  
  136.     //Publish new depth image.
  137.     pub_di.publish(out_di);
  138.  
  139.     ////
  140.     // Use new point cloud to generate point cloud with
  141.     // spherical coordinates.
  142.     sensor_msgs::PointCloud2 out_sc;
  143.     pcl::PointCloud< PointDTPRGB > pc_sc;
  144.  
  145.     //Point cloud has same characteristics as the received one.
  146.     pc_sc.header = pc.header;
  147.     pc_sc.width = pc.width;
  148.     pc_sc.height = pc.height;
  149.     pc_sc.is_dense = pc.is_dense;
  150.     pc_sc.sensor_origin_ = pc.sensor_origin_;
  151.     pc_sc.sensor_orientation_ = pc.sensor_orientation_;
  152.  
  153.     pc_sc.points = std::vector< PointDTPRGB, Eigen::aligned_allocator< PointDTPRGB > >(pc.height * pc.width);
  154.  
  155.     //Convert each point from cartesian to spherical coordinates.
  156.     for(unsigned int i=0; i < pc.height; i++)
  157.     {
  158.         for(unsigned int j=0; j < pc.width; j++)
  159.         {
  160.             int index = i*pc.width + j;
  161.  
  162.             int x = pc.points[index].x;
  163.             int y = pc.points[index].y;
  164.             int z = pc.points[index].z;
  165.  
  166.             pc_sc.points[index].d = sqrt(x*x + y*y + z*z);
  167.             if(pc_sc.points[index].d == 0)
  168.                 pc_sc.points[index].t = 0;
  169.             else
  170.                 pc_sc.points[index].t = acos(z / pc_sc.points[index].d);
  171.             if(x == 0)
  172.                 pc_sc.points[index].p = 0;
  173.             else
  174.                 pc_sc.points[index].p = atan(y / x);
  175.  
  176.             pc_sc.points[index].rgb = pc.points[index].rgb;
  177.         }
  178.     }
  179.  
  180.     //Convert from 'pcl::PointCloud' to 'sensor_msgs::PointCloud2'.
  181.     pcl::toROSMsg(pc_sc, out_sc);
  182.  
  183.     //Publish new spherical coordinates point cloud.
  184.     pub_sc.publish(out_sc);
  185. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement