00001
00061 #ifdef __LINUX__
00062 #include "cob_people_detection/face_detector_node.h"
00063 #include "cob_vision_utils/GlobalDefines.h"
00064 #include "cob_people_detection/face_detection_message_helper.h"
00065 #else
00066 #endif
00067
00068
00069 #include <opencv2/opencv.hpp>
00070 #include <cv_bridge/cv_bridge.h>
00071 #include <sensor_msgs/image_encodings.h>
00072
00073
00074 #include <boost/shared_ptr.hpp>
00075
00076
00077 #include <cob_people_detection/timer.h>
00078
00079 using namespace ipa_PeopleDetector;
00080
00081 FaceDetectorNode::FaceDetectorNode(ros::NodeHandle nh) :
00082 node_handle_(nh)
00083 {
00084 data_directory_ = ros::package::getPath("cob_people_detection") + "/common/files/";
00085
00086
00087 double faces_increase_search_scale;
00088 int faces_drop_groups;
00089 int faces_min_search_scale_x;
00090 int faces_min_search_scale_y;
00091 bool reason_about_3dface_size;
00092 double face_size_max_m;
00093 double face_size_min_m;
00094 double max_face_z_m;
00095 bool debug;
00096 std::cout << "\n--------------------------\nFace Detector Parameters:\n--------------------------\n";
00097 node_handle_.param("data_directory", data_directory_, data_directory_);
00098 std::cout << "data_directory = " << data_directory_ << "\n";
00099 node_handle_.param("faces_increase_search_scale", faces_increase_search_scale, 1.1);
00100 std::cout << "faces_increase_search_scale = " << faces_increase_search_scale << "\n";
00101 node_handle_.param("faces_drop_groups", faces_drop_groups, 68);
00102 std::cout << "faces_drop_groups = " << faces_drop_groups << "\n";
00103 node_handle_.param("faces_min_search_scale_x", faces_min_search_scale_x, 20);
00104 std::cout << "faces_min_search_scale_x = " << faces_min_search_scale_x << "\n";
00105 node_handle_.param("faces_min_search_scale_y", faces_min_search_scale_y, 20);
00106 std::cout << "faces_min_search_scale_y = " << faces_min_search_scale_y << "\n";
00107 node_handle_.param("reason_about_3dface_size", reason_about_3dface_size, true);
00108 std::cout << "reason_about_3dface_size = " << reason_about_3dface_size << "\n";
00109 node_handle_.param("face_size_max_m", face_size_max_m, 0.35);
00110 std::cout << "face_size_max_m = " << face_size_max_m << "\n";
00111 node_handle_.param("face_size_min_m", face_size_min_m, 0.1);
00112 std::cout << "face_size_min_m = " << face_size_min_m << "\n";
00113 node_handle_.param("max_face_z_m", max_face_z_m, 8.0);
00114 std::cout << "max_face_z_m = " << max_face_z_m << "\n";
00115 node_handle_.param("debug", debug, false);
00116 std::cout << "debug = " << debug << "\n";
00117 node_handle_.param("display_timing", display_timing_, false);
00118 std::cout << "display_timing = " << display_timing_ << "\n";
00119
00120
00121 face_detector_.init(data_directory_, faces_increase_search_scale, faces_drop_groups, faces_min_search_scale_x, faces_min_search_scale_y, reason_about_3dface_size,
00122 face_size_max_m, face_size_min_m, max_face_z_m, debug);
00123
00124
00125 face_position_publisher_ = node_handle_.advertise<cob_perception_msgs::ColorDepthImageArray>("face_positions", 1);
00126 face_position_publisher_cartesian_ = node_handle_.advertise<cob_perception_msgs::DetectionArray>("face_detections_cartesian", 1);
00127
00128
00129 head_position_subscriber_ = nh.subscribe("head_positions", 1, &FaceDetectorNode::head_positions_callback, this);
00130
00131 std::cout << "FaceDetectorNode initialized." << std::endl;
00132 }
00133
00134 FaceDetectorNode::~FaceDetectorNode(void)
00135 {
00136 }
00137
00138
00139 void voidDeleter(const sensor_msgs::Image* const )
00140 {
00141 }
00142
00143 void FaceDetectorNode::head_positions_callback(const cob_perception_msgs::ColorDepthImageArray::ConstPtr& head_positions)
00144 {
00145
00146
00147
00148
00149
00150
00151 std::vector<cv::Mat> heads_color_images(head_positions->head_detections.size());
00152 std::vector<cv::Mat> heads_depth_images(head_positions->head_detections.size());
00153 std::vector<cv::Rect> head_bounding_boxes(head_positions->head_detections.size());
00154 cv_bridge::CvImageConstPtr cv_cptr;
00155 cv_bridge::CvImagePtr cv_ptr(new cv_bridge::CvImage);
00156 for (unsigned int i = 0; i < head_positions->head_detections.size(); i++)
00157 {
00158
00159 sensor_msgs::ImageConstPtr msgPtr = boost::shared_ptr<sensor_msgs::Image const>(&(head_positions->head_detections[i].color_image), voidDeleter);
00160 try
00161 {
00162 cv_cptr = cv_bridge::toCvShare(msgPtr, sensor_msgs::image_encodings::RGB8);
00163 } catch (cv_bridge::Exception& e)
00164 {
00165 ROS_ERROR("cv_bridge exception: %s", e.what());
00166 return;
00167 }
00168 heads_color_images[i] = cv_cptr->image.clone();
00169
00170
00171 msgPtr = boost::shared_ptr<const sensor_msgs::Image>(&(head_positions->head_detections[i].depth_image), voidDeleter);
00172 try
00173 {
00174 cv_cptr = cv_bridge::toCvShare(msgPtr, sensor_msgs::image_encodings::TYPE_32FC3);
00175 } catch (cv_bridge::Exception& e)
00176 {
00177 ROS_ERROR("cv_bridge exception: %s", e.what());
00178 return;
00179 }
00180 heads_depth_images[i] = cv_cptr->image;
00181
00182
00183 const cob_perception_msgs::Rect& source_rect = head_positions->head_detections[i].head_detection;
00184 cv::Rect rect(source_rect.x, source_rect.y, source_rect.width, source_rect.height);
00185 head_bounding_boxes[i] = rect;
00186 }
00187 std::vector < std::vector<cv::Rect> > face_bounding_boxes;
00188 face_detector_.detectColorFaces(heads_color_images, heads_depth_images, face_bounding_boxes);
00189
00190
00191
00192 if (face_position_publisher_.getNumSubscribers() > 0)
00193 {
00194 cob_perception_msgs::ColorDepthImageArray image_array;
00195 image_array = *head_positions;
00196 for (unsigned int i = 0; i < face_bounding_boxes.size(); i++)
00197 {
00198 for (unsigned int j = 0; j < face_bounding_boxes[i].size(); j++)
00199 {
00200
00201 cob_perception_msgs::Rect rect;
00202 rect.x = face_bounding_boxes[i][j].x;
00203 rect.y = face_bounding_boxes[i][j].y;
00204 rect.width = face_bounding_boxes[i][j].width;
00205 rect.height = face_bounding_boxes[i][j].height;
00206 image_array.head_detections[i].face_detections.push_back(rect);
00207 }
00208
00209 cv_ptr->encoding = sensor_msgs::image_encodings::RGB8;
00210 cv_ptr->image = heads_color_images[i];
00211 cv_ptr->toImageMsg(image_array.head_detections[i].color_image);
00212 image_array.head_detections[i].color_image.header = head_positions->head_detections[i].color_image.header;
00213 }
00214 face_position_publisher_.publish(image_array);
00215 }
00216
00217
00218 if (face_position_publisher_cartesian_.getNumSubscribers() > 0)
00219 {
00220 FaceDetectionMessageHelper face_detection_message_helper;
00221 cob_perception_msgs::DetectionArray detection_msg;
00222 face_detection_message_helper.prepareCartesionDetectionMessage(detection_msg, head_positions->header, heads_depth_images, head_bounding_boxes, face_bounding_boxes, 0);
00223 face_position_publisher_cartesian_.publish(detection_msg);
00224 }
00225
00226 if (display_timing_ == true)
00227 ROS_INFO("%d FaceDetection: Time stamp of pointcloud message: %f. Delay: %f.", head_positions->header.seq, head_positions->header.stamp.toSec(),
00228 ros::Time::now().toSec() - head_positions->header.stamp.toSec());
00229
00230 }
00231
00232
00233
00234 int main(int argc, char** argv)
00235 {
00236
00237 ros::init(argc, argv, "face_detector");
00238
00239
00240 ros::NodeHandle nh("~");
00241
00242
00243 FaceDetectorNode face_detector_node(nh);
00244
00245
00246
00247
00248
00249
00250 ros::spin();
00251
00252 return 0;
00253 }