Commit e310fc55 authored by Alexander Alekhin's avatar Alexander Alekhin

face: refactoring

- change face detector interface
- avoid using of legacy C-API defines
- simplify CV_Error()
- avoid using of legacy license headers
parent 7e9c5323
// 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.
/* /*
By downloading, copying, installing or using the software you agree to this This file contains results of GSoC Project: Facemark API for OpenCV
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 was part of GSoC Project: Facemark API for OpenCV
Final report: https://gist.github.com/kurnianggoro/74de9121e122ad0bd825176751d47ecc Final report: https://gist.github.com/kurnianggoro/74de9121e122ad0bd825176751d47ecc
Student: Laksono Kurnianggoro Student: Laksono Kurnianggoro
Mentor: Delia Passalacqua Mentor: Delia Passalacqua
...@@ -45,29 +20,36 @@ Mentor: Delia Passalacqua ...@@ -45,29 +20,36 @@ Mentor: Delia Passalacqua
#include "opencv2/face.hpp" #include "opencv2/face.hpp"
#include "opencv2/objdetect.hpp" #include "opencv2/objdetect.hpp"
#include "opencv2/objdetect/objdetect_c.h" #include <vector>
#include "opencv2/imgproc/types_c.h" #include <string>
namespace cv { namespace cv {
namespace face { namespace face {
//! @addtogroup face //! @addtogroup face
//! @{ //! @{
struct CV_EXPORTS_W CParams{
typedef bool(*FN_FaceDetector)(InputArray, OutputArray, void* userData);
struct CParams{
String cascade; //!< the face detector String cascade; //!< the face detector
double scaleFactor; //!< Parameter specifying how much the image size is reduced at each image scale. 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. int minNeighbors; //!< Parameter specifying how many neighbors each candidate rectangle should have to retain it.
Size minSize; //!< Minimum possible object size. Size minSize; //!< Minimum possible object size.
Size maxSize; //!< Maximum possible object size. Size maxSize; //!< Maximum possible object size.
CParams( CV_EXPORTS CParams(
String cascade_model, String cascade_model,
double sf = 1.1, double sf = 1.1,
int minN = 3, int minN = 3,
Size minSz = Size(30, 30), Size minSz = Size(30, 30),
Size maxSz = Size() Size maxSz = Size()
); );
CascadeClassifier face_cascade;
}; };
/** @brief Default face detector /** @brief Default face detector
This function is mainly utilized by the implementation of a Facemark Algorithm. 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 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. ...@@ -76,7 +58,7 @@ and circumvented to the algorithm by Facemark::setFaceDetector.
@param image The input image to be processed. @param image The input image to be processed.
@param faces Output of the function which represent region of interest of the detected faces. @param faces Output of the function which represent region of interest of the detected faces.
Each face is stored in cv::Rect container. Each face is stored in cv::Rect container.
@param extra_params extra parameters @param params detector parameters
<B>Example of usage</B> <B>Example of usage</B>
@code @code
...@@ -89,11 +71,7 @@ for(int j=0;j<faces.size();j++){ ...@@ -89,11 +71,7 @@ for(int j=0;j<faces.size();j++){
cv::imshow("detection", frame); cv::imshow("detection", frame);
@endcode @endcode
*/ */
/*other option: move this function inside Facemark as default face detector*/ CV_EXPORTS bool getFaces(InputArray image, OutputArray faces, CParams* params);
CV_EXPORTS bool getFaces( InputArray image,
OutputArray faces,
void * extra_params
);
/** @brief A utility to load list of paths to training image and annotation file. /** @brief A utility to load list of paths to training image and annotation file.
@param imageList The specified file contains paths to the training images. @param imageList The specified file contains paths to the training images.
...@@ -109,7 +87,6 @@ std::vector<String> images_train; ...@@ -109,7 +87,6 @@ std::vector<String> images_train;
std::vector<String> landmarks_train; std::vector<String> landmarks_train;
loadDatasetList(imageFiles,ptsFiles,images_train,landmarks_train); loadDatasetList(imageFiles,ptsFiles,images_train,landmarks_train);
@endcode @endcode
*/ */
CV_EXPORTS_W bool loadDatasetList(String imageList, CV_EXPORTS_W bool loadDatasetList(String imageList,
String annotationList, String annotationList,
...@@ -138,13 +115,12 @@ cv::String imageFiles = "../data/images_train.txt"; ...@@ -138,13 +115,12 @@ cv::String imageFiles = "../data/images_train.txt";
cv::String ptsFiles = "../data/points_train.txt"; cv::String ptsFiles = "../data/points_train.txt";
std::vector<String> images; std::vector<String> images;
std::vector<std::vector<Point2f> > facePoints; std::vector<std::vector<Point2f> > facePoints;
loadTrainingData(imageFiles, ptsFiles, images, facePoints, 0.0); loadTrainingData(imageFiles, ptsFiles, images, facePoints, 0.0f);
@endcode @endcode
*/ */
CV_EXPORTS_W bool loadTrainingData( String filename , std::vector<String> & images, CV_EXPORTS_W bool loadTrainingData( String filename , std::vector<String> & images,
OutputArray facePoints, 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. /** @brief A utility to load facial landmark information from the dataset.
...@@ -163,7 +139,7 @@ cv::String imageFiles = "../data/images_train.txt"; ...@@ -163,7 +139,7 @@ cv::String imageFiles = "../data/images_train.txt";
cv::String ptsFiles = "../data/points_train.txt"; cv::String ptsFiles = "../data/points_train.txt";
std::vector<String> images; std::vector<String> images;
std::vector<std::vector<Point2f> > facePoints; std::vector<std::vector<Point2f> > facePoints;
loadTrainingData(imageFiles, ptsFiles, images, facePoints, 0.0); loadTrainingData(imageFiles, ptsFiles, images, facePoints, 0.0f);
@endcode @endcode
example of content in the images_train.txt example of content in the images_train.txt
...@@ -182,11 +158,10 @@ example of content in the points_train.txt ...@@ -182,11 +158,10 @@ example of content in the points_train.txt
/home/user/ibug/image_006.pts /home/user/ibug/image_006.pts
@endcode @endcode
*/ */
CV_EXPORTS_W bool loadTrainingData( String imageList, String groundTruth, CV_EXPORTS_W bool loadTrainingData( String imageList, String groundTruth,
std::vector<String> & images, std::vector<String> & images,
OutputArray facePoints, OutputArray facePoints,
float offset = 0.0); float offset = 0.0f);
/** @brief A utility to load facial landmark information from a given file. /** @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, ...@@ -197,7 +172,7 @@ CV_EXPORTS_W bool loadTrainingData( String imageList, String groundTruth,
<B>Example of usage</B> <B>Example of usage</B>
@code @code
std::vector<Point2f> points; std::vector<Point2f> points;
face::loadFacePoints("filename.txt", points, 0.0); face::loadFacePoints("filename.txt", points, 0.0f);
@endcode @endcode
The annotation file should follow the default format which is The annotation file should follow the default format which is
...@@ -213,9 +188,8 @@ n_points: 68 ...@@ -213,9 +188,8 @@ n_points: 68
where n_points is the number of points considered where n_points is the number of points considered
and each point is represented as its position in x and y. and each point is represented as its position in x and y.
*/ */
CV_EXPORTS_W bool loadFacePoints( String filename, OutputArray points, 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 /** @brief Utility to draw the detected facial landmark points
...@@ -365,40 +339,42 @@ public: ...@@ -365,40 +339,42 @@ public:
std::vector<std::vector<Point2f> > landmarks; std::vector<std::vector<Point2f> > landmarks;
facemark->fit(image, faces, landmarks); facemark->fit(image, faces, landmarks);
@endcode @endcode
TODO remove "config" from here
*/ */
virtual bool fit( InputArray image,\ virtual bool fit( InputArray image,
InputArray faces,\ InputArray faces,
InputOutputArray landmarks,\ InputOutputArray landmarks,
void * config = 0)=0; void * config = 0)=0;
/** @brief Set a user defined face detector for the Facemark algorithm. /** @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
<B>Example of usage</B> <B>Example of usage</B>
@code @code
facemark->setFaceDetector(myDetector); MyDetectorParameters detectorParameters(...);
facemark->setFaceDetector(myDetector, &detectorParameters);
@endcode @endcode
Example of a user defined face detector Example of a user defined face detector
@code @code
bool myDetector( InputArray image, OutputArray ROIs ){ bool myDetector( InputArray image, OutputArray faces, void* userData)
std::vector<Rect> & faces = *(std::vector<Rect>*) ROIs.getObj(); {
faces.clear(); MyDetectorParameters* params = (MyDetectorParameters*)userData;
Mat img = image.getMat();
// -------- do something -------- // -------- do something --------
} }
@endcode @endcode
TODO Lifetime of detector parameters is uncontrolled. Rework interface design to "Ptr<FaceDetector>".
*/ */
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. /** @brief Detect faces from a given image using default or user defined face detector.
Some Algorithm might not provide a default face detector. Some Algorithm might not provide a default face detector.
@param image Input image. @param image Input image.
@param faces Output of the function which represent region of interest of the detected faces. @param faces Output of the function which represent region of interest of the detected faces. Each face is stored in cv::Rect container.
Each face is stored in cv::Rect container.
@param extra_params Optional extra-parameters for the face detector function.
<B>Example of usage</B> <B>Example of usage</B>
@code @code
...@@ -409,7 +385,7 @@ public: ...@@ -409,7 +385,7 @@ public:
} }
@endcode @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 /** @brief Get data from an algorithm
...@@ -427,13 +403,10 @@ public: ...@@ -427,13 +403,10 @@ public:
cout<<s0<<endl; cout<<s0<<endl;
@endcode @endcode
*/ */
virtual bool getData(void * items=0)=0; virtual bool getData(void * items=0)=0; // FIXIT
}; /* Facemark*/ }; /* Facemark*/
//! @} //! @}
} /* namespace face */ } /* namespace face */
} /* namespace cv */ } /* namespace cv */
#endif //__OPENCV_FACELANDMARK_HPP__ #endif //__OPENCV_FACELANDMARK_HPP__
// 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.
/* /*
By downloading, copying, installing or using the software you agree to this This file contains results of GSoC Project: Facemark API for OpenCV
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 was part of GSoC Project: Facemark API for OpenCV
Final report: https://gist.github.com/kurnianggoro/74de9121e122ad0bd825176751d47ecc Final report: https://gist.github.com/kurnianggoro/74de9121e122ad0bd825176751d47ecc
Student: Laksono Kurnianggoro Student: Laksono Kurnianggoro
Mentor: Delia Passalacqua Mentor: Delia Passalacqua
...@@ -80,8 +55,8 @@ public: ...@@ -80,8 +55,8 @@ public:
struct CV_EXPORTS Config struct CV_EXPORTS Config
{ {
Config( Mat rot = Mat::eye(2,2,CV_32F), Config( Mat rot = Mat::eye(2,2,CV_32F),
Point2f trans = Point2f(0.0,0.0), Point2f trans = Point2f(0.0f,0.0f),
float scaling = 1.0, float scaling = 1.0f,
int scale_id=0 int scale_id=0
); );
......
// 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.
/* /*
By downloading, copying, installing or using the software you agree to this This file contains results of GSoC Project: Facemark API for OpenCV
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 was part of GSoC Project: Facemark API for OpenCV
Final report: https://gist.github.com/kurnianggoro/74de9121e122ad0bd825176751d47ecc Final report: https://gist.github.com/kurnianggoro/74de9121e122ad0bd825176751d47ecc
Student: Laksono Kurnianggoro Student: Laksono Kurnianggoro
Mentor: Delia Passalacqua Mentor: Delia Passalacqua
......
...@@ -50,7 +50,7 @@ using namespace std; ...@@ -50,7 +50,7 @@ using namespace std;
using namespace cv; using namespace cv;
using namespace cv::face; using namespace cv::face;
bool myDetector( InputArray image, OutputArray ROIs, CascadeClassifier face_cascade); bool myDetector( InputArray image, OutputArray ROIs, CascadeClassifier *face_cascade);
bool getInitialFitting(Mat image, Rect face, std::vector<Point2f> s0, bool getInitialFitting(Mat image, Rect face, std::vector<Point2f> s0,
CascadeClassifier eyes_cascade, Mat & R, Point2f & Trans, float & scale); CascadeClassifier eyes_cascade, Mat & R, Point2f & Trans, float & scale);
bool parseArguments(int argc, char** argv, CommandLineParser & , String & cascade, bool parseArguments(int argc, char** argv, CommandLineParser & , String & cascade,
...@@ -130,7 +130,7 @@ int main(int argc, char** argv ) ...@@ -130,7 +130,7 @@ int main(int argc, char** argv )
printf("image #%i ", i); printf("image #%i ", i);
//! [detect_face] //! [detect_face]
image = imread(images[i]); image = imread(images[i]);
myDetector(image, faces, face_cascade); myDetector(image, faces, &face_cascade);
//! [detect_face] //! [detect_face]
if(faces.size()>0){ if(faces.size()>0){
//! [get_initialization] //! [get_initialization]
...@@ -167,19 +167,20 @@ int main(int argc, char** argv ) ...@@ -167,19 +167,20 @@ int main(int argc, char** argv )
//! [fitting] //! [fitting]
} }
bool myDetector( InputArray image, OutputArray ROIs, CascadeClassifier face_cascade){ bool myDetector(InputArray image, OutputArray faces, CascadeClassifier *face_cascade)
{
Mat gray; Mat gray;
std::vector<Rect> & faces = *(std::vector<Rect>*) ROIs.getObj();
faces.clear();
if(image.channels()>1){ if (image.channels() > 1)
cvtColor(image.getMat(),gray,CV_BGR2GRAY); cvtColor(image, gray, COLOR_BGR2GRAY);
}else{ else
gray = image.getMat().clone(); 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<Rect> faces_;
face_cascade->detectMultiScale(gray, faces_, 1.4, 2, CASCADE_SCALE_IMAGE, Size(30, 30));
Mat(faces_).copyTo(faces);
return true; return true;
} }
...@@ -201,7 +202,7 @@ bool getInitialFitting(Mat image, Rect face, std::vector<Point2f> s0 ,CascadeCla ...@@ -201,7 +202,7 @@ bool getInitialFitting(Mat image, Rect face, std::vector<Point2f> s0 ,CascadeCla
std::vector<Rect> eyes; std::vector<Rect> eyes;
//-- In each face, detect 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){ if(eyes.size()==2){
found = true; found = true;
int j=0; int j=0;
......
...@@ -47,10 +47,9 @@ using namespace std; ...@@ -47,10 +47,9 @@ using namespace std;
using namespace cv; using namespace cv;
using namespace cv::face; using namespace cv::face;
CascadeClassifier face_cascade; static bool myDetector( InputArray image, OutputArray roi, CascadeClassifier *face_detector);
bool myDetector( InputArray image, OutputArray roi, void * config=0 ); static bool parseArguments(int argc, char** argv, CommandLineParser & , String & cascade,
bool parseArguments(int argc, char** argv, CommandLineParser & , String & cascade, String & model, String & images, String & annotations, String & testImages
String & model, String & images, String & annotations, String & testImages
); );
int main(int argc, char** argv) int main(int argc, char** argv)
...@@ -66,8 +65,9 @@ int main(int argc, char** argv) ...@@ -66,8 +65,9 @@ int main(int argc, char** argv)
params.cascade_face = cascade_path; params.cascade_face = cascade_path;
Ptr<Facemark> facemark = FacemarkLBF::create(params); Ptr<Facemark> facemark = FacemarkLBF::create(params);
CascadeClassifier face_cascade;
face_cascade.load(params.cascade_face.c_str()); face_cascade.load(params.cascade_face.c_str());
facemark->setFaceDetector(myDetector); facemark->setFaceDetector((FN_FaceDetector)myDetector, &face_cascade);
/*Loads the dataset*/ /*Loads the dataset*/
std::vector<String> images_train; std::vector<String> images_train;
...@@ -118,27 +118,22 @@ int main(int argc, char** argv) ...@@ -118,27 +118,22 @@ int main(int argc, char** argv)
cout<<"face not found"<<endl; cout<<"face not found"<<endl;
} }
} }
} }
bool myDetector( InputArray image, OutputArray roi, void * config ){ bool myDetector(InputArray image, OutputArray faces, CascadeClassifier *face_cascade)
{
Mat gray; Mat gray;
std::vector<Rect> & faces = *(std::vector<Rect>*) roi.getObj();
faces.clear();
if(config!=0){ if (image.channels() > 1)
//do nothing cvtColor(image, gray, COLOR_BGR2GRAY);
} else
if(image.channels()>1){
cvtColor(image,gray,CV_BGR2GRAY);
}else{
gray = image.getMat().clone(); 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<Rect> faces_;
face_cascade->detectMultiScale(gray, faces_, 1.4, 2, CASCADE_SCALE_IMAGE, Size(30, 30));
Mat(faces_).copyTo(faces);
return true; return true;
} }
......
/* /*
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 Final report: https://gist.github.com/kurnianggoro/74de9121e122ad0bd825176751d47ecc
Student: Laksono Kurnianggoro Student: Laksono Kurnianggoro
Mentor: Delia Passalacqua Mentor: Delia Passalacqua
...@@ -28,9 +28,8 @@ using namespace std; ...@@ -28,9 +28,8 @@ using namespace std;
using namespace cv; using namespace cv;
using namespace cv::face; using namespace cv::face;
CascadeClassifier face_cascade; static bool myDetector(InputArray image, OutputArray ROIs, CascadeClassifier *face_cascade);
bool myDetector( InputArray image, OutputArray ROIs, void * config = 0); static bool parseArguments(int argc, char** argv, CommandLineParser & parser,
bool parseArguments(int argc, char** argv, CommandLineParser & parser,
String & cascade, String & model,String & video); String & cascade, String & model,String & video);
int main(int argc, char** argv ){ int main(int argc, char** argv ){
...@@ -39,6 +38,7 @@ 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)) if(!parseArguments(argc, argv, parser,cascade_path,model_path,video_path))
return -1; return -1;
CascadeClassifier face_cascade;
face_cascade.load(cascade_path); face_cascade.load(cascade_path);
FacemarkLBF::Params params; FacemarkLBF::Params params;
...@@ -46,7 +46,7 @@ int main(int argc, char** argv ){ ...@@ -46,7 +46,7 @@ int main(int argc, char** argv ){
params.cascade_face = cascade_path; params.cascade_face = cascade_path;
Ptr<Facemark> facemark = FacemarkLBF::create(params); Ptr<Facemark> facemark = FacemarkLBF::create(params);
facemark->setFaceDetector(myDetector); facemark->setFaceDetector((FN_FaceDetector)myDetector, &face_cascade);
facemark->loadModel(params.model_filename.c_str()); facemark->loadModel(params.model_filename.c_str());
VideoCapture capture(video_path); VideoCapture capture(video_path);
...@@ -115,23 +115,20 @@ int main(int argc, char** argv ){ ...@@ -115,23 +115,20 @@ int main(int argc, char** argv ){
waitKey(0); // key press to close window 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; Mat gray;
std::vector<Rect> & faces = *(std::vector<Rect>*) ROIs.getObj();
faces.clear();
if(config!=0){
//do nothing
}
if(image.channels()>1){ if (image.channels() > 1)
cvtColor(image.getMat(),gray,CV_BGR2GRAY); cvtColor(image, gray, COLOR_BGR2GRAY);
}else{ else
gray = image.getMat().clone(); 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<Rect> faces_;
face_cascade->detectMultiScale(gray, faces_, 1.4, 2, CASCADE_SCALE_IMAGE, Size(30, 30));
Mat(faces_).copyTo(faces);
return true; return true;
} }
......
// 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.
/* /*
By downloading, copying, installing or using the software you agree to this This file contains results of GSoC Project: Facemark API for OpenCV
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 was part of GSoC Project: Facemark API for OpenCV
Final report: https://gist.github.com/kurnianggoro/74de9121e122ad0bd825176751d47ecc Final report: https://gist.github.com/kurnianggoro/74de9121e122ad0bd825176751d47ecc
Student: Laksono Kurnianggoro Student: Laksono Kurnianggoro
Mentor: Delia Passalacqua Mentor: Delia Passalacqua
*/ */
#include "precomp.hpp"
#include "opencv2/face.hpp" #include "opencv2/face.hpp"
#include "opencv2/core.hpp" #include "opencv2/core.hpp"
#include "precomp.hpp"
/*dataset parser*/ /*dataset parser*/
#include <fstream> #include <fstream>
...@@ -46,33 +22,35 @@ Mentor: Delia Passalacqua ...@@ -46,33 +22,35 @@ Mentor: Delia Passalacqua
namespace cv { namespace cv {
namespace face { namespace face {
using namespace std;
CParams::CParams(String s, double sf, int minN, Size minSz, Size maxSz){ CParams::CParams(String s, double sf, int minN, Size minSz, Size maxSz){
cascade = s; cascade = s;
scaleFactor = sf; scaleFactor = sf;
minNeighbors = minN; minNeighbors = minN;
minSize = minSz; minSize = minSz;
maxSize = maxSz; 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; Mat gray;
std::vector<Rect> roi; std::vector<Rect> roi;
if(parameters!=0){ cvtColor(image.getMat(), gray, COLOR_BGR2GRAY);
CParams * params = (CParams *)parameters; equalizeHist(gray, gray);
cvtColor( image.getMat(), gray, CV_BGR2GRAY );
equalizeHist( gray, gray );
CascadeClassifier face_cascade; params->face_cascade.detectMultiScale( gray, roi, params->scaleFactor, params->minNeighbors, CASCADE_SCALE_IMAGE, params->minSize, params->maxSize);
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;
}
Mat(roi).copyTo(faces);
return true;
} }
bool loadDatasetList(String imageList, String groundTruth, std::vector<String> & images, std::vector<String> & landmarks){ bool loadDatasetList(String imageList, String groundTruth, std::vector<String> & images, std::vector<String> & landmarks){
...@@ -111,14 +89,14 @@ bool loadTrainingData(String filename, std::vector<String> & images, OutputArray ...@@ -111,14 +89,14 @@ bool loadTrainingData(String filename, std::vector<String> & images, OutputArray
std::vector<Point2f> pts; std::vector<Point2f> pts;
std::vector<float> raw; std::vector<float> raw;
// FIXIT
std::vector<std::vector<Point2f> > & facePoints = std::vector<std::vector<Point2f> > & facePoints =
*(std::vector<std::vector<Point2f> >*) _facePoints.getObj(); *(std::vector<std::vector<Point2f> >*) _facePoints.getObj();
std::ifstream infile; std::ifstream infile;
infile.open(filename.c_str(), std::ios::in); infile.open(filename.c_str(), std::ios::in);
if (!infile) { if (!infile) {
std::string error_message = "No valid input file was given, please check the given filename."; CV_Error_(Error::StsBadArg, ("No valid input file was given, please check the given filename: %s", filename.c_str()));
CV_Error(CV_StsBadArg, error_message);
} }
/*clear the output containers*/ /*clear the output containers*/
...@@ -154,6 +132,7 @@ bool loadTrainingData(String imageList, String groundTruth, std::vector<String> ...@@ -154,6 +132,7 @@ bool loadTrainingData(String imageList, String groundTruth, std::vector<String>
std::string line; std::string line;
std::vector<Point2f> facePts; std::vector<Point2f> facePts;
// FIXIT
std::vector<std::vector<Point2f> > & facePoints = std::vector<std::vector<Point2f> > & facePoints =
*(std::vector<std::vector<Point2f> >*) _facePoints.getObj(); *(std::vector<std::vector<Point2f> >*) _facePoints.getObj();
...@@ -165,8 +144,7 @@ bool loadTrainingData(String imageList, String groundTruth, std::vector<String> ...@@ -165,8 +144,7 @@ bool loadTrainingData(String imageList, String groundTruth, std::vector<String>
std::ifstream infile; std::ifstream infile;
infile.open(imageList.c_str(), std::ios::in); infile.open(imageList.c_str(), std::ios::in);
if (!infile) { if (!infile) {
std::string error_message = "No valid input file was given, please check the given filename."; CV_Error_(Error::StsBadArg, ("No valid input file was given, please check the given filename: %s", imageList.c_str()));
CV_Error(CV_StsBadArg, error_message);
} }
while (getline (infile, line)){ while (getline (infile, line)){
...@@ -185,7 +163,7 @@ bool loadTrainingData(String imageList, String groundTruth, std::vector<String> ...@@ -185,7 +163,7 @@ bool loadTrainingData(String imageList, String groundTruth, std::vector<String>
} }
bool loadFacePoints(String filename, OutputArray points, float offset){ bool loadFacePoints(String filename, OutputArray points, float offset){
std::vector<Point2f> & pts = *(std::vector<Point2f> *)points.getObj(); vector<Point2f> pts;
std::string line, item; std::string line, item;
std::ifstream infile(filename.c_str()); std::ifstream infile(filename.c_str());
...@@ -222,16 +200,16 @@ bool loadFacePoints(String filename, OutputArray points, float offset){ ...@@ -222,16 +200,16 @@ bool loadFacePoints(String filename, OutputArray points, float offset){
} }
Mat(pts).copyTo(points);
return true; return true;
} }
void drawFacemarks(InputOutputArray image, InputArray points, Scalar color){ void drawFacemarks(InputOutputArray image, InputArray points, Scalar color){
Mat img = image.getMat(); Mat img = image.getMat();
std::vector<Point2f> pts = *(std::vector<Point2f>*)points.getObj(); vector<Point2f> pts = points.getMat();
for(size_t i=0;i<pts.size();i++){ for(size_t i=0;i<pts.size();i++){
circle(img, pts[i],3, color,-1); circle(img, pts[i],3, color,-1);
} }
} //drawPoints }
} /* namespace face */ } /* namespace face */
} /* namespace cv */ } /* namespace cv */
// 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.
/* /*
By downloading, copying, installing or using the software you agree to this This file contains results of GSoC Project: Facemark API for OpenCV
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 was part of GSoC Project: Facemark API for OpenCV
Final report: https://gist.github.com/kurnianggoro/74de9121e122ad0bd825176751d47ecc Final report: https://gist.github.com/kurnianggoro/74de9121e122ad0bd825176751d47ecc
Student: Laksono Kurnianggoro Student: Laksono Kurnianggoro
Mentor: Delia Passalacqua Mentor: Delia Passalacqua
*/ */
#include "opencv2/face.hpp"
#include "precomp.hpp" #include "precomp.hpp"
#include "opencv2/face.hpp"
namespace cv { namespace cv {
namespace face { namespace face {
...@@ -98,8 +73,8 @@ public: ...@@ -98,8 +73,8 @@ public:
void saveModel(String fs); void saveModel(String fs);
void loadModel(String fs); void loadModel(String fs);
bool setFaceDetector(bool(*f)(InputArray , OutputArray, void * )); bool setFaceDetector(bool(*f)(InputArray , OutputArray, void * ), void* userData);
bool getFaces( InputArray image ,OutputArray faces, void * extra_params); bool getFaces(InputArray image, OutputArray faces);
bool getData(void * items); bool getData(void * items);
...@@ -139,8 +114,8 @@ protected: ...@@ -139,8 +114,8 @@ protected:
std::vector<std::vector<Point2f> > facePoints; std::vector<std::vector<Point2f> > facePoints;
FacemarkAAM::Params params; FacemarkAAM::Params params;
FacemarkAAM::Model AAM; FacemarkAAM::Model AAM;
bool(*faceDetector)(InputArray , OutputArray, void *); FN_FaceDetector faceDetector;
bool isSetDetector; void* faceDetectorData;
private: private:
bool isModelTrained; bool isModelTrained;
...@@ -154,9 +129,9 @@ Ptr<FacemarkAAM> FacemarkAAM::create(const FacemarkAAM::Params &parameters){ ...@@ -154,9 +129,9 @@ Ptr<FacemarkAAM> FacemarkAAM::create(const FacemarkAAM::Params &parameters){
} }
FacemarkAAMImpl::FacemarkAAMImpl( const FacemarkAAM::Params &parameters ) : FacemarkAAMImpl::FacemarkAAMImpl( const FacemarkAAM::Params &parameters ) :
params( parameters ) params( parameters ),
faceDetector(NULL), faceDetectorData(NULL)
{ {
isSetDetector =false;
isModelTrained = false; isModelTrained = false;
} }
...@@ -168,42 +143,30 @@ void FacemarkAAMImpl::write( cv::FileStorage& fs ) const { ...@@ -168,42 +143,30 @@ void FacemarkAAMImpl::write( cv::FileStorage& fs ) const {
params.write( fs ); params.write( fs );
} }
bool FacemarkAAMImpl::setFaceDetector(bool(*f)(InputArray , OutputArray, void *)){ bool FacemarkAAMImpl::setFaceDetector(bool(*f)(InputArray , OutputArray, void *), void* userData){
faceDetector = f; faceDetector = f;
isSetDetector = true; faceDetectorData = userData;
return true; return true;
} }
bool FacemarkAAMImpl::getFaces( InputArray image , OutputArray roi, void * extra_params){ bool FacemarkAAMImpl::getFaces(InputArray image, OutputArray faces)
{
if(!isSetDetector){ if (!faceDetector)
return false; return false;
} return faceDetector(image, faces, faceDetectorData);
if(extra_params!=0){
//do nothing
}
std::vector<Rect> faces;
faces.clear();
faceDetector(image.getMat(), faces, extra_params);
Mat(faces).copyTo(roi);
return true;
} }
bool FacemarkAAMImpl::getData(void * items){ bool FacemarkAAMImpl::getData(void * items){
if(items==0){ CV_Assert(items);
return true;
}else{ Data* data = (Data*)items;
Data * data = (Data*)items; data->s0 = AAM.s0;
data->s0 = AAM.s0; return true;
return true;
}
} }
bool FacemarkAAMImpl::addTrainingSample(InputArray image, InputArray landmarks){ bool FacemarkAAMImpl::addTrainingSample(InputArray image, InputArray landmarks){
// FIXIT
std::vector<Point2f> & _landmarks = *(std::vector<Point2f>*)landmarks.getObj(); std::vector<Point2f> & _landmarks = *(std::vector<Point2f>*)landmarks.getObj();
images.push_back(image.getMat()); images.push_back(image.getMat());
...@@ -215,14 +178,11 @@ bool FacemarkAAMImpl::addTrainingSample(InputArray image, InputArray landmarks){ ...@@ -215,14 +178,11 @@ bool FacemarkAAMImpl::addTrainingSample(InputArray image, InputArray landmarks){
void FacemarkAAMImpl::training(void* parameters){ void FacemarkAAMImpl::training(void* parameters){
if(parameters!=0){/*do nothing*/} if(parameters!=0){/*do nothing*/}
if (images.size()<1) { if (images.size()<1) {
std::string error_message = CV_Error(Error::StsBadArg, "Training data is not provided. Consider to add using addTrainingSample() function!");
"Training data is not provided. Consider to add using addTrainingSample() function!";
CV_Error(CV_StsBadArg, error_message);
} }
if(strcmp(params.model_filename.c_str(),"")==0 && params.save_model){ if(strcmp(params.model_filename.c_str(),"")==0 && params.save_model){
std::string error_message = "The model_filename parameter should be set!"; CV_Error(Error::StsBadArg, "The model_filename parameter should be set!");
CV_Error(CV_StsBadArg, error_message);
} }
std::vector<std::vector<Point2f> > normalized; std::vector<std::vector<Point2f> > normalized;
...@@ -297,7 +257,7 @@ void FacemarkAAMImpl::training(void* parameters){ ...@@ -297,7 +257,7 @@ void FacemarkAAMImpl::training(void* parameters){
Mat T= texture_feats.t(); Mat T= texture_feats.t();
/* -------------- E. Create the texture model -----------------*/ /* -------------- 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"); if(params.verbose) printf("(2/4) Compute the feature average ...\n");
Mat A0_mtx = repeat(AAM.textures[scale].A0,1,T.cols); Mat A0_mtx = repeat(AAM.textures[scale].A0,1,T.cols);
...@@ -341,9 +301,7 @@ bool FacemarkAAMImpl::fit( InputArray image, InputArray roi, InputOutputArray _l ...@@ -341,9 +301,7 @@ bool FacemarkAAMImpl::fit( InputArray image, InputArray roi, InputOutputArray _l
std::vector<Config> conf = *(std::vector<Config>*)runtime_params; std::vector<Config> conf = *(std::vector<Config>*)runtime_params;
if (conf.size()!=faces.size()) { if (conf.size()!=faces.size()) {
std::string error_message = CV_Error(Error::StsBadArg, "Number of faces and extra_parameters are different!");
"Number of faces and extra_parameters are different!";
CV_Error(CV_StsBadArg, error_message);
} }
for(size_t i=0; i<conf.size();i++){ for(size_t i=0; i<conf.size();i++){
fitImpl(img, landmarks[i], conf[i].R,conf[i].t, conf[i].scale, conf[i].model_scale_idx); fitImpl(img, landmarks[i], conf[i].R,conf[i].t, conf[i].scale, conf[i].model_scale_idx);
...@@ -386,7 +344,7 @@ bool FacemarkAAMImpl::fitImpl( const Mat image, std::vector<Point2f>& landmarks, ...@@ -386,7 +344,7 @@ bool FacemarkAAMImpl::fitImpl( const Mat image, std::vector<Point2f>& landmarks,
Mat imgray; Mat imgray;
Mat img; Mat img;
if(image.channels()>1){ if(image.channels()>1){
cvtColor(image,imgray,CV_BGR2GRAY); cvtColor(image,imgray,COLOR_BGR2GRAY);
}else{ }else{
imgray = image; imgray = image;
} }
...@@ -564,8 +522,8 @@ Mat FacemarkAAMImpl::procrustes(std::vector<Point2f> P, std::vector<Point2f> Q, ...@@ -564,8 +522,8 @@ Mat FacemarkAAMImpl::procrustes(std::vector<Point2f> P, std::vector<Point2f> Q,
// calculate the sum // calculate the sum
Mat sumXs, sumYs; Mat sumXs, sumYs;
reduce(Xs,sumXs, 0, CV_REDUCE_SUM); reduce(Xs,sumXs, 0, REDUCE_SUM);
reduce(Ys,sumYs, 0, CV_REDUCE_SUM); reduce(Ys,sumYs, 0, REDUCE_SUM);
//calculate the normrnd //calculate the normrnd
double normX = sqrt(Mat(sumXs.reshape(1)).at<float>(0)+Mat(sumXs.reshape(1)).at<float>(1)); double normX = sqrt(Mat(sumXs.reshape(1)).at<float>(0)+Mat(sumXs.reshape(1)).at<float>(1));
...@@ -901,7 +859,7 @@ Mat FacemarkAAMImpl::warpImage( ...@@ -901,7 +859,7 @@ Mat FacemarkAAMImpl::warpImage(
Mat image,part, warped_part; Mat image,part, warped_part;
if(img.channels()>1){ if(img.channels()>1){
cvtColor(img,image,CV_BGR2GRAY); cvtColor(img,image,COLOR_BGR2GRAY);
}else{ }else{
image = img; image = img;
} }
......
This diff is collapsed.
...@@ -52,5 +52,7 @@ ...@@ -52,5 +52,7 @@
#include <set> #include <set>
#include <limits> #include <limits>
#include <iostream>
#endif #endif
/* // This file is part of OpenCV project.
By downloading, copying, installing or using the software you agree to this // It is subject to the license terms in the LICENSE file found in the top-level directory
license. If you do not agree to this license, do not download, install, // of this distribution and at http://opencv.org/license.html.
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 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 Final report: https://gist.github.com/kurnianggoro/74de9121e122ad0bd825176751d47ecc
Student: Laksono Kurnianggoro Student: Laksono Kurnianggoro
Mentor: Delia Passalacqua Mentor: Delia Passalacqua
......
// 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.
/* /*
By downloading, copying, installing or using the software you agree to this This file contains results of GSoC Project: Facemark API for OpenCV
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 was part of GSoC Project: Facemark API for OpenCV
Final report: https://gist.github.com/kurnianggoro/74de9121e122ad0bd825176751d47ecc Final report: https://gist.github.com/kurnianggoro/74de9121e122ad0bd825176751d47ecc
Student: Laksono Kurnianggoro Student: Laksono Kurnianggoro
Mentor: Delia Passalacqua Mentor: Delia Passalacqua
...@@ -50,24 +25,19 @@ using namespace std; ...@@ -50,24 +25,19 @@ using namespace std;
using namespace cv; using namespace cv;
using namespace cv::face; using namespace cv::face;
CascadeClassifier face_detector; static bool customDetector( InputArray image, OutputArray ROIs, CascadeClassifier *face_detector){
static bool customDetector( InputArray image, OutputArray ROIs, void * config = 0 ){
Mat gray; Mat gray;
std::vector<Rect> & faces = *(std::vector<Rect>*) ROIs.getObj(); std::vector<Rect> & faces = *(std::vector<Rect>*) ROIs.getObj();
faces.clear(); faces.clear();
if(config!=0){
//do nothing
}
if(image.channels()>1){ if(image.channels()>1){
cvtColor(image.getMat(),gray,CV_BGR2GRAY); cvtColor(image.getMat(),gray, COLOR_BGR2GRAY);
}else{ }else{
gray = image.getMat().clone(); gray = image.getMat().clone();
} }
equalizeHist( gray, gray ); 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; return true;
} }
...@@ -82,11 +52,11 @@ TEST(CV_Face_FacemarkAAM, can_create_default) { ...@@ -82,11 +52,11 @@ TEST(CV_Face_FacemarkAAM, can_create_default) {
TEST(CV_Face_FacemarkAAM, can_set_custom_detector) { TEST(CV_Face_FacemarkAAM, can_set_custom_detector) {
string cascade_filename = string cascade_filename =
cvtest::findDataFile("cascadeandhog/cascades/lbpcascade_frontalface.xml", true); cvtest::findDataFile("cascadeandhog/cascades/lbpcascade_frontalface.xml", true);
CascadeClassifier face_detector;
EXPECT_TRUE(face_detector.load(cascade_filename)); EXPECT_TRUE(face_detector.load(cascade_filename));
Ptr<Facemark> facemark = FacemarkAAM::create(); Ptr<Facemark> 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) { TEST(CV_Face_FacemarkAAM, test_workflow) {
...@@ -106,6 +76,9 @@ TEST(CV_Face_FacemarkAAM, test_workflow) { ...@@ -106,6 +76,9 @@ TEST(CV_Face_FacemarkAAM, test_workflow) {
string cascade_filename = string cascade_filename =
cvtest::findDataFile("cascadeandhog/cascades/lbpcascade_frontalface.xml", true); cvtest::findDataFile("cascadeandhog/cascades/lbpcascade_frontalface.xml", true);
CascadeClassifier face_detector;
EXPECT_TRUE(face_detector.load(cascade_filename));
FacemarkAAM::Params params; FacemarkAAM::Params params;
params.n = 1; params.n = 1;
params.m = 1; params.m = 1;
...@@ -115,7 +88,8 @@ TEST(CV_Face_FacemarkAAM, test_workflow) { ...@@ -115,7 +88,8 @@ TEST(CV_Face_FacemarkAAM, test_workflow) {
Mat image; Mat image;
std::vector<Point2f> landmarks; std::vector<Point2f> landmarks;
for(size_t i=0;i<images_train.size();i++){ for(size_t i=0;i<images_train.size();i++)
{
image = imread(images_train[i].c_str()); image = imread(images_train[i].c_str());
EXPECT_TRUE(loadFacePoints(points_train[i].c_str(),landmarks)); EXPECT_TRUE(loadFacePoints(points_train[i].c_str(),landmarks));
EXPECT_TRUE(landmarks.size()>0); EXPECT_TRUE(landmarks.size()>0);
...@@ -125,7 +99,7 @@ TEST(CV_Face_FacemarkAAM, test_workflow) { ...@@ -125,7 +99,7 @@ TEST(CV_Face_FacemarkAAM, test_workflow) {
EXPECT_NO_THROW(facemark->training()); EXPECT_NO_THROW(facemark->training());
/*------------ Fitting Part ---------------*/ /*------------ 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); string image_filename = cvtest::findDataFile("face/david1.jpg", true);
image = imread(image_filename.c_str()); image = imread(image_filename.c_str());
EXPECT_TRUE(!image.empty()); EXPECT_TRUE(!image.empty());
......
// 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.
/* /*
By downloading, copying, installing or using the software you agree to this This file contains results of GSoC Project: Facemark API for OpenCV
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 was part of GSoC Project: Facemark API for OpenCV
Final report: https://gist.github.com/kurnianggoro/74de9121e122ad0bd825176751d47ecc Final report: https://gist.github.com/kurnianggoro/74de9121e122ad0bd825176751d47ecc
Student: Laksono Kurnianggoro Student: Laksono Kurnianggoro
Mentor: Delia Passalacqua Mentor: Delia Passalacqua
...@@ -61,13 +36,13 @@ static bool myCustomDetector( InputArray image, OutputArray ROIs, void * config ...@@ -61,13 +36,13 @@ static bool myCustomDetector( InputArray image, OutputArray ROIs, void * config
} }
if(image.channels()>1){ if(image.channels()>1){
cvtColor(image.getMat(),gray,CV_BGR2GRAY); cvtColor(image.getMat(),gray,COLOR_BGR2GRAY);
}else{ }else{
gray = image.getMat().clone(); gray = image.getMat().clone();
} }
equalizeHist( gray, gray ); 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; return true;
} }
...@@ -141,8 +116,3 @@ TEST(CV_Face_FacemarkLBF, test_workflow) { ...@@ -141,8 +116,3 @@ TEST(CV_Face_FacemarkLBF, test_workflow) {
EXPECT_TRUE(facemark->fit(image, rects, facial_points)); EXPECT_TRUE(facemark->fit(image, rects, facial_points));
EXPECT_TRUE(facial_points[0].size()>0); EXPECT_TRUE(facial_points[0].size()>0);
} }
TEST(CV_Face_FacemarkLBF, get_data) {
Ptr<Facemark> facemark = FacemarkLBF::create();
EXPECT_TRUE(facemark->getData());
}
...@@ -69,31 +69,25 @@ struct Conf { ...@@ -69,31 +69,25 @@ struct Conf {
Conf(cv::String s, double d){ Conf(cv::String s, double d){
model_path = s; model_path = s;
scaleFactor = d; 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; Mat gray;
std::vector<Rect> & faces = *(std::vector<Rect>*) roi.getObj();
faces.clear();
if(config!=0){
Conf* conf = (Conf*)config;
if(image.channels()>1){ if (image.channels() > 1)
cvtColor(image,gray,CV_BGR2GRAY); cvtColor(image, gray, COLOR_BGR2GRAY);
}else{ else
gray = image.getMat().clone(); gray = image.getMat().clone();
}
equalizeHist( gray, gray );
CascadeClassifier face_cascade(conf->model_path); equalizeHist(gray, gray);
face_cascade.detectMultiScale( gray, faces, conf->scaleFactor, 2, CV_HAAR_SCALE_IMAGE, Size(30, 30) );
return true;
}else{
return false;
}
std::vector<Rect> faces_;
conf->face_cascade.detectMultiScale(gray, faces_, conf->scaleFactor, 2, CASCADE_SCALE_IMAGE, Size(30, 30) );
Mat(faces_).copyTo(faces);
return true;
} }
@endcode @endcode
...@@ -101,8 +95,8 @@ bool myDetector( InputArray image, OutputArray roi, void * config ){ ...@@ -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. 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 @code
Conf* config = new Conf("../data/lbpcascade_frontalface.xml",1.4); Conf config("../data/lbpcascade_frontalface.xml", 1.4);
facemark->setFaceDetector(myDetector); facemark->setFaceDetector(myDetector, &config); // we must guarantee proper lifetime of "config" object
@endcode @endcode
Here is the snippet for detecting face using the user defined face detector function. Here is the snippet for detecting face using the user defined face detector function.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment