camera_people_detection_alg_node.cpp
Go to the documentation of this file.
00001 #include "camera_people_detection_alg_node.h"
00002 
00003 CameraPeopleDetectionAlgNode::CameraPeopleDetectionAlgNode(void) :
00004   algorithm_base::IriBaseAlgorithm<CameraPeopleDetectionAlgorithm>(), 
00005   it_(public_node_handle_),
00006   tf_listener_(ros::Duration(30.f)),
00007   new_laser_event_id_("new_laser_event"),
00008   new_image_event_id_("new_image_event"),
00009   new_tracker_event_id_("new_tracker_event"),
00010   width_resize_(0.3f),
00011   height_resize_(0.3f),
00012   minthr_(-0.5)
00013 {
00014   //init class attributes if necessary
00015   loop_rate_ = 10;//in [Hz]
00016 
00017   // [init publishers]
00018   markers_publisher_         = public_node_handle_.advertise<visualization_msgs::MarkerArray>("markers", 100);
00019   image_detection_publisher_ = public_node_handle_.advertise<iri_perception_msgs::detectionArray>("image_detection", 100);
00020   debug_img_publisher_       = it_.advertise("debug_image", 1);
00021 
00022   // [init subscribers]
00023   this->tracker_subscriber_ = this->public_node_handle_.subscribe("tracker", 100, &CameraPeopleDetectionAlgNode::tracker_callback, this);
00024   laser_subscriber_ = public_node_handle_.subscribe("scan", 100, &CameraPeopleDetectionAlgNode::laser_callback, this);
00025   people_detection_subscriber_ = public_node_handle_.subscribe("people_detection", 100, &CameraPeopleDetectionAlgNode::people_detection_callback, this);
00026   cam_sub_ = it_.subscribeCamera("image_in", 1, &CameraPeopleDetectionAlgNode::image_callback, this);
00027   
00028   // [init services]
00029   
00030   // [init clients]
00031   
00032   // [init action servers]
00033   
00034   // [init action clients]
00035 
00036   event_server_ = CEventServer::instance();
00037   event_server_->create_event(new_laser_event_id_);
00038   event_server_->create_event(new_image_event_id_);
00039   event_server_->create_event(new_tracker_event_id_);
00040 }
00041 
00042 CameraPeopleDetectionAlgNode::~CameraPeopleDetectionAlgNode(void)
00043 {
00044   // [free dynamic memory]
00045 }
00046 
00047 void CameraPeopleDetectionAlgNode::fillMarkerArray(const iri_perception_msgs::detectionArray & fusion_poses_msg,
00048                                                    visualization_msgs::MarkerArray & markerArray_msg)
00049 {
00050   static unsigned int lastSize=0;
00051   markerArray_msg.markers.resize(std::max(uint(fusion_poses_msg.detection.size()), lastSize));
00052   lastSize = fusion_poses_msg.detection.size();
00053 
00054   for(unsigned int ii=0; ii<fusion_poses_msg.detection.size(); ii++)
00055   {
00056     markerArray_msg.markers[ii].header   = fusion_poses_msg.header;
00057     markerArray_msg.markers[ii].id       = ii;
00058     markerArray_msg.markers[ii].pose     = fusion_poses_msg.detection[ii].pose.pose;
00059     markerArray_msg.markers[ii].type     = visualization_msgs::Marker::CYLINDER;
00060     markerArray_msg.markers[ii].action   = visualization_msgs::Marker::ADD;
00061     markerArray_msg.markers[ii].scale.x  = 0.5f;
00062     markerArray_msg.markers[ii].scale.y  = 0.5f;
00063     markerArray_msg.markers[ii].scale.z  = 1.0f;
00064     markerArray_msg.markers[ii].color.a  = 0.75f;
00065 
00066     // if laser and camera match detection
00067     if(fusion_poses_msg.detection[ii].probability > 0)
00068     {
00069       markerArray_msg.markers[ii].color.r  = 0.0f;
00070       markerArray_msg.markers[ii].color.g  = 1.0f;
00071       markerArray_msg.markers[ii].color.b  = 0.0f;
00072     }
00073     else
00074     {
00075       // if detection is out of camera viewpoint
00076       if(fusion_poses_msg.detection[ii].probability == 0)
00077       {
00078         markerArray_msg.markers[ii].color.r  = 1.0f;
00079         markerArray_msg.markers[ii].color.g  = 1.0f;
00080         markerArray_msg.markers[ii].color.b  = 0.0f;
00081       }
00082       // if laser and camera match detection too close to camera
00083       else
00084       {
00085         markerArray_msg.markers[ii].color.r  = 0.0f;
00086         markerArray_msg.markers[ii].color.g  = 0.0f;
00087         markerArray_msg.markers[ii].color.b  = 1.0f;
00088       }
00089     }
00090     markerArray_msg.markers[ii].lifetime = ros::Duration(1.0f);;
00091   }
00092 
00093   //Delete extra previous markers;
00094   for(unsigned int i=fusion_poses_msg.detection.size(); i<markerArray_msg.markers.size(); i++)
00095   {
00096     markerArray_msg.markers[i].action = visualization_msgs::Marker::DELETE;
00097   }
00098 }
00099 
00100 void CameraPeopleDetectionAlgNode::filterLaserDetections(iri_perception_msgs::detectionArray & fusion_poses_msg,
00101                                                          cv_bridge::CvImage  & img_msg)
00102 {
00103   image_mutex_.enter();
00104   people_detection_mutex_.enter();
00105     std::vector<detection> vLaserPeople(laser_poses_msg_.detection.size(),detection());
00106     //std::vector<detection> vTrackPeople(tracker_msg_.peopleSet.size(),detection());
00107 
00108     //resize original image size and detections
00109     cv::Mat img_resized;
00110     cv::resize(cv_ptr_->image, img_resized, cv::Size(), width_resize_, height_resize_, cv::INTER_LINEAR);
00111     
00112     // compute transform from laser frame to camera frame
00113     // and create detections vector
00114     tf::StampedTransform laser_to_camera_transf;
00115     try
00116     {
00117       //ros::Time acquisition_time = laser_poses_msg_.header.stamp;
00118       ros::Time now = ros::Time::now();
00119       ros::Duration timeout(1.0f);
00120       
00121           ROS_INFO("Entra_waittf");
00122       // wait for transform from laser to camera 
00123       bool tf_exists = tf_listener_.waitForTransform(cam_model_.tfFrame(), laser_poses_msg_.header.frame_id,
00124                                                      now, timeout);
00125                                                      //acquisition_time, timeout);
00126 
00127       if(tf_exists)
00128       {
00129         tf_listener_.lookupTransform(cam_model_.tfFrame(), laser_poses_msg_.header.frame_id,
00130                                      now, laser_to_camera_transf);
00131                                      //acquisition_time, laser_to_camera_transf);
00132                 ROS_INFO("Entra_ldec");
00133         // create vector with laser detections transformed into image plane
00134         // vLaserPeople.resize(laser_poses_msg_.detection.size());
00135         for(unsigned int ii=0; ii<laser_poses_msg_.detection.size(); ii++)
00136         {
00137           //transform points from laser frame to image coordinates
00138           tf::Point laser_point(laser_poses_msg_.detection[ii].pose.pose.position.x,
00139                                 laser_poses_msg_.detection[ii].pose.pose.position.y,
00140                                 laser_poses_msg_.detection[ii].pose.pose.position.z);
00141           tf::Point cam_point(laser_to_camera_transf * laser_point);
00142           cv::Point3d cv_cam_point(cam_point.x(), cam_point.y(), cam_point.z());
00143           cv::Point2d image_point = cam_model_.project3dToPixel(cv_cam_point);
00144           
00145           // fill detections struct
00146           float x     = laser_poses_msg_.detection[ii].pose.pose.position.x;
00147           float y     = laser_poses_msg_.detection[ii].pose.pose.position.y;
00148           float depth = sqrt(x*x + y*y);
00149 
00150           vLaserPeople[ii].id    = ii;
00151           vLaserPeople[ii].im_x  = floor(image_point.x * width_resize_);
00152           vLaserPeople[ii].im_y  = floor(image_point.y * height_resize_);
00153           vLaserPeople[ii].depth = depth;
00154           vLaserPeople[ii].score = laser_poses_msg_.detection[ii].probability;
00155         }
00156                 ROS_INFO("Sale_ldec");
00157 
00158         /*tracker_mutex_.enter();
00159                 ROS_INFO("Entra_tdec"); 
00160                 ROS_WARN("tracker_msg_.peopleSet.size=%d ",tracker_msg_.peopleSet.size());
00161         for(unsigned int ii=0; ii<tracker_msg_.peopleSet.size(); ii++)
00162         {
00163           tf::Point tracker_point(tracker_msg_.peopleSet[ii].x,
00164                                   tracker_msg_.peopleSet[ii].y,
00165                                   0.f);
00166           tf::Point cam_point(laser_to_camera_transf * tracker_point);
00167           cv::Point3d cv_cam_point(cam_point.x(), cam_point.y(), cam_point.z());
00168           cv::Point2d image_point = cam_model_.project3dToPixel(cv_cam_point);
00169           
00170           // fill detections struct
00171           float x     = tracker_msg_.peopleSet[ii].x;
00172           float y     = tracker_msg_.peopleSet[ii].y;
00173           float depth = sqrt(x*x + y*y);
00174 
00175           vTrackPeople[ii].id    = ii;
00176           vTrackPeople[ii].im_x  = floor(image_point.x * width_resize_);
00177           vTrackPeople[ii].im_y  = floor(image_point.y * height_resize_);
00178           vTrackPeople[ii].depth = depth;
00179           vTrackPeople[ii].score = tracker_msg_.peopleSet[ii].probability;
00180           ROS_WARN("vTrackPeople[%d].im_x=%d vTrackPeople[ii].im_y=%d",ii,vTrackPeople[ii].im_x,vTrackPeople[ii].im_y);
00181         }
00182                 ROS_INFO("Sale_tdec");
00183         tracker_mutex_.exit();*/      
00184       }
00185       else
00186       {
00187           ROS_INFO("CameraPeopleDetectionAlgNode::No transform: %s-->%s", cam_model_.tfFrame().c_str(), laser_poses_msg_.header.frame_id.c_str());
00188       }
00189           ROS_INFO("Sale_waittf");
00190     }
00191     catch (tf::TransformException& ex)
00192     {
00193       ROS_WARN("TF exception:\n%s", ex.what());
00194     }
00195 
00196     // filter laser detections
00197     std::vector<detection> vOutputPeople;
00198     std::vector<cv::Rect> found;
00199     std::vector<double> foundWeights;    
00200 
00201     // execute camera people detection algorithm
00202         ROS_INFO("Entra_val_detec");
00203     cam_detector_.validate_detections(img_resized, vLaserPeople, vOutputPeople, found, foundWeights, minthr_);
00204     //cam_detector_.validate_detections(img_resized, vLaserPeople, vTrackPeople, vOutputPeople, found, foundWeights, minthr_);
00205         ROS_INFO("Sale_val_detec");
00206 
00207     // debug output image
00208     cv::Mat outIm;
00209 
00210     // draw all laser points on image
00211     laser_mutex_.enter();
00212       std::vector<detection> vAllScans(scan_.ranges.size(),detection());
00213       for(unsigned int ii=0; ii<scan_.ranges.size(); ii++)
00214       {
00215         float scan_x = scan_.ranges[ii]*cos(scan_.angle_min+scan_.angle_increment*ii);
00216         float scan_y = scan_.ranges[ii]*sin(scan_.angle_min+scan_.angle_increment*ii);
00217         float scan_z = 0.f;
00218 
00219         //transform points from laser frame to image coordinates
00220         tf::Point laser_point(scan_x, scan_y, scan_z);
00221         tf::Point cam_point(laser_to_camera_transf * laser_point);
00222         cv::Point3d cv_cam_point(cam_point.x(), cam_point.y(), cam_point.z());
00223         cv::Point2d image_point = cam_model_.project3dToPixel(cv_cam_point);
00224         
00225         // fill detections struct
00226         vAllScans[ii].id    = -1;
00227         vAllScans[ii].im_x  = floor(image_point.x * width_resize_);
00228         vAllScans[ii].im_y  = floor(image_point.y * height_resize_);
00229         vAllScans[ii].depth = sqrt(scan_x*scan_x + scan_y*scan_y);
00230         vAllScans[ii].score = -2;
00231       }
00232           ROS_INFO("Entra_draw");
00233       cam_detector_.drawalllaserdetections(img_resized, outIm, vAllScans);
00234           ROS_INFO("Sale_draw");    
00235         laser_mutex_.exit();
00236 
00237     // draw detections on image
00238    cam_detector_.drawvalImagelaserdetections(outIm, outIm, vLaserPeople, vOutputPeople, found, minthr_); // only show
00239  //   cam_detector_.drawvalImagelaserdetectionsFile(outIm, outIm, vLaserPeople, vOutputPeople, found, minthr_); // show and save in a File
00240 //    cam_detector_.drawallinfodetections(outIm, outIm, vLaserPeople, vOutputPeople, found, foundWeights); // show all info from detcs
00241     
00242     img_msg.header   = cv_ptr_->header;
00243     img_msg.encoding = cv_ptr_->encoding;
00244     img_msg.image    = outIm;
00245    
00246     // fill new vector to publish
00247     fusion_poses_msg.detection.clear();
00248     fusion_poses_msg.detection.resize(vOutputPeople.size());
00249 
00250     fusion_poses_msg.header = laser_poses_msg_.header;
00251 
00252         ROS_WARN("vOutputPeople.size=%lu ",vOutputPeople.size());
00253     for(unsigned int ii=0; ii<vOutputPeople.size(); ii++)
00254     {
00255           ROS_WARN("vOutputPeople[%d].id=%d laser_poses_msg_.detection.size()=%lu",ii,vOutputPeople[ii].id,laser_poses_msg_.detection.size());
00256           // TODO: posible problem laser does not contain all the poses from vOutputPeople (when is with tracking)
00257           fusion_poses_msg.detection[ii] = laser_poses_msg_.detection[vOutputPeople[ii].id]; 
00258       fusion_poses_msg.detection[ii].probability = vOutputPeople[ii].score;
00259           
00260     }
00261 
00262   people_detection_mutex_.exit();
00263   image_mutex_.exit();
00264 
00265 }
00266 
00267 void CameraPeopleDetectionAlgNode::mainNodeThread(void)
00268 {
00269   static std::list<std::string> events;
00270   events.push_back(new_laser_event_id_);
00271   events.push_back(new_image_event_id_);
00272   events.push_back(new_tracker_event_id_);
00273 
00274   // [fill msg structures]
00275 
00276   // [fill srv structure and make request to the server]
00277   
00278   // [fill action structure and make request to the action server]
00279 
00280   // [publish messages]
00281 
00282   //unsigned int event_id = event_server_->wait_first(events);
00283   //event_server_->wait_all(events);
00284   if(event_server_->event_is_set(new_laser_event_id_) && 
00285      event_server_->event_is_set(new_image_event_id_) &&
00286      event_server_->event_is_set(new_tracker_event_id_) )
00287   {
00288     event_server_->reset_event(new_laser_event_id_);
00289     event_server_->reset_event(new_image_event_id_);
00290     event_server_->reset_event(new_tracker_event_id_);
00291 
00292         ROS_INFO("Entra_Camera_People");  
00293     // filter laser detections with image detections
00294     iri_perception_msgs::detectionArray fusion_poses_msg;
00295     cv_bridge::CvImage img_msg;
00296     filterLaserDetections(fusion_poses_msg, img_msg);
00297         ROS_INFO("Sale_Camera_People");  
00298 
00299         ROS_INFO("Entra_copydect");  
00300     // copy image detections to marker array for rviz visualization
00301     visualization_msgs::MarkerArray markerArray_msg;
00302     fillMarkerArray(fusion_poses_msg, markerArray_msg);
00303         ROS_INFO("Sale_copydect");  
00304 
00305         ROS_INFO("Entra_publish");  
00306     // publish all data
00307     image_detection_publisher_.publish(fusion_poses_msg);
00308     markers_publisher_.publish(markerArray_msg);
00309     debug_img_publisher_.publish(img_msg.toImageMsg());
00310         ROS_INFO("Sale_publish");  
00311   }
00312 
00313 }
00314 
00315 /*  [subscriber callbacks] */
00316 void CameraPeopleDetectionAlgNode::tracker_callback(const iri_perception_msgs::peopleTrackingArray::ConstPtr& msg) 
00317 { 
00318   ROS_DEBUG("CameraPeopleDetectionAlgNode::tracker_callback: New Message Received"); 
00319 
00320   tracker_mutex_.enter(); 
00321     tracker_msg_.header = msg->header;
00322     tracker_msg_.peopleSet.clear();
00323     tracker_msg_.peopleSet.resize(msg->peopleSet.size());
00324     for(unsigned int ii=0; ii<msg->peopleSet.size(); ii++)
00325     {
00326       tracker_msg_.peopleSet[ii].targetId = msg->peopleSet[ii].targetId;
00327       tracker_msg_.peopleSet[ii].x = msg->peopleSet[ii].x;
00328       tracker_msg_.peopleSet[ii].y = msg->peopleSet[ii].y;
00329       tracker_msg_.peopleSet[ii].vx = msg->peopleSet[ii].vx;
00330       tracker_msg_.peopleSet[ii].vy = msg->peopleSet[ii].vy;
00331       tracker_msg_.peopleSet[ii].covariances = msg->peopleSet[ii].covariances;
00332     }
00333   tracker_mutex_.exit(); 
00334   
00335   if( !event_server_->event_is_set(new_tracker_event_id_) )
00336     event_server_->set_event(new_tracker_event_id_);
00337 }
00338 
00339 void CameraPeopleDetectionAlgNode::laser_callback(const sensor_msgs::LaserScan::ConstPtr& msg) 
00340 { 
00341   ROS_DEBUG("CameraPeopleDetectionAlgNode::laser_callback: New Message Received"); 
00342 
00343   laser_mutex_.enter(); 
00344     scan_.header          = msg->header;
00345     scan_.angle_min       = msg->angle_min;
00346     scan_.angle_max       = msg->angle_max;
00347     scan_.angle_increment = msg->angle_increment;
00348     scan_.time_increment  = msg->time_increment;
00349     scan_.scan_time       = msg->scan_time;
00350     scan_.range_min       = msg->range_min;
00351     scan_.range_max       = msg->range_max;
00352     scan_.ranges          = msg->ranges;
00353     scan_.intensities     = msg->intensities;
00354   laser_mutex_.exit(); 
00355 }
00356 void CameraPeopleDetectionAlgNode::people_detection_callback(const iri_perception_msgs::detectionArray::ConstPtr& msg) 
00357 { 
00358   ROS_DEBUG("CameraPeopleDetectionAlgNode::people_detection_callback: New Message Received"); 
00359 
00360   people_detection_mutex_.enter();
00361     laser_poses_msg_.detection.clear(); 
00362     laser_poses_msg_.header     = msg->header;
00363     laser_poses_msg_.detection  = msg->detection;
00364   people_detection_mutex_.exit(); 
00365 
00366   if( !event_server_->event_is_set(new_laser_event_id_) )
00367     event_server_->set_event(new_laser_event_id_);
00368 }
00369 
00370 void CameraPeopleDetectionAlgNode::image_callback(const sensor_msgs::ImageConstPtr& image_msg, 
00371                                                   const sensor_msgs::CameraInfoConstPtr& info_msg)
00372 {
00373   ROS_DEBUG("CameraPeopleDetectionAlgNode::image_callback: New Message Received"); 
00374 
00375   image_mutex_.enter();
00376     try
00377     {
00378       cv_ptr_ = cv_bridge::toCvCopy(image_msg, sensor_msgs::image_encodings::BGR8);
00379     }
00380     catch (cv_bridge::Exception& e)
00381     {
00382       ROS_ERROR("cv_bridge exception: %s", e.what());
00383       return;
00384     }
00385     
00386     // update camera model
00387     cam_model_.fromCameraInfo(info_msg);
00388   image_mutex_.exit();
00389 
00390   if( !event_server_->event_is_set(new_image_event_id_) )
00391     event_server_->set_event(new_image_event_id_);
00392 }
00393 
00394 /*  [service callbacks] */
00395 
00396 /*  [action callbacks] */
00397 
00398 /*  [action requests] */
00399 
00400 void CameraPeopleDetectionAlgNode::node_config_update(Config &config, uint32_t level)
00401 {
00402   alg_.lock();
00403   image_mutex_.enter();
00404     width_resize_  = config.width_resize;
00405     height_resize_ = config.height_resize;
00406     minthr_ = config.min_threshold;
00407     cam_detector_.setDectThr(config.thr_dect);
00408   image_mutex_.exit();
00409   alg_.unlock();
00410 }
00411 
00412 void CameraPeopleDetectionAlgNode::addNodeDiagnostics(void)
00413 {
00414 }
00415 
00416 /* main function */
00417 int main(int argc,char *argv[])
00418 {
00419   return algorithm_base::main<CameraPeopleDetectionAlgNode>(argc, argv, "camera_people_detection_alg_node");
00420 }


iri_camera_people_detection
Author(s): Joan Perez, jnperez at iri.upc.edu
autogenerated on Fri Dec 6 2013 22:21:44