face_detection.cpp
Go to the documentation of this file.
00001 /****************************************************************
00002  *
00003  * Copyright (c) 2010
00004  *
00005  * Fraunhofer Institute for Manufacturing Engineering   
00006  * and Automation (IPA)
00007  *
00008  * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00009  *
00010  * Project name: care-o-bot
00011  * ROS stack name: cob_vision
00012  * ROS package name: cob_people_detection
00013  * Description:
00014  *                                                              
00015  * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00016  *                      
00017  * Author: Jan Fischer, email:jan.fischer@ipa.fhg.de
00018  * Author: Richard Bormann, email: richard.bormann@ipa.fhg.de
00019  * Supervised by: 
00020  *
00021  * Date of creation: 03/2011
00022  * ToDo:
00023  *
00024  * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00025  *
00026  * Redistribution and use in source and binary forms, with or without
00027  * modification, are permitted provided that the following conditions are met:
00028  *
00029  *     * Redistributions of source code must retain the above copyright
00030  *       notice, this list of conditions and the following disclaimer.
00031  *     * Redistributions in binary form must reproduce the above copyright
00032  *       notice, this list of conditions and the following disclaimer in the
00033  *       documentation and/or other materials provided with the distribution.
00034  *     * Neither the name of the Fraunhofer Institute for Manufacturing 
00035  *       Engineering and Automation (IPA) nor the names of its
00036  *       contributors may be used to endorse or promote products derived from
00037  *       this software without specific prior written permission.
00038  *
00039  * This program is free software: you can redistribute it and/or modify
00040  * it under the terms of the GNU Lesser General Public License LGPL as 
00041  * published by the Free Software Foundation, either version 3 of the 
00042  * License, or (at your option) any later version.
00043  * 
00044  * This program is distributed in the hope that it will be useful,
00045  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00046  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00047  * GNU Lesser General Public License LGPL for more details.
00048  * 
00049  * You should have received a copy of the GNU Lesser General Public 
00050  * License LGPL along with this program. 
00051  * If not, see <http://www.gnu.org/licenses/>.
00052  *
00053  ****************************************************************/
00054 
00055 #include "cob_people_detection/face_detection.h"
00056 #include <pluginlib/class_list_macros.h>
00057 
00058 #ifdef __LINUX__
00059 #include "cob_vision_utils/GlobalDefines.h"
00060 #include "cob_vision_utils/VisionUtils.h"
00061 #else
00062 #include "cob_common/cob_vision_utils/common/include/cob_vision_utils/GlobalDefines.h"
00063 #include "cob_common/cob_vision_utils/common/include/cob_vision_utils/VisionUtils.h"
00064 #endif
00065 
00066 #include <opencv2/opencv.hpp>
00067 
00068 PLUGINLIB_EXPORT_CLASS(ipa_PeopleDetector::CobFaceDetectionNodelet, nodelet::Nodelet);
00069 
00070 using namespace ipa_PeopleDetector;
00071 
00072 // Prevent deleting memory twice, when using smart pointer
00073 void voidDeleter(sensor_msgs::PointCloud2* const )
00074 {
00075 }
00076 
00077 //####################
00078 //#### node class ####
00079 CobFaceDetectionNodelet::CobFaceDetectionNodelet()
00080 {
00081         it_ = 0;
00082         sync_pointcloud_ = 0;
00083         people_detector_ = 0;
00084         train_continuous_server_ = 0;
00085         train_capture_sample_server_ = 0;
00086         recognize_server_ = 0;
00087         load_server_ = 0;
00088         save_server_ = 0;
00089         show_server_ = 0;
00090         occupied_by_action_ = false;
00091         recognize_server_running_ = false;
00092         train_continuous_server_running_ = false;
00093         number_training_images_captured_ = 0;
00094         do_recognition_ = true;
00095         display_ = false;
00096         directory_ = ros::package::getPath("cob_people_detection") + "/common/files/windows/"; // can be changed by a parameter
00097 }
00098 
00099 CobFaceDetectionNodelet::~CobFaceDetectionNodelet()
00100 {
00101         if (people_detector_ != 0)
00102                 delete people_detector_;
00103         if (train_continuous_server_ != 0)
00104                 delete train_continuous_server_;
00105         if (train_capture_sample_server_ != 0)
00106                 delete train_capture_sample_server_;
00107         if (recognize_server_ != 0)
00108                 delete recognize_server_;
00109         if (load_server_ != 0)
00110                 delete load_server_;
00111         if (save_server_ != 0)
00112                 delete save_server_;
00113         if (show_server_ != 0)
00114                 delete show_server_;
00115         if (it_ != 0)
00116                 delete it_;
00117         if (sync_pointcloud_ != 0)
00118                 delete sync_pointcloud_;
00119 }
00120 
00121 void CobFaceDetectionNodelet::onInit()
00122 {
00123         sync_pointcloud_ = new message_filters::Synchronizer<message_filters::sync_policies::ApproximateTime<sensor_msgs::PointCloud2, sensor_msgs::Image> >(2);
00124         node_handle_ = getNodeHandle();
00125         it_ = new image_transport::ImageTransport(node_handle_);
00126         face_position_publisher_ = node_handle_.advertise<cob_perception_msgs::DetectionArray>("face_position_array", 1);
00127         face_detection_image_pub_ = it_->advertise("face_detection_image", 1);
00128 
00129         recognize_server_ = new RecognizeServer(node_handle_, "recognize_server", boost::bind(&CobFaceDetectionNodelet::recognizeServerCallback, this, _1), false);
00130         recognize_server_->start();
00131 
00132         recognize_service_server_ = node_handle_.advertiseService("recognize_service_server", &CobFaceDetectionNodelet::recognizeServiceServerCallback, this);
00133 
00134         train_continuous_server_ = new TrainContinuousServer(node_handle_, "train_continuous_server", boost::bind(&CobFaceDetectionNodelet::trainContinuousServerCallback, this, _1),
00135                         false);
00136         train_continuous_server_->start();
00137 
00138         train_capture_sample_server_ = new TrainCaptureSampleServer(node_handle_, "train_capture_sample_server",
00139                         boost::bind(&CobFaceDetectionNodelet::trainCaptureSampleServerCallback, this, _1), false);
00140         train_capture_sample_server_->start();
00141 
00142         load_server_ = new LoadServer(node_handle_, "load_server", boost::bind(&CobFaceDetectionNodelet::loadServerCallback, this, _1), false);
00143         load_server_->start();
00144 
00145         save_server_ = new SaveServer(node_handle_, "save_server", boost::bind(&CobFaceDetectionNodelet::saveServerCallback, this, _1), false);
00146         save_server_->start();
00147 
00148         show_server_ = new ShowServer(node_handle_, "show_server", boost::bind(&CobFaceDetectionNodelet::showServerCallback, this, _1), false);
00149         show_server_->start();
00150 
00151         // Parameters
00152         std::cout << "\n--------------------------\nFace Detection Parameters:\n--------------------------\n";
00153         node_handle_.param("face_size_min_m", face_size_min_m_, FACE_SIZE_MIN_M);
00154         std::cout << "face_size_min_m = " << face_size_min_m_ << "\n";
00155         node_handle_.param("face_size_max_m", face_size_max_m_, FACE_SIZE_MAX_M);
00156         std::cout << "face_size_max_m = " << face_size_max_m_ << "\n";
00157         node_handle_.param("max_face_z_m", max_face_z_m_, MAX_FACE_Z_M);
00158         std::cout << "max_face_z_m = " << max_face_z_m_ << "\n";
00159         node_handle_.param("data_directory", directory_, directory_);
00160         std::cout << "data_directory = " << directory_ << "\n";
00161         node_handle_.param("fill_unassigned_depth_values", fill_unassigned_depth_values_, true);
00162         std::cout << "fill_unassigned_depth_values = " << fill_unassigned_depth_values_ << "\n";
00163         node_handle_.param("reason_about_3dface_size", reason_about_3dface_size_, true);
00164         std::cout << "reason_about_3dface_size = " << reason_about_3dface_size_ << "\n";
00165 
00166         // initializations
00167         init();
00168 
00169         //ros::spin(); not necessary with nodelets
00170 }
00171 
00172 unsigned long CobFaceDetectionNodelet::init()
00173 {
00174         std::cout << "CobFaceDetectionNodelet::init()..." << std::endl;
00175 
00176         shared_image_sub_.subscribe(node_handle_, "pointcloud", 1);
00177         color_camera_image_sub_.subscribe(*it_, "colorimage", 1);
00178         //      sync_pointcloud_->connectInput(shared_image_sub_, color_camera_image_sub_);
00179         //      sync_pointcloud_->registerCallback(boost::bind(&CobFaceDetectionNodelet::recognizeCallback, this, _1, _2));
00180 
00181         sync_pointcloud_->connectInput(shared_image_sub_, color_camera_image_sub_);
00182         sync_pointcloud_callback_connection_ = sync_pointcloud_->registerCallback(boost::bind(&CobFaceDetectionNodelet::recognizeCallback, this, _1, _2));
00183 
00184         std::cout << "   inputs connected." << std::endl;
00185 
00186 #ifdef __LINUX__
00187 #else
00188         colored_pc_ = ipa_SensorFusion::CreateColoredPointCloud();
00189 #endif
00190 
00191         if (people_detector_ != 0)
00192                 delete people_detector_;
00193         people_detector_ = new ipa_PeopleDetector::PeopleDetector();
00194 
00195         std::cout << "   PeopleDetector created." << std::endl;
00196 
00197         filename_ = 0;
00198 
00199         // load data for face recognition
00200         loadRecognizerData();
00201         std::cout << "   recognizer data loaded." << std::endl;
00202 
00203         // use this instead if the rdata.xml file is corrupted
00204         // todo:
00205         //      loadTrainingData(false);
00206         //      //loadRecognizerData();
00207         //      //loadTrainingData(false);
00208         //      run_pca_ = true;
00209         //      PCA();
00210         //      saveRecognizerData();
00211 
00212         std::string iniFileNameAndPath = directory_ + "peopleDetectorIni.xml";
00213 
00214         //if (CameraSensorsControlFlow::Init(directory, "peopleDetectorIni.xml", colorCamera0, colorCamera1, rangeImagingSensor) & ipa_Utils::RET_FAILED)
00215         //{
00216         //      std::cerr << "ERROR - CameraDataViewerControlFlow::Init:" << std::endl;
00217         //      std::cerr << "\t ... Could not initialize 'CameraSensorsControlFlow'" << std::endl;
00218         //      return ipa_Utils::RET_FAILED;
00219         //}
00220 
00221         if (people_detector_->Init(directory_) & ipa_Utils::RET_FAILED)
00222         {
00223                 std::cerr << "ERROR - PeopleDetector::Init:" << std::endl;
00224                 std::cerr << "\t ... Could not initialize people detector library.\n";
00225                 return ipa_Utils::RET_FAILED;
00226         }
00227         std::cout << "   PeopleDetector initilized." << std::endl;
00228 
00229         if (loadParameters(iniFileNameAndPath.c_str()) & ipa_Utils::RET_FAILED)
00230         {
00231                 std::cerr << "ERROR - PeopleDetector::Init:" << std::endl;
00232                 std::cerr << "\t ... Error while loading configuration file '" << std::endl;
00233                 std::cerr << "\t ... " << iniFileNameAndPath << "'.\n";
00234                 return ipa_Utils::RET_FAILED;
00235         }
00236         std::cout << "   ini-file loaded." << std::endl;
00237 
00238         run_pca_ = false;
00239 
00240         return ipa_Utils::RET_OK;
00241 }
00242 
00243 bool CobFaceDetectionNodelet::recognizeServiceServerCallback(cob_people_detection::Recognition::Request &req, cob_people_detection::Recognition::Response &res)
00244 {
00245         // secure this section with a mutex
00246         boost::timed_mutex::scoped_timed_lock lock(action_mutex_, boost::posix_time::milliseconds(2000));
00247 
00248         if (lock.owns_lock() == false || (occupied_by_action_ == true && recognize_server_running_ == false))
00249         {
00250                 // another action is running at the moment, first the other action has to finish or to be stopped before this action can run
00251                 std::cerr << "ERROR - PeopleDetector::recognizeServerCallback:" << std::endl;
00252                 std::cerr << "\t ... Another action is running at the moment. The other action has to finish or to be stopped before this action can run.\n";
00253                 res.success = ipa_Utils::RET_FAILED;
00254                 return false;
00255         }
00256 
00257         // read out req message
00258         // set up the recognition callback linkage
00259         if (req.running == true)
00260         {
00261                 // enable recognition
00262                 occupied_by_action_ = true;
00263                 recognize_server_running_ = true;
00264                 do_recognition_ = req.doRecognition;
00265                 display_ = req.display;
00266                 //cv::namedWindow("Face Detector");
00267                 //cv::waitKey(1);
00268                 //sync_pointcloud_->connectInput(shared_image_sub_, color_camera_image_sub_);
00269                 //sync_pointcloud_callback_connection_ = sync_pointcloud_->registerCallback(boost::bind(&CobFaceDetectionNodelet::recognizeCallback, this, _1, _2, req->doRecognition, req->display));
00270         }
00271         else
00272         {
00273                 // disable recognition
00274                 occupied_by_action_ = false;
00275                 recognize_server_running_ = false;
00276         }
00277 
00278         res.success = ipa_Utils::RET_OK;
00279         return true;
00280 }
00281 
00282 void CobFaceDetectionNodelet::recognizeServerCallback(const cob_people_detection::RecognizeGoalConstPtr& goal)
00283 {
00284         // secure this section with a mutex
00285         boost::timed_mutex::scoped_timed_lock lock(action_mutex_, boost::posix_time::milliseconds(2000));
00286 
00287         cob_people_detection::RecognizeResult result;
00288         if (lock.owns_lock() == false || (occupied_by_action_ == true && recognize_server_running_ == false))
00289         {
00290                 // another action is running at the moment, first the other action has to finish or to be stopped before this action can run
00291                 std::cerr << "ERROR - PeopleDetector::recognizeServerCallback:" << std::endl;
00292                 std::cerr << "\t ... Another action is running at the moment. The other action has to finish or to be stopped before this action can run.\n";
00293                 result.success = ipa_Utils::RET_FAILED;
00294                 recognize_server_->setSucceeded(result, "Some other action is handled at the moment.");
00295                 return;
00296         }
00297 
00298         // read out goal message
00299         // set up the recognition callback linkage
00300         if (goal->running == true)
00301         {
00302                 // enable recognition
00303                 occupied_by_action_ = true;
00304                 recognize_server_running_ = true;
00305                 do_recognition_ = goal->doRecognition;
00306                 display_ = goal->display;
00307                 //cv::namedWindow("Face Detector");
00308                 //cv::waitKey(1);
00309                 //sync_pointcloud_->connectInput(shared_image_sub_, color_camera_image_sub_);
00310                 //sync_pointcloud_callback_connection_ = sync_pointcloud_->registerCallback(boost::bind(&CobFaceDetectionNodelet::recognizeCallback, this, _1, _2, goal->doRecognition, goal->display));
00311         }
00312         else
00313         {
00314                 // disable recognition
00315                 occupied_by_action_ = false;
00316                 recognize_server_running_ = false;
00317         }
00318 
00319         result.success = ipa_Utils::RET_OK;
00320         recognize_server_->setSucceeded(result);
00321 }
00322 
00323 void CobFaceDetectionNodelet::trainContinuousServerCallback(const cob_people_detection::TrainContinuousGoalConstPtr& goal)
00324 {
00325         // secure this section with a mutex
00326         boost::timed_mutex::scoped_timed_lock lock(action_mutex_, boost::posix_time::milliseconds(2000));
00327 
00328         cob_people_detection::TrainContinuousResult result;
00329         if (lock.owns_lock() == false || (occupied_by_action_ == true && train_continuous_server_running_ == false))
00330         {
00331                 // another action is running at the moment, first the other action has to finish or to be stopped before this action can run
00332                 std::cerr << "ERROR - PeopleDetector::trainContinuousServerCallback:" << std::endl;
00333                 std::cerr << "\t ... Another action is running at the moment. The other action has to finish or to be stopped before this action can run.\n";
00334                 result.success = ipa_Utils::RET_FAILED;
00335                 train_continuous_server_->setSucceeded(result, "Some other action is handled at the moment.");
00336                 return;
00337         }
00338 
00339         // read out goal message
00340         // set up the recognition callback linkage
00341         if (goal->running == true)
00342         {
00343                 // enable training
00344                 capture_training_face_ = false;
00345                 current_training_id_ = goal->trainingID;
00346 
00347                 if (goal->appendData == true)
00348                         loadTrainingData(false);
00349                 else
00350                 {
00351                         filename_ = 0;
00352                         std::string path = directory_ + "TrainingData/";
00353                         try
00354                         {
00355                                 boost::filesystem::remove_all(path.c_str());
00356                                 boost::filesystem::create_directory(path.c_str());
00357                         } catch (const std::exception &ex)
00358                         {
00359                                 std::cerr << "ERROR - PeopleDetector::trainContinuousServerCallback():" << std::endl;
00360                                 std::cerr << "\t ... Exception catch of '" << ex.what() << "'" << std::endl;
00361                         }
00362                 }
00363                 occupied_by_action_ = true;
00364                 train_continuous_server_running_ = true;
00365                 //cv::namedWindow("Face Recognizer Training");
00366                 //cv::waitKey(10);
00367                 //sync_pointcloud_->connectInput(shared_image_sub_, color_camera_image_sub_);
00368                 //sync_pointcloud_callback_connection_ = sync_pointcloud_->registerCallback(boost::bind(&CobFaceDetectionNodelet::trainContinuousCallback, this, _1, _2));
00369                 std::cout << "train run...\n";
00370 
00371                 // check whether the continuous mode was enabled or if the image capture is manually triggered
00372                 if (goal->numberOfImagesToCapture > 0)
00373                 {
00374                         lock.unlock();
00375                         number_training_images_captured_ = 0;
00376                         bool capture = true;
00377                         while (capture)
00378                         {
00379                                 boost::timed_mutex::scoped_timed_lock lock(action_mutex_, boost::posix_time::milliseconds(10));
00380                                 if (lock.owns_lock() && capture_training_face_ == false)
00381                                         capture_training_face_ = true;
00382                                 capture = (number_training_images_captured_ < goal->numberOfImagesToCapture);
00383                         }
00384 
00385                         // turn off training mode
00386                         std::cout << "continuous train off...\n";
00387 
00388                         // disable training
00389                         occupied_by_action_ = false;
00390                         train_continuous_server_running_ = false;
00391 
00392                         // save images
00393                         saveTrainingData();
00394 
00395                         // do data analysis if enabled
00396                         if (goal->doPCA)
00397                         {
00398                                 PCA();
00399                                 saveRecognizerData();
00400                         }
00401                 }
00402         }
00403         else
00404         {
00405                 std::cout << "train off...\n";
00406                 // disable training
00407                 //sync_pointcloud_callback_connection_.disconnect();
00408                 occupied_by_action_ = false;
00409                 train_continuous_server_running_ = false;
00410                 //cv::destroyWindow("Face Recognizer Training");
00411                 //cv::waitKey(10);
00412 
00413                 // save images
00414                 saveTrainingData();
00415 
00416                 // do data analysis if enabled
00417                 if (goal->doPCA)
00418                 {
00419                         PCA();
00420                         saveRecognizerData();
00421                 }
00422         }
00423 
00424         result.success = ipa_Utils::RET_OK;
00425         train_continuous_server_->setSucceeded(result);
00426 }
00427 
00428 void CobFaceDetectionNodelet::trainCaptureSampleServerCallback(const cob_people_detection::TrainCaptureSampleGoalConstPtr& goal)
00429 {
00430         // secure this section with a mutex
00431         boost::timed_mutex::scoped_timed_lock lock(action_mutex_, boost::posix_time::milliseconds(10));
00432 
00433         cob_people_detection::TrainCaptureSampleResult result;
00434         if (lock.owns_lock() == false || (occupied_by_action_ == true && train_continuous_server_running_ == false) || occupied_by_action_ == false)
00435         {
00436                 // another action is running at the moment, first the other action has to finish or to be stopped before this action can run
00437                 std::cerr << "ERROR - PeopleDetector::trainCaptureSampleServerCallback:" << std::endl;
00438                 std::cerr
00439                                 << "\t ... Either the training mode is not started or another action is running at the moment. The other action has to finish or to be stopped before this action can run.\n";
00440                 result.success = ipa_Utils::RET_FAILED;
00441                 train_capture_sample_server_->setSucceeded(result, "Some other action is handled at the moment or training mode not started.");
00442                 return;
00443         }
00444 
00445         capture_training_face_ = true;
00446         result.success = ipa_Utils::RET_OK;
00447         train_capture_sample_server_->setSucceeded(result);
00448 }
00449 
00450 void CobFaceDetectionNodelet::loadServerCallback(const cob_people_detection::LoadGoalConstPtr& goal)
00451 {
00452         // secure this section with a mutex
00453         boost::timed_mutex::scoped_timed_lock lock(action_mutex_, boost::posix_time::milliseconds(2000));
00454 
00455         cob_people_detection::LoadResult result;
00456         if (lock.owns_lock() == false || occupied_by_action_ == true)
00457         {
00458                 // another action is running at the moment, first the other action has to finish or to be stopped before this action can run
00459                 std::cerr << "ERROR - PeopleDetector::loadServerCallback:" << std::endl;
00460                 std::cerr << "\t ... Another action is running at the moment. The other action has to finish or to be stopped before this action can run.\n";
00461                 result.success = ipa_Utils::RET_FAILED;
00462                 load_server_->setSucceeded(result, "Some other action is handled at the moment or training mode not started.");
00463                 return;
00464         }
00465 
00466         // load data
00467         result.success = ipa_Utils::RET_OK;
00468         if (goal->loadMode == 0)
00469                 result.success = loadAllData();
00470         else if (goal->loadMode == 1)
00471                 result.success = loadTrainingData(goal->doPCA);
00472         else if (goal->loadMode == 2)
00473                 result.success = loadRecognizerData();
00474 
00475         load_server_->setSucceeded(result);
00476 }
00477 
00478 void CobFaceDetectionNodelet::saveServerCallback(const cob_people_detection::SaveGoalConstPtr& goal)
00479 {
00480         // secure this section with a mutex
00481         boost::timed_mutex::scoped_timed_lock lock(action_mutex_, boost::posix_time::milliseconds(2000));
00482 
00483         cob_people_detection::SaveResult result;
00484         if (lock.owns_lock() == false || occupied_by_action_ == true)
00485         {
00486                 // another action is running at the moment, first the other action has to finish or to be stopped before this action can run
00487                 std::cerr << "ERROR - PeopleDetector::saveServerCallback:" << std::endl;
00488                 std::cerr << "\t ... Another action is running at the moment. The other action has to finish or to be stopped before this action can run.\n";
00489                 result.success = ipa_Utils::RET_FAILED;
00490                 save_server_->setSucceeded(result, "Some other action is handled at the moment or training mode not started.");
00491                 return;
00492         }
00493 
00494         // save data
00495         result.success = ipa_Utils::RET_OK;
00496         if (goal->saveMode == 0)
00497                 result.success = saveAllData();
00498         else if (goal->saveMode == 1)
00499                 result.success = saveTrainingData();
00500         else if (goal->saveMode == 2)
00501                 result.success = saveRecognizerData();
00502 
00503         save_server_->setSucceeded(result);
00504 }
00505 
00506 void CobFaceDetectionNodelet::showServerCallback(const cob_people_detection::ShowGoalConstPtr& goal)
00507 {
00508         // secure this section with a mutex
00509         boost::timed_mutex::scoped_timed_lock lock(action_mutex_, boost::posix_time::milliseconds(2000));
00510 
00511         cob_people_detection::ShowResult result;
00512         if (lock.owns_lock() == false || occupied_by_action_ == true)
00513         {
00514                 // another action is running at the moment, first the other action has to finish or to be stopped before this action can run
00515                 std::cerr << "ERROR - PeopleDetector::showServerCallback:" << std::endl;
00516                 std::cerr << "\t ... Another action is running at the moment. The other action has to finish or to be stopped before this action can run.\n";
00517                 result.success = ipa_Utils::RET_FAILED;
00518                 show_server_->setSucceeded(result, "Some other action is handled at the moment or training mode not started.");
00519                 return;
00520         }
00521 
00522         // display
00523         loadTrainingData(false);
00524         if (goal->mode == 0)
00525         {
00526                 // show average image
00527                 cv::Mat avgImage(100, 100, CV_8UC1);
00528                 PCA();
00529                 showAVGImage(avgImage);
00530 
00531                 cv::namedWindow("AVGImage");
00532                 cv::imshow("AVGImage", avgImage);
00533                 cv::waitKey(3000);
00534 
00535                 cv::destroyWindow("AVGImage");
00536         }
00537         else if (goal->mode == 1)
00538         {
00539                 // show eigenfaces
00540                 cv::Mat eigenface;
00541                 cv::namedWindow("Eigenfaces");
00542                 PCA();
00543                 for (int i = 0; i < (int)20/*face_images_.size()-1*/; i++)
00544                 {
00545                         getEigenface(eigenface, i);
00546                         cv::imshow("Eigenfaces", eigenface);
00547                         cv::waitKey();
00548                 }
00549                 cv::destroyWindow("Eigenfaces");
00550         }
00551 
00552         result.success = ipa_Utils::RET_OK;
00553         show_server_->setSucceeded(result);
00554 }
00555 
00556 unsigned long CobFaceDetectionNodelet::detectFaces(cv::Mat& xyz_image, cv::Mat& color_image)
00557 {
00558         cv::Mat xyz_image_8U3;
00559         ipa_Utils::ConvertToShowImage(xyz_image, xyz_image_8U3, 3);
00560         if (people_detector_->DetectFaces(color_image, xyz_image_8U3, color_faces_, range_faces_, range_face_indices_with_color_face_detection_, fill_unassigned_depth_values_)
00561                         & ipa_Utils::RET_FAILED)
00562         {
00563                 std::cerr << "ERROR - PeopleDetection::detectFaces" << std::endl;
00564                 std::cerr << "\t ... Could not detect faces.\n";
00565                 return ipa_Utils::RET_FAILED;
00566         }
00567 
00568         // check whether the color faces have a reasonable 3D size
00569         std::vector < cv::Rect > tempFaces = color_faces_; // todo: why copy to tempFaces?
00570         color_faces_.clear();
00571         // For each face...
00572         for (uint iface = 0; iface < tempFaces.size(); iface++)
00573         {
00574                 cv::Rect& face = tempFaces[iface];
00575 
00576                 //              one_face.box2d = faces_vec[iface];
00577                 //              one_face.id = i; // The cascade that computed this face.
00578 
00579                 // Get the median disparity in the middle half of the bounding box.
00580                 int uStart = floor(0.25 * face.width);
00581                 int uEnd = floor(0.75 * face.width) + 1;
00582                 int vStart = floor(0.25 * face.height);
00583                 int vEnd = floor(0.75 * face.height) + 1;
00584                 int du = abs(uEnd - uStart);
00585 
00586                 cv::Mat faceRegion = xyz_image(face);
00587                 cv::Mat tmat(1, du * abs(vEnd - vStart), CV_32FC1); // vector of all depth values in the face region
00588                 float* tmatPtr = (float*)tmat.data;
00589                 for (int v = vStart; v < vEnd; v++)
00590                 {
00591                         float* zPtr = (float*)faceRegion.row(v).data;
00592                         zPtr += 2 + 3 * uStart;
00593                         for (int u = uStart; u < uEnd; u++)
00594                         {
00595                                 float depthval = *zPtr;
00596                                 if (!isnan(depthval))
00597                                         *tmatPtr = depthval;
00598                                 else
00599                                         *tmatPtr = 1e20;
00600                                 tmatPtr++;
00601                                 zPtr += 3;
00602                         }
00603                 }
00604                 //
00605                 //
00606                 //              int vector_position = 0;
00607                 //              for (int v=vStart; v<vEnd; v++)
00608                 //                for (int u=uStart; u<uEnd; u++, vector_position++)
00609                 //                {
00610                 //                      float depthval = xyz_image.at<cv::Vec3f>(v,u).z;
00611                 //                      if (!isnan(depthval)) tmat.at<float>(0,vector_position) = depthval;
00612                 //                      else tmat.at<float>(0,vector_position) = 1e20;
00613                 //                }
00614 
00615                 cv::Mat tmat_sorted;
00616                 cv::sort(tmat, tmat_sorted, CV_SORT_EVERY_COLUMN + CV_SORT_DESCENDING);
00617                 double avg_depth = tmat_sorted.at<float>(floor(cv::countNonZero(tmat_sorted >= 0.0) * 0.5)); // Get the middle valid disparity (-1 disparities are invalid)
00618 
00619                 // Fill in the rest of the face data structure.
00620                 //              one_face.center2d = cv::Point2d(one_face.box2d.x+one_face.box2d.width*0.5,
00621                 //                                                                              one_face.box2d.y+one_face.box2d.height*0.5);
00622                 //              one_face.radius2d = one_face.box2d.width*0.5;
00623 
00624                 // If the median disparity was valid and the face is a reasonable size, the face status is "good".
00625                 // If the median disparity was valid but the face isn't a reasonable size, the face status is "bad".
00626                 // Otherwise, the face status is "unknown".
00627                 // Only bad faces are removed
00628                 if (avg_depth > 0)
00629                 {
00630                         double radiusX, radiusY, radius3d = 1e20;
00631                         cv::Vec3f a, b;
00632                         // vertical line regularly lies completely on the head whereas this does not hold very often for the horizontal line crossing the bounding box of the face
00633                         // rectangle in the middle
00634                         a = xyz_image.at<cv::Vec3f>((int)(face.y + face.height * 0.25), (int)(face.x + 0.5 * face.width));
00635                         b = xyz_image.at<cv::Vec3f>((int)(face.y + face.height * 0.75), (int)(face.x + 0.5 * face.width));
00636                         if (display_)
00637                                 std::cout << "a: " << a.val[0] << " " << a.val[1] << " " << a.val[2] << "   b: " << " " << b.val[0] << " " << b.val[1] << " " << b.val[2] << "\n";
00638                         if (isnan(a.val[0]) || isnan(b.val[0]))
00639                                 radiusY = 0.0;
00640                         else
00641                                 radiusY = cv::norm(b - a);
00642                         radius3d = radiusY;
00643 
00644                         // for radius estimation with the horizontal line through the face rectangle use points which typically still lie on the face and not in the background
00645                         a = xyz_image.at<cv::Vec3f>((int)(face.y + face.height * 0.5), (int)(face.x + face.width * 0.25));
00646                         b = xyz_image.at<cv::Vec3f>((int)(face.y + face.height * 0.5), (int)(face.x + face.width * 0.75));
00647                         if (display_)
00648                                 std::cout << "a: " << a.val[0] << " " << a.val[1] << " " << a.val[2] << "   b: " << " " << b.val[0] << " " << b.val[1] << " " << b.val[2] << "\n";
00649                         if (isnan(a.val[0]) || isnan(b.val[0]))
00650                                 radiusX = 0.0;
00651                         else
00652                         {
00653                                 radiusX = cv::norm(b - a);
00654                                 if (radiusY != 0.0)
00655                                         radius3d = (radiusX + radiusY) * 0.5;
00656                                 else
00657                                         radius3d = radiusX;
00658                         }
00659 
00660                         //                      cv::Point pup(face.x+0.5*face.width, face.y+face.height*0.25);
00661                         //                      cv::Point plo(face.x+0.5*face.width, face.y+face.height*0.75);
00662                         //                      cv::Point ple(face.x+face.width*0.25, face.y+face.height*0.5);
00663                         //                      cv::Point pri(face.x+face.width*0.75, face.y+face.height*0.5);
00664                         //                      cv::line(xyz_image_8U3, pup, plo, CV_RGB(255, 255, 255), 2);
00665                         //                      cv::line(xyz_image_8U3, ple, pri, CV_RGB(255, 255, 255), 2);
00666 
00667                         if (display_)
00668                         {
00669                                 std::cout << "radiusX: " << radiusX << "  radiusY: " << radiusY << "\n";
00670                                 std::cout << "avg_depth: " << avg_depth << " > max_face_z_m_: " << max_face_z_m_ << " ?  2*radius3d: " << 2.0 * radius3d << " < face_size_min_m_: "
00671                                                 << face_size_min_m_ << " ?  2radius3d: " << 2.0 * radius3d << " > face_size_max_m_:" << face_size_max_m_ << "?\n";
00672                         }
00673                         if (reason_about_3dface_size_ == true && radius3d > 0.0 && (avg_depth > max_face_z_m_ || 2.0 * radius3d < face_size_min_m_ || 2.0 * radius3d > face_size_max_m_))
00674                                 continue; // face does not match normal human appearance
00675                 }
00676                 color_faces_.push_back(face);
00677         }
00678         //                      imshow("xyz image", xyz_image_8U3);
00679         //                      cv::waitKey(10);
00680 
00681         return ipa_Utils::RET_OK;
00682 }
00683 
00684 unsigned long CobFaceDetectionNodelet::recognizeFace(cv::Mat& color_image, std::vector<int>& index)
00685 {
00686         if (people_detector_->RecognizeFace(color_image, color_faces_, &n_eigens_, eigen_vectors_, avg_image_, face_class_avg_projections_, index, &threshold_, &threshold_fs_,
00687                         eigen_val_mat_, /*&person_classifier_*/0) & ipa_Utils::RET_FAILED)
00688         {
00689                 std::cerr << "ERROR - PeopleDetector::recognizeFace:" << std::endl;
00690                 std::cerr << "\t ... Error while recognizing faces.\n";
00691                 return ipa_Utils::RET_FAILED;
00692         }
00693 
00694         return ipa_Utils::RET_OK;
00695 }
00696 
00697 unsigned long CobFaceDetectionNodelet::addFace(cv::Mat& image, std::string id)
00698 {
00699         // addFace should only be called if there is exactly one face found --> so we access it with color_faces_[0]
00700         if (people_detector_->AddFace(image, color_faces_[0], id, face_images_, id_) & ipa_Utils::RET_FAILED)
00701         {
00702                 std::cerr << "ERROR - PeopleDetectorControlFlow::AddFace:" << std::endl;
00703                 std::cerr << "\t ... Could not save face.\n";
00704                 return ipa_Utils::RET_FAILED;
00705         }
00706         run_pca_ = true;
00707 
00708         return ipa_Utils::RET_OK;
00709 }
00710 
00711 unsigned long CobFaceDetectionNodelet::PCA()
00712 {
00713         // only run PCA if new data has arrived after last computation
00714         if (!run_pca_)
00715         {
00716                 //std::cout << "INFO - PeopleDetector::PCA:" << std::endl;
00717                 //std::cout << "\t ... PCA algorithm skipped.\n";
00718                 return ipa_Utils::RET_OK;
00719         }
00720 
00721         if (face_images_.size() < 2)
00722         {
00723                 std::cout << "WARNING - PeopleDetector::ConsoleGUI:" << std::endl;
00724                 std::cout << "\t ... Less than two images are trained.\n";
00725                 return ipa_Utils::RET_OK;
00726         }
00727 
00728         // Delete memory
00729         eigen_vectors_.clear();
00730 
00731         // mirror images
00732         //todo:
00733         //      std::vector<cv::Mat> face_images_doubled;
00734         //      std::vector<std::string> id_doubled;
00735         //      for (int i=0; i<(int)face_images_.size(); i++)
00736         //      {
00737         //              face_images_doubled.push_back(face_images_[i]);
00738         //              id_doubled.push_back(id_[i]);
00739         //              cv::Mat temp;
00740         //              cv::flip(face_images_[i], temp, 1);
00741         //              face_images_doubled.push_back(temp);
00742         //              id_doubled.push_back(id_[i]);
00743         //      }
00744 
00745         // Do PCA
00746         if (people_detector_->PCA(&n_eigens_, eigen_vectors_, eigen_val_mat_, avg_image_, face_images_/*doubled*/, projected_train_face_mat_) & ipa_Utils::RET_FAILED)
00747         {
00748                 std::cerr << "ERROR - PeopleDetectorControlFlow::PCA:" << std::endl;
00749                 std::cerr << "\t ... Error while PCA.\n";
00750                 return ipa_Utils::RET_FAILED;
00751         }
00752 
00753         // Calculate FaceClasses
00754         std::cout << "Debug: n_eigens: " << n_eigens_ << " id: " << id_.size() << "\n";
00755         if (people_detector_->CalculateFaceClasses(projected_train_face_mat_, id_/*doubled*/, &n_eigens_, face_class_avg_projections_, id_unique_, /*&person_classifier_*/0)
00756                         & ipa_Utils::RET_FAILED)
00757         {
00758                 std::cerr << "ERROR - PeopleDetectorControlFlow::PCA:" << std::endl;
00759                 std::cerr << "\t ... Error while calculating FaceClasses.\n";
00760                 return ipa_Utils::RET_FAILED;
00761         }
00762 
00763         run_pca_ = false;
00764 
00765         return ipa_Utils::RET_OK;
00766 }
00767 
00768 unsigned long CobFaceDetectionNodelet::saveAllData()
00769 {
00770         //      try
00771         //      {
00772         //              fs::remove_all(path.c_str());
00773         //              fs::create_directory(path.c_str());
00774         //      }
00775         //      catch (const std::exception &ex)
00776         //      {
00777         //              std::cerr << "ERROR - PeopleDetector::SaveTrainingData():" << std::endl;
00778         //              std::cerr << "\t ... Exception catch of '" << ex.what() << "'" << std::endl;
00779         //      }
00780 
00781         if (saveTrainingData() != ipa_Utils::RET_OK)
00782                 return ipa_Utils::RET_FAILED;
00783         if (saveRecognizerData() != ipa_Utils::RET_OK)
00784                 return ipa_Utils::RET_FAILED;
00785 
00786         return ipa_Utils::RET_OK;
00787 }
00788 
00789 unsigned long CobFaceDetectionNodelet::saveTrainingData()
00790 {
00791         std::string path = directory_ + "TrainingData/";
00792         std::string filename = "tdata.xml";
00793         std::string img_ext = ".bmp";
00794 
00795         std::ostringstream complete;
00796         complete << path << filename;
00797 
00798         cv::FileStorage fileStorage(complete.str().c_str(), cv::FileStorage::WRITE);
00799         if (!fileStorage.isOpened())
00800         {
00801                 std::cout << "WARNING - PeopleDetector::SaveTrainingData:" << std::endl;
00802                 std::cout << "\t ... Can't save training data.\n";
00803                 return ipa_Utils::RET_OK;
00804         }
00805 
00806         // Ids
00807         fileStorage << "id_num" << (int)id_.size();
00808         for (int i = 0; i < (int)id_.size(); i++)
00809         {
00810                 std::ostringstream tag;
00811                 tag << "id_" << i;
00812                 fileStorage << tag.str().c_str() << id_[i].c_str();
00813         }
00814 
00815         // Face images
00816         fileStorage << "faces_num" << (int)face_images_.size();
00817         for (int i = 0; i < (int)face_images_.size(); i++)
00818         {
00819                 std::ostringstream img, shortname;
00820                 img << path << i << img_ext;
00821                 shortname << "TrainingData/" << i << img_ext;
00822                 std::ostringstream tag;
00823                 tag << "img_" << i;
00824                 fileStorage << tag.str().c_str() << shortname.str().c_str();
00825                 cv::imwrite(img.str().c_str(), face_images_[i]);
00826         }
00827 
00828         fileStorage.release();
00829 
00830         std::cout << "INFO - PeopleDetector::SaveTrainingData:" << std::endl;
00831         std::cout << "\t ... " << face_images_.size() << " images saved.\n";
00832         return ipa_Utils::RET_OK;
00833 }
00834 
00835 unsigned long CobFaceDetectionNodelet::saveRecognizerData()
00836 {
00837         std::string path = directory_ + "TrainingData/";
00838         std::string filename = "rdata.xml";
00839 
00840         std::ostringstream complete;
00841         complete << path << filename;
00842 
00843         cv::FileStorage fileStorage(complete.str().c_str(), cv::FileStorage::WRITE);
00844         if (!fileStorage.isOpened())
00845         {
00846                 std::cout << "WARNING - PeopleDetector::saveRecognizerData:" << std::endl;
00847                 std::cout << "\t ... Can't save training data.\n";
00848                 return ipa_Utils::RET_OK;
00849         }
00850 
00851         // Number eigenvalues/eigenvectors
00852         fileStorage << "eigens_num" << n_eigens_;
00853 
00854         // Eigenvectors
00855         for (int i = 0; i < n_eigens_; i++)
00856         {
00857                 std::ostringstream tag;
00858                 tag << "ev_" << i;
00859                 fileStorage << tag.str().c_str() << eigen_vectors_[i];
00860         }
00861 
00862         // Eigenvalue matrix
00863         fileStorage << "eigen_val_mat" << eigen_val_mat_;
00864 
00865         // Average image
00866         fileStorage << "avg_image" << avg_image_;
00867 
00868         // Projection coefficients of the training faces
00869         fileStorage << "projected_train_face_mat" << projected_train_face_mat_;
00870 
00871         // Unique Ids (id_unique_[i] stores the corresponding id to the average face coordinates in the face subspace in face_class_avg_projections_.row(i))
00872         fileStorage << "id_unique_num" << (int)id_unique_.size();
00873         for (int i = 0; i < (int)id_unique_.size(); i++)
00874         {
00875                 std::ostringstream tag;
00876                 tag << "id_unique_" << i;
00877                 fileStorage << tag.str().c_str() << id_unique_[i].c_str();
00878         }
00879 
00880         // The average factors of the eigenvector decomposition from each face class
00881         fileStorage << "face_class_avg_projections" << face_class_avg_projections_;
00882 
00883         fileStorage.release();
00884 
00885         // save classifier
00886         std::string classifierFile = path + "svm.dat";
00887         //person_classifier_.save(classifierFile.c_str());
00888 
00889         std::cout << "INFO - PeopleDetector::saveRecognizerData:" << std::endl;
00890         std::cout << "\t ... recognizer data saved.\n";
00891         return ipa_Utils::RET_OK;
00892 }
00893 
00894 unsigned long CobFaceDetectionNodelet::loadAllData()
00895 {
00896         if (loadTrainingData(true) != ipa_Utils::RET_OK)
00897                 return ipa_Utils::RET_FAILED;
00898         if (loadRecognizerData() != ipa_Utils::RET_OK)
00899                 return ipa_Utils::RET_FAILED;
00900 
00901         return ipa_Utils::RET_OK;
00902 }
00903 
00904 unsigned long CobFaceDetectionNodelet::loadTrainingData(bool runPCA)
00905 {
00906         std::string path = directory_ + "TrainingData/";
00907         std::string filename = "tdata.xml";
00908 
00909         std::ostringstream complete;
00910         complete << path << filename;
00911 
00912         if (fs::is_directory(path.c_str()))
00913         {
00914                 cv::FileStorage fileStorage(complete.str().c_str(), cv::FileStorage::READ);
00915                 if (!fileStorage.isOpened())
00916                 {
00917                         std::cout << "WARNING - PeopleDetector::loadTrainingData:" << std::endl;
00918                         std::cout << "\t ... Cant open " << complete.str() << ".\n";
00919                         return ipa_Utils::RET_OK;
00920                 }
00921 
00922                 // Ids
00923                 id_.clear();
00924                 int id_num = (int)fileStorage["id_num"];
00925                 for (int i = 0; i < id_num; i++)
00926                 {
00927                         std::ostringstream tag;
00928                         tag << "id_" << i;
00929                         id_.push_back((std::string)fileStorage[tag.str().c_str()]);
00930                 }
00931 
00932                 // Images
00933                 face_images_.clear();
00934                 int faces_num = (int)fileStorage["faces_num"];
00935                 for (int i = 0; i < faces_num; i++)
00936                 {
00937                         std::ostringstream tag;
00938                         tag << "img_" << i;
00939                         std::string path = directory_ + (std::string)fileStorage[tag.str().c_str()];
00940                         cv::Mat temp = cv::imread(path.c_str(), 0);
00941                         face_images_.push_back(temp);
00942                 }
00943 
00944                 // set next free filename
00945                 filename_ = faces_num;
00946 
00947                 fileStorage.release();
00948 
00949                 // Run PCA - now or later
00950                 run_pca_ = true;
00951                 if (runPCA)
00952                         PCA();
00953 
00954                 std::cout << "INFO - PeopleDetector::loadTrainingData:" << std::endl;
00955                 std::cout << "\t ... " << faces_num << " images loaded.\n";
00956         }
00957         else
00958         {
00959                 std::cerr << "ERROR - PeopleDetector::loadTrainingData:" << std::endl;
00960                 std::cerr << "\t .... Path '" << path << "' is not a directory." << std::endl;
00961                 return ipa_Utils::RET_FAILED;
00962         }
00963 
00964         return ipa_Utils::RET_OK;
00965 }
00966 
00967 unsigned long CobFaceDetectionNodelet::loadRecognizerData()
00968 {
00969         std::string path = directory_ + "TrainingData/";
00970         std::string filename = "rdata.xml";
00971 
00972         std::ostringstream complete;
00973         complete << path << filename;
00974 
00975         if (fs::is_directory(path.c_str()))
00976         {
00977                 cv::FileStorage fileStorage(complete.str().c_str(), cv::FileStorage::READ);
00978                 if (!fileStorage.isOpened())
00979                 {
00980                         std::cout << "WARNING - PeopleDetector::loadRecognizerData:" << std::endl;
00981                         std::cout << "\t ... Cant open " << complete.str() << ".\n";
00982                         return ipa_Utils::RET_OK;
00983                 }
00984                 std::cout << "   loading recognizer data..." << std::endl;
00985 
00986                 // Number eigenvalues/eigenvectors
00987                 n_eigens_ = (int)fileStorage["eigens_num"];
00988 
00989                 // Eigenvectors
00990                 eigen_vectors_.clear();
00991                 eigen_vectors_.resize(n_eigens_, cv::Mat());
00992                 for (int i = 0; i < n_eigens_; i++)
00993                 {
00994                         std::ostringstream tag;
00995                         tag << "ev_" << i;
00996                         fileStorage[tag.str().c_str()] >> eigen_vectors_[i];
00997                 }
00998 
00999                 // Eigenvalue matrix
01000                 eigen_val_mat_ = cv::Mat();
01001                 fileStorage["eigen_val_mat"] >> eigen_val_mat_;
01002 
01003                 // Average image
01004                 avg_image_ = cv::Mat();
01005                 fileStorage["avg_image"] >> avg_image_;
01006 
01007                 // Projections of the training faces
01008                 projected_train_face_mat_ = cv::Mat();
01009                 fileStorage["projected_train_face_mat"] >> projected_train_face_mat_;
01010 
01011                 // Unique Ids (id_unique_[i] stores the corresponding id to the average face coordinates in the face subspace in face_class_avg_projections_.row(i))
01012                 id_unique_.clear();
01013                 int idUniqueNum = (int)fileStorage["id_unique_num"];
01014                 for (int i = 0; i < idUniqueNum; i++)
01015                 {
01016                         std::ostringstream tag;
01017                         tag << "id_unique_" << i;
01018                         id_unique_.push_back((std::string)fileStorage[tag.str().c_str()]);
01019                 }
01020 
01021                 // The average factors of the eigenvector decomposition from each face class
01022                 face_class_avg_projections_ = cv::Mat();
01023                 fileStorage["face_class_avg_projections"] >> face_class_avg_projections_;
01024 
01025                 fileStorage.release();
01026 
01027                 // load classifier
01028                 std::string classifierFile = path + "svm.dat";
01029                 //person_classifier_.load(classifierFile.c_str());
01030 
01031                 // do not run PCA
01032                 run_pca_ = false;
01033 
01034                 std::cout << "INFO - PeopleDetector::loadRecognizerData:" << std::endl;
01035                 std::cout << "\t ... recognizer data loaded.\n";
01036         }
01037         else
01038         {
01039                 std::cerr << "ERROR - PeopleDetector::loadRecognizerData():" << std::endl;
01040                 std::cerr << "\t .... Path '" << path << "' is not a directory." << std::endl;
01041                 return ipa_Utils::RET_FAILED;
01042         }
01043 
01044         return ipa_Utils::RET_OK;
01045 }
01046 
01047 unsigned long CobFaceDetectionNodelet::getEigenface(cv::Mat& eigenface, int index)
01048 {
01049         cv::normalize(eigen_vectors_[index], eigenface, 0, 255, cv::NORM_MINMAX, CV_8UC1);
01050 
01051         return ipa_Utils::RET_OK;
01052 }
01053 
01054 unsigned long CobFaceDetectionNodelet::showAVGImage(cv::Mat& avgImage)
01055 {
01056         if (!run_pca_ && face_images_.size() < 2)
01057         {
01058                 std::cerr << "PeopleDetector::showAvgImage()" << std::endl;
01059                 std::cerr << "No AVG image calculated" << std::endl;
01060                 return 0;
01061         }
01062 
01063         cv::normalize(avg_image_, avgImage, 0, 255, cv::NORM_MINMAX, CV_8UC1);
01064 
01065         return ipa_Utils::RET_OK;
01066 }
01067 
01068 unsigned long CobFaceDetectionNodelet::saveRangeTrainImages(cv::Mat& xyz_image)
01069 {
01070         std::string path = directory_ + "haarcascades/";
01071         std::string img_ext = ".jpg";
01072         cv::Mat xyzImage_8U3(xyz_image.size(), CV_8UC3); //IplImage* xyzImage_8U3 = cvCreateImage(cvGetSize(pc->GetXYZImage()), 8, 3);
01073         ipa_Utils::ConvertToShowImage(xyz_image, xyzImage_8U3, 3);
01074 
01075         for (int i = 0; i < (int)color_faces_.size(); i++)
01076         {
01077                 cv::Mat xyzImage_8U3_resized(100, 100, CV_8UC3); //cvCreateImage(cvSize(100,100), 8, 3); 8=IPL_DEPTH_8U
01078 
01079                 double scale = 1.6;
01080                 cv::Rect rangeFace;
01081                 rangeFace.height = (int)(color_faces_[i].height * scale);
01082                 rangeFace.width = (int)(color_faces_[i].width * scale);
01083                 rangeFace.x = color_faces_[i].x - ((rangeFace.width - color_faces_[i].width) / 2);
01084                 rangeFace.y = color_faces_[i].y - ((rangeFace.height - color_faces_[i].height) / 2) - 10;
01085 
01086                 cv::Mat xyzImage_8U3_roi = xyzImage_8U3(rangeFace);
01087                 //cvSetImageROI(xyzImage_8U3, rangeFace);
01088                 cv::resize(xyzImage_8U3_roi, xyzImage_8U3_resized, xyzImage_8U3_resized.size());
01089 
01090                 std::ostringstream file;
01091                 file << path << filename_ << img_ext;
01092 
01093                 cv::imwrite(file.str().c_str(), xyzImage_8U3_resized);//cvSaveImage(file.str().c_str(), xyzImage_8U3_resized);
01094                 filename_++;
01095         }
01096 
01097         return ipa_Utils::RET_OK;
01098 }
01099 
01100 //unsigned long CobFaceDetectionNodelet::getMeasurement(const sensor_msgs::PointCloud2::ConstPtr& shared_image_msg, const sensor_msgs::Image::ConstPtr& color_image_msg)
01101 //{
01102 //      cv::Mat color_image_8U3(shared_image_msg->height, shared_image_msg->width, CV_8UC3);
01103 //      cv::Mat xyz_image_32F3(shared_image_msg->height, shared_image_msg->width, CV_32FC3);
01104 //      float* f_ptr = 0;
01105 //      const uint8_t* data_ptr = 0;
01106 //      unsigned char* uc_ptr = 0;
01107 //      unsigned int xyz_offset = shared_image_msg->fields[0].offset;
01108 //      unsigned int rgb_offset = shared_image_msg->fields[3].offset;
01109 //      size_t b_offset = 2*sizeof(unsigned char);
01110 //      size_t g_offset = sizeof(unsigned char);
01111 //      size_t r_offset = 0;
01112 //      unsigned int col_times_3 = 0;
01113 //      for (unsigned int row = 0; row < shared_image_msg->height; row++)
01114 //      {
01115 //              uc_ptr = color_image_8U3.ptr<unsigned char>(row);
01116 //              f_ptr = xyz_image_32F3.ptr<float>(row);
01117 //
01118 //              data_ptr = &shared_image_msg->data[row * shared_image_msg->width * shared_image_msg->point_step];
01119 //
01120 //              for (unsigned int col = 0; col < shared_image_msg->width; col++)
01121 //              {
01122 //                      col_times_3 = 3*col;
01123 //                      // Reorder incoming image channels
01124 //                      memcpy(&uc_ptr[col_times_3], &data_ptr[col * shared_image_msg->point_step + rgb_offset + b_offset], sizeof(unsigned char));
01125 //                      memcpy(&uc_ptr[col_times_3 + 1], &data_ptr[col * shared_image_msg->point_step + rgb_offset + g_offset], sizeof(unsigned char));
01126 //                      memcpy(&uc_ptr[col_times_3 + 2], &data_ptr[col * shared_image_msg->point_step + rgb_offset + r_offset], sizeof(unsigned char));
01127 //
01128 //                      memcpy(&f_ptr[col_times_3], &data_ptr[col * shared_image_msg->point_step + xyz_offset], 3*sizeof(float));
01129 //              }
01130 //      }
01131 //
01132 //#ifdef __LINUX__
01133 //      color_image_ = color_image_8U3;
01134 //      range_image_ = xyz_image_32F3;
01135 //#else
01136 //      // Images are cloned within setter functions
01137 //      colored_pc_->SetColorImage(color_image_8U3);
01138 //      colored_pc_->SetXYZImage(xyz_image_32F3);
01139 //#endif
01140 //
01146 //
01147 //      return ipa_Utils::RET_OK;
01148 //}
01149 
01150 
01151 unsigned long CobFaceDetectionNodelet::convertColorImageMessageToMat(const sensor_msgs::Image::ConstPtr& color_image_msg, cv_bridge::CvImageConstPtr& color_image_ptr,
01152                 cv::Mat& color_image)
01153 {
01154         try
01155         {
01156                 color_image_ptr = cv_bridge::toCvShare(color_image_msg, sensor_msgs::image_encodings::BGR8);
01157         } catch (cv_bridge::Exception& e)
01158         {
01159                 ROS_ERROR("PeopleDetection: cv_bridge exception: %s", e.what());
01160                 return ipa_Utils::RET_FAILED;
01161         }
01162         color_image = color_image_ptr->image;
01163 
01164         return ipa_Utils::RET_OK;
01165 }
01166 
01167 unsigned long CobFaceDetectionNodelet::convertPclMessageToMat(const sensor_msgs::PointCloud2::ConstPtr& shared_image_msg, cv::Mat& depth_image)
01168 {
01169         pcl::PointCloud < pcl::PointXYZ > depth_cloud; // point cloud
01170         pcl::fromROSMsg(*shared_image_msg, depth_cloud);
01171         depth_image.create(depth_cloud.height, depth_cloud.width, CV_32FC3);
01172         uchar* depth_image_ptr = (uchar*)depth_image.data;
01173         for (int v = 0; v < (int)depth_cloud.height; v++)
01174         {
01175                 int baseIndex = depth_image.step * v;
01176                 for (int u = 0; u < (int)depth_cloud.width; u++)
01177                 {
01178                         int index = baseIndex + 3 * u * sizeof(float);
01179                         float* data_ptr = (float*)(depth_image_ptr + index);
01180                         pcl::PointXYZ point_xyz = depth_cloud(u, v);
01181                         data_ptr[0] = point_xyz.x;
01182                         data_ptr[1] = point_xyz.y;
01183                         data_ptr[2] = (isnan(point_xyz.z)) ? 0.f : point_xyz.z;
01184                         //if (u%100 == 0) std::cout << "u" << u << " v" << v << " z" << data_ptr[2] << "\n";
01185                 }
01186         }
01187         return ipa_Utils::RET_OK;
01188 }
01189 
01190 inline std::string CobFaceDetectionNodelet::getLabel(int index)
01191 {
01192         switch (index)
01193         {
01194         case -1:
01195                 // Distance to face class is too high
01196                 return "Unknown";
01197                 break;
01198         case -2:
01199                 // Distance to face space is too high
01200                 return "No face";
01201                 break;
01202         default:
01203                 // Face classified
01204                 return id_unique_[index];
01205         }
01206 }
01207 
01208 inline int abs(int x)
01209 {
01210         return ((x < 0) ? -x : x);
01211 }
01212 
01213 void CobFaceDetectionNodelet::recognizeCallback(const sensor_msgs::PointCloud2::ConstPtr& shared_image_msg, const sensor_msgs::Image::ConstPtr& color_image_msg)
01214 {
01215         // check if this is a training call
01216         if (train_continuous_server_running_ == true)
01217         {
01218                 trainContinuousCallback(shared_image_msg, color_image_msg);
01219                 return;
01220         }
01221 
01222         // check for disabled recognition
01223         if (recognize_server_running_ == false)
01224                 return;
01225 
01226         // convert input to cv::Mat images
01227         // color
01228         cv_bridge::CvImageConstPtr color_image_ptr;
01229         cv::Mat color_image;
01230         convertColorImageMessageToMat(color_image_msg, color_image_ptr, color_image);//color_image_ptr->image;
01231 
01232         // point cloud
01233         cv::Mat depth_image;
01234         convertPclMessageToMat(shared_image_msg, depth_image);
01235 
01236 #ifdef __LINUX__
01237         color_image_ = color_image;
01238         range_image_ = depth_image;
01239 #else
01240         // convert point cloud and color image to colored point cloud
01241         colored_pc_->SetColorImage(color_image);
01242         colored_pc_->SetXYZImage(depth_image);
01243 #endif
01244         //getMeasurement(shared_image_msg, color_image_msg);
01245 
01246         // todo: should not be necessary here (e.g. set a trained flag)
01247         PCA();
01248 
01249         if (eigen_vectors_.size() < 1)
01250         {
01251                 std::cout << "WARNING - PeopleDetector::ConsoleGUI:" << std::endl;
01252                 std::cout << "\t ... Less than two images are trained.\n";
01253                 return;
01254         }
01255 
01256         //DWORD start = timeGetTime();
01257         cv::Mat colorImage_8U3;
01258 #ifdef __LINUX__
01259         detectFaces(range_image_, color_image_);
01260         colorImage_8U3 = color_image_.clone();
01261 #else
01262         detectFaces(colored_pc_->GetXYZImage(), colored_pc_->GetColorImage());
01263         colored_pc_->GetColorImage().copyTo(colorImage_8U3);
01264 #endif
01265 
01266         std::vector<int> index;
01267         if (do_recognition_ == true)
01268         {
01269                 recognizeFace(color_image, index);
01270                 //std::cout << "INFO - PeopleDetector::Recognize:" << std::endl;
01271         }
01272         else
01273                 for (int i = 0; i < (int)color_faces_.size(); i++)
01274                         index.push_back(-1);
01275         //std::cout << "\t ... Recognize Time: " << (timeGetTime() - start) << std::endl;
01276 
01277         // publish face positions
01278         cob_perception_msgs::DetectionArray facePositionMsg;
01279         // image dimensions
01280         // time stamp
01281         facePositionMsg.header.stamp = shared_image_msg->header.stamp;
01282         //facePositionMsg.detections.reserve(color_faces_.size());
01283         // add all range faces that do not contain a face detection in the color image
01284         for (int i = 0; i < (int)range_faces_.size(); i++)
01285         {
01286                 // if no color face was detected in that region, add it to the published list
01287                 if (range_face_indices_with_color_face_detection_.find(i) == range_face_indices_with_color_face_detection_.end())
01288                 {
01289                         cv::Rect face = range_faces_[i];
01290 
01291                         // 2D image coordinates
01292                         cob_perception_msgs::Detection det;
01293                         det.header = shared_image_msg->header;
01294                         det.mask.roi.x = face.x;
01295                         det.mask.roi.y = face.y;
01296                         det.mask.roi.width = face.width;
01297                         det.mask.roi.height = face.height;
01298                         float center2Dx = face.x + face.width * 0.5f;
01299                         float center2Dy = face.y + face.height * 0.5f;
01300 
01301                         // 3D world coordinates (and verify that the read pixel contained valid coordinates, otherwise search for valid pixel in neighborhood)
01302                         geometry_msgs::Point* point = &(det.pose.pose.position);
01303                         cv::Point3f p;
01304                         bool validCoordinates = false;
01305                         for (int d = 0; (d < 6 && !validCoordinates); d++)
01306                         {
01307                                 for (int v = -d; (v <= d && !validCoordinates); v++)
01308                                 {
01309                                         for (int u = -d; (u <= d && !validCoordinates); u++)
01310                                         {
01311                                                 if (abs(v) != d && abs(u) != d)
01312                                                         continue;
01313 
01314                                                 p = depth_image.at<cv::Point3f>(center2Dy + v, center2Dx + u);
01315                                                 point->x = p.x;
01316                                                 point->y = p.y;
01317                                                 point->z = p.z;
01318 
01319                                                 if (!isnan(point->x) && !isnan(point->y) && point->z != 0.f)
01320                                                         validCoordinates = true;
01321                                         }
01322                                 }
01323                         }
01324                         if (validCoordinates == false)
01325                                 continue;
01326 
01327                         // person ID
01328                         det.label = "UnknownRange";
01329 
01330                         // origin of detection
01331                         det.detector = "range";
01332 
01333                         facePositionMsg.detections.push_back(det);
01334                 }
01335         }
01336 
01337         // add all color face detections
01338         for (int i = 0; i < (int)color_faces_.size(); i++)
01339         {
01340                 cv::Rect face = color_faces_[i];
01341 
01342                 // 2D image coordinates
01343                 cob_perception_msgs::Detection det;
01344                 det.mask.roi.x = face.x;
01345                 det.mask.roi.y = face.y;
01346                 det.mask.roi.width = face.width;
01347                 det.mask.roi.height = face.height;
01348                 float center2Dx = face.x + face.width * 0.5f;
01349                 float center2Dy = face.y + face.height * 0.5f;
01350 
01351                 // 3D world coordinates
01352                 //              cv::Point3f p = depth_image.at<cv::Point3f>(center2Dy, center2Dx);
01353                 //              geometry_msgs::Point* point = &(det.pose.pose.position);
01354                 //              point->x = p.x; point->y=p.y; point->z=p.z;
01355 
01356                 // 3D world coordinates (and verify that the read pixel contained valid coordinates, otherwise search for valid pixel in neighborhood)
01357                 geometry_msgs::Point* point = &(det.pose.pose.position);
01358                 cv::Point3f p;
01359                 bool validCoordinates = false;
01360                 for (int d = 0; (d < 6 && !validCoordinates); d++)
01361                 {
01362                         for (int v = -d; (v <= d && !validCoordinates); v++)
01363                         {
01364                                 for (int u = -d; (u <= d && !validCoordinates); u++)
01365                                 {
01366                                         if (abs(v) != d && abs(u) != d)
01367                                                 continue;
01368 
01369                                         p = depth_image.at<cv::Point3f>(center2Dy + v, center2Dx + u);
01370                                         point->x = p.x;
01371                                         point->y = p.y;
01372                                         point->z = p.z;
01373 
01374                                         if (!isnan(point->x) && !isnan(point->y) && point->z != 0.f)
01375                                                 validCoordinates = true;
01376                                 }
01377                         }
01378                 }
01379                 if (validCoordinates == false)
01380                         continue;
01381 
01382                 // person ID
01383                 det.label = getLabel(index[i]);
01384 
01385                 // origin of detection
01386                 det.detector = "color";
01387 
01388                 facePositionMsg.detections.push_back(det);
01389         }
01390         face_position_publisher_.publish(facePositionMsg);
01391 
01392         //      std_msgs::Float32MultiArrayPtr facePositionMsg(new std_msgs::Float32MultiArray);
01393         //      const int dataBlockSize = 8;
01394         //      std::vector<float> data(dataBlockSize*color_faces_.size());
01395         //      for(int i=0; i<(int)color_faces_.size(); i++)
01396         //      {
01397         //              cv::Rect face = color_faces_[i];
01398         //              int baseIndex = i*dataBlockSize;
01399         //
01400         //              // 2D image coordinates
01401         //              data[baseIndex]=face.x; data[baseIndex+1]=face.y; data[baseIndex+2]=face.width; data[baseIndex+3]=face.height;
01402         //              float center2Dx = face.x + face.width*0.5f;
01403         //              float center2Dy = face.y + face.height*0.5f;
01404         //
01405         //              // 3D world coordinates
01406         //              cv::Point3f p = depth_image.at<cv::Point3f>(center2Dy, center2Dx);
01407         //              data[baseIndex+4]=p.x; data[baseIndex+5]=p.y; data[baseIndex+6]=p.z;
01408         //
01409         //              // person ID
01410         //              data[baseIndex+7]=index[i];
01411         //      }
01412         //      facePositionMsg->data = data;
01413         //      std::vector<std_msgs::MultiArrayDimension> dim(2, std_msgs::MultiArrayDimension());
01414         //      dim[0].label = "faces";       dim[0].size = color_faces_.size();        dim[0].stride = data.size();
01415         //      dim[1].label = "coordinates"; dim[1].size = dataBlockSize;          dim[1].stride = dataBlockSize;
01416         //      std_msgs::MultiArrayLayout layout;
01417         //      layout.dim = dim;
01418         //      layout.data_offset = 0;
01419         //      facePositionMsg->layout = layout;
01420         //      face_position_publisher_->publish(facePositionMsg);
01421 
01422         // display results
01423         if (display_ == true)
01424         {
01425                 for (int i = 0; i < (int)range_faces_.size(); i++)
01426                 {
01427                         cv::Rect face = range_faces_[i];
01428                         cv::rectangle(colorImage_8U3, cv::Point(face.x, face.y), cv::Point(face.x + face.width, face.y + face.height), CV_RGB(0, 0, 255), 2, 8, 0);
01429                 }
01430 
01431                 for (int i = 0; i < (int)color_faces_.size(); i++)
01432                 {
01433                         cv::Rect face = color_faces_[i];
01434 
01435                         cv::rectangle(colorImage_8U3, cv::Point(face.x, face.y), cv::Point(face.x + face.width, face.y + face.height), CV_RGB(0, 255, 0), 2, 8, 0);
01436 
01437                         std::stringstream tmp;
01438                         switch (index[i])
01439                         {
01440                         case -1:
01441                                 // Distance to face class is too high
01442                                 tmp << "Unknown";
01443                                 cv::putText(colorImage_8U3, tmp.str().c_str(), cv::Point(face.x, face.y + face.height + 25), cv::FONT_HERSHEY_PLAIN, 2, CV_RGB( 255, 0, 0 ), 2);
01444                                 break;
01445                         case -2:
01446                                 // Distance to face space is too high
01447                                 tmp << "No face";
01448                                 cv::putText(colorImage_8U3, tmp.str().c_str(), cv::Point(face.x, face.y + face.height + 25), cv::FONT_HERSHEY_PLAIN, 2, CV_RGB( 255, 0, 0 ), 2);
01449                                 break;
01450                         default:
01451                                 // Face classified
01452                                 tmp << id_unique_[index[i]].c_str();
01453                                 cv::putText(colorImage_8U3, tmp.str().c_str(), cv::Point(face.x, face.y + face.height + 25), cv::FONT_HERSHEY_PLAIN, 2, CV_RGB( 0, 255, 0 ), 2);
01454                         }
01455                 }
01456                 //cv::imshow("Face Detector", colorImage_8U3);
01457                 //cv::waitKey(10);
01458                 // publish topic
01459                 cv_bridge::CvImage cv_ptr;
01460                 cv_ptr.image = colorImage_8U3;
01461                 cv_ptr.encoding = "bgr8";
01462                 face_detection_image_pub_.publish(cv_ptr.toImageMsg());
01463         }
01464 }
01465 
01466 void CobFaceDetectionNodelet::trainContinuousCallback(const sensor_msgs::PointCloud2::ConstPtr& shared_image_msg, const sensor_msgs::Image::ConstPtr& color_image_msg)
01467 {
01468         if (train_continuous_server_running_ == false)
01469                 return;
01470 
01471         // convert input to cv::Mat images
01472         // color
01473         cv_bridge::CvImageConstPtr color_image_ptr;
01474         cv::Mat color_image;
01475         convertColorImageMessageToMat(color_image_msg, color_image_ptr, color_image);//color_image_ptr->image;
01476 
01477         // point cloud
01478         cv::Mat depth_image;
01479         convertPclMessageToMat(shared_image_msg, depth_image);
01480 
01481 #ifdef __LINUX__
01482         color_image_ = color_image;
01483         range_image_ = depth_image;
01484 #else
01485         // convert point cloud and color image to colored point cloud
01486         colored_pc_->SetColorImage(color_image);
01487         colored_pc_->SetXYZImage(depth_image);
01488 #endif
01489         //getMeasurement(shared_image_msg, color_image_msg);
01490 
01491         cv::Mat colorImage_8U3;
01492 #ifdef __LINUX__
01493         detectFaces(range_image_, color_image_);
01494         colorImage_8U3 = color_image_.clone();
01495 #else
01496         detectFaces(colored_pc_->GetXYZImage(), colored_pc_->GetColorImage());
01497         colored_pc_->GetColorImage().copyTo(colorImage_8U3);
01498 #endif
01499 
01500         for (int i = 0; i < (int)color_faces_.size(); i++)
01501         {
01502                 cv::Rect face = color_faces_[i];
01503                 cv::rectangle(colorImage_8U3, cv::Point(face.x, face.y), cv::Point(face.x + face.width, face.y + face.height), CV_RGB( 0, 255, 0 ), 2, 8, 0);
01504         }
01505 
01506         //cv::imshow("Face Recognizer Training", colorImage_8U3);
01507         //cv::waitKey(10);
01508         // publish topic
01509         cv_bridge::CvImage cv_ptr;
01510         cv_ptr.image = colorImage_8U3;
01511         cv_ptr.encoding = "bgr8";
01512         face_detection_image_pub_.publish(cv_ptr.toImageMsg());
01513 
01514         // capture image if triggered by an action
01515         // secure this section with a mutex
01516         boost::timed_mutex::scoped_timed_lock lock(action_mutex_, boost::posix_time::milliseconds(10));
01517         if (lock.owns_lock() && capture_training_face_ == true)
01518         {
01519                 capture_training_face_ = false;
01520 
01521                 // Check if there is more than one face detected
01522                 if (color_faces_.size() > 1)
01523                 {
01524                         std::cout << "WARNING - CobFaceDetectionNodelet::trainContinuousCallback:" << std::endl;
01525                         std::cout << "\t ... More than one faces are detected in image. Please try again." << std::endl;
01526                         return;
01527                 }
01528 
01529                 // Check if there is less than one face detected
01530                 if (color_faces_.size() < 1)
01531                 {
01532                         std::cout << "WARNING - CobFaceDetectionNodelet::trainContinuousCallback:" << std::endl;
01533                         std::cout << "\t ... Less than one faces are detected in image. Please try again." << std::endl;
01534                         return;
01535                 }
01536 
01537 #ifdef __LINUX__
01538                 addFace(color_image_, current_training_id_);
01539 #else
01540                 addFace(colored_pc_->GetColorImage(), current_training_id_);
01541 #endif
01542                 number_training_images_captured_++;
01543                 std::cout << "INFO - CuiPeopleDetector::ConsoleGUI:" << std::endl;
01544                 std::cout << "\t ... Face captured (" << face_images_.size() << ")." << std::endl;
01545         }
01546 }
01547 
01548 unsigned long CobFaceDetectionNodelet::loadParameters(const char* iniFileName)
01549 {
01551         TiXmlDocument* p_configXmlDocument = new TiXmlDocument(iniFileName);
01552         if (!p_configXmlDocument->LoadFile())
01553         {
01554                 std::cerr << "ERROR - PeopleDetector::LoadParameters:" << std::endl;
01555                 std::cerr << "\t ... Error while loading xml configuration file" << std::endl;
01556                 std::cerr << "\t ... (Check filename and syntax of the file):" << std::endl;
01557                 std::cerr << "\t ... '" << iniFileName << "'" << std::endl;
01558                 return ipa_Utils::RET_FAILED;
01559         }
01560         std::cout << "INFO - PeopleDetector::LoadParameters:" << std::endl;
01561         std::cout << "\t ... Parsing xml configuration file:" << std::endl;
01562         std::cout << "\t ... '" << iniFileName << "'" << std::endl;
01563 
01564         if (p_configXmlDocument)
01565         {
01566 
01567                 //************************************************************************************
01568                 //      BEGIN PeopleDetector
01569                 //************************************************************************************
01570                 // Tag element "PeopleDetector" of Xml Inifile
01571                 TiXmlElement *p_xmlElement_Root = NULL;
01572                 p_xmlElement_Root = p_configXmlDocument->FirstChildElement("PeopleDetector");
01573 
01574                 if (p_xmlElement_Root)
01575                 {
01576 
01577                         //************************************************************************************
01578                         //      BEGIN PeopleDetector->adaBoost
01579                         //************************************************************************************
01580                         // Tag element "adaBoost" of Xml Inifile
01581                         TiXmlElement *p_xmlElement_Root_OD = NULL;
01582                         p_xmlElement_Root_OD = p_xmlElement_Root->FirstChildElement("adaBoost");
01583 
01584                         if (p_xmlElement_Root_OD)
01585                         {
01586 
01587                                 //************************************************************************************
01588                                 //      BEGIN PeopleDetector->adaBoost->Faces_increase_search_scale
01589                                 //************************************************************************************
01590                                 // Subtag element "adaBoost" of Xml Inifile
01591                                 TiXmlElement *p_xmlElement_Child = NULL;
01592                                 p_xmlElement_Child = p_xmlElement_Root_OD->FirstChildElement("Faces_increase_search_scale");
01593 
01594                                 if (p_xmlElement_Child)
01595                                 {
01596                                         // read and save value of attribute
01597                                         if (p_xmlElement_Child->QueryValueAttribute("value", &people_detector_->m_faces_increase_search_scale) != TIXML_SUCCESS)
01598                                         {
01599                                                 std::cerr << "ERROR - PeopleDetector::LoadParameters:" << std::endl;
01600                                                 std::cerr << "\t ... Can't find attribute 'value' of tag 'Faces_increase_search_scale'" << std::endl;
01601                                                 return ipa_Utils::RET_FAILED;
01602                                         }
01603                                 }
01604                                 else
01605                                 {
01606                                         std::cerr << "ERROR - PeopleDetector::LoadParameters:" << std::endl;
01607                                         std::cerr << "\t ... Can't find tag 'Faces_increase_search_scale'" << std::endl;
01608                                         return ipa_Utils::RET_FAILED;
01609                                 }
01610 
01611                                 //************************************************************************************
01612                                 //      BEGIN PeopleDetector->adaBoost->Faces_drop_groups
01613                                 //************************************************************************************
01614                                 // Subtag element "adaBoost" of Xml Inifile
01615                                 p_xmlElement_Child = NULL;
01616                                 p_xmlElement_Child = p_xmlElement_Root_OD->FirstChildElement("Faces_drop_groups");
01617 
01618                                 if (p_xmlElement_Child)
01619                                 {
01620                                         // read and save value of attribute
01621                                         if (p_xmlElement_Child->QueryValueAttribute("value", &people_detector_->m_faces_drop_groups) != TIXML_SUCCESS)
01622                                         {
01623                                                 std::cerr << "ERROR - PeopleDetector::LoadParameters:" << std::endl;
01624                                                 std::cerr << "\t ... Can't find attribute 'value' of tag 'Faces_drop_groups'" << std::endl;
01625                                                 return ipa_Utils::RET_FAILED;
01626                                         }
01627                                 }
01628                                 else
01629                                 {
01630                                         std::cerr << "ERROR - PeopleDetector::LoadParameters:" << std::endl;
01631                                         std::cerr << "\t ... Can't find tag 'Faces_drop_groups'" << std::endl;
01632                                         return ipa_Utils::RET_FAILED;
01633                                 }
01634 
01635                                 //************************************************************************************
01636                                 //      BEGIN PeopleDetector->adaBoost->Faces_min_search_scale_x
01637                                 //************************************************************************************
01638                                 // Subtag element "adaBoost" of Xml Inifile
01639                                 p_xmlElement_Child = NULL;
01640                                 p_xmlElement_Child = p_xmlElement_Root_OD->FirstChildElement("Faces_min_search_scale_x");
01641 
01642                                 if (p_xmlElement_Child)
01643                                 {
01644                                         // read and save value of attribute
01645                                         if (p_xmlElement_Child->QueryValueAttribute("value", &people_detector_->m_faces_min_search_scale_x) != TIXML_SUCCESS)
01646                                         {
01647                                                 std::cerr << "ERROR - PeopleDetector::LoadParameters:" << std::endl;
01648                                                 std::cerr << "\t ... Can't find attribute 'value' of tag 'Faces_min_search_scale_x'" << std::endl;
01649                                                 return ipa_Utils::RET_FAILED;
01650                                         }
01651                                 }
01652                                 else
01653                                 {
01654                                         std::cerr << "ERROR - PeopleDetector::LoadParameters:" << std::endl;
01655                                         std::cerr << "\t ... Can't find tag 'Faces_min_search_scale_x'" << std::endl;
01656                                         return ipa_Utils::RET_FAILED;
01657                                 }
01658 
01659                                 //************************************************************************************
01660                                 //      BEGIN PeopleDetector->adaBoost->Faces_min_search_scale_y
01661                                 //************************************************************************************
01662                                 // Subtag element "adaBoost" of Xml Inifile
01663                                 p_xmlElement_Child = NULL;
01664                                 p_xmlElement_Child = p_xmlElement_Root_OD->FirstChildElement("Faces_min_search_scale_y");
01665 
01666                                 if (p_xmlElement_Child)
01667                                 {
01668                                         // read and save value of attribute
01669                                         if (p_xmlElement_Child->QueryValueAttribute("value", &people_detector_->m_faces_min_search_scale_y) != TIXML_SUCCESS)
01670                                         {
01671                                                 std::cerr << "ERROR - PeopleDetector::LoadParameters:" << std::endl;
01672                                                 std::cerr << "\t ... Can't find attribute 'value' of tag 'Faces_min_search_scale_y'" << std::endl;
01673                                                 return ipa_Utils::RET_FAILED;
01674                                         }
01675                                 }
01676                                 else
01677                                 {
01678                                         std::cerr << "ERROR - PeopleDetector::LoadParameters:" << std::endl;
01679                                         std::cerr << "\t ... Can't find tag 'Faces_min_search_scale_y'" << std::endl;
01680                                         return ipa_Utils::RET_FAILED;
01681                                 }
01682 
01683                                 //************************************************************************************
01684                                 //      BEGIN PeopleDetector->adaBoost->Range_increase_search_scale
01685                                 //************************************************************************************
01686                                 // Subtag element "adaBoost" of Xml Inifile
01687                                 p_xmlElement_Child = NULL;
01688                                 p_xmlElement_Child = p_xmlElement_Root_OD->FirstChildElement("Range_increase_search_scale");
01689 
01690                                 if (p_xmlElement_Child)
01691                                 {
01692                                         // read and save value of attribute
01693                                         if (p_xmlElement_Child->QueryValueAttribute("value", &people_detector_->m_range_increase_search_scale) != TIXML_SUCCESS)
01694                                         {
01695                                                 std::cerr << "ERROR - PeopleDetector::LoadParameters:" << std::endl;
01696                                                 std::cerr << "\t ... Can't find attribute 'value' of tag 'Range_increase_search_scale'" << std::endl;
01697                                                 return ipa_Utils::RET_FAILED;
01698                                         }
01699                                 }
01700                                 else
01701                                 {
01702                                         std::cerr << "ERROR - PeopleDetector::LoadParameters:" << std::endl;
01703                                         std::cerr << "\t ... Can't find tag 'Range_increase_search_scale'" << std::endl;
01704                                         return ipa_Utils::RET_FAILED;
01705                                 }
01706 
01707                                 //************************************************************************************
01708                                 //      BEGIN PeopleDetector->adaBoost->Range_drop_groups
01709                                 //************************************************************************************
01710                                 // Subtag element "adaBoost" of Xml Inifile
01711                                 p_xmlElement_Child = NULL;
01712                                 p_xmlElement_Child = p_xmlElement_Root_OD->FirstChildElement("Range_drop_groups");
01713 
01714                                 if (p_xmlElement_Child)
01715                                 {
01716                                         // read and save value of attribute
01717                                         if (p_xmlElement_Child->QueryValueAttribute("value", &people_detector_->m_range_drop_groups) != TIXML_SUCCESS)
01718                                         {
01719                                                 std::cerr << "ERROR - PeopleDetector::LoadParameters:" << std::endl;
01720                                                 std::cerr << "\t ... Can't find attribute 'value' of tag 'Range_drop_groups'" << std::endl;
01721                                                 return ipa_Utils::RET_FAILED;
01722                                         }
01723                                 }
01724                                 else
01725                                 {
01726                                         std::cerr << "ERROR - PeopleDetector::LoadParameters:" << std::endl;
01727                                         std::cerr << "\t ... Can't find tag 'Range_drop_groups'" << std::endl;
01728                                         return ipa_Utils::RET_FAILED;
01729                                 }
01730 
01731                                 //************************************************************************************
01732                                 //      BEGIN PeopleDetector->adaBoost->Range_min_search_scale_x
01733                                 //************************************************************************************
01734                                 // Subtag element "adaBoost" of Xml Inifile
01735                                 p_xmlElement_Child = NULL;
01736                                 p_xmlElement_Child = p_xmlElement_Root_OD->FirstChildElement("Range_min_search_scale_x");
01737 
01738                                 if (p_xmlElement_Child)
01739                                 {
01740                                         // read and save value of attribute
01741                                         if (p_xmlElement_Child->QueryValueAttribute("value", &people_detector_->m_range_min_search_scale_x) != TIXML_SUCCESS)
01742                                         {
01743                                                 std::cerr << "ERROR - PeopleDetector::LoadParameters:" << std::endl;
01744                                                 std::cerr << "\t ... Can't find attribute 'value' of tag 'Range_min_search_scale_x'" << std::endl;
01745                                                 return ipa_Utils::RET_FAILED;
01746                                         }
01747                                 }
01748                                 else
01749                                 {
01750                                         std::cerr << "ERROR - PeopleDetector::LoadParameters:" << std::endl;
01751                                         std::cerr << "\t ... Can't find tag 'Range_min_search_scale_x'" << std::endl;
01752                                         return ipa_Utils::RET_FAILED;
01753                                 }
01754 
01755                                 //************************************************************************************
01756                                 //      BEGIN PeopleDetector->adaBoost->Range_min_search_scale_y
01757                                 //************************************************************************************
01758                                 // Subtag element "adaBoost" of Xml Inifile
01759                                 p_xmlElement_Child = NULL;
01760                                 p_xmlElement_Child = p_xmlElement_Root_OD->FirstChildElement("Range_min_search_scale_y");
01761 
01762                                 if (p_xmlElement_Child)
01763                                 {
01764                                         // read and save value of attribute
01765                                         if (p_xmlElement_Child->QueryValueAttribute("value", &people_detector_->m_range_min_search_scale_y) != TIXML_SUCCESS)
01766                                         {
01767                                                 std::cerr << "ERROR - PeopleDetector::LoadParameters:" << std::endl;
01768                                                 std::cerr << "\t ... Can't find attribute 'value' of tag 'Range_min_search_scale_y'" << std::endl;
01769                                                 return ipa_Utils::RET_FAILED;
01770                                         }
01771                                 }
01772                                 else
01773                                 {
01774                                         std::cerr << "ERROR - PeopleDetector::LoadParameters:" << std::endl;
01775                                         std::cerr << "\t ... Can't find tag 'Range_min_search_scale_y'" << std::endl;
01776                                         return ipa_Utils::RET_FAILED;
01777                                 }
01778                         }
01779                         //************************************************************************************
01780                         //      END CameraDataViewerControlFlow->adaBoost
01781                         //************************************************************************************
01782 
01783                         //************************************************************************************
01784                         //      BEGIN PeopleDetector->eigenfaces
01785                         //************************************************************************************
01786                         // Tag element "adaBoost" of Xml Inifile
01787                         p_xmlElement_Root_OD = NULL;
01788                         p_xmlElement_Root_OD = p_xmlElement_Root->FirstChildElement("eigenfaces");
01789 
01790                         if (p_xmlElement_Root_OD)
01791                         {
01792 
01793                                 //************************************************************************************
01794                                 //      BEGIN PeopleDetector->eigenfaces->Threshold_Face_Class
01795                                 //************************************************************************************
01796                                 // Subtag element "adaBoost" of Xml Inifile
01797                                 TiXmlElement *p_xmlElement_Child = NULL;
01798                                 p_xmlElement_Child = p_xmlElement_Root_OD->FirstChildElement("Threshold_Face_Class");
01799 
01800                                 if (p_xmlElement_Child)
01801                                 {
01802                                         // read and save value of attribute
01803                                         if (p_xmlElement_Child->QueryValueAttribute("value", &threshold_) != TIXML_SUCCESS)
01804                                         {
01805                                                 std::cerr << "ERROR - PeopleDetector::LoadParameters:" << std::endl;
01806                                                 std::cerr << "\t ... Can't find attribute 'value' of tag 'Threshold_Face_Class'" << std::endl;
01807                                                 return ipa_Utils::RET_FAILED;
01808                                         }
01809                                 }
01810                                 else
01811                                 {
01812                                         std::cerr << "ERROR - PeopleDetector::LoadParameters:" << std::endl;
01813                                         std::cerr << "\t ... Can't find tag 'Threshold_Face_Class'" << std::endl;
01814                                         return ipa_Utils::RET_FAILED;
01815                                 }
01816                                 //************************************************************************************
01817                                 //      BEGIN PeopleDetector->eigenfaces->Threshold_Facespace
01818                                 //************************************************************************************
01819                                 // Subtag element "adaBoost" of Xml Inifile
01820                                 p_xmlElement_Child = NULL;
01821                                 p_xmlElement_Child = p_xmlElement_Root_OD->FirstChildElement("Threshold_Facespace");
01822 
01823                                 if (p_xmlElement_Child)
01824                                 {
01825                                         // read and save value of attribute
01826                                         if (p_xmlElement_Child->QueryValueAttribute("value", &threshold_fs_) != TIXML_SUCCESS)
01827                                         {
01828                                                 std::cerr << "ERROR - PeopleDetector::LoadParameters:" << std::endl;
01829                                                 std::cerr << "\t ... Can't find attribute 'value' of tag 'Threshold_Facespace'" << std::endl;
01830                                                 return ipa_Utils::RET_FAILED;
01831                                         }
01832                                 }
01833                                 else
01834                                 {
01835                                         std::cerr << "ERROR - PeopleDetector::LoadParameters:" << std::endl;
01836                                         std::cerr << "\t ... Can't find tag 'Threshold_Facespace'" << std::endl;
01837                                         return ipa_Utils::RET_FAILED;
01838                                 }
01839                                 //************************************************************************************
01840                                 //      END CameraDataViewerControlFlow->eigenfaces
01841                                 //************************************************************************************
01842 
01843                         }
01844                         else
01845                         {
01846                                 std::cerr << "ERROR - CameraDataViewerControlFlow::LoadParameters:" << std::endl;
01847                                 std::cerr << "\t ... Can't find tag 'ObjectDetectorParameters'" << std::endl;
01848                                 return ipa_Utils::RET_FAILED;
01849                         }
01850 
01851                 }
01852 
01853                 //************************************************************************************
01854                 //      END ObjectDetector
01855                 //************************************************************************************
01856                 else
01857                 {
01858                         std::cerr << "ERROR - CameraDataViewerControlFlow::LoadParameters:" << std::endl;
01859                         std::cerr << "\t ... Can't find tag 'ObjectDetector'" << std::endl;
01860                         return ipa_Utils::RET_FAILED;
01861                 }
01862         }
01863         return ipa_Utils::RET_OK;
01864 }
01865 
01866 //#######################
01867 //#### main programm ####
01868 //int main(int argc, char** argv)
01869 //{
01870 //      // Initialize ROS, specify name of node
01871 //      ros::init(argc, argv, "people_detection");
01872 //
01873 //      // Create a handle for this node, initialize node
01874 //      ros::NodeHandle nh;
01875 //
01876 //      // Create people detection node class instance
01877 //      CobFaceDetectionNodelet people_detection_node(nh);
01878 //
01879 //      // Initialize people detection node
01880 //      if (people_detection_node.init() != ipa_Utils::RET_OK)
01881 //              return 0;
01882 //
01883 //      // Create action nodes
01884 //      //DetectObjectsAction detect_action_node(object_detection_node, nh);
01885 //      //AcquireObjectImageAction acquire_image_node(object_detection_node, nh);
01886 //      //TrainObjectAction train_object_node(object_detection_node, nh);
01887 //
01888 //      ros::spin();
01889 //
01890 //      return 0;
01891 //}
01892 


cob_people_detection
Author(s): Richard Bormann , Thomas Zwölfer
autogenerated on Mon May 6 2019 02:32:06