00001
00060 #include <cob_people_detection/face_capture_node.h>
00061
00062 using namespace ipa_PeopleDetector;
00063
00064
00065 void voidDeleter(const sensor_msgs::Image* const) {}
00066
00067 FaceCaptureNode::FaceCaptureNode(ros::NodeHandle nh)
00068 : node_handle_(nh)
00069 {
00070 it_ = 0;
00071 sync_input_2_ = 0;
00072 capture_image_ = false;
00073 finish_image_capture_ = false;
00074 face_images_.clear();
00075 face_depthmaps_.clear();
00076
00077
00078
00079 bool debug;
00080 bool use_depth;
00081
00082 bool norm_illumination;
00083 bool norm_align;
00084 bool norm_extreme_illumination;
00085 int norm_size;
00086
00087 std::cout << "\n---------------------------\nFace Capture Node Parameters:\n---------------------------\n";
00088 if(!node_handle_.getParam("/cob_people_detection/data_storage_directory", data_directory_)) std::cout<<"PARAM NOT AVAILABLE"<<std::endl;
00089 std::cout << "data_directory = " << data_directory_ << "\n";
00090 node_handle_.param("norm_size", norm_size, 100);
00091 std::cout << "norm_size = " << norm_size << "\n";
00092 node_handle_.param("norm_illumination", norm_illumination, true);
00093 std::cout << "norm_illumination = " << norm_illumination << "\n";
00094 node_handle_.param("norm_align", norm_align, false);
00095 std::cout << "norm_align = " << norm_align << "\n";
00096 node_handle_.param("norm_extreme_illumination", norm_extreme_illumination, false);
00097 std::cout << "norm_extreme_illumination = " << norm_extreme_illumination << "\n";
00098 node_handle_.param("debug", debug, false);
00099 std::cout << "debug = " << debug << "\n";
00100 node_handle_.param("use_depth",use_depth,false);
00101 std::cout<< "use depth: "<<use_depth<<"\n";
00102
00103
00104
00105 face_recognizer_trainer_.initTraining(data_directory_, norm_size,norm_illumination,norm_align,norm_extreme_illumination, debug, face_images_, face_depthmaps_, use_depth);
00106
00107
00108 it_ = new image_transport::ImageTransport(node_handle_);
00109
00110
00111
00112
00113
00114
00115
00116 add_data_server_ = new AddDataServer(node_handle_, "add_data_server", boost::bind(&FaceCaptureNode::addDataServerCallback, this, _1), false);
00117 add_data_server_->start();
00118 update_data_server_ = new UpdateDataServer(node_handle_, "update_data_server", boost::bind(&FaceCaptureNode::updateDataServerCallback, this, _1), false);
00119 update_data_server_->start();
00120 delete_data_server_ = new DeleteDataServer(node_handle_, "delete_data_server", boost::bind(&FaceCaptureNode::deleteDataServerCallback, this, _1), false);
00121 delete_data_server_->start();
00122
00123
00124
00125
00126
00127 std::cout << "FaceCaptureNode initialized. " << face_images_.size() << " color images and " << face_depthmaps_.size() << " depth images for training loaded.\n" << std::endl;
00128 }
00129
00130 FaceCaptureNode::~FaceCaptureNode()
00131 {
00132 if (it_ != 0) delete it_;
00133 if (sync_input_2_ != 0) delete sync_input_2_;
00134 if (add_data_server_ != 0) delete add_data_server_;
00135 if (update_data_server_ != 0) delete update_data_server_;
00136 if (delete_data_server_ != 0) delete delete_data_server_;
00137 }
00138
00139 void FaceCaptureNode::addDataServerCallback(const cob_people_detection::addDataGoalConstPtr& goal)
00140 {
00141
00142 boost::lock_guard<boost::mutex> lock(active_action_mutex_);
00143
00144
00145
00146
00147
00148 current_label_ = goal->label;
00149
00150
00151
00152 face_detection_subscriber_.subscribe(node_handle_, "face_detections", 1);
00153 face_detection_subscriber_.registerCallback(boost::bind(&FaceCaptureNode::inputCallback, this, _1));
00154
00155
00156 if (goal->capture_mode == MANUAL)
00157 {
00158
00159 number_captured_images_ = 0;
00160 finish_image_capture_ = false;
00161 capture_image_ = false;
00162
00163
00164 service_server_capture_image_ = node_handle_.advertiseService("capture_image", &FaceCaptureNode::captureImageCallback, this);
00165 service_server_finish_recording_ = node_handle_.advertiseService("finish_recording", &FaceCaptureNode::finishRecordingCallback, this);
00166
00167
00168 while (finish_image_capture_ == false)
00169 ros::spinOnce();
00170
00171
00172 service_server_capture_image_.shutdown();
00173 service_server_finish_recording_.shutdown();
00174
00175
00176 face_recognizer_trainer_.saveTrainingData(face_images_,face_depthmaps_);
00177
00178
00179 cob_people_detection::addDataResult result;
00180 add_data_server_->setSucceeded(result, "Manual capture finished successfully.");
00181 }
00182 else if (goal->capture_mode == CONTINUOUS)
00183 {
00184
00185 number_captured_images_ = 0;
00186 while (number_captured_images_ < goal->continuous_mode_images_to_capture)
00187 {
00188 capture_image_ = true;
00189 ros::Duration(goal->continuous_mode_delay).sleep();
00190 }
00191
00192
00193 face_recognizer_trainer_.saveTrainingData(face_images_,face_depthmaps_);
00194
00195
00196 cob_people_detection::addDataResult result;
00197 std::stringstream ss;
00198 ss << "Continuous capture of " << goal->continuous_mode_images_to_capture << " images finished successfully.";
00199 add_data_server_->setSucceeded(result, ss.str());
00200 }
00201 else
00202 {
00203 ROS_ERROR("FaceCaptureNode::addDataServerCallback: Unknown capture mode: %d.", goal->capture_mode);
00204 cob_people_detection::addDataResult result;
00205 std::stringstream ss;
00206 ss << "Unknown capture mode: " << goal->capture_mode;
00207 add_data_server_->setAborted(result, ss.str());
00208 }
00209
00210
00211
00212 face_detection_subscriber_.unsubscribe();
00213 }
00214
00216 void FaceCaptureNode::inputCallback(const cob_perception_msgs::ColorDepthImageArray::ConstPtr& face_detection_msg)
00217 {
00218
00219
00220
00221 if (capture_image_ == true)
00222 {
00223
00224 int numberFaces = 0;
00225 int headIndex = 0;
00226 for (unsigned int i=0; i<face_detection_msg->head_detections.size(); i++)
00227 {
00228 numberFaces += face_detection_msg->head_detections[i].face_detections.size();
00229 if (face_detection_msg->head_detections[i].face_detections.size() == 1)
00230 headIndex = i;
00231 }
00232 if (numberFaces != 1)
00233 {
00234 ROS_WARN("Either no head or more than one head detected. Discarding image.");
00235 return;
00236 }
00237
00238
00239 cv_bridge::CvImageConstPtr color_image_ptr;
00240 cv::Mat color_image,depth_image;
00241
00242 sensor_msgs::ImageConstPtr msgPtr = boost::shared_ptr<sensor_msgs::Image const>(&(face_detection_msg->head_detections[headIndex].color_image), voidDeleter);
00243 convertColorImageMessageToMat(msgPtr, color_image_ptr, color_image);
00244
00245 msgPtr = boost::shared_ptr<sensor_msgs::Image const>(&(face_detection_msg->head_detections[headIndex].depth_image), voidDeleter);
00246 convertDepthImageMessageToMat(msgPtr, color_image_ptr, depth_image);
00247
00248
00249
00250
00251
00252
00253 const cob_perception_msgs::Rect& face_rect = face_detection_msg->head_detections[headIndex].face_detections[0];
00254 const cob_perception_msgs::Rect& head_rect = face_detection_msg->head_detections[headIndex].head_detection;
00255 cv::Rect face_bounding_box(face_rect.x, face_rect.y, face_rect.width, face_rect.height);
00256 cv::Rect head_bounding_box(head_rect.x, head_rect.y, head_rect.width, head_rect.height);
00257 cv::Mat img_color = color_image;
00258 cv::Mat img_depth = depth_image;
00259
00260
00261 if (face_recognizer_trainer_.addFace(img_color, img_depth, face_bounding_box, head_bounding_box, current_label_, face_images_, face_depthmaps_)==ipa_Utils::RET_FAILED)
00262 {
00263 ROS_WARN("face_capture: Adding face failed.");
00264 capture_image_ = false;
00265 return;
00266 }
00267
00268
00269 number_captured_images_++;
00270 capture_image_ = false;
00271
00272 ROS_INFO("Face number %d captured.", number_captured_images_);
00273 }
00274 }
00275
00277 unsigned long FaceCaptureNode::convertColorImageMessageToMat(const sensor_msgs::Image::ConstPtr& image_msg, cv_bridge::CvImageConstPtr& image_ptr, cv::Mat& image)
00278 {
00279 try
00280 {
00281 image_ptr = cv_bridge::toCvShare(image_msg, sensor_msgs::image_encodings::BGR8);
00282 }
00283 catch (cv_bridge::Exception& e)
00284 {
00285 ROS_ERROR("PeopleDetection: cv_bridge exception: %s", e.what());
00286 return ipa_Utils::RET_FAILED;
00287 }
00288 image = image_ptr->image;
00289
00290 return ipa_Utils::RET_OK;
00291 }
00292
00294 unsigned long FaceCaptureNode::convertDepthImageMessageToMat(const sensor_msgs::Image::ConstPtr& image_msg, cv_bridge::CvImageConstPtr& image_ptr, cv::Mat& image)
00295 {
00296 try
00297 {
00298 image_ptr = cv_bridge::toCvShare(image_msg, sensor_msgs::image_encodings::TYPE_32FC3);
00299 }
00300 catch (cv_bridge::Exception& e)
00301 {
00302 ROS_ERROR("PeopleDetection: cv_bridge exception: %s", e.what());
00303 return ipa_Utils::RET_FAILED;
00304 }
00305 image = image_ptr->image;
00306
00307 return ipa_Utils::RET_OK;
00308 }
00309
00310 bool FaceCaptureNode::captureImageCallback(cob_people_detection::captureImage::Request &req, cob_people_detection::captureImage::Response &res)
00311 {
00312 capture_image_ = true;
00313
00314 while (capture_image_ == true)
00315 ros::spinOnce();
00316 res.number_captured_images = number_captured_images_;
00317 return true;
00318 }
00319
00320 bool FaceCaptureNode::finishRecordingCallback(cob_people_detection::finishRecording::Request &req, cob_people_detection::finishRecording::Response &res)
00321 {
00322 finish_image_capture_ = true;
00323 return true;
00324 }
00325
00326 void FaceCaptureNode::updateDataServerCallback(const cob_people_detection::updateDataGoalConstPtr& goal)
00327 {
00328
00329 boost::lock_guard<boost::mutex> lock(active_action_mutex_);
00330
00331 cob_people_detection::updateDataResult result;
00332
00333
00334 if (goal->update_mode == BY_INDEX)
00335 {
00336
00337 face_recognizer_trainer_.updateFaceLabel(goal->update_index, goal->new_label);
00338 }
00339 else if (goal->update_mode == BY_LABEL)
00340 {
00341
00342 face_recognizer_trainer_.updateFaceLabels(goal->old_label, goal->new_label);
00343 }
00344 else
00345 {
00346 ROS_ERROR("FaceCaptureNode::updateDataServerCallback: Unknown update_mode.");
00347 update_data_server_->setAborted(result, "Unknown update_mode. No entries have been updated.");
00348 return;
00349 }
00350
00351
00352 face_recognizer_trainer_.saveTrainingData(face_images_,face_depthmaps_);
00353
00354
00355 update_data_server_->setSucceeded(result, "Database update finished successfully.");
00356 }
00357
00358 void FaceCaptureNode::deleteDataServerCallback(const cob_people_detection::deleteDataGoalConstPtr& goal)
00359 {
00360
00361 boost::lock_guard<boost::mutex> lock(active_action_mutex_);
00362
00363 cob_people_detection::deleteDataResult result;
00364
00365
00366 if (goal->delete_mode == BY_INDEX)
00367 {
00368
00369 face_recognizer_trainer_.deleteFace(goal->delete_index, face_images_,face_depthmaps_);
00370 }
00371 else if (goal->delete_mode == BY_LABEL)
00372 {
00373
00374 face_recognizer_trainer_.deleteFaces(goal->label, face_images_,face_depthmaps_);
00375 }
00376 else
00377 {
00378 ROS_ERROR("FaceCaptureNode::deleteDataServerCallback: Unknown delete_mode.");
00379 delete_data_server_->setAborted(result, "Unknown delete_mode. No entries have been deleted from the database.");
00380 return;
00381 }
00382
00383
00384 face_recognizer_trainer_.saveTrainingData(face_images_,face_depthmaps_);
00385
00386
00387 delete_data_server_->setSucceeded(result, "Deleting entries from the database finished successfully.");
00388 }
00389
00390
00391
00392
00393 int main(int argc, char** argv)
00394 {
00395
00396 ros::init(argc, argv, "face_capture");
00397
00398
00399 ros::NodeHandle nh;
00400
00401
00402 FaceCaptureNode face_capture_node(nh);
00403
00404
00405
00406
00407
00408
00409 ros::spin();
00410
00411 return 0;
00412 }
00413