Advertisement
Guest User

New kinectRef2IMPEPRef.cc

a guest
Aug 22nd, 2013
549
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.90 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.  
  25. //Function declarations.
  26. void tfPointCloud(const sensor_msgs::PointCloud2ConstPtr &);
  27. void transformPC();
  28. void generateDepthAndSpherical();
  29.  
  30. //Global variables.
  31. bool newPC = false;
  32. sensor_msgs::PointCloud2 in_pc;
  33. sensor_msgs::PointCloud2 out_pc;
  34.  
  35. ros::Publisher pub_pc; //point cloud
  36. ros::Publisher pub_di; //depth image
  37. ros::Publisher pub_sc; //spherical coordinates
  38. tf::TransformListener *tfListener;
  39.  
  40. int main(int argc, char *argv[])
  41. {
  42.     //The node's name.
  43.     std::string name = "kinectRef2IMPEPref";
  44.  
  45.     //Initialize ROS.
  46.     ros::init(argc, argv, name);
  47.     ros::NodeHandle node;
  48.  
  49.     //Initialize the Transform Listener.
  50.     tfListener = new tf::TransformListener();
  51.  
  52.     //Subscribe to /camera/depth_registered/points (registered point cloud).
  53.     ros::Subscriber sub = node.subscribe<sensor_msgs::PointCloud2>("/camera/depth_registered/points", 1000, tfPointCloud);
  54.  
  55.     //Publish to '/camera/impep_depth_registered/points' (point cloud registered
  56.     //to IMPEP's referential).
  57.     pub_pc = node.advertise<sensor_msgs::PointCloud2>("/camera/impep_depth_registered/points", 1000);
  58.  
  59.     //Publish to '/camera/impep_depth_registered/image' (depth image registered
  60.     //to IMPEP's referential).
  61.     pub_di = node.advertise<sensor_msgs::Image>("/camera/impep_depth_registered/image", 1000);
  62.  
  63.     //Publish to '/camera/impep_depth_registered/points_spherical' (point cloud
  64.     //using spherical coordinates registered to IMPEP's referential).
  65.     pub_sc = node.advertise<sensor_msgs::PointCloud2>("/camera/impep_depth_registered/points_spherical", 1000);
  66.  
  67.  
  68.     while(ros::ok())
  69.     {
  70.         ros::spinOnce();
  71.  
  72.         //If no new Point Cloud arrived, spinOnce again.
  73.         if(newPC == false)
  74.             continue;
  75.  
  76.         //Transform point cloud.
  77.         transformPC();
  78.  
  79.         //Generate and publish depth image and spherical coordinates point cloud.
  80.         generateDepthAndSpherical();
  81.  
  82.         newPC = false;
  83.     }
  84.  
  85.     delete tfListener;
  86.  
  87.     return 0;
  88. }
  89.  
  90. ////
  91. // This function reads point clouds from the '/camera/depth_registered/points'
  92. // topic and saves them to the variable 'in_pc'.
  93. void tfPointCloud(const sensor_msgs::PointCloud2ConstPtr& msg)
  94. {
  95.     in_pc = sensor_msgs::PointCloud2(*msg);
  96.     newPC = true;
  97. }
  98.  
  99. ////
  100. // Transforms the point cloud 'in_pc' from Kinect's referential to IMPEP's referential
  101. // and publishes the new point clouds to '/camera/impep_depth_registered/points'.
  102. void transformPC()
  103. {
  104.     //Transform point cloud.
  105.     bool hasTF = false;
  106.     while(!hasTF)
  107.         hasTF = tfListener->waitForTransform("/camera_rgb_optical_frame", "/impep_frame", ros::Time::now(), ros::Duration(3.0));
  108.     pcl_ros::transformPointCloud("/impep_frame", in_pc, out_pc, *tfListener);
  109.  
  110.     //Publish point cloud to '/camera/impep_depth_registered/points'.
  111.     pub_pc.publish(out_pc);
  112. }
  113.  
  114. ////
  115. // Using the transformed point cloud, generate a new depth image, published
  116. // to '/camera/impep_depth_registered/image', and a point cloud using spherical
  117. // coordinates instead of cartesian coordinates, published to
  118. // '/camera/impep_depth_registered/points_spherical'.
  119. void generateDepthAndSpherical()
  120. {
  121.     ////
  122.     // Depth image initializations.
  123.     sensor_msgs::Image out_di;
  124.     pcl::PointCloud< pcl::PointXYZRGB > pc;
  125.  
  126.     out_di = sensor_msgs::Image();
  127.     pcl::fromROSMsg(in_pc, pc);
  128.  
  129.     cv::Mat img = cv::Mat(480, 640, CV_32FC1);
  130.  
  131.     ////
  132.     // Point cloud with spherical coordinates initializations.
  133.     sensor_msgs::PointCloud2 out_sc;
  134.     pcl::PointCloud< PointDTPRGB > pc_sc;
  135.  
  136.     //Point cloud has same characteristics as the received one.
  137.     pc_sc.header = pc.header;
  138.     pc_sc.width = pc.width;
  139.     pc_sc.height = pc.height;
  140.     pc_sc.is_dense = pc.is_dense;
  141.     pc_sc.sensor_origin_ = pc.sensor_origin_;
  142.     pc_sc.sensor_orientation_ = pc.sensor_orientation_;
  143.  
  144.     pc_sc.points = std::vector< PointDTPRGB, Eigen::aligned_allocator< PointDTPRGB > >(pc.height * pc.width);
  145.  
  146.     ////
  147.     // Create each pixel from the coordinates of each point in the cloud
  148.     // and convert each point from cartesian to spherical coordinates.
  149.     for(unsigned int i=0; i < pc.height; i++)
  150.     {
  151.         for(unsigned int j=0; j < pc.width; j++)
  152.         {
  153.             int index = i*pc.width + j;
  154.  
  155.             int x = pc.points[index].x;
  156.             int y = pc.points[index].y;
  157.             int z = pc.points[index].z;
  158.  
  159.             //Depth image.
  160.             int depth = sqrt(x*x + y*y + z*z);
  161.             img.at<float>(i, j) = depth;
  162.  
  163.             //Spherical coordinates
  164.             pc_sc.points[index].d = depth;
  165.             if(pc_sc.points[index].d == 0)
  166.                 pc_sc.points[index].t = 0;
  167.             else
  168.                 pc_sc.points[index].t = acos(z / pc_sc.points[index].d);
  169.             if(x == 0)
  170.                 pc_sc.points[index].p = 0;
  171.             else
  172.                 pc_sc.points[index].p = atan(y / x);
  173.  
  174.             pc_sc.points[index].rgb = pc.points[index].rgb;
  175.         }
  176.     }
  177.  
  178.     //Convert the 'cv::Mat' to 'sensor_msgs::Image'.
  179.     cv_bridge::CvImage cv_di = cv_bridge::CvImage(out_di.header, "32FC1", img);
  180.     cv_di.toImageMsg(out_di);
  181.  
  182.     //Publish new depth image.
  183.     pub_di.publish(out_di);
  184.  
  185.     //Convert from 'pcl::PointCloud' to 'sensor_msgs::PointCloud2'.
  186.     pcl::toROSMsg(pc_sc, out_sc);
  187.  
  188.     //Publish new spherical coordinates point cloud.
  189.     pub_sc.publish(out_sc);
  190. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement