Commit 1864cc4c authored by Vadim Pisarevsky's avatar Vadim Pisarevsky

Merge pull request #1239 from sovrasov:face_refactoring

parents b593cae0 087210de
...@@ -318,7 +318,7 @@ public: ...@@ -318,7 +318,7 @@ public:
The suffix const means that prediction does not affect the internal model state, so the method can The suffix const means that prediction does not affect the internal model state, so the method can
be safely called from within different threads. be safely called from within different threads.
*/ */
CV_WRAP virtual void save(const String& filename) const; CV_WRAP virtual void write(const String& filename) const;
/** @brief Loads a FaceRecognizer and its model state. /** @brief Loads a FaceRecognizer and its model state.
...@@ -327,16 +327,16 @@ public: ...@@ -327,16 +327,16 @@ public:
FaceRecognizer::load(FileStorage& fs) in turn gets called by FaceRecognizer::load(FileStorage& fs) in turn gets called by
FaceRecognizer::load(const String& filename), to ease saving a model. FaceRecognizer::load(const String& filename), to ease saving a model.
*/ */
CV_WRAP virtual void load(const String& filename); CV_WRAP virtual void read(const String& filename);
/** @overload /** @overload
Saves this model to a given FileStorage. Saves this model to a given FileStorage.
@param fs The FileStorage to store this FaceRecognizer to. @param fs The FileStorage to store this FaceRecognizer to.
*/ */
virtual void save(FileStorage& fs) const = 0; virtual void write(FileStorage& fs) const = 0;
/** @overload */ /** @overload */
virtual void load(const FileStorage& fs) = 0; virtual void read(const FileNode& fn) = 0;
/** @brief Sets string info for the specified model's label. /** @brief Sets string info for the specified model's label.
......
...@@ -68,14 +68,14 @@ public: ...@@ -68,14 +68,14 @@ public:
*/ */
CV_WRAP virtual void compute(InputArray image, CV_WRAP virtual void compute(InputArray image,
OutputArray features) const = 0; OutputArray features) const = 0;
};
/** /**
* @param num_bands The number of filter bands (<=8) used for computing BIF. * @param num_bands The number of filter bands (<=8) used for computing BIF.
* @param num_rotations The number of image rotations for computing BIF. * @param num_rotations The number of image rotations for computing BIF.
* @returns Object for computing BIF. * @returns Object for computing BIF.
*/ */
CV_EXPORTS_W cv::Ptr<BIF> createBIF(int num_bands = 8, int num_rotations = 12); CV_WRAP static Ptr<BIF> create(int num_bands = 8, int num_rotations = 12);
};
} // namespace cv } // namespace cv
} // namespace face } // namespace face
......
...@@ -121,14 +121,14 @@ int main(int argc, const char *argv[]) { ...@@ -121,14 +121,14 @@ int main(int argc, const char *argv[]) {
// 10 principal components (read Eigenfaces), then call // 10 principal components (read Eigenfaces), then call
// the factory method like this: // the factory method like this:
// //
// cv::createEigenFaceRecognizer(10); // EigenFaceRecognizer::create(10);
// //
// If you want to create a FaceRecognizer with a // If you want to create a FaceRecognizer with a
// confidennce threshold, call it with: // confidennce threshold, call it with:
// //
// cv::createEigenFaceRecognizer(10, 123.0); // EigenFaceRecognizer::create(10, 123.0);
// //
Ptr<BasicFaceRecognizer> model = createEigenFaceRecognizer(); Ptr<EigenFaceRecognizer> model = EigenFaceRecognizer::create();
for( int i = 0; i < nlabels; i++ ) for( int i = 0; i < nlabels; i++ )
model->setLabelInfo(i, labelsInfo[i]); model->setLabelInfo(i, labelsInfo[i]);
model->train(images, labels); model->train(images, labels);
......
...@@ -115,19 +115,19 @@ int main(int argc, const char *argv[]) { ...@@ -115,19 +115,19 @@ int main(int argc, const char *argv[]) {
// 10 principal components (read Eigenfaces), then call // 10 principal components (read Eigenfaces), then call
// the factory method like this: // the factory method like this:
// //
// cv::createEigenFaceRecognizer(10); // EigenFaceRecognizer::create(10);
// //
// If you want to create a FaceRecognizer with a // If you want to create a FaceRecognizer with a
// confidence threshold (e.g. 123.0), call it with: // confidence threshold (e.g. 123.0), call it with:
// //
// cv::createEigenFaceRecognizer(10, 123.0); // EigenFaceRecognizer::create(10, 123.0);
// //
// If you want to use _all_ Eigenfaces and have a threshold, // If you want to use _all_ Eigenfaces and have a threshold,
// then call the method like this: // then call the method like this:
// //
// cv::createEigenFaceRecognizer(0, 123.0); // EigenFaceRecognizer::create(0, 123.0);
// //
Ptr<BasicFaceRecognizer> model = createEigenFaceRecognizer(); Ptr<EigenFaceRecognizer> model = EigenFaceRecognizer::create();
model->train(images, labels); model->train(images, labels);
// The following line predicts the label of a given // The following line predicts the label of a given
// test image: // test image:
......
...@@ -114,7 +114,7 @@ int main(int argc, const char *argv[]) { ...@@ -114,7 +114,7 @@ int main(int argc, const char *argv[]) {
// If you just want to keep 10 Fisherfaces, then call // If you just want to keep 10 Fisherfaces, then call
// the factory method like this: // the factory method like this:
// //
// cv::createFisherFaceRecognizer(10); // FisherFaceRecognizer::create(10);
// //
// However it is not useful to discard Fisherfaces! Please // However it is not useful to discard Fisherfaces! Please
// always try to use _all_ available Fisherfaces for // always try to use _all_ available Fisherfaces for
...@@ -124,9 +124,9 @@ int main(int argc, const char *argv[]) { ...@@ -124,9 +124,9 @@ int main(int argc, const char *argv[]) {
// confidence threshold (e.g. 123.0) and use _all_ // confidence threshold (e.g. 123.0) and use _all_
// Fisherfaces, then call it with: // Fisherfaces, then call it with:
// //
// cv::createFisherFaceRecognizer(0, 123.0); // FisherFaceRecognizer::create(0, 123.0);
// //
Ptr<BasicFaceRecognizer> model = createFisherFaceRecognizer(); Ptr<FisherFaceRecognizer> model = FisherFaceRecognizer::create();
model->train(images, labels); model->train(images, labels);
// The following line predicts the label of a given // The following line predicts the label of a given
// test image: // test image:
......
...@@ -103,7 +103,7 @@ int main(int argc, const char *argv[]) { ...@@ -103,7 +103,7 @@ int main(int argc, const char *argv[]) {
// //
// cv::createLBPHFaceRecognizer(1,8,8,8,123.0) // cv::createLBPHFaceRecognizer(1,8,8,8,123.0)
// //
Ptr<LBPHFaceRecognizer> model = createLBPHFaceRecognizer(); Ptr<LBPHFaceRecognizer> model = LBPHFaceRecognizer::create();
model->train(images, labels); model->train(images, labels);
// The following line predicts the label of a given // The following line predicts the label of a given
// test image: // test image:
......
...@@ -127,7 +127,7 @@ int main(int argc, const char *argv[]) { ...@@ -127,7 +127,7 @@ int main(int argc, const char *argv[]) {
// //
// cv::createEigenFaceRecognizer(0, 123.0); // cv::createEigenFaceRecognizer(0, 123.0);
// //
Ptr<BasicFaceRecognizer> model0 = createEigenFaceRecognizer(); Ptr<EigenFaceRecognizer> model0 = EigenFaceRecognizer::create();
model0->train(images, labels); model0->train(images, labels);
// save the model to eigenfaces_at.yaml // save the model to eigenfaces_at.yaml
model0->save("eigenfaces_at.yml"); model0->save("eigenfaces_at.yml");
...@@ -135,8 +135,7 @@ int main(int argc, const char *argv[]) { ...@@ -135,8 +135,7 @@ int main(int argc, const char *argv[]) {
// //
// Now create a new Eigenfaces Recognizer // Now create a new Eigenfaces Recognizer
// //
Ptr<BasicFaceRecognizer> model1 = createEigenFaceRecognizer(); Ptr<EigenFaceRecognizer> model1 = Algorithm::load<EigenFaceRecognizer>("eigenfaces_at.yml");
model1->load("eigenfaces_at.yml");
// The following line predicts the label of a given // The following line predicts the label of a given
// test image: // test image:
int predictedLabel = model1->predict(testSample); int predictedLabel = model1->predict(testSample);
......
...@@ -79,7 +79,7 @@ int main(int argc, const char *argv[]) { ...@@ -79,7 +79,7 @@ int main(int argc, const char *argv[]) {
int im_width = images[0].cols; int im_width = images[0].cols;
int im_height = images[0].rows; int im_height = images[0].rows;
// Create a FaceRecognizer and train it on the given images: // Create a FaceRecognizer and train it on the given images:
Ptr<BasicFaceRecognizer> model = createFisherFaceRecognizer(); Ptr<FisherFaceRecognizer> model = FisherFaceRecognizer::create();
model->train(images, labels); model->train(images, labels);
// That's it for learning the Face Recognition model. You now // That's it for learning the Face Recognition model. You now
// need to create the classifier for the task of Face Detection. // need to create the classifier for the task of Face Detection.
......
...@@ -216,6 +216,6 @@ void BIFImpl::computeUnit(int unit_idx, const cv::Mat &img, ...@@ -216,6 +216,6 @@ void BIFImpl::computeUnit(int unit_idx, const cv::Mat &img,
} // namespace } // namespace
cv::Ptr<cv::face::BIF> cv::face::createBIF(int num_bands, int num_rotations) { cv::Ptr<cv::face::BIF> cv::face::BIF::create(int num_bands, int num_rotations) {
return cv::Ptr<cv::face::BIF>(new BIFImpl(num_bands, num_rotations)); return cv::Ptr<cv::face::BIF>(new BIFImpl(num_bands, num_rotations));
} }
...@@ -16,7 +16,8 @@ ...@@ -16,7 +16,8 @@
* See <http://www.opensource.org/licenses/bsd-license> * See <http://www.opensource.org/licenses/bsd-license>
*/ */
#include "precomp.hpp" #include "precomp.hpp"
#include "face_basic.hpp" #include <opencv2/face.hpp>
#include "face_utils.hpp"
#include <set> #include <set>
#include <limits> #include <limits>
#include <iostream> #include <iostream>
...@@ -28,14 +29,17 @@ namespace face ...@@ -28,14 +29,17 @@ namespace face
// Turk, M., and Pentland, A. "Eigenfaces for recognition.". Journal of // Turk, M., and Pentland, A. "Eigenfaces for recognition.". Journal of
// Cognitive Neuroscience 3 (1991), 71–86. // Cognitive Neuroscience 3 (1991), 71–86.
class Eigenfaces : public BasicFaceRecognizerImpl class Eigenfaces : public EigenFaceRecognizer
{ {
public: public:
// Initializes an empty Eigenfaces model. // Initializes an empty Eigenfaces model.
Eigenfaces(int num_components = 0, double threshold = DBL_MAX) Eigenfaces(int num_components = 0, double threshold = DBL_MAX)
: BasicFaceRecognizerImpl(num_components, threshold) //: BasicFaceRecognizerImpl(num_components, threshold)
{} {
_num_components = num_components;
_threshold = threshold;
}
// Computes an Eigenfaces model with images in src and corresponding labels // Computes an Eigenfaces model with images in src and corresponding labels
// in labels. // in labels.
...@@ -122,7 +126,7 @@ void Eigenfaces::predict(InputArray _src, Ptr<PredictCollector> collector) const ...@@ -122,7 +126,7 @@ void Eigenfaces::predict(InputArray _src, Ptr<PredictCollector> collector) const
} }
} }
Ptr<BasicFaceRecognizer> createEigenFaceRecognizer(int num_components, double threshold) Ptr<EigenFaceRecognizer> EigenFaceRecognizer::create(int num_components, double threshold)
{ {
return makePtr<Eigenfaces>(num_components, threshold); return makePtr<Eigenfaces>(num_components, threshold);
} }
......
#include "opencv2/face.hpp"
#include "face_utils.hpp"
#include "precomp.hpp"
using namespace cv;
using namespace face;
int BasicFaceRecognizer::getNumComponents() const
{
return _num_components;
}
void BasicFaceRecognizer::setNumComponents(int val)
{
_num_components = val;
}
double BasicFaceRecognizer::getThreshold() const
{
return _threshold;
}
void BasicFaceRecognizer::setThreshold(double val)
{
_threshold = val;
}
std::vector<cv::Mat> BasicFaceRecognizer::getProjections() const
{
return _projections;
}
cv::Mat BasicFaceRecognizer::getLabels() const
{
return _labels;
}
cv::Mat BasicFaceRecognizer::getEigenValues() const
{
return _eigenvalues;
}
cv::Mat BasicFaceRecognizer::getEigenVectors() const
{
return _eigenvectors;
}
cv::Mat BasicFaceRecognizer::getMean() const
{
return _mean;
}
void BasicFaceRecognizer::read(const FileNode& fs)
{
//read matrices
fs["num_components"] >> _num_components;
fs["mean"] >> _mean;
fs["eigenvalues"] >> _eigenvalues;
fs["eigenvectors"] >> _eigenvectors;
// read sequences
readFileNodeList(fs["projections"], _projections);
fs["labels"] >> _labels;
const FileNode& fn = fs["labelsInfo"];
if (fn.type() == FileNode::SEQ)
{
_labelsInfo.clear();
for (FileNodeIterator it = fn.begin(); it != fn.end();)
{
LabelInfo item;
it >> item;
_labelsInfo.insert(std::make_pair(item.label, item.value));
}
}
}
void BasicFaceRecognizer::write(FileStorage& fs) const
{
// write matrices
fs << "num_components" << _num_components;
fs << "mean" << _mean;
fs << "eigenvalues" << _eigenvalues;
fs << "eigenvectors" << _eigenvectors;
// write sequences
writeFileNodeList(fs, "projections", _projections);
fs << "labels" << _labels;
fs << "labelsInfo" << "[";
for (std::map<int, String>::const_iterator it = _labelsInfo.begin(); it != _labelsInfo.end(); it++)
fs << LabelInfo(it->first, it->second);
fs << "]";
}
#ifndef __OPENCV_FACE_BASIC_HPP // This file is part of OpenCV project.
#define __OPENCV_FACE_BASIC_HPP // 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.
#include "opencv2/face.hpp" #ifndef __OPENCV_FACE_UTILS_HPP
#include "precomp.hpp" #define __OPENCV_FACE_UTILS_HPP
#include <set> #include "precomp.hpp"
#include <limits>
#include <iostream>
using namespace cv; using namespace cv;
// Reads a sequence from a FileNode::SEQ with type _Tp into a result vector.
template<typename _Tp>
inline void readFileNodeList(const FileNode& fn, std::vector<_Tp>& result) {
if (fn.type() == FileNode::SEQ) {
for (FileNodeIterator it = fn.begin(); it != fn.end();) {
_Tp item;
it >> item;
result.push_back(item);
}
}
}
// Writes the a list of given items to a cv::FileStorage.
template<typename _Tp>
inline void writeFileNodeList(FileStorage& fs, const String& name,
const std::vector<_Tp>& items) {
// typedefs
typedef typename std::vector<_Tp>::const_iterator constVecIterator;
// write the elements in item to fs
fs << name << "[";
for (constVecIterator it = items.begin(); it != items.end(); ++it) {
fs << *it;
}
fs << "]";
}
inline Mat asRowMatrix(InputArrayOfArrays src, int rtype, double alpha=1, double beta=0) { inline Mat asRowMatrix(InputArrayOfArrays src, int rtype, double alpha=1, double beta=0) {
// make sure the input data is a vector of matrices or vector of vector // make sure the input data is a vector of matrices or vector of vector
if(src.kind() != _InputArray::STD_VECTOR_MAT && src.kind() != _InputArray::STD_VECTOR_VECTOR) { if(src.kind() != _InputArray::STD_VECTOR_MAT && src.kind() != _InputArray::STD_VECTOR_VECTOR) {
...@@ -70,6 +43,32 @@ inline Mat asRowMatrix(InputArrayOfArrays src, int rtype, double alpha=1, double ...@@ -70,6 +43,32 @@ inline Mat asRowMatrix(InputArrayOfArrays src, int rtype, double alpha=1, double
return data; return data;
} }
// Reads a sequence from a FileNode::SEQ with type _Tp into a result vector.
template<typename _Tp>
inline void readFileNodeList(const FileNode& fn, std::vector<_Tp>& result) {
if (fn.type() == FileNode::SEQ) {
for (FileNodeIterator it = fn.begin(); it != fn.end();) {
_Tp item;
it >> item;
result.push_back(item);
}
}
}
// Writes the a list of given items to a cv::FileStorage.
template<typename _Tp>
inline void writeFileNodeList(FileStorage& fs, const String& name,
const std::vector<_Tp>& items) {
// typedefs
typedef typename std::vector<_Tp>::const_iterator constVecIterator;
// write the elements in item to fs
fs << name << "[";
for (constVecIterator it = items.begin(); it != items.end(); ++it) {
fs << *it;
}
fs << "]";
}
// Utility structure to load/save face label info (a pair of int and string) via FileStorage // Utility structure to load/save face label info (a pair of int and string) via FileStorage
struct LabelInfo struct LabelInfo
{ {
...@@ -106,70 +105,4 @@ inline void read(const cv::FileNode& node, LabelInfo& x, const LabelInfo& defaul ...@@ -106,70 +105,4 @@ inline void read(const cv::FileNode& node, LabelInfo& x, const LabelInfo& defaul
x.read(node); x.read(node);
} }
#endif
class BasicFaceRecognizerImpl : public cv::face::BasicFaceRecognizer
{
public:
BasicFaceRecognizerImpl(int num_components = 0, double threshold = DBL_MAX)
: _num_components(num_components), _threshold(threshold)
{}
void load(const FileStorage& fs)
{
//read matrices
fs["num_components"] >> _num_components;
fs["mean"] >> _mean;
fs["eigenvalues"] >> _eigenvalues;
fs["eigenvectors"] >> _eigenvectors;
// read sequences
readFileNodeList(fs["projections"], _projections);
fs["labels"] >> _labels;
const FileNode& fn = fs["labelsInfo"];
if (fn.type() == FileNode::SEQ)
{
_labelsInfo.clear();
for (FileNodeIterator it = fn.begin(); it != fn.end();)
{
LabelInfo item;
it >> item;
_labelsInfo.insert(std::make_pair(item.label, item.value));
}
}
}
void save(FileStorage& fs) const
{
// write matrices
fs << "num_components" << _num_components;
fs << "mean" << _mean;
fs << "eigenvalues" << _eigenvalues;
fs << "eigenvectors" << _eigenvectors;
// write sequences
writeFileNodeList(fs, "projections", _projections);
fs << "labels" << _labels;
fs << "labelsInfo" << "[";
for (std::map<int, String>::const_iterator it = _labelsInfo.begin(); it != _labelsInfo.end(); it++)
fs << LabelInfo(it->first, it->second);
fs << "]";
}
CV_IMPL_PROPERTY(int, NumComponents, _num_components)
CV_IMPL_PROPERTY(double, Threshold, _threshold)
CV_IMPL_PROPERTY_RO(std::vector<cv::Mat>, Projections, _projections)
CV_IMPL_PROPERTY_RO(cv::Mat, Labels, _labels)
CV_IMPL_PROPERTY_RO(cv::Mat, EigenValues, _eigenvalues)
CV_IMPL_PROPERTY_RO(cv::Mat, EigenVectors, _eigenvectors)
CV_IMPL_PROPERTY_RO(cv::Mat, Mean, _mean)
protected:
int _num_components;
double _threshold;
std::vector<Mat> _projections;
Mat _labels;
Mat _eigenvectors;
Mat _eigenvalues;
Mat _mean;
};
#endif // __OPENCV_FACE_BASIC_HPP
...@@ -54,21 +54,21 @@ void FaceRecognizer::update(InputArrayOfArrays src, InputArray labels) ...@@ -54,21 +54,21 @@ void FaceRecognizer::update(InputArrayOfArrays src, InputArray labels)
CV_Error(Error::StsNotImplemented, error_msg); CV_Error(Error::StsNotImplemented, error_msg);
} }
void FaceRecognizer::load(const String &filename) void FaceRecognizer::read(const String &filename)
{ {
FileStorage fs(filename, FileStorage::READ); FileStorage fs(filename, FileStorage::READ);
if (!fs.isOpened()) if (!fs.isOpened())
CV_Error(Error::StsError, "File can't be opened for reading!"); CV_Error(Error::StsError, "File can't be opened for reading!");
this->load(fs); this->read(fs.root());
fs.release(); fs.release();
} }
void FaceRecognizer::save(const String &filename) const void FaceRecognizer::write(const String &filename) const
{ {
FileStorage fs(filename, FileStorage::WRITE); FileStorage fs(filename, FileStorage::WRITE);
if (!fs.isOpened()) if (!fs.isOpened())
CV_Error(Error::StsError, "File can't be opened for writing!"); CV_Error(Error::StsError, "File can't be opened for writing!");
this->save(fs); this->write(fs);
fs.release(); fs.release();
} }
......
...@@ -16,7 +16,8 @@ ...@@ -16,7 +16,8 @@
* See <http://www.opensource.org/licenses/bsd-license> * See <http://www.opensource.org/licenses/bsd-license>
*/ */
#include "precomp.hpp" #include "precomp.hpp"
#include "face_basic.hpp" #include <opencv2/face.hpp>
#include "face_utils.hpp"
namespace cv { namespace face { namespace cv { namespace face {
...@@ -24,13 +25,16 @@ namespace cv { namespace face { ...@@ -24,13 +25,16 @@ namespace cv { namespace face {
// faces: Recognition using class specific linear projection.". IEEE // faces: Recognition using class specific linear projection.". IEEE
// Transactions on Pattern Analysis and Machine Intelligence 19, 7 (1997), // Transactions on Pattern Analysis and Machine Intelligence 19, 7 (1997),
// 711–720. // 711–720.
class Fisherfaces: public BasicFaceRecognizerImpl class Fisherfaces: public FisherFaceRecognizer
{ {
public: public:
// Initializes an empty Fisherfaces model. // Initializes an empty Fisherfaces model.
Fisherfaces(int num_components = 0, double threshold = DBL_MAX) Fisherfaces(int num_components = 0, double threshold = DBL_MAX)
: BasicFaceRecognizerImpl(num_components, threshold) //: BasicFaceRecognizer(num_components, threshold)
{ } {
_num_components = num_components;
_threshold = threshold;
}
// Computes a Fisherfaces model with images in src and corresponding labels // Computes a Fisherfaces model with images in src and corresponding labels
// in labels. // in labels.
...@@ -142,7 +146,7 @@ void Fisherfaces::predict(InputArray _src, Ptr<PredictCollector> collector) cons ...@@ -142,7 +146,7 @@ void Fisherfaces::predict(InputArray _src, Ptr<PredictCollector> collector) cons
} }
} }
Ptr<BasicFaceRecognizer> createFisherFaceRecognizer(int num_components, double threshold) Ptr<FisherFaceRecognizer> FisherFaceRecognizer::create(int num_components, double threshold)
{ {
return makePtr<Fisherfaces>(num_components, threshold); return makePtr<Fisherfaces>(num_components, threshold);
} }
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
*/ */
#include "precomp.hpp" #include "precomp.hpp"
#include "opencv2/face.hpp" #include "opencv2/face.hpp"
#include "face_basic.hpp" #include "face_utils.hpp"
namespace cv { namespace face { namespace cv { namespace face {
...@@ -46,8 +46,8 @@ private: ...@@ -46,8 +46,8 @@ private:
public: public:
using FaceRecognizer::save; using FaceRecognizer::read;
using FaceRecognizer::load; using FaceRecognizer::write;
// Initializes this LBPH Model. The current implementation is rather fixed // Initializes this LBPH Model. The current implementation is rather fixed
// as it uses the Extended Local Binary Patterns per default. // as it uses the Extended Local Binary Patterns per default.
...@@ -94,11 +94,11 @@ public: ...@@ -94,11 +94,11 @@ public:
// Send all predict results to caller side for custom result handling // Send all predict results to caller side for custom result handling
void predict(InputArray src, Ptr<PredictCollector> collector) const; void predict(InputArray src, Ptr<PredictCollector> collector) const;
// See FaceRecognizer::load. // See FaceRecognizer::write.
void load(const FileStorage& fs); void read(const FileNode& fn);
// See FaceRecognizer::save. // See FaceRecognizer::save.
void save(FileStorage& fs) const; void write(FileStorage& fs) const;
CV_IMPL_PROPERTY(int, GridX, _grid_x) CV_IMPL_PROPERTY(int, GridX, _grid_x)
CV_IMPL_PROPERTY(int, GridY, _grid_y) CV_IMPL_PROPERTY(int, GridY, _grid_y)
...@@ -110,7 +110,7 @@ public: ...@@ -110,7 +110,7 @@ public:
}; };
void LBPH::load(const FileStorage& fs) { void LBPH::read(const FileNode& fs) {
fs["radius"] >> _radius; fs["radius"] >> _radius;
fs["neighbors"] >> _neighbors; fs["neighbors"] >> _neighbors;
fs["grid_x"] >> _grid_x; fs["grid_x"] >> _grid_x;
...@@ -132,7 +132,7 @@ void LBPH::load(const FileStorage& fs) { ...@@ -132,7 +132,7 @@ void LBPH::load(const FileStorage& fs) {
} }
// See FaceRecognizer::save. // See FaceRecognizer::save.
void LBPH::save(FileStorage& fs) const { void LBPH::write(FileStorage& fs) const {
fs << "radius" << _radius; fs << "radius" << _radius;
fs << "neighbors" << _neighbors; fs << "neighbors" << _neighbors;
fs << "grid_x" << _grid_x; fs << "grid_x" << _grid_x;
...@@ -407,11 +407,10 @@ void LBPH::predict(InputArray _src, Ptr<PredictCollector> collector) const { ...@@ -407,11 +407,10 @@ void LBPH::predict(InputArray _src, Ptr<PredictCollector> collector) const {
} }
} }
Ptr<LBPHFaceRecognizer> createLBPHFaceRecognizer(int radius, int neighbors, Ptr<LBPHFaceRecognizer> LBPHFaceRecognizer::create(int radius, int neighbors,
int grid_x, int grid_y, double threshold) int grid_x, int grid_y, double threshold)
{ {
return makePtr<LBPH>(radius, neighbors, grid_x, grid_y, threshold); return makePtr<LBPH>(radius, neighbors, grid_x, grid_y, threshold);
} }
}} }}
...@@ -49,10 +49,8 @@ ...@@ -49,10 +49,8 @@
#include "opencv2/core/private.hpp" #include "opencv2/core/private.hpp"
#include "opencv2/core/persistence.hpp" #include "opencv2/core/persistence.hpp"
#include <map> #include <map>
#include <iostream>
#include <set> #include <set>
#include <limits> #include <limits>
#include <iostream>
#endif #endif
...@@ -40,27 +40,27 @@ the use of this software, even if advised of the possibility of such damage. ...@@ -40,27 +40,27 @@ the use of this software, even if advised of the possibility of such damage.
TEST(CV_Face_BIF, can_create_default) { TEST(CV_Face_BIF, can_create_default) {
cv::Ptr<cv::face::BIF> bif; cv::Ptr<cv::face::BIF> bif;
EXPECT_NO_THROW(bif = cv::face::createBIF()); EXPECT_NO_THROW(bif = cv::face::BIF::create());
EXPECT_FALSE(bif.empty()); EXPECT_FALSE(bif.empty());
} }
TEST(CV_Face_BIF, fails_when_zero_bands) { TEST(CV_Face_BIF, fails_when_zero_bands) {
EXPECT_ANY_THROW(cv::face::createBIF(0)); EXPECT_ANY_THROW(cv::face::BIF::create(0));
} }
TEST(CV_Face_BIF, fails_when_too_many_bands) { TEST(CV_Face_BIF, fails_when_too_many_bands) {
EXPECT_ANY_THROW(cv::face::createBIF(9)); EXPECT_ANY_THROW(cv::face::BIF::create(9));
} }
TEST(CV_Face_BIF, fails_when_zero_rotations) { TEST(CV_Face_BIF, fails_when_zero_rotations) {
EXPECT_ANY_THROW(cv::face::createBIF(8, 0)); EXPECT_ANY_THROW(cv::face::BIF::create(8, 0));
} }
TEST(CV_Face_BIF, can_compute) { TEST(CV_Face_BIF, can_compute) {
cv::Mat image(60, 60, CV_32F); cv::Mat image(60, 60, CV_32F);
cv::theRNG().fill(image, cv::RNG::UNIFORM, -1, 1); cv::theRNG().fill(image, cv::RNG::UNIFORM, -1, 1);
cv::Ptr<cv::face::BIF> bif = cv::face::createBIF(); cv::Ptr<cv::face::BIF> bif = cv::face::BIF::create();
cv::Mat fea; cv::Mat fea;
EXPECT_NO_THROW(bif->compute(image, fea)); EXPECT_NO_THROW(bif->compute(image, fea));
EXPECT_EQ(cv::Size(1, 13188), fea.size()); EXPECT_EQ(cv::Size(1, 13188), fea.size());
......
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