Merge pull request #169 from mshabunin/remove-algorithm-factory

Remove algorithm factory
pull/139/merge
Vadim Pisarevsky 10 years ago
commit 23314751aa
  1. 2
      modules/bgsegm/src/bgfg_gaussmix.cpp
  2. 2
      modules/bgsegm/src/bgfg_gmg.cpp
  3. 21
      modules/datasets/samples/ar_hmdb_benchmark.cpp
  4. 312
      modules/face/include/opencv2/face.hpp
  5. 323
      modules/face/include/opencv2/face/facerec.hpp
  6. 8
      modules/face/samples/facerec_demo.cpp
  7. 144
      modules/face/src/eigen_faces.cpp
  8. 175
      modules/face/src/face_basic.hpp
  9. 1013
      modules/face/src/facerec.cpp
  10. 163
      modules/face/src/fisher_faces.cpp
  11. 430
      modules/face/src/lbph_faces.cpp
  12. 8
      modules/face/src/precomp.hpp
  13. 6
      modules/line_descriptor/include/opencv2/line_descriptor.hpp
  14. 13
      modules/line_descriptor/include/opencv2/line_descriptor/descriptor.hpp
  15. 64
      modules/line_descriptor/src/line_descriptor_init.cpp
  16. 2
      modules/optflow/src/deepflow.cpp
  17. 2
      modules/optflow/src/interfaces.cpp
  18. 94
      modules/rgbd/include/opencv2/rgbd.hpp
  19. 4
      modules/rgbd/samples/odometry_evaluation.cpp
  20. 37
      modules/rgbd/src/odometry.cpp
  21. 119
      modules/rgbd/src/rgbd_init.cpp
  22. 2
      modules/rgbd/test/test_normal.cpp
  23. 8
      modules/rgbd/test/test_odometry.cpp
  24. 8
      modules/saliency/include/opencv2/saliency.hpp
  25. 14
      modules/saliency/include/opencv2/saliency/saliencySpecializedClasses.hpp
  26. 10
      modules/saliency/src/saliency.cpp
  27. 73
      modules/saliency/src/saliency_init.cpp
  28. 6
      modules/tracking/include/opencv2/tracking.hpp
  29. 1
      modules/tracking/include/opencv2/tracking/tracker.hpp
  30. 4
      modules/tracking/src/tracker.cpp
  31. 53
      modules/tracking/src/tracking_init.cpp
  32. 2
      modules/xfeatures2d/include/opencv2/xfeatures2d/cuda.hpp
  33. 15
      modules/xfeatures2d/samples/bagofwords_classification.cpp
  34. 5
      modules/xfeatures2d/src/surf.cuda.cpp
  35. 7
      modules/ximgproc/include/opencv2/ximgproc/edge_filter.hpp
  36. 27
      modules/ximgproc/src/adaptive_manifold_filter_n.cpp
  37. 6
      modules/ximgproc/test/test_adaptive_manifold.cpp
  38. 25
      modules/ximgproc/test/test_adaptive_manifold_ref_impl.cpp
  39. 11
      modules/xobjdetect/include/opencv2/xobjdetect.hpp

@ -122,8 +122,6 @@ public:
bgmodel = Scalar::all(0);
}
virtual AlgorithmInfo* info() const { return 0; }
virtual void getBackgroundImage(OutputArray) const
{
CV_Error( Error::StsNotImplemented, "" );

@ -81,8 +81,6 @@ public:
{
}
virtual AlgorithmInfo* info() const { return 0; }
/**
* Validate parameters and set up data structures for appropriate image size.
* Must call before running on data.

@ -188,17 +188,16 @@ int main(int argc, char *argv[])
fillData(path, curr, flann_index, trainData, trainLabels);
printf("train svm\n");
SVM::Params params;
params.svmType = SVM::C_SVC;
params.kernelType = SVM::POLY; //SVM::RBF;
params.degree = 0.5;
params.gamma = 1;
params.coef0 = 1;
params.C = 1;
params.nu = 0.5;
params.p = 0;
params.termCrit = TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS, 1000, 0.01);
Ptr<SVM> svm = SVM::create(params);
Ptr<SVM> svm = SVM::create();
svm->setType(SVM::C_SVC);
svm->setKernel(SVM::POLY); //SVM::RBF;
svm->setDegree(0.5);
svm->setGamma(1);
svm->setCoef0(1);
svm->setC(1);
svm->setNu(0.5);
svm->setP(0);
svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS, 1000, 0.01));
svm->train(trainData, ROW_SAMPLE, trainLabels);
// prepare to predict

@ -39,8 +39,6 @@ the use of this software, even if advised of the possibility of such damage.
#ifndef __OPENCV_FACE_HPP__
#define __OPENCV_FACE_HPP__
#include "opencv2/face/facerec.hpp"
/**
@defgroup face Face Recognition
@ -49,4 +47,314 @@ the use of this software, even if advised of the possibility of such damage.
*/
#include "opencv2/core.hpp"
#include <map>
namespace cv { namespace face {
//! @addtogroup face
//! @{
/** @brief Abstract base class for all face recognition models
All face recognition models in OpenCV are derived from the abstract base class FaceRecognizer, which
provides a unified access to all face recongition algorithms in OpenCV.
### Description
I'll go a bit more into detail explaining FaceRecognizer, because it doesn't look like a powerful
interface at first sight. But: Every FaceRecognizer is an Algorithm, so you can easily get/set all
model internals (if allowed by the implementation). Algorithm is a relatively new OpenCV concept,
which is available since the 2.4 release. I suggest you take a look at its description.
Algorithm provides the following features for all derived classes:
- So called virtual constructor. That is, each Algorithm derivative is registered at program
start and you can get the list of registered algorithms and create instance of a particular
algorithm by its name (see Algorithm::create). If you plan to add your own algorithms, it is
good practice to add a unique prefix to your algorithms to distinguish them from other
algorithms.
- Setting/Retrieving algorithm parameters by name. If you used video capturing functionality from
OpenCV highgui module, you are probably familar with cv::cvSetCaptureProperty,
ocvcvGetCaptureProperty, VideoCapture::set and VideoCapture::get. Algorithm provides similar
method where instead of integer id's you specify the parameter names as text Strings. See
Algorithm::set and Algorithm::get for details.
- Reading and writing parameters from/to XML or YAML files. Every Algorithm derivative can store
all its parameters and then read them back. There is no need to re-implement it each time.
Moreover every FaceRecognizer supports the:
- **Training** of a FaceRecognizer with FaceRecognizer::train on a given set of images (your face
database!).
- **Prediction** of a given sample image, that means a face. The image is given as a Mat.
- **Loading/Saving** the model state from/to a given XML or YAML.
- **Setting/Getting labels info**, that is stored as a string. String labels info is useful for
keeping names of the recognized people.
@note When using the FaceRecognizer interface in combination with Python, please stick to Python 2.
Some underlying scripts like create_csv will not work in other versions, like Python 3. Setting the
Thresholds +++++++++++++++++++++++
Sometimes you run into the situation, when you want to apply a threshold on the prediction. A common
scenario in face recognition is to tell, whether a face belongs to the training dataset or if it is
unknown. You might wonder, why there's no public API in FaceRecognizer to set the threshold for the
prediction, but rest assured: It's supported. It just means there's no generic way in an abstract
class to provide an interface for setting/getting the thresholds of *every possible* FaceRecognizer
algorithm. The appropriate place to set the thresholds is in the constructor of the specific
FaceRecognizer and since every FaceRecognizer is a Algorithm (see above), you can get/set the
thresholds at runtime!
Here is an example of setting a threshold for the Eigenfaces method, when creating the model:
@code
// Let's say we want to keep 10 Eigenfaces and have a threshold value of 10.0
int num_components = 10;
double threshold = 10.0;
// Then if you want to have a cv::FaceRecognizer with a confidence threshold,
// create the concrete implementation with the appropiate parameters:
Ptr<FaceRecognizer> model = createEigenFaceRecognizer(num_components, threshold);
@endcode
Sometimes it's impossible to train the model, just to experiment with threshold values. Thanks to
Algorithm it's possible to set internal model thresholds during runtime. Let's see how we would
set/get the prediction for the Eigenface model, we've created above:
@code
// The following line reads the threshold from the Eigenfaces model:
double current_threshold = model->getDouble("threshold");
// And this line sets the threshold to 0.0:
model->set("threshold", 0.0);
@endcode
If you've set the threshold to 0.0 as we did above, then:
@code
//
Mat img = imread("person1/3.jpg", CV_LOAD_IMAGE_GRAYSCALE);
// Get a prediction from the model. Note: We've set a threshold of 0.0 above,
// since the distance is almost always larger than 0.0, you'll get -1 as
// label, which indicates, this face is unknown
int predicted_label = model->predict(img);
// ...
@endcode
is going to yield -1 as predicted label, which states this face is unknown.
### Getting the name of a FaceRecognizer
Since every FaceRecognizer is a Algorithm, you can use Algorithm::name to get the name of a
FaceRecognizer:
@code
// Create a FaceRecognizer:
Ptr<FaceRecognizer> model = createEigenFaceRecognizer();
// And here's how to get its name:
String name = model->name();
@endcode
*/
class CV_EXPORTS_W FaceRecognizer : public Algorithm
{
public:
/** @brief Trains a FaceRecognizer with given data and associated labels.
@param src The training images, that means the faces you want to learn. The data has to be
given as a vector\<Mat\>.
@param labels The labels corresponding to the images have to be given either as a vector\<int\>
or a
The following source code snippet shows you how to learn a Fisherfaces model on a given set of
images. The images are read with imread and pushed into a std::vector\<Mat\>. The labels of each
image are stored within a std::vector\<int\> (you could also use a Mat of type CV_32SC1). Think of
the label as the subject (the person) this image belongs to, so same subjects (persons) should have
the same label. For the available FaceRecognizer you don't have to pay any attention to the order of
the labels, just make sure same persons have the same label:
@code
// holds images and labels
vector<Mat> images;
vector<int> labels;
// images for first person
images.push_back(imread("person0/0.jpg", CV_LOAD_IMAGE_GRAYSCALE)); labels.push_back(0);
images.push_back(imread("person0/1.jpg", CV_LOAD_IMAGE_GRAYSCALE)); labels.push_back(0);
images.push_back(imread("person0/2.jpg", CV_LOAD_IMAGE_GRAYSCALE)); labels.push_back(0);
// images for second person
images.push_back(imread("person1/0.jpg", CV_LOAD_IMAGE_GRAYSCALE)); labels.push_back(1);
images.push_back(imread("person1/1.jpg", CV_LOAD_IMAGE_GRAYSCALE)); labels.push_back(1);
images.push_back(imread("person1/2.jpg", CV_LOAD_IMAGE_GRAYSCALE)); labels.push_back(1);
@endcode
Now that you have read some images, we can create a new FaceRecognizer. In this example I'll create
a Fisherfaces model and decide to keep all of the possible Fisherfaces:
@code
// Create a new Fisherfaces model and retain all available Fisherfaces,
// this is the most common usage of this specific FaceRecognizer:
//
Ptr<FaceRecognizer> model = createFisherFaceRecognizer();
@endcode
And finally train it on the given dataset (the face images and labels):
@code
// This is the common interface to train all of the available cv::FaceRecognizer
// implementations:
//
model->train(images, labels);
@endcode
*/
CV_WRAP virtual void train(InputArrayOfArrays src, InputArray labels) = 0;
/** @brief Updates a FaceRecognizer with given data and associated labels.
@param src The training images, that means the faces you want to learn. The data has to be given
as a vector\<Mat\>.
@param labels The labels corresponding to the images have to be given either as a vector\<int\> or
a
This method updates a (probably trained) FaceRecognizer, but only if the algorithm supports it. The
Local Binary Patterns Histograms (LBPH) recognizer (see createLBPHFaceRecognizer) can be updated.
For the Eigenfaces and Fisherfaces method, this is algorithmically not possible and you have to
re-estimate the model with FaceRecognizer::train. In any case, a call to train empties the existing
model and learns a new model, while update does not delete any model data.
@code
// Create a new LBPH model (it can be updated) and use the default parameters,
// this is the most common usage of this specific FaceRecognizer:
//
Ptr<FaceRecognizer> model = createLBPHFaceRecognizer();
// This is the common interface to train all of the available cv::FaceRecognizer
// implementations:
//
model->train(images, labels);
// Some containers to hold new image:
vector<Mat> newImages;
vector<int> newLabels;
// You should add some images to the containers:
//
// ...
//
// Now updating the model is as easy as calling:
model->update(newImages,newLabels);
// This will preserve the old model data and extend the existing model
// with the new features extracted from newImages!
@endcode
Calling update on an Eigenfaces model (see createEigenFaceRecognizer), which doesn't support
updating, will throw an error similar to:
@code
OpenCV Error: The function/feature is not implemented (This FaceRecognizer (FaceRecognizer.Eigenfaces) does not support updating, you have to use FaceRecognizer::train to update it.) in update, file /home/philipp/git/opencv/modules/contrib/src/facerec.cpp, line 305
terminate called after throwing an instance of 'cv::Exception'
@endcode
@note The FaceRecognizer does not store your training images, because this would be very
memory intense and it's not the responsibility of te FaceRecognizer to do so. The caller is
responsible for maintaining the dataset, he want to work with.
*/
CV_WRAP virtual void update(InputArrayOfArrays src, InputArray labels);
/** @overload */
virtual int predict(InputArray src) const = 0;
/** @brief Predicts a label and associated confidence (e.g. distance) for a given input image.
@param src Sample image to get a prediction from.
@param label The predicted label for the given image.
@param confidence Associated confidence (e.g. distance) for the predicted label.
The suffix const means that prediction does not affect the internal model state, so the method can
be safely called from within different threads.
The following example shows how to get a prediction from a trained model:
@code
using namespace cv;
// Do your initialization here (create the cv::FaceRecognizer model) ...
// ...
// Read in a sample image:
Mat img = imread("person1/3.jpg", CV_LOAD_IMAGE_GRAYSCALE);
// And get a prediction from the cv::FaceRecognizer:
int predicted = model->predict(img);
@endcode
Or to get a prediction and the associated confidence (e.g. distance):
@code
using namespace cv;
// Do your initialization here (create the cv::FaceRecognizer model) ...
// ...
Mat img = imread("person1/3.jpg", CV_LOAD_IMAGE_GRAYSCALE);
// Some variables for the predicted label and associated confidence (e.g. distance):
int predicted_label = -1;
double predicted_confidence = 0.0;
// Get the prediction and associated confidence from the model
model->predict(img, predicted_label, predicted_confidence);
@endcode
*/
CV_WRAP virtual void predict(InputArray src, CV_OUT int &label, CV_OUT double &confidence) const = 0;
/** @brief Saves a FaceRecognizer and its model state.
Saves this model to a given filename, either as XML or YAML.
@param filename The filename to store this FaceRecognizer to (either XML/YAML).
Every FaceRecognizer overwrites FaceRecognizer::save(FileStorage& fs) to save the internal model
state. FaceRecognizer::save(const String& filename) saves the state of a model to the given
filename.
The suffix const means that prediction does not affect the internal model state, so the method can
be safely called from within different threads.
*/
CV_WRAP virtual void save(const String& filename) const;
/** @brief Loads a FaceRecognizer and its model state.
Loads a persisted model and state from a given XML or YAML file . Every FaceRecognizer has to
overwrite FaceRecognizer::load(FileStorage& fs) to enable loading the model state.
FaceRecognizer::load(FileStorage& fs) in turn gets called by
FaceRecognizer::load(const String& filename), to ease saving a model.
*/
CV_WRAP virtual void load(const String& filename);
/** @overload
Saves this model to a given FileStorage.
@param fs The FileStorage to store this FaceRecognizer to.
*/
virtual void save(FileStorage& fs) const = 0;
/** @overload */
virtual void load(const FileStorage& fs) = 0;
/** @brief Sets string info for the specified model's label.
The string info is replaced by the provided value if it was set before for the specified label.
*/
CV_WRAP virtual void setLabelInfo(int label, const String& strInfo);
/** @brief Gets string information by label.
If an unknown label id is provided or there is no label information associated with the specified
label id the method returns an empty string.
*/
CV_WRAP virtual String getLabelInfo(int label) const;
/** @brief Gets vector of labels by string.
The function searches for the labels containing the specified sub-string in the associated string
info.
*/
CV_WRAP virtual std::vector<int> getLabelsByString(const String& str) const;
protected:
// Stored pairs "label id - string info"
std::map<int, String> _labelsInfo;
};
//! @}
}}
#include "opencv2/face/facerec.hpp"
#endif

@ -8,6 +8,7 @@
#ifndef __OPENCV_FACEREC_HPP__
#define __OPENCV_FACEREC_HPP__
#include "opencv2/face.hpp"
#include "opencv2/core.hpp"
namespace cv { namespace face {
@ -15,299 +16,17 @@ namespace cv { namespace face {
//! @addtogroup face
//! @{
/** @brief Abstract base class for all face recognition models
All face recognition models in OpenCV are derived from the abstract base class FaceRecognizer, which
provides a unified access to all face recongition algorithms in OpenCV.
### Description
I'll go a bit more into detail explaining FaceRecognizer, because it doesn't look like a powerful
interface at first sight. But: Every FaceRecognizer is an Algorithm, so you can easily get/set all
model internals (if allowed by the implementation). Algorithm is a relatively new OpenCV concept,
which is available since the 2.4 release. I suggest you take a look at its description.
Algorithm provides the following features for all derived classes:
- So called virtual constructor. That is, each Algorithm derivative is registered at program
start and you can get the list of registered algorithms and create instance of a particular
algorithm by its name (see Algorithm::create). If you plan to add your own algorithms, it is
good practice to add a unique prefix to your algorithms to distinguish them from other
algorithms.
- Setting/Retrieving algorithm parameters by name. If you used video capturing functionality from
OpenCV highgui module, you are probably familar with cv::cvSetCaptureProperty,
ocvcvGetCaptureProperty, VideoCapture::set and VideoCapture::get. Algorithm provides similar
method where instead of integer id's you specify the parameter names as text Strings. See
Algorithm::set and Algorithm::get for details.
- Reading and writing parameters from/to XML or YAML files. Every Algorithm derivative can store
all its parameters and then read them back. There is no need to re-implement it each time.
Moreover every FaceRecognizer supports the:
- **Training** of a FaceRecognizer with FaceRecognizer::train on a given set of images (your face
database!).
- **Prediction** of a given sample image, that means a face. The image is given as a Mat.
- **Loading/Saving** the model state from/to a given XML or YAML.
- **Setting/Getting labels info**, that is stored as a string. String labels info is useful for
keeping names of the recognized people.
@note When using the FaceRecognizer interface in combination with Python, please stick to Python 2.
Some underlying scripts like create_csv will not work in other versions, like Python 3. Setting the
Thresholds +++++++++++++++++++++++
Sometimes you run into the situation, when you want to apply a threshold on the prediction. A common
scenario in face recognition is to tell, whether a face belongs to the training dataset or if it is
unknown. You might wonder, why there's no public API in FaceRecognizer to set the threshold for the
prediction, but rest assured: It's supported. It just means there's no generic way in an abstract
class to provide an interface for setting/getting the thresholds of *every possible* FaceRecognizer
algorithm. The appropriate place to set the thresholds is in the constructor of the specific
FaceRecognizer and since every FaceRecognizer is a Algorithm (see above), you can get/set the
thresholds at runtime!
Here is an example of setting a threshold for the Eigenfaces method, when creating the model:
@code
// Let's say we want to keep 10 Eigenfaces and have a threshold value of 10.0
int num_components = 10;
double threshold = 10.0;
// Then if you want to have a cv::FaceRecognizer with a confidence threshold,
// create the concrete implementation with the appropiate parameters:
Ptr<FaceRecognizer> model = createEigenFaceRecognizer(num_components, threshold);
@endcode
Sometimes it's impossible to train the model, just to experiment with threshold values. Thanks to
Algorithm it's possible to set internal model thresholds during runtime. Let's see how we would
set/get the prediction for the Eigenface model, we've created above:
@code
// The following line reads the threshold from the Eigenfaces model:
double current_threshold = model->getDouble("threshold");
// And this line sets the threshold to 0.0:
model->set("threshold", 0.0);
@endcode
If you've set the threshold to 0.0 as we did above, then:
@code
//
Mat img = imread("person1/3.jpg", CV_LOAD_IMAGE_GRAYSCALE);
// Get a prediction from the model. Note: We've set a threshold of 0.0 above,
// since the distance is almost always larger than 0.0, you'll get -1 as
// label, which indicates, this face is unknown
int predicted_label = model->predict(img);
// ...
@endcode
is going to yield -1 as predicted label, which states this face is unknown.
### Getting the name of a FaceRecognizer
Since every FaceRecognizer is a Algorithm, you can use Algorithm::name to get the name of a
FaceRecognizer:
@code
// Create a FaceRecognizer:
Ptr<FaceRecognizer> model = createEigenFaceRecognizer();
// And here's how to get its name:
String name = model->name();
@endcode
*/
class CV_EXPORTS_W FaceRecognizer : public Algorithm
// base for two classes
class CV_EXPORTS_W BasicFaceRecognizer : public FaceRecognizer
{
public:
//! virtual destructor
virtual ~FaceRecognizer() {}
/** @brief Trains a FaceRecognizer with given data and associated labels.
@param src The training images, that means the faces you want to learn. The data has to be
given as a vector\<Mat\>.
@param labels The labels corresponding to the images have to be given either as a vector\<int\>
or a
The following source code snippet shows you how to learn a Fisherfaces model on a given set of
images. The images are read with imread and pushed into a std::vector\<Mat\>. The labels of each
image are stored within a std::vector\<int\> (you could also use a Mat of type CV_32SC1). Think of
the label as the subject (the person) this image belongs to, so same subjects (persons) should have
the same label. For the available FaceRecognizer you don't have to pay any attention to the order of
the labels, just make sure same persons have the same label:
@code
// holds images and labels
vector<Mat> images;
vector<int> labels;
// images for first person
images.push_back(imread("person0/0.jpg", CV_LOAD_IMAGE_GRAYSCALE)); labels.push_back(0);
images.push_back(imread("person0/1.jpg", CV_LOAD_IMAGE_GRAYSCALE)); labels.push_back(0);
images.push_back(imread("person0/2.jpg", CV_LOAD_IMAGE_GRAYSCALE)); labels.push_back(0);
// images for second person
images.push_back(imread("person1/0.jpg", CV_LOAD_IMAGE_GRAYSCALE)); labels.push_back(1);
images.push_back(imread("person1/1.jpg", CV_LOAD_IMAGE_GRAYSCALE)); labels.push_back(1);
images.push_back(imread("person1/2.jpg", CV_LOAD_IMAGE_GRAYSCALE)); labels.push_back(1);
@endcode
Now that you have read some images, we can create a new FaceRecognizer. In this example I'll create
a Fisherfaces model and decide to keep all of the possible Fisherfaces:
@code
// Create a new Fisherfaces model and retain all available Fisherfaces,
// this is the most common usage of this specific FaceRecognizer:
//
Ptr<FaceRecognizer> model = createFisherFaceRecognizer();
@endcode
And finally train it on the given dataset (the face images and labels):
@code
// This is the common interface to train all of the available cv::FaceRecognizer
// implementations:
//
model->train(images, labels);
@endcode
*/
CV_WRAP virtual void train(InputArrayOfArrays src, InputArray labels) = 0;
/** @brief Updates a FaceRecognizer with given data and associated labels.
@param src The training images, that means the faces you want to learn. The data has to be given
as a vector\<Mat\>.
@param labels The labels corresponding to the images have to be given either as a vector\<int\> or
a
This method updates a (probably trained) FaceRecognizer, but only if the algorithm supports it. The
Local Binary Patterns Histograms (LBPH) recognizer (see createLBPHFaceRecognizer) can be updated.
For the Eigenfaces and Fisherfaces method, this is algorithmically not possible and you have to
re-estimate the model with FaceRecognizer::train. In any case, a call to train empties the existing
model and learns a new model, while update does not delete any model data.
@code
// Create a new LBPH model (it can be updated) and use the default parameters,
// this is the most common usage of this specific FaceRecognizer:
//
Ptr<FaceRecognizer> model = createLBPHFaceRecognizer();
// This is the common interface to train all of the available cv::FaceRecognizer
// implementations:
//
model->train(images, labels);
// Some containers to hold new image:
vector<Mat> newImages;
vector<int> newLabels;
// You should add some images to the containers:
//
// ...
//
// Now updating the model is as easy as calling:
model->update(newImages,newLabels);
// This will preserve the old model data and extend the existing model
// with the new features extracted from newImages!
@endcode
Calling update on an Eigenfaces model (see createEigenFaceRecognizer), which doesn't support
updating, will throw an error similar to:
@code
OpenCV Error: The function/feature is not implemented (This FaceRecognizer (FaceRecognizer.Eigenfaces) does not support updating, you have to use FaceRecognizer::train to update it.) in update, file /home/philipp/git/opencv/modules/contrib/src/facerec.cpp, line 305
terminate called after throwing an instance of 'cv::Exception'
@endcode
@note The FaceRecognizer does not store your training images, because this would be very
memory intense and it's not the responsibility of te FaceRecognizer to do so. The caller is
responsible for maintaining the dataset, he want to work with.
*/
CV_WRAP virtual void update(InputArrayOfArrays src, InputArray labels) = 0;
/** @overload */
virtual int predict(InputArray src) const = 0;
/** @brief Predicts a label and associated confidence (e.g. distance) for a given input image.
@param src Sample image to get a prediction from.
@param label The predicted label for the given image.
@param confidence Associated confidence (e.g. distance) for the predicted label.
The suffix const means that prediction does not affect the internal model state, so the method can
be safely called from within different threads.
The following example shows how to get a prediction from a trained model:
@code
using namespace cv;
// Do your initialization here (create the cv::FaceRecognizer model) ...
// ...
// Read in a sample image:
Mat img = imread("person1/3.jpg", CV_LOAD_IMAGE_GRAYSCALE);
// And get a prediction from the cv::FaceRecognizer:
int predicted = model->predict(img);
@endcode
Or to get a prediction and the associated confidence (e.g. distance):
@code
using namespace cv;
// Do your initialization here (create the cv::FaceRecognizer model) ...
// ...
Mat img = imread("person1/3.jpg", CV_LOAD_IMAGE_GRAYSCALE);
// Some variables for the predicted label and associated confidence (e.g. distance):
int predicted_label = -1;
double predicted_confidence = 0.0;
// Get the prediction and associated confidence from the model
model->predict(img, predicted_label, predicted_confidence);
@endcode
*/
CV_WRAP virtual void predict(InputArray src, CV_OUT int &label, CV_OUT double &confidence) const = 0;
/** @brief Saves a FaceRecognizer and its model state.
Saves this model to a given filename, either as XML or YAML.
@param filename The filename to store this FaceRecognizer to (either XML/YAML).
Every FaceRecognizer overwrites FaceRecognizer::save(FileStorage& fs) to save the internal model
state. FaceRecognizer::save(const String& filename) saves the state of a model to the given
filename.
The suffix const means that prediction does not affect the internal model state, so the method can
be safely called from within different threads.
*/
CV_WRAP virtual void save(const String& filename) const = 0;
/** @brief Loads a FaceRecognizer and its model state.
Loads a persisted model and state from a given XML or YAML file . Every FaceRecognizer has to
overwrite FaceRecognizer::load(FileStorage& fs) to enable loading the model state.
FaceRecognizer::load(FileStorage& fs) in turn gets called by
FaceRecognizer::load(const String& filename), to ease saving a model.
*/
CV_WRAP virtual void load(const String& filename) = 0;
/** @overload
Saves this model to a given FileStorage.
@param fs The FileStorage to store this FaceRecognizer to.
*/
virtual void save(FileStorage& fs) const = 0;
/** @overload */
virtual void load(const FileStorage& fs) = 0;
/** @brief Sets string info for the specified model's label.
The string info is replaced by the provided value if it was set before for the specified label.
*/
virtual void setLabelInfo(int label, const String& strInfo) = 0;
/** @brief Gets string information by label.
If an unknown label id is provided or there is no label information associated with the specified
label id the method returns an empty string.
*/
virtual String getLabelInfo(int label) const = 0;
/** @brief Gets vector of labels by string.
The function searches for the labels containing the specified sub-string in the associated string
info.
*/
virtual std::vector<int> getLabelsByString(const String& str) const = 0;
CV_PURE_PROPERTY(int, NumComponents)
CV_PURE_PROPERTY(double, Threshold)
CV_PURE_PROPERTY_RO(std::vector<cv::Mat>, Projections)
CV_PURE_PROPERTY_RO(cv::Mat, Labels)
CV_PURE_PROPERTY_RO(cv::Mat, EigenValues)
CV_PURE_PROPERTY_RO(cv::Mat, EigenVectors)
CV_PURE_PROPERTY_RO(cv::Mat, Mean)
};
/**
@ -339,7 +58,8 @@ number. Keeping 80 components should almost always be sufficient.
- labels The threshold applied in the prediction. If the distance to the nearest neighbor is
larger than the threshold, this method returns -1.
*/
CV_EXPORTS_W Ptr<FaceRecognizer> createEigenFaceRecognizer(int num_components = 0, double threshold = DBL_MAX);
CV_EXPORTS_W Ptr<BasicFaceRecognizer> createEigenFaceRecognizer(int num_components = 0, double threshold = DBL_MAX);
/**
@param num_components The number of components (read: Fisherfaces) kept for this Linear
Discriminant Analysis with the Fisherfaces criterion. It's useful to keep all components, that
@ -370,7 +90,20 @@ is larger than the threshold, this method returns -1.
- projections The projections of the training data.
- labels The labels corresponding to the projections.
*/
CV_EXPORTS_W Ptr<FaceRecognizer> createFisherFaceRecognizer(int num_components = 0, double threshold = DBL_MAX);
CV_EXPORTS_W Ptr<BasicFaceRecognizer> createFisherFaceRecognizer(int num_components = 0, double threshold = DBL_MAX);
class CV_EXPORTS_W LBPHFaceRecognizer : public FaceRecognizer
{
public:
CV_PURE_PROPERTY(int, GridX)
CV_PURE_PROPERTY(int, GridY)
CV_PURE_PROPERTY(int, Radius)
CV_PURE_PROPERTY(int, Neighbors)
CV_PURE_PROPERTY(double, Threshold)
CV_PURE_PROPERTY_RO(std::vector<cv::Mat>, Histograms)
CV_PURE_PROPERTY_RO(cv::Mat, Labels)
};
/**
@param radius The radius used for building the Circular Local Binary Pattern. The greater the
radius, the
@ -403,9 +136,7 @@ is larger than the threshold, this method returns -1.
none was given).
- labels Labels corresponding to the calculated Local Binary Patterns Histograms.
*/
CV_EXPORTS_W Ptr<FaceRecognizer> createLBPHFaceRecognizer(int radius=1, int neighbors=8, int grid_x=8, int grid_y=8, double threshold = DBL_MAX);
bool initModule_facerec();
CV_EXPORTS_W Ptr<LBPHFaceRecognizer> createLBPHFaceRecognizer(int radius=1, int neighbors=8, int grid_x=8, int grid_y=8, double threshold = DBL_MAX);
//! @}

@ -128,7 +128,7 @@ int main(int argc, const char *argv[]) {
//
// cv::createEigenFaceRecognizer(10, 123.0);
//
Ptr<FaceRecognizer> model = createEigenFaceRecognizer();
Ptr<BasicFaceRecognizer> model = createEigenFaceRecognizer();
for( int i = 0; i < nlabels; i++ )
model->setLabelInfo(i, labelsInfo[i]);
model->train(images, labels);
@ -162,16 +162,16 @@ int main(int argc, const char *argv[]) {
// to 0.0 without retraining the model. This can be useful if
// you are evaluating the model:
//
model->set("threshold", 0.0);
model->setThreshold(0.0);
// Now the threshold of this model is set to 0.0. A prediction
// now returns -1, as it's impossible to have a distance below
// it
predictedLabel = model->predict(testSample);
cout << "Predicted class = " << predictedLabel << endl;
// Here is how to get the eigenvalues of this Eigenfaces model:
Mat eigenvalues = model->getMat("eigenvalues");
Mat eigenvalues = model->getEigenValues();
// And we can do the same to display the Eigenvectors (read Eigenfaces):
Mat W = model->getMat("eigenvectors");
Mat W = model->getEigenVectors();
// From this we will display the (at most) first 10 Eigenfaces:
for (int i = 0; i < min(10, W.cols); i++) {
string msg = format("Eigenvalue #%d = %.5f", i, eigenvalues.at<double>(i));

@ -0,0 +1,144 @@
/*
* Copyright (c) 2011,2012. Philipp Wagner <bytefish[at]gmx[dot]de>.
* Released to public domain under terms of the BSD Simplified license.
*
* 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 name of the organization nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* See <http://www.opensource.org/licenses/bsd-license>
*/
#include "precomp.hpp"
#include "face_basic.hpp"
#include <set>
#include <limits>
#include <iostream>
namespace cv
{
namespace face
{
// Turk, M., and Pentland, A. "Eigenfaces for recognition.". Journal of
// Cognitive Neuroscience 3 (1991), 71–86.
class Eigenfaces : public BasicFaceRecognizerImpl
{
public:
// Initializes an empty Eigenfaces model.
Eigenfaces(int num_components = 0, double threshold = DBL_MAX)
: BasicFaceRecognizerImpl(num_components, threshold)
{}
// Computes an Eigenfaces model with images in src and corresponding labels
// in labels.
void train(InputArrayOfArrays src, InputArray labels);
// Predicts the label of a query image in src.
int predict(InputArray src) const;
// Predicts the label and confidence for a given sample.
void predict(InputArray _src, int &label, double &dist) const;
};
//------------------------------------------------------------------------------
// Eigenfaces
//------------------------------------------------------------------------------
void Eigenfaces::train(InputArrayOfArrays _src, InputArray _local_labels) {
if(_src.total() == 0) {
String error_message = format("Empty training data was given. You'll need more than one sample to learn a model.");
CV_Error(Error::StsBadArg, error_message);
} else if(_local_labels.getMat().type() != CV_32SC1) {
String error_message = format("Labels must be given as integer (CV_32SC1). Expected %d, but was %d.", CV_32SC1, _local_labels.type());
CV_Error(Error::StsBadArg, error_message);
}
// make sure data has correct size
if(_src.total() > 1) {
for(int i = 1; i < static_cast<int>(_src.total()); i++) {
if(_src.getMat(i-1).total() != _src.getMat(i).total()) {
String error_message = format("In the Eigenfaces method all input samples (training images) must be of equal size! Expected %d pixels, but was %d pixels.", _src.getMat(i-1).total(), _src.getMat(i).total());
CV_Error(Error::StsUnsupportedFormat, error_message);
}
}
}
// get labels
Mat labels = _local_labels.getMat();
// observations in row
Mat data = asRowMatrix(_src, CV_64FC1);
// number of samples
int n = data.rows;
// assert there are as much samples as labels
if(static_cast<int>(labels.total()) != n) {
String error_message = format("The number of samples (src) must equal the number of labels (labels)! len(src)=%d, len(labels)=%d.", n, labels.total());
CV_Error(Error::StsBadArg, error_message);
}
// clear existing model data
_labels.release();
_projections.clear();
// clip number of components to be valid
if((_num_components <= 0) || (_num_components > n))
_num_components = n;
// perform the PCA
PCA pca(data, Mat(), PCA::DATA_AS_ROW, _num_components);
// copy the PCA results
_mean = pca.mean.reshape(1,1); // store the mean vector
_eigenvalues = pca.eigenvalues.clone(); // eigenvalues by row
transpose(pca.eigenvectors, _eigenvectors); // eigenvectors by column
// store labels for prediction
_labels = labels.clone();
// save projections
for(int sampleIdx = 0; sampleIdx < data.rows; sampleIdx++) {
Mat p = LDA::subspaceProject(_eigenvectors, _mean, data.row(sampleIdx));
_projections.push_back(p);
}
}
void Eigenfaces::predict(InputArray _src, int &minClass, double &minDist) const {
// get data
Mat src = _src.getMat();
// make sure the user is passing correct data
if(_projections.empty()) {
// throw error if no data (or simply return -1?)
String error_message = "This Eigenfaces model is not computed yet. Did you call Eigenfaces::train?";
CV_Error(Error::StsError, error_message);
} else if(_eigenvectors.rows != static_cast<int>(src.total())) {
// check data alignment just for clearer exception messages
String error_message = format("Wrong input image size. Reason: Training and Test images must be of equal size! Expected an image with %d elements, but got %d.", _eigenvectors.rows, src.total());
CV_Error(Error::StsBadArg, error_message);
}
// project into PCA subspace
Mat q = LDA::subspaceProject(_eigenvectors, _mean, src.reshape(1,1));
minDist = DBL_MAX;
minClass = -1;
for(size_t sampleIdx = 0; sampleIdx < _projections.size(); sampleIdx++) {
double dist = norm(_projections[sampleIdx], q, NORM_L2);
if((dist < minDist) && (dist < _threshold)) {
minDist = dist;
minClass = _labels.at<int>((int)sampleIdx);
}
}
}
int Eigenfaces::predict(InputArray _src) const {
int label;
double dummy;
predict(_src, label, dummy);
return label;
}
Ptr<BasicFaceRecognizer> createEigenFaceRecognizer(int num_components, double threshold)
{
return makePtr<Eigenfaces>(num_components, threshold);
}
}
}

@ -0,0 +1,175 @@
#ifndef __OPENCV_FACE_BASIC_HPP
#define __OPENCV_FACE_BASIC_HPP
#include "opencv2/face.hpp"
#include "precomp.hpp"
#include <set>
#include <limits>
#include <iostream>
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) {
// 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) {
String error_message = "The data is expected as InputArray::STD_VECTOR_MAT (a std::vector<Mat>) or _InputArray::STD_VECTOR_VECTOR (a std::vector< std::vector<...> >).";
CV_Error(Error::StsBadArg, error_message);
}
// number of samples
size_t n = src.total();
// return empty matrix if no matrices given
if(n == 0)
return Mat();
// dimensionality of (reshaped) samples
size_t d = src.getMat(0).total();
// create data matrix
Mat data((int)n, (int)d, rtype);
// now copy data
for(unsigned int i = 0; i < n; i++) {
// make sure data can be reshaped, throw exception if not!
if(src.getMat(i).total() != d) {
String error_message = format("Wrong number of elements in matrix #%d! Expected %d was %d.", i, d, src.getMat(i).total());
CV_Error(Error::StsBadArg, error_message);
}
// get a hold of the current row
Mat xi = data.row(i);
// make reshape happy by cloning for non-continuous matrices
if(src.getMat(i).isContinuous()) {
src.getMat(i).reshape(1, 1).convertTo(xi, rtype, alpha, beta);
} else {
src.getMat(i).clone().reshape(1, 1).convertTo(xi, rtype, alpha, beta);
}
}
return data;
}
// Utility structure to load/save face label info (a pair of int and string) via FileStorage
struct LabelInfo
{
LabelInfo():label(-1), value("") {}
LabelInfo(int _label, const String &_value): label(_label), value(_value) {}
int label;
String value;
void write(cv::FileStorage& fs) const
{
fs << "{" << "label" << label << "value" << value << "}";
}
void read(const cv::FileNode& node)
{
label = (int)node["label"];
value = (String)node["value"];
}
std::ostream& operator<<(std::ostream& out)
{
out << "{ label = " << label << ", " << "value = " << value.c_str() << "}";
return out;
}
};
inline void write(cv::FileStorage& fs, const String&, const LabelInfo& x)
{
x.write(fs);
}
inline void read(const cv::FileNode& node, LabelInfo& x, const LabelInfo& default_value = LabelInfo())
{
if(node.empty())
x = default_value;
else
x.read(node);
}
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

File diff suppressed because it is too large Load Diff

@ -0,0 +1,163 @@
/*
* Copyright (c) 2011,2012. Philipp Wagner <bytefish[at]gmx[dot]de>.
* Released to public domain under terms of the BSD Simplified license.
*
* 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 name of the organization nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* See <http://www.opensource.org/licenses/bsd-license>
*/
#include "precomp.hpp"
#include "face_basic.hpp"
namespace cv { namespace face {
// Belhumeur, P. N., Hespanha, J., and Kriegman, D. "Eigenfaces vs. Fisher-
// faces: Recognition using class specific linear projection.". IEEE
// Transactions on Pattern Analysis and Machine Intelligence 19, 7 (1997),
// 711–720.
class Fisherfaces: public BasicFaceRecognizerImpl
{
public:
// Initializes an empty Fisherfaces model.
Fisherfaces(int num_components = 0, double threshold = DBL_MAX)
: BasicFaceRecognizerImpl(num_components, threshold)
{ }
// Computes a Fisherfaces model with images in src and corresponding labels
// in labels.
void train(InputArrayOfArrays src, InputArray labels);
// Predicts the label of a query image in src.
int predict(InputArray src) const;
// Predicts the label and confidence for a given sample.
void predict(InputArray _src, int &label, double &dist) const;
};
// Removes duplicate elements in a given vector.
template<typename _Tp>
inline std::vector<_Tp> remove_dups(const std::vector<_Tp>& src) {
typedef typename std::set<_Tp>::const_iterator constSetIterator;
typedef typename std::vector<_Tp>::const_iterator constVecIterator;
std::set<_Tp> set_elems;
for (constVecIterator it = src.begin(); it != src.end(); ++it)
set_elems.insert(*it);
std::vector<_Tp> elems;
for (constSetIterator it = set_elems.begin(); it != set_elems.end(); ++it)
elems.push_back(*it);
return elems;
}
//------------------------------------------------------------------------------
// Fisherfaces
//------------------------------------------------------------------------------
void Fisherfaces::train(InputArrayOfArrays src, InputArray _lbls) {
if(src.total() == 0) {
String error_message = format("Empty training data was given. You'll need more than one sample to learn a model.");
CV_Error(Error::StsBadArg, error_message);
} else if(_lbls.getMat().type() != CV_32SC1) {
String error_message = format("Labels must be given as integer (CV_32SC1). Expected %d, but was %d.", CV_32SC1, _lbls.type());
CV_Error(Error::StsBadArg, error_message);
}
// make sure data has correct size
if(src.total() > 1) {
for(int i = 1; i < static_cast<int>(src.total()); i++) {
if(src.getMat(i-1).total() != src.getMat(i).total()) {
String error_message = format("In the Fisherfaces method all input samples (training images) must be of equal size! Expected %d pixels, but was %d pixels.", src.getMat(i-1).total(), src.getMat(i).total());
CV_Error(Error::StsUnsupportedFormat, error_message);
}
}
}
// get data
Mat labels = _lbls.getMat();
Mat data = asRowMatrix(src, CV_64FC1);
// number of samples
int N = data.rows;
// make sure labels are passed in correct shape
if(labels.total() != (size_t) N) {
String error_message = format("The number of samples (src) must equal the number of labels (labels)! len(src)=%d, len(labels)=%d.", N, labels.total());
CV_Error(Error::StsBadArg, error_message);
} else if(labels.rows != 1 && labels.cols != 1) {
String error_message = format("Expected the labels in a matrix with one row or column! Given dimensions are rows=%s, cols=%d.", labels.rows, labels.cols);
CV_Error(Error::StsBadArg, error_message);
}
// clear existing model data
_labels.release();
_projections.clear();
// safely copy from cv::Mat to std::vector
std::vector<int> ll;
for(unsigned int i = 0; i < labels.total(); i++) {
ll.push_back(labels.at<int>(i));
}
// get the number of unique classes
int C = (int) remove_dups(ll).size();
// clip number of components to be a valid number
if((_num_components <= 0) || (_num_components > (C-1)))
_num_components = (C-1);
// perform a PCA and keep (N-C) components
PCA pca(data, Mat(), PCA::DATA_AS_ROW, (N-C));
// project the data and perform a LDA on it
LDA lda(pca.project(data),labels, _num_components);
// store the total mean vector
_mean = pca.mean.reshape(1,1);
// store labels
_labels = labels.clone();
// store the eigenvalues of the discriminants
lda.eigenvalues().convertTo(_eigenvalues, CV_64FC1);
// Now calculate the projection matrix as pca.eigenvectors * lda.eigenvectors.
// Note: OpenCV stores the eigenvectors by row, so we need to transpose it!
gemm(pca.eigenvectors, lda.eigenvectors(), 1.0, Mat(), 0.0, _eigenvectors, GEMM_1_T);
// store the projections of the original data
for(int sampleIdx = 0; sampleIdx < data.rows; sampleIdx++) {
Mat p = LDA::subspaceProject(_eigenvectors, _mean, data.row(sampleIdx));
_projections.push_back(p);
}
}
void Fisherfaces::predict(InputArray _src, int &minClass, double &minDist) const {
Mat src = _src.getMat();
// check data alignment just for clearer exception messages
if(_projections.empty()) {
// throw error if no data (or simply return -1?)
String error_message = "This Fisherfaces model is not computed yet. Did you call Fisherfaces::train?";
CV_Error(Error::StsBadArg, error_message);
} else if(src.total() != (size_t) _eigenvectors.rows) {
String error_message = format("Wrong input image size. Reason: Training and Test images must be of equal size! Expected an image with %d elements, but got %d.", _eigenvectors.rows, src.total());
CV_Error(Error::StsBadArg, error_message);
}
// project into LDA subspace
Mat q = LDA::subspaceProject(_eigenvectors, _mean, src.reshape(1,1));
// find 1-nearest neighbor
minDist = DBL_MAX;
minClass = -1;
for(size_t sampleIdx = 0; sampleIdx < _projections.size(); sampleIdx++) {
double dist = norm(_projections[sampleIdx], q, NORM_L2);
if((dist < minDist) && (dist < _threshold)) {
minDist = dist;
minClass = _labels.at<int>((int)sampleIdx);
}
}
}
int Fisherfaces::predict(InputArray _src) const {
int label;
double dummy;
predict(_src, label, dummy);
return label;
}
Ptr<BasicFaceRecognizer> createFisherFaceRecognizer(int num_components, double threshold)
{
return makePtr<Fisherfaces>(num_components, threshold);
}
} }

@ -0,0 +1,430 @@
/*
* Copyright (c) 2011,2012. Philipp Wagner <bytefish[at]gmx[dot]de>.
* Released to public domain under terms of the BSD Simplified license.
*
* 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 name of the organization nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* See <http://www.opensource.org/licenses/bsd-license>
*/
#include "precomp.hpp"
#include "opencv2/face.hpp"
#include "face_basic.hpp"
namespace cv { namespace face {
// Face Recognition based on Local Binary Patterns.
//
// Ahonen T, Hadid A. and Pietikäinen M. "Face description with local binary
// patterns: Application to face recognition." IEEE Transactions on Pattern
// Analysis and Machine Intelligence, 28(12):2037-2041.
//
class LBPH : public LBPHFaceRecognizer
{
private:
int _grid_x;
int _grid_y;
int _radius;
int _neighbors;
double _threshold;
std::vector<Mat> _histograms;
Mat _labels;
// Computes a LBPH model with images in src and
// corresponding labels in labels, possibly preserving
// old model data.
void train(InputArrayOfArrays src, InputArray labels, bool preserveData);
public:
using FaceRecognizer::save;
using FaceRecognizer::load;
// Initializes this LBPH Model. The current implementation is rather fixed
// as it uses the Extended Local Binary Patterns per default.
//
// radius, neighbors are used in the local binary patterns creation.
// grid_x, grid_y control the grid size of the spatial histograms.
LBPH(int radius_=1, int neighbors_=8,
int gridx=8, int gridy=8,
double threshold = DBL_MAX) :
_grid_x(gridx),
_grid_y(gridy),
_radius(radius_),
_neighbors(neighbors_),
_threshold(threshold) {}
// Initializes and computes this LBPH Model. The current implementation is
// rather fixed as it uses the Extended Local Binary Patterns per default.
//
// (radius=1), (neighbors=8) are used in the local binary patterns creation.
// (grid_x=8), (grid_y=8) controls the grid size of the spatial histograms.
LBPH(InputArrayOfArrays src,
InputArray labels,
int radius_=1, int neighbors_=8,
int gridx=8, int gridy=8,
double threshold = DBL_MAX) :
_grid_x(gridx),
_grid_y(gridy),
_radius(radius_),
_neighbors(neighbors_),
_threshold(threshold) {
train(src, labels);
}
~LBPH() { }
// Computes a LBPH model with images in src and
// corresponding labels in labels.
void train(InputArrayOfArrays src, InputArray labels);
// Updates this LBPH model with images in src and
// corresponding labels in labels.
void update(InputArrayOfArrays src, InputArray labels);
// Predicts the label of a query image in src.
int predict(InputArray src) const;
// Predicts the label and confidence for a given sample.
void predict(InputArray _src, int &label, double &dist) const;
// See FaceRecognizer::load.
void load(const FileStorage& fs);
// See FaceRecognizer::save.
void save(FileStorage& fs) const;
CV_IMPL_PROPERTY(int, GridX, _grid_x)
CV_IMPL_PROPERTY(int, GridY, _grid_y)
CV_IMPL_PROPERTY(int, Radius, _radius)
CV_IMPL_PROPERTY(int, Neighbors, _neighbors)
CV_IMPL_PROPERTY(double, Threshold, _threshold)
CV_IMPL_PROPERTY_RO(std::vector<cv::Mat>, Histograms, _histograms)
CV_IMPL_PROPERTY_RO(cv::Mat, Labels, _labels)
};
void LBPH::load(const FileStorage& fs) {
fs["radius"] >> _radius;
fs["neighbors"] >> _neighbors;
fs["grid_x"] >> _grid_x;
fs["grid_y"] >> _grid_y;
//read matrices
readFileNodeList(fs["histograms"], _histograms);
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));
}
}
}
// See FaceRecognizer::save.
void LBPH::save(FileStorage& fs) const {
fs << "radius" << _radius;
fs << "neighbors" << _neighbors;
fs << "grid_x" << _grid_x;
fs << "grid_y" << _grid_y;
// write matrices
writeFileNodeList(fs, "histograms", _histograms);
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 << "]";
}
void LBPH::train(InputArrayOfArrays _in_src, InputArray _in_labels) {
this->train(_in_src, _in_labels, false);
}
void LBPH::update(InputArrayOfArrays _in_src, InputArray _in_labels) {
// got no data, just return
if(_in_src.total() == 0)
return;
this->train(_in_src, _in_labels, true);
}
//------------------------------------------------------------------------------
// LBPH
//------------------------------------------------------------------------------
template <typename _Tp> static
void olbp_(InputArray _src, OutputArray _dst) {
// get matrices
Mat src = _src.getMat();
// allocate memory for result
_dst.create(src.rows-2, src.cols-2, CV_8UC1);
Mat dst = _dst.getMat();
// zero the result matrix
dst.setTo(0);
// calculate patterns
for(int i=1;i<src.rows-1;i++) {
for(int j=1;j<src.cols-1;j++) {
_Tp center = src.at<_Tp>(i,j);
unsigned char code = 0;
code |= (src.at<_Tp>(i-1,j-1) >= center) << 7;
code |= (src.at<_Tp>(i-1,j) >= center) << 6;
code |= (src.at<_Tp>(i-1,j+1) >= center) << 5;
code |= (src.at<_Tp>(i,j+1) >= center) << 4;
code |= (src.at<_Tp>(i+1,j+1) >= center) << 3;
code |= (src.at<_Tp>(i+1,j) >= center) << 2;
code |= (src.at<_Tp>(i+1,j-1) >= center) << 1;
code |= (src.at<_Tp>(i,j-1) >= center) << 0;
dst.at<unsigned char>(i-1,j-1) = code;
}
}
}
//------------------------------------------------------------------------------
// cv::elbp
//------------------------------------------------------------------------------
template <typename _Tp> static
inline void elbp_(InputArray _src, OutputArray _dst, int radius, int neighbors) {
//get matrices
Mat src = _src.getMat();
// allocate memory for result
_dst.create(src.rows-2*radius, src.cols-2*radius, CV_32SC1);
Mat dst = _dst.getMat();
// zero
dst.setTo(0);
for(int n=0; n<neighbors; n++) {
// sample points
float x = static_cast<float>(radius * cos(2.0*CV_PI*n/static_cast<float>(neighbors)));
float y = static_cast<float>(-radius * sin(2.0*CV_PI*n/static_cast<float>(neighbors)));
// relative indices
int fx = static_cast<int>(floor(x));
int fy = static_cast<int>(floor(y));
int cx = static_cast<int>(ceil(x));
int cy = static_cast<int>(ceil(y));
// fractional part
float ty = y - fy;
float tx = x - fx;
// set interpolation weights
float w1 = (1 - tx) * (1 - ty);
float w2 = tx * (1 - ty);
float w3 = (1 - tx) * ty;
float w4 = tx * ty;
// iterate through your data
for(int i=radius; i < src.rows-radius;i++) {
for(int j=radius;j < src.cols-radius;j++) {
// calculate interpolated value
float t = static_cast<float>(w1*src.at<_Tp>(i+fy,j+fx) + w2*src.at<_Tp>(i+fy,j+cx) + w3*src.at<_Tp>(i+cy,j+fx) + w4*src.at<_Tp>(i+cy,j+cx));
// floating point precision, so check some machine-dependent epsilon
dst.at<int>(i-radius,j-radius) += ((t > src.at<_Tp>(i,j)) || (std::abs(t-src.at<_Tp>(i,j)) < std::numeric_limits<float>::epsilon())) << n;
}
}
}
}
static void elbp(InputArray src, OutputArray dst, int radius, int neighbors)
{
int type = src.type();
switch (type) {
case CV_8SC1: elbp_<char>(src,dst, radius, neighbors); break;
case CV_8UC1: elbp_<unsigned char>(src, dst, radius, neighbors); break;
case CV_16SC1: elbp_<short>(src,dst, radius, neighbors); break;
case CV_16UC1: elbp_<unsigned short>(src,dst, radius, neighbors); break;
case CV_32SC1: elbp_<int>(src,dst, radius, neighbors); break;
case CV_32FC1: elbp_<float>(src,dst, radius, neighbors); break;
case CV_64FC1: elbp_<double>(src,dst, radius, neighbors); break;
default:
String error_msg = format("Using Original Local Binary Patterns for feature extraction only works on single-channel images (given %d). Please pass the image data as a grayscale image!", type);
CV_Error(Error::StsNotImplemented, error_msg);
break;
}
}
static Mat
histc_(const Mat& src, int minVal=0, int maxVal=255, bool normed=false)
{
Mat result;
// Establish the number of bins.
int histSize = maxVal-minVal+1;
// Set the ranges.
float range[] = { static_cast<float>(minVal), static_cast<float>(maxVal+1) };
const float* histRange = { range };
// calc histogram
calcHist(&src, 1, 0, Mat(), result, 1, &histSize, &histRange, true, false);
// normalize
if(normed) {
result /= (int)src.total();
}
return result.reshape(1,1);
}
static Mat histc(InputArray _src, int minVal, int maxVal, bool normed)
{
Mat src = _src.getMat();
switch (src.type()) {
case CV_8SC1:
return histc_(Mat_<float>(src), minVal, maxVal, normed);
break;
case CV_8UC1:
return histc_(src, minVal, maxVal, normed);
break;
case CV_16SC1:
return histc_(Mat_<float>(src), minVal, maxVal, normed);
break;
case CV_16UC1:
return histc_(src, minVal, maxVal, normed);
break;
case CV_32SC1:
return histc_(Mat_<float>(src), minVal, maxVal, normed);
break;
case CV_32FC1:
return histc_(src, minVal, maxVal, normed);
break;
default:
CV_Error(Error::StsUnmatchedFormats, "This type is not implemented yet."); break;
}
return Mat();
}
static Mat spatial_histogram(InputArray _src, int numPatterns,
int grid_x, int grid_y, bool /*normed*/)
{
Mat src = _src.getMat();
// calculate LBP patch size
int width = src.cols/grid_x;
int height = src.rows/grid_y;
// allocate memory for the spatial histogram
Mat result = Mat::zeros(grid_x * grid_y, numPatterns, CV_32FC1);
// return matrix with zeros if no data was given
if(src.empty())
return result.reshape(1,1);
// initial result_row
int resultRowIdx = 0;
// iterate through grid
for(int i = 0; i < grid_y; i++) {
for(int j = 0; j < grid_x; j++) {
Mat src_cell = Mat(src, Range(i*height,(i+1)*height), Range(j*width,(j+1)*width));
Mat cell_hist = histc(src_cell, 0, (numPatterns-1), true);
// copy to the result matrix
Mat result_row = result.row(resultRowIdx);
cell_hist.reshape(1,1).convertTo(result_row, CV_32FC1);
// increase row count in result matrix
resultRowIdx++;
}
}
// return result as reshaped feature vector
return result.reshape(1,1);
}
//------------------------------------------------------------------------------
// wrapper to cv::elbp (extended local binary patterns)
//------------------------------------------------------------------------------
static Mat elbp(InputArray src, int radius, int neighbors) {
Mat dst;
elbp(src, dst, radius, neighbors);
return dst;
}
void LBPH::train(InputArrayOfArrays _in_src, InputArray _in_labels, bool preserveData) {
if(_in_src.kind() != _InputArray::STD_VECTOR_MAT && _in_src.kind() != _InputArray::STD_VECTOR_VECTOR) {
String error_message = "The images are expected as InputArray::STD_VECTOR_MAT (a std::vector<Mat>) or _InputArray::STD_VECTOR_VECTOR (a std::vector< std::vector<...> >).";
CV_Error(Error::StsBadArg, error_message);
}
if(_in_src.total() == 0) {
String error_message = format("Empty training data was given. You'll need more than one sample to learn a model.");
CV_Error(Error::StsUnsupportedFormat, error_message);
} else if(_in_labels.getMat().type() != CV_32SC1) {
String error_message = format("Labels must be given as integer (CV_32SC1). Expected %d, but was %d.", CV_32SC1, _in_labels.type());
CV_Error(Error::StsUnsupportedFormat, error_message);
}
// get the vector of matrices
std::vector<Mat> src;
_in_src.getMatVector(src);
// get the label matrix
Mat labels = _in_labels.getMat();
// check if data is well- aligned
if(labels.total() != src.size()) {
String error_message = format("The number of samples (src) must equal the number of labels (labels). Was len(samples)=%d, len(labels)=%d.", src.size(), _labels.total());
CV_Error(Error::StsBadArg, error_message);
}
// if this model should be trained without preserving old data, delete old model data
if(!preserveData) {
_labels.release();
_histograms.clear();
}
// append labels to _labels matrix
for(size_t labelIdx = 0; labelIdx < labels.total(); labelIdx++) {
_labels.push_back(labels.at<int>((int)labelIdx));
}
// store the spatial histograms of the original data
for(size_t sampleIdx = 0; sampleIdx < src.size(); sampleIdx++) {
// calculate lbp image
Mat lbp_image = elbp(src[sampleIdx], _radius, _neighbors);
// get spatial histogram from this lbp image
Mat p = spatial_histogram(
lbp_image, /* lbp_image */
static_cast<int>(std::pow(2.0, static_cast<double>(_neighbors))), /* number of possible patterns */
_grid_x, /* grid size x */
_grid_y, /* grid size y */
true);
// add to templates
_histograms.push_back(p);
}
}
void LBPH::predict(InputArray _src, int &minClass, double &minDist) const {
if(_histograms.empty()) {
// throw error if no data (or simply return -1?)
String error_message = "This LBPH model is not computed yet. Did you call the train method?";
CV_Error(Error::StsBadArg, error_message);
}
Mat src = _src.getMat();
// get the spatial histogram from input image
Mat lbp_image = elbp(src, _radius, _neighbors);
Mat query = spatial_histogram(
lbp_image, /* lbp_image */
static_cast<int>(std::pow(2.0, static_cast<double>(_neighbors))), /* number of possible patterns */
_grid_x, /* grid size x */
_grid_y, /* grid size y */
true /* normed histograms */);
// find 1-nearest neighbor
minDist = DBL_MAX;
minClass = -1;
for(size_t sampleIdx = 0; sampleIdx < _histograms.size(); sampleIdx++) {
double dist = compareHist(_histograms[sampleIdx], query, HISTCMP_CHISQR_ALT);
if((dist < minDist) && (dist < _threshold)) {
minDist = dist;
minClass = _labels.at<int>((int) sampleIdx);
}
}
}
int LBPH::predict(InputArray _src) const {
int label;
double dummy;
predict(_src, label, dummy);
return label;
}
Ptr<LBPHFaceRecognizer> createLBPHFaceRecognizer(int radius, int neighbors,
int grid_x, int grid_y, double threshold)
{
return makePtr<LBPH>(radius, neighbors, grid_x, grid_y, threshold);
}
}}

@ -43,12 +43,16 @@
#ifndef __OPENCV_PRECOMP_H__
#define __OPENCV_PRECOMP_H__
#include "opencv2/face.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/core.hpp"
#include "opencv2/core/utility.hpp"
#include "opencv2/core/private.hpp"
#include "opencv2/core/persistence.hpp"
#include <map>
#include <iostream>
#include <set>
#include <limits>
#include <iostream>
#endif

@ -116,10 +116,4 @@ generates an 8 bit string. Concatenating 32 comparison strings, we get the 256-b
representation of a single LBD.
*/
namespace cv
{
CV_EXPORTS bool initModule_line_descriptor( void );
}
#endif

@ -74,8 +74,6 @@ namespace line_descriptor
//! @addtogroup line_descriptor
//! @{
CV_EXPORTS bool initModule_line_descriptor();
/** @brief A class to represent a line
As aformentioned, it is been necessary to design a class that fully stores the information needed to
@ -307,9 +305,6 @@ class CV_EXPORTS BinaryDescriptor : public Algorithm
virtual void computeImpl( const Mat& imageSrc, std::vector<KeyLine>& keylines, Mat& descriptors, bool returnFloatDescr,
bool useDetectionData ) const;
/** function inherited from Algorithm */
AlgorithmInfo* info() const;
private:
/** struct to represent lines extracted from an octave */
struct OctaveLine
@ -911,10 +906,6 @@ void detectImpl( const Mat& imageSrc, std::vector<KeyLine>& keylines, int numOct
/* matrices for Gaussian pyramids */
std::vector<cv::Mat> gaussianPyrs;
protected:
/* function inherited from Algorithm */
AlgorithmInfo* info() const;
};
/** @brief furnishes all functionalities for querying a dataset provided by user or internal to
@ -1068,10 +1059,6 @@ BinaryDescriptorMatcher();
{
}
protected:
/** function inherited from Algorithm */
AlgorithmInfo* info() const;
private:
class BucketGroup
{

@ -1,64 +0,0 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// 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
//
// Copyright (C) 2014, Biagio Montesano, 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:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's 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.
//
// * The name of the copyright holders may not 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 the Intel Corporation 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.
//
//M*/
#include "precomp.hpp"
namespace cv
{
namespace line_descriptor
{
CV_INIT_ALGORITHM( BinaryDescriptor, "BINARY.DESCRIPTOR", );
CV_INIT_ALGORITHM( BinaryDescriptorMatcher, "BINARY.DESCRIPTOR.MATCHER", );
CV_INIT_ALGORITHM( LSDDetector, "LSDDETECTOR", );
bool initModule_line_descriptor( void )
{
bool all = true;
all &= !BinaryDescriptor_info_auto.name().empty();
all &= !BinaryDescriptorMatcher_info_auto.name().empty();
all &= !LSDDetector_info_auto.name().empty();
return all;
}
}
}

@ -56,8 +56,6 @@ public:
void calc( InputArray I0, InputArray I1, InputOutputArray flow );
void collectGarbage();
// AlgorithmInfo* info() const;
protected:
float sigma; // Gaussian smoothing parameter
int minSize; // minimal dimension of an image in the pyramid

@ -56,7 +56,6 @@ public:
OpticalFlowSimpleFlow();
void calc(InputArray I0, InputArray I1, InputOutputArray flow);
void collectGarbage();
// AlgorithmInfo* info() const;
protected:
int layers;
@ -129,7 +128,6 @@ public:
OpticalFlowFarneback();
void calc(InputArray I0, InputArray I1, InputOutputArray flow);
void collectGarbage();
// AlgorithmInfo* info() const;
protected:
int numLevels;
double pyrScale;

@ -137,9 +137,6 @@ namespace rgbd
~RgbdNormals();
AlgorithmInfo*
info() const;
/** Given a set of 3d points in a depth image, compute the normals at each point.
* @param points a rows x cols x 3 matrix of CV_32F/CV64F or a rows x cols x 1 CV_U16S
* @param normals a rows x cols x 3 matrix
@ -153,14 +150,13 @@ namespace rgbd
void
initialize() const;
/** Return the current method in that normal computer
* @return
*/
int
method() const
{
return method_;
}
CV_IMPL_PROPERTY(int, Rows, rows_)
CV_IMPL_PROPERTY(int, Cols, cols_)
CV_IMPL_PROPERTY(int, WindowSize, window_size_)
CV_IMPL_PROPERTY(int, Depth, depth_)
CV_IMPL_PROPERTY_S(cv::Mat, K, K_)
CV_IMPL_PROPERTY(int, Method, method_)
protected:
void
initialize_normals_impl(int rows, int cols, int depth, const Mat & K, int window_size, int method) const;
@ -204,9 +200,6 @@ namespace rgbd
~DepthCleaner();
AlgorithmInfo*
info() const;
/** Given a set of 3d points in a depth image, compute the normals at each point.
* @param points a rows x cols x 3 matrix of CV_32F/CV64F or a rows x cols x 1 CV_U16S
* @param depth a rows x cols matrix of the cleaned up depth
@ -220,14 +213,10 @@ namespace rgbd
void
initialize() const;
/** Return the current method in that normal computer
* @return
*/
int
method() const
{
return method_;
}
CV_IMPL_PROPERTY(int, WindowSize, window_size_)
CV_IMPL_PROPERTY(int, Depth, depth_)
CV_IMPL_PROPERTY(int, Method, method_)
protected:
void
initialize_cleaner_impl() const;
@ -316,8 +305,14 @@ namespace rgbd
void
operator()(InputArray points3d, OutputArray mask, OutputArray plane_coefficients);
AlgorithmInfo*
info() const;
CV_IMPL_PROPERTY(int, BlockSize, block_size_)
CV_IMPL_PROPERTY(int, MinSize, min_size_)
CV_IMPL_PROPERTY(int, Method, method_)
CV_IMPL_PROPERTY(double, Threshold, threshold_)
CV_IMPL_PROPERTY(double, SensorErrorA, sensor_error_a_)
CV_IMPL_PROPERTY(double, SensorErrorB, sensor_error_b_)
CV_IMPL_PROPERTY(double, SensorErrorC, sensor_error_c_)
private:
/** The method to use to compute the planes */
int method_;
@ -469,6 +464,19 @@ namespace rgbd
*/
virtual Size prepareFrameCache(Ptr<OdometryFrame>& frame, int cacheType) const;
static Ptr<Odometry> create(const String & odometryType);
//TODO: which properties are common for all Odometry successors?
CV_PURE_PROPERTY_S(cv::Mat, CameraMatrix)
// CV_PURE_PROPERTY(double, MinDepth)
// CV_PURE_PROPERTY(double, MaxDepth)
// CV_PURE_PROPERTY(double, MaxDepthDiff)
// CV_PURE_PROPERTY_S(cv::Mat, IterationCounts)
// CV_PURE_PROPERTY(double, MaxPointsPart)
CV_PURE_PROPERTY(int, TransformType)
// CV_PURE_PROPERTY(double, MaxTranslation)
// CV_PURE_PROPERTY(double, MaxRotation)
protected:
virtual void
checkParams() const = 0;
@ -504,8 +512,16 @@ namespace rgbd
virtual Size prepareFrameCache(Ptr<OdometryFrame>& frame, int cacheType) const;
AlgorithmInfo*
info() const;
CV_IMPL_PROPERTY_S(cv::Mat, CameraMatrix, cameraMatrix)
CV_IMPL_PROPERTY(double, MinDepth, minDepth)
CV_IMPL_PROPERTY(double, MaxDepth, maxDepth)
CV_IMPL_PROPERTY(double, MaxDepthDiff, maxDepthDiff)
CV_IMPL_PROPERTY_S(cv::Mat, IterationCounts, iterCounts)
CV_IMPL_PROPERTY_S(cv::Mat, MinGradientMagnitudes, minGradientMagnitudes)
CV_IMPL_PROPERTY(double, MaxPointsPart, maxPointsPart)
CV_IMPL_PROPERTY(int, TransformType, transformType)
CV_IMPL_PROPERTY(double, MaxTranslation, maxTranslation)
CV_IMPL_PROPERTY(double, MaxRotation, maxRotation)
protected:
virtual void
@ -553,8 +569,16 @@ namespace rgbd
virtual Size prepareFrameCache(Ptr<OdometryFrame>& frame, int cacheType) const;
AlgorithmInfo*
info() const;
CV_IMPL_PROPERTY_S(cv::Mat, CameraMatrix, cameraMatrix)
CV_IMPL_PROPERTY(double, MinDepth, minDepth)
CV_IMPL_PROPERTY(double, MaxDepth, maxDepth)
CV_IMPL_PROPERTY(double, MaxDepthDiff, maxDepthDiff)
CV_IMPL_PROPERTY_S(cv::Mat, IterationCounts, iterCounts)
CV_IMPL_PROPERTY(double, MaxPointsPart, maxPointsPart)
CV_IMPL_PROPERTY(int, TransformType, transformType)
CV_IMPL_PROPERTY(double, MaxTranslation, maxTranslation)
CV_IMPL_PROPERTY(double, MaxRotation, maxRotation)
CV_IMPL_PROPERTY_RO(Ptr<RgbdNormals>, NormalsComputer, normalsComputer)
protected:
virtual void
@ -607,8 +631,17 @@ namespace rgbd
virtual Size prepareFrameCache(Ptr<OdometryFrame>& frame, int cacheType) const;
AlgorithmInfo*
info() const;
CV_IMPL_PROPERTY_S(cv::Mat, CameraMatrix, cameraMatrix)
CV_IMPL_PROPERTY(double, MinDepth, minDepth)
CV_IMPL_PROPERTY(double, MaxDepth, maxDepth)
CV_IMPL_PROPERTY(double, MaxDepthDiff, maxDepthDiff)
CV_IMPL_PROPERTY(double, MaxPointsPart, maxPointsPart)
CV_IMPL_PROPERTY_S(cv::Mat, IterationCounts, iterCounts)
CV_IMPL_PROPERTY_S(cv::Mat, MinGradientMagnitudes, minGradientMagnitudes)
CV_IMPL_PROPERTY(int, TransformType, transformType)
CV_IMPL_PROPERTY(double, MaxTranslation, maxTranslation)
CV_IMPL_PROPERTY(double, MaxRotation, maxRotation)
CV_IMPL_PROPERTY_RO(Ptr<RgbdNormals>, NormalsComputer, normalsComputer)
protected:
virtual void
@ -669,3 +702,4 @@ namespace rgbd
#endif
/* End of file. */

@ -173,13 +173,13 @@ int main(int argc, char** argv)
Ptr<OdometryFrame> frame_prev = Ptr<OdometryFrame>(new OdometryFrame()),
frame_curr = Ptr<OdometryFrame>(new OdometryFrame());
Ptr<Odometry> odometry = Algorithm::create<Odometry>("RGBD." + string(argv[3]) + "Odometry");
Ptr<Odometry> odometry = Odometry::create("RGBD." + string(argv[3]) + "Odometry");
if(odometry.empty())
{
cout << "Can not create Odometry algorithm. Check the passed odometry name." << endl;
return -1;
}
odometry->set("cameraMatrix", cameraMatrix);
odometry->setCameraMatrix(cameraMatrix);
MyTickMeter gtm;
int count = 0;

@ -1069,6 +1069,17 @@ Size Odometry::prepareFrameCache(Ptr<OdometryFrame> &frame, int /*cacheType*/) c
return Size();
}
Ptr<Odometry> Odometry::create(const String & odometryType)
{
if (odometryType == "RgbdOdometry")
return makePtr<RgbdOdometry>();
else if (odometryType == "ICPOdometry")
return makePtr<ICPOdometry>();
else if (odometryType == "RgbdICPOdometry")
return makePtr<RgbdICPOdometry>();
return Ptr<Odometry>();
}
//
RgbdOdometry::RgbdOdometry() :
minDepth(DEFAULT_MIN_DEPTH()),
@ -1229,10 +1240,15 @@ Size ICPOdometry::prepareFrameCache(Ptr<OdometryFrame>& frame, int cacheType) co
else
{
if(normalsComputer.empty() ||
normalsComputer->get<int>("rows") != frame->depth.rows ||
normalsComputer->get<int>("cols") != frame->depth.cols ||
norm(normalsComputer->get<Mat>("K"), cameraMatrix) > FLT_EPSILON)
normalsComputer = Ptr<RgbdNormals>(new RgbdNormals(frame->depth.rows, frame->depth.cols, frame->depth.depth(), cameraMatrix, normalWinSize, normalMethod));
normalsComputer->getRows() != frame->depth.rows ||
normalsComputer->getCols() != frame->depth.cols ||
norm(normalsComputer->getK(), cameraMatrix) > FLT_EPSILON)
normalsComputer = makePtr<RgbdNormals>(frame->depth.rows,
frame->depth.cols,
frame->depth.depth(),
cameraMatrix,
normalWinSize,
normalMethod);
(*normalsComputer)(frame->pyramidCloud[0], frame->normals);
}
@ -1338,10 +1354,15 @@ Size RgbdICPOdometry::prepareFrameCache(Ptr<OdometryFrame>& frame, int cacheType
else
{
if(normalsComputer.empty() ||
normalsComputer->get<int>("rows") != frame->depth.rows ||
normalsComputer->get<int>("cols") != frame->depth.cols ||
norm(normalsComputer->get<Mat>("K"), cameraMatrix) > FLT_EPSILON)
normalsComputer = Ptr<RgbdNormals>(new RgbdNormals(frame->depth.rows, frame->depth.cols, frame->depth.depth(), cameraMatrix, normalWinSize, normalMethod));
normalsComputer->getRows() != frame->depth.rows ||
normalsComputer->getCols() != frame->depth.cols ||
norm(normalsComputer->getK(), cameraMatrix) > FLT_EPSILON)
normalsComputer = makePtr<RgbdNormals>(frame->depth.rows,
frame->depth.cols,
frame->depth.depth(),
cameraMatrix,
normalWinSize,
normalMethod);
(*normalsComputer)(frame->pyramidCloud[0], frame->normals);
}

@ -1,119 +0,0 @@
/*
* Software License Agreement (BSD License)
*
* Copyright (c) 2012, Willow Garage, Inc.
* All rights reserved.
*
* 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 name of Willow Garage, Inc. nor the names of its
* 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 THE
* COPYRIGHT OWNER 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.
*
*/
#include <opencv2/core.hpp>
#include <opencv2/rgbd.hpp>
#include "opencv2/core/utility.hpp"
#include "opencv2/core/private.hpp"
namespace cv
{
namespace rgbd
{
CV_INIT_ALGORITHM(DepthCleaner, "RGBD.DepthCleaner",
obj.info()->addParam(obj, "window_size", obj.window_size_);
obj.info()->addParam(obj, "depth", obj.depth_);
obj.info()->addParam(obj, "method", obj.method_))
CV_INIT_ALGORITHM(RgbdNormals, "RGBD.RgbdNormals",
obj.info()->addParam(obj, "rows", obj.rows_);
obj.info()->addParam(obj, "cols", obj.cols_);
obj.info()->addParam(obj, "window_size", obj.window_size_);
obj.info()->addParam(obj, "depth", obj.depth_);
obj.info()->addParam(obj, "K", obj.K_);
obj.info()->addParam(obj, "method", obj.method_))
CV_INIT_ALGORITHM(RgbdPlane, "RGBD.RgbdPlane",
obj.info()->addParam(obj, "block_size", obj.block_size_);
obj.info()->addParam(obj, "min_size", obj.min_size_);
obj.info()->addParam(obj, "method", obj.method_);
obj.info()->addParam(obj, "threshold", obj.threshold_);
obj.info()->addParam(obj, "sensor_error_a", obj.sensor_error_a_);
obj.info()->addParam(obj, "sensor_error_b", obj.sensor_error_b_);
obj.info()->addParam(obj, "sensor_error_c", obj.sensor_error_c_))
CV_INIT_ALGORITHM(RgbdOdometry, "RGBD.RgbdOdometry",
obj.info()->addParam(obj, "cameraMatrix", obj.cameraMatrix);
obj.info()->addParam(obj, "minDepth", obj.minDepth);
obj.info()->addParam(obj, "maxDepth", obj.maxDepth);
obj.info()->addParam(obj, "maxDepthDiff", obj.maxDepthDiff);
obj.info()->addParam(obj, "iterCounts", obj.iterCounts);
obj.info()->addParam(obj, "minGradientMagnitudes", obj.minGradientMagnitudes);
obj.info()->addParam(obj, "maxPointsPart", obj.maxPointsPart);
obj.info()->addParam(obj, "transformType", obj.transformType);
obj.info()->addParam(obj, "maxTranslation", obj.maxTranslation);
obj.info()->addParam(obj, "maxRotation", obj.maxRotation);)
CV_INIT_ALGORITHM(ICPOdometry, "RGBD.ICPOdometry",
obj.info()->addParam(obj, "cameraMatrix", obj.cameraMatrix);
obj.info()->addParam(obj, "minDepth", obj.minDepth);
obj.info()->addParam(obj, "maxDepth", obj.maxDepth);
obj.info()->addParam(obj, "maxDepthDiff", obj.maxDepthDiff);
obj.info()->addParam(obj, "maxPointsPart", obj.maxPointsPart);
obj.info()->addParam(obj, "iterCounts", obj.iterCounts);
obj.info()->addParam(obj, "transformType", obj.transformType);
obj.info()->addParam(obj, "maxTranslation", obj.maxTranslation);
obj.info()->addParam(obj, "maxRotation", obj.maxRotation);
obj.info()->addParam<RgbdNormals>(obj, "normalsComputer", obj.normalsComputer, true, NULL, NULL);)
CV_INIT_ALGORITHM(RgbdICPOdometry, "RGBD.RgbdICPOdometry",
obj.info()->addParam(obj, "cameraMatrix", obj.cameraMatrix);
obj.info()->addParam(obj, "minDepth", obj.minDepth);
obj.info()->addParam(obj, "maxDepth", obj.maxDepth);
obj.info()->addParam(obj, "maxDepthDiff", obj.maxDepthDiff);
obj.info()->addParam(obj, "maxPointsPart", obj.maxPointsPart);
obj.info()->addParam(obj, "iterCounts", obj.iterCounts);
obj.info()->addParam(obj, "minGradientMagnitudes", obj.minGradientMagnitudes);
obj.info()->addParam(obj, "transformType", obj.transformType);
obj.info()->addParam(obj, "maxTranslation", obj.maxTranslation);
obj.info()->addParam(obj, "maxRotation", obj.maxRotation);
obj.info()->addParam<RgbdNormals>(obj, "normalsComputer", obj.normalsComputer, true, NULL, NULL);)
bool
initModule_rgbd(void);
bool
initModule_rgbd(void)
{
bool all = true;
all &= !RgbdNormals_info_auto.name().empty();
all &= !RgbdPlane_info_auto.name().empty();
all &= !RgbdOdometry_info_auto.name().empty();
all &= !ICPOdometry_info_auto.name().empty();
all &= !RgbdICPOdometry_info_auto.name().empty();
return all;
}
}
}

@ -309,7 +309,7 @@ protected:
TickMeter tm;
tm.start();
Mat in_normals;
if (normals_computer.method() == RgbdNormals::RGBD_NORMALS_METHOD_LINEMOD)
if (normals_computer.getMethod() == RgbdNormals::RGBD_NORMALS_METHOD_LINEMOD)
{
std::vector<Mat> channels;
split(points3d, channels);

@ -241,7 +241,7 @@ void CV_OdometryTest::run(int)
if(!readData(image, depth))
return;
odometry->set("cameraMatrix", K);
odometry->setCameraMatrix(K);
Mat calcRt;
@ -338,18 +338,18 @@ void CV_OdometryTest::run(int)
TEST(RGBD_Odometry_Rgbd, algorithmic)
{
cv::rgbd::CV_OdometryTest test(cv::Algorithm::create<cv::rgbd::Odometry>("RGBD.RgbdOdometry"), 0.99, 0.94);
cv::rgbd::CV_OdometryTest test(cv::rgbd::Odometry::create("RGBD.RgbdOdometry"), 0.99, 0.94);
test.safe_run();
}
TEST(RGBD_Odometry_ICP, algorithmic)
{
cv::rgbd::CV_OdometryTest test(cv::Algorithm::create<cv::rgbd::Odometry>("RGBD.ICPOdometry"), 0.99, 0.99);
cv::rgbd::CV_OdometryTest test(cv::rgbd::Odometry::create("RGBD.ICPOdometry"), 0.99, 0.99);
test.safe_run();
}
TEST(RGBD_Odometry_RgbdICP, algorithmic)
{
cv::rgbd::CV_OdometryTest test(cv::Algorithm::create<cv::rgbd::Odometry>("RGBD.RgbdICPOdometry"), 0.99, 0.99);
cv::rgbd::CV_OdometryTest test(cv::rgbd::Odometry::create("RGBD.RgbdICPOdometry"), 0.99, 0.99);
test.safe_run();
}

@ -80,12 +80,4 @@ To see how API works, try tracker demo:
*/
namespace cv
{
namespace saliency
{
CV_EXPORTS bool initModule_saliency( void );
}
}
#endif //__OPENCV_SALIENCY_HPP__

@ -47,6 +47,7 @@
#include <string>
#include <iostream>
#include <stdint.h>
#include "opencv2/core.hpp"
namespace cv
{
@ -75,9 +76,11 @@ public:
void read( const FileNode& fn );
void write( FileStorage& fs ) const;
CV_IMPL_PROPERTY(int, ImageWidth, resImWidth)
CV_IMPL_PROPERTY(int, ImageHeight, resImHeight)
protected:
bool computeSaliencyImpl( const InputArray image, OutputArray saliencyMap );
AlgorithmInfo* info() const;
int resImWidth;
int resImHeight;
@ -111,6 +114,9 @@ public:
*/
bool init();
CV_IMPL_PROPERTY(int, ImageWidth, imageWidth)
CV_IMPL_PROPERTY(int, ImageHeight, imageHeight)
protected:
/** @brief Performs all the operations and calls all internal functions necessary for the accomplishment of the
Fast Self-tuning Background Subtraction Algorithm algorithm.
@ -121,7 +127,6 @@ protected:
stream).
*/
bool computeSaliencyImpl( const InputArray image, OutputArray saliencyMap );
AlgorithmInfo* info() const;
private:
@ -200,6 +205,10 @@ public:
*/
void setBBResDir( std::string resultsDir );
CV_IMPL_PROPERTY(double, Base, _base)
CV_IMPL_PROPERTY(int, NSS, _NSS)
CV_IMPL_PROPERTY(int, W, _W)
protected:
/** @brief Performs all the operations and calls all internal functions necessary for the
accomplishment of the Binarized normed gradients algorithm.
@ -211,7 +220,6 @@ protected:
represented by a *Vec4i* for (minX, minY, maxX, maxY).
*/
bool computeSaliencyImpl( const InputArray image, OutputArray objectnessBoundingBox );
AlgorithmInfo* info() const;
private:

@ -53,9 +53,13 @@ Saliency::~Saliency()
Ptr<Saliency> Saliency::create( const String& saliencyType )
{
return Algorithm::create<Saliency>( "SALIENCY." + saliencyType );
if (saliencyType == "SPECTRAL_RESIDUAL")
return makePtr<StaticSaliencySpectralResidual>();
else if (saliencyType == "BING")
return makePtr<ObjectnessBING>();
else if (saliencyType == "BinWangApr2014")
return makePtr<MotionSaliencyBinWangApr2014>();
return Ptr<Saliency>();
}
bool Saliency::computeSaliency( const InputArray image, OutputArray saliencyMap )

@ -1,73 +0,0 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// 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
//
// Copyright (C) 2014, 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:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's 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.
//
// * The name of the copyright holders may not 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 the Intel Corporation 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.
//
//M*/
#include "precomp.hpp"
#include "opencv2/saliency.hpp"
namespace cv
{
namespace saliency
{
CV_INIT_ALGORITHM( StaticSaliencySpectralResidual, "SALIENCY.SPECTRAL_RESIDUAL",
obj.info()->addParam( obj, "resImWidth", obj.resImWidth); obj.info()->addParam( obj, "resImHeight", obj.resImHeight) );
CV_INIT_ALGORITHM(
ObjectnessBING, "SALIENCY.BING",
obj.info()->addParam(obj, "_base", obj._base); obj.info()->addParam(obj, "_NSS", obj._NSS); obj.info()->addParam(obj, "_W", obj._W) );
CV_INIT_ALGORITHM( MotionSaliencyBinWangApr2014, "SALIENCY.BinWangApr2014",
obj.info()->addParam( obj, "imageWidth", obj.imageWidth); obj.info()->addParam( obj, "imageHeight", obj.imageHeight) );
bool initModule_saliency( void )
{
bool all = true;
all &= !StaticSaliencySpectralResidual_info_auto.name().empty();
//all &= !MotionSaliencySuBSENSE_info_auto.name().empty();
all &= !MotionSaliencyBinWangApr2014_info_auto.name().empty();
all &= !ObjectnessBING_info_auto.name().empty();
return all;
}
} // namespace saliency
} // namespace cv

@ -327,10 +327,6 @@ The first argument is the name of the tracker and the second is a video source.
*/
namespace cv
{
CV_EXPORTS bool initModule_tracking(void);
}
#include "opencv2/tracking/tracker.hpp"
#endif //__OPENCV_TRACKING_LENLEN

@ -574,7 +574,6 @@ class CV_EXPORTS_W Tracker : public virtual Algorithm
Ptr<TrackerFeatureSet> featureSet;
Ptr<TrackerSampler> sampler;
Ptr<TrackerModel> model;
virtual AlgorithmInfo* info() const;
};
/************************************ Specific TrackerStateEstimator Classes ************************************/

@ -104,10 +104,6 @@ bool Tracker::update( const Mat& image, Rect2d& boundingBox )
return updateImpl( image, boundingBox );
}
AlgorithmInfo* Tracker::info() const{
return 0;
}
Ptr<Tracker> Tracker::create( const String& trackerType )
{
BOILERPLATE_CODE("MIL",TrackerMIL);

@ -1,53 +0,0 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// 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
//
// 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:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's 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.
//
// * The name of the copyright holders may not 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 the Intel Corporation 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.
//
//M*/
#include "precomp.hpp"
#include "opencv2/tracking.hpp"
namespace cv
{
bool initModule_tracking(void)
{
return true;
}
}

@ -152,7 +152,7 @@ public:
//! max keypoints = min(keypointsRatio * img.size().area(), 65535)
float keypointsRatio;
GpuMat sum, mask1, maskSum, intBuffer;
GpuMat sum, mask1, maskSum;
GpuMat det, trace;

@ -2327,14 +2327,14 @@ static void removeBowImageDescriptorsByCount( vector<ObdImage>& images, vector<M
CV_Assert( bowImageDescriptors.size() == objectPresent.size() );
}
static void setSVMParams( SVM::Params& svmParams, Mat& class_wts_cv, const Mat& responses, bool balanceClasses )
static void setSVMParams( Ptr<SVM> & svm, const Mat& responses, bool balanceClasses )
{
int pos_ex = countNonZero(responses == 1);
int neg_ex = countNonZero(responses == -1);
cout << pos_ex << " positive training samples; " << neg_ex << " negative training samples" << endl;
svmParams.svmType = SVM::C_SVC;
svmParams.kernelType = SVM::RBF;
svm->setType(SVM::C_SVC);
svm->setKernel(SVM::RBF);
if( balanceClasses )
{
Mat class_wts( 2, 1, CV_32FC1 );
@ -2351,8 +2351,7 @@ static void setSVMParams( SVM::Params& svmParams, Mat& class_wts_cv, const Mat&
class_wts.at<float>(0) = static_cast<float>(neg_ex)/static_cast<float>(pos_ex+neg_ex);
class_wts.at<float>(1) = static_cast<float>(pos_ex)/static_cast<float>(pos_ex+neg_ex);
}
class_wts_cv = class_wts;
svmParams.classWeights = class_wts_cv;
svm->setClassWeights(class_wts);
}
}
@ -2440,10 +2439,8 @@ static Ptr<SVM> trainSVMClassifier( const SVMTrainParamsExt& svmParamsExt, const
}
cout << "TRAINING SVM FOR CLASS ..." << objClassName << "..." << endl;
SVM::Params svmParams;
Mat class_wts_cv;
setSVMParams( svmParams, class_wts_cv, responses, svmParamsExt.balanceClasses );
svm = SVM::create(svmParams);
svm = SVM::create();
setSVMParams( svm, responses, svmParamsExt.balanceClasses );
ParamGrid c_grid, gamma_grid, p_grid, nu_grid, coef_grid, degree_grid;
setSVMTrainAutoParams( c_grid, gamma_grid, p_grid, nu_grid, coef_grid, degree_grid );

@ -146,13 +146,13 @@ namespace
bindImgTex(img);
cuda::integral(img, surf_.sum, surf_.intBuffer);
cuda::integral(img, surf_.sum);
sumOffset = bindSumTex(surf_.sum);
if (use_mask)
{
cuda::min(mask, 1.0, surf_.mask1);
cuda::integral(surf_.mask1, surf_.maskSum, surf_.intBuffer);
cuda::integral(surf_.mask1, surf_.maskSum);
maskOffset = bindMaskSumTex(surf_.maskSum);
}
}
@ -425,7 +425,6 @@ void cv::cuda::SURF_CUDA::releaseMemory()
sum.release();
mask1.release();
maskSum.release();
intBuffer.release();
det.release();
trace.release();
maxPosBuffer.release();

@ -216,6 +216,13 @@ public:
CV_WRAP virtual void collectGarbage() = 0;
CV_WRAP static Ptr<AdaptiveManifoldFilter> create();
CV_PURE_PROPERTY(double, SigmaS)
CV_PURE_PROPERTY(double, SigmaR)
CV_PURE_PROPERTY(int, TreeHeight)
CV_PURE_PROPERTY(int, PCAIterations)
CV_PURE_PROPERTY(bool, AdjustOutliers)
CV_PURE_PROPERTY(bool, UseRNG)
};
/** @brief Factory method, create instance of AdaptiveManifoldFilter and produce some initialization routines.

@ -107,14 +107,19 @@ static void splitChannels(InputArrayOfArrays src, vector<Mat>& dst)
class AdaptiveManifoldFilterN : public AdaptiveManifoldFilter
{
public:
AlgorithmInfo* info() const;
AdaptiveManifoldFilterN();
void filter(InputArray src, OutputArray dst, InputArray joint);
void collectGarbage();
CV_IMPL_PROPERTY(double, SigmaS, sigma_s_)
CV_IMPL_PROPERTY(double, SigmaR, sigma_r_)
CV_IMPL_PROPERTY(int, TreeHeight, tree_height_)
CV_IMPL_PROPERTY(int, PCAIterations, num_pca_iterations_)
CV_IMPL_PROPERTY(bool, AdjustOutliers, adjust_outliers_)
CV_IMPL_PROPERTY(bool, UseRNG, useRNG)
protected:
bool adjust_outliers_;
@ -261,14 +266,6 @@ private: /*Parallelization routines*/
};
CV_INIT_ALGORITHM(AdaptiveManifoldFilterN, "AdaptiveManifoldFilter",
obj.info()->addParam(obj, "sigma_s", obj.sigma_s_, false, 0, 0, "Filter spatial standard deviation");
obj.info()->addParam(obj, "sigma_r", obj.sigma_r_, false, 0, 0, "Filter range standard deviation");
obj.info()->addParam(obj, "tree_height", obj.tree_height_, false, 0, 0, "Height of the manifold tree (default = -1 : automatically computed)");
obj.info()->addParam(obj, "num_pca_iterations", obj.num_pca_iterations_, false, 0, 0, "Number of iterations to computed the eigenvector v1");
obj.info()->addParam(obj, "adjust_outliers", obj.adjust_outliers_, false, 0, 0, "Specify adjust outliers using Eq. 9 or not");
obj.info()->addParam(obj, "use_RNG", obj.useRNG, false, 0, 0, "Specify use random to compute eigenvector or not");)
AdaptiveManifoldFilterN::AdaptiveManifoldFilterN()
{
sigma_s_ = 16.0;
@ -852,19 +849,17 @@ Ptr<AdaptiveManifoldFilter> AdaptiveManifoldFilter::create()
return Ptr<AdaptiveManifoldFilter>(new AdaptiveManifoldFilterN());
}
CV_EXPORTS_W
Ptr<AdaptiveManifoldFilter> createAMFilter(double sigma_s, double sigma_r, bool adjust_outliers)
{
Ptr<AdaptiveManifoldFilter> amf(new AdaptiveManifoldFilterN());
amf->set("sigma_s", sigma_s);
amf->set("sigma_r", sigma_r);
amf->set("adjust_outliers", adjust_outliers);
amf->setSigmaS(sigma_s);
amf->setSigmaR(sigma_r);
amf->setAdjustOutliers(adjust_outliers);
return amf;
}
CV_EXPORTS_W
void amFilter(InputArray joint, InputArray src, OutputArray dst, double sigma_s, double sigma_r, bool adjust_outliers)
{
Ptr<AdaptiveManifoldFilter> amf = createAMFilter(sigma_s, sigma_r, adjust_outliers);
@ -872,4 +867,4 @@ void amFilter(InputArray joint, InputArray src, OutputArray dst, double sigma_s,
}
}
}
}

@ -139,7 +139,7 @@ TEST(AdaptiveManifoldTest, AuthorsReferenceAccuracy)
Mat res;
Ptr<AdaptiveManifoldFilter> amf = createAMFilter(sigma_s, sigma_r, false);
amf->setBool("use_RNG", false);
amf->setUseRNG(false);
amf->filter(srcImg, res, srcImg);
amf->collectGarbage();
@ -155,7 +155,7 @@ TEST(AdaptiveManifoldTest, AuthorsReferenceAccuracy)
Mat res;
Ptr<AdaptiveManifoldFilter> amf = createAMFilter(sigma_s, sigma_r, true);
amf->setBool("use_RNG", false);
amf->setUseRNG(false);
amf->filter(srcImg, res, srcImg);
amf->collectGarbage();
@ -216,4 +216,4 @@ INSTANTIATE_TEST_CASE_P(TypicalSet, AdaptiveManifoldRefImplTest,
Values("cv/shared/lena.png", "cv/edgefilter/kodim23.png", "cv/npr/test4.png")
));
}
}

@ -179,14 +179,19 @@ namespace
class AdaptiveManifoldFilterRefImpl : public AdaptiveManifoldFilter
{
public:
AlgorithmInfo* info() const;
AdaptiveManifoldFilterRefImpl();
void filter(InputArray src, OutputArray dst, InputArray joint);
void collectGarbage();
CV_IMPL_PROPERTY(double, SigmaS, sigma_s_)
CV_IMPL_PROPERTY(double, SigmaR, sigma_r_)
CV_IMPL_PROPERTY(int, TreeHeight, tree_height_)
CV_IMPL_PROPERTY(int, PCAIterations, num_pca_iterations_)
CV_IMPL_PROPERTY(bool, AdjustOutliers, adjust_outliers_)
CV_IMPL_PROPERTY(bool, UseRNG, useRNG)
protected:
bool adjust_outliers_;
double sigma_s_;
@ -237,14 +242,6 @@ namespace
min_pixel_dist_to_manifold_squared_.release();
}
CV_INIT_ALGORITHM(AdaptiveManifoldFilterRefImpl, "AdaptiveManifoldFilterRefImpl",
obj.info()->addParam(obj, "sigma_s", obj.sigma_s_, false, 0, 0, "Filter spatial standard deviation");
obj.info()->addParam(obj, "sigma_r", obj.sigma_r_, false, 0, 0, "Filter range standard deviation");
obj.info()->addParam(obj, "tree_height", obj.tree_height_, false, 0, 0, "Height of the manifold tree (default = -1 : automatically computed)");
obj.info()->addParam(obj, "num_pca_iterations", obj.num_pca_iterations_, false, 0, 0, "Number of iterations to computed the eigenvector v1");
obj.info()->addParam(obj, "adjust_outliers", obj.adjust_outliers_, false, 0, 0, "Specify supress outliers using Eq. 9 or not");
obj.info()->addParam(obj, "use_RNG", obj.useRNG, false, 0, 0, "Specify use random to compute eigenvector or not");)
inline double Log2(double n)
{
return log(n) / log(2.0);
@ -974,11 +971,11 @@ Ptr<AdaptiveManifoldFilter> createAMFilterRefImpl(double sigma_s, double sigma_r
{
Ptr<AdaptiveManifoldFilter> amf(new AdaptiveManifoldFilterRefImpl());
amf->set("sigma_s", sigma_s);
amf->set("sigma_r", sigma_r);
amf->set("adjust_outliers", adjust_outliers);
amf->setSigmaS(sigma_s);
amf->setSigmaR(sigma_r);
amf->setAdjustOutliers(adjust_outliers);
return amf;
}
}
}

@ -153,17 +153,6 @@ public:
*/
virtual float predict(
const Ptr<FeatureEvaluator>& feature_evaluator) const = 0;
/** @brief Write WaldBoost to FileStorage
@param fs FileStorage for output
*/
virtual void write(FileStorage& fs) const = 0;
/** @brief Write WaldBoost to FileNode
@param node FileNode for reading
*/
virtual void read(const FileNode& node) = 0;
};
/** @brief Construct WaldBoost object.

Loading…
Cancel
Save