object_button_detector.cpp
Go to the documentation of this file.
00001 #include <numeric>
00002 #include <ros/ros.h>
00003 #include <algorithm>
00004 
00005 #include <geometry_msgs/PointStamped.h>
00006 #include <geometry_msgs/PoseStamped.h>
00007 #include <pcl/point_types.h>
00008 #include <pcl_ros/point_cloud.h>
00009 #include <pcl/point_cloud.h>
00010 #include <pcl/surface/concave_hull.h>
00011 #include <tf/transform_listener.h>
00012 #include <opencv/cv.h>
00013 #include <image_transport/image_transport.h>
00014 #include <image_geometry/pinhole_camera_model.h>
00015 #include <pcl_ros/transforms.h>
00016 #include <tabletop_object_detector/TabletopSegmentation.h>
00017 #include <hrl_table_detect/ObjectButtonDetect.h>
00018 
00019 namespace hrl_table_detect {
00020 
00021     class ObjectButtonDetector {
00022         public:
00023             ros::NodeHandle nh;
00024             tf::TransformListener tf_listener;
00025             ros::ServiceServer table_obj_srv;
00026             ros::ServiceClient table_seg_srv;
00027             ros::Publisher hull_pub;
00028             std::string camera_frame;
00029 
00030             ObjectButtonDetector();
00031             void onInit();
00032             bool detectCallback(ObjectButtonDetect::Request& req, ObjectButtonDetect::Response& resp);
00033 
00034     };
00035 
00036     ObjectButtonDetector::ObjectButtonDetector() {
00037     }
00038 
00039     void ObjectButtonDetector::onInit() {
00040         nh.param<std::string>("camera_frame", camera_frame, "/openni_rgb_optical_frame");
00041 
00042         table_obj_srv = nh.advertiseService("object_button_detect", 
00043                                             &ObjectButtonDetector::detectCallback, this);
00044         table_seg_srv = nh.serviceClient<tabletop_object_detector::TabletopSegmentation>(
00045                                "table_segmentation", false);
00046         hull_pub = nh.advertise<visualization_msgs::Marker>("object_hull", 1);
00047         ROS_INFO("[object_button_detector] ObjectButtonDetector loaded.");
00048         ros::Duration(1).sleep();
00049     }
00050 
00051     bool ObjectButtonDetector::detectCallback(ObjectButtonDetect::Request& req, 
00052                                               ObjectButtonDetect::Response& resp) {
00053         // call tabletop segmentation
00054         tabletop_object_detector::TabletopSegmentation::Request table_seg_req;
00055         tabletop_object_detector::TabletopSegmentation::Response table_seg_resp;
00056         table_seg_srv.call(table_seg_req, table_seg_resp);
00057 
00058 
00059         // get table height in image frame
00060         geometry_msgs::PointStamped table_pt, table_base_frame, cam_pt, cam_base_frame;
00061         table_pt.header.frame_id = "/torso_lift_link";
00062         table_pt.header.stamp = table_seg_resp.table.pose.header.stamp;
00063         table_pt.point.x = table_seg_resp.table.pose.pose.position.x;
00064         table_pt.point.y = table_seg_resp.table.pose.pose.position.y;
00065         table_pt.point.z = table_seg_resp.table.pose.pose.position.z;
00066         cam_pt.header.frame_id = camera_frame;
00067         cam_pt.header.stamp = ros::Time(0);
00068         cam_pt.point.x = 0; cam_pt.point.y = 0; cam_pt.point.z = 0; 
00069 
00070         tf_listener.transformPoint("/base_footprint", table_pt, table_base_frame);
00071         tf_listener.transformPoint("/base_footprint", cam_pt, cam_base_frame);
00072         float table_height = table_base_frame.point.z;
00073         for(uint32_t i=0;i<table_seg_resp.clusters.size();i++) {
00074             // transform object into image frame
00075             sensor_msgs::PointCloud obj_img_frame;
00076             table_seg_resp.clusters[i].header.frame_id = "/torso_lift_link";
00077             tf_listener.transformPointCloud("/base_footprint", table_seg_resp.clusters[i], 
00078                                                                  obj_img_frame);
00079             // project object silhouette onto table
00080             pcl::PointCloud<pcl::PointXYZ>::Ptr table_proj_obj 
00081                                                       (new pcl::PointCloud<pcl::PointXYZ>);
00082             BOOST_FOREACH(const geometry_msgs::Point32& pt, obj_img_frame.points) {
00083                 if(pt.x != pt.x || pt.y != pt.y || pt.z != pt.z)
00084                     continue;
00085                 geometry_msgs::Vector3Stamped ray, ray_trans;
00086                 ray.header.frame_id = camera_frame;
00087                 ray.vector.x = pt.x - cam_base_frame.point.x; 
00088                 ray.vector.y = pt.y - cam_base_frame.point.y; 
00089                 ray.vector.z = pt.z - cam_base_frame.point.z; 
00090                 tf_listener.transformVector("/base_footprint", ray, ray_trans);
00091                 float t = (table_height - cam_base_frame.point.z) / ray.vector.z;
00092                 pcl::PointXYZ proj_pt;
00093                 proj_pt.x = cam_base_frame.point.x + ray.vector.x * t; 
00094                 proj_pt.y = cam_base_frame.point.y + ray.vector.y * t; 
00095                 proj_pt.z = table_height; 
00096                 table_proj_obj->points.push_back(proj_pt);
00097             }
00098 
00099             // Find concave_hull of resulting points
00100             pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_hull 
00101                                                       (new pcl::PointCloud<pcl::PointXYZ>);
00102             pcl::PointCloud<pcl::PointXYZ>::Ptr voronoi_centers 
00103                                                       (new pcl::PointCloud<pcl::PointXYZ>);
00104             std::vector<pcl::Vertices> hull_verts;
00105             pcl::ConcaveHull<pcl::PointXYZ> concave_hull;
00106             concave_hull.setInputCloud(table_proj_obj);
00107             concave_hull.setAlpha(0.1);
00108             concave_hull.setVoronoiCenters(voronoi_centers);
00109             concave_hull.reconstruct(*cloud_hull, hull_verts);
00110 
00111             // create polygon of projected object
00112             visualization_msgs::Marker hull_poly;
00113             hull_poly.type = visualization_msgs::Marker::LINE_STRIP; 
00114             hull_poly.action = visualization_msgs::Marker::ADD;
00115             hull_poly.ns = "object_hull";
00116             hull_poly.header.frame_id = "/base_footprint";
00117             hull_poly.header.stamp = ros::Time::now();
00118             hull_poly.id = i;
00119             hull_poly.pose.orientation.w = 1;
00120             hull_poly.scale.x = 0.01; hull_poly.scale.y = 0.01; hull_poly.scale.z = 0.01; 
00121             hull_poly.color.r = 1; hull_poly.color.b = 1; hull_poly.color.a = 1;
00122             BOOST_FOREACH(const pcl::PointXYZ& pt, cloud_hull->points) {
00123                 geometry_msgs::Point n_pt; 
00124                 n_pt.x = pt.x; n_pt.y = pt.y; n_pt.z = pt.z; 
00125                 hull_poly.points.push_back(n_pt);
00126             }
00127             hull_poly.points.push_back(hull_poly.points[0]);
00128             resp.objects.push_back(hull_poly);
00129             hull_pub.publish(hull_poly);
00130         }
00131         return true;
00132     }
00133 
00134 };
00135 
00136 
00137 using namespace hrl_table_detect;
00138 
00139 int main(int argc, char **argv)
00140 {
00141     ros::init(argc, argv, "object_button_detector");
00142     ObjectButtonDetector obd;
00143     obd.onInit();
00144     ros::spin();
00145     return 0;
00146 }


hrl_table_detect
Author(s): kelsey
autogenerated on Wed Nov 27 2013 12:15:26