opencv: /usr/ports/pobj/OpenCV-2.2.0/OpenCV-2.2.0/modules/features2d/include/opencv2/features2d/features2d.hpp Source File

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

# /usr/ports/pobj/OpenCV-2.2.0/OpenCV-2.2.0/modules/features2d/include/opencv2/features2d/features2d.hpp

Go to the documentation of this file.

    00001 /*M///////////////////////////////////////////////////////////////////////////////////////
    00002 //
    00003 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
    00004 //
    00005 //  By downloading, copying, installing or using the software you agree to this license.
    00006 //  If you do not agree to this license, do not download, install,
    00007 //  copy or use the software.
    00008 //
    00009 //
    00010 //                           License Agreement
    00011 //                For Open Source Computer Vision Library
    00012 //
    00013 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
    00014 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
    00015 // Third party copyrights are property of their respective owners.
    00016 //
    00017 // Redistribution and use in source and binary forms, with or without modification,
    00018 // are permitted provided that the following conditions are met:
    00019 //
    00020 //   * Redistribution's of source code must retain the above copyright notice,
    00021 //     this list of conditions and the following disclaimer.
    00022 //
    00023 //   * Redistribution's in binary form must reproduce the above copyright notice,
    00024 //     this list of conditions and the following disclaimer in the documentation
    00025 //     and/or other materials provided with the distribution.
    00026 //
    00027 //   * The name of the copyright holders may not be used to endorse or promote products
    00028 //     derived from this software without specific prior written permission.
    00029 //
    00030 // This software is provided by the copyright holders and contributors "as is" and
    00031 // any express or implied warranties, including, but not limited to, the implied
    00032 // warranties of merchantability and fitness for a particular purpose are disclaimed.
    00033 // In no event shall the Intel Corporation or contributors be liable for any direct,
    00034 // indirect, incidental, special, exemplary, or consequential damages
    00035 // (including, but not limited to, procurement of substitute goods or services;
    00036 // loss of use, data, or profits; or business interruption) however caused
    00037 // and on any theory of liability, whether in contract, strict liability,
    00038 // or tort (including negligence or otherwise) arising in any way out of
    00039 // the use of this software, even if advised of the possibility of such damage.
    00040 //
    00041 //M*/
    00042
    00043 #ifndef __OPENCV_FEATURES_2D_HPP__
    00044 #define __OPENCV_FEATURES_2D_HPP__
    00045
    00046 #include "opencv2/core/core.hpp"
    00047 #include "opencv2/flann/flann.hpp"
    00048
    00049 #ifdef __cplusplus
    00050 #include <limits>
    00051
    00052 extern "C" {
    00053 #endif
    00054
    00055 typedef struct CvSURFPoint
    00056 {
    00057     CvPoint2D32f pt;
    00058     int laplacian;
    00059     int size;
    00060     float dir;
    00061     float hessian;
    00062 } CvSURFPoint;
    00063
    00064 CV_INLINE CvSURFPoint cvSURFPoint( CvPoint2D32f pt, int laplacian,
    00065                                    int size, float dir CV_DEFAULT(0),
    00066                                    float hessian CV_DEFAULT(0))
    00067 {
    00068     CvSURFPoint kp;
    00069     kp.pt = pt;
    00070     kp.laplacian = laplacian;
    00071     kp.size = size;
    00072     kp.dir = dir;
    00073     kp.hessian = hessian;
    00074     return kp;
    00075 }
    00076
    00077 typedef struct CvSURFParams
    00078 {
    00079     int extended;
    00080     double hessianThreshold;
    00081
    00082     int nOctaves;
    00083     int nOctaveLayers;
    00084 } CvSURFParams;
    00085
    00086 CVAPI(CvSURFParams) cvSURFParams( double hessianThreshold, int extended CV_DEFAULT(0) );
    00087
    00088 // If useProvidedKeyPts!=0, keypoints are not detected, but descriptors are computed
    00089 //  at the locations provided in keypoints (a CvSeq of CvSURFPoint).
    00090 CVAPI(void) cvExtractSURF( const CvArr* img, const CvArr* mask,
    00091                            CvSeq** keypoints, CvSeq** descriptors,
    00092                            CvMemStorage* storage, CvSURFParams params, int useProvidedKeyPts CV_DEFAULT(0)  );
    00093
    00097 typedef struct CvMSERParams
    00098 {
    00100     int delta;
    00102     int maxArea;
    00104     int minArea;
    00106     float maxVariation;
    00108     float minDiversity;
    00109
    00111
    00113     int maxEvolution;
    00115     double areaThreshold;
    00117     double minMargin;
    00119     int edgeBlurSize;
    00120 } CvMSERParams;
    00121
    00122 CVAPI(CvMSERParams) cvMSERParams( int delta CV_DEFAULT(5), int min_area CV_DEFAULT(60),
    00123                            int max_area CV_DEFAULT(14400), float max_variation CV_DEFAULT(.25f),
    00124                            float min_diversity CV_DEFAULT(.2f), int max_evolution CV_DEFAULT(200),
    00125                            double area_threshold CV_DEFAULT(1.01),
    00126                            double min_margin CV_DEFAULT(.003),
    00127                            int edge_blur_size CV_DEFAULT(5) );
    00128
    00129 // Extracts the contours of Maximally Stable Extremal Regions
    00130 CVAPI(void) cvExtractMSER( CvArr* _img, CvArr* _mask, CvSeq** contours, CvMemStorage* storage, CvMSERParams params );
    00131
    00132
    00133 typedef struct CvStarKeypoint
    00134 {
    00135     CvPoint pt;
    00136     int size;
    00137     float response;
    00138 } CvStarKeypoint;
    00139
    00140 CV_INLINE CvStarKeypoint cvStarKeypoint(CvPoint pt, int size, float response)
    00141 {
    00142     CvStarKeypoint kpt;
    00143     kpt.pt = pt;
    00144     kpt.size = size;
    00145     kpt.response = response;
    00146     return kpt;
    00147 }
    00148
    00149 typedef struct CvStarDetectorParams
    00150 {
    00151     int maxSize;
    00152     int responseThreshold;
    00153     int lineThresholdProjected;
    00154     int lineThresholdBinarized;
    00155     int suppressNonmaxSize;
    00156 } CvStarDetectorParams;
    00157
    00158 CV_INLINE CvStarDetectorParams cvStarDetectorParams(
    00159     int maxSize CV_DEFAULT(45),
    00160     int responseThreshold CV_DEFAULT(30),
    00161     int lineThresholdProjected CV_DEFAULT(10),
    00162     int lineThresholdBinarized CV_DEFAULT(8),
    00163     int suppressNonmaxSize CV_DEFAULT(5))
    00164 {
    00165     CvStarDetectorParams params;
    00166     params.maxSize = maxSize;
    00167     params.responseThreshold = responseThreshold;
    00168     params.lineThresholdProjected = lineThresholdProjected;
    00169     params.lineThresholdBinarized = lineThresholdBinarized;
    00170     params.suppressNonmaxSize = suppressNonmaxSize;
    00171
    00172     return params;
    00173 }
    00174
    00175 CVAPI(CvSeq*) cvGetStarKeypoints( const CvArr* img, CvMemStorage* storage,
    00176         CvStarDetectorParams params CV_DEFAULT(cvStarDetectorParams()));
    00177
    00178 #ifdef __cplusplus
    00179 }
    00180
    00181 namespace cv
    00182 {
    00183     struct CV_EXPORTS DefaultRngAuto
    00184     {
    00185         const uint64 old_state;
    00186
    00187         DefaultRngAuto() : old_state(theRNG().state) { theRNG().state = (uint64)-1; }
    00188         ~DefaultRngAuto() { theRNG().state = old_state; }
    00189
    00190         DefaultRngAuto& operator=(const DefaultRngAuto&);
    00191     };
    00192
    00193
    00194 // CvAffinePose: defines a parameterized affine transformation of an image patch.
    00195 // An image patch is rotated on angle phi (in degrees), then scaled lambda1 times
    00196 // along horizontal and lambda2 times along vertical direction, and then rotated again
    00197 // on angle (theta - phi).
    00198 class CV_EXPORTS CvAffinePose
    00199 {
    00200 public:
    00201     float phi;
    00202     float theta;
    00203     float lambda1;
    00204     float lambda2;
    00205 };
    00206
    00219 class CV_EXPORTS_W_SIMPLE KeyPoint
    00220 {
    00221 public:
    00223     CV_WRAP KeyPoint() : pt(0,0), size(0), angle(-1), response(0), octave(0), class_id(-1) {}
    00225     KeyPoint(Point2f _pt, float _size, float _angle=-1,
    00226             float _response=0, int _octave=0, int _class_id=-1)
    00227             : pt(_pt), size(_size), angle(_angle),
    00228             response(_response), octave(_octave), class_id(_class_id) {}
    00230     CV_WRAP KeyPoint(float x, float y, float _size, float _angle=-1,
    00231             float _response=0, int _octave=0, int _class_id=-1)
    00232             : pt(x, y), size(_size), angle(_angle),
    00233             response(_response), octave(_octave), class_id(_class_id) {}
    00235     static void convert(const std::vector<KeyPoint>& keypoints,
    00236                         CV_OUT std::vector<Point2f>& points2f,
    00237                         const std::vector<int>& keypointIndexes=std::vector<int>());
    00239     static void convert(const std::vector<Point2f>& points2f,
    00240                         CV_OUT std::vector<KeyPoint>& keypoints,
    00241                         float size=1, float response=1, int octave=0, int class_id=-1);
    00242
    00246     static float overlap(const KeyPoint& kp1, const KeyPoint& kp2);
    00247
    00248     CV_PROP_RW Point2f pt;
    00249     CV_PROP_RW float size;
    00250     CV_PROP_RW float angle;
    00251     CV_PROP_RW float response;
    00252     CV_PROP_RW int octave;
    00253     CV_PROP_RW int class_id;
    00254 };
    00255
    00257 CV_EXPORTS void write(FileStorage& fs, const string& name, const vector<KeyPoint>& keypoints);
    00259 CV_EXPORTS void read(const FileNode& node, CV_OUT vector<KeyPoint>& keypoints);
    00260
    00266 class CV_EXPORTS SIFT
    00267 {
    00268 public:
    00269     struct CV_EXPORTS CommonParams
    00270     {
    00271         static const int DEFAULT_NOCTAVES = 4;
    00272         static const int DEFAULT_NOCTAVE_LAYERS = 3;
    00273         static const int DEFAULT_FIRST_OCTAVE = -1;
    00274         enum{ FIRST_ANGLE = 0, AVERAGE_ANGLE = 1 };
    00275
    00276         CommonParams();
    00277         CommonParams( int _nOctaves, int _nOctaveLayers, int _firstOctave, int _angleMode );
    00278         int nOctaves, nOctaveLayers, firstOctave;
    00279         int angleMode;
    00280     };
    00281
    00282     struct CV_EXPORTS DetectorParams
    00283     {
    00284         static double GET_DEFAULT_THRESHOLD() { return 0.04 / SIFT::CommonParams::DEFAULT_NOCTAVE_LAYERS / 2.0; }
    00285         static double GET_DEFAULT_EDGE_THRESHOLD() { return 10.0; }
    00286
    00287         DetectorParams();
    00288         DetectorParams( double _threshold, double _edgeThreshold );
    00289         double threshold, edgeThreshold;
    00290     };
    00291
    00292     struct CV_EXPORTS DescriptorParams
    00293     {
    00294         static double GET_DEFAULT_MAGNIFICATION() { return 3.0; }
    00295         static const bool DEFAULT_IS_NORMALIZE = true;
    00296         static const int DESCRIPTOR_SIZE = 128;
    00297
    00298         DescriptorParams();
    00299         DescriptorParams( double _magnification, bool _isNormalize, bool _recalculateAngles );
    00300         double magnification;
    00301         bool isNormalize;
    00302         bool recalculateAngles;
    00303     };
    00304
    00305     SIFT();
    00307     SIFT( double _threshold, double _edgeThreshold,
    00308           int _nOctaves=CommonParams::DEFAULT_NOCTAVES,
    00309           int _nOctaveLayers=CommonParams::DEFAULT_NOCTAVE_LAYERS,
    00310           int _firstOctave=CommonParams::DEFAULT_FIRST_OCTAVE,
    00311           int _angleMode=CommonParams::FIRST_ANGLE );
    00313     SIFT( double _magnification, bool _isNormalize=true,
    00314           bool _recalculateAngles = true,
    00315           int _nOctaves=CommonParams::DEFAULT_NOCTAVES,
    00316           int _nOctaveLayers=CommonParams::DEFAULT_NOCTAVE_LAYERS,
    00317           int _firstOctave=CommonParams::DEFAULT_FIRST_OCTAVE,
    00318           int _angleMode=CommonParams::FIRST_ANGLE );
    00319     SIFT( const CommonParams& _commParams,
    00320           const DetectorParams& _detectorParams = DetectorParams(),
    00321           const DescriptorParams& _descriptorParams = DescriptorParams() );
    00322
    00324     int descriptorSize() const { return DescriptorParams::DESCRIPTOR_SIZE; }
    00326     void operator()(const Mat& img, const Mat& mask,
    00327                     vector<KeyPoint>& keypoints) const;
    00330     void operator()(const Mat& img, const Mat& mask,
    00331                     vector<KeyPoint>& keypoints,
    00332                     Mat& descriptors,
    00333                     bool useProvidedKeypoints=false) const;
    00334
    00335     CommonParams getCommonParams () const { return commParams; }
    00336     DetectorParams getDetectorParams () const { return detectorParams; }
    00337     DescriptorParams getDescriptorParams () const { return descriptorParams; }
    00338 protected:
    00339     CommonParams commParams;
    00340     DetectorParams detectorParams;
    00341     DescriptorParams descriptorParams;
    00342 };
    00343
    00344
    00350 class CV_EXPORTS_W SURF : public CvSURFParams
    00351 {
    00352 public:
    00354     CV_WRAP SURF();
    00356     CV_WRAP SURF(double _hessianThreshold, int _nOctaves=4,
    00357          int _nOctaveLayers=2, bool _extended=false);
    00358
    00360     CV_WRAP int descriptorSize() const;
    00362     CV_WRAP_AS(detect) void operator()(const Mat& img, const Mat& mask,
    00363                     CV_OUT vector<KeyPoint>& keypoints) const;
    00365     CV_WRAP_AS(detect) void operator()(const Mat& img, const Mat& mask,
    00366                     CV_OUT vector<KeyPoint>& keypoints,
    00367                     CV_OUT vector<float>& descriptors,
    00368                     bool useProvidedKeypoints=false) const;
    00369 };
    00370
    00380 class CV_EXPORTS_W MSER : public CvMSERParams
    00381 {
    00382 public:
    00384     CV_WRAP MSER();
    00386     CV_WRAP MSER( int _delta, int _min_area, int _max_area,
    00387           double _max_variation, double _min_diversity,
    00388           int _max_evolution, double _area_threshold,
    00389           double _min_margin, int _edge_blur_size );
    00391     CV_WRAP_AS(detect) void operator()( const Mat& image,
    00392         CV_OUT vector<vector<Point> >& msers, const Mat& mask ) const;
    00393 };
    00394
    00400 class CV_EXPORTS_W StarDetector : public CvStarDetectorParams
    00401 {
    00402 public:
    00404     CV_WRAP StarDetector();
    00406     CV_WRAP StarDetector(int _maxSize, int _responseThreshold,
    00407                  int _lineThresholdProjected,
    00408                  int _lineThresholdBinarized,
    00409                  int _suppressNonmaxSize);
    00411     CV_WRAP_AS(detect) void operator()(const Mat& image,
    00412                 CV_OUT vector<KeyPoint>& keypoints) const;
    00413 };
    00414
    00416 CV_EXPORTS void FAST( const Mat& image, CV_OUT vector<KeyPoint>& keypoints,
    00417                       int threshold, bool nonmaxSupression=true );
    00418
    00422 class CV_EXPORTS PatchGenerator
    00423 {
    00424 public:
    00425     PatchGenerator();
    00426     PatchGenerator(double _backgroundMin, double _backgroundMax,
    00427                    double _noiseRange, bool _randomBlur=true,
    00428                    double _lambdaMin=0.6, double _lambdaMax=1.5,
    00429                    double _thetaMin=-CV_PI, double _thetaMax=CV_PI,
    00430                    double _phiMin=-CV_PI, double _phiMax=CV_PI );
    00431     void operator()(const Mat& image, Point2f pt, Mat& patch, Size patchSize, RNG& rng) const;
    00432     void operator()(const Mat& image, const Mat& transform, Mat& patch,
    00433                     Size patchSize, RNG& rng) const;
    00434     void warpWholeImage(const Mat& image, Mat& matT, Mat& buf,
    00435                         CV_OUT Mat& warped, int border, RNG& rng) const;
    00436     void generateRandomTransform(Point2f srcCenter, Point2f dstCenter,
    00437                                  CV_OUT Mat& transform, RNG& rng,
    00438                                  bool inverse=false) const;
    00439     void setAffineParam(double lambda, double theta, double phi);
    00440
    00441     double backgroundMin, backgroundMax;
    00442     double noiseRange;
    00443     bool randomBlur;
    00444     double lambdaMin, lambdaMax;
    00445     double thetaMin, thetaMax;
    00446     double phiMin, phiMax;
    00447 };
    00448
    00449
    00450 class CV_EXPORTS LDetector
    00451 {
    00452 public:
    00453     LDetector();
    00454     LDetector(int _radius, int _threshold, int _nOctaves,
    00455               int _nViews, double _baseFeatureSize, double _clusteringDistance);
    00456     void operator()(const Mat& image,
    00457                     CV_OUT vector<KeyPoint>& keypoints,
    00458                     int maxCount=0, bool scaleCoords=true) const;
    00459     void operator()(const vector<Mat>& pyr,
    00460                     CV_OUT vector<KeyPoint>& keypoints,
    00461                     int maxCount=0, bool scaleCoords=true) const;
    00462     void getMostStable2D(const Mat& image, CV_OUT vector<KeyPoint>& keypoints,
    00463                          int maxCount, const PatchGenerator& patchGenerator) const;
    00464     void setVerbose(bool verbose);
    00465
    00466     void read(const FileNode& node);
    00467     void write(FileStorage& fs, const String& name=String()) const;
    00468
    00469     int radius;
    00470     int threshold;
    00471     int nOctaves;
    00472     int nViews;
    00473     bool verbose;
    00474
    00475     double baseFeatureSize;
    00476     double clusteringDistance;
    00477 };
    00478
    00479 typedef LDetector YAPE;
    00480
    00481 class CV_EXPORTS FernClassifier
    00482 {
    00483 public:
    00484     FernClassifier();
    00485     FernClassifier(const FileNode& node);
    00486     FernClassifier(const vector<vector<Point2f> >& points,
    00487                    const vector<Mat>& refimgs,
    00488                    const vector<vector<int> >& labels=vector<vector<int> >(),
    00489                    int _nclasses=0, int _patchSize=PATCH_SIZE,
    00490                    int _signatureSize=DEFAULT_SIGNATURE_SIZE,
    00491                    int _nstructs=DEFAULT_STRUCTS,
    00492                    int _structSize=DEFAULT_STRUCT_SIZE,
    00493                    int _nviews=DEFAULT_VIEWS,
    00494                    int _compressionMethod=COMPRESSION_NONE,
    00495                    const PatchGenerator& patchGenerator=PatchGenerator());
    00496     virtual ~FernClassifier();
    00497     virtual void read(const FileNode& n);
    00498     virtual void write(FileStorage& fs, const String& name=String()) const;
    00499     virtual void trainFromSingleView(const Mat& image,
    00500                                      const vector<KeyPoint>& keypoints,
    00501                                      int _patchSize=PATCH_SIZE,
    00502                                      int _signatureSize=DEFAULT_SIGNATURE_SIZE,
    00503                                      int _nstructs=DEFAULT_STRUCTS,
    00504                                      int _structSize=DEFAULT_STRUCT_SIZE,
    00505                                      int _nviews=DEFAULT_VIEWS,
    00506                                      int _compressionMethod=COMPRESSION_NONE,
    00507                                      const PatchGenerator& patchGenerator=PatchGenerator());
    00508     virtual void train(const vector<vector<Point2f> >& points,
    00509                        const vector<Mat>& refimgs,
    00510                        const vector<vector<int> >& labels=vector<vector<int> >(),
    00511                        int _nclasses=0, int _patchSize=PATCH_SIZE,
    00512                        int _signatureSize=DEFAULT_SIGNATURE_SIZE,
    00513                        int _nstructs=DEFAULT_STRUCTS,
    00514                        int _structSize=DEFAULT_STRUCT_SIZE,
    00515                        int _nviews=DEFAULT_VIEWS,
    00516                        int _compressionMethod=COMPRESSION_NONE,
    00517                        const PatchGenerator& patchGenerator=PatchGenerator());
    00518     virtual int operator()(const Mat& img, Point2f kpt, vector<float>& signature) const;
    00519     virtual int operator()(const Mat& patch, vector<float>& signature) const;
    00520     virtual void clear();
    00521     void setVerbose(bool verbose);
    00522
    00523     int getClassCount() const;
    00524     int getStructCount() const;
    00525     int getStructSize() const;
    00526     int getSignatureSize() const;
    00527     int getCompressionMethod() const;
    00528     Size getPatchSize() const;
    00529
    00530     struct Feature
    00531     {
    00532         uchar x1, y1, x2, y2;
    00533         Feature() : x1(0), y1(0), x2(0), y2(0) {}
    00534         Feature(int _x1, int _y1, int _x2, int _y2)
    00535         : x1((uchar)_x1), y1((uchar)_y1), x2((uchar)_x2), y2((uchar)_y2)
    00536         {}
    00537         template<typename _Tp> bool operator ()(const Mat_<_Tp>& patch) const
    00538         { return patch(y1,x1) > patch(y2, x2); }
    00539     };
    00540
    00541     enum
    00542     {
    00543         PATCH_SIZE = 31,
    00544         DEFAULT_STRUCTS = 50,
    00545         DEFAULT_STRUCT_SIZE = 9,
    00546         DEFAULT_VIEWS = 5000,
    00547         DEFAULT_SIGNATURE_SIZE = 176,
    00548         COMPRESSION_NONE = 0,
    00549         COMPRESSION_RANDOM_PROJ = 1,
    00550         COMPRESSION_PCA = 2,
    00551         DEFAULT_COMPRESSION_METHOD = COMPRESSION_NONE
    00552     };
    00553
    00554 protected:
    00555     virtual void prepare(int _nclasses, int _patchSize, int _signatureSize,
    00556                          int _nstructs, int _structSize,
    00557                          int _nviews, int _compressionMethod);
    00558     virtual void finalize(RNG& rng);
    00559     virtual int getLeaf(int fidx, const Mat& patch) const;
    00560
    00561     bool verbose;
    00562     int nstructs;
    00563     int structSize;
    00564     int nclasses;
    00565     int signatureSize;
    00566     int compressionMethod;
    00567     int leavesPerStruct;
    00568     Size patchSize;
    00569     vector<Feature> features;
    00570     vector<int> classCounters;
    00571     vector<float> posteriors;
    00572 };
    00573
    00574
    00575 class CV_EXPORTS PlanarObjectDetector
    00576 {
    00577 public:
    00578     PlanarObjectDetector();
    00579     PlanarObjectDetector(const FileNode& node);
    00580     PlanarObjectDetector(const vector<Mat>& pyr, int _npoints=300,
    00581                          int _patchSize=FernClassifier::PATCH_SIZE,
    00582                          int _nstructs=FernClassifier::DEFAULT_STRUCTS,
    00583                          int _structSize=FernClassifier::DEFAULT_STRUCT_SIZE,
    00584                          int _nviews=FernClassifier::DEFAULT_VIEWS,
    00585                          const LDetector& detector=LDetector(),
    00586                          const PatchGenerator& patchGenerator=PatchGenerator());
    00587     virtual ~PlanarObjectDetector();
    00588     virtual void train(const vector<Mat>& pyr, int _npoints=300,
    00589                        int _patchSize=FernClassifier::PATCH_SIZE,
    00590                        int _nstructs=FernClassifier::DEFAULT_STRUCTS,
    00591                        int _structSize=FernClassifier::DEFAULT_STRUCT_SIZE,
    00592                        int _nviews=FernClassifier::DEFAULT_VIEWS,
    00593                        const LDetector& detector=LDetector(),
    00594                        const PatchGenerator& patchGenerator=PatchGenerator());
    00595     virtual void train(const vector<Mat>& pyr, const vector<KeyPoint>& keypoints,
    00596                        int _patchSize=FernClassifier::PATCH_SIZE,
    00597                        int _nstructs=FernClassifier::DEFAULT_STRUCTS,
    00598                        int _structSize=FernClassifier::DEFAULT_STRUCT_SIZE,
    00599                        int _nviews=FernClassifier::DEFAULT_VIEWS,
    00600                        const LDetector& detector=LDetector(),
    00601                        const PatchGenerator& patchGenerator=PatchGenerator());
    00602     Rect getModelROI() const;
    00603     vector<KeyPoint> getModelPoints() const;
    00604     const LDetector& getDetector() const;
    00605     const FernClassifier& getClassifier() const;
    00606     void setVerbose(bool verbose);
    00607
    00608     void read(const FileNode& node);
    00609     void write(FileStorage& fs, const String& name=String()) const;
    00610     bool operator()(const Mat& image, CV_OUT Mat& H, CV_OUT vector<Point2f>& corners) const;
    00611     bool operator()(const vector<Mat>& pyr, const vector<KeyPoint>& keypoints,
    00612                                        CV_OUT Mat& H, CV_OUT vector<Point2f>& corners,
    00613                                        CV_OUT vector<int>* pairs=0) const;
    00614
    00615 protected:
    00616     bool verbose;
    00617     Rect modelROI;
    00618     vector<KeyPoint> modelPoints;
    00619     LDetector ldetector;
    00620     FernClassifier fernClassifier;
    00621 };
    00622
    00623 /****************************************************************************************\
    00624 *                                 Calonder Classifier                                    *
    00625 \****************************************************************************************/
    00626
    00627 struct RTreeNode;
    00628
    00629 struct CV_EXPORTS BaseKeypoint
    00630 {
    00631   int x;
    00632   int y;
    00633   IplImage* image;
    00634
    00635   BaseKeypoint()
    00636     : x(0), y(0), image(NULL)
    00637   {}
    00638
    00639   BaseKeypoint(int x, int y, IplImage* image)
    00640     : x(x), y(y), image(image)
    00641   {}
    00642 };
    00643
    00644 class CV_EXPORTS RandomizedTree
    00645 {
    00646 public:
    00647   friend class RTreeClassifier;
    00648
    00649   static const uchar PATCH_SIZE = 32;
    00650   static const int DEFAULT_DEPTH = 9;
    00651   static const int DEFAULT_VIEWS = 5000;
    00652   static const size_t DEFAULT_REDUCED_NUM_DIM = 176;
    00653   static float GET_LOWER_QUANT_PERC() { return .03f; }
    00654   static float GET_UPPER_QUANT_PERC() { return .92f; }
    00655
    00656   RandomizedTree();
    00657   ~RandomizedTree();
    00658
    00659   void train(std::vector<BaseKeypoint> const& base_set, RNG &rng,
    00660              int depth, int views, size_t reduced_num_dim, int num_quant_bits);
    00661   void train(std::vector<BaseKeypoint> const& base_set, RNG &rng,
    00662              PatchGenerator &make_patch, int depth, int views, size_t reduced_num_dim,
    00663              int num_quant_bits);
    00664
    00665   // following two funcs are EXPERIMENTAL (do not use unless you know exactly what you do)
    00666   static void quantizeVector(float *vec, int dim, int N, float bnds[2], int clamp_mode=0);
    00667   static void quantizeVector(float *src, int dim, int N, float bnds[2], uchar *dst);
    00668
    00669   // patch_data must be a 32x32 array (no row padding)
    00670   float* getPosterior(uchar* patch_data);
    00671   const float* getPosterior(uchar* patch_data) const;
    00672   uchar* getPosterior2(uchar* patch_data);
    00673   const uchar* getPosterior2(uchar* patch_data) const;
    00674
    00675   void read(const char* file_name, int num_quant_bits);
    00676   void read(std::istream &is, int num_quant_bits);
    00677   void write(const char* file_name) const;
    00678   void write(std::ostream &os) const;
    00679
    00680   int classes() { return classes_; }
    00681   int depth() { return depth_; }
    00682
    00683   //void setKeepFloatPosteriors(bool b) { keep_float_posteriors_ = b; }
    00684   void discardFloatPosteriors() { freePosteriors(1); }
    00685
    00686   inline void applyQuantization(int num_quant_bits) { makePosteriors2(num_quant_bits); }
    00687
    00688   // debug
    00689   void savePosteriors(std::string url, bool append=false);
    00690   void savePosteriors2(std::string url, bool append=false);
    00691
    00692 private:
    00693   int classes_;
    00694   int depth_;
    00695   int num_leaves_;
    00696   std::vector<RTreeNode> nodes_;
    00697   float **posteriors_;        // 16-bytes aligned posteriors
    00698   uchar **posteriors2_;     // 16-bytes aligned posteriors
    00699   std::vector<int> leaf_counts_;
    00700
    00701   void createNodes(int num_nodes, RNG &rng);
    00702   void allocPosteriorsAligned(int num_leaves, int num_classes);
    00703   void freePosteriors(int which);    // which: 1=posteriors_, 2=posteriors2_, 3=both
    00704   void init(int classes, int depth, RNG &rng);
    00705   void addExample(int class_id, uchar* patch_data);
    00706   void finalize(size_t reduced_num_dim, int num_quant_bits);
    00707   int getIndex(uchar* patch_data) const;
    00708   inline float* getPosteriorByIndex(int index);
    00709   inline const float* getPosteriorByIndex(int index) const;
    00710   inline uchar* getPosteriorByIndex2(int index);
    00711   inline const uchar* getPosteriorByIndex2(int index) const;
    00712   //void makeRandomMeasMatrix(float *cs_phi, PHI_DISTR_TYPE dt, size_t reduced_num_dim);
    00713   void convertPosteriorsToChar();
    00714   void makePosteriors2(int num_quant_bits);
    00715   void compressLeaves(size_t reduced_num_dim);
    00716   void estimateQuantPercForPosteriors(float perc[2]);
    00717 };
    00718
    00719
    00720 inline uchar* getData(IplImage* image)
    00721 {
    00722   return reinterpret_cast<uchar*>(image->imageData);
    00723 }
    00724
    00725 inline float* RandomizedTree::getPosteriorByIndex(int index)
    00726 {
    00727   return const_cast<float*>(const_cast<const RandomizedTree*>(this)->getPosteriorByIndex(index));
    00728 }
    00729
    00730 inline const float* RandomizedTree::getPosteriorByIndex(int index) const
    00731 {
    00732   return posteriors_[index];
    00733 }
    00734
    00735 inline uchar* RandomizedTree::getPosteriorByIndex2(int index)
    00736 {
    00737   return const_cast<uchar*>(const_cast<const RandomizedTree*>(this)->getPosteriorByIndex2(index));
    00738 }
    00739
    00740 inline const uchar* RandomizedTree::getPosteriorByIndex2(int index) const
    00741 {
    00742   return posteriors2_[index];
    00743 }
    00744
    00745 struct CV_EXPORTS RTreeNode
    00746 {
    00747   short offset1, offset2;
    00748
    00749   RTreeNode() {}
    00750   RTreeNode(uchar x1, uchar y1, uchar x2, uchar y2)
    00751     : offset1(y1*RandomizedTree::PATCH_SIZE + x1),
    00752       offset2(y2*RandomizedTree::PATCH_SIZE + x2)
    00753   {}
    00754
    00756   inline bool operator() (uchar* patch_data) const
    00757   {
    00758     return patch_data[offset1] > patch_data[offset2];
    00759   }
    00760 };
    00761
    00762 class CV_EXPORTS RTreeClassifier
    00763 {
    00764 public:
    00765   static const int DEFAULT_TREES = 48;
    00766   static const size_t DEFAULT_NUM_QUANT_BITS = 4;
    00767
    00768   RTreeClassifier();
    00769   void train(std::vector<BaseKeypoint> const& base_set,
    00770              RNG &rng,
    00771              int num_trees = RTreeClassifier::DEFAULT_TREES,
    00772              int depth = RandomizedTree::DEFAULT_DEPTH,
    00773              int views = RandomizedTree::DEFAULT_VIEWS,
    00774              size_t reduced_num_dim = RandomizedTree::DEFAULT_REDUCED_NUM_DIM,
    00775              int num_quant_bits = DEFAULT_NUM_QUANT_BITS);
    00776   void train(std::vector<BaseKeypoint> const& base_set,
    00777              RNG &rng,
    00778              PatchGenerator &make_patch,
    00779              int num_trees = RTreeClassifier::DEFAULT_TREES,
    00780              int depth = RandomizedTree::DEFAULT_DEPTH,
    00781              int views = RandomizedTree::DEFAULT_VIEWS,
    00782              size_t reduced_num_dim = RandomizedTree::DEFAULT_REDUCED_NUM_DIM,
    00783              int num_quant_bits = DEFAULT_NUM_QUANT_BITS);
    00784
    00785   // sig must point to a memory block of at least classes()*sizeof(float|uchar) bytes
    00786   void getSignature(IplImage *patch, uchar *sig) const;
    00787   void getSignature(IplImage *patch, float *sig) const;
    00788   void getSparseSignature(IplImage *patch, float *sig, float thresh) const;
    00789   // TODO: deprecated in favor of getSignature overload, remove
    00790   void getFloatSignature(IplImage *patch, float *sig) const { getSignature(patch, sig); }
    00791
    00792   static int countNonZeroElements(float *vec, int n, double tol=1e-10);
    00793   static inline void safeSignatureAlloc(uchar **sig, int num_sig=1, int sig_len=176);
    00794   static inline uchar* safeSignatureAlloc(int num_sig=1, int sig_len=176);
    00795
    00796   inline int classes() const { return classes_; }
    00797   inline int original_num_classes() const { return original_num_classes_; }
    00798
    00799   void setQuantization(int num_quant_bits);
    00800   void discardFloatPosteriors();
    00801
    00802   void read(const char* file_name);
    00803   void read(std::istream &is);
    00804   void write(const char* file_name) const;
    00805   void write(std::ostream &os) const;
    00806
    00807   // experimental and debug
    00808   void saveAllFloatPosteriors(std::string file_url);
    00809   void saveAllBytePosteriors(std::string file_url);
    00810   void setFloatPosteriorsFromTextfile_176(std::string url);
    00811   float countZeroElements();
    00812
    00813   std::vector<RandomizedTree> trees_;
    00814
    00815 private:
    00816   int classes_;
    00817   int num_quant_bits_;
    00818   mutable uchar **posteriors_;
    00819   mutable unsigned short *ptemp_;
    00820   int original_num_classes_;
    00821   bool keep_floats_;
    00822 };
    00823
    00824 /****************************************************************************************\
    00825 *                                     One-Way Descriptor                                 *
    00826 \****************************************************************************************/
    00827
    00828 class CV_EXPORTS OneWayDescriptor
    00829 {
    00830 public:
    00831     OneWayDescriptor();
    00832     ~OneWayDescriptor();
    00833
    00834     // allocates memory for given descriptor parameters
    00835     void Allocate(int pose_count, CvSize size, int nChannels);
    00836
    00837     // GenerateSamples: generates affine transformed patches with averaging them over small transformation variations.
    00838     // If external poses and transforms were specified, uses them instead of generating random ones
    00839     // - pose_count: the number of poses to be generated
    00840     // - frontal: the input patch (can be a roi in a larger image)
    00841     // - norm: if nonzero, normalizes the output patch so that the sum of pixel intensities is 1
    00842     void GenerateSamples(int pose_count, IplImage* frontal, int norm = 0);
    00843
    00844     // GenerateSamplesFast: generates affine transformed patches with averaging them over small transformation variations.
    00845     // Uses precalculated transformed pca components.
    00846     // - frontal: the input patch (can be a roi in a larger image)
    00847     // - pca_hr_avg: pca average vector
    00848     // - pca_hr_eigenvectors: pca eigenvectors
    00849     // - pca_descriptors: an array of precomputed descriptors of pca components containing their affine transformations
    00850     //   pca_descriptors[0] corresponds to the average, pca_descriptors[1]-pca_descriptors[pca_dim] correspond to eigenvectors
    00851     void GenerateSamplesFast(IplImage* frontal, CvMat* pca_hr_avg,
    00852                              CvMat* pca_hr_eigenvectors, OneWayDescriptor* pca_descriptors);
    00853
    00854     // sets the poses and corresponding transforms
    00855     void SetTransforms(CvAffinePose* poses, CvMat** transforms);
    00856
    00857     // Initialize: builds a descriptor.
    00858     // - pose_count: the number of poses to build. If poses were set externally, uses them rather than generating random ones
    00859     // - frontal: input patch. Can be a roi in a larger image
    00860     // - feature_name: the feature name to be associated with the descriptor
    00861     // - norm: if 1, the affine transformed patches are normalized so that their sum is 1
    00862     void Initialize(int pose_count, IplImage* frontal, const char* feature_name = 0, int norm = 0);
    00863
    00864     // InitializeFast: builds a descriptor using precomputed descriptors of pca components
    00865     // - pose_count: the number of poses to build
    00866     // - frontal: input patch. Can be a roi in a larger image
    00867     // - feature_name: the feature name to be associated with the descriptor
    00868     // - pca_hr_avg: average vector for PCA
    00869     // - pca_hr_eigenvectors: PCA eigenvectors (one vector per row)
    00870     // - pca_descriptors: precomputed descriptors of PCA components, the first descriptor for the average vector
    00871     // followed by the descriptors for eigenvectors
    00872     void InitializeFast(int pose_count, IplImage* frontal, const char* feature_name,
    00873                         CvMat* pca_hr_avg, CvMat* pca_hr_eigenvectors, OneWayDescriptor* pca_descriptors);
    00874
    00875     // ProjectPCASample: unwarps an image patch into a vector and projects it into PCA space
    00876     // - patch: input image patch
    00877     // - avg: PCA average vector
    00878     // - eigenvectors: PCA eigenvectors, one per row
    00879     // - pca_coeffs: output PCA coefficients
    00880     void ProjectPCASample(IplImage* patch, CvMat* avg, CvMat* eigenvectors, CvMat* pca_coeffs) const;
    00881
    00882     // InitializePCACoeffs: projects all warped patches into PCA space
    00883     // - avg: PCA average vector
    00884     // - eigenvectors: PCA eigenvectors, one per row
    00885     void InitializePCACoeffs(CvMat* avg, CvMat* eigenvectors);
    00886
    00887     // EstimatePose: finds the closest match between an input patch and a set of patches with different poses
    00888     // - patch: input image patch
    00889     // - pose_idx: the output index of the closest pose
    00890     // - distance: the distance to the closest pose (L2 distance)
    00891     void EstimatePose(IplImage* patch, int& pose_idx, float& distance) const;
    00892
    00893     // EstimatePosePCA: finds the closest match between an input patch and a set of patches with different poses.
    00894     // The distance between patches is computed in PCA space
    00895     // - patch: input image patch
    00896     // - pose_idx: the output index of the closest pose
    00897     // - distance: distance to the closest pose (L2 distance in PCA space)
    00898     // - avg: PCA average vector. If 0, matching without PCA is used
    00899     // - eigenvectors: PCA eigenvectors, one per row
    00900     void EstimatePosePCA(CvArr* patch, int& pose_idx, float& distance, CvMat* avg, CvMat* eigenvalues) const;
    00901
    00902     // GetPatchSize: returns the size of each image patch after warping (2 times smaller than the input patch)
    00903     CvSize GetPatchSize() const
    00904     {
    00905         return m_patch_size;
    00906     }
    00907
    00908     // GetInputPatchSize: returns the required size of the patch that the descriptor is built from
    00909     // (2 time larger than the patch after warping)
    00910     CvSize GetInputPatchSize() const
    00911     {
    00912         return cvSize(m_patch_size.width*2, m_patch_size.height*2);
    00913     }
    00914
    00915     // GetPatch: returns a patch corresponding to specified pose index
    00916     // - index: pose index
    00917     // - return value: the patch corresponding to specified pose index
    00918     IplImage* GetPatch(int index);
    00919
    00920     // GetPose: returns a pose corresponding to specified pose index
    00921     // - index: pose index
    00922     // - return value: the pose corresponding to specified pose index
    00923     CvAffinePose GetPose(int index) const;
    00924
    00925     // Save: saves all patches with different poses to a specified path
    00926     void Save(const char* path);
    00927
    00928     // ReadByName: reads a descriptor from a file storage
    00929     // - fs: file storage
    00930     // - parent: parent node
    00931     // - name: node name
    00932     // - return value: 1 if succeeded, 0 otherwise
    00933     int ReadByName(CvFileStorage* fs, CvFileNode* parent, const char* name);
    00934
    00935     // ReadByName: reads a descriptor from a file node
    00936     // - parent: parent node
    00937     // - name: node name
    00938     // - return value: 1 if succeeded, 0 otherwise
    00939     int ReadByName(const FileNode &parent, const char* name);
    00940
    00941     // Write: writes a descriptor into a file storage
    00942     // - fs: file storage
    00943     // - name: node name
    00944     void Write(CvFileStorage* fs, const char* name);
    00945
    00946     // GetFeatureName: returns a name corresponding to a feature
    00947     const char* GetFeatureName() const;
    00948
    00949     // GetCenter: returns the center of the feature
    00950     CvPoint GetCenter() const;
    00951
    00952     void SetPCADimHigh(int pca_dim_high) {m_pca_dim_high = pca_dim_high;};
    00953     void SetPCADimLow(int pca_dim_low) {m_pca_dim_low = pca_dim_low;};
    00954
    00955     int GetPCADimLow() const;
    00956     int GetPCADimHigh() const;
    00957
    00958     CvMat** GetPCACoeffs() const {return m_pca_coeffs;}
    00959
    00960 protected:
    00961     int m_pose_count; // the number of poses
    00962     CvSize m_patch_size; // size of each image
    00963     IplImage** m_samples; // an array of length m_pose_count containing the patch in different poses
    00964     IplImage* m_input_patch;
    00965     IplImage* m_train_patch;
    00966     CvMat** m_pca_coeffs; // an array of length m_pose_count containing pca decomposition of the patch in different poses
    00967     CvAffinePose* m_affine_poses; // an array of poses
    00968     CvMat** m_transforms; // an array of affine transforms corresponding to poses
    00969
    00970     string m_feature_name; // the name of the feature associated with the descriptor
    00971     CvPoint m_center; // the coordinates of the feature (the center of the input image ROI)
    00972
    00973     int m_pca_dim_high; // the number of descriptor pca components to use for generating affine poses
    00974     int m_pca_dim_low; // the number of pca components to use for comparison
    00975 };
    00976
    00977
    00978 // OneWayDescriptorBase: encapsulates functionality for training/loading a set of one way descriptors
    00979 // and finding the nearest closest descriptor to an input feature
    00980 class CV_EXPORTS OneWayDescriptorBase
    00981 {
    00982 public:
    00983
    00984     // creates an instance of OneWayDescriptor from a set of training files
    00985     // - patch_size: size of the input (large) patch
    00986     // - pose_count: the number of poses to generate for each descriptor
    00987     // - train_path: path to training files
    00988     // - pca_config: the name of the file that contains PCA for small patches (2 times smaller
    00989     // than patch_size each dimension
    00990     // - pca_hr_config: the name of the file that contains PCA for large patches (of patch_size size)
    00991     // - pca_desc_config: the name of the file that contains descriptors of PCA components
    00992     OneWayDescriptorBase(CvSize patch_size, int pose_count, const char* train_path = 0, const char* pca_config = 0,
    00993                          const char* pca_hr_config = 0, const char* pca_desc_config = 0, int pyr_levels = 1,
    00994                          int pca_dim_high = 100, int pca_dim_low = 100);
    00995
    00996     OneWayDescriptorBase(CvSize patch_size, int pose_count, const string &pca_filename, const string &train_path = string(), const string &images_list = string(),
    00997                          float _scale_min = 0.7f, float _scale_max=1.5f, float _scale_step=1.2f, int pyr_levels = 1,
    00998                          int pca_dim_high = 100, int pca_dim_low = 100);
    00999
    01000
    01001     virtual ~OneWayDescriptorBase();
    01002     void clear ();
    01003
    01004
    01005     // Allocate: allocates memory for a given number of descriptors
    01006     void Allocate(int train_feature_count);
    01007
    01008     // AllocatePCADescriptors: allocates memory for pca descriptors
    01009     void AllocatePCADescriptors();
    01010
    01011     // returns patch size
    01012     CvSize GetPatchSize() const {return m_patch_size;};
    01013     // returns the number of poses for each descriptor
    01014     int GetPoseCount() const {return m_pose_count;};
    01015
    01016     // returns the number of pyramid levels
    01017     int GetPyrLevels() const {return m_pyr_levels;};
    01018
    01019     // returns the number of descriptors
    01020     int GetDescriptorCount() const {return m_train_feature_count;};
    01021
    01022     // CreateDescriptorsFromImage: creates descriptors for each of the input features
    01023     // - src: input image
    01024     // - features: input features
    01025     // - pyr_levels: the number of pyramid levels
    01026     void CreateDescriptorsFromImage(IplImage* src, const std::vector<cv::KeyPoint>& features);
    01027
    01028     // CreatePCADescriptors: generates descriptors for PCA components, needed for fast generation of feature descriptors
    01029     void CreatePCADescriptors();
    01030
    01031     // returns a feature descriptor by feature index
    01032     const OneWayDescriptor* GetDescriptor(int desc_idx) const {return &m_descriptors[desc_idx];};
    01033
    01034     // FindDescriptor: finds the closest descriptor
    01035     // - patch: input image patch
    01036     // - desc_idx: output index of the closest descriptor to the input patch
    01037     // - pose_idx: output index of the closest pose of the closest descriptor to the input patch
    01038     // - distance: distance from the input patch to the closest feature pose
    01039     // - _scales: scales of the input patch for each descriptor
    01040     // - scale_ranges: input scales variation (float[2])
    01041     void FindDescriptor(IplImage* patch, int& desc_idx, int& pose_idx, float& distance, float* _scale = 0, float* scale_ranges = 0) const;
    01042
    01043     // - patch: input image patch
    01044     // - n: number of the closest indexes
    01045     // - desc_idxs: output indexes of the closest descriptor to the input patch (n)
    01046     // - pose_idx: output indexes of the closest pose of the closest descriptor to the input patch (n)
    01047     // - distances: distance from the input patch to the closest feature pose (n)
    01048     // - _scales: scales of the input patch
    01049     // - scale_ranges: input scales variation (float[2])
    01050     void FindDescriptor(IplImage* patch, int n, std::vector<int>& desc_idxs, std::vector<int>& pose_idxs,
    01051                         std::vector<float>& distances, std::vector<float>& _scales, float* scale_ranges = 0) const;
    01052
    01053     // FindDescriptor: finds the closest descriptor
    01054     // - src: input image
    01055     // - pt: center of the feature
    01056     // - desc_idx: output index of the closest descriptor to the input patch
    01057     // - pose_idx: output index of the closest pose of the closest descriptor to the input patch
    01058     // - distance: distance from the input patch to the closest feature pose
    01059     void FindDescriptor(IplImage* src, cv::Point2f pt, int& desc_idx, int& pose_idx, float& distance) const;
    01060
    01061     // InitializePoses: generates random poses
    01062     void InitializePoses();
    01063
    01064     // InitializeTransformsFromPoses: generates 2x3 affine matrices from poses (initializes m_transforms)
    01065     void InitializeTransformsFromPoses();
    01066
    01067     // InitializePoseTransforms: subsequently calls InitializePoses and InitializeTransformsFromPoses
    01068     void InitializePoseTransforms();
    01069
    01070     // InitializeDescriptor: initializes a descriptor
    01071     // - desc_idx: descriptor index
    01072     // - train_image: image patch (ROI is supported)
    01073     // - feature_label: feature textual label
    01074     void InitializeDescriptor(int desc_idx, IplImage* train_image, const char* feature_label);
    01075
    01076     void InitializeDescriptor(int desc_idx, IplImage* train_image, const cv::KeyPoint& keypoint, const char* feature_label);
    01077
    01078     // InitializeDescriptors: load features from an image and create descriptors for each of them
    01079     void InitializeDescriptors(IplImage* train_image, const vector<cv::KeyPoint>& features,
    01080                                const char* feature_label = "", int desc_start_idx = 0);
    01081
    01082     // Write: writes this object to a file storage
    01083     // - fs: output filestorage
    01084     void Write (FileStorage &fs) const;
    01085
    01086     // Read: reads OneWayDescriptorBase object from a file node
    01087     // - fn: input file node
    01088     void Read (const FileNode &fn);
    01089
    01090     // LoadPCADescriptors: loads PCA descriptors from a file
    01091     // - filename: input filename
    01092     int LoadPCADescriptors(const char* filename);
    01093
    01094     // LoadPCADescriptors: loads PCA descriptors from a file node
    01095     // - fn: input file node
    01096     int LoadPCADescriptors(const FileNode &fn);
    01097
    01098     // SavePCADescriptors: saves PCA descriptors to a file
    01099     // - filename: output filename
    01100     void SavePCADescriptors(const char* filename);
    01101
    01102     // SavePCADescriptors: saves PCA descriptors to a file storage
    01103     // - fs: output file storage
    01104     void SavePCADescriptors(CvFileStorage* fs) const;
    01105
    01106     // GeneratePCA: calculate and save PCA components and descriptors
    01107     // - img_path: path to training PCA images directory
    01108     // - images_list: filename with filenames of training PCA images
    01109     void GeneratePCA(const char* img_path, const char* images_list, int pose_count=500);
    01110
    01111     // SetPCAHigh: sets the high resolution pca matrices (copied to internal structures)
    01112     void SetPCAHigh(CvMat* avg, CvMat* eigenvectors);
    01113
    01114     // SetPCALow: sets the low resolution pca matrices (copied to internal structures)
    01115     void SetPCALow(CvMat* avg, CvMat* eigenvectors);
    01116
    01117     int GetLowPCA(CvMat** avg, CvMat** eigenvectors)
    01118     {
    01119         *avg = m_pca_avg;
    01120         *eigenvectors = m_pca_eigenvectors;
    01121         return m_pca_dim_low;
    01122     };
    01123
    01124     int GetPCADimLow() const {return m_pca_dim_low;};
    01125     int GetPCADimHigh() const {return m_pca_dim_high;};
    01126
    01127     void ConvertDescriptorsArrayToTree(); // Converting pca_descriptors array to KD tree
    01128
    01129     // GetPCAFilename: get default PCA filename
    01130     static string GetPCAFilename () { return "pca.yml"; }
    01131
    01132 protected:
    01133     CvSize m_patch_size; // patch size
    01134     int m_pose_count; // the number of poses for each descriptor
    01135     int m_train_feature_count; // the number of the training features
    01136     OneWayDescriptor* m_descriptors; // array of train feature descriptors
    01137     CvMat* m_pca_avg; // PCA average Vector for small patches
    01138     CvMat* m_pca_eigenvectors; // PCA eigenvectors for small patches
    01139     CvMat* m_pca_hr_avg; // PCA average Vector for large patches
    01140     CvMat* m_pca_hr_eigenvectors; // PCA eigenvectors for large patches
    01141     OneWayDescriptor* m_pca_descriptors; // an array of PCA descriptors
    01142
    01143     cv::flann::Index* m_pca_descriptors_tree;
    01144     CvMat* m_pca_descriptors_matrix;
    01145
    01146     CvAffinePose* m_poses; // array of poses
    01147     CvMat** m_transforms; // array of affine transformations corresponding to poses
    01148
    01149     int m_pca_dim_high;
    01150     int m_pca_dim_low;
    01151
    01152     int m_pyr_levels;
    01153     float scale_min;
    01154     float scale_max;
    01155     float scale_step;
    01156
    01157     // SavePCAall: saves PCA components and descriptors to a file storage
    01158     // - fs: output file storage
    01159     void SavePCAall (FileStorage &fs) const;
    01160
    01161     // LoadPCAall: loads PCA components and descriptors from a file node
    01162     // - fn: input file node
    01163     void LoadPCAall (const FileNode &fn);
    01164 };
    01165
    01166 class CV_EXPORTS OneWayDescriptorObject : public OneWayDescriptorBase
    01167 {
    01168 public:
    01169     // creates an instance of OneWayDescriptorObject from a set of training files
    01170     // - patch_size: size of the input (large) patch
    01171     // - pose_count: the number of poses to generate for each descriptor
    01172     // - train_path: path to training files
    01173     // - pca_config: the name of the file that contains PCA for small patches (2 times smaller
    01174     // than patch_size each dimension
    01175     // - pca_hr_config: the name of the file that contains PCA for large patches (of patch_size size)
    01176     // - pca_desc_config: the name of the file that contains descriptors of PCA components
    01177     OneWayDescriptorObject(CvSize patch_size, int pose_count, const char* train_path, const char* pca_config,
    01178                            const char* pca_hr_config = 0, const char* pca_desc_config = 0, int pyr_levels = 1);
    01179
    01180     OneWayDescriptorObject(CvSize patch_size, int pose_count, const string &pca_filename,
    01181                            const string &train_path = string (), const string &images_list = string (),
    01182                            float _scale_min = 0.7f, float _scale_max=1.5f, float _scale_step=1.2f, int pyr_levels = 1);
    01183
    01184
    01185     virtual ~OneWayDescriptorObject();
    01186
    01187     // Allocate: allocates memory for a given number of features
    01188     // - train_feature_count: the total number of features
    01189     // - object_feature_count: the number of features extracted from the object
    01190     void Allocate(int train_feature_count, int object_feature_count);
    01191
    01192
    01193     void SetLabeledFeatures(const vector<cv::KeyPoint>& features) {m_train_features = features;};
    01194     vector<cv::KeyPoint>& GetLabeledFeatures() {return m_train_features;};
    01195     const vector<cv::KeyPoint>& GetLabeledFeatures() const {return m_train_features;};
    01196     vector<cv::KeyPoint> _GetLabeledFeatures() const;
    01197
    01198     // IsDescriptorObject: returns 1 if descriptor with specified index is positive, otherwise 0
    01199     int IsDescriptorObject(int desc_idx) const;
    01200
    01201     // MatchPointToPart: returns the part number of a feature if it matches one of the object parts, otherwise -1
    01202     int MatchPointToPart(CvPoint pt) const;
    01203
    01204     // GetDescriptorPart: returns the part number of the feature corresponding to a specified descriptor
    01205     // - desc_idx: descriptor index
    01206     int GetDescriptorPart(int desc_idx) const;
    01207
    01208
    01209     void InitializeObjectDescriptors(IplImage* train_image, const vector<cv::KeyPoint>& features,
    01210                                      const char* feature_label, int desc_start_idx = 0, float scale = 1.0f,
    01211                                      int is_background = 0);
    01212
    01213     // GetObjectFeatureCount: returns the number of object features
    01214     int GetObjectFeatureCount() const {return m_object_feature_count;};
    01215
    01216 protected:
    01217     int* m_part_id; // contains part id for each of object descriptors
    01218     vector<cv::KeyPoint> m_train_features; // train features
    01219     int m_object_feature_count; // the number of the positive features
    01220
    01221 };
    01222
    01223
    01224 /****************************************************************************************\
    01225 *                                    FeatureDetector                                     *
    01226 \****************************************************************************************/
    01227
    01228 /*
    01229  * Abstract base class for 2D image feature detectors.
    01230  */
    01231 class CV_EXPORTS FeatureDetector
    01232 {
    01233 public:
    01234     virtual ~FeatureDetector();
    01235
    01236     /*
    01237      * Detect keypoints in an image.
    01238      * image        The image.
    01239      * keypoints    The detected keypoints.
    01240      * mask         Mask specifying where to look for keypoints (optional). Must be a char
    01241      *              matrix with non-zero values in the region of interest.
    01242      */
    01243     void detect( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
    01244
    01245     /*
    01246      * Detect keypoints in an image set.
    01247      * images       Image collection.
    01248      * keypoints    Collection of keypoints detected in an input images. keypoints[i] is a set of keypoints detected in an images[i].
    01249      * masks        Masks for image set. masks[i] is a mask for images[i].
    01250      */
    01251     void detect( const vector<Mat>& images, vector<vector<KeyPoint> >& keypoints, const vector<Mat>& masks=vector<Mat>() ) const;
    01252
    01253     // Read detector object from a file node.
    01254     virtual void read( const FileNode& );
    01255     // Read detector object from a file node.
    01256     virtual void write( FileStorage& ) const;
    01257
    01258     // Create feature detector by detector name.
    01259     static Ptr<FeatureDetector> create( const string& detectorType );
    01260
    01261 protected:
    01262         virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const = 0;
    01263     /*
    01264      * Remove keypoints that are not in the mask.
    01265      * Helper function, useful when wrapping a library call for keypoint detection that
    01266      * does not support a mask argument.
    01267      */
    01268     static void removeInvalidPoints( const Mat& mask, vector<KeyPoint>& keypoints );
    01269 };
    01270
    01271 class CV_EXPORTS FastFeatureDetector : public FeatureDetector
    01272 {
    01273 public:
    01274     FastFeatureDetector( int threshold=10, bool nonmaxSuppression=true );
    01275     virtual void read( const FileNode& fn );
    01276     virtual void write( FileStorage& fs ) const;
    01277
    01278 protected:
    01279         virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
    01280
    01281     int threshold;
    01282     bool nonmaxSuppression;
    01283 };
    01284
    01285
    01286 class CV_EXPORTS GoodFeaturesToTrackDetector : public FeatureDetector
    01287 {
    01288 public:
    01289     class CV_EXPORTS Params
    01290     {
    01291     public:
    01292         Params( int maxCorners=1000, double qualityLevel=0.01, double minDistance=1.,
    01293                 int blockSize=3, bool useHarrisDetector=false, double k=0.04 );
    01294         void read( const FileNode& fn );
    01295         void write( FileStorage& fs ) const;
    01296
    01297         int maxCorners;
    01298         double qualityLevel;
    01299         double minDistance;
    01300         int blockSize;
    01301         bool useHarrisDetector;
    01302         double k;
    01303     };
    01304
    01305     GoodFeaturesToTrackDetector( const GoodFeaturesToTrackDetector::Params& params=GoodFeaturesToTrackDetector::Params() );
    01306     GoodFeaturesToTrackDetector( int maxCorners, double qualityLevel, double minDistance,
    01307                                  int blockSize=3, bool useHarrisDetector=false, double k=0.04 );
    01308     virtual void read( const FileNode& fn );
    01309     virtual void write( FileStorage& fs ) const;
    01310
    01311 protected:
    01312         virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
    01313
    01314         Params params;
    01315 };
    01316
    01317 class CV_EXPORTS MserFeatureDetector : public FeatureDetector
    01318 {
    01319 public:
    01320     MserFeatureDetector( CvMSERParams params=cvMSERParams() );
    01321     MserFeatureDetector( int delta, int minArea, int maxArea, double maxVariation, double minDiversity,
    01322                          int maxEvolution, double areaThreshold, double minMargin, int edgeBlurSize );
    01323     virtual void read( const FileNode& fn );
    01324     virtual void write( FileStorage& fs ) const;
    01325
    01326 protected:
    01327         virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
    01328
    01329     MSER mser;
    01330 };
    01331
    01332 class CV_EXPORTS StarFeatureDetector : public FeatureDetector
    01333 {
    01334 public:
    01335     StarFeatureDetector( const CvStarDetectorParams& params=cvStarDetectorParams() );
    01336     StarFeatureDetector( int maxSize, int responseThreshold=30, int lineThresholdProjected = 10,
    01337                          int lineThresholdBinarized=8, int suppressNonmaxSize=5 );
    01338     virtual void read( const FileNode& fn );
    01339     virtual void write( FileStorage& fs ) const;
    01340
    01341 protected:
    01342         virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
    01343
    01344     StarDetector star;
    01345 };
    01346
    01347 class CV_EXPORTS SiftFeatureDetector : public FeatureDetector
    01348 {
    01349 public:
    01350     SiftFeatureDetector( const SIFT::DetectorParams& detectorParams=SIFT::DetectorParams(),
    01351                          const SIFT::CommonParams& commonParams=SIFT::CommonParams() );
    01352     SiftFeatureDetector( double threshold, double edgeThreshold,
    01353                          int nOctaves=SIFT::CommonParams::DEFAULT_NOCTAVES,
    01354                          int nOctaveLayers=SIFT::CommonParams::DEFAULT_NOCTAVE_LAYERS,
    01355                          int firstOctave=SIFT::CommonParams::DEFAULT_FIRST_OCTAVE,
    01356                          int angleMode=SIFT::CommonParams::FIRST_ANGLE );
    01357     virtual void read( const FileNode& fn );
    01358     virtual void write( FileStorage& fs ) const;
    01359
    01360 protected:
    01361         virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
    01362
    01363     SIFT sift;
    01364 };
    01365
    01366 class CV_EXPORTS SurfFeatureDetector : public FeatureDetector
    01367 {
    01368 public:
    01369     SurfFeatureDetector( double hessianThreshold=400., int octaves=3, int octaveLayers=4 );
    01370     virtual void read( const FileNode& fn );
    01371     virtual void write( FileStorage& fs ) const;
    01372
    01373 protected:
    01374         virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
    01375
    01376     SURF surf;
    01377 };
    01378
    01379 class CV_EXPORTS DenseFeatureDetector : public FeatureDetector
    01380 {
    01381 public:
    01382     class CV_EXPORTS Params
    01383     {
    01384     public:
    01385         Params( float initFeatureScale=1.f, int featureScaleLevels=1, float featureScaleMul=0.1f,
    01386                 int initXyStep=6, int initImgBound=0, bool varyXyStepWithScale=true, bool varyImgBoundWithScale=false );
    01387         float initFeatureScale;
    01388         int featureScaleLevels;
    01389         float featureScaleMul;
    01390
    01391         int initXyStep;
    01392         int initImgBound;
    01393
    01394         bool varyXyStepWithScale;
    01395         bool varyImgBoundWithScale;
    01396     };
    01397
    01398     DenseFeatureDetector( const DenseFeatureDetector::Params& params=DenseFeatureDetector::Params() );
    01399
    01400         // TODO implement read/write
    01401
    01402 protected:
    01403         virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
    01404
    01405         Params params;
    01406 };
    01407
    01408 /*
    01409  * Adapts a detector to partition the source image into a grid and detect
    01410  * points in each cell.
    01411  */
    01412 class CV_EXPORTS GridAdaptedFeatureDetector : public FeatureDetector
    01413 {
    01414 public:
    01415     /*
    01416      * detector            Detector that will be adapted.
    01417      * maxTotalKeypoints   Maximum count of keypoints detected on the image. Only the strongest keypoints
    01418      *                      will be keeped.
    01419      * gridRows            Grid rows count.
    01420      * gridCols            Grid column count.
    01421      */
    01422     GridAdaptedFeatureDetector( const Ptr<FeatureDetector>& detector, int maxTotalKeypoints=1000,
    01423                                 int gridRows=4, int gridCols=4 );
    01424
    01425     // TODO implement read/write
    01426
    01427 protected:
    01428         virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
    01429
    01430     Ptr<FeatureDetector> detector;
    01431     int maxTotalKeypoints;
    01432     int gridRows;
    01433     int gridCols;
    01434 };
    01435
    01436 /*
    01437  * Adapts a detector to detect points over multiple levels of a Gaussian
    01438  * pyramid. Useful for detectors that are not inherently scaled.
    01439  */
    01440 class CV_EXPORTS PyramidAdaptedFeatureDetector : public FeatureDetector
    01441 {
    01442 public:
    01443     PyramidAdaptedFeatureDetector( const Ptr<FeatureDetector>& detector, int levels=2 );
    01444
    01445     // TODO implement read/write
    01446
    01447 protected:
    01448         virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
    01449
    01450     Ptr<FeatureDetector> detector;
    01451     int levels;
    01452 };
    01453
    01457 class CV_EXPORTS AdjusterAdapter: public FeatureDetector
    01458 {
    01459 public:
    01462     virtual ~AdjusterAdapter() {}
    01467         virtual void tooFew(int min, int n_detected) = 0;
    01472         virtual void tooMany(int max, int n_detected) = 0;
    01476         virtual bool good() const = 0;
    01477
    01478     static Ptr<AdjusterAdapter> create( const string& detectorType );
    01479 };
    01492 class CV_EXPORTS DynamicAdaptedFeatureDetector: public FeatureDetector
    01493 {
    01494 public:
    01495
    01502     DynamicAdaptedFeatureDetector( const Ptr<AdjusterAdapter>& adjaster, int min_features=400, int max_features=500, int max_iters=5 );
    01503
    01504 protected:
    01505     virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
    01506
    01507 private:
    01508         int escape_iters_;
    01509         int min_features_, max_features_;
    01510         Ptr<AdjusterAdapter> adjuster_;
    01511 };
    01512
    01516 class CV_EXPORTS FastAdjuster: public AdjusterAdapter
    01517 {
    01518 public:
    01522         FastAdjuster(int init_thresh = 20, bool nonmax = true);
    01523         virtual void tooFew(int min, int n_detected);
    01524         virtual void tooMany(int max, int n_detected);
    01525         virtual bool good() const;
    01526
    01527 protected:
    01528     virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
    01529
    01530         int thresh_;
    01531         bool nonmax_;
    01532 };
    01533
    01534
    01538 class CV_EXPORTS StarAdjuster: public AdjusterAdapter
    01539 {
    01540 public:
    01541         StarAdjuster(double initial_thresh = 30.0);
    01542         virtual void tooFew(int min, int n_detected);
    01543         virtual void tooMany(int max, int n_detected);
    01544         virtual bool good() const;
    01545
    01546 protected:
    01547     virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
    01548
    01549         double thresh_;
    01550         CvStarDetectorParams params_; //todo use these instead of thresh_
    01551 };
    01552
    01553 class CV_EXPORTS SurfAdjuster: public AdjusterAdapter
    01554 {
    01555 public:
    01556     SurfAdjuster();
    01557         virtual void tooFew(int min, int n_detected);
    01558         virtual void tooMany(int max, int n_detected);
    01559         virtual bool good() const;
    01560
    01561 protected:
    01562     virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
    01563
    01564         double thresh_;
    01565 };
    01566
    01567 CV_EXPORTS Mat windowedMatchingMask( const vector<KeyPoint>& keypoints1, const vector<KeyPoint>& keypoints2,
    01568                                      float maxDeltaX, float maxDeltaY );
    01569
    01570 /****************************************************************************************\
    01571 *                                 DescriptorExtractor                                    *
    01572 \****************************************************************************************/
    01573
    01574 /*
    01575  * Abstract base class for computing descriptors for image keypoints.
    01576  *
    01577  * In this interface we assume a keypoint descriptor can be represented as a
    01578  * dense, fixed-dimensional vector of some basic type. Most descriptors used
    01579  * in practice follow this pattern, as it makes it very easy to compute
    01580  * distances between descriptors. Therefore we represent a collection of
    01581  * descriptors as a cv::Mat, where each row is one keypoint descriptor.
    01582  */
    01583 class CV_EXPORTS DescriptorExtractor
    01584 {
    01585 public:
    01586     virtual ~DescriptorExtractor();
    01587
    01588     /*
    01589      * Compute the descriptors for a set of keypoints in an image.
    01590      * image        The image.
    01591      * keypoints    The input keypoints. Keypoints for which a descriptor cannot be computed are removed.
    01592      * descriptors  Copmputed descriptors. Row i is the descriptor for keypoint i.
    01593      */
    01594     void compute( const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors ) const;
    01595
    01596     /*
    01597      * Compute the descriptors for a keypoints collection detected in image collection.
    01598      * images       Image collection.
    01599      * keypoints    Input keypoints collection. keypoints[i] is keypoints detected in images[i].
    01600      *              Keypoints for which a descriptor cannot be computed are removed.
    01601      * descriptors  Descriptor collection. descriptors[i] are descriptors computed for set keypoints[i].
    01602      */
    01603     void compute( const vector<Mat>& images, vector<vector<KeyPoint> >& keypoints, vector<Mat>& descriptors ) const;
    01604
    01605     virtual void read( const FileNode& );
    01606     virtual void write( FileStorage& ) const;
    01607
    01608     virtual int descriptorSize() const = 0;
    01609     virtual int descriptorType() const = 0;
    01610
    01611     static Ptr<DescriptorExtractor> create( const string& descriptorExtractorType );
    01612
    01613 protected:
    01614         virtual void computeImpl( const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors ) const = 0;
    01615
    01616     /*
    01617      * Remove keypoints within borderPixels of an image edge.
    01618      */
    01619     static void removeBorderKeypoints( vector<KeyPoint>& keypoints,
    01620                                        Size imageSize, int borderSize );
    01621 };
    01622
    01623 /*
    01624  * SiftDescriptorExtractor
    01625  */
    01626 class CV_EXPORTS SiftDescriptorExtractor : public DescriptorExtractor
    01627 {
    01628 public:
    01629     SiftDescriptorExtractor( const SIFT::DescriptorParams& descriptorParams=SIFT::DescriptorParams(),
    01630                              const SIFT::CommonParams& commonParams=SIFT::CommonParams() );
    01631     SiftDescriptorExtractor( double magnification, bool isNormalize=true, bool recalculateAngles=true,
    01632                              int nOctaves=SIFT::CommonParams::DEFAULT_NOCTAVES,
    01633                              int nOctaveLayers=SIFT::CommonParams::DEFAULT_NOCTAVE_LAYERS,
    01634                              int firstOctave=SIFT::CommonParams::DEFAULT_FIRST_OCTAVE,
    01635                              int angleMode=SIFT::CommonParams::FIRST_ANGLE );
    01636
    01637     virtual void read( const FileNode &fn );
    01638     virtual void write( FileStorage &fs ) const;
    01639
    01640     virtual int descriptorSize() const;
    01641     virtual int descriptorType() const;
    01642
    01643 protected:
    01644         virtual void computeImpl( const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors ) const;
    01645
    01646     SIFT sift;
    01647 };
    01648
    01649 /*
    01650  * SurfDescriptorExtractor
    01651  */
    01652 class CV_EXPORTS SurfDescriptorExtractor : public DescriptorExtractor
    01653 {
    01654 public:
    01655     SurfDescriptorExtractor( int nOctaves=4, int nOctaveLayers=2, bool extended=false );
    01656
    01657     virtual void read( const FileNode &fn );
    01658     virtual void write( FileStorage &fs ) const;
    01659
    01660     virtual int descriptorSize() const;
    01661     virtual int descriptorType() const;
    01662
    01663 protected:
    01664         virtual void computeImpl( const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors ) const;
    01665
    01666     SURF surf;
    01667 };
    01668
    01669 /*
    01670  * CalonderDescriptorExtractor
    01671  */
    01672 template<typename T>
    01673 class CV_EXPORTS CalonderDescriptorExtractor : public DescriptorExtractor
    01674 {
    01675 public:
    01676     CalonderDescriptorExtractor( const string& classifierFile );
    01677
    01678     virtual void read( const FileNode &fn );
    01679     virtual void write( FileStorage &fs ) const;
    01680
    01681     virtual int descriptorSize() const { return classifier_.classes(); }
    01682     virtual int descriptorType() const { return DataType<T>::type; }
    01683
    01684 protected:
    01685         virtual void computeImpl( const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors ) const;
    01686
    01687     RTreeClassifier classifier_;
    01688     static const int BORDER_SIZE = 16;
    01689 };
    01690
    01691 template<typename T>
    01692 CalonderDescriptorExtractor<T>::CalonderDescriptorExtractor(const std::string& classifier_file)
    01693 {
    01694     classifier_.read( classifier_file.c_str() );
    01695 }
    01696
    01697 template<typename T>
    01698 void CalonderDescriptorExtractor<T>::computeImpl( const cv::Mat& image,
    01699                                               std::vector<cv::KeyPoint>& keypoints,
    01700                                               cv::Mat& descriptors) const
    01701 {
    01702     // Cannot compute descriptors for keypoints on the image border.
    01703     removeBorderKeypoints(keypoints, image.size(), BORDER_SIZE);
    01704
    01706     descriptors.create(keypoints.size(), classifier_.classes(), cv::DataType<T>::type);
    01707
    01708     int patchSize = RandomizedTree::PATCH_SIZE;
    01709     int offset = patchSize / 2;
    01710     for (size_t i = 0; i < keypoints.size(); ++i)
    01711     {
    01712         cv::Point2f pt = keypoints[i].pt;
    01713         IplImage ipl = image( Rect((int)(pt.x - offset), (int)(pt.y - offset), patchSize, patchSize) );
    01714         classifier_.getSignature( &ipl, descriptors.ptr<T>(i));
    01715     }
    01716 }
    01717
    01718 template<typename T>
    01719 void CalonderDescriptorExtractor<T>::read( const FileNode& )
    01720 {}
    01721
    01722 template<typename T>
    01723 void CalonderDescriptorExtractor<T>::write( FileStorage& ) const
    01724 {}
    01725
    01726 /*
    01727  * OpponentColorDescriptorExtractor
    01728  *
    01729  * Adapts a descriptor extractor to compute descripors in Opponent Color Space
    01730  * (refer to van de Sande et al., CGIV 2008 "Color Descriptors for Object Category Recognition").
    01731  * Input RGB image is transformed in Opponent Color Space. Then unadapted descriptor extractor
    01732  * (set in constructor) computes descriptors on each of the three channel and concatenate
    01733  * them into a single color descriptor.
    01734  */
    01735 class CV_EXPORTS OpponentColorDescriptorExtractor : public DescriptorExtractor
    01736 {
    01737 public:
    01738     OpponentColorDescriptorExtractor( const Ptr<DescriptorExtractor>& descriptorExtractor );
    01739
    01740     virtual void read( const FileNode& );
    01741     virtual void write( FileStorage& ) const;
    01742
    01743     virtual int descriptorSize() const;
    01744     virtual int descriptorType() const;
    01745
    01746 protected:
    01747         virtual void computeImpl( const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors ) const;
    01748
    01749     Ptr<DescriptorExtractor> descriptorExtractor;
    01750 };
    01751
    01752 /*
    01753  * BRIEF Descriptor
    01754  */
    01755 class CV_EXPORTS BriefDescriptorExtractor : public DescriptorExtractor
    01756 {
    01757 public:
    01758     static const int PATCH_SIZE = 48;
    01759     static const int KERNEL_SIZE = 9;
    01760
    01761     // bytes is a length of descriptor in bytes. It can be equal 16, 32 or 64 bytes.
    01762     BriefDescriptorExtractor( int bytes = 32 );
    01763
    01764     virtual int descriptorSize() const;
    01765     virtual int descriptorType() const;
    01766
    01768
    01769 protected:
    01770         virtual void computeImpl(const Mat& image, std::vector<KeyPoint>& keypoints, Mat& descriptors) const;
    01771
    01772     typedef void(*PixelTestFn)(const Mat&, const std::vector<KeyPoint>&, Mat&);
    01773
    01774     int bytes_;
    01775     PixelTestFn test_fn_;
    01776 };
    01777
    01778 /****************************************************************************************\
    01779 *                                          Distance                                      *
    01780 \****************************************************************************************/
    01781 template<typename T>
    01782 struct CV_EXPORTS Accumulator
    01783 {
    01784     typedef T Type;
    01785 };
    01786
    01787 template<> struct Accumulator<unsigned char>  { typedef float Type; };
    01788 template<> struct Accumulator<unsigned short> { typedef float Type; };
    01789 template<> struct Accumulator<char>   { typedef float Type; };
    01790 template<> struct Accumulator<short>  { typedef float Type; };
    01791
    01792 /*
    01793  * Squared Euclidean distance functor
    01794  */
    01795 template<class T>
    01796 struct CV_EXPORTS L2
    01797 {
    01798     typedef T ValueType;
    01799     typedef typename Accumulator<T>::Type ResultType;
    01800
    01801     ResultType operator()( const T* a, const T* b, int size ) const
    01802     {
    01803         ResultType result = ResultType();
    01804         for( int i = 0; i < size; i++ )
    01805         {
    01806             ResultType diff = (ResultType)(a[i] - b[i]);
    01807             result += diff*diff;
    01808         }
    01809         return (ResultType)sqrt((double)result);
    01810     }
    01811 };
    01812
    01813 /*
    01814  * Manhattan distance (city block distance) functor
    01815  */
    01816 template<class T>
    01817 struct CV_EXPORTS L1
    01818 {
    01819     typedef T ValueType;
    01820     typedef typename Accumulator<T>::Type ResultType;
    01821
    01822     ResultType operator()( const T* a, const T* b, int size ) const
    01823     {
    01824         ResultType result = ResultType();
    01825         for( int i = 0; i < size; i++ )
    01826         {
    01827             ResultType diff = a[i] - b[i];
    01828             result += (ResultType)fabs( diff );
    01829         }
    01830         return result;
    01831     }
    01832 };
    01833
    01834 /*
    01835  * Hamming distance functor - counts the bit differences between two strings - useful for the Brief descriptor
    01836  * bit count of A exclusive XOR'ed with B
    01837  */
    01838 struct CV_EXPORTS HammingLUT
    01839 {
    01840     typedef unsigned char ValueType;
    01841     typedef int ResultType;
    01842
    01845     ResultType operator()( const unsigned char* a, const unsigned char* b, int size ) const;
    01846
    01852     static unsigned char byteBitsLookUp(unsigned char b);
    01853 };
    01854
    01855
    01859 struct CV_EXPORTS Hamming
    01860 {
    01861     typedef unsigned char ValueType;
    01862
    01864     // in BruteForce if not
    01865     typedef int ResultType;
    01866
    01869     ResultType operator()(const unsigned char* a, const unsigned char* b, int size) const;
    01870 };
    01871
    01872
    01873 /****************************************************************************************\
    01874 *                                      DMatch                                            *
    01875 \****************************************************************************************/
    01876 /*
    01877  * Struct for matching: query descriptor index, train descriptor index, train image index and distance between descriptors.
    01878  */
    01879 struct CV_EXPORTS DMatch
    01880 {
    01881     DMatch() : queryIdx(-1), trainIdx(-1), imgIdx(-1), distance(std::numeric_limits<float>::max()) {}
    01882     DMatch( int _queryIdx, int _trainIdx, float _distance ) :
    01883             queryIdx(_queryIdx), trainIdx(_trainIdx), imgIdx(-1), distance(_distance) {}
    01884     DMatch( int _queryIdx, int _trainIdx, int _imgIdx, float _distance ) :
    01885             queryIdx(_queryIdx), trainIdx(_trainIdx), imgIdx(_imgIdx), distance(_distance) {}
    01886
    01887     int queryIdx; // query descriptor index
    01888     int trainIdx; // train descriptor index
    01889     int imgIdx;   // train image index
    01890
    01891     float distance;
    01892
    01893     // less is better
    01894     bool operator<( const DMatch &m ) const
    01895     {
    01896         return distance < m.distance;
    01897     }
    01898 };
    01899
    01900 /****************************************************************************************\
    01901 *                                  DescriptorMatcher                                     *
    01902 \****************************************************************************************/
    01903 /*
    01904  * Abstract base class for matching two sets of descriptors.
    01905  */
    01906 class CV_EXPORTS DescriptorMatcher
    01907 {
    01908 public:
    01909     virtual ~DescriptorMatcher();
    01910
    01911         /*
    01912      * Add descriptors to train descriptor collection.
    01913      * descriptors      Descriptors to add. Each descriptors[i] is a descriptors set from one image.
    01914      */
    01915     virtual void add( const vector<Mat>& descriptors );
    01916     /*
    01917      * Get train descriptors collection.
    01918      */
    01919     const vector<Mat>& getTrainDescriptors() const;
    01920     /*
    01921      * Clear train descriptors collection.
    01922      */
    01923     virtual void clear();
    01924
    01925     /*
    01926      * Return true if there are not train descriptors in collection.
    01927      */
    01928         bool empty() const;
    01929     /*
    01930      * Return true if the matcher supports mask in match methods.
    01931      */
    01932     virtual bool isMaskSupported() const = 0;
    01933
    01934     /*
    01935      * Train matcher (e.g. train flann index).
    01936      * In all methods to match the method train() is run every time before matching.
    01937      * Some descriptor matchers (e.g. BruteForceMatcher) have empty implementation
    01938      * of this method, other matchers realy train their inner structures
    01939      * (e.g. FlannBasedMatcher trains flann::Index). So nonempty implementation
    01940      * of train() should check the class object state and do traing/retraining
    01941      * only if the state requires that (e.g. FlannBasedMatcher trains flann::Index
    01942      * if it has not trained yet or if new descriptors have been added to the train
    01943      * collection).
    01944      */
    01945     virtual void train();
    01946     /*
    01947      * Group of methods to match descriptors from image pair.
    01948      * Method train() is run in this methods.
    01949      */
    01950     // Find one best match for each query descriptor (if mask is empty).
    01951     void match( const Mat& queryDescriptors, const Mat& trainDescriptors,
    01952                 vector<DMatch>& matches, const Mat& mask=Mat() ) const;
    01953     // Find k best matches for each query descriptor (in increasing order of distances).
    01954     // compactResult is used when mask is not empty. If compactResult is false matches
    01955     // vector will have the same size as queryDescriptors rows. If compactResult is true
    01956     // matches vector will not contain matches for fully masked out query descriptors.
    01957     void knnMatch( const Mat& queryDescriptors, const Mat& trainDescriptors,
    01958                    vector<vector<DMatch> >& matches, int k,
    01959                    const Mat& mask=Mat(), bool compactResult=false ) const;
    01960     // Find best matches for each query descriptor which have distance less than
    01961     // maxDistance (in increasing order of distances).
    01962     void radiusMatch( const Mat& queryDescriptors, const Mat& trainDescriptors,
    01963                       vector<vector<DMatch> >& matches, float maxDistance,
    01964                       const Mat& mask=Mat(), bool compactResult=false ) const;
    01965     /*
    01966      * Group of methods to match descriptors from one image to image set.
    01967      * See description of similar methods for matching image pair above.
    01968      */
    01969     void match( const Mat& queryDescriptors, vector<DMatch>& matches,
    01970                 const vector<Mat>& masks=vector<Mat>() );
    01971     void knnMatch( const Mat& queryDescriptors, vector<vector<DMatch> >& matches, int k,
    01972            const vector<Mat>& masks=vector<Mat>(), bool compactResult=false );
    01973     void radiusMatch( const Mat& queryDescriptors, vector<vector<DMatch> >& matches, float maxDistance,
    01974                    const vector<Mat>& masks=vector<Mat>(), bool compactResult=false );
    01975
    01976     // Reads matcher object from a file node
    01977     virtual void read( const FileNode& );
    01978     // Writes matcher object to a file storage
    01979     virtual void write( FileStorage& ) const;
    01980
    01981     // Clone the matcher. If emptyTrainData is false the method create deep copy of the object, i.e. copies
    01982     // both parameters and train data. If emptyTrainData is true the method create object copy with current parameters
    01983     // but with empty train data.
    01984     virtual Ptr<DescriptorMatcher> clone( bool emptyTrainData=false ) const = 0;
    01985
    01986     static Ptr<DescriptorMatcher> create( const string& descriptorMatcherType );
    01987 protected:
    01988     /*
    01989      * Class to work with descriptors from several images as with one merged matrix.
    01990      * It is used e.g. in FlannBasedMatcher.
    01991      */
    01992     class CV_EXPORTS DescriptorCollection
    01993     {
    01994     public:
    01995         DescriptorCollection();
    01996         DescriptorCollection( const DescriptorCollection& collection );
    01997         virtual ~DescriptorCollection();
    01998
    01999         // Vector of matrices "descriptors" will be merged to one matrix "mergedDescriptors" here.
    02000         void set( const vector<Mat>& descriptors );
    02001         virtual void clear();
    02002
    02003         const Mat& getDescriptors() const;
    02004         const Mat getDescriptor( int imgIdx, int localDescIdx ) const;
    02005         const Mat getDescriptor( int globalDescIdx ) const;
    02006         void getLocalIdx( int globalDescIdx, int& imgIdx, int& localDescIdx ) const;
    02007
    02008         int size() const;
    02009
    02010     protected:
    02011         Mat mergedDescriptors;
    02012         vector<int> startIdxs;
    02013     };
    02014
    02015     // In fact the matching is implemented only by the following two methods. These methods suppose
    02016     // that the class object has been trained already. Public match methods call these methods
    02017     // after calling train().
    02018     virtual void knnMatchImpl( const Mat& queryDescriptors, vector<vector<DMatch> >& matches, int k,
    02019            const vector<Mat>& masks=vector<Mat>(), bool compactResult=false ) = 0;
    02020     virtual void radiusMatchImpl( const Mat& queryDescriptors, vector<vector<DMatch> >& matches, float maxDistance,
    02021            const vector<Mat>& masks=vector<Mat>(), bool compactResult=false ) = 0;
    02022
    02023     static bool isPossibleMatch( const Mat& mask, int queryIdx, int trainIdx );
    02024     static bool isMaskedOut( const vector<Mat>& masks, int queryIdx );
    02025
    02026     static Mat clone_op( Mat m ) { return m.clone(); }
    02027         void checkMasks( const vector<Mat>& masks, int queryDescriptorsCount ) const;
    02028
    02029     // Collection of descriptors from train images.
    02030     vector<Mat> trainDescCollection;
    02031 };
    02032
    02033 /*
    02034  * Brute-force descriptor matcher.
    02035  *
    02036  * For each descriptor in the first set, this matcher finds the closest
    02037  * descriptor in the second set by trying each one.
    02038  *
    02039  * For efficiency, BruteForceMatcher is templated on the distance metric.
    02040  * For float descriptors, a common choice would be cv::L2<float>.
    02041  */
    02042 template<class Distance>
    02043 class CV_EXPORTS BruteForceMatcher : public DescriptorMatcher
    02044 {
    02045 public:
    02046     BruteForceMatcher( Distance d = Distance() ) : distance(d) {}
    02047     virtual ~BruteForceMatcher() {}
    02048
    02049     virtual bool isMaskSupported() const { return true; }
    02050
    02051     virtual Ptr<DescriptorMatcher> clone( bool emptyTrainData=false ) const;
    02052
    02053 protected:
    02054     virtual void knnMatchImpl( const Mat& queryDescriptors, vector<vector<DMatch> >& matches, int k,
    02055            const vector<Mat>& masks=vector<Mat>(), bool compactResult=false );
    02056     virtual void radiusMatchImpl( const Mat& queryDescriptors, vector<vector<DMatch> >& matches, float maxDistance,
    02057            const vector<Mat>& masks=vector<Mat>(), bool compactResult=false );
    02058
    02059     Distance distance;
    02060
    02061 private:
    02062     /*
    02063      * Next two methods are used to implement specialization.
    02064      */
    02065     static void commonKnnMatchImpl( BruteForceMatcher<Distance>& matcher,
    02066                     const Mat& queryDescriptors, vector<vector<DMatch> >& matches, int k,
    02067                     const vector<Mat>& masks, bool compactResult );
    02068     static void commonRadiusMatchImpl( BruteForceMatcher<Distance>& matcher,
    02069                     const Mat& queryDescriptors, vector<vector<DMatch> >& matches, float maxDistance,
    02070                     const vector<Mat>& masks, bool compactResult );
    02071 };
    02072
    02073 template<class Distance>
    02074 Ptr<DescriptorMatcher> BruteForceMatcher<Distance>::clone( bool emptyTrainData ) const
    02075 {
    02076     BruteForceMatcher* matcher = new BruteForceMatcher(distance);
    02077     if( !emptyTrainData )
    02078     {
    02079         transform( trainDescCollection.begin(), trainDescCollection.end(),
    02080                    matcher->trainDescCollection.begin(), clone_op );
    02081     }
    02082     return matcher;
    02083 }
    02084
    02085 template<class Distance>
    02086 void BruteForceMatcher<Distance>::knnMatchImpl( const Mat& queryDescriptors, vector<vector<DMatch> >& matches, int k,
    02087                                                 const vector<Mat>& masks, bool compactResult )
    02088 {
    02089     commonKnnMatchImpl( *this, queryDescriptors, matches, k, masks, compactResult );
    02090 }
    02091
    02092 template<class Distance>
    02093 void BruteForceMatcher<Distance>::radiusMatchImpl( const Mat& queryDescriptors, vector<vector<DMatch> >& matches,
    02094                                                    float maxDistance, const vector<Mat>& masks, bool compactResult )
    02095 {
    02096     commonRadiusMatchImpl( *this, queryDescriptors, matches, maxDistance, masks, compactResult );
    02097 }
    02098
    02099 template<class Distance>
    02100 inline void BruteForceMatcher<Distance>::commonKnnMatchImpl( BruteForceMatcher<Distance>& matcher,
    02101                           const Mat& queryDescriptors, vector<vector<DMatch> >& matches, int knn,
    02102                           const vector<Mat>& masks, bool compactResult )
    02103  {
    02104      typedef typename Distance::ValueType ValueType;
    02105      typedef typename Distance::ResultType DistanceType;
    02106          CV_DbgAssert( !queryDescriptors.empty() );
    02107      CV_Assert( DataType<ValueType>::type == queryDescriptors.type() );
    02108
    02109      int dimension = queryDescriptors.cols;
    02110      matches.reserve(queryDescriptors.rows);
    02111
    02112      size_t imgCount = matcher.trainDescCollection.size();
    02113      vector<Mat> allDists( imgCount ); // distances between one query descriptor and all train descriptors
    02114      for( size_t i = 0; i < imgCount; i++ )
    02115         allDists[i] = Mat( 1, matcher.trainDescCollection[i].rows, DataType<DistanceType>::type );
    02116
    02117      for( int qIdx = 0; qIdx < queryDescriptors.rows; qIdx++ )
    02118      {
    02119          if( matcher.isMaskedOut( masks, qIdx ) )
    02120          {
    02121              if( !compactResult ) // push empty vector
    02122                  matches.push_back( vector<DMatch>() );
    02123          }
    02124          else
    02125          {
    02126              // 1. compute distances between i-th query descriptor and all train descriptors
    02127              for( size_t iIdx = 0; iIdx < imgCount; iIdx++ )
    02128              {
    02129                  CV_Assert( DataType<ValueType>::type == matcher.trainDescCollection[iIdx].type() ||  matcher.trainDescCollection[iIdx].empty() );
    02130                                  CV_Assert( queryDescriptors.cols == matcher.trainDescCollection[iIdx].cols ||
    02131                                             matcher.trainDescCollection[iIdx].empty() );
    02132
    02133                  const ValueType* d1 = (const ValueType*)(queryDescriptors.data + queryDescriptors.step*qIdx);
    02134                  allDists[iIdx].setTo( Scalar::all(std::numeric_limits<DistanceType>::max()) );
    02135                  for( int tIdx = 0; tIdx < matcher.trainDescCollection[iIdx].rows; tIdx++ )
    02136                  {
    02137                      if( masks.empty() || matcher.isPossibleMatch(masks[iIdx], qIdx, tIdx) )
    02138                      {
    02139                          const ValueType* d2 = (const ValueType*)(matcher.trainDescCollection[iIdx].data +
    02140                                                                   matcher.trainDescCollection[iIdx].step*tIdx);
    02141                          allDists[iIdx].at<DistanceType>(0, tIdx) = matcher.distance(d1, d2, dimension);
    02142                      }
    02143                  }
    02144              }
    02145
    02146              // 2. choose k nearest matches for query[i]
    02147              matches.push_back( vector<DMatch>() );
    02148              vector<vector<DMatch> >::reverse_iterator curMatches = matches.rbegin();
    02149              for( int k = 0; k < knn; k++ )
    02150              {
    02151                  DMatch bestMatch;
    02152                  bestMatch.distance = std::numeric_limits<float>::max();
    02153                  for( size_t iIdx = 0; iIdx < imgCount; iIdx++ )
    02154                  {
    02155                                          if( !allDists[iIdx].empty() )
    02156                                          {
    02157                                                  double minVal;
    02158                                                  Point minLoc;
    02159                                                  minMaxLoc( allDists[iIdx], &minVal, 0, &minLoc, 0 );
    02160                                                  if( minVal < bestMatch.distance )
    02161                                                          bestMatch = DMatch( qIdx, minLoc.x, (int)iIdx, (float)minVal );
    02162                                          }
    02163                  }
    02164                  if( bestMatch.trainIdx == -1 )
    02165                      break;
    02166
    02167                  allDists[bestMatch.imgIdx].at<DistanceType>(0, bestMatch.trainIdx) = std::numeric_limits<DistanceType>::max();
    02168                  curMatches->push_back( bestMatch );
    02169              }
    02170              //TODO should already be sorted at this point?
    02171              std::sort( curMatches->begin(), curMatches->end() );
    02172          }
    02173      }
    02174 }
    02175
    02176 template<class Distance>
    02177 inline void BruteForceMatcher<Distance>::commonRadiusMatchImpl( BruteForceMatcher<Distance>& matcher,
    02178                              const Mat& queryDescriptors, vector<vector<DMatch> >& matches, float maxDistance,
    02179                              const vector<Mat>& masks, bool compactResult )
    02180 {
    02181     typedef typename Distance::ValueType ValueType;
    02182     typedef typename Distance::ResultType DistanceType;
    02183         CV_DbgAssert( !queryDescriptors.empty() );
    02184     CV_Assert( DataType<ValueType>::type == queryDescriptors.type() );
    02185
    02186     int dimension = queryDescriptors.cols;
    02187     matches.reserve(queryDescriptors.rows);
    02188
    02189     size_t imgCount = matcher.trainDescCollection.size();
    02190     for( int qIdx = 0; qIdx < queryDescriptors.rows; qIdx++ )
    02191     {
    02192         if( matcher.isMaskedOut( masks, qIdx ) )
    02193         {
    02194             if( !compactResult ) // push empty vector
    02195                 matches.push_back( vector<DMatch>() );
    02196         }
    02197         else
    02198         {
    02199             matches.push_back( vector<DMatch>() );
    02200             vector<vector<DMatch> >::reverse_iterator curMatches = matches.rbegin();
    02201             for( size_t iIdx = 0; iIdx < imgCount; iIdx++ )
    02202             {
    02203                 CV_Assert( DataType<ValueType>::type == matcher.trainDescCollection[iIdx].type() ||
    02204                            matcher.trainDescCollection[iIdx].empty() );
    02205                 CV_Assert( queryDescriptors.cols == matcher.trainDescCollection[iIdx].cols ||
    02206                                                    matcher.trainDescCollection[iIdx].empty() );
    02207
    02208                 const ValueType* d1 = (const ValueType*)(queryDescriptors.data + queryDescriptors.step*qIdx);
    02209                 for( int tIdx = 0; tIdx < matcher.trainDescCollection[iIdx].rows; tIdx++ )
    02210                 {
    02211                     if( masks.empty() || matcher.isPossibleMatch(masks[iIdx], qIdx, tIdx) )
    02212                     {
    02213                         const ValueType* d2 = (const ValueType*)(matcher.trainDescCollection[iIdx].data +
    02214                                                                  matcher.trainDescCollection[iIdx].step*tIdx);
    02215                         DistanceType d = matcher.distance(d1, d2, dimension);
    02216                         if( d < maxDistance )
    02217                             curMatches->push_back( DMatch( qIdx, tIdx, (int)iIdx, (float)d ) );
    02218                     }
    02219                 }
    02220             }
    02221             std::sort( curMatches->begin(), curMatches->end() );
    02222         }
    02223     }
    02224 }
    02225
    02226 /*
    02227  * BruteForceMatcher L2 specialization
    02228  */
    02229 template<>
    02230 void BruteForceMatcher<L2<float> >::knnMatchImpl( const Mat& queryDescriptors, vector<vector<DMatch> >& matches, int k,
    02231                                                   const vector<Mat>& masks, bool compactResult );
    02232 template<>
    02233 void BruteForceMatcher<L2<float> >::radiusMatchImpl( const Mat& queryDescriptors, vector<vector<DMatch> >& matches,
    02234                                                      float maxDistance, const vector<Mat>& masks, bool compactResult );
    02235
    02236 /*
    02237  * Flann based matcher
    02238  */
    02239 class CV_EXPORTS FlannBasedMatcher : public DescriptorMatcher
    02240 {
    02241 public:
    02242     FlannBasedMatcher( const Ptr<flann::IndexParams>& indexParams=new flann::KDTreeIndexParams(),
    02243                        const Ptr<flann::SearchParams>& searchParams=new flann::SearchParams() );
    02244
    02245     virtual void add( const vector<Mat>& descriptors );
    02246     virtual void clear();
    02247
    02248     virtual void train();
    02249     virtual bool isMaskSupported() const;
    02250
    02251     virtual Ptr<DescriptorMatcher> clone( bool emptyTrainData=false ) const;
    02252
    02253 protected:
    02254     static void convertToDMatches( const DescriptorCollection& descriptors,
    02255                                    const Mat& indices, const Mat& distances,
    02256                                    vector<vector<DMatch> >& matches );
    02257
    02258     virtual void knnMatchImpl( const Mat& queryDescriptors, vector<vector<DMatch> >& matches, int k,
    02259                    const vector<Mat>& masks=vector<Mat>(), bool compactResult=false );
    02260     virtual void radiusMatchImpl( const Mat& queryDescriptors, vector<vector<DMatch> >& matches, float maxDistance,
    02261                    const vector<Mat>& masks=vector<Mat>(), bool compactResult=false );
    02262
    02263     Ptr<flann::IndexParams> indexParams;
    02264     Ptr<flann::SearchParams> searchParams;
    02265     Ptr<flann::Index> flannIndex;
    02266
    02267     DescriptorCollection mergedDescriptors;
    02268     int addedDescCount;
    02269 };
    02270
    02271 /****************************************************************************************\
    02272 *                                GenericDescriptorMatcher                                *
    02273 \****************************************************************************************/
    02274 /*
    02275  *   Abstract interface for a keypoint descriptor and matcher
    02276  */
    02277 class GenericDescriptorMatcher;
    02278 typedef GenericDescriptorMatcher GenericDescriptorMatch;
    02279
    02280 class CV_EXPORTS GenericDescriptorMatcher
    02281 {
    02282 public:
    02283     GenericDescriptorMatcher();
    02284     virtual ~GenericDescriptorMatcher();
    02285
    02286     /*
    02287      * Add train collection: images and keypoints from them.
    02288      * images       A set of train images.
    02289      * ketpoints    Keypoint collection that have been detected on train images.
    02290      *
    02291      * Keypoints for which a descriptor cannot be computed are removed. Such keypoints
    02292      * must be filtered in this method befor adding keypoints to train collection "trainPointCollection".
    02293      * If inheritor class need perform such prefiltering the method add() must be overloaded.
    02294      * In the other class methods programmer has access to the train keypoints by a constant link.
    02295      */
    02296     virtual void add( const vector<Mat>& images,
    02297                       vector<vector<KeyPoint> >& keypoints );
    02298
    02299     const vector<Mat>& getTrainImages() const;
    02300     const vector<vector<KeyPoint> >& getTrainKeypoints() const;
    02301
    02302     /*
    02303      * Clear images and keypoints storing in train collection.
    02304      */
    02305     virtual void clear();
    02306     /*
    02307      * Returns true if matcher supports mask to match descriptors.
    02308      */
    02309     virtual bool isMaskSupported() = 0;
    02310     /*
    02311      * Train some inner structures (e.g. flann index or decision trees).
    02312      * train() methods is run every time in matching methods. So the method implementation
    02313      * should has a check whether these inner structures need be trained/retrained or not.
    02314      */
    02315     virtual void train();
    02316
    02317     /*
    02318      * Classifies query keypoints.
    02319      * queryImage    The query image
    02320      * queryKeypoints   Keypoints from the query image
    02321      * trainImage    The train image
    02322      * trainKeypoints   Keypoints from the train image
    02323      */
    02324     // Classify keypoints from query image under one train image.
    02325     void classify( const Mat& queryImage, vector<KeyPoint>& queryKeypoints,
    02326                            const Mat& trainImage, vector<KeyPoint>& trainKeypoints ) const;
    02327     // Classify keypoints from query image under train image collection.
    02328     void classify( const Mat& queryImage, vector<KeyPoint>& queryKeypoints );
    02329
    02330     /*
    02331      * Group of methods to match keypoints from image pair.
    02332      * Keypoints for which a descriptor cannot be computed are removed.
    02333      * train() method is called here.
    02334      */
    02335     // Find one best match for each query descriptor (if mask is empty).
    02336     void match( const Mat& queryImage, vector<KeyPoint>& queryKeypoints,
    02337                 const Mat& trainImage, vector<KeyPoint>& trainKeypoints,
    02338                 vector<DMatch>& matches, const Mat& mask=Mat() ) const;
    02339     // Find k best matches for each query keypoint (in increasing order of distances).
    02340     // compactResult is used when mask is not empty. If compactResult is false matches
    02341     // vector will have the same size as queryDescriptors rows.
    02342     // If compactResult is true matches vector will not contain matches for fully masked out query descriptors.
    02343     void knnMatch( const Mat& queryImage, vector<KeyPoint>& queryKeypoints,
    02344                    const Mat& trainImage, vector<KeyPoint>& trainKeypoints,
    02345                    vector<vector<DMatch> >& matches, int k,
    02346                    const Mat& mask=Mat(), bool compactResult=false ) const;
    02347     // Find best matches for each query descriptor which have distance less than maxDistance (in increasing order of distances).
    02348     void radiusMatch( const Mat& queryImage, vector<KeyPoint>& queryKeypoints,
    02349                       const Mat& trainImage, vector<KeyPoint>& trainKeypoints,
    02350                       vector<vector<DMatch> >& matches, float maxDistance,
    02351                       const Mat& mask=Mat(), bool compactResult=false ) const;
    02352     /*
    02353      * Group of methods to match keypoints from one image to image set.
    02354      * See description of similar methods for matching image pair above.
    02355      */
    02356     void match( const Mat& queryImage, vector<KeyPoint>& queryKeypoints,
    02357                 vector<DMatch>& matches, const vector<Mat>& masks=vector<Mat>() );
    02358     void knnMatch( const Mat& queryImage, vector<KeyPoint>& queryKeypoints,
    02359                    vector<vector<DMatch> >& matches, int k,
    02360                    const vector<Mat>& masks=vector<Mat>(), bool compactResult=false );
    02361     void radiusMatch( const Mat& queryImage, vector<KeyPoint>& queryKeypoints,
    02362                       vector<vector<DMatch> >& matches, float maxDistance,
    02363                       const vector<Mat>& masks=vector<Mat>(), bool compactResult=false );
    02364
    02365     // Reads matcher object from a file node
    02366     virtual void read( const FileNode& );
    02367     // Writes matcher object to a file storage
    02368     virtual void write( FileStorage& ) const;
    02369
    02370     // Clone the matcher. If emptyTrainData is false the method create deep copy of the object, i.e. copies
    02371     // both parameters and train data. If emptyTrainData is true the method create object copy with current parameters
    02372     // but with empty train data.
    02373     virtual Ptr<GenericDescriptorMatcher> clone( bool emptyTrainData=false ) const = 0;
    02374
    02375     static Ptr<GenericDescriptorMatcher> create( const string& genericDescritptorMatcherType,
    02376                                                  const string &paramsFilename=string() );
    02377
    02378 protected:
    02379     // In fact the matching is implemented only by the following two methods. These methods suppose
    02380     // that the class object has been trained already. Public match methods call these methods
    02381     // after calling train().
    02382     virtual void knnMatchImpl( const Mat& queryImage, vector<KeyPoint>& queryKeypoints,
    02383                                vector<vector<DMatch> >& matches, int k,
    02384                                const vector<Mat>& masks, bool compactResult ) = 0;
    02385     virtual void radiusMatchImpl( const Mat& queryImage, vector<KeyPoint>& queryKeypoints,
    02386                                   vector<vector<DMatch> >& matches, float maxDistance,
    02387                                   const vector<Mat>& masks, bool compactResult ) = 0;
    02388     /*
    02389      * A storage for sets of keypoints together with corresponding images and class IDs
    02390      */
    02391     class CV_EXPORTS KeyPointCollection
    02392     {
    02393     public:
    02394         KeyPointCollection();
    02395         KeyPointCollection( const KeyPointCollection& collection );
    02396         void add( const vector<Mat>& images, const vector<vector<KeyPoint> >& keypoints );
    02397         void clear();
    02398
    02399         // Returns the total number of keypoints in the collection
    02400         size_t keypointCount() const;
    02401         size_t imageCount() const;
    02402
    02403         const vector<vector<KeyPoint> >& getKeypoints() const;
    02404         const vector<KeyPoint>& getKeypoints( int imgIdx ) const;
    02405         const KeyPoint& getKeyPoint( int imgIdx, int localPointIdx ) const;
    02406         const KeyPoint& getKeyPoint( int globalPointIdx ) const;
    02407         void getLocalIdx( int globalPointIdx, int& imgIdx, int& localPointIdx ) const;
    02408
    02409         const vector<Mat>& getImages() const;
    02410         const Mat& getImage( int imgIdx ) const;
    02411
    02412     protected:
    02413         int pointCount;
    02414
    02415         vector<Mat> images;
    02416         vector<vector<KeyPoint> > keypoints;
    02417         // global indices of the first points in each image, startIndices.size() = keypoints.size()
    02418         vector<int> startIndices;
    02419
    02420     private:
    02421         static Mat clone_op( Mat m ) { return m.clone(); }
    02422     };
    02423
    02424     KeyPointCollection trainPointCollection;
    02425 };
    02426
    02427 /*
    02428  *  OneWayDescriptorMatcher
    02429  */
    02430 class OneWayDescriptorMatcher;
    02431 typedef OneWayDescriptorMatcher OneWayDescriptorMatch;
    02432
    02433 class CV_EXPORTS OneWayDescriptorMatcher : public GenericDescriptorMatcher
    02434 {
    02435 public:
    02436     class CV_EXPORTS Params
    02437     {
    02438     public:
    02439         static const int POSE_COUNT = 500;
    02440         static const int PATCH_WIDTH = 24;
    02441         static const int PATCH_HEIGHT = 24;
    02442         static float GET_MIN_SCALE() { return 0.7f; }
    02443         static float GET_MAX_SCALE() { return 1.5f; }
    02444         static float GET_STEP_SCALE() { return 1.2f; }
    02445
    02446         Params( int poseCount = POSE_COUNT,
    02447                 Size patchSize = Size(PATCH_WIDTH, PATCH_HEIGHT),
    02448                 string pcaFilename = string(),
    02449                 string trainPath = string(), string trainImagesList = string(),
    02450                 float minScale = GET_MIN_SCALE(), float maxScale = GET_MAX_SCALE(),
    02451                 float stepScale = GET_STEP_SCALE() );
    02452
    02453         int poseCount;
    02454         Size patchSize;
    02455         string pcaFilename;
    02456         string trainPath;
    02457         string trainImagesList;
    02458
    02459         float minScale, maxScale, stepScale;
    02460     };
    02461
    02462     OneWayDescriptorMatcher( const Params& params=Params() );
    02463     virtual ~OneWayDescriptorMatcher();
    02464
    02465     void initialize( const Params& params, const Ptr<OneWayDescriptorBase>& base=Ptr<OneWayDescriptorBase>() );
    02466
    02467     // Clears keypoints storing in collection and OneWayDescriptorBase
    02468     virtual void clear();
    02469
    02470     virtual void train();
    02471
    02472     virtual bool isMaskSupported();
    02473
    02474     virtual void read( const FileNode &fn );
    02475     virtual void write( FileStorage& fs ) const;
    02476
    02477     virtual Ptr<GenericDescriptorMatcher> clone( bool emptyTrainData=false ) const;
    02478
    02479 protected:
    02480     // Matches a set of keypoints from a single image of the training set. A rectangle with a center in a keypoint
    02481     // and size (patch_width/2*scale, patch_height/2*scale) is cropped from the source image for each
    02482     // keypoint. scale is iterated from DescriptorOneWayParams::min_scale to DescriptorOneWayParams::max_scale.
    02483     // The minimum distance to each training patch with all its affine poses is found over all scales.
    02484     // The class ID of a match is returned for each keypoint. The distance is calculated over PCA components
    02485     // loaded with DescriptorOneWay::Initialize, kd tree is used for finding minimum distances.
    02486     virtual void knnMatchImpl( const Mat& queryImage, vector<KeyPoint>& queryKeypoints,
    02487                                vector<vector<DMatch> >& matches, int k,
    02488                                const vector<Mat>& masks, bool compactResult );
    02489     virtual void radiusMatchImpl( const Mat& queryImage, vector<KeyPoint>& queryKeypoints,
    02490                                   vector<vector<DMatch> >& matches, float maxDistance,
    02491                                   const vector<Mat>& masks, bool compactResult );
    02492
    02493     Ptr<OneWayDescriptorBase> base;
    02494     Params params;
    02495     int prevTrainCount;
    02496 };
    02497
    02498 /*
    02499  *  FernDescriptorMatcher
    02500  */
    02501 class FernDescriptorMatcher;
    02502 typedef FernDescriptorMatcher FernDescriptorMatch;
    02503
    02504 class CV_EXPORTS FernDescriptorMatcher : public GenericDescriptorMatcher
    02505 {
    02506 public:
    02507     class CV_EXPORTS Params
    02508     {
    02509     public:
    02510         Params( int nclasses=0,
    02511                 int patchSize=FernClassifier::PATCH_SIZE,
    02512                 int signatureSize=FernClassifier::DEFAULT_SIGNATURE_SIZE,
    02513                 int nstructs=FernClassifier::DEFAULT_STRUCTS,
    02514                 int structSize=FernClassifier::DEFAULT_STRUCT_SIZE,
    02515                 int nviews=FernClassifier::DEFAULT_VIEWS,
    02516                 int compressionMethod=FernClassifier::COMPRESSION_NONE,
    02517                 const PatchGenerator& patchGenerator=PatchGenerator() );
    02518
    02519         Params( const string& filename );
    02520
    02521         int nclasses;
    02522         int patchSize;
    02523         int signatureSize;
    02524         int nstructs;
    02525         int structSize;
    02526         int nviews;
    02527         int compressionMethod;
    02528         PatchGenerator patchGenerator;
    02529
    02530         string filename;
    02531     };
    02532
    02533     FernDescriptorMatcher( const Params& params=Params() );
    02534     virtual ~FernDescriptorMatcher();
    02535
    02536     virtual void clear();
    02537
    02538     virtual void train();
    02539
    02540     virtual bool isMaskSupported();
    02541
    02542     virtual void read( const FileNode &fn );
    02543     virtual void write( FileStorage& fs ) const;
    02544
    02545     virtual Ptr<GenericDescriptorMatcher> clone( bool emptyTrainData=false ) const;
    02546
    02547 protected:
    02548     virtual void knnMatchImpl( const Mat& queryImage, vector<KeyPoint>& queryKeypoints,
    02549                                vector<vector<DMatch> >& matches, int k,
    02550                                const vector<Mat>& masks, bool compactResult );
    02551     virtual void radiusMatchImpl( const Mat& queryImage, vector<KeyPoint>& queryKeypoints,
    02552                                   vector<vector<DMatch> >& matches, float maxDistance,
    02553                                   const vector<Mat>& masks, bool compactResult );
    02554
    02555     void trainFernClassifier();
    02556     void calcBestProbAndMatchIdx( const Mat& image, const Point2f& pt,
    02557                                   float& bestProb, int& bestMatchIdx, vector<float>& signature );
    02558     Ptr<FernClassifier> classifier;
    02559     Params params;
    02560     int prevTrainCount;
    02561 };
    02562
    02563 /****************************************************************************************\
    02564 *                                VectorDescriptorMatcher                                 *
    02565 \****************************************************************************************/
    02566
    02567 /*
    02568  *  A class used for matching descriptors that can be described as vectors in a finite-dimensional space
    02569  */
    02570 class VectorDescriptorMatcher;
    02571 typedef VectorDescriptorMatcher VectorDescriptorMatch;
    02572
    02573 class CV_EXPORTS VectorDescriptorMatcher : public GenericDescriptorMatcher
    02574 {
    02575 public:
    02576     VectorDescriptorMatcher( const Ptr<DescriptorExtractor>& extractor, const Ptr<DescriptorMatcher>& matcher );
    02577     virtual ~VectorDescriptorMatcher();
    02578
    02579     virtual void add( const vector<Mat>& imgCollection,
    02580                       vector<vector<KeyPoint> >& pointCollection );
    02581
    02582     virtual void clear();
    02583
    02584     virtual void train();
    02585
    02586     virtual bool isMaskSupported();
    02587
    02588     virtual void read( const FileNode& fn );
    02589     virtual void write( FileStorage& fs ) const;
    02590
    02591     virtual Ptr<GenericDescriptorMatcher> clone( bool emptyTrainData=false ) const;
    02592
    02593 protected:
    02594     virtual void knnMatchImpl( const Mat& queryImage, vector<KeyPoint>& queryKeypoints,
    02595                                vector<vector<DMatch> >& matches, int k,
    02596                                const vector<Mat>& masks, bool compactResult );
    02597     virtual void radiusMatchImpl( const Mat& queryImage, vector<KeyPoint>& queryKeypoints,
    02598                                   vector<vector<DMatch> >& matches, float maxDistance,
    02599                                   const vector<Mat>& masks, bool compactResult );
    02600
    02601     Ptr<DescriptorExtractor> extractor;
    02602     Ptr<DescriptorMatcher> matcher;
    02603 };
    02604
    02605 /****************************************************************************************\
    02606 *                                   Drawing functions                                    *
    02607 \****************************************************************************************/
    02608 struct CV_EXPORTS DrawMatchesFlags
    02609 {
    02610     enum{ DEFAULT = 0, // Output image matrix will be created (Mat::create),
    02611                        // i.e. existing memory of output image may be reused.
    02612                        // Two source image, matches and single keypoints will be drawn.
    02613                        // For each keypoint only the center point will be drawn (without
    02614                        // the circle around keypoint with keypoint size and orientation).
    02615           DRAW_OVER_OUTIMG = 1, // Output image matrix will not be created (Mat::create).
    02616                                 // Matches will be drawn on existing content of output image.
    02617           NOT_DRAW_SINGLE_POINTS = 2, // Single keypoints will not be drawn.
    02618           DRAW_RICH_KEYPOINTS = 4 // For each keypoint the circle around keypoint with keypoint size and
    02619                                   // orientation will be drawn.
    02620         };
    02621 };
    02622
    02623 // Draw keypoints.
    02624 CV_EXPORTS void drawKeypoints( const Mat& image, const vector<KeyPoint>& keypoints, Mat& outImg,
    02625                                const Scalar& color=Scalar::all(-1), int flags=DrawMatchesFlags::DEFAULT );
    02626
    02627 // Draws matches of keypints from two images on output image.
    02628 CV_EXPORTS void drawMatches( const Mat& img1, const vector<KeyPoint>& keypoints1,
    02629                              const Mat& img2, const vector<KeyPoint>& keypoints2,
    02630                              const vector<DMatch>& matches1to2, Mat& outImg,
    02631                              const Scalar& matchColor=Scalar::all(-1), const Scalar& singlePointColor=Scalar::all(-1),
    02632                              const vector<char>& matchesMask=vector<char>(), int flags=DrawMatchesFlags::DEFAULT );
    02633
    02634 CV_EXPORTS void drawMatches( const Mat& img1, const vector<KeyPoint>& keypoints1,
    02635                              const Mat& img2, const vector<KeyPoint>& keypoints2,
    02636                              const vector<vector<DMatch> >& matches1to2, Mat& outImg,
    02637                              const Scalar& matchColor=Scalar::all(-1), const Scalar& singlePointColor=Scalar::all(-1),
    02638                              const vector<vector<char> >& matchesMask=vector<vector<char> >(), int flags=DrawMatchesFlags::DEFAULT );
    02639
    02640 /****************************************************************************************\
    02641 *   Functions to evaluate the feature detectors and [generic] descriptor extractors      *
    02642 \****************************************************************************************/
    02643
    02644 CV_EXPORTS void evaluateFeatureDetector( const Mat& img1, const Mat& img2, const Mat& H1to2,
    02645                                          vector<KeyPoint>* keypoints1, vector<KeyPoint>* keypoints2,
    02646                                          float& repeatability, int& correspCount,
    02647                                          const Ptr<FeatureDetector>& fdetector=Ptr<FeatureDetector>() );
    02648
    02649 CV_EXPORTS void computeRecallPrecisionCurve( const vector<vector<DMatch> >& matches1to2,
    02650                                              const vector<vector<uchar> >& correctMatches1to2Mask,
    02651                                              vector<Point2f>& recallPrecisionCurve );
    02652 CV_EXPORTS float getRecall( const vector<Point2f>& recallPrecisionCurve, float l_precision );
    02653
    02654 CV_EXPORTS void evaluateGenericDescriptorMatcher( const Mat& img1, const Mat& img2, const Mat& H1to2,
    02655                                                   vector<KeyPoint>& keypoints1, vector<KeyPoint>& keypoints2,
    02656                                                   vector<vector<DMatch> >* matches1to2, vector<vector<uchar> >* correctMatches1to2Mask,
    02657                                                   vector<Point2f>& recallPrecisionCurve,
    02658                                                   const Ptr<GenericDescriptorMatcher>& dmatch=Ptr<GenericDescriptorMatcher>() );
    02659
    02660
    02661 /****************************************************************************************\
    02662 *                                     Bag of visual words                                *
    02663 \****************************************************************************************/
    02664 /*
    02665  * Abstract base class for training of a 'bag of visual words' vocabulary from a set of descriptors
    02666  */
    02667 class CV_EXPORTS BOWTrainer
    02668 {
    02669 public:
    02670     BOWTrainer();
    02671     virtual ~BOWTrainer();
    02672
    02673     void add( const Mat& descriptors );
    02674     const vector<Mat>& getDescriptors() const;
    02675     int descripotorsCount() const;
    02676
    02677     virtual void clear();
    02678
    02679     /*
    02680      * Train visual words vocabulary, that is cluster training descriptors and
    02681      * compute cluster centers.
    02682      * Returns cluster centers.
    02683      *
    02684      * descriptors      Training descriptors computed on images keypoints.
    02685      */
    02686     virtual Mat cluster() const = 0;
    02687     virtual Mat cluster( const Mat& descriptors ) const = 0;
    02688
    02689 protected:
    02690     vector<Mat> descriptors;
    02691     int size;
    02692 };
    02693
    02694 /*
    02695  * This is BOWTrainer using cv::kmeans to get vocabulary.
    02696  */
    02697 class CV_EXPORTS BOWKMeansTrainer : public BOWTrainer
    02698 {
    02699 public:
    02700     BOWKMeansTrainer( int clusterCount, const TermCriteria& termcrit=TermCriteria(),
    02701                       int attempts=3, int flags=KMEANS_PP_CENTERS );
    02702     virtual ~BOWKMeansTrainer();
    02703
    02704     // Returns trained vocabulary (i.e. cluster centers).
    02705     virtual Mat cluster() const;
    02706     virtual Mat cluster( const Mat& descriptors ) const;
    02707
    02708 protected:
    02709
    02710     int clusterCount;
    02711     TermCriteria termcrit;
    02712     int attempts;
    02713     int flags;
    02714 };
    02715
    02716 /*
    02717  * Class to compute image descriptor using bag of visual words.
    02718  */
    02719 class CV_EXPORTS BOWImgDescriptorExtractor
    02720 {
    02721 public:
    02722     BOWImgDescriptorExtractor( const Ptr<DescriptorExtractor>& dextractor,
    02723                                const Ptr<DescriptorMatcher>& dmatcher );
    02724     virtual ~BOWImgDescriptorExtractor();
    02725
    02726     void setVocabulary( const Mat& vocabulary );
    02727     const Mat& getVocabulary() const;
    02728     void compute( const Mat& image, vector<KeyPoint>& keypoints, Mat& imgDescriptor,
    02729                   vector<vector<int> >* pointIdxsOfClusters=0, Mat* descriptors=0 );
    02730     // compute() is not constant because DescriptorMatcher::match is not constant
    02731
    02732     int descriptorSize() const;
    02733     int descriptorType() const;
    02734
    02735 protected:
    02736     Mat vocabulary;
    02737     Ptr<DescriptorExtractor> dextractor;
    02738     Ptr<DescriptorMatcher> dmatcher;
    02739 };
    02740
    02741 } /* namespace cv */
    02742
    02743 #endif /* __cplusplus */
    02744
    02745 #endif
    02746
    02747 /* End of file. */

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines