00001
00061 #ifdef __LINUX__
00062 #include "cob_people_detection/face_recognizer.h"
00063 #include "cob_vision_utils/GlobalDefines.h"
00064 #else
00065 #include "cob_vision/cob_people_detection/common/include/cob_people_detection/PeopleDetector.h"
00066 #include "cob_common/cob_vision_utils/common/include/cob_vision_utils/GlobalDefines.h"
00067 #endif
00068
00069
00070 #include <fstream>
00071
00072
00073 #include <opencv/cv.h>
00074 #include <opencv/cvaux.h>
00075 #include <opencv/highgui.h>
00076
00077
00078 #include "boost/filesystem/operations.hpp"
00079 #include "boost/filesystem/convenience.hpp"
00080
00081 #include <sys/time.h>
00082
00083 namespace fs = boost::filesystem;
00084 using namespace ipa_PeopleDetector;
00085
00086 ipa_PeopleDetector::FaceRecognizer::FaceRecognizer(void)
00087 {
00088 m_eigenvectors_ipl = 0;
00089
00090 }
00091
00092 ipa_PeopleDetector::FaceRecognizer::~FaceRecognizer(void)
00093 {
00094 if (m_eigenvectors_ipl != 0)
00095 {
00096 for (uint i=0; i<m_eigenvectors.size(); i++)
00097 cvReleaseImage(&(m_eigenvectors_ipl[i]));
00098 cvFree(&m_eigenvectors_ipl);
00099 }
00100 }
00101
00102 unsigned long ipa_PeopleDetector::FaceRecognizer::init(std::string data_directory, int norm_size, bool norm_illumination, bool norm_align, bool norm_extreme_illumination,
00103 int metric, bool debug, std::vector<std::string>& identification_labels_to_recognize, int subs_meth, int feature_dim, bool use_unknown_thresh, bool use_depth)
00104 {
00105
00106 m_data_directory = boost::filesystem::path(data_directory);
00107 m_data_directory /= "training_data";
00108 assertDirectories(m_data_directory);
00109
00110 m_norm_size = norm_size;
00111 m_metric = metric;
00112 m_debug = debug;
00113 m_depth_mode = use_depth;
00114 m_use_unknown_thresh = use_unknown_thresh;
00115
00116 m_feature_dim = feature_dim;
00117
00118 switch(subs_meth)
00119 {
00120 case 0:
00121 {
00122 m_subs_meth = ipa_PeopleDetector::METH_FISHER;
00123 eff_color = new ipa_PeopleDetector::FaceRecognizer_Fisherfaces();
00124 break;
00125 }
00126 case 1:
00127 {
00128 m_subs_meth = ipa_PeopleDetector::METH_EIGEN;
00129 eff_color = new ipa_PeopleDetector::FaceRecognizer_Eigenfaces();
00130 break;
00131 }
00132 case 2:
00133 {
00134 m_subs_meth = ipa_PeopleDetector::METH_LDA2D;
00135 eff_color = new ipa_PeopleDetector::FaceRecognizer_LDA2D();
00136 break;
00137 }
00138 case 3:
00139 {
00140 m_subs_meth = ipa_PeopleDetector::METH_PCA2D;
00141 eff_color = new ipa_PeopleDetector::FaceRecognizer_PCA2D();
00142 break;
00143 }
00144 default:
00145 {
00146 m_subs_meth = ipa_PeopleDetector::METH_FISHER;
00147 eff_color = new ipa_PeopleDetector::FaceRecognizer_Fisherfaces();
00148 break;
00149 }
00150 };
00151
00152 FaceNormalizer::FNConfig fn_cfg;
00153 fn_cfg.eq_ill = norm_illumination;
00154 fn_cfg.align = norm_align;
00155 fn_cfg.resize = true;
00156 fn_cfg.cvt2gray = true;
00157 fn_cfg.extreme_illumination_condtions = norm_extreme_illumination;
00158
00159 std::string classifier_directory = data_directory + "haarcascades/";
00160
00161 std::string storage_directory = "/share/goa-tz/people_detection/eval/KinectIPA/";
00162 face_normalizer_.init(classifier_directory, storage_directory, fn_cfg, 0, false, false);
00163
00164
00165 unsigned long return_value = loadRecognitionModel(identification_labels_to_recognize);
00166 if (return_value == ipa_Utils::RET_FAILED)
00167 {
00168 return ipa_Utils::RET_FAILED;
00169 }
00170 return ipa_Utils::RET_OK;
00171 }
00172
00173 unsigned long ipa_PeopleDetector::FaceRecognizer::initTraining(std::string data_directory, int norm_size, bool norm_illumination, bool norm_align, bool norm_extreme_illumination,
00174 bool debug, std::vector<cv::Mat>& face_images, std::vector<cv::Mat>& face_depthmaps, bool use_depth)
00175 {
00176
00177 m_data_directory = boost::filesystem::path(data_directory);
00178 m_data_directory /= "training_data";
00179 assertDirectories(m_data_directory);
00180 m_norm_size = norm_size;
00181 m_debug = debug;
00182 m_depth_mode = use_depth;
00183
00184 FaceNormalizer::FNConfig fn_cfg;
00185 fn_cfg.eq_ill = norm_illumination;
00186 fn_cfg.align = norm_align;
00187 fn_cfg.resize = true;
00188 fn_cfg.cvt2gray = true;
00189 fn_cfg.extreme_illumination_condtions = norm_extreme_illumination;
00190
00191 std::string classifier_directory = data_directory + "haarcascades/";
00192
00193 std::string storage_directory = "/share/goa-tz/people_detection/eval/KinectIPA/";
00194 face_normalizer_.init(classifier_directory, storage_directory, fn_cfg, 0, false, false);
00195
00196 m_current_label_set.clear();
00197 loadTrainingData(face_images, m_current_label_set);
00198
00199 return ipa_Utils::RET_OK;
00200 }
00201
00202 unsigned long ipa_PeopleDetector::FaceRecognizer::addFace(cv::Mat& color_image, cv::Mat& depth_image, cv::Rect& face_bounding_box, cv::Rect& head_bounding_box, std::string label,
00203 std::vector<cv::Mat>& face_images, std::vector<cv::Mat>& face_depthmaps)
00204 {
00205
00206 boost::lock_guard<boost::mutex> lock(m_data_mutex);
00207
00208
00209
00210 cv::Mat roi_color = color_image(face_bounding_box);
00211 cv::Mat roi_depth_xyz = depth_image(face_bounding_box).clone();
00212 cv::Size norm_size = cv::Size(m_norm_size, m_norm_size);
00213 cv::Mat roi_depth;
00214
00215
00216
00217 if (!face_normalizer_.normalizeFace(roi_color, roi_depth_xyz, norm_size))
00218 return ipa_Utils::RET_FAILED;
00219
00220
00221 face_images.push_back(roi_color);
00222 face_depthmaps.push_back(roi_depth_xyz);
00223 m_face_labels.push_back(label);
00224 dm_exist.push_back(true);
00225
00226 return ipa_Utils::RET_OK;
00227
00228 }
00229
00230 unsigned long ipa_PeopleDetector::FaceRecognizer::updateFaceLabels(std::string old_label, std::string new_label)
00231 {
00232 for (int i=0; i<(int)m_face_labels.size(); i++)
00233 {
00234 if (m_face_labels[i].compare(old_label) == 0)
00235 m_face_labels[i] = new_label;
00236 }
00237 return ipa_Utils::RET_OK;
00238 }
00239
00240 unsigned long ipa_PeopleDetector::FaceRecognizer::updateFaceLabel(int index, std::string new_label)
00241 {
00242 m_face_labels[index] = new_label;
00243 return ipa_Utils::RET_OK;
00244 }
00245
00246 unsigned long ipa_PeopleDetector::FaceRecognizer::deleteFaces(std::string label, std::vector<cv::Mat>& face_images, std::vector<cv::Mat>& face_depthmaps)
00247 {
00248 for (int i=0; i<(int)m_face_labels.size(); i++)
00249 {
00250 if (m_face_labels[i].compare(label) == 0)
00251 {
00252 m_face_labels.erase(m_face_labels.begin() + i);
00253 face_images.erase(face_images.begin() + i);
00254 i--;
00255 }
00256 }
00257 return ipa_Utils::RET_OK;
00258 }
00259
00260 unsigned long ipa_PeopleDetector::FaceRecognizer::deleteFace(int index, std::vector<cv::Mat>& face_images, std::vector<cv::Mat>& face_depthmaps)
00261 {
00262 m_face_labels.erase(m_face_labels.begin() + index);
00263 face_images.erase(face_images.begin() + index);
00264 return ipa_Utils::RET_OK;
00265 }
00266
00267 unsigned long ipa_PeopleDetector::FaceRecognizer::trainFaceRecognition(ipa_PeopleDetector::FaceRecognizerBaseClass* eff, std::vector<cv::Mat>& data, std::vector<int>& labels)
00268 {
00269
00270 std::vector<cv::Mat> in_vec;
00271 for (unsigned int i = 0; i < data.size(); i++)
00272 {
00273 cv::Mat temp = data[i];
00274 temp.convertTo(temp, CV_64FC1);
00275 in_vec.push_back(temp);
00276 }
00277
00278 if (!eff->trainModel(in_vec, labels, m_feature_dim))
00279 {
00280 std::cout << "[FACEREC] Reognition module could not be initialized !" << std::endl;
00281 return ipa_Utils::RET_FAILED;
00282 }
00283
00284 return ipa_Utils::RET_OK;
00285 }
00286
00287 unsigned long ipa_PeopleDetector::FaceRecognizer::trainRecognitionModel(std::vector<std::string>& identification_labels_to_train)
00288 {
00289
00290 boost::lock_guard<boost::mutex> lock(m_data_mutex);
00291
00292
00293
00294 std::vector<cv::Mat> face_images;
00295 loadTrainingData(face_images, identification_labels_to_train);
00296
00297 m_current_label_set = identification_labels_to_train;
00298
00299 m_label_num.clear();
00300 for (unsigned int li = 0; li < m_face_labels.size(); li++)
00301 {
00302 for (unsigned int lj = 0; lj < identification_labels_to_train.size(); lj++)
00303 {
00304 if (identification_labels_to_train[lj].compare(m_face_labels[li]) == 0)
00305 m_label_num.push_back(lj);
00306 }
00307 }
00308
00309 boost::filesystem::path path = m_data_directory;
00310 boost::filesystem::path path_color = path / "rdata_color.xml";
00311
00312 unsigned long trained;
00313 if (face_images.size() > 0)
00314 {
00315 trained = trainFaceRecognition(eff_color, face_images, m_label_num);
00316 }
00317
00318 saveRecognitionModel();
00319 return trained;
00320
00321 }
00322
00323 unsigned long ipa_PeopleDetector::FaceRecognizer::saveRecognitionModel()
00324 {
00325 boost::filesystem::path path = m_data_directory;
00326 boost::filesystem::path complete = path / "rdata_color.xml";
00327
00328 if (fs::is_directory(path.string()))
00329 {
00330 if (fs::is_regular_file(complete.string()))
00331 {
00332 if (fs::remove(complete.string()) == false)
00333 {
00334 std::cout << "Error: FaceRecognizer::saveRecognitionModel: Cannot remove old recognizer data.\n" << std::endl;
00335 return ipa_Utils::RET_FAILED;
00336 }
00337 }
00338 eff_color->saveModel(complete);
00339
00340 std::cout << "OPENING at " << complete.string() << std::endl;
00341 cv::FileStorage fileStorage(complete.string(), cv::FileStorage::APPEND);
00342 if (!fileStorage.isOpened())
00343 {
00344 std::cout << "Error: FaceRecognizer::saveRecognitionModel: Can't save training data.\n" << std::endl;
00345 return ipa_Utils::RET_FAILED;
00346 }
00347
00348 fileStorage << "string_labels" << "[";
00349 for (int i = 0; i < m_face_labels.size(); i++)
00350 {
00351 fileStorage << m_face_labels[i];
00352 }
00353 fileStorage << "]";
00354
00355 fileStorage.release();
00356
00357 std::cout << "INFO: FaceRecognizer::saveRecognitionModel: recognizer data saved.\n" << std::endl;
00358 }
00359 else
00360 {
00361 std::cerr << "Error: FaceRecognizer::saveRecognitionModel: Path '" << path << "' is not a directory." << std::endl;
00362 return ipa_Utils::RET_FAILED;
00363 }
00364
00365 return ipa_Utils::RET_OK;
00366 }
00367
00368 unsigned long ipa_PeopleDetector::FaceRecognizer::loadRecognitionModel(std::vector<std::string>& identification_labels_to_recognize)
00369 {
00370
00371 boost::lock_guard<boost::mutex>* lock = new boost::lock_guard<boost::mutex>(m_data_mutex);
00372
00373
00374 boost::filesystem::path path = m_data_directory;
00375 boost::filesystem::path complete = path / "rdata_color.xml";
00376
00377 bool training_necessary = false;
00378 std::vector<string> temp_face_labels;
00379 if (fs::is_directory(path.string()))
00380 {
00381 cv::FileStorage fileStorage(complete.string(), cv::FileStorage::READ);
00382 if (!fileStorage.isOpened())
00383 {
00384 std::cout << "Info: FaceRecognizer::loadRecognitionModel: Can't open " << complete.string() << ".\n" << std::endl;
00385 training_necessary = true;
00386 }
00387 else
00388 {
00389
00390 cv::FileNode fn = fileStorage["string_labels"];
00391 cv::FileNodeIterator it = fn.begin(), it_end = fn.end();
00392 int idx = 0;
00393 m_current_label_set.clear();
00394 for (; it != it_end; ++it, idx++)
00395 {
00396 temp_face_labels.push_back(*it);
00397 bool new_label = true;
00398 if (idx > 0)
00399 {
00400 for (int i = 0; i < m_current_label_set.size(); i++)
00401 {
00402 if (m_current_label_set[i].compare(*it) == 0)
00403 new_label = false;
00404 }
00405 }
00406 if (new_label)
00407 m_current_label_set.push_back(*it);
00408 }
00409
00410
00411 bool same_data_set = true;
00412 if (identification_labels_to_recognize.size() == 0 || m_current_label_set.size() != identification_labels_to_recognize.size())
00413 {
00414 same_data_set = false;
00415 }
00416 else
00417 {
00418 for (uint i = 0; i < identification_labels_to_recognize.size(); i++)
00419 {
00420 if (identification_labels_to_recognize[i].compare(m_current_label_set[i]) != 0)
00421 {
00422 same_data_set = false;
00423 break;
00424 }
00425 }
00426 }
00427
00428 if (same_data_set == true)
00429 {
00430 eff_color->loadModel(complete);
00431 m_face_labels = temp_face_labels;
00432 std::cout << "INFO: FaceRecognizer::loadRecognitionModel: recognizer data loaded.\n" << std::endl;
00433 }
00434 else
00435 {
00436 training_necessary = true;
00437 }
00438
00439 fileStorage.release();
00440 delete lock;
00441 lock = 0;
00442 }
00443 }
00444 else
00445 {
00446 std::cerr << "Error: FaceRecognizer::loadRecognizerData: Path '" << path.string() << "' is not a directory." << std::endl;
00447 return ipa_Utils::RET_FAILED;
00448 }
00449
00450 if (training_necessary == true)
00451 {
00452
00453
00454 if (lock != 0)
00455 delete lock;
00456
00457 unsigned long return_value = trainRecognitionModel(identification_labels_to_recognize);
00458 if (return_value == ipa_Utils::RET_FAILED)
00459 return ipa_Utils::RET_FAILED;
00460
00461 }
00462
00463 if (m_debug == true)
00464 {
00465 std::cout << "Current model set:" << std::endl;
00466 for (int i = 0; i < (int)m_current_label_set.size(); i++)
00467 std::cout << " - " << m_current_label_set[i] << std::endl;
00468 std::cout << std::endl;
00469 }
00470
00471 return ipa_Utils::RET_OK;
00472 }
00473
00474 unsigned long ipa_PeopleDetector::FaceRecognizer::recognizeFace(cv::Mat& color_image, std::vector<cv::Rect>& face_coordinates, std::vector<std::string>& identification_labels)
00475 {
00476
00477 boost::lock_guard<boost::mutex> lock(m_data_mutex);
00478
00479 if (eff_color->trained_ == false)
00480 {
00481 std::cout << "Error: FaceRecognizer::recognizeFace: Load or train some identification model, first.\n" << std::endl;
00482 return ipa_Utils::RET_FAILED;
00483 }
00484
00485 identification_labels.clear();
00486
00487 cv::Mat resized_8U1;
00488 cv::Size resized_size(m_eigenvectors[0].size());
00489 for (int i = 0; i < (int)face_coordinates.size(); i++)
00490 {
00491 cv::Rect face = face_coordinates[i];
00492 cv::Size norm_size = cv::Size(m_norm_size, m_norm_size);
00493 convertAndResize(color_image, resized_8U1, face, norm_size);
00494
00495 double DFFS;
00496 resized_8U1.convertTo(resized_8U1, CV_64FC1);
00497
00498 cv::Mat coeff_arr;
00499
00500
00501 if (m_debug)
00502 std::cout << "distance to face space: " << DFFS << std::endl;
00503
00504 if (0 == 1)
00505 {
00506
00507 identification_labels.push_back("No face");
00508 }
00509 else
00510 {
00511
00512 int res_label;
00513 eff_color->classifyImage(resized_8U1, res_label);
00514 if (res_label == -1)
00515 {
00516 identification_labels.push_back("Unknown Face");
00517 }
00518 else
00519 {
00520 identification_labels.push_back(m_current_label_set[res_label]);
00521 }
00522 }
00523 }
00524
00525 return ipa_Utils::RET_OK;
00526 }
00527
00528 unsigned long ipa_PeopleDetector::FaceRecognizer::recognizeFace(cv::Mat& color_image, cv::Mat& depth_image, std::vector<cv::Rect>& face_coordinates,
00529 std::vector<std::string>& identification_labels)
00530 {
00531 timeval t1, t2;
00532 gettimeofday(&t1, NULL);
00533
00534 boost::lock_guard<boost::mutex> lock(m_data_mutex);
00535
00536
00537 if (eff_color->trained_ == false)
00538 {
00539 std::cout << "Error: FaceRecognizer::recognizeFace: Load or train some identification model, first.\n" << std::endl;
00540 return ipa_Utils::RET_FAILED;
00541 }
00542
00543 identification_labels.clear();
00544
00545
00546 for (int i = 0; i < (int)face_coordinates.size(); i++)
00547 {
00548 cv::Rect face = face_coordinates[i];
00549
00550 cv::Mat color_crop = color_image(face);
00551 cv::Mat depth_crop_xyz = depth_image(face);
00552
00553 cv::Mat DM_crop = cv::Mat::zeros(m_norm_size, m_norm_size, CV_8UC1);
00554 cv::Size norm_size = cv::Size(m_norm_size, m_norm_size);
00555 if (face_normalizer_.normalizeFace(color_crop, depth_crop_xyz, norm_size, DM_crop))
00556 ;
00557
00558 double DFFS;
00559 cv::Mat temp;
00560 color_crop.convertTo(color_crop, CV_64FC1);
00561
00562 int res_label_color, res_label_depth;
00563 std::string class_color;
00564
00565 if (eff_color->trained_)
00566 {
00567 eff_color->classifyImage(color_crop, res_label_color);
00568 if (res_label_color == -1)
00569 {
00570 class_color = "Unknown";
00571 }
00572 else
00573 {
00574 class_color = m_current_label_set[res_label_color];
00575 }
00576 }
00577
00578 identification_labels.push_back(class_color);
00579 }
00580
00581 gettimeofday(&t2, NULL);
00582 if (m_debug)
00583 std::cout << "time =" << (t2.tv_usec - t1.tv_usec) / 1000.0 << std::endl;
00584
00585 return ipa_Utils::RET_OK;
00586 }
00587
00588 unsigned long ipa_PeopleDetector::FaceRecognizer::convertAndResize(cv::Mat& img, cv::Mat& resized, cv::Rect& face, cv::Size new_size)
00589 {
00590 resized = img(face);
00591 cv::resize(resized, resized, new_size);
00592
00593
00594
00595 return ipa_Utils::RET_OK;
00596 }
00597
00598 unsigned long ipa_PeopleDetector::FaceRecognizer::saveTrainingData(std::vector<cv::Mat>& face_images)
00599 {
00600 boost::filesystem::path path = m_data_directory;
00601 boost::filesystem::path complete = path / "tdata.xml";
00602 std::string img_ext = ".bmp";
00603
00604 if (fs::is_directory(complete))
00605 {
00606 cv::FileStorage fileStorage(complete.string(), cv::FileStorage::WRITE);
00607 if (!fileStorage.isOpened())
00608 {
00609 std::cout << "Error: FaceRecognizer::saveTrainingData: Can't save training data.\n" << std::endl;
00610 return ipa_Utils::RET_FAILED;
00611 }
00612
00613
00614 fileStorage << "number_entries" << (int)m_face_labels.size();
00615 for (int i = 0; i < (int)m_face_labels.size(); i++)
00616 {
00617
00618 std::ostringstream tag;
00619 tag << "label_" << i;
00620 fileStorage << tag.str().c_str() << m_face_labels[i].c_str();
00621
00622
00623 boost::filesystem::path img_path = path / "img" / (boost::lexical_cast<string>(i) + img_ext);
00624 std::ostringstream img, shortname;
00625 shortname << "img/" << i << img_ext;
00626 std::ostringstream tag2;
00627 tag2 << "image_" << i;
00628 fileStorage << tag2.str().c_str() << shortname.str().c_str();
00629 cv::imwrite(img_path.string(), face_images[i]);
00630 }
00631
00632 fileStorage.release();
00633
00634 std::cout << "INFO: FaceRecognizer::saveTrainingData: " << face_images.size() << " color images saved.\n" << std::endl;
00635 }
00636 else
00637 {
00638 std::cerr << "Error: FaceRecognizer::saveTrainingData: Path '" << path << "' is not a directory." << std::endl;
00639 return ipa_Utils::RET_FAILED;
00640 }
00641
00642 return ipa_Utils::RET_OK;
00643 }
00644
00645 unsigned long ipa_PeopleDetector::FaceRecognizer::saveTrainingData(std::vector<cv::Mat>& face_images, std::vector<cv::Mat>& face_depthmaps)
00646 {
00647 boost::filesystem::path path = m_data_directory;
00648 boost::filesystem::path complete = path / "tdata.xml";
00649 std::string img_ext = ".bmp";
00650 std::string dm_ext = ".xml";
00651
00652 if (fs::is_directory(path.string()))
00653 {
00654 cv::FileStorage fileStorage(complete.string(), cv::FileStorage::WRITE);
00655 if (!fileStorage.isOpened())
00656 {
00657 std::cout << "Error: FaceRecognizer::saveTrainingData: Can't save training data.\n" << std::endl;
00658 return ipa_Utils::RET_FAILED;
00659 }
00660
00661
00662 fileStorage << "number_entries" << (int)m_face_labels.size();
00663 for (int i = 0; i < (int)m_face_labels.size(); i++)
00664 {
00665
00666 std::ostringstream tag;
00667 tag << "label_" << i;
00668 fileStorage << tag.str().c_str() << m_face_labels[i].c_str();
00669
00670
00671 boost::filesystem::path img_path = path / "img" / (boost::lexical_cast<string>(i) + img_ext);
00672 std::ostringstream img, shortname_img, shortname_depth;
00673 shortname_img << "img/" << i << img_ext;
00674 std::ostringstream tag2, tag3;
00675 tag2 << "image_" << i;
00676 fileStorage << tag2.str().c_str() << shortname_img.str().c_str();
00677
00678 if (dm_exist[i])
00679 {
00680 shortname_depth << "depth/" << i << dm_ext;
00681 tag3 << "depthmap_" << i;
00682 fileStorage << tag3.str().c_str() << shortname_depth.str().c_str();
00683 }
00684 cv::imwrite(img_path.string(), face_images[i]);
00685 }
00686
00687 fileStorage.release();
00688
00689 int j = 0;
00690 for (unsigned int i = 0; i < dm_exist.size(); i++)
00691 {
00692 if (dm_exist[i])
00693 {
00694
00695 boost::filesystem::path dm_path = path / "depth" / (boost::lexical_cast<string>(i) + ".xml");
00696 cv::FileStorage fs(dm_path.string(), FileStorage::WRITE);
00697 fs << "depthmap" << face_depthmaps[j];
00698 fs.release();
00699 j++;
00700 }
00701 }
00702 std::cout << "INFO: FaceRecognizer::saveTrainingData: " << face_images.size() << " color images and " << face_depthmaps.size() << " depth images saved.\n" << std::endl;
00703 }
00704 else
00705 {
00706 std::cerr << "Error: FaceRecognizer::saveTrainingData: Path '" << path << "' is not a directory." << std::endl;
00707 return ipa_Utils::RET_FAILED;
00708 }
00709
00710 return ipa_Utils::RET_OK;
00711 }
00712
00713 unsigned long ipa_PeopleDetector::FaceRecognizer::loadTrainingData(std::vector<cv::Mat>& face_images, std::vector<std::string>& identification_labels_to_train)
00714 {
00715 bool use_all_data = false;
00716 if (identification_labels_to_train.size() == 0)
00717 use_all_data = true;
00718
00719 boost::filesystem::path path = m_data_directory;
00720 boost::filesystem::path complete = path / "tdata.xml";
00721
00722 if (fs::is_directory(path.string()))
00723 {
00724 cv::FileStorage fileStorage(complete.string(), cv::FileStorage::READ);
00725 if (!fileStorage.isOpened())
00726 {
00727 std::cout << "Error: FaceRecognizer::loadTrainingData: Can't open " << complete.string() << ".\n" << std::endl;
00728 return ipa_Utils::RET_OK;
00729 }
00730
00731
00732 m_face_labels.clear();
00733 face_images.clear();
00734 cv::Size norm_size = cv::Size(m_norm_size, m_norm_size);
00735 int number_entries = (int)fileStorage["number_entries"];
00736 for (int i = 0; i < number_entries; i++)
00737 {
00738
00739 std::ostringstream tag_label;
00740 tag_label << "label_" << i;
00741 std::string label = (std::string)fileStorage[tag_label.str().c_str()];
00742
00743 bool class_exists = false;
00744 for (int j = 0; j < (int)identification_labels_to_train.size(); j++)
00745 {
00746 if (!identification_labels_to_train[j].compare(label))
00747 class_exists = true;
00748 }
00749
00750 if (class_exists == false)
00751 {
00752 if (use_all_data == true)
00753 {
00754
00755 identification_labels_to_train.push_back(label);
00756 }
00757 else
00758 {
00759
00760 continue;
00761 }
00762 }
00763 m_face_labels.push_back(label);
00764
00765
00766 std::ostringstream tag_image;
00767 tag_image << "image_" << i;
00768 boost::filesystem::path path = m_data_directory / (std::string)fileStorage[tag_image.str().c_str()];
00769 cv::Mat temp = cv::imread(path.string(), -1);
00770 cv::resize(temp, temp, cv::Size(m_norm_size, m_norm_size));
00771
00772 face_images.push_back(temp);
00773 }
00774
00775
00776 for (int j = 0; j < (int)identification_labels_to_train.size(); j++)
00777 {
00778 bool class_exists = false;
00779 for (int k = 0; k < (int)m_face_labels.size(); k++)
00780 {
00781 if (identification_labels_to_train[j].compare(m_face_labels[k]) == 0)
00782 class_exists = true;
00783 }
00784 if (class_exists == false)
00785 {
00786 identification_labels_to_train.erase(identification_labels_to_train.begin() + j);
00787 j--;
00788 }
00789 }
00790
00791
00792
00793
00794 fileStorage.release();
00795
00796 std::cout << "INFO: FaceRecognizer::loadTrainingData: " << number_entries << " color images loaded.\n" << std::endl;
00797 }
00798 else
00799 {
00800 std::cerr << "Error: FaceRecognizer::loadTrainingData: Path '" << path << "' is not a directory." << std::endl;
00801 return ipa_Utils::RET_FAILED;
00802 }
00803
00804 return ipa_Utils::RET_OK;
00805 }
00806
00807 unsigned long ipa_PeopleDetector::FaceRecognizer::loadTrainingData(std::vector<cv::Mat>& face_images, std::vector<cv::Mat>& face_depthmaps,
00808 std::vector<std::string>& identification_labels_to_train)
00809 {
00810 bool use_all_data = false;
00811 dm_exist.clear();
00812 if (identification_labels_to_train.size() == 0)
00813 use_all_data = true;
00814
00815 boost::filesystem::path path = m_data_directory;
00816 boost::filesystem::path complete = path / "tdata.xml";
00817
00818 if (fs::is_directory(path.string()))
00819 {
00820 cv::FileStorage fileStorage(complete.string(), cv::FileStorage::READ);
00821 if (!fileStorage.isOpened())
00822 {
00823 std::cout << "Error: FaceRecognizer::loadTrainingData: Can't open " << complete.string() << ".\n" << std::endl;
00824 return ipa_Utils::RET_OK;
00825 }
00826
00827
00828 m_face_labels.clear();
00829 face_images.clear();
00830 cv::Size norm_size = cv::Size(m_norm_size, m_norm_size);
00831 int number_entries = (int)fileStorage["number_entries"];
00832 for (int i = 0; i < number_entries; i++)
00833 {
00834
00835 std::ostringstream tag_label;
00836 tag_label << "label_" << i;
00837 std::string label = (std::string)fileStorage[tag_label.str().c_str()];
00838
00839 bool class_exists = false;
00840 for (int j = 0; j < (int)identification_labels_to_train.size(); j++)
00841 {
00842 if (!identification_labels_to_train[j].compare(label))
00843 class_exists = true;
00844 }
00845
00846 if (class_exists == false)
00847 {
00848 if (use_all_data == true)
00849 {
00850
00851 identification_labels_to_train.push_back(label);
00852 }
00853 else
00854 {
00855
00856 continue;
00857 }
00858 }
00859 m_face_labels.push_back(label);
00860
00861
00862 std::ostringstream tag_image, tag_dm;
00863 tag_image << "image_" << i;
00864 tag_dm << "depthmap_" << i;
00865 boost::filesystem::path img_path = m_data_directory / (std::string)fileStorage[tag_image.str().c_str()];
00866 boost::filesystem::path dm_path = m_data_directory / (std::string)fileStorage[tag_dm.str().c_str()];
00867 cv::Mat temp = cv::imread(img_path.string(), -1);
00868
00869 if (dm_path.string().compare(m_data_directory.string()))
00870 {
00871 cv::Mat xyz_temp, dm_temp;
00872 cv::FileStorage fs(dm_path.string(), FileStorage::READ);
00873 fs["depthmap"] >> xyz_temp;
00874 face_normalizer_.normalizeFace(temp, xyz_temp, norm_size, dm_temp);
00875 face_depthmaps.push_back(dm_temp);
00876 dm_exist.push_back(true);
00877 fs.release();
00878 }
00879 else
00880 {
00881 dm_exist.push_back(false);
00882 }
00883
00884 cv::resize(temp, temp, cv::Size(m_norm_size, m_norm_size));
00885 face_images.push_back(temp);
00886 }
00887
00888
00889 for (int j = 0; j < (int)identification_labels_to_train.size(); j++)
00890 {
00891 bool class_exists = false;
00892 for (int k = 0; k < (int)m_face_labels.size(); k++)
00893 {
00894 if (identification_labels_to_train[j].compare(m_face_labels[k]) == 0)
00895 class_exists = true;
00896 }
00897 if (class_exists == false)
00898 {
00899 identification_labels_to_train.erase(identification_labels_to_train.begin() + j);
00900 j--;
00901 }
00902 }
00903
00904
00905
00906
00907 fileStorage.release();
00908
00909 std::cout << "INFO: FaceRecognizer::loadTrainingData: " << number_entries << " images loaded (" << face_images.size() << " color images and " << face_depthmaps.size() << " depth images).\n" << std::endl;
00910 }
00911 else
00912 {
00913 std::cerr << "Error: FaceRecognizer::loadTrainingData: Path '" << path << "' is not a directory." << std::endl;
00914 return ipa_Utils::RET_FAILED;
00915 }
00916
00917 return ipa_Utils::RET_OK;
00918 }
00919 void ipa_PeopleDetector::FaceRecognizer::assertDirectories(boost::filesystem::path& data_directory)
00920 {
00921
00922 if (!boost::filesystem::exists(data_directory))
00923 boost::filesystem::create_directories(data_directory);
00924 if (!boost::filesystem::exists(data_directory / "depth"))
00925 boost::filesystem::create_directories(data_directory / "depth");
00926 if (!boost::filesystem::exists(data_directory / "img"))
00927 boost::filesystem::create_directories(data_directory / "img");
00928 }