diff --git a/modules/face/include/opencv2/face/facemark.hpp b/modules/face/include/opencv2/face/facemark.hpp index 104a96cc5..82bb186be 100644 --- a/modules/face/include/opencv2/face/facemark.hpp +++ b/modules/face/include/opencv2/face/facemark.hpp @@ -1,34 +1,9 @@ -/* -By downloading, copying, installing or using the software you agree to this -license. If you do not agree to this license, do not download, install, -copy or use the software. - License Agreement - For Open Source Computer Vision Library - (3-clause BSD License) -Copyright (C) 2013, OpenCV Foundation, all rights reserved. -Third party copyrights are property of their respective owners. -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the names of the copyright holders nor the names of the contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. -This software is provided by the copyright holders and contributors "as is" and -any express or implied warranties, including, but not limited to, the implied -warranties of merchantability and fitness for a particular purpose are -disclaimed. In no event shall copyright holders or contributors be liable for -any direct, indirect, incidental, special, exemplary, or consequential damages -(including, but not limited to, procurement of substitute goods or services; -loss of use, data, or profits; or business interruption) however caused -and on any theory of liability, whether in contract, strict liability, -or tort (including negligence or otherwise) arising in any way out of -the use of this software, even if advised of the possibility of such damage. +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. -This file was part of GSoC Project: Facemark API for OpenCV +/* +This file contains results of GSoC Project: Facemark API for OpenCV Final report: https://gist.github.com/kurnianggoro/74de9121e122ad0bd825176751d47ecc Student: Laksono Kurnianggoro Mentor: Delia Passalacqua @@ -45,29 +20,36 @@ Mentor: Delia Passalacqua #include "opencv2/face.hpp" #include "opencv2/objdetect.hpp" -#include "opencv2/objdetect/objdetect_c.h" -#include "opencv2/imgproc/types_c.h" +#include +#include + namespace cv { namespace face { //! @addtogroup face //! @{ -struct CV_EXPORTS_W CParams{ + +typedef bool(*FN_FaceDetector)(InputArray, OutputArray, void* userData); + +struct CParams{ String cascade; //!< the face detector double scaleFactor; //!< Parameter specifying how much the image size is reduced at each image scale. int minNeighbors; //!< Parameter specifying how many neighbors each candidate rectangle should have to retain it. Size minSize; //!< Minimum possible object size. Size maxSize; //!< Maximum possible object size. - CParams( + CV_EXPORTS CParams( String cascade_model, double sf = 1.1, int minN = 3, Size minSz = Size(30, 30), Size maxSz = Size() ); + + CascadeClassifier face_cascade; }; + /** @brief Default face detector This function is mainly utilized by the implementation of a Facemark Algorithm. End users are advised to use function Facemark::getFaces which can be manually defined @@ -76,7 +58,7 @@ and circumvented to the algorithm by Facemark::setFaceDetector. @param image The input image to be processed. @param faces Output of the function which represent region of interest of the detected faces. Each face is stored in cv::Rect container. -@param extra_params extra parameters +@param params detector parameters Example of usage @code @@ -89,11 +71,7 @@ for(int j=0;j images_train; std::vector landmarks_train; loadDatasetList(imageFiles,ptsFiles,images_train,landmarks_train); @endcode - */ CV_EXPORTS_W bool loadDatasetList(String imageList, String annotationList, @@ -138,13 +115,12 @@ cv::String imageFiles = "../data/images_train.txt"; cv::String ptsFiles = "../data/points_train.txt"; std::vector images; std::vector > facePoints; -loadTrainingData(imageFiles, ptsFiles, images, facePoints, 0.0); +loadTrainingData(imageFiles, ptsFiles, images, facePoints, 0.0f); @endcode */ - CV_EXPORTS_W bool loadTrainingData( String filename , std::vector & images, OutputArray facePoints, - char delim = ' ', float offset = 0.0); + char delim = ' ', float offset = 0.0f); /** @brief A utility to load facial landmark information from the dataset. @@ -163,7 +139,7 @@ cv::String imageFiles = "../data/images_train.txt"; cv::String ptsFiles = "../data/points_train.txt"; std::vector images; std::vector > facePoints; -loadTrainingData(imageFiles, ptsFiles, images, facePoints, 0.0); +loadTrainingData(imageFiles, ptsFiles, images, facePoints, 0.0f); @endcode example of content in the images_train.txt @@ -182,11 +158,10 @@ example of content in the points_train.txt /home/user/ibug/image_006.pts @endcode */ - CV_EXPORTS_W bool loadTrainingData( String imageList, String groundTruth, std::vector & images, OutputArray facePoints, - float offset = 0.0); + float offset = 0.0f); /** @brief A utility to load facial landmark information from a given file. @@ -197,7 +172,7 @@ CV_EXPORTS_W bool loadTrainingData( String imageList, String groundTruth, Example of usage @code std::vector points; -face::loadFacePoints("filename.txt", points, 0.0); +face::loadFacePoints("filename.txt", points, 0.0f); @endcode The annotation file should follow the default format which is @@ -213,9 +188,8 @@ n_points: 68 where n_points is the number of points considered and each point is represented as its position in x and y. */ - CV_EXPORTS_W bool loadFacePoints( String filename, OutputArray points, - float offset = 0.0); + float offset = 0.0f); /** @brief Utility to draw the detected facial landmark points @@ -365,40 +339,42 @@ public: std::vector > landmarks; facemark->fit(image, faces, landmarks); @endcode + + TODO remove "config" from here */ - virtual bool fit( InputArray image,\ - InputArray faces,\ - InputOutputArray landmarks,\ + virtual bool fit( InputArray image, + InputArray faces, + InputOutputArray landmarks, void * config = 0)=0; /** @brief Set a user defined face detector for the Facemark algorithm. - @param f The user defined face detector function + @param detector The user defined face detector function + @param userData Detector parameters + Example of usage @code - facemark->setFaceDetector(myDetector); + MyDetectorParameters detectorParameters(...); + facemark->setFaceDetector(myDetector, &detectorParameters); @endcode Example of a user defined face detector @code - bool myDetector( InputArray image, OutputArray ROIs ){ - std::vector & faces = *(std::vector*) ROIs.getObj(); - faces.clear(); - - Mat img = image.getMat(); - + bool myDetector( InputArray image, OutputArray faces, void* userData) + { + MyDetectorParameters* params = (MyDetectorParameters*)userData; // -------- do something -------- } @endcode + + TODO Lifetime of detector parameters is uncontrolled. Rework interface design to "Ptr". */ - virtual bool setFaceDetector(bool(*f)(InputArray , OutputArray, void * ))=0; + virtual bool setFaceDetector(FN_FaceDetector detector, void* userData = 0)=0; /** @brief Detect faces from a given image using default or user defined face detector. Some Algorithm might not provide a default face detector. @param image Input image. - @param faces Output of the function which represent region of interest of the detected faces. - Each face is stored in cv::Rect container. - @param extra_params Optional extra-parameters for the face detector function. + @param faces Output of the function which represent region of interest of the detected faces. Each face is stored in cv::Rect container. Example of usage @code @@ -409,7 +385,7 @@ public: } @endcode */ - virtual bool getFaces( InputArray image , OutputArray faces, void * extra_params=0)=0; + virtual bool getFaces(InputArray image, OutputArray faces)=0; /** @brief Get data from an algorithm @@ -427,13 +403,10 @@ public: cout< s0, CascadeClassifier eyes_cascade, Mat & R, Point2f & Trans, float & scale); bool parseArguments(int argc, char** argv, CommandLineParser & , String & cascade, @@ -130,7 +130,7 @@ int main(int argc, char** argv ) printf("image #%i ", i); //! [detect_face] image = imread(images[i]); - myDetector(image, faces, face_cascade); + myDetector(image, faces, &face_cascade); //! [detect_face] if(faces.size()>0){ //! [get_initialization] @@ -167,19 +167,20 @@ int main(int argc, char** argv ) //! [fitting] } -bool myDetector( InputArray image, OutputArray ROIs, CascadeClassifier face_cascade){ +bool myDetector(InputArray image, OutputArray faces, CascadeClassifier *face_cascade) +{ Mat gray; - std::vector & faces = *(std::vector*) ROIs.getObj(); - faces.clear(); - if(image.channels()>1){ - cvtColor(image.getMat(),gray,CV_BGR2GRAY); - }else{ + if (image.channels() > 1) + cvtColor(image, gray, COLOR_BGR2GRAY); + else gray = image.getMat().clone(); - } - equalizeHist( gray, gray ); - face_cascade.detectMultiScale( gray, faces, 1.2, 2, CV_HAAR_SCALE_IMAGE, Size(30, 30) ); + equalizeHist(gray, gray); + + std::vector faces_; + face_cascade->detectMultiScale(gray, faces_, 1.4, 2, CASCADE_SCALE_IMAGE, Size(30, 30)); + Mat(faces_).copyTo(faces); return true; } @@ -201,7 +202,7 @@ bool getInitialFitting(Mat image, Rect face, std::vector s0 ,CascadeCla std::vector eyes; //-- In each face, detect eyes - eyes_cascade.detectMultiScale( faceROI, eyes, 1.1, 2, 0 |CV_HAAR_SCALE_IMAGE, Size(20, 20) ); + eyes_cascade.detectMultiScale( faceROI, eyes, 1.1, 2, CASCADE_SCALE_IMAGE, Size(20, 20) ); if(eyes.size()==2){ found = true; int j=0; diff --git a/modules/face/samples/facemark_demo_lbf.cpp b/modules/face/samples/facemark_demo_lbf.cpp index 49cefce4b..16e4a3a7a 100644 --- a/modules/face/samples/facemark_demo_lbf.cpp +++ b/modules/face/samples/facemark_demo_lbf.cpp @@ -47,10 +47,9 @@ using namespace std; using namespace cv; using namespace cv::face; -CascadeClassifier face_cascade; -bool myDetector( InputArray image, OutputArray roi, void * config=0 ); -bool parseArguments(int argc, char** argv, CommandLineParser & , String & cascade, - String & model, String & images, String & annotations, String & testImages +static bool myDetector( InputArray image, OutputArray roi, CascadeClassifier *face_detector); +static bool parseArguments(int argc, char** argv, CommandLineParser & , String & cascade, + String & model, String & images, String & annotations, String & testImages ); int main(int argc, char** argv) @@ -66,8 +65,9 @@ int main(int argc, char** argv) params.cascade_face = cascade_path; Ptr facemark = FacemarkLBF::create(params); + CascadeClassifier face_cascade; face_cascade.load(params.cascade_face.c_str()); - facemark->setFaceDetector(myDetector); + facemark->setFaceDetector((FN_FaceDetector)myDetector, &face_cascade); /*Loads the dataset*/ std::vector images_train; @@ -118,27 +118,22 @@ int main(int argc, char** argv) cout<<"face not found"< & faces = *(std::vector*) roi.getObj(); - faces.clear(); - if(config!=0){ - //do nothing - } - - if(image.channels()>1){ - cvtColor(image,gray,CV_BGR2GRAY); - }else{ + if (image.channels() > 1) + cvtColor(image, gray, COLOR_BGR2GRAY); + else gray = image.getMat().clone(); - } - equalizeHist( gray, gray ); - face_cascade.detectMultiScale( gray, faces, 1.4, 2, CV_HAAR_SCALE_IMAGE, Size(30, 30) ); + equalizeHist(gray, gray); + std::vector faces_; + face_cascade->detectMultiScale(gray, faces_, 1.4, 2, CASCADE_SCALE_IMAGE, Size(30, 30)); + Mat(faces_).copyTo(faces); return true; } diff --git a/modules/face/samples/facemark_lbf_fitting.cpp b/modules/face/samples/facemark_lbf_fitting.cpp index 0fe5b3979..1d18804ae 100644 --- a/modules/face/samples/facemark_lbf_fitting.cpp +++ b/modules/face/samples/facemark_lbf_fitting.cpp @@ -1,5 +1,5 @@ /* -This file was part of GSoC Project: Facemark API for OpenCV +This file contains results of GSoC Project: Facemark API for OpenCV Final report: https://gist.github.com/kurnianggoro/74de9121e122ad0bd825176751d47ecc Student: Laksono Kurnianggoro Mentor: Delia Passalacqua @@ -28,9 +28,8 @@ using namespace std; using namespace cv; using namespace cv::face; -CascadeClassifier face_cascade; -bool myDetector( InputArray image, OutputArray ROIs, void * config = 0); -bool parseArguments(int argc, char** argv, CommandLineParser & parser, +static bool myDetector(InputArray image, OutputArray ROIs, CascadeClassifier *face_cascade); +static bool parseArguments(int argc, char** argv, CommandLineParser & parser, String & cascade, String & model,String & video); int main(int argc, char** argv ){ @@ -39,6 +38,7 @@ int main(int argc, char** argv ){ if(!parseArguments(argc, argv, parser,cascade_path,model_path,video_path)) return -1; + CascadeClassifier face_cascade; face_cascade.load(cascade_path); FacemarkLBF::Params params; @@ -46,7 +46,7 @@ int main(int argc, char** argv ){ params.cascade_face = cascade_path; Ptr facemark = FacemarkLBF::create(params); - facemark->setFaceDetector(myDetector); + facemark->setFaceDetector((FN_FaceDetector)myDetector, &face_cascade); facemark->loadModel(params.model_filename.c_str()); VideoCapture capture(video_path); @@ -115,23 +115,20 @@ int main(int argc, char** argv ){ waitKey(0); // key press to close window } -bool myDetector( InputArray image, OutputArray ROIs, void * config ){ +bool myDetector(InputArray image, OutputArray faces, CascadeClassifier *face_cascade) +{ Mat gray; - std::vector & faces = *(std::vector*) ROIs.getObj(); - faces.clear(); - if(config!=0){ - //do nothing - } - - if(image.channels()>1){ - cvtColor(image.getMat(),gray,CV_BGR2GRAY); - }else{ + if (image.channels() > 1) + cvtColor(image, gray, COLOR_BGR2GRAY); + else gray = image.getMat().clone(); - } - equalizeHist( gray, gray ); - face_cascade.detectMultiScale( gray, faces, 1.4, 2, CV_HAAR_SCALE_IMAGE, Size(30, 30) ); + equalizeHist(gray, gray); + + std::vector faces_; + face_cascade->detectMultiScale(gray, faces_, 1.4, 2, CASCADE_SCALE_IMAGE, Size(30, 30)); + Mat(faces_).copyTo(faces); return true; } diff --git a/modules/face/src/facemark.cpp b/modules/face/src/facemark.cpp index d44a89058..05e2ab686 100644 --- a/modules/face/src/facemark.cpp +++ b/modules/face/src/facemark.cpp @@ -1,42 +1,18 @@ -/* -By downloading, copying, installing or using the software you agree to this -license. If you do not agree to this license, do not download, install, -copy or use the software. - License Agreement - For Open Source Computer Vision Library - (3-clause BSD License) -Copyright (C) 2013, OpenCV Foundation, all rights reserved. -Third party copyrights are property of their respective owners. -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the names of the copyright holders nor the names of the contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. -This software is provided by the copyright holders and contributors "as is" and -any express or implied warranties, including, but not limited to, the implied -warranties of merchantability and fitness for a particular purpose are -disclaimed. In no event shall copyright holders or contributors be liable for -any direct, indirect, incidental, special, exemplary, or consequential damages -(including, but not limited to, procurement of substitute goods or services; -loss of use, data, or profits; or business interruption) however caused -and on any theory of liability, whether in contract, strict liability, -or tort (including negligence or otherwise) arising in any way out of -the use of this software, even if advised of the possibility of such damage. +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. -This file was part of GSoC Project: Facemark API for OpenCV +/* +This file contains results of GSoC Project: Facemark API for OpenCV Final report: https://gist.github.com/kurnianggoro/74de9121e122ad0bd825176751d47ecc Student: Laksono Kurnianggoro Mentor: Delia Passalacqua */ +#include "precomp.hpp" + #include "opencv2/face.hpp" #include "opencv2/core.hpp" -#include "precomp.hpp" /*dataset parser*/ #include @@ -46,33 +22,35 @@ Mentor: Delia Passalacqua namespace cv { namespace face { + +using namespace std; + CParams::CParams(String s, double sf, int minN, Size minSz, Size maxSz){ cascade = s; scaleFactor = sf; minNeighbors = minN; minSize = minSz; maxSize = maxSz; + + if (!face_cascade.load(cascade)) + { + CV_Error_(Error::StsBadArg, ("Error loading face_cascade: %s", cascade.c_str())); + } } -bool getFaces(InputArray image, OutputArray faces, void * parameters){ +bool getFaces(InputArray image, OutputArray faces, CParams* params) +{ + CV_Assert(params); Mat gray; std::vector roi; - if(parameters!=0){ - CParams * params = (CParams *)parameters; - cvtColor( image.getMat(), gray, CV_BGR2GRAY ); - equalizeHist( gray, gray ); + cvtColor(image.getMat(), gray, COLOR_BGR2GRAY); + equalizeHist(gray, gray); - CascadeClassifier face_cascade; - if( !face_cascade.load( params->cascade ) ){ printf("--(!)Error loading face_cascade\n"); return false; }; - face_cascade.detectMultiScale( gray, roi, params->scaleFactor, params->minNeighbors, 0|CV_HAAR_SCALE_IMAGE, params->minSize, params->maxSize); - - Mat(roi).copyTo(faces); - return true; - }else{ - return false; - } + params->face_cascade.detectMultiScale( gray, roi, params->scaleFactor, params->minNeighbors, CASCADE_SCALE_IMAGE, params->minSize, params->maxSize); + Mat(roi).copyTo(faces); + return true; } bool loadDatasetList(String imageList, String groundTruth, std::vector & images, std::vector & landmarks){ @@ -111,14 +89,14 @@ bool loadTrainingData(String filename, std::vector & images, OutputArray std::vector pts; std::vector raw; + // FIXIT std::vector > & facePoints = *(std::vector >*) _facePoints.getObj(); std::ifstream infile; infile.open(filename.c_str(), std::ios::in); if (!infile) { - std::string error_message = "No valid input file was given, please check the given filename."; - CV_Error(CV_StsBadArg, error_message); + CV_Error_(Error::StsBadArg, ("No valid input file was given, please check the given filename: %s", filename.c_str())); } /*clear the output containers*/ @@ -154,6 +132,7 @@ bool loadTrainingData(String imageList, String groundTruth, std::vector std::string line; std::vector facePts; + // FIXIT std::vector > & facePoints = *(std::vector >*) _facePoints.getObj(); @@ -165,8 +144,7 @@ bool loadTrainingData(String imageList, String groundTruth, std::vector std::ifstream infile; infile.open(imageList.c_str(), std::ios::in); if (!infile) { - std::string error_message = "No valid input file was given, please check the given filename."; - CV_Error(CV_StsBadArg, error_message); + CV_Error_(Error::StsBadArg, ("No valid input file was given, please check the given filename: %s", imageList.c_str())); } while (getline (infile, line)){ @@ -185,7 +163,7 @@ bool loadTrainingData(String imageList, String groundTruth, std::vector } bool loadFacePoints(String filename, OutputArray points, float offset){ - std::vector & pts = *(std::vector *)points.getObj(); + vector pts; std::string line, item; std::ifstream infile(filename.c_str()); @@ -222,16 +200,16 @@ bool loadFacePoints(String filename, OutputArray points, float offset){ } + Mat(pts).copyTo(points); return true; } void drawFacemarks(InputOutputArray image, InputArray points, Scalar color){ Mat img = image.getMat(); - std::vector pts = *(std::vector*)points.getObj(); + vector pts = points.getMat(); for(size_t i=0;i > facePoints; FacemarkAAM::Params params; FacemarkAAM::Model AAM; - bool(*faceDetector)(InputArray , OutputArray, void *); - bool isSetDetector; + FN_FaceDetector faceDetector; + void* faceDetectorData; private: bool isModelTrained; @@ -154,9 +129,9 @@ Ptr FacemarkAAM::create(const FacemarkAAM::Params ¶meters){ } FacemarkAAMImpl::FacemarkAAMImpl( const FacemarkAAM::Params ¶meters ) : - params( parameters ) + params( parameters ), + faceDetector(NULL), faceDetectorData(NULL) { - isSetDetector =false; isModelTrained = false; } @@ -168,42 +143,30 @@ void FacemarkAAMImpl::write( cv::FileStorage& fs ) const { params.write( fs ); } -bool FacemarkAAMImpl::setFaceDetector(bool(*f)(InputArray , OutputArray, void *)){ +bool FacemarkAAMImpl::setFaceDetector(bool(*f)(InputArray , OutputArray, void *), void* userData){ faceDetector = f; - isSetDetector = true; + faceDetectorData = userData; return true; } -bool FacemarkAAMImpl::getFaces( InputArray image , OutputArray roi, void * extra_params){ - - if(!isSetDetector){ +bool FacemarkAAMImpl::getFaces(InputArray image, OutputArray faces) +{ + if (!faceDetector) return false; - } - - if(extra_params!=0){ - //do nothing - } - - std::vector faces; - faces.clear(); - - faceDetector(image.getMat(), faces, extra_params); - Mat(faces).copyTo(roi); - return true; + return faceDetector(image, faces, faceDetectorData); } bool FacemarkAAMImpl::getData(void * items){ - if(items==0){ - return true; - }else{ - Data * data = (Data*)items; - data->s0 = AAM.s0; - return true; - } + CV_Assert(items); + + Data* data = (Data*)items; + data->s0 = AAM.s0; + return true; } bool FacemarkAAMImpl::addTrainingSample(InputArray image, InputArray landmarks){ + // FIXIT std::vector & _landmarks = *(std::vector*)landmarks.getObj(); images.push_back(image.getMat()); @@ -215,14 +178,11 @@ bool FacemarkAAMImpl::addTrainingSample(InputArray image, InputArray landmarks){ void FacemarkAAMImpl::training(void* parameters){ if(parameters!=0){/*do nothing*/} if (images.size()<1) { - std::string error_message = - "Training data is not provided. Consider to add using addTrainingSample() function!"; - CV_Error(CV_StsBadArg, error_message); + CV_Error(Error::StsBadArg, "Training data is not provided. Consider to add using addTrainingSample() function!"); } if(strcmp(params.model_filename.c_str(),"")==0 && params.save_model){ - std::string error_message = "The model_filename parameter should be set!"; - CV_Error(CV_StsBadArg, error_message); + CV_Error(Error::StsBadArg, "The model_filename parameter should be set!"); } std::vector > normalized; @@ -297,7 +257,7 @@ void FacemarkAAMImpl::training(void* parameters){ Mat T= texture_feats.t(); /* -------------- E. Create the texture model -----------------*/ - reduce(T,AAM.textures[scale].A0,1, CV_REDUCE_AVG); + reduce(T,AAM.textures[scale].A0,1, REDUCE_AVG); if(params.verbose) printf("(2/4) Compute the feature average ...\n"); Mat A0_mtx = repeat(AAM.textures[scale].A0,1,T.cols); @@ -341,9 +301,7 @@ bool FacemarkAAMImpl::fit( InputArray image, InputArray roi, InputOutputArray _l std::vector conf = *(std::vector*)runtime_params; if (conf.size()!=faces.size()) { - std::string error_message = - "Number of faces and extra_parameters are different!"; - CV_Error(CV_StsBadArg, error_message); + CV_Error(Error::StsBadArg, "Number of faces and extra_parameters are different!"); } for(size_t i=0; i& landmarks, Mat imgray; Mat img; if(image.channels()>1){ - cvtColor(image,imgray,CV_BGR2GRAY); + cvtColor(image,imgray,COLOR_BGR2GRAY); }else{ imgray = image; } @@ -564,8 +522,8 @@ Mat FacemarkAAMImpl::procrustes(std::vector P, std::vector Q, // calculate the sum Mat sumXs, sumYs; - reduce(Xs,sumXs, 0, CV_REDUCE_SUM); - reduce(Ys,sumYs, 0, CV_REDUCE_SUM); + reduce(Xs,sumXs, 0, REDUCE_SUM); + reduce(Ys,sumYs, 0, REDUCE_SUM); //calculate the normrnd double normX = sqrt(Mat(sumXs.reshape(1)).at(0)+Mat(sumXs.reshape(1)).at(1)); @@ -901,7 +859,7 @@ Mat FacemarkAAMImpl::warpImage( Mat image,part, warped_part; if(img.channels()>1){ - cvtColor(img,image,CV_BGR2GRAY); + cvtColor(img,image,COLOR_BGR2GRAY); }else{ image = img; } diff --git a/modules/face/src/facemarkLBF.cpp b/modules/face/src/facemarkLBF.cpp index 00f3df9f5..1aa93e81d 100644 --- a/modules/face/src/facemarkLBF.cpp +++ b/modules/face/src/facemarkLBF.cpp @@ -1,46 +1,20 @@ -/* -By downloading, copying, installing or using the software you agree to this -license. If you do not agree to this license, do not download, install, -copy or use the software. - License Agreement - For Open Source Computer Vision Library - (3-clause BSD License) -Copyright (C) 2013, OpenCV Foundation, all rights reserved. -Third party copyrights are property of their respective owners. -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the names of the copyright holders nor the names of the contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. -This software is provided by the copyright holders and contributors "as is" and -any express or implied warranties, including, but not limited to, the implied -warranties of merchantability and fitness for a particular purpose are -disclaimed. In no event shall copyright holders or contributors be liable for -any direct, indirect, incidental, special, exemplary, or consequential damages -(including, but not limited to, procurement of substitute goods or services; -loss of use, data, or profits; or business interruption) however caused -and on any theory of liability, whether in contract, strict liability, -or tort (including negligence or otherwise) arising in any way out of -the use of this software, even if advised of the possibility of such damage. +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. -This file was part of GSoC Project: Facemark API for OpenCV +/* +This file contains results of GSoC Project: Facemark API for OpenCV Final report: https://gist.github.com/kurnianggoro/74de9121e122ad0bd825176751d47ecc Student: Laksono Kurnianggoro Mentor: Delia Passalacqua */ -#include "opencv2/face.hpp" #include "precomp.hpp" +#include "opencv2/face.hpp" #include #include #include #include -#include #include namespace cv { @@ -108,8 +82,8 @@ public: void loadModel(String fs); - bool setFaceDetector(bool(*f)(InputArray , OutputArray, void * extra_params )); - bool getFaces( InputArray image , OutputArray faces, void * extra_params); + bool setFaceDetector(bool(*f)(InputArray , OutputArray, void * extra_params ), void* userData); + bool getFaces(InputArray image, OutputArray faces); bool getData(void * items); Params params; @@ -128,12 +102,11 @@ protected: void data_augmentation(std::vector &imgs, std::vector >_shapes, std::vector &bboxes); Mat getMeanShape(std::vector >_shapes, std::vector &bboxes); - bool configFaceDetector(); - bool defaultFaceDetector(const Mat image, std::vector & faces); + bool defaultFaceDetector(const Mat& image, std::vector& faces); CascadeClassifier face_cascade; - bool(*faceDetector)(InputArray , OutputArray, void * ); - bool isSetDetector; + FN_FaceDetector faceDetector; + void* faceDetectorData; /*training data*/ std::vector > data_facemarks; //original position @@ -251,98 +224,85 @@ Ptr FacemarkLBF::create(const FacemarkLBF::Params ¶meters){ return Ptr(new FacemarkLBFImpl(parameters)); } -FacemarkLBFImpl::FacemarkLBFImpl( const FacemarkLBF::Params ¶meters ) +FacemarkLBFImpl::FacemarkLBFImpl( const FacemarkLBF::Params ¶meters ) : + faceDetector(NULL), faceDetectorData(NULL) { - isSetDetector =false; isModelTrained = false; params = parameters; } -bool FacemarkLBFImpl::setFaceDetector(bool(*f)(InputArray , OutputArray, void * extra_params )){ +bool FacemarkLBFImpl::setFaceDetector(bool(*f)(InputArray , OutputArray, void * extra_params ), void* userData){ faceDetector = f; - isSetDetector = true; + faceDetectorData = userData; return true; } -bool FacemarkLBFImpl::getFaces( InputArray image , OutputArray roi, void * extra_params){ - - if(!isSetDetector){ - return false; +bool FacemarkLBFImpl::getFaces(InputArray image, OutputArray faces_) +{ + if (!faceDetector) + { + std::vector faces; + defaultFaceDetector(image.getMat(), faces); + Mat(faces).copyTo(faces_); + return true; } - - if(extra_params!=0){ - //do nothing - } - - std::vector & faces = *(std::vector*)roi.getObj(); - faces.clear(); - - faceDetector(image.getMat(), faces, extra_params); - - return true; + return faceDetector(image, faces_, faceDetectorData); } -bool FacemarkLBFImpl::configFaceDetector(){ - if(!isSetDetector){ - /*check the cascade classifier file*/ - std::ifstream infile; - infile.open(params.cascade_face.c_str(), std::ios::in); - if (!infile) { - std::string error_message = "The cascade classifier model is not found."; - CV_Error(CV_StsBadArg, error_message); - - return false; - } - - face_cascade.load(params.cascade_face.c_str()); - } - return true; -} - -bool FacemarkLBFImpl::defaultFaceDetector(const Mat image, std::vector & faces){ +bool FacemarkLBFImpl::defaultFaceDetector(const Mat& image, std::vector& faces){ Mat gray; faces.clear(); - if(image.channels()>1){ - cvtColor(image,gray,CV_BGR2GRAY); - }else{ + if (image.channels() > 1) + { + cvtColor(image, gray, COLOR_BGR2GRAY); + } + else + { gray = image; } - equalizeHist( gray, gray ); - face_cascade.detectMultiScale( gray, faces, 1.05, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) ); + equalizeHist(gray, gray); + if (face_cascade.empty()) + { + { /* check the cascade classifier file */ + std::ifstream infile; + infile.open(params.cascade_face.c_str(), std::ios::in); + if (!infile) + CV_Error_(Error::StsBadArg, ("The cascade classifier model is not found: %s", params.cascade_face.c_str())); + } + face_cascade.load(params.cascade_face.c_str()); + CV_Assert(!face_cascade.empty()); + } + face_cascade.detectMultiScale(gray, faces, 1.05, 2, CASCADE_SCALE_IMAGE, Size(30, 30) ); return true; } bool FacemarkLBFImpl::getData(void * items){ - if(items!=0){ - // do nothing - } - return true; + CV_UNUSED(items); + return false; } bool FacemarkLBFImpl::addTrainingSample(InputArray image, InputArray landmarks){ + // FIXIT std::vector & _landmarks = *(std::vector*)landmarks.getObj(); - configFaceDetector(); prepareTrainingData(image.getMat(), _landmarks, data_faces, data_shapes, data_boxes); return true; } void FacemarkLBFImpl::training(void* parameters){ - if(parameters!=0){/*do nothing*/} - if (data_faces.size()<1) { - std::string error_message = - "Training data is not provided. Consider to add using addTrainingSample() function!"; - CV_Error(CV_StsBadArg, error_message); + CV_UNUSED(parameters); + + if (data_faces.empty()) + { + CV_Error(Error::StsBadArg, "Training data is not provided. Consider to add using addTrainingSample() function!"); } - if(strcmp(params.cascade_face.c_str(),"")==0 - ||(strcmp(params.model_filename.c_str(),"")==0 && params.save_model) - ){ - std::string error_message = "The parameter cascade_face and model_filename should be set!"; - CV_Error(CV_StsBadArg, error_message); + if (params.cascade_face.empty() || (params.model_filename.empty() && params.save_model)) + { + CV_Error(Error::StsBadArg, "The parameter cascade_face and model_filename should be set!"); } // flip the image and swap the landmark position @@ -358,10 +318,8 @@ void FacemarkLBFImpl::training(void* parameters){ for (int i = 0; i < N; i++) { for (int j = 0; j < params.initShape_n; j++) { int idx = i*params.initShape_n + j; - int k = 0; - do { - k = rng.uniform(0, N); - } while (k == i); + int k = rng.uniform(0, N - 1); + k = (k >= i) ? k + 1 : k; // require k != i imgs[idx] = data_faces[i]; gt_shapes[idx] = data_shapes[i]; bboxes[idx] = data_boxes[i]; @@ -382,12 +340,11 @@ void FacemarkLBFImpl::training(void* parameters){ bool FacemarkLBFImpl::fit( InputArray image, InputArray roi, InputOutputArray _landmarks, void * runtime_params ) { - if(runtime_params!=0){ - // do nothing - } + CV_UNUSED(runtime_params); + // FIXIT std::vector & faces = *(std::vector *)roi.getObj(); - if(faces.size()<1) return false; + if (faces.empty()) return false; std::vector > & landmarks = *(std::vector >*) _landmarks.getObj(); @@ -407,13 +364,12 @@ bool FacemarkLBFImpl::fitImpl( const Mat image, std::vector& landmarks) landmarks.clear(); if (!isModelTrained) { - std::string error_message = "The LBF model is not trained yet. Please provide a trained model."; - CV_Error(CV_StsBadArg, error_message); + CV_Error(Error::StsBadArg, "The LBF model is not trained yet. Please provide a trained model."); } Mat img; if(image.channels()>1){ - cvtColor(image,img,CV_BGR2GRAY); + cvtColor(image,img,COLOR_BGR2GRAY); }else{ img = image; } @@ -424,13 +380,8 @@ bool FacemarkLBFImpl::fitImpl( const Mat image, std::vector& landmarks) }else{ std::vector rects; - if(!isSetDetector){ - defaultFaceDetector(img, rects); - }else{ - faceDetector(img, rects,0); - } - - if (rects.size() == 0) return 0; //failed to get face + if (!getFaces(img, rects)) return 0; + if (rects.empty()) return 0; //failed to get face box = rects[0]; } @@ -470,8 +421,7 @@ void FacemarkLBFImpl::loadModel(String s){ std::ifstream infile; infile.open(s.c_str(), std::ios::in); if (!infile) { - std::string error_message = "No valid input file was given, please check the given filename."; - CV_Error(CV_StsBadArg, error_message); + CV_Error(Error::StsBadArg, "No valid input file was given, please check the given filename."); } FileStorage fs(s.c_str(),FileStorage::READ); @@ -483,7 +433,7 @@ void FacemarkLBFImpl::loadModel(String s){ Rect FacemarkLBFImpl::getBBox(Mat &img, const Mat_ shape) { std::vector rects; - if(!isSetDetector){ + if(!faceDetector){ defaultFaceDetector(img, rects); }else{ faceDetector(img, rects,0); @@ -523,7 +473,7 @@ void FacemarkLBFImpl::prepareTrainingData(Mat img, std::vector facePoin std::vector & cropped, std::vector & shapes, std::vector &boxes) { if(img.channels()>1){ - cvtColor(img,img,CV_BGR2GRAY); + cvtColor(img,img,COLOR_BGR2GRAY); } Mat shape; @@ -697,8 +647,8 @@ void FacemarkLBFImpl::LBF::calcSimilarityTransform(const Mat &shape1, const Mat Mat_ covar1, covar2; Mat_ mean1, mean2; - calcCovarMatrix(temp1, covar1, mean1, CV_COVAR_COLS); - calcCovarMatrix(temp2, covar2, mean2, CV_COVAR_COLS); + calcCovarMatrix(temp1, covar1, mean1, COVAR_COLS); + calcCovarMatrix(temp2, covar2, mean2, COVAR_COLS); double s1 = sqrt(cv::norm(covar1)); double s2 = sqrt(cv::norm(covar2)); @@ -1075,7 +1025,7 @@ void FacemarkLBFImpl::Regressor::initRegressor(Params config) { void FacemarkLBFImpl::Regressor::trainRegressor(std::vector &imgs, std::vector >_shapes, std::vector ¤t_shapes, std::vector &bboxes, Mat &mean_shape_, int start_from, Params config) { - assert(start_from >= 0 && start_from < stages_n); + CV_Assert(start_from >= 0 && start_from < stages_n); mean_shape = mean_shape_; int N = (int)imgs.size(); diff --git a/modules/face/src/precomp.hpp b/modules/face/src/precomp.hpp index 01215cec8..cfa29c2c7 100644 --- a/modules/face/src/precomp.hpp +++ b/modules/face/src/precomp.hpp @@ -52,5 +52,7 @@ #include #include +#include + #endif diff --git a/modules/face/test/test_facemark.cpp b/modules/face/test/test_facemark.cpp index d91470663..e1cd733d0 100644 --- a/modules/face/test/test_facemark.cpp +++ b/modules/face/test/test_facemark.cpp @@ -1,34 +1,9 @@ -/* -By downloading, copying, installing or using the software you agree to this -license. If you do not agree to this license, do not download, install, -copy or use the software. - License Agreement - For Open Source Computer Vision Library - (3-clause BSD License) -Copyright (C) 2013, OpenCV Foundation, all rights reserved. -Third party copyrights are property of their respective owners. -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the names of the copyright holders nor the names of the contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. -This software is provided by the copyright holders and contributors "as is" and -any express or implied warranties, including, but not limited to, the implied -warranties of merchantability and fitness for a particular purpose are -disclaimed. In no event shall copyright holders or contributors be liable for -any direct, indirect, incidental, special, exemplary, or consequential damages -(including, but not limited to, procurement of substitute goods or services; -loss of use, data, or profits; or business interruption) however caused -and on any theory of liability, whether in contract, strict liability, -or tort (including negligence or otherwise) arising in any way out of -the use of this software, even if advised of the possibility of such damage. +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. -This file was part of GSoC Project: Facemark API for OpenCV +/* +This file contains results of GSoC Project: Facemark API for OpenCV Final report: https://gist.github.com/kurnianggoro/74de9121e122ad0bd825176751d47ecc Student: Laksono Kurnianggoro Mentor: Delia Passalacqua diff --git a/modules/face/test/test_facemark_aam.cpp b/modules/face/test/test_facemark_aam.cpp index 91c5713b9..2cf4ceacb 100644 --- a/modules/face/test/test_facemark_aam.cpp +++ b/modules/face/test/test_facemark_aam.cpp @@ -1,34 +1,9 @@ -/* -By downloading, copying, installing or using the software you agree to this -license. If you do not agree to this license, do not download, install, -copy or use the software. - License Agreement - For Open Source Computer Vision Library - (3-clause BSD License) -Copyright (C) 2013, OpenCV Foundation, all rights reserved. -Third party copyrights are property of their respective owners. -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the names of the copyright holders nor the names of the contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. -This software is provided by the copyright holders and contributors "as is" and -any express or implied warranties, including, but not limited to, the implied -warranties of merchantability and fitness for a particular purpose are -disclaimed. In no event shall copyright holders or contributors be liable for -any direct, indirect, incidental, special, exemplary, or consequential damages -(including, but not limited to, procurement of substitute goods or services; -loss of use, data, or profits; or business interruption) however caused -and on any theory of liability, whether in contract, strict liability, -or tort (including negligence or otherwise) arising in any way out of -the use of this software, even if advised of the possibility of such damage. +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. -This file was part of GSoC Project: Facemark API for OpenCV +/* +This file contains results of GSoC Project: Facemark API for OpenCV Final report: https://gist.github.com/kurnianggoro/74de9121e122ad0bd825176751d47ecc Student: Laksono Kurnianggoro Mentor: Delia Passalacqua @@ -50,24 +25,19 @@ using namespace std; using namespace cv; using namespace cv::face; -CascadeClassifier face_detector; -static bool customDetector( InputArray image, OutputArray ROIs, void * config = 0 ){ +static bool customDetector( InputArray image, OutputArray ROIs, CascadeClassifier *face_detector){ Mat gray; std::vector & faces = *(std::vector*) ROIs.getObj(); faces.clear(); - if(config!=0){ - //do nothing - } - if(image.channels()>1){ - cvtColor(image.getMat(),gray,CV_BGR2GRAY); + cvtColor(image.getMat(),gray, COLOR_BGR2GRAY); }else{ gray = image.getMat().clone(); } equalizeHist( gray, gray ); - face_detector.detectMultiScale( gray, faces, 1.4, 2, CV_HAAR_SCALE_IMAGE, Size(30, 30) ); + face_detector->detectMultiScale( gray, faces, 1.4, 2, CASCADE_SCALE_IMAGE, Size(30, 30) ); return true; } @@ -82,11 +52,11 @@ TEST(CV_Face_FacemarkAAM, can_create_default) { TEST(CV_Face_FacemarkAAM, can_set_custom_detector) { string cascade_filename = cvtest::findDataFile("cascadeandhog/cascades/lbpcascade_frontalface.xml", true); - + CascadeClassifier face_detector; EXPECT_TRUE(face_detector.load(cascade_filename)); Ptr facemark = FacemarkAAM::create(); - EXPECT_TRUE(facemark->setFaceDetector(customDetector)); + EXPECT_TRUE(facemark->setFaceDetector((cv::face::FN_FaceDetector)customDetector, &face_detector)); } TEST(CV_Face_FacemarkAAM, test_workflow) { @@ -106,6 +76,9 @@ TEST(CV_Face_FacemarkAAM, test_workflow) { string cascade_filename = cvtest::findDataFile("cascadeandhog/cascades/lbpcascade_frontalface.xml", true); + CascadeClassifier face_detector; + EXPECT_TRUE(face_detector.load(cascade_filename)); + FacemarkAAM::Params params; params.n = 1; params.m = 1; @@ -115,7 +88,8 @@ TEST(CV_Face_FacemarkAAM, test_workflow) { Mat image; std::vector landmarks; - for(size_t i=0;i0); @@ -125,7 +99,7 @@ TEST(CV_Face_FacemarkAAM, test_workflow) { EXPECT_NO_THROW(facemark->training()); /*------------ Fitting Part ---------------*/ - facemark->setFaceDetector(customDetector); + EXPECT_TRUE(facemark->setFaceDetector((cv::face::FN_FaceDetector)customDetector, &face_detector)); string image_filename = cvtest::findDataFile("face/david1.jpg", true); image = imread(image_filename.c_str()); EXPECT_TRUE(!image.empty()); diff --git a/modules/face/test/test_facemark_lbf.cpp b/modules/face/test/test_facemark_lbf.cpp index eade8ab18..80044a01e 100644 --- a/modules/face/test/test_facemark_lbf.cpp +++ b/modules/face/test/test_facemark_lbf.cpp @@ -1,34 +1,9 @@ -/* -By downloading, copying, installing or using the software you agree to this -license. If you do not agree to this license, do not download, install, -copy or use the software. - License Agreement - For Open Source Computer Vision Library - (3-clause BSD License) -Copyright (C) 2013, OpenCV Foundation, all rights reserved. -Third party copyrights are property of their respective owners. -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the names of the copyright holders nor the names of the contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. -This software is provided by the copyright holders and contributors "as is" and -any express or implied warranties, including, but not limited to, the implied -warranties of merchantability and fitness for a particular purpose are -disclaimed. In no event shall copyright holders or contributors be liable for -any direct, indirect, incidental, special, exemplary, or consequential damages -(including, but not limited to, procurement of substitute goods or services; -loss of use, data, or profits; or business interruption) however caused -and on any theory of liability, whether in contract, strict liability, -or tort (including negligence or otherwise) arising in any way out of -the use of this software, even if advised of the possibility of such damage. +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. -This file was part of GSoC Project: Facemark API for OpenCV +/* +This file contains results of GSoC Project: Facemark API for OpenCV Final report: https://gist.github.com/kurnianggoro/74de9121e122ad0bd825176751d47ecc Student: Laksono Kurnianggoro Mentor: Delia Passalacqua @@ -61,13 +36,13 @@ static bool myCustomDetector( InputArray image, OutputArray ROIs, void * config } if(image.channels()>1){ - cvtColor(image.getMat(),gray,CV_BGR2GRAY); + cvtColor(image.getMat(),gray,COLOR_BGR2GRAY); }else{ gray = image.getMat().clone(); } equalizeHist( gray, gray ); - cascade_detector.detectMultiScale( gray, faces, 1.4, 2, CV_HAAR_SCALE_IMAGE, Size(30, 30) ); + cascade_detector.detectMultiScale( gray, faces, 1.4, 2, CASCADE_SCALE_IMAGE, Size(30, 30) ); return true; } @@ -141,8 +116,3 @@ TEST(CV_Face_FacemarkLBF, test_workflow) { EXPECT_TRUE(facemark->fit(image, rects, facial_points)); EXPECT_TRUE(facial_points[0].size()>0); } - -TEST(CV_Face_FacemarkLBF, get_data) { - Ptr facemark = FacemarkLBF::create(); - EXPECT_TRUE(facemark->getData()); -} diff --git a/modules/face/tutorials/facemark_usage/facemark_usage.markdown b/modules/face/tutorials/facemark_usage/facemark_usage.markdown index 002f39d69..dc320fb90 100644 --- a/modules/face/tutorials/facemark_usage/facemark_usage.markdown +++ b/modules/face/tutorials/facemark_usage/facemark_usage.markdown @@ -69,31 +69,25 @@ struct Conf { Conf(cv::String s, double d){ model_path = s; scaleFactor = d; + face_detector.load(model_path); }; + + CascadeClassifier face_detector; }; -bool myDetector( InputArray image, OutputArray roi, void * config ){ +bool myDetector(InputArray image, OutputArray faces, Conf *conf){ Mat gray; - std::vector & faces = *(std::vector*) roi.getObj(); - faces.clear(); - if(config!=0){ - Conf* conf = (Conf*)config; + if (image.channels() > 1) + cvtColor(image, gray, COLOR_BGR2GRAY); + else + gray = image.getMat().clone(); - if(image.channels()>1){ - cvtColor(image,gray,CV_BGR2GRAY); - }else{ - gray = image.getMat().clone(); - } - equalizeHist( gray, gray ); - - CascadeClassifier face_cascade(conf->model_path); - face_cascade.detectMultiScale( gray, faces, conf->scaleFactor, 2, CV_HAAR_SCALE_IMAGE, Size(30, 30) ); - - return true; - }else{ - return false; - } + equalizeHist(gray, gray); + std::vector faces_; + conf->face_cascade.detectMultiScale(gray, faces_, conf->scaleFactor, 2, CASCADE_SCALE_IMAGE, Size(30, 30) ); + Mat(faces_).copyTo(faces); + return true; } @endcode @@ -101,8 +95,8 @@ bool myDetector( InputArray image, OutputArray roi, void * config ){ The following snippet demonstrates how to set the custom detector to the facemark object and use it to detect the faces. Keep in mind that some facemark object might use the face detector during the training process. @code -Conf* config = new Conf("../data/lbpcascade_frontalface.xml",1.4); -facemark->setFaceDetector(myDetector); +Conf config("../data/lbpcascade_frontalface.xml", 1.4); +facemark->setFaceDetector(myDetector, &config); // we must guarantee proper lifetime of "config" object @endcode Here is the snippet for detecting face using the user defined face detector function.