face_recognizer.cpp
Go to the documentation of this file.
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 // stream
00070 #include <fstream>
00071 
00072 // opencv
00073 #include <opencv/cv.h>
00074 #include <opencv/cvaux.h>
00075 #include <opencv/highgui.h>
00076 
00077 // boost
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         // parameters
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         //std::string storage_directory="/share/goa-tz/people_detection/eval/KinectIPA/";
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         // load model
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         // parameters
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         //std::string storage_directory="/share/goa-tz/people_detection/eval/KinectIPA/";
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         // load model
00196         m_current_label_set.clear(); // keep empty to load all available data
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         // secure this function with a mutex
00206         boost::lock_guard<boost::mutex> lock(m_data_mutex);
00207 
00208         //cv::Rect combined_face_bounding_box=cv::Rect(face_bounding_box.x+head_bounding_box.x,face_bounding_box.y+head_bounding_box.y,face_bounding_box.width,face_bounding_box.height);
00209         //cv::Mat roi_color = color_image(combined_face_bounding_box);
00210         cv::Mat roi_color = color_image(face_bounding_box);     // color image has size of head area, not only face area
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         //if(!face_normalizer_.normalizeFace(roi_color,roi_depth_xyz,norm_size)) ;
00215         // this is probably obsolete:  face_normalizer_.recordFace(roi_color, roi_depth_xyz);
00216 
00217         if (!face_normalizer_.normalizeFace(roi_color, roi_depth_xyz, norm_size))
00218                 return ipa_Utils::RET_FAILED;
00219 
00220         // Save image
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         // secure this function with a mutex
00290         boost::lock_guard<boost::mutex> lock(m_data_mutex);
00291 
00292         // load necessary data
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         // secure this function with a mutex
00371         boost::lock_guard<boost::mutex>* lock = new boost::lock_guard<boost::mutex>(m_data_mutex);
00372 
00373         // check whether currently trained data set corresponds with intentification_labels_to_recognize
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                         // load model labels
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                         // A vector containing all different labels from the training session exactly once, order of appearance matters! (m_current_label_set[i] stores the corresponding name to the average face coordinates in the face subspace in m_face_class_average_projections.rows(i))
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                 // stored set differs from requested set -> recompute the model from training data
00453                 // release lock, trainRecognitionModel requests its own lock
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         // secure this function with a mutex
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                 //eff_color.projectToSubspace(resized_8U1,coeff_arr,DFFS);
00500 
00501                 if (m_debug)
00502                         std::cout << "distance to face space: " << DFFS << std::endl;
00503                 //TODO temporary turned off
00504                 if (0 == 1)
00505                 {
00506                         // no face
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         // secure this function with a mutex
00534         boost::lock_guard<boost::mutex> lock(m_data_mutex);
00535 
00536         //int number_eigenvectors = m_eigenvectors.size();
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         //cv::Size resized_size(m_eigenvectors[0].size());
00546         for (int i = 0; i < (int)face_coordinates.size(); i++)
00547         {
00548                 cv::Rect face = face_coordinates[i];
00549                 //convertAndResize(depth_image, resized_8U1, face, resized_size);
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         //cv::cvtColor(resized, resized, CV_BGR2GRAY);
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                 // store data
00614                 fileStorage << "number_entries" << (int)m_face_labels.size();
00615                 for (int i = 0; i < (int)m_face_labels.size(); i++)
00616                 {
00617                         // labels
00618                         std::ostringstream tag;
00619                         tag << "label_" << i;
00620                         fileStorage << tag.str().c_str() << m_face_labels[i].c_str();
00621 
00622                         // face images
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                 // store data
00662                 fileStorage << "number_entries" << (int)m_face_labels.size();
00663                 for (int i = 0; i < (int)m_face_labels.size(); i++)
00664                 {
00665                         // labels
00666                         std::ostringstream tag;
00667                         tag << "label_" << i;
00668                         fileStorage << tag.str().c_str() << m_face_labels[i].c_str();
00669 
00670                         // face images
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                                 // depth maps
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                 // labels
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                         // labels
00739                         std::ostringstream tag_label;
00740                         tag_label << "label_" << i;
00741                         std::string label = (std::string)fileStorage[tag_label.str().c_str()];
00742                         // look up this label in the list of unique labels identification_labels_to_train
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                         // if it does not appear in the list either append it (use all data option) or neglect this piece of data
00750                         if (class_exists == false)
00751                         {
00752                                 if (use_all_data == true)
00753                                 {
00754                                         // append this label to the list of labels
00755                                         identification_labels_to_train.push_back(label);
00756                                 }
00757                                 else
00758                                 {
00759                                         // skip this data because it does not contain one of the desired labels
00760                                         continue;
00761                                 }
00762                         }
00763                         m_face_labels.push_back(label);
00764 
00765                         // face images
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                         //face_normalizer_.normalizeFace(temp,norm_size);
00772                         face_images.push_back(temp);
00773                 }
00774 
00775                 // clean identification_labels_to_train -> only keep those labels that appear in the training data
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                 // set next free filename
00792                 // filename_ = number_face_images;
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                 // labels
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                         // labels
00835                         std::ostringstream tag_label;
00836                         tag_label << "label_" << i;
00837                         std::string label = (std::string)fileStorage[tag_label.str().c_str()];
00838                         // look up this label in the list of unique labels identification_labels_to_train
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                         // if it does not appear in the list either append it (use all data option) or neglect this piece of data
00846                         if (class_exists == false)
00847                         {
00848                                 if (use_all_data == true)
00849                                 {
00850                                         // append this label to the list of labels
00851                                         identification_labels_to_train.push_back(label);
00852                                 }
00853                                 else
00854                                 {
00855                                         // skip this data because it does not contain one of the desired labels
00856                                         continue;
00857                                 }
00858                         }
00859                         m_face_labels.push_back(label);
00860 
00861                         // face images
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                 // clean identification_labels_to_train -> only keep those labels that appear in the training data
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                 // set next free filename
00905                 // filename_ = number_face_images;
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 }


cob_people_detection
Author(s): Richard Bormann , Thomas Zwölfer
autogenerated on Fri Aug 28 2015 10:24:12