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 <std_msgs/String.h>
00035
00036 #include <sensor_msgs/CameraInfo.h>
00037 #include <stereo_msgs/DisparityImage.h>
00038
00039 #include <fast_plane_detection/Plane.h>
00040
00041 #include <visualization_msgs/Marker.h>
00042
00043
00044 #include "fast_plane_detector/plane_detection.h"
00045 #include "fast_plane_detector/plane_transform.h"
00046
00047 #include <image_transport/image_transport.h>
00048
00049 #include "fast_plane_detector/timercpu.h"
00050 #include "fast_plane_detector/utils.h"
00051
00052 namespace fast_plane_detection {
00053
00054 class FastPlaneDetector
00055 {
00056
00057 private:
00058
00059 void clearOldMarkers(std::string frame_id);
00060
00061 void maskDisparityImage(const stereo_msgs::DisparityImage::ConstPtr&
00062 disparity_image,
00063 const sensor_msgs::Image &labels,
00064 stereo_msgs::DisparityImage &masked_disparity);
00065
00067 ros::NodeHandle root_nh_;
00069 ros::NodeHandle priv_nh_;
00070
00072 ros::Subscriber camera_info_sub_;
00073 std::string camera_info_topic_;
00074
00076 ros::Subscriber disparity_image_sub_;
00077 std::string disparity_image_topic_;
00078
00080 int buffer_size_;
00081
00083 stereo_msgs::DisparityImage::ConstPtr disparity_image_;
00084
00086 sensor_msgs::CameraInfo::ConstPtr camera_info_;
00087
00089 ros::Publisher plane_marker_pub_;
00090
00092 ros::Publisher plane_msg_pub_;
00093
00095 ros::Publisher disparity_image_pub_;
00096
00098 image_transport::Publisher image_pub_;
00099
00100
00101
00103 PlaneDetection* plane_detect_;
00104
00106 bool find_table_;
00107
00109 PlaneTransform* plane_transform_;
00110
00112 double up_direction_;
00113
00115 int inlier_threshold_;
00116
00118 int num_markers_published_;
00120 int current_marker_id_;
00121
00122 public:
00123
00124 FastPlaneDetector( int buffer_size );
00125 ~FastPlaneDetector();
00126
00127
00128
00130 void planeCallback(const stereo_msgs::DisparityImage::ConstPtr&
00131 disparity_image);
00132
00133
00134
00136 Plane plane_;
00137
00138 };
00139
00140
00141 FastPlaneDetector::FastPlaneDetector( int buffer_size)
00142 : root_nh_("")
00143 , priv_nh_("~")
00144 , buffer_size_(buffer_size)
00145 , num_markers_published_(0)
00146 , current_marker_id_(0)
00147 {
00148
00149
00150 priv_nh_.param<std::string>("camera_info_topic",
00151 camera_info_topic_,
00152 "/narrow_stereo_textured/left/camera_info");
00153 priv_nh_.param<std::string>("disparity_image_topic",
00154 disparity_image_topic_,
00155 "/narrow_stereo_textured/disparity");
00156 priv_nh_.param<bool>("find_table",
00157 find_table_,
00158 true);
00159 priv_nh_.param<double>("up_direction",
00160 up_direction_,
00161 -1.0f);
00162 priv_nh_.param<int>("inlier_threshold",
00163 inlier_threshold_,
00164 300);
00165
00166
00167
00168 while (!camera_info_ || ! disparity_image_){
00169 if( !camera_info_ ){
00170 ROS_INFO_STREAM(" Waiting for message on topic "
00171 << camera_info_topic_);
00172 camera_info_ = ros::topic::waitForMessage<sensor_msgs::CameraInfo>
00173 (camera_info_topic_, root_nh_, ros::Duration(0.5));
00174 }
00175
00176 if( !disparity_image_){
00177 ROS_INFO_STREAM(" Waiting for message on topic "
00178 << disparity_image_topic_);
00179 disparity_image_ = ros::topic::waitForMessage<stereo_msgs::DisparityImage>
00180 (disparity_image_topic_, root_nh_, ros::Duration(1.0));
00181 }
00182 }
00183
00184
00185 float drange = disparity_image_->max_disparity -
00186 disparity_image_->min_disparity;
00187 int w = disparity_image_->image.width;
00188 int h = disparity_image_->image.height;
00189
00190 plane_detect_ = new PlaneDetection((int)drange, w, h, find_table_,
00191 disparity_image_->image.header);
00192
00193 plane_transform_ = new PlaneTransform( *camera_info_,
00194 disparity_image_->T,
00195 up_direction_);
00196
00197 disparity_image_sub_ = root_nh_.subscribe(disparity_image_topic_,
00198 buffer_size_,
00199 &FastPlaneDetector::planeCallback,
00200 this);
00201
00202
00203 plane_marker_pub_ = root_nh_.advertise<visualization_msgs::Marker>("plane_markers", 1);
00204
00205
00206 plane_msg_pub_ = root_nh_.advertise<Plane>("plane_msg", 1);
00207
00208
00209 std::string topic = root_nh_.resolveName("/plane_detection/disparity");
00210 disparity_image_pub_
00211 = root_nh_.advertise<stereo_msgs::DisparityImage>(topic, 1);
00212
00214 image_transport::ImageTransport it_(root_nh_);
00215 image_pub_ = it_.advertise("plane_out", 1);
00216
00217 }
00218
00219 FastPlaneDetector::~FastPlaneDetector()
00220 {}
00221
00222
00223 void FastPlaneDetector::planeCallback(const stereo_msgs::DisparityImage::ConstPtr& disparity_image)
00224 {
00225 TimerCPU timer(2800);
00226
00227 plane_detect_->Update(disparity_image);
00228
00229 float alpha, beta, d;
00230 int min_x, max_x, min_y, max_y;
00231 plane_detect_->GetPlaneParameters( alpha, beta, d,
00232 min_x, max_x, min_y, max_y);
00233
00234 sensor_msgs::Image labels;
00235 plane_detect_->GetLabels(labels);
00236
00237 stereo_msgs::DisparityImage disparity_masked;
00238 maskDisparityImage(disparity_image, labels, disparity_masked);
00239
00240 int sum = 0;
00241 for(unsigned int i=0; i<labels.height; ++i)
00242 for(unsigned int j=0; j<labels.width; ++j){
00243 int adr = i*labels.width+j;
00244 sum+=(labels.data[adr])/255;
00245 }
00246
00247
00248 image_pub_.publish(labels);
00249 disparity_image_pub_.publish(disparity_masked);
00250
00251
00252 if(sum<inlier_threshold_){
00253 ROS_WARN("Plane has only %d inliers", sum);
00254 return;
00255 }
00256
00257 plane_transform_->setParameters( alpha,
00258 beta,
00259 d,
00260 min_x, max_x,
00261 min_y, max_y,
00262 disparity_image->header);
00263
00264 if(!plane_transform_->getPlane(plane_)) {
00265 ROS_WARN("No Plane found");
00266 return;
00267 } else {
00268
00269 visualization_msgs::Marker planeMarker
00270 = getPlaneMarker( plane_.top_left,
00271 plane_.top_right,
00272 plane_.bottom_left,
00273 plane_.bottom_right);
00274 planeMarker.header = disparity_image->header;
00275 planeMarker.pose = plane_.pose.pose;
00276 planeMarker.ns = "tabletop_node";
00277 planeMarker.id = current_marker_id_++;
00278 plane_marker_pub_.publish(planeMarker);
00279
00280
00281
00282
00283
00284 clearOldMarkers(disparity_image->header.frame_id);
00285
00286
00287
00288
00289
00290
00291 }
00292
00293 ROS_INFO_STREAM("Time: " << timer.read() << " ms");
00294
00295 }
00296
00297 void FastPlaneDetector::clearOldMarkers(std::string frame_id)
00298 {
00299 for (int id=current_marker_id_; id < num_markers_published_; id++)
00300 {
00301
00302 ROS_WARN("Cleared old markers");
00303
00304 visualization_msgs::Marker delete_marker;
00305 delete_marker.header.stamp = ros::Time::now();
00306 delete_marker.header.frame_id = frame_id;
00307 delete_marker.id = id;
00308 delete_marker.action = visualization_msgs::Marker::DELETE;
00309 delete_marker.ns = "tabletop_node";
00310 plane_marker_pub_.publish(delete_marker);
00311 }
00312
00313 num_markers_published_ = current_marker_id_;
00314 current_marker_id_ = 0;
00315 }
00316
00317
00318 void
00319 FastPlaneDetector::maskDisparityImage( const stereo_msgs::DisparityImage::ConstPtr
00320 &disparity_image,
00321 const sensor_msgs::Image &labels,
00322 stereo_msgs::DisparityImage &masked_disparity)
00323 {
00324 int height = labels.height;
00325 int width = labels.width;
00326
00327 masked_disparity.header = disparity_image->header;
00328 masked_disparity.image.header = disparity_image->image.header;
00329 masked_disparity.image.height = height;
00330 masked_disparity.image.width = width;
00331 masked_disparity.image.encoding = disparity_image->image.encoding;
00332 masked_disparity.image.is_bigendian = disparity_image->image.is_bigendian;
00333 masked_disparity.image.step = disparity_image->image.step;
00334 size_t size = masked_disparity.image.step * masked_disparity.image.height;
00335 masked_disparity.image.data.resize(size, 0);
00336
00337 masked_disparity.f = disparity_image->f;
00338 masked_disparity.T = disparity_image->T;
00339 masked_disparity.min_disparity = disparity_image->min_disparity;
00340 masked_disparity.max_disparity = disparity_image->max_disparity;
00341 masked_disparity.delta_d = disparity_image->delta_d;
00342
00343 float *dimd_in = (float*)&(disparity_image->image.data[0]);
00344 uint8_t *labelsd = (uint8_t*)&(labels.data[0]);
00345
00346 float *dimd_out = (float*)&(masked_disparity.image.data[0]);
00347
00348 for (int y=0;y<height; y++) {
00349 for (int x=0;x<width; x++) {
00350 int adr = y*width+x;
00351 if(labelsd[adr]==0)
00352 dimd_out[adr] = dimd_in[adr];
00353 else dimd_out[adr] = -1.0f;
00354 }
00355 }
00356 }
00357 }
00358
00359 int main(int argc, char **argv)
00360 {
00361 ros::init(argc, argv, "fast_plane_detection_node");
00362
00364 int buffer_size_ = 1;
00365 fast_plane_detection::FastPlaneDetector node_(buffer_size_);
00366 ros::spin();
00367
00368 return 0;
00369 }