tracker_node.cpp
Go to the documentation of this file.
00001 #include <blort_ros/tracker_node.h>
00002 #include <boost/foreach.hpp>
00003 #include <sstream>
00004 
00005 TrackerNode::TrackerNode(std::string root)
00006   : nh_("blort_tracker"), it_(nh_), pose_seq(0), camera_frame_id("0"), root_(root), tracker(0)
00007 {
00008   nh_.param<std::string>("launch_mode", launch_mode, "tracking");
00009   detection_result = nh_.advertise<blort_msgs::TrackerResults>("detection_result", 100);
00010   confidences_pub = nh_.advertise<blort_msgs::TrackerConfidences>("confidences", 100);
00011   image_pub = it_.advertise("image_result", 1);
00012 
00013   if(launch_mode == "tracking")
00014   {
00015     mode = new TrackingMode(this);
00016   }else if(launch_mode == "singleshot")
00017   {
00018     mode = new SingleShotMode(this);
00019   } else {
00020     ROS_FATAL("Invalid launch_mode parameter passed to blort_tracker.");
00021   }
00022 }
00023 
00024 TrackerNode::~TrackerNode()
00025 {
00026   if(tracker != 0)
00027     delete(tracker);
00028   delete mode;
00029 }
00030 
00031 void TrackerNode::setCameraFrameID(const std::string & id)
00032 {
00033   camera_frame_id = id;
00034 }
00035 
00036 void TrackerNode::imageCb(const sensor_msgs::ImageConstPtr& detectorImgMsg,
00037                           const sensor_msgs::ImageConstPtr& trackerImgMsg )
00038 {
00039   if(tracker != 0)
00040   {
00041     cv_bridge::CvImagePtr cv_detector_ptr, cv_tracker_ptr;
00042     try
00043     {
00044       cv_detector_ptr = cv_bridge::toCvCopy(detectorImgMsg, sensor_msgs::image_encodings::BGR8);
00045       cv_tracker_ptr  = cv_bridge::toCvCopy(trackerImgMsg,  sensor_msgs::image_encodings::BGR8);
00046     }
00047     catch (cv_bridge::Exception& e)
00048     {
00049       ROS_ERROR("cv_bridge exception: %s", e.what());
00050       return;
00051     }
00052 
00053     bool should_process = false;
00054     std::vector<std::string> lost_ids;
00055     BOOST_FOREACH(const blort::ObjectEntry& obj, tracker->getObjects())
00056     {
00057       if(obj.is_tracked)
00058       {
00059         if(tracker->getMode(obj.name) == blort_ros::TRACKER_RECOVERY_MODE)
00060         {
00061           if(recovery_answers.count(obj.name))
00062           {
00063             tracker->resetWithPose(obj.name, recovery_answers[obj.name]);
00064             recovery_answers.erase(obj.name);
00065           }
00066           else
00067           {
00068             lost_ids.push_back(obj.name);
00069           }
00070         }
00071         else //TRACKER_TRACKING_MODE or TRACKER_LOCKED_MODE
00072         {
00073           should_process = true;
00074         }
00075       }
00076     }
00077     if(!lost_ids.empty())
00078     {
00079       boost::mutex::scoped_lock lock(recovery_mutex, boost::try_to_lock);
00080       if(lock)
00081       {
00082         // the recovery() function will be called with the result of "getRecoveryCall()" on a separate thread
00083         recovery_th = boost::thread(boost::bind(&TrackerNode::recovery, this, mode->getRecoveryCall(lost_ids, detectorImgMsg)));
00084       }
00085     }
00086     if(should_process)
00087     {
00088       ROS_INFO("----------------------------------------------");
00089       ROS_INFO("TrackerNode::imageCb: calling tracker->process");
00090       tracker->process(cv_tracker_ptr->image);
00091       BOOST_FOREACH(const blort::ObjectEntry& obj, tracker->getObjects())
00092       {
00093         if(tracker->getMode(obj.name) != blort_ros::TRACKER_RECOVERY_MODE && obj.is_tracked)
00094         {
00095           //confidences_pub.publish(*(tracker->getConfidences()[item.first]));
00096           if(tracker->getConfidence(obj.name) == blort_ros::TRACKER_CONF_GOOD ||
00097              (tracker->getConfidence(obj.name) == blort_ros::TRACKER_CONF_FAIR &&
00098               tracker->getPublishMode() == blort_ros::TRACKER_PUBLISH_GOOD_AND_FAIR) )
00099           {
00100             blort_msgs::TrackerResults msg;
00101             msg.obj_name.data = obj.name;
00102             msg.pose.header.seq = pose_seq++;
00103             msg.pose.header.stamp = ros::Time::now();
00104             msg.pose.header.frame_id = camera_frame_id;
00105             msg.pose.pose = blort_ros::blortPosesToRosPose(tracker->getCameraReferencePose(),
00106                                                            tracker->getDetections()[obj.name]);
00107             detection_result.publish(msg);
00108           }
00109         }
00110         cv_bridge::CvImage out_msg;
00111         out_msg.header = trackerImgMsg->header;
00112         out_msg.header.stamp = ros::Time::now();
00113         out_msg.encoding = sensor_msgs::image_encodings::BGR8;
00114         out_msg.image = tracker->getImage();
00115         image_pub.publish(out_msg.toImageMsg());
00116       }
00117     }
00118   }
00119 }
00120 
00121 void TrackerNode::recovery(blort_msgs::RecoveryCall srv)
00122 {
00123   boost::mutex::scoped_lock lock(recovery_mutex);
00124   ros::Time before = ros::Time::now();
00125   {
00126     std::stringstream ss;
00127     ss << "tracker_node calling detector_node recovery service for object(s): ";
00128     for(size_t i = 0; i < srv.request.object_ids.size();++i)
00129     {
00130       ss << srv.request.object_ids[i]  << ", ";
00131     }
00132     ROS_WARN_STREAM(ss.str());
00133   }
00134   if(recovery_client.call(srv))
00135   {
00136     for(size_t i = 0; i < srv.response.Poses.size(); ++i)
00137     {
00138       if(srv.response.object_founds[i])
00139       {
00140         recovery_answers[srv.response.object_ids[i]] = srv.response.Poses[i];
00141       }
00142     }
00143   }
00144   else
00145   {
00146     ROS_WARN("Detector not confident enough.");
00147   }
00148   ROS_INFO_STREAM("Recovery call took " << (ros::Time::now() - before));
00149 }
00150 
00151 bool TrackerNode::trackerControlServiceCb(blort_msgs::TrackerCommand::Request &req,
00152                                           blort_msgs::TrackerCommand::Response &)
00153 {
00154   if(tracker != 0)
00155   {
00156     tracker->trackerControl(req.code, req.param);
00157     return true;
00158   } else {
00159     ROS_WARN("Please publish camera_info for the tracker initialization.");
00160     return false;
00161   }
00162 }
00163 
00164 // STATE DESIGN PATTERN
00165 // to implement the different tracker modes
00166 TrackerNode::TrackingMode::TrackingMode(TrackerNode* parent) : parent_(parent)
00167 {
00168   ROS_INFO("Blort tracker launched in tracking mode.");
00169   cam_info_sub = parent_->nh_.subscribe("/detector_camera_info", 10,
00170                                         &TrackerNode::TrackingMode::cam_info_callback, this);
00171 }
00172 
00173 void TrackerNode::TrackingMode::reconf_callback(blort_ros::TrackerConfig &config, uint32_t level)
00174 {
00175   if(parent_->tracker != 0)
00176   {
00177     parent_->tracker->reconfigure(config);
00178   } else {
00179     ROS_WARN("Please publish camera_info for the tracker initialization.");
00180   }
00181 }
00182 
00183 blort_msgs::RecoveryCall TrackerNode::TrackingMode::getRecoveryCall(std::vector<std::string> & ids,
00184                                                                     const sensor_msgs::ImageConstPtr& msg)
00185 {
00186   blort_msgs::RecoveryCall srv;
00187   srv.request.object_ids.resize(ids.size());
00188   for(size_t i = 0; i < ids.size(); ++i)
00189   {
00190     srv.request.object_ids[i] = ids[i];
00191   }
00192   srv.request.Image = *msg;
00193   return srv;
00194 }
00195 
00196 // The real initialization is being done after receiving the camerainfo.
00197 void TrackerNode::TrackingMode::cam_info_callback(const sensor_msgs::CameraInfo &msg)
00198 {
00199   if(parent_->tracker == 0)
00200   {
00201     ROS_INFO("Camera parameters received, ready to run.");
00202     parent_->setCameraFrameID(msg.header.frame_id);
00203     //parent_->_msg = msg; //2012-11-27 Jordi: keep a copy to reset the tracker when necessary
00204     cam_info_sub.shutdown();
00205     parent_->tracker = new blort_ros::GLTracker(msg, parent_->root_, true);
00206     parent_->tracker->setVisualizeObjPose(true);
00207     parent_->tracker->enableAllTracking(true);
00208 
00209     image_transport::TransportHints transportHint("raw");
00210 
00211     detector_image_sub.reset(new image_transport::SubscriberFilter(
00212                                parent_->it_, "/detector_image", 1, transportHint));
00213     tracker_image_sub.reset(new image_transport::SubscriberFilter(
00214                               parent_->it_, "/tracker_image", 1, transportHint));
00215 
00216     imageSynchronizer.reset( new message_filters::TimeSynchronizer<sensor_msgs::Image,
00217                              sensor_msgs::Image>(*detector_image_sub, *tracker_image_sub, 1) );
00218 
00219     imageSynchronizer->registerCallback(boost::bind(&TrackerNode::imageCb, parent_, _1, _2));
00220 
00221     parent_->control_service = parent_->nh_.advertiseService(
00222           "tracker_control", &TrackerNode::trackerControlServiceCb, parent_);
00223     parent_->server_ = std::auto_ptr<dynamic_reconfigure::Server<blort_ros::TrackerConfig> >
00224         (new dynamic_reconfigure::Server<blort_ros::TrackerConfig>());
00225     parent_->f_ = boost::bind(&TrackerNode::TrackingMode::reconf_callback, this, _1, _2);
00226     parent_->server_->setCallback(parent_->f_);
00227     parent_->recovery_client = parent_->nh_.serviceClient<blort_msgs::RecoveryCall>("/blort_detector/pose_service");
00228   }
00229 }
00230 
00231 TrackerNode::SingleShotMode::SingleShotMode(TrackerNode* parent)
00232   : as_(parent->nh_, "recognize_object", false)
00233   , parent_(parent)
00234 {
00235   ROS_INFO("Blort tracker launched in singleshot mode.");
00236   detector_set_caminfo_service = parent_->nh_.serviceClient<blort_msgs::SetCameraInfo>("/blort_detector/set_camera_info");
00237   singleshot_service = parent_->nh_.advertiseService("singleshot_service", &TrackerNode::SingleShotMode::singleShotService, this);
00238 
00239   parent_->control_service = parent_->nh_.advertiseService("tracker_control", &TrackerNode::trackerControlServiceCb, parent_);
00240   parent_->server_ = std::auto_ptr<dynamic_reconfigure::Server<blort_ros::TrackerConfig> >
00241       (new dynamic_reconfigure::Server<blort_ros::TrackerConfig>());
00242   parent_->f_ = boost::bind(&SingleShotMode::reconf_callback, this, _1, _2);
00243   parent_->server_->setCallback(parent_->f_);
00244 
00245   time_to_run_singleshot = 10.;
00246   inServiceCall = false;
00247   parent->nh_.param<double>("conf_threshold", conf_treshold_, 0.3);
00248 
00249   as_.registerGoalCallback(boost::bind(&TrackerNode::SingleShotMode::goalCb, this, _1));
00250   as_.start();
00251 }
00252 
00253 void TrackerNode::SingleShotMode::reconf_callback(blort_ros::TrackerConfig &config, uint32_t level)
00254 {
00255   time_to_run_singleshot =  config.time_to_run_singleshot;
00256 }
00257 
00258 blort_msgs::RecoveryCall TrackerNode::SingleShotMode::getRecoveryCall(std::vector<std::string> & ids,
00259                                                                       const sensor_msgs::ImageConstPtr& msg)
00260 {
00261   blort_msgs::RecoveryCall srv;
00262   if(!inServiceCall)
00263   {
00264     srv.request.object_ids.resize(ids.size());
00265     for(size_t i = 0; i < ids.size(); ++i)
00266     {
00267       ROS_WARN_STREAM("TrackerNode::SingleShotMode::getRecoveryCall: "  << ids[i]);
00268       srv.request.object_ids[i] = ids[i];
00269     }
00270     srv.request.Image = *msg;
00271     // we step into the service call "state" with the first recoverycall made
00272     // no new images are accepted until the end of the singleShotServiceCall
00273     inServiceCall = true;
00274   }
00275   return srv;
00276 }
00277 
00278 /* FIXME Implement single-shot with object selection */
00279 /* For now, single-shot runs on first object for backward compatibility */
00280 bool TrackerNode::SingleShotMode::singleShotService(blort_msgs::EstimatePose::Request &req,
00281                                                     blort_msgs::EstimatePose::Response &resp)
00282 {
00283   lastImage.reset();
00284   lastImage = ros::topic::waitForMessage<sensor_msgs::Image>("/detector_image", parent_->nh_, ros::Duration(1.0));
00285   lastCameraInfo.reset();
00286   lastCameraInfo = ros::topic::waitForMessage<sensor_msgs::CameraInfo>("/detector_camera_info", parent_->nh_, ros::Duration(1.0));
00287 
00288   if(lastImage.use_count() < 1 && lastCameraInfo.use_count() < 1)
00289   {
00290     ROS_ERROR("Service called but there was no data on the input topics!");
00291     return false;
00292   }
00293   else
00294   {
00295     ROS_INFO("Singleshot service has been called with a timeout of %f seconds.", time_to_run_singleshot);
00296     results_list.clear();
00297 
00298     if(parent_->tracker == 0)
00299     {
00300       parent_->tracker = new blort_ros::GLTracker(*lastCameraInfo, parent_->root_, true);
00301       parent_->recovery_client = parent_->nh_.serviceClient<blort_msgs::RecoveryCall>("/blort_detector/pose_service");
00302     }
00303     else
00304     {
00305       parent_->tracker->reset();
00306       parent_->recovery_answers.clear();
00307     }
00308     //HACK: hardcoded tracking for pringles
00309     parent_->tracker->enableAllTracking(false);
00310     parent_->tracker->setTracked("Pringles", true);
00311 
00312     parent_->tracker->setPublishMode(blort_ros::TRACKER_PUBLISH_GOOD);
00313     parent_->tracker->setVisualizeObjPose(true);
00314     blort_msgs::SetCameraInfo camera_info;
00315     camera_info.request.CameraInfo = *lastCameraInfo;
00316     if(!detector_set_caminfo_service.call(camera_info))
00317       ROS_ERROR("blort_tracker failed to call blort_detector/set_camera_info service");
00318 
00319     double start_secs = ros::Time::now().toSec();
00320     while(ros::Time::now().toSec()-start_secs < time_to_run_singleshot)
00321     {
00322       ROS_INFO("Remaining time %f", time_to_run_singleshot+start_secs-ros::Time::now().toSec());
00323       parent_->imageCb(lastImage, lastImage);
00324       if(parent_->tracker->getConfidence("Pringles") == blort_ros::TRACKER_CONF_FAIR) // HACK
00325       {
00326         // instead of returning right away let's store the result
00327         // to see if the tracker can get better
00328         results_list.push_back(parent_->tracker->getDetections()["Pringles"]); // HACK
00329       }
00330       else if(parent_->tracker->getConfidence("Pringles") == blort_ros::TRACKER_CONF_LOST) // HACK
00331       {
00332         results_list.clear();
00333       }
00334     }
00335     // we are out of the service call now, the results will be published
00336     inServiceCall = false;
00337     if(!results_list.empty())
00338     {
00339       //convert results to a tf style transform and multiply them
00340       //to get the camera-to-target transformation
00341       resp.Pose = blort_ros::blortPosesToRosPose(parent_->tracker->getCameraReferencePose(),
00342                                                  results_list.back());
00343       //NOTE: check the pose in vec3 location + mat3x3 rotation could be added here
00344       // if we have any previous knowledge of the given scene
00345       ROS_INFO_STREAM("PUBLISHED POSE:" << std::endl << resp.Pose.position << std::endl <<
00346                       blort_ros::quaternionTo3x3cvMat(resp.Pose.orientation) << std::endl);
00347       return true;
00348     }
00349     else
00350     {
00351       //if the time was not enough to get a good detection, make the whole thing fail
00352       return false;
00353     }
00354   }
00355 }
00356 
00357 void TrackerNode::SingleShotMode::goalCb(AcServer::GoalHandle gh)
00358 {
00359   AcServer::GoalConstPtr goal = gh.getGoal();
00360   gh.setAccepted();
00361   result_.recognized_objects.objects.clear();
00362 
00363   if(goal->objects.empty())
00364   {
00365     gh.setSucceeded(result_);
00366     return;
00367   }
00368 
00369   lastImage.reset();
00370   lastImage = ros::topic::waitForMessage<sensor_msgs::Image>("/detector_image", parent_->nh_, ros::Duration(3.0));
00371   sensor_msgs::ImageConstPtr lastDepth = ros::topic::waitForMessage<sensor_msgs::Image>("/depth_image", parent_->nh_, ros::Duration(3.0));
00372   lastCameraInfo.reset();
00373   lastCameraInfo = ros::topic::waitForMessage<sensor_msgs::CameraInfo>("/detector_camera_info", parent_->nh_, ros::Duration(3.0));
00374   if(lastImage.use_count() < 1 && lastCameraInfo.use_count() < 1)
00375   {
00376     ROS_ERROR("Action called but there was no data on the input topics!");
00377     gh.setAborted();
00378     return;
00379   }
00380 
00381   if(goal->refine_pose_time <= 0)
00382   {
00383     ROS_ERROR("Refine pose time must be positive.");
00384     gh.setRejected();
00385     return;
00386   }
00387 
00388 
00389   // RUN blort tracking mechanism
00390   // initialize tracker if it wasn't, otherwise reset it
00391   if(parent_->tracker != 0)
00392     delete parent_->tracker;
00393 
00394   parent_->tracker = new blort_ros::GLTracker(*lastCameraInfo, parent_->root_, true);
00395   parent_->recovery_client = parent_->nh_.serviceClient<blort_msgs::RecoveryCall>("/blort_detector/pose_service");
00396   parent_->recovery_answers.clear();
00397   parent_->tracker->enableAllTracking(false);
00398 
00399   // validate goal
00400   BOOST_FOREACH(const object_recognition_msgs::ObjectType& obj_type, goal->objects)
00401   {
00402     bool found = false;
00403     BOOST_FOREACH(const blort::ObjectEntry& obj, parent_->tracker->getObjects())
00404     {
00405       if(obj.name == obj_type.key)
00406       {
00407         found = true;
00408         break;
00409       }
00410     }
00411     if(!found)
00412     {
00413       ROS_ERROR_STREAM("Unknown object called: " << obj_type.key);
00414       gh.setAborted();
00415       return;
00416     }
00417   }
00418 
00419   std::stringstream ss;
00420   BOOST_FOREACH(const object_recognition_msgs::ObjectType& obj_type, goal->objects)
00421   {
00422     parent_->tracker->setTracked(obj_type.key, true);
00423     ss << obj_type.key << ",";
00424   }
00425   ROS_INFO_STREAM("TrackerNode::SingleShotMode::goalCb(): Received request to recognize '"
00426                   << ss.str() <<"' in " << goal->refine_pose_time << "seconds.");
00427 
00428 
00429   parent_->tracker->setPublishMode(blort_ros::TRACKER_PUBLISH_GOOD_AND_FAIR);
00430   parent_->tracker->setVisualizeObjPose(true);
00431   blort_msgs::SetCameraInfo camera_info;
00432   camera_info.request.CameraInfo = *lastCameraInfo;
00433   if(!detector_set_caminfo_service.call(camera_info))
00434     ROS_ERROR("blort_tracker failed to call blort_detector/set_camera_info service");
00435 
00436   std::map< std::string, std::vector<geometry_msgs::Pose> > results;
00437   double start_secs = ros::Time::now().toSec();
00438   while(ros::Time::now().toSec()-start_secs < goal->refine_pose_time)
00439   {
00440     // feedback
00441     feedback_.time_left = goal->refine_pose_time+start_secs-ros::Time::now().toSec();
00442     gh.publishFeedback(feedback_);
00443     ROS_INFO("Remaining time %f", feedback_.time_left);
00444 
00445     parent_->imageCb(lastImage, lastImage);
00446 
00447     BOOST_FOREACH(const blort::ObjectEntry& obj, parent_->tracker->getObjects())
00448     {
00449       bool found = false;
00450       BOOST_FOREACH(const object_recognition_msgs::ObjectType& obj_type, goal->objects)
00451       {
00452         found = found || (obj.name == obj_type.key);
00453       }
00454       if(found)
00455       {
00456         ROS_ERROR_STREAM(obj.name << " with confidence " << obj.edgeConf
00457                          << ", when threshold is " << conf_treshold_);
00458         // Check that the edge confidence is high enought BUT ALSO that the pose
00459         // has been updated. If not, it means that model confidence state is not
00460         // the required by the /blort_tracker/publish_mode
00461         if(obj.edgeConf > conf_treshold_ &&
00462            !(parent_->tracker->getDetections()[obj.name].position.x == 0 &&
00463              parent_->tracker->getDetections()[obj.name].position.y == 0 &&
00464              parent_->tracker->getDetections()[obj.name].position.z == 0) )
00465         {
00466           // instead of returning right away let's store the result
00467           // to see if the tracker can get better
00468           results[obj.name].push_back(parent_->tracker->getDetections()[obj.name]);
00469         }
00470         else
00471         {
00472           results[obj.name].clear();
00473         }
00474       }
00475     }
00476   }
00477   inServiceCall = false;
00478 
00479   // time is up, pose refinement is done
00480   BOOST_FOREACH(const object_recognition_msgs::ObjectType& obj, goal->objects)
00481   {
00482     if(!results[obj.key].empty())
00483     {
00484       object_recognition_msgs::RecognizedObject r_obj;
00485       //pose.header.frame_id = camera frame name
00486       r_obj.pose.header.frame_id = lastCameraInfo->header.frame_id;
00487       r_obj.pose.header.stamp = ros::Time::now(); // or take the stamp of the last image
00488       r_obj.type.key = obj.key;
00489       //convert results to a tf style transform and multiply them
00490       //to get the camera-to-target transformation
00491       r_obj.pose.pose.pose = blort_ros::blortPosesToRosPose(parent_->tracker->getCameraReferencePose(),
00492                                                             results[obj.key].back());
00493       //copy Z element of depth[X,Y]
00494       if(lastDepth.use_count() > 0)
00495       {
00496         r_obj.pose.pose.pose.position.z = getDistance(lastDepth,
00497                                                       r_obj.pose.pose.pose.position.x,
00498                                                       r_obj.pose.pose.pose.position.y,
00499                                                       r_obj.pose.pose.pose.position.z);
00500       }
00501       result_.recognized_objects.objects.push_back(r_obj);
00502       //NOTE: check the pose in vec3 location + mat3x3 rotation could be added here
00503       // if we have any previous knowledge of the given scene
00504       //            ROS_INFO_STREAM("PUBLISHED POSE:" << std::endl << resp.Pose.position << std::endl <<
00505       //                            pal_blort::quaternionTo3x3cvMat(resp.Pose.orientation) << std::endl);
00506     }
00507   }
00508   gh.setSucceeded(result_);
00509 }
00510 
00511 double TrackerNode::SingleShotMode::getDistance(const sensor_msgs::ImageConstPtr& img, double x, double y, double z)
00512 {
00513   double u = (lastCameraInfo->P[0]*x)/z + lastCameraInfo->P[2];
00514   double v = (lastCameraInfo->P[5]*y)/z + lastCameraInfo->P[6];
00515 
00516   cv_bridge::CvImagePtr depth_ptr;
00517   try
00518   {
00519     depth_ptr = cv_bridge::toCvCopy(img, sensor_msgs::image_encodings::TYPE_32FC1);
00520     ROS_WARN_STREAM("[x,y,z] : " << "[" << x << "," << y << "," << z << "]   --- " <<
00521                     "[u,v] : [" << u << "," << v << "] in an image of [" << depth_ptr->image.rows << "," << depth_ptr->image.cols << "]");
00522   }
00523   catch (cv_bridge::Exception& e)
00524   {
00525     ROS_ERROR("cv_bridge exception: %s", e.what());
00526     return 0.0;
00527   }
00528 
00529   // compute the median of the 3x3 neighborhood of the point
00530   float arr[] = {depth_ptr->image.at<float>(round(v)-1, round(u)-1), depth_ptr->image.at<float>(round(v)-1, round(u)),
00531                  depth_ptr->image.at<float>(round(v)-1, round(u)+1), depth_ptr->image.at<float>(round(v), round(u)-1),
00532                  depth_ptr->image.at<float>(round(v), round(u)), depth_ptr->image.at<float>(round(v), round(u)+1),
00533                  depth_ptr->image.at<float>(round(v)+1, round(u)-1), depth_ptr->image.at<float>(round(v)+1, round(u)),
00534                  depth_ptr->image.at<float>(round(v)+1, round(u)+1)};
00535   std::nth_element(arr, arr+5, arr+9);
00536 
00537   // print neighbouring elements
00538   //  ROS_ERROR_STREAM(
00539   //        "-| " << depth_ptr->image.at<float>(round(v)-1, round(u)-1) << " | " << depth_ptr->image.at<float>(round(v)-1, round(u)) <<  " | " << depth_ptr->image.at<float>(round(v)-1, round(u)+1) <<  " |-" <<
00540   //        "-| " << depth_ptr->image.at<float>(round(v), round(u)-1) << " | " << depth_ptr->image.at<float>(round(v), round(u)) <<  " | " << depth_ptr->image.at<float>(round(v), round(u)+1) <<  " |-" <<
00541   //        "-| " << depth_ptr->image.at<float>(round(v)+1, round(u)-1) << " | " << depth_ptr->image.at<float>(round(v)+1, round(u)) <<  " | " << depth_ptr->image.at<float>(round(v)+1, round(u)+1) <<  " |-"
00542   //                  );
00543   ROS_WARN_STREAM("Median is " << arr[5]);
00544 
00545   return arr[5];
00546 }
00547 
00548 
00549 int main(int argc, char *argv[] )
00550 {
00551   if(argc < 2)
00552   {
00553     ROS_ERROR("The first command line argument should be the package root!");
00554     return -1;
00555   }
00556   ros::init(argc, argv, "blort_tracker");
00557   //FIXME: hardcoded size, 1x1 is not good, renders the tracker unfunctional in runtime
00558   // size should be not smaller the image size, too big size is also wrong
00559   blort_ros::GLXHidingWindow window(656, 492, "Tracker"); // a window which should hide itself after start
00560   //blortGLWindow::GLWindow window(640  , 480, "Window"); // a normal opengl window
00561   TrackerNode node(argv[1]);
00562   ros::spin();
00563   return 0;
00564 }
00565 


blort_ros
Author(s): Bence Magyar
autogenerated on Wed Aug 26 2015 15:24:39