From 64d8cf1e2e09bb0a51bcccaffce5bb7723791404 Mon Sep 17 00:00:00 2001 From: Andrey Pavlenko Date: Sat, 12 Jul 2014 19:28:43 +0400 Subject: [PATCH] improving face-rec sample: * CSV can contain dir-s and wildcards * save trained model --- samples/cpp/facerec_demo.cpp | 135 +++++++++++++++++++---------------- 1 file changed, 75 insertions(+), 60 deletions(-) diff --git a/samples/cpp/facerec_demo.cpp b/samples/cpp/facerec_demo.cpp index b92308e898..f3837d4d3f 100644 --- a/samples/cpp/facerec_demo.cpp +++ b/samples/cpp/facerec_demo.cpp @@ -27,35 +27,38 @@ using namespace cv; using namespace std; -static Mat toGrayscale(InputArray _src) { - Mat src = _src.getMat(); - // only allow one channel - if(src.channels() != 1) { - CV_Error(CV_StsBadArg, "Only Matrices with one channel are supported"); - } - // create and return normalized image - Mat dst; - cv::normalize(_src, dst, 0, 255, NORM_MINMAX, CV_8UC1); - return dst; -} - static void read_csv(const string& filename, vector& images, vector& labels, std::map& labelsInfo, char separator = ';') { - std::ifstream file(filename.c_str(), ifstream::in); - if (!file) { - string error_message = "No valid input file was given, please check the given filename."; - CV_Error(CV_StsBadArg, error_message); - } + ifstream csv(filename.c_str()); + if (!csv) CV_Error(CV_StsBadArg, "No valid input file was given, please check the given filename."); string line, path, classlabel, info; - while (getline(file, line)) { + while (getline(csv, line)) { stringstream liness(line); + path.clear(); classlabel.clear(); info.clear(); getline(liness, path, separator); getline(liness, classlabel, separator); getline(liness, info, separator); if(!path.empty() && !classlabel.empty()) { - images.push_back(imread(path, 0)); - labels.push_back(atoi(classlabel.c_str())); + cout << "Processing " << path << endl; + int label = atoi(classlabel.c_str()); if(!info.empty()) - labelsInfo.insert(std::make_pair(labels.back(), info)); + labelsInfo.insert(std::make_pair(label, info)); + // 'path' can be file, dir or wildcard path + String root(path.c_str()); + vector files; + glob(root, files, true); + for(vector::const_iterator f = files.begin(); f != files.end(); ++f) { + cout << "\t" << *f << endl; + Mat img = imread(*f, CV_LOAD_IMAGE_GRAYSCALE); + static int w=-1, h=-1; + static bool showSmallSizeWarning = true; + if(w>0 && h>0 && (w!=img.cols || h!=img.rows)) cout << "\t* Warning: images should be of the same size!" << endl; + if(showSmallSizeWarning && (img.cols<50 || img.rows<50)) { + cout << "* Warning: for better results images should be not smaller than 50x50!" << endl; + showSmallSizeWarning = false; + } + images.push_back(img); + labels.push_back(label); + } } } } @@ -63,8 +66,17 @@ static void read_csv(const string& filename, vector& images, vector& l int main(int argc, const char *argv[]) { // Check for valid command line arguments, print usage // if no arguments were given. - if (argc != 2) { - cout << "usage: " << argv[0] << " " << endl; + if (argc != 2 && argc != 3) { + cout << "Usage: " << argv[0] << " [arg2]\n" + << "\t - path to config file in CSV format\n" + << "\targ2 - if the 2nd argument is provided (with any value) " + << "the advanced stuff is run and shown to console.\n" + << "The CSV config file consists of the following lines:\n" + << ";