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
00034
00035
00036
00037
00038
00039
00040 #include <stdio.h>
00041 #include <iostream>
00042 #include <vector>
00043 #include <fstream>
00044
00045 #include <ros/ros.h>
00046 #include <ros/console.h>
00047 #include <boost/filesystem.hpp>
00048 #include <boost/thread/mutex.hpp>
00049
00050 #include <people_msgs/PositionMeasurement.h>
00051 #include <people_msgs/PositionMeasurementArray.h>
00052 #include <message_filters/subscriber.h>
00053 #include <message_filters/time_synchronizer.h>
00054 #include <message_filters/sync_policies/exact_time.h>
00055 #include <message_filters/sync_policies/approximate_time.h>
00056 #include <image_transport/subscriber_filter.h>
00057 #include "sensor_msgs/CameraInfo.h"
00058 #include "sensor_msgs/Image.h"
00059 #include "stereo_msgs/DisparityImage.h"
00060 #include "sensor_msgs/image_encodings.h"
00061 #include "cv_bridge/cv_bridge.h"
00062 #include "tf/transform_listener.h"
00063 #include "sensor_msgs/PointCloud.h"
00064 #include "geometry_msgs/Point32.h"
00065
00066 #include "opencv/cxcore.hpp"
00067 #include "opencv/cv.hpp"
00068 #include "opencv/highgui.h"
00069
00070 #include "face_detector/faces.h"
00071
00072 #include "image_geometry/stereo_camera_model.h"
00073
00074 #include <actionlib/server/simple_action_server.h>
00075 #include <face_detector/FaceDetectorAction.h>
00076
00077 using namespace std;
00078
00079 namespace people
00080 {
00081
00084 class FaceDetector
00085 {
00086 public:
00087
00088 const double BIGDIST_M;
00089
00090
00091 ros::NodeHandle nh_;
00092
00093 boost::mutex connect_mutex_;
00094 bool use_rgbd_;
00095
00096
00097 string image_image_;
00098
00099 string stereo_namespace_;
00100 string left_topic_;
00101 string disparity_topic_;
00102 string left_camera_info_topic_;
00103 string right_camera_info_topic_;
00104
00105 string camera_;
00106 string camera_topic_;
00107 string depth_image_;
00108 string depth_topic_;
00109 string camera_info_topic_;
00110 string depth_info_topic_;
00111 string rgb_ns_;
00112 string depth_ns_;
00113
00114
00115 image_transport::ImageTransport it_;
00116 image_transport::SubscriberFilter image_sub_;
00117 image_transport::SubscriberFilter depth_image_sub_;
00118 message_filters::Subscriber<stereo_msgs::DisparityImage> disp_image_sub_;
00119 message_filters::Subscriber<sensor_msgs::CameraInfo> c1_info_sub_;
00120 message_filters::Subscriber<sensor_msgs::CameraInfo> c2_info_sub_;
00122
00123 typedef message_filters::sync_policies::ExactTime<sensor_msgs::Image, stereo_msgs::DisparityImage, sensor_msgs::CameraInfo, sensor_msgs::CameraInfo> ExactDispPolicy;
00124 typedef message_filters::sync_policies::ApproximateTime<sensor_msgs::Image, stereo_msgs::DisparityImage, sensor_msgs::CameraInfo, sensor_msgs::CameraInfo> ApproximateDispPolicy;
00125 typedef message_filters::Synchronizer<ExactDispPolicy> ExactDispSync;
00126 typedef message_filters::Synchronizer<ApproximateDispPolicy> ApproximateDispSync;
00127 boost::shared_ptr<ExactDispSync> exact_disp_sync_;
00128 boost::shared_ptr<ApproximateDispSync> approximate_disp_sync_;
00129
00130
00131 typedef message_filters::sync_policies::ExactTime<sensor_msgs::Image, sensor_msgs::Image, sensor_msgs::CameraInfo, sensor_msgs::CameraInfo> ExactDepthPolicy;
00132 typedef message_filters::sync_policies::ApproximateTime<sensor_msgs::Image, sensor_msgs::Image, sensor_msgs::CameraInfo, sensor_msgs::CameraInfo> ApproximateDepthPolicy;
00133 typedef message_filters::Synchronizer<ExactDepthPolicy> ExactDepthSync;
00134 typedef message_filters::Synchronizer<ApproximateDepthPolicy> ApproximateDepthSync;
00135 boost::shared_ptr<ExactDepthSync> exact_depth_sync_;
00136 boost::shared_ptr<ApproximateDepthSync> approximate_depth_sync_;
00137
00138
00139 actionlib::SimpleActionServer<face_detector::FaceDetectorAction> as_;
00140 face_detector::FaceDetectorFeedback feedback_;
00141 face_detector::FaceDetectorResult result_;
00142
00143
00144
00145 ros::Subscriber pos_sub_;
00146 bool external_init_;
00147
00148
00149
00150
00151
00152
00153 ros::Publisher cloud_pub_;
00154 ros::Publisher pos_array_pub_;
00155
00156
00157 bool do_display_;
00158 bool do_display_face_id_;
00159 cv::Mat cv_image_out_;
00161
00162 bool use_depth_;
00163 image_geometry::StereoCameraModel cam_model_;
00165
00166 Faces *faces_;
00167 string name_;
00168 string haar_filename_;
00169 double reliability_;
00171 struct RestampedPositionMeasurement
00172 {
00173 ros::Time restamp;
00174 people_msgs::PositionMeasurement pos;
00175 double dist;
00176 };
00177 map<string, RestampedPositionMeasurement> pos_list_;
00179 int max_id_;
00180
00181 bool quit_;
00182
00183 tf::TransformListener tf_;
00184
00185 std::string fixed_frame_;
00186
00187 boost::mutex cv_mutex_, pos_mutex_, limage_mutex_, dimage_mutex_;
00188
00189 bool do_continuous_;
00191 bool do_publish_unknown_;
00193 FaceDetector(std::string name) :
00194 BIGDIST_M(1000000.0),
00195 it_(nh_),
00196 as_(nh_, name, false),
00197 faces_(0),
00198 max_id_(-1),
00199 quit_(false)
00200 {
00201 ROS_INFO_STREAM_NAMED("face_detector", "Constructing FaceDetector.");
00202
00203
00204 as_.registerGoalCallback(boost::bind(&FaceDetector::goalCB, this));
00205 as_.registerPreemptCallback(boost::bind(&FaceDetector::preemptCB, this));
00206 as_.start();
00207
00208 faces_ = new Faces();
00209 double face_size_min_m, face_size_max_m, max_face_z_m, face_sep_dist_m;
00210 int queue_size;
00211 bool approx;
00212
00213
00214 ros::NodeHandle local_nh("~");
00215 local_nh.param("classifier_name", name_, std::string(""));
00216 local_nh.param("classifier_filename", haar_filename_, std::string(""));
00217 local_nh.param("classifier_reliability", reliability_, 0.0);
00218 local_nh.param("do_display", do_display_, false);
00219 local_nh.param("do_display_face_id", do_display_face_id_, false);
00220 local_nh.param("do_continuous", do_continuous_, true);
00221 local_nh.param("do_publish_faces_of_unknown_size", do_publish_unknown_, false);
00222 local_nh.param("use_depth", use_depth_, true);
00223 local_nh.param("use_external_init", external_init_, false);
00224 local_nh.param("face_size_min_m", face_size_min_m, FACE_SIZE_MIN_M);
00225 local_nh.param("face_size_max_m", face_size_max_m, FACE_SIZE_MAX_M);
00226 local_nh.param("max_face_z_m", max_face_z_m, MAX_FACE_Z_M);
00227 local_nh.param("face_separation_dist_m", face_sep_dist_m, FACE_SEP_DIST_M);
00228 local_nh.param("use_rgbd", use_rgbd_, false);
00229 local_nh.param("queue_size", queue_size, 5);
00230 local_nh.param("approximate_sync", approx, false);
00231
00232 if (do_display_)
00233 {
00234
00235 cv::namedWindow("Face detector: Face Detection", CV_WINDOW_AUTOSIZE);
00236 }
00237
00238
00239 if (use_rgbd_)
00240 {
00241
00242 faces_->initFaceDetectionDepth(1, haar_filename_, face_size_min_m, face_size_max_m, max_face_z_m, face_sep_dist_m);
00243
00244 camera_ = nh_.resolveName("camera");
00245 image_image_ = nh_.resolveName("image_topic");
00246 depth_image_ = nh_.resolveName("depth_topic");
00247 rgb_ns_ = nh_.resolveName("rgb_ns");
00248 depth_ns_ = nh_.resolveName("depth_ns");
00249 camera_topic_ = ros::names::clean(camera_ + "/" + rgb_ns_ + "/" + image_image_);
00250 depth_topic_ = ros::names::clean(camera_ + "/" + depth_ns_ + "/" + depth_image_);
00251 camera_info_topic_ = ros::names::clean(camera_ + "/" + rgb_ns_ + "/camera_info");
00252 depth_info_topic_ = ros::names::clean(camera_ + "/" + depth_ns_ + "/camera_info");
00253
00254 ROS_DEBUG("camera_topic_: %s", camera_topic_.c_str());
00255 ROS_DEBUG("depth_topic_: %s", depth_topic_.c_str());
00256 ROS_DEBUG("camera_info_topic_: %s", camera_info_topic_.c_str());
00257 ROS_DEBUG("depth_info_topic_: %s", depth_info_topic_.c_str());
00258
00259 local_nh.param("fixed_frame", fixed_frame_, std::string("camera_rgb_optical_frame"));
00260
00261 if (approx)
00262 {
00263 approximate_depth_sync_.reset(new ApproximateDepthSync(ApproximateDepthPolicy(queue_size),
00264 image_sub_, depth_image_sub_, c1_info_sub_, c2_info_sub_));
00265 approximate_depth_sync_->registerCallback(boost::bind(&FaceDetector::imageCBAllDepth,
00266 this, _1, _2, _3, _4));
00267 }
00268 else
00269 {
00270 exact_depth_sync_.reset(new ExactDepthSync(ExactDepthPolicy(queue_size),
00271 image_sub_, depth_image_sub_, c1_info_sub_, c2_info_sub_));
00272 exact_depth_sync_->registerCallback(boost::bind(&FaceDetector::imageCBAllDepth,
00273 this, _1, _2, _3, _4));
00274 }
00275
00276 }
00277 else
00278 {
00279 faces_->initFaceDetectionDisparity(1, haar_filename_, face_size_min_m, face_size_max_m, max_face_z_m, face_sep_dist_m);
00280
00281 stereo_namespace_ = nh_.resolveName("camera");
00282 image_image_ = nh_.resolveName("image_topic");
00283 left_topic_ = ros::names::clean(stereo_namespace_ + "/left/" + image_image_);
00284 disparity_topic_ = ros::names::clean(stereo_namespace_ + "/disparity");
00285 left_camera_info_topic_ = ros::names::clean(stereo_namespace_ + "/left/camera_info");
00286 right_camera_info_topic_ = ros::names::clean(stereo_namespace_ + "/right/camera_info");
00287
00288 local_nh.param("fixed_frame", fixed_frame_, stereo_namespace_.append("_optical_frame"));
00289
00290 if (approx)
00291 {
00292 approximate_disp_sync_.reset(new ApproximateDispSync(ApproximateDispPolicy(queue_size),
00293 image_sub_, disp_image_sub_, c1_info_sub_, c2_info_sub_));
00294 approximate_disp_sync_->registerCallback(boost::bind(&FaceDetector::imageCBAllDisp,
00295 this, _1, _2, _3, _4));
00296 }
00297 else
00298 {
00299 exact_disp_sync_.reset(new ExactDispSync(ExactDispPolicy(queue_size),
00300 image_sub_, disp_image_sub_, c1_info_sub_, c2_info_sub_));
00301 exact_disp_sync_->registerCallback(boost::bind(&FaceDetector::imageCBAllDisp,
00302 this, _1, _2, _3, _4));
00303 }
00304 }
00305
00306
00307 ros::SubscriberStatusCallback pos_pub_connect_cb = boost::bind(&FaceDetector::connectCb, this);
00308 ros::SubscriberStatusCallback cloud_pub_connect_cb = boost::bind(&FaceDetector::connectCb, this);
00309 if (do_continuous_)
00310 ROS_INFO_STREAM_NAMED("face_detector", "You must subscribe to one of FaceDetector's outbound topics or else it will not publish anything.");
00311
00312 {
00313 boost::mutex::scoped_lock lock(connect_mutex_);
00314
00315
00316 pos_array_pub_ = nh_.advertise<people_msgs::PositionMeasurementArray>("face_detector/people_tracker_measurements_array", 1, pos_pub_connect_cb, pos_pub_connect_cb);
00317
00318 cloud_pub_ = nh_.advertise<sensor_msgs::PointCloud>("face_detector/faces_cloud", 0, cloud_pub_connect_cb, cloud_pub_connect_cb);
00319 }
00320
00321
00322
00323 if (!do_continuous_) connectCb();
00324
00325 ros::MultiThreadedSpinner s(2);
00326 ros::spin(s);
00327
00328 }
00329
00330 ~FaceDetector()
00331 {
00332
00333 cv_image_out_.release();
00334
00335 if (do_display_)
00336 {
00337 cv::destroyWindow("Face detector: Face Detection");
00338 }
00339
00340 if (faces_)
00341 {
00342 delete faces_;
00343 faces_ = 0;
00344 }
00345 }
00346
00347
00348 void connectCb()
00349 {
00350 boost::mutex::scoped_lock lock(connect_mutex_);
00351 if (use_rgbd_)
00352 {
00353 if (do_continuous_ && cloud_pub_.getNumSubscribers() == 0 && pos_array_pub_.getNumSubscribers() == 0)
00354 {
00355 ROS_INFO_STREAM_NAMED("face_detector", "You have unsubscribed to FaceDetector's outbound topics, so it will no longer publish anything.");
00356 image_sub_.unsubscribe();
00357 depth_image_sub_.unsubscribe();
00358 c1_info_sub_.unsubscribe();
00359 c2_info_sub_.unsubscribe();
00360 pos_sub_.shutdown();
00361 }
00362 else if (!do_continuous_ || !image_sub_.getSubscriber())
00363 {
00364 image_sub_.subscribe(it_, camera_topic_, 3);
00365 depth_image_sub_.subscribe(it_, depth_topic_, 3);
00366 c1_info_sub_.subscribe(nh_, camera_info_topic_, 3);
00367 c2_info_sub_.subscribe(nh_, depth_info_topic_, 3);
00368
00369
00370
00371
00372
00373 }
00374 }
00375 else
00376 {
00377 if (do_continuous_ && cloud_pub_.getNumSubscribers() == 0 && pos_array_pub_.getNumSubscribers() == 0)
00378 {
00379 ROS_INFO_STREAM_NAMED("face_detector", "You have unsubscribed to FaceDetector's outbound topics, so it will no longer publish anything.");
00380 image_sub_.unsubscribe();
00381 disp_image_sub_.unsubscribe();
00382 c1_info_sub_.unsubscribe();
00383 c2_info_sub_.unsubscribe();
00384 pos_sub_.shutdown();
00385 }
00386 else if (!do_continuous_ || !image_sub_.getSubscriber())
00387 {
00388 image_sub_.subscribe(it_, left_topic_, 3);
00389 disp_image_sub_.subscribe(nh_, disparity_topic_, 3);
00390 c1_info_sub_.subscribe(nh_, left_camera_info_topic_, 3);
00391 c2_info_sub_.subscribe(nh_, right_camera_info_topic_, 3);
00392
00393
00394
00395
00396
00397 }
00398 }
00399 }
00400
00401
00402 void goalCB()
00403 {
00404 as_.acceptNewGoal();
00405 }
00406
00407 void preemptCB()
00408 {
00409 as_.setPreempted();
00410 }
00411
00412
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443 struct NullDeleter
00444 {
00445 void operator()(void const *) const {}
00446 };
00447
00456 void imageCBAllDepth(const sensor_msgs::Image::ConstPtr &image, const sensor_msgs::Image::ConstPtr& depth_image, const sensor_msgs::CameraInfo::ConstPtr& c1_info, const sensor_msgs::CameraInfo::ConstPtr& c2_info)
00457 {
00458
00459
00460 if (!do_continuous_ && !as_.isActive())
00461 return;
00462
00463
00464 result_.face_positions.clear();
00465
00466 if (do_display_)
00467 {
00468 cv_mutex_.lock();
00469 }
00470
00471
00472 cv_bridge::CvImageConstPtr cv_image_ptr = cv_bridge::toCvShare(image, "bgr8");
00473 cv_bridge::CvImageConstPtr cv_depth_ptr = cv_bridge::toCvShare(depth_image);
00474 cv::Mat depth_32fc1 = cv_depth_ptr->image;
00475 if (depth_image->encoding != "32FC1")
00476 {
00477 cv_depth_ptr->image.convertTo(depth_32fc1, CV_32FC1, 0.001);
00478 }
00479
00480
00481
00482 cam_model_.fromCameraInfo(c1_info, c2_info);
00483
00484
00485 if (do_display_)
00486 {
00487 cv_image_out_ = (cv_image_ptr->image).clone();
00488 }
00489
00490 struct timeval timeofday;
00491 gettimeofday(&timeofday, NULL);
00492 ros::Time starttdetect = ros::Time().fromNSec(1e9 * timeofday.tv_sec + 1e3 * timeofday.tv_usec);
00493
00494 vector<Box2D3D> faces_vector = faces_->detectAllFacesDepth(cv_image_ptr->image, 1.0, depth_32fc1, &cam_model_);
00495 gettimeofday(&timeofday, NULL);
00496 ros::Time endtdetect = ros::Time().fromNSec(1e9 * timeofday.tv_sec + 1e3 * timeofday.tv_usec);
00497 ros::Duration diffdetect = endtdetect - starttdetect;
00498 ROS_INFO_STREAM_NAMED("face_detector", "Detection duration = " << diffdetect.toSec() << "sec");
00499
00500 matchAndDisplay(faces_vector, image->header);
00501 }
00502
00511 void imageCBAllDisp(const sensor_msgs::Image::ConstPtr &image, const stereo_msgs::DisparityImage::ConstPtr& disp_image, const sensor_msgs::CameraInfo::ConstPtr& c1_info, const sensor_msgs::CameraInfo::ConstPtr& c2_info)
00512 {
00513
00514
00515 if (!do_continuous_ && !as_.isActive())
00516 return;
00517
00518
00519 result_.face_positions.clear();
00520
00521 if (do_display_)
00522 {
00523 cv_mutex_.lock();
00524 }
00525
00526
00527
00528 cv_bridge::CvImageConstPtr cv_image_ptr = cv_bridge::toCvShare(image, sensor_msgs::image_encodings::BGR8);
00529 cv_bridge::CvImageConstPtr cv_disp_ptr = cv_bridge::toCvShare(disp_image->image, disp_image);
00530 cam_model_.fromCameraInfo(c1_info, c2_info);
00531
00532
00533 if (do_display_)
00534 {
00535 cv_image_out_ = (cv_image_ptr->image).clone();
00536 }
00537
00538 struct timeval timeofday;
00539 gettimeofday(&timeofday, NULL);
00540 ros::Time starttdetect = ros::Time().fromNSec(1e9 * timeofday.tv_sec + 1e3 * timeofday.tv_usec);
00541
00542 vector<Box2D3D> faces_vector = faces_->detectAllFacesDisparity(cv_image_ptr->image, 1.0, cv_disp_ptr->image, &cam_model_);
00543 gettimeofday(&timeofday, NULL);
00544 ros::Time endtdetect = ros::Time().fromNSec(1e9 * timeofday.tv_sec + 1e3 * timeofday.tv_usec);
00545 ros::Duration diffdetect = endtdetect - starttdetect;
00546 ROS_INFO_STREAM_NAMED("face_detector", "Detection duration = " << diffdetect.toSec() << "sec");
00547
00548 matchAndDisplay(faces_vector, image->header);
00549 }
00550
00551
00552 private:
00553
00554 void matchAndDisplay(vector<Box2D3D> faces_vector, std_msgs::Header header)
00555 {
00556 bool found_faces = false;
00557
00558 int ngood = 0;
00559 sensor_msgs::PointCloud cloud;
00560 cloud.header.stamp = header.stamp;
00561 cloud.header.frame_id = header.frame_id;
00562
00563 if (faces_vector.size() > 0)
00564 {
00565
00566
00567
00568 map<string, RestampedPositionMeasurement>::iterator it;
00569 it = pos_list_.begin();
00570 while (it != pos_list_.end())
00571 {
00572 if ((header.stamp - (*it).second.restamp) > ros::Duration().fromSec(5.0))
00573 {
00574
00575 pos_list_.erase(it++);
00576 }
00577 else
00578 {
00579
00580 tf::Point pt;
00581 tf::pointMsgToTF((*it).second.pos.pos, pt);
00582 tf::Stamped<tf::Point> loc(pt, (*it).second.pos.header.stamp, (*it).second.pos.header.frame_id);
00583 try
00584 {
00585 tf_.transformPoint(header.frame_id, header.stamp, loc, fixed_frame_, loc);
00586 (*it).second.pos.header.stamp = header.stamp;
00587 (*it).second.pos.pos.x = loc[0];
00588 (*it).second.pos.pos.y = loc[1];
00589 (*it).second.pos.pos.z = loc[2];
00590 }
00591 catch (tf::TransformException& ex)
00592 {
00593 }
00594 it++;
00595 }
00596 }
00597
00598
00599
00600 Box2D3D *one_face;
00601 people_msgs::PositionMeasurement pos;
00602 people_msgs::PositionMeasurementArray pos_array;
00603
00604 for (uint iface = 0; iface < faces_vector.size(); iface++)
00605 {
00606 one_face = &faces_vector[iface];
00607
00608 if (one_face->status == "good" || (one_face->status == "unknown" && do_publish_unknown_))
00609 {
00610
00611 std::string id = "";
00612
00613
00614 pos.header.stamp = header.stamp;
00615 pos.name = name_;
00616 pos.pos.x = one_face->center3d.x;
00617 pos.pos.y = one_face->center3d.y;
00618 pos.pos.z = one_face->center3d.z;
00619 pos.header.frame_id = header.frame_id;
00620 pos.reliability = reliability_;
00621 pos.initialization = 1;
00622 pos.covariance[0] = 0.04;
00623 pos.covariance[1] = 0.0;
00624 pos.covariance[2] = 0.0;
00625 pos.covariance[3] = 0.0;
00626 pos.covariance[4] = 0.04;
00627 pos.covariance[5] = 0.0;
00628 pos.covariance[6] = 0.0;
00629 pos.covariance[7] = 0.0;
00630 pos.covariance[8] = 0.04;
00631
00632
00633
00634
00635 double dist, mindist = BIGDIST_M;
00636 map<string, RestampedPositionMeasurement>::iterator close_it = pos_list_.end();
00637 for (it = pos_list_.begin(); it != pos_list_.end(); it++)
00638 {
00639 dist = pow((*it).second.pos.pos.x - pos.pos.x, 2.0) + pow((*it).second.pos.pos.y - pos.pos.y, 2.0) + pow((*it).second.pos.pos.z - pos.pos.z, 2.0);
00640 if (dist <= faces_->face_sep_dist_m_ && dist < mindist)
00641 {
00642 mindist = dist;
00643 close_it = it;
00644 }
00645 }
00646 if (close_it != pos_list_.end())
00647 {
00648 pos.object_id = (*close_it).second.pos.object_id;
00649 if (mindist < (*close_it).second.dist)
00650 {
00651 (*close_it).second.restamp = header.stamp;
00652 (*close_it).second.dist = mindist;
00653 (*close_it).second.pos = pos;
00654 }
00655 ROS_INFO_STREAM_NAMED("face_detector", "Found face to match with id " << pos.object_id);
00656 }
00657 else
00658 {
00659 max_id_++;
00660 pos.object_id = static_cast<ostringstream*>(&(ostringstream() << max_id_))->str();
00661 ROS_INFO_STREAM_NAMED("face_detector", "Didn't find face to match, starting new ID " << pos.object_id);
00662 }
00663 result_.face_positions.push_back(pos);
00664 found_faces = true;
00665
00666 }
00667
00668 }
00669 pos_array.header.stamp = header.stamp;
00670 pos_array.header.frame_id = header.frame_id;
00671 pos_array.people = result_.face_positions;
00672 if (pos_array.people.size() > 0)
00673 {
00674 pos_array_pub_.publish(pos_array);
00675
00676
00677 map<string, RestampedPositionMeasurement>::iterator it;
00678 for (uint ipa = 0; ipa < pos_array.people.size(); ipa++)
00679 {
00680 it = pos_list_.find(pos_array.people[ipa].object_id);
00681 RestampedPositionMeasurement rpm;
00682 rpm.pos = pos_array.people[ipa];
00683 rpm.restamp = pos_array.people[ipa].header.stamp;
00684 rpm.dist = BIGDIST_M;
00685 if (it == pos_list_.end())
00686 {
00687 pos_list_.insert(pair<string, RestampedPositionMeasurement>(pos_array.people[ipa].object_id, rpm));
00688 }
00689 else if ((pos_array.people[ipa].header.stamp - (*it).second.pos.header.stamp) > ros::Duration().fromSec(-1.0))
00690 {
00691 (*it).second = rpm;
00692 }
00693 }
00694
00695
00696
00697 for (it = pos_list_.begin(); it != pos_list_.end(); it++)
00698 {
00699 (*it).second.dist = BIGDIST_M;
00700 }
00701
00702 }
00703
00704
00705
00706
00707
00708
00709
00710
00711 cloud.channels.resize(1);
00712 cloud.channels[0].name = "intensity";
00713
00714 for (uint iface = 0; iface < faces_vector.size(); iface++)
00715 {
00716 one_face = &faces_vector[iface];
00717
00718
00719 if (one_face->status == "good")
00720 {
00721
00722 geometry_msgs::Point32 p;
00723 p.x = one_face->center3d.x;
00724 p.y = one_face->center3d.y;
00725 p.z = one_face->center3d.z;
00726 cloud.points.push_back(p);
00727 cloud.channels[0].values.push_back(1.0f);
00728
00729 ngood ++;
00730 }
00731 }
00732
00733 cloud_pub_.publish(cloud);
00734
00735
00736 }
00737
00738
00739
00740 if (do_display_)
00741 {
00742 displayFacesOnImage(faces_vector);
00743 cv_mutex_.unlock();
00744 }
00745
00746
00747
00748
00749 ROS_INFO_STREAM_NAMED("face_detector", "Number of faces found: " << faces_vector.size() << ", number with good depth and size: " << ngood);
00750
00751
00752 if (!do_continuous_ && found_faces)
00753 {
00754 as_.setSucceeded(result_);
00755 }
00756 }
00757
00758
00759 void displayFacesOnImage(vector<Box2D3D> faces_vector)
00760 {
00761
00762 Box2D3D *one_face;
00763
00764 for (uint iface = 0; iface < faces_vector.size(); iface++)
00765 {
00766 one_face = &faces_vector[iface];
00767
00768 if (do_display_)
00769 {
00770 cv::Scalar color;
00771 if (one_face->status == "good")
00772 {
00773 color = cv::Scalar(0, 255, 0);
00774 }
00775 else if (one_face->status == "unknown")
00776 {
00777 color = cv::Scalar(255, 0, 0);
00778 }
00779 else
00780 {
00781 color = cv::Scalar(0, 0, 255);
00782 }
00783
00784 cv::rectangle(cv_image_out_,
00785 cv::Point(one_face->box2d.x, one_face->box2d.y),
00786 cv::Point(one_face->box2d.x + one_face->box2d.width, one_face->box2d.y + one_face->box2d.height), color, 4);
00787
00788 if (do_display_face_id_) {
00789
00790 char id_str[16];
00791 sprintf(id_str, "Id: %d", one_face->id);
00792 cv::putText(cv_image_out_, id_str, cv::Point(one_face->box2d.x, one_face->box2d.y- 6), cv::FONT_HERSHEY_PLAIN, 1, color);
00793
00794 }
00795
00796 }
00797 }
00798
00799 cv::imshow("Face detector: Face Detection", cv_image_out_);
00800 cv::waitKey(2);
00801
00802 }
00803
00804
00805 };
00806
00807 };
00808
00809
00810 int main(int argc, char **argv)
00811 {
00812 ros::init(argc, argv, "face_detector");
00813
00814 people::FaceDetector fd(ros::this_node::getName());
00815
00816 return 0;
00817 }