00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
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
00059 int laplacian;
00060 int size;
00061 float dir;
00062 float hessian;
00063
00064 } CvSURFPoint;
00065
00066 CV_INLINE CvSURFPoint cvSURFPoint( CvPoint2D32f pt, int laplacian,
00067 int size, float dir CV_DEFAULT(0),
00068 float hessian CV_DEFAULT(0))
00069 {
00070 CvSURFPoint kp;
00071
00072 kp.pt = pt;
00073 kp.laplacian = laplacian;
00074 kp.size = size;
00075 kp.dir = dir;
00076 kp.hessian = hessian;
00077
00078 return kp;
00079 }
00080
00081 typedef struct CvSURFParams
00082 {
00083 int extended;
00084 int upright;
00085 double hessianThreshold;
00086
00087 int nOctaves;
00088 int nOctaveLayers;
00089
00090 } CvSURFParams;
00091
00092 CVAPI(CvSURFParams) cvSURFParams( double hessianThreshold, int extended CV_DEFAULT(0) );
00093
00094
00095
00096 CVAPI(void) cvExtractSURF( const CvArr* img, const CvArr* mask,
00097 CvSeq** keypoints, CvSeq** descriptors,
00098 CvMemStorage* storage, CvSURFParams params, int useProvidedKeyPts CV_DEFAULT(0) );
00099
00103 typedef struct CvMSERParams
00104 {
00106 int delta;
00108 int maxArea;
00110 int minArea;
00112 float maxVariation;
00114 float minDiversity;
00115
00117
00119 int maxEvolution;
00121 double areaThreshold;
00123 double minMargin;
00125 int edgeBlurSize;
00126 } CvMSERParams;
00127
00128 CVAPI(CvMSERParams) cvMSERParams( int delta CV_DEFAULT(5), int min_area CV_DEFAULT(60),
00129 int max_area CV_DEFAULT(14400), float max_variation CV_DEFAULT(.25f),
00130 float min_diversity CV_DEFAULT(.2f), int max_evolution CV_DEFAULT(200),
00131 double area_threshold CV_DEFAULT(1.01),
00132 double min_margin CV_DEFAULT(.003),
00133 int edge_blur_size CV_DEFAULT(5) );
00134
00135
00136 CVAPI(void) cvExtractMSER( CvArr* _img, CvArr* _mask, CvSeq** contours, CvMemStorage* storage, CvMSERParams params );
00137
00138
00139 typedef struct CvStarKeypoint
00140 {
00141 CvPoint pt;
00142 int size;
00143 float response;
00144 } CvStarKeypoint;
00145
00146 CV_INLINE CvStarKeypoint cvStarKeypoint(CvPoint pt, int size, float response)
00147 {
00148 CvStarKeypoint kpt;
00149 kpt.pt = pt;
00150 kpt.size = size;
00151 kpt.response = response;
00152 return kpt;
00153 }
00154
00155 typedef struct CvStarDetectorParams
00156 {
00157 int maxSize;
00158 int responseThreshold;
00159 int lineThresholdProjected;
00160 int lineThresholdBinarized;
00161 int suppressNonmaxSize;
00162 } CvStarDetectorParams;
00163
00164 CV_INLINE CvStarDetectorParams cvStarDetectorParams(
00165 int maxSize CV_DEFAULT(45),
00166 int responseThreshold CV_DEFAULT(30),
00167 int lineThresholdProjected CV_DEFAULT(10),
00168 int lineThresholdBinarized CV_DEFAULT(8),
00169 int suppressNonmaxSize CV_DEFAULT(5))
00170 {
00171 CvStarDetectorParams params;
00172 params.maxSize = maxSize;
00173 params.responseThreshold = responseThreshold;
00174 params.lineThresholdProjected = lineThresholdProjected;
00175 params.lineThresholdBinarized = lineThresholdBinarized;
00176 params.suppressNonmaxSize = suppressNonmaxSize;
00177
00178 return params;
00179 }
00180
00181 CVAPI(CvSeq*) cvGetStarKeypoints( const CvArr* img, CvMemStorage* storage,
00182 CvStarDetectorParams params CV_DEFAULT(cvStarDetectorParams()));
00183
00184 #ifdef __cplusplus
00185 }
00186
00187 namespace cv
00188 {
00189 struct CV_EXPORTS DefaultRngAuto
00190 {
00191 const uint64 old_state;
00192
00193 DefaultRngAuto() : old_state(theRNG().state) { theRNG().state = (uint64)-1; }
00194 ~DefaultRngAuto() { theRNG().state = old_state; }
00195
00196 DefaultRngAuto& operator=(const DefaultRngAuto&);
00197 };
00198
00199
00200
00201
00202
00203
00204 class CV_EXPORTS CvAffinePose
00205 {
00206 public:
00207 float phi;
00208 float theta;
00209 float lambda1;
00210 float lambda2;
00211 };
00212
00225 class CV_EXPORTS_W_SIMPLE KeyPoint
00226 {
00227 public:
00229 CV_WRAP KeyPoint() : pt(0,0), size(0), angle(-1), response(0), octave(0), class_id(-1) {}
00231 KeyPoint(Point2f _pt, float _size, float _angle=-1,
00232 float _response=0, int _octave=0, int _class_id=-1)
00233 : pt(_pt), size(_size), angle(_angle),
00234 response(_response), octave(_octave), class_id(_class_id) {}
00236 CV_WRAP KeyPoint(float x, float y, float _size, float _angle=-1,
00237 float _response=0, int _octave=0, int _class_id=-1)
00238 : pt(x, y), size(_size), angle(_angle),
00239 response(_response), octave(_octave), class_id(_class_id) {}
00240
00241 size_t hash() const;
00242
00244 static void convert(const std::vector<KeyPoint>& keypoints,
00245 CV_OUT std::vector<Point2f>& points2f,
00246 const std::vector<int>& keypointIndexes=std::vector<int>());
00248 static void convert(const std::vector<Point2f>& points2f,
00249 CV_OUT std::vector<KeyPoint>& keypoints,
00250 float size=1, float response=1, int octave=0, int class_id=-1);
00251
00255 static float overlap(const KeyPoint& kp1, const KeyPoint& kp2);
00256
00257 CV_PROP_RW Point2f pt;
00258 CV_PROP_RW float size;
00259 CV_PROP_RW float angle;
00260 CV_PROP_RW float response;
00261 CV_PROP_RW int octave;
00262 CV_PROP_RW int class_id;
00263 };
00264
00266 CV_EXPORTS void write(FileStorage& fs, const string& name, const vector<KeyPoint>& keypoints);
00268 CV_EXPORTS void read(const FileNode& node, CV_OUT vector<KeyPoint>& keypoints);
00269
00270
00271
00272
00273
00274
00275 class CV_EXPORTS KeyPointsFilter
00276 {
00277 public:
00278 KeyPointsFilter(){}
00279
00280
00281
00282
00283 static void runByImageBorder( vector<KeyPoint>& keypoints, Size imageSize, int borderSize );
00284
00285
00286
00287 static void runByKeypointSize( vector<KeyPoint>& keypoints, float minSize, float maxSize=std::numeric_limits<float>::max() );
00288
00289
00290
00291 static void runByPixelsMask( vector<KeyPoint>& keypoints, const Mat& mask );
00292
00293
00294
00295 static void removeDuplicated( vector<KeyPoint>& keypoints );
00296 };
00297
00304 class CV_EXPORTS SIFT
00305 {
00306 public:
00307 struct CV_EXPORTS CommonParams
00308 {
00309 static const int DEFAULT_NOCTAVES = 4;
00310 static const int DEFAULT_NOCTAVE_LAYERS = 3;
00311 static const int DEFAULT_FIRST_OCTAVE = -1;
00312 enum { FIRST_ANGLE = 0, AVERAGE_ANGLE = 1 };
00313
00314 CommonParams();
00315 CommonParams( int _nOctaves, int _nOctaveLayers, int , int );
00316 CommonParams( int _nOctaves, int _nOctaveLayers );
00317 int nOctaves, nOctaveLayers;
00318 int firstOctave;
00319 int angleMode;
00320 };
00321
00322 struct CV_EXPORTS DetectorParams
00323 {
00324 static double GET_DEFAULT_THRESHOLD() { return 0.04; }
00325 static double GET_DEFAULT_EDGE_THRESHOLD() { return 10.0; }
00326
00327 DetectorParams();
00328 DetectorParams( double _threshold, double _edgeThreshold );
00329 double threshold, edgeThreshold;
00330 };
00331
00332 struct CV_EXPORTS DescriptorParams
00333 {
00334 static double GET_DEFAULT_MAGNIFICATION() { return 3.0; }
00335 static const bool DEFAULT_IS_NORMALIZE = true;
00336 static const int DESCRIPTOR_SIZE = 128;
00337
00338 DescriptorParams();
00339 DescriptorParams( double _magnification, bool , bool _recalculateAngles );
00340 DescriptorParams( bool _recalculateAngles );
00341 double magnification;
00342 bool isNormalize;
00343 bool recalculateAngles;
00344 };
00345
00346 SIFT();
00348 SIFT( double _threshold, double _edgeThreshold,
00349 int _nOctaves=CommonParams::DEFAULT_NOCTAVES,
00350 int _nOctaveLayers=CommonParams::DEFAULT_NOCTAVE_LAYERS,
00351 int _firstOctave=CommonParams::DEFAULT_FIRST_OCTAVE,
00352 int _angleMode=CommonParams::FIRST_ANGLE );
00354 SIFT( double _magnification, bool _isNormalize=true,
00355 bool _recalculateAngles = true,
00356 int _nOctaves=CommonParams::DEFAULT_NOCTAVES,
00357 int _nOctaveLayers=CommonParams::DEFAULT_NOCTAVE_LAYERS,
00358 int _firstOctave=CommonParams::DEFAULT_FIRST_OCTAVE,
00359 int _angleMode=CommonParams::FIRST_ANGLE );
00360 SIFT( const CommonParams& _commParams,
00361 const DetectorParams& _detectorParams = DetectorParams(),
00362 const DescriptorParams& _descriptorParams = DescriptorParams() );
00363
00365 int descriptorSize() const;
00367 void operator()(const Mat& img, const Mat& mask,
00368 vector<KeyPoint>& keypoints) const;
00371 void operator()(const Mat& img, const Mat& mask,
00372 vector<KeyPoint>& keypoints,
00373 Mat& descriptors,
00374 bool useProvidedKeypoints=false) const;
00375
00376 CommonParams getCommonParams () const;
00377 DetectorParams getDetectorParams () const;
00378 DescriptorParams getDescriptorParams () const;
00379
00380 protected:
00381 CommonParams commParams;
00382 DetectorParams detectorParams;
00383 DescriptorParams descriptorParams;
00384 };
00385
00386
00392 class CV_EXPORTS_W SURF : public CvSURFParams
00393 {
00394 public:
00396 CV_WRAP SURF();
00398 CV_WRAP SURF(double _hessianThreshold, int _nOctaves=4,
00399 int _nOctaveLayers=2, bool _extended=false, bool _upright=false);
00400
00402 CV_WRAP int descriptorSize() const;
00404 CV_WRAP_AS(detect) void operator()(const Mat& img, const Mat& mask,
00405 CV_OUT vector<KeyPoint>& keypoints) const;
00407 CV_WRAP_AS(detect) void operator()(const Mat& img, const Mat& mask,
00408 CV_OUT vector<KeyPoint>& keypoints,
00409 CV_OUT vector<float>& descriptors,
00410 bool useProvidedKeypoints=false) const;
00411 };
00412
00416 class CV_EXPORTS ORB
00417 {
00418 public:
00419
00421 enum { kBytes = 32 };
00422
00423 struct CV_EXPORTS CommonParams
00424 {
00425 enum { DEFAULT_N_LEVELS = 3, DEFAULT_FIRST_LEVEL = 0};
00426
00428 CommonParams(float scale_factor = 1.2f, unsigned int n_levels = DEFAULT_N_LEVELS, int edge_threshold = 31,
00429 unsigned int first_level = DEFAULT_FIRST_LEVEL) :
00430 scale_factor_(scale_factor), n_levels_(n_levels), first_level_(first_level >= n_levels ? 0 : first_level),
00431 edge_threshold_(edge_threshold)
00432 {
00433
00434 patch_size_ = 31;
00435 }
00436 void read(const FileNode& fn);
00437 void write(FileStorage& fs) const;
00438
00440 float scale_factor_;
00442 unsigned int n_levels_;
00446 unsigned int first_level_;
00448 int edge_threshold_;
00449
00450 friend class ORB;
00451 protected:
00453 int patch_size_;
00454 };
00455
00460 ORB(size_t n_features = 500, const CommonParams & detector_params = CommonParams());
00461
00463 ~ORB();
00464
00466 int descriptorSize() const;
00467
00473 void
00474 operator()(const cv::Mat &image, const cv::Mat &mask, std::vector<cv::KeyPoint> & keypoints);
00475
00483 void
00484 operator()(const cv::Mat &image, const cv::Mat &mask, std::vector<cv::KeyPoint> & keypoints, cv::Mat & descriptors,
00485 bool useProvidedKeypoints = false);
00486
00487 private:
00489 static const int kKernelWidth = 5;
00490
00499 void
00500 operator()(const cv::Mat &image, const cv::Mat &mask, std::vector<cv::KeyPoint> & keypoints, cv::Mat & descriptors,
00501 bool do_keypoints, bool do_descriptors);
00502
00508 void computeKeyPoints(const std::vector<cv::Mat>& image_pyramid, const std::vector<cv::Mat>& mask_pyramid,
00509 std::vector<std::vector<cv::KeyPoint> >& keypoints) const;
00510
00517 void
00518 computeOrientation(const cv::Mat& image, const cv::Mat& integral_image, unsigned int level,
00519 std::vector<cv::KeyPoint>& keypoints) const;
00520
00528 void
00529 computeDescriptors(const cv::Mat& image, const cv::Mat& integral_image, unsigned int level,
00530 std::vector<cv::KeyPoint>& keypoints, cv::Mat & descriptors) const;
00531
00537 void computeIntegralImage(const cv::Mat & image, unsigned int level, cv::Mat &integral_image);
00538
00540 CommonParams params_;
00541
00543 int half_patch_size_;
00544
00546 std::vector<std::vector<int> > orientation_horizontal_offsets_;
00547 std::vector<std::vector<int> > orientation_vertical_offsets_;
00548
00550 std::vector<size_t> integral_image_steps_;
00551
00553 std::vector<size_t> n_features_per_level_;
00554
00556 size_t n_features_;
00557
00559 std::vector<int> u_max_;
00560
00562 class OrbPatterns;
00563 std::vector<OrbPatterns*> patterns_;
00564 };
00565
00575 class CV_EXPORTS_W MSER : public CvMSERParams
00576 {
00577 public:
00579 CV_WRAP MSER();
00581 CV_WRAP MSER( int _delta, int _min_area, int _max_area,
00582 double _max_variation, double _min_diversity,
00583 int _max_evolution, double _area_threshold,
00584 double _min_margin, int _edge_blur_size );
00586 CV_WRAP_AS(detect) void operator()( const Mat& image,
00587 CV_OUT vector<vector<Point> >& msers, const Mat& mask ) const;
00588 };
00589
00595 class CV_EXPORTS_W StarDetector : public CvStarDetectorParams
00596 {
00597 public:
00599 CV_WRAP StarDetector();
00601 CV_WRAP StarDetector(int _maxSize, int _responseThreshold,
00602 int _lineThresholdProjected,
00603 int _lineThresholdBinarized,
00604 int _suppressNonmaxSize);
00606 CV_WRAP_AS(detect) void operator()(const Mat& image,
00607 CV_OUT vector<KeyPoint>& keypoints) const;
00608 };
00609
00611 CV_EXPORTS void FAST( const Mat& image, CV_OUT vector<KeyPoint>& keypoints,
00612 int threshold, bool nonmaxSupression=true );
00613
00617 class CV_EXPORTS PatchGenerator
00618 {
00619 public:
00620 PatchGenerator();
00621 PatchGenerator(double _backgroundMin, double _backgroundMax,
00622 double _noiseRange, bool _randomBlur=true,
00623 double _lambdaMin=0.6, double _lambdaMax=1.5,
00624 double _thetaMin=-CV_PI, double _thetaMax=CV_PI,
00625 double _phiMin=-CV_PI, double _phiMax=CV_PI );
00626 void operator()(const Mat& image, Point2f pt, Mat& patch, Size patchSize, RNG& rng) const;
00627 void operator()(const Mat& image, const Mat& transform, Mat& patch,
00628 Size patchSize, RNG& rng) const;
00629 void warpWholeImage(const Mat& image, Mat& matT, Mat& buf,
00630 CV_OUT Mat& warped, int border, RNG& rng) const;
00631 void generateRandomTransform(Point2f srcCenter, Point2f dstCenter,
00632 CV_OUT Mat& transform, RNG& rng,
00633 bool inverse=false) const;
00634 void setAffineParam(double lambda, double theta, double phi);
00635
00636 double backgroundMin, backgroundMax;
00637 double noiseRange;
00638 bool randomBlur;
00639 double lambdaMin, lambdaMax;
00640 double thetaMin, thetaMax;
00641 double phiMin, phiMax;
00642 };
00643
00644
00645 class CV_EXPORTS LDetector
00646 {
00647 public:
00648 LDetector();
00649 LDetector(int _radius, int _threshold, int _nOctaves,
00650 int _nViews, double _baseFeatureSize, double _clusteringDistance);
00651 void operator()(const Mat& image,
00652 CV_OUT vector<KeyPoint>& keypoints,
00653 int maxCount=0, bool scaleCoords=true) const;
00654 void operator()(const vector<Mat>& pyr,
00655 CV_OUT vector<KeyPoint>& keypoints,
00656 int maxCount=0, bool scaleCoords=true) const;
00657 void getMostStable2D(const Mat& image, CV_OUT vector<KeyPoint>& keypoints,
00658 int maxCount, const PatchGenerator& patchGenerator) const;
00659 void setVerbose(bool verbose);
00660
00661 void read(const FileNode& node);
00662 void write(FileStorage& fs, const String& name=String()) const;
00663
00664 int radius;
00665 int threshold;
00666 int nOctaves;
00667 int nViews;
00668 bool verbose;
00669
00670 double baseFeatureSize;
00671 double clusteringDistance;
00672 };
00673
00674 typedef LDetector YAPE;
00675
00676 class CV_EXPORTS FernClassifier
00677 {
00678 public:
00679 FernClassifier();
00680 FernClassifier(const FileNode& node);
00681 FernClassifier(const vector<vector<Point2f> >& points,
00682 const vector<Mat>& refimgs,
00683 const vector<vector<int> >& labels=vector<vector<int> >(),
00684 int _nclasses=0, int _patchSize=PATCH_SIZE,
00685 int _signatureSize=DEFAULT_SIGNATURE_SIZE,
00686 int _nstructs=DEFAULT_STRUCTS,
00687 int _structSize=DEFAULT_STRUCT_SIZE,
00688 int _nviews=DEFAULT_VIEWS,
00689 int _compressionMethod=COMPRESSION_NONE,
00690 const PatchGenerator& patchGenerator=PatchGenerator());
00691 virtual ~FernClassifier();
00692 virtual void read(const FileNode& n);
00693 virtual void write(FileStorage& fs, const String& name=String()) const;
00694 virtual void trainFromSingleView(const Mat& image,
00695 const vector<KeyPoint>& keypoints,
00696 int _patchSize=PATCH_SIZE,
00697 int _signatureSize=DEFAULT_SIGNATURE_SIZE,
00698 int _nstructs=DEFAULT_STRUCTS,
00699 int _structSize=DEFAULT_STRUCT_SIZE,
00700 int _nviews=DEFAULT_VIEWS,
00701 int _compressionMethod=COMPRESSION_NONE,
00702 const PatchGenerator& patchGenerator=PatchGenerator());
00703 virtual void train(const vector<vector<Point2f> >& points,
00704 const vector<Mat>& refimgs,
00705 const vector<vector<int> >& labels=vector<vector<int> >(),
00706 int _nclasses=0, int _patchSize=PATCH_SIZE,
00707 int _signatureSize=DEFAULT_SIGNATURE_SIZE,
00708 int _nstructs=DEFAULT_STRUCTS,
00709 int _structSize=DEFAULT_STRUCT_SIZE,
00710 int _nviews=DEFAULT_VIEWS,
00711 int _compressionMethod=COMPRESSION_NONE,
00712 const PatchGenerator& patchGenerator=PatchGenerator());
00713 virtual int operator()(const Mat& img, Point2f kpt, vector<float>& signature) const;
00714 virtual int operator()(const Mat& patch, vector<float>& signature) const;
00715 virtual void clear();
00716 virtual bool empty() const;
00717 void setVerbose(bool verbose);
00718
00719 int getClassCount() const;
00720 int getStructCount() const;
00721 int getStructSize() const;
00722 int getSignatureSize() const;
00723 int getCompressionMethod() const;
00724 Size getPatchSize() const;
00725
00726 struct Feature
00727 {
00728 uchar x1, y1, x2, y2;
00729 Feature() : x1(0), y1(0), x2(0), y2(0) {}
00730 Feature(int _x1, int _y1, int _x2, int _y2)
00731 : x1((uchar)_x1), y1((uchar)_y1), x2((uchar)_x2), y2((uchar)_y2)
00732 {}
00733 template<typename _Tp> bool operator ()(const Mat_<_Tp>& patch) const
00734 { return patch(y1,x1) > patch(y2, x2); }
00735 };
00736
00737 enum
00738 {
00739 PATCH_SIZE = 31,
00740 DEFAULT_STRUCTS = 50,
00741 DEFAULT_STRUCT_SIZE = 9,
00742 DEFAULT_VIEWS = 5000,
00743 DEFAULT_SIGNATURE_SIZE = 176,
00744 COMPRESSION_NONE = 0,
00745 COMPRESSION_RANDOM_PROJ = 1,
00746 COMPRESSION_PCA = 2,
00747 DEFAULT_COMPRESSION_METHOD = COMPRESSION_NONE
00748 };
00749
00750 protected:
00751 virtual void prepare(int _nclasses, int _patchSize, int _signatureSize,
00752 int _nstructs, int _structSize,
00753 int _nviews, int _compressionMethod);
00754 virtual void finalize(RNG& rng);
00755 virtual int getLeaf(int fidx, const Mat& patch) const;
00756
00757 bool verbose;
00758 int nstructs;
00759 int structSize;
00760 int nclasses;
00761 int signatureSize;
00762 int compressionMethod;
00763 int leavesPerStruct;
00764 Size patchSize;
00765 vector<Feature> features;
00766 vector<int> classCounters;
00767 vector<float> posteriors;
00768 };
00769
00770
00771
00772
00773
00774
00775 struct RTreeNode;
00776
00777 struct CV_EXPORTS BaseKeypoint
00778 {
00779 int x;
00780 int y;
00781 IplImage* image;
00782
00783 BaseKeypoint()
00784 : x(0), y(0), image(NULL)
00785 {}
00786
00787 BaseKeypoint(int x, int y, IplImage* image)
00788 : x(x), y(y), image(image)
00789 {}
00790 };
00791
00792 class CV_EXPORTS RandomizedTree
00793 {
00794 public:
00795 friend class RTreeClassifier;
00796
00797 static const uchar PATCH_SIZE = 32;
00798 static const int DEFAULT_DEPTH = 9;
00799 static const int DEFAULT_VIEWS = 5000;
00800 static const size_t DEFAULT_REDUCED_NUM_DIM = 176;
00801 static float GET_LOWER_QUANT_PERC() { return .03f; }
00802 static float GET_UPPER_QUANT_PERC() { return .92f; }
00803
00804 RandomizedTree();
00805 ~RandomizedTree();
00806
00807 void train(std::vector<BaseKeypoint> const& base_set, RNG &rng,
00808 int depth, int views, size_t reduced_num_dim, int num_quant_bits);
00809 void train(std::vector<BaseKeypoint> const& base_set, RNG &rng,
00810 PatchGenerator &make_patch, int depth, int views, size_t reduced_num_dim,
00811 int num_quant_bits);
00812
00813
00814 static void quantizeVector(float *vec, int dim, int N, float bnds[2], int clamp_mode=0);
00815 static void quantizeVector(float *src, int dim, int N, float bnds[2], uchar *dst);
00816
00817
00818 float* getPosterior(uchar* patch_data);
00819 const float* getPosterior(uchar* patch_data) const;
00820 uchar* getPosterior2(uchar* patch_data);
00821 const uchar* getPosterior2(uchar* patch_data) const;
00822
00823 void read(const char* file_name, int num_quant_bits);
00824 void read(std::istream &is, int num_quant_bits);
00825 void write(const char* file_name) const;
00826 void write(std::ostream &os) const;
00827
00828 int classes() { return classes_; }
00829 int depth() { return depth_; }
00830
00831
00832 void discardFloatPosteriors() { freePosteriors(1); }
00833
00834 inline void applyQuantization(int num_quant_bits) { makePosteriors2(num_quant_bits); }
00835
00836
00837 void savePosteriors(std::string url, bool append=false);
00838 void savePosteriors2(std::string url, bool append=false);
00839
00840 private:
00841 int classes_;
00842 int depth_;
00843 int num_leaves_;
00844 std::vector<RTreeNode> nodes_;
00845 float **posteriors_;
00846 uchar **posteriors2_;
00847 std::vector<int> leaf_counts_;
00848
00849 void createNodes(int num_nodes, RNG &rng);
00850 void allocPosteriorsAligned(int num_leaves, int num_classes);
00851 void freePosteriors(int which);
00852 void init(int classes, int depth, RNG &rng);
00853 void addExample(int class_id, uchar* patch_data);
00854 void finalize(size_t reduced_num_dim, int num_quant_bits);
00855 int getIndex(uchar* patch_data) const;
00856 inline float* getPosteriorByIndex(int index);
00857 inline const float* getPosteriorByIndex(int index) const;
00858 inline uchar* getPosteriorByIndex2(int index);
00859 inline const uchar* getPosteriorByIndex2(int index) const;
00860
00861 void convertPosteriorsToChar();
00862 void makePosteriors2(int num_quant_bits);
00863 void compressLeaves(size_t reduced_num_dim);
00864 void estimateQuantPercForPosteriors(float perc[2]);
00865 };
00866
00867
00868 inline uchar* getData(IplImage* image)
00869 {
00870 return reinterpret_cast<uchar*>(image->imageData);
00871 }
00872
00873 inline float* RandomizedTree::getPosteriorByIndex(int index)
00874 {
00875 return const_cast<float*>(const_cast<const RandomizedTree*>(this)->getPosteriorByIndex(index));
00876 }
00877
00878 inline const float* RandomizedTree::getPosteriorByIndex(int index) const
00879 {
00880 return posteriors_[index];
00881 }
00882
00883 inline uchar* RandomizedTree::getPosteriorByIndex2(int index)
00884 {
00885 return const_cast<uchar*>(const_cast<const RandomizedTree*>(this)->getPosteriorByIndex2(index));
00886 }
00887
00888 inline const uchar* RandomizedTree::getPosteriorByIndex2(int index) const
00889 {
00890 return posteriors2_[index];
00891 }
00892
00893 struct CV_EXPORTS RTreeNode
00894 {
00895 short offset1, offset2;
00896
00897 RTreeNode() {}
00898 RTreeNode(uchar x1, uchar y1, uchar x2, uchar y2)
00899 : offset1(y1*RandomizedTree::PATCH_SIZE + x1),
00900 offset2(y2*RandomizedTree::PATCH_SIZE + x2)
00901 {}
00902
00904 inline bool operator() (uchar* patch_data) const
00905 {
00906 return patch_data[offset1] > patch_data[offset2];
00907 }
00908 };
00909
00910 class CV_EXPORTS RTreeClassifier
00911 {
00912 public:
00913 static const int DEFAULT_TREES = 48;
00914 static const size_t DEFAULT_NUM_QUANT_BITS = 4;
00915
00916 RTreeClassifier();
00917 void train(std::vector<BaseKeypoint> const& base_set,
00918 RNG &rng,
00919 int num_trees = RTreeClassifier::DEFAULT_TREES,
00920 int depth = RandomizedTree::DEFAULT_DEPTH,
00921 int views = RandomizedTree::DEFAULT_VIEWS,
00922 size_t reduced_num_dim = RandomizedTree::DEFAULT_REDUCED_NUM_DIM,
00923 int num_quant_bits = DEFAULT_NUM_QUANT_BITS);
00924 void train(std::vector<BaseKeypoint> const& base_set,
00925 RNG &rng,
00926 PatchGenerator &make_patch,
00927 int num_trees = RTreeClassifier::DEFAULT_TREES,
00928 int depth = RandomizedTree::DEFAULT_DEPTH,
00929 int views = RandomizedTree::DEFAULT_VIEWS,
00930 size_t reduced_num_dim = RandomizedTree::DEFAULT_REDUCED_NUM_DIM,
00931 int num_quant_bits = DEFAULT_NUM_QUANT_BITS);
00932
00933
00934 void getSignature(IplImage *patch, uchar *sig) const;
00935 void getSignature(IplImage *patch, float *sig) const;
00936 void getSparseSignature(IplImage *patch, float *sig, float thresh) const;
00937
00938 void getFloatSignature(IplImage *patch, float *sig) const { getSignature(patch, sig); }
00939
00940 static int countNonZeroElements(float *vec, int n, double tol=1e-10);
00941 static inline void safeSignatureAlloc(uchar **sig, int num_sig=1, int sig_len=176);
00942 static inline uchar* safeSignatureAlloc(int num_sig=1, int sig_len=176);
00943
00944 inline int classes() const { return classes_; }
00945 inline int original_num_classes() const { return original_num_classes_; }
00946
00947 void setQuantization(int num_quant_bits);
00948 void discardFloatPosteriors();
00949
00950 void read(const char* file_name);
00951 void read(std::istream &is);
00952 void write(const char* file_name) const;
00953 void write(std::ostream &os) const;
00954
00955
00956 void saveAllFloatPosteriors(std::string file_url);
00957 void saveAllBytePosteriors(std::string file_url);
00958 void setFloatPosteriorsFromTextfile_176(std::string url);
00959 float countZeroElements();
00960
00961 std::vector<RandomizedTree> trees_;
00962
00963 private:
00964 int classes_;
00965 int num_quant_bits_;
00966 mutable uchar **posteriors_;
00967 mutable unsigned short *ptemp_;
00968 int original_num_classes_;
00969 bool keep_floats_;
00970 };
00971
00972
00973
00974
00975
00976 class CV_EXPORTS OneWayDescriptor
00977 {
00978 public:
00979 OneWayDescriptor();
00980 ~OneWayDescriptor();
00981
00982
00983 void Allocate(int pose_count, CvSize size, int nChannels);
00984
00985
00986
00987
00988
00989
00990 void GenerateSamples(int pose_count, IplImage* frontal, int norm = 0);
00991
00992
00993
00994
00995
00996
00997
00998
00999 void GenerateSamplesFast(IplImage* frontal, CvMat* pca_hr_avg,
01000 CvMat* pca_hr_eigenvectors, OneWayDescriptor* pca_descriptors);
01001
01002
01003 void SetTransforms(CvAffinePose* poses, CvMat** transforms);
01004
01005
01006
01007
01008
01009
01010 void Initialize(int pose_count, IplImage* frontal, const char* feature_name = 0, int norm = 0);
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020 void InitializeFast(int pose_count, IplImage* frontal, const char* feature_name,
01021 CvMat* pca_hr_avg, CvMat* pca_hr_eigenvectors, OneWayDescriptor* pca_descriptors);
01022
01023
01024
01025
01026
01027
01028 void ProjectPCASample(IplImage* patch, CvMat* avg, CvMat* eigenvectors, CvMat* pca_coeffs) const;
01029
01030
01031
01032
01033 void InitializePCACoeffs(CvMat* avg, CvMat* eigenvectors);
01034
01035
01036
01037
01038
01039 void EstimatePose(IplImage* patch, int& pose_idx, float& distance) const;
01040
01041
01042
01043
01044
01045
01046
01047
01048 void EstimatePosePCA(CvArr* patch, int& pose_idx, float& distance, CvMat* avg, CvMat* eigenvalues) const;
01049
01050
01051 CvSize GetPatchSize() const
01052 {
01053 return m_patch_size;
01054 }
01055
01056
01057
01058 CvSize GetInputPatchSize() const
01059 {
01060 return cvSize(m_patch_size.width*2, m_patch_size.height*2);
01061 }
01062
01063
01064
01065
01066 IplImage* GetPatch(int index);
01067
01068
01069
01070
01071 CvAffinePose GetPose(int index) const;
01072
01073
01074 void Save(const char* path);
01075
01076
01077
01078
01079
01080
01081 int ReadByName(CvFileStorage* fs, CvFileNode* parent, const char* name);
01082
01083
01084
01085
01086
01087 int ReadByName(const FileNode &parent, const char* name);
01088
01089
01090
01091
01092 void Write(CvFileStorage* fs, const char* name);
01093
01094
01095 const char* GetFeatureName() const;
01096
01097
01098 CvPoint GetCenter() const;
01099
01100 void SetPCADimHigh(int pca_dim_high) {m_pca_dim_high = pca_dim_high;};
01101 void SetPCADimLow(int pca_dim_low) {m_pca_dim_low = pca_dim_low;};
01102
01103 int GetPCADimLow() const;
01104 int GetPCADimHigh() const;
01105
01106 CvMat** GetPCACoeffs() const {return m_pca_coeffs;}
01107
01108 protected:
01109 int m_pose_count;
01110 CvSize m_patch_size;
01111 IplImage** m_samples;
01112 IplImage* m_input_patch;
01113 IplImage* m_train_patch;
01114 CvMat** m_pca_coeffs;
01115 CvAffinePose* m_affine_poses;
01116 CvMat** m_transforms;
01117
01118 string m_feature_name;
01119 CvPoint m_center;
01120
01121 int m_pca_dim_high;
01122 int m_pca_dim_low;
01123 };
01124
01125
01126
01127
01128 class CV_EXPORTS OneWayDescriptorBase
01129 {
01130 public:
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140 OneWayDescriptorBase(CvSize patch_size, int pose_count, const char* train_path = 0, const char* pca_config = 0,
01141 const char* pca_hr_config = 0, const char* pca_desc_config = 0, int pyr_levels = 1,
01142 int pca_dim_high = 100, int pca_dim_low = 100);
01143
01144 OneWayDescriptorBase(CvSize patch_size, int pose_count, const string &pca_filename, const string &train_path = string(), const string &images_list = string(),
01145 float _scale_min = 0.7f, float _scale_max=1.5f, float _scale_step=1.2f, int pyr_levels = 1,
01146 int pca_dim_high = 100, int pca_dim_low = 100);
01147
01148
01149 virtual ~OneWayDescriptorBase();
01150 void clear ();
01151
01152
01153
01154 void Allocate(int train_feature_count);
01155
01156
01157 void AllocatePCADescriptors();
01158
01159
01160 CvSize GetPatchSize() const {return m_patch_size;};
01161
01162 int GetPoseCount() const {return m_pose_count;};
01163
01164
01165 int GetPyrLevels() const {return m_pyr_levels;};
01166
01167
01168 int GetDescriptorCount() const {return m_train_feature_count;};
01169
01170
01171
01172
01173
01174 void CreateDescriptorsFromImage(IplImage* src, const std::vector<cv::KeyPoint>& features);
01175
01176
01177 void CreatePCADescriptors();
01178
01179
01180 const OneWayDescriptor* GetDescriptor(int desc_idx) const {return &m_descriptors[desc_idx];};
01181
01182
01183
01184
01185
01186
01187
01188
01189 void FindDescriptor(IplImage* patch, int& desc_idx, int& pose_idx, float& distance, float* _scale = 0, float* scale_ranges = 0) const;
01190
01191
01192
01193
01194
01195
01196
01197
01198 void FindDescriptor(IplImage* patch, int n, std::vector<int>& desc_idxs, std::vector<int>& pose_idxs,
01199 std::vector<float>& distances, std::vector<float>& _scales, float* scale_ranges = 0) const;
01200
01201
01202
01203
01204
01205
01206
01207 void FindDescriptor(IplImage* src, cv::Point2f pt, int& desc_idx, int& pose_idx, float& distance) const;
01208
01209
01210 void InitializePoses();
01211
01212
01213 void InitializeTransformsFromPoses();
01214
01215
01216 void InitializePoseTransforms();
01217
01218
01219
01220
01221
01222 void InitializeDescriptor(int desc_idx, IplImage* train_image, const char* feature_label);
01223
01224 void InitializeDescriptor(int desc_idx, IplImage* train_image, const cv::KeyPoint& keypoint, const char* feature_label);
01225
01226
01227 void InitializeDescriptors(IplImage* train_image, const vector<cv::KeyPoint>& features,
01228 const char* feature_label = "", int desc_start_idx = 0);
01229
01230
01231
01232 void Write (FileStorage &fs) const;
01233
01234
01235
01236 void Read (const FileNode &fn);
01237
01238
01239
01240 int LoadPCADescriptors(const char* filename);
01241
01242
01243
01244 int LoadPCADescriptors(const FileNode &fn);
01245
01246
01247
01248 void SavePCADescriptors(const char* filename);
01249
01250
01251
01252 void SavePCADescriptors(CvFileStorage* fs) const;
01253
01254
01255
01256
01257 void GeneratePCA(const char* img_path, const char* images_list, int pose_count=500);
01258
01259
01260 void SetPCAHigh(CvMat* avg, CvMat* eigenvectors);
01261
01262
01263 void SetPCALow(CvMat* avg, CvMat* eigenvectors);
01264
01265 int GetLowPCA(CvMat** avg, CvMat** eigenvectors)
01266 {
01267 *avg = m_pca_avg;
01268 *eigenvectors = m_pca_eigenvectors;
01269 return m_pca_dim_low;
01270 };
01271
01272 int GetPCADimLow() const {return m_pca_dim_low;};
01273 int GetPCADimHigh() const {return m_pca_dim_high;};
01274
01275 void ConvertDescriptorsArrayToTree();
01276
01277
01278 static string GetPCAFilename () { return "pca.yml"; }
01279
01280 virtual bool empty() const { return m_train_feature_count <= 0 ? true : false; }
01281
01282 protected:
01283 CvSize m_patch_size;
01284 int m_pose_count;
01285 int m_train_feature_count;
01286 OneWayDescriptor* m_descriptors;
01287 CvMat* m_pca_avg;
01288 CvMat* m_pca_eigenvectors;
01289 CvMat* m_pca_hr_avg;
01290 CvMat* m_pca_hr_eigenvectors;
01291 OneWayDescriptor* m_pca_descriptors;
01292
01293 cv::flann::Index* m_pca_descriptors_tree;
01294 CvMat* m_pca_descriptors_matrix;
01295
01296 CvAffinePose* m_poses;
01297 CvMat** m_transforms;
01298
01299 int m_pca_dim_high;
01300 int m_pca_dim_low;
01301
01302 int m_pyr_levels;
01303 float scale_min;
01304 float scale_max;
01305 float scale_step;
01306
01307
01308
01309 void SavePCAall (FileStorage &fs) const;
01310
01311
01312
01313 void LoadPCAall (const FileNode &fn);
01314 };
01315
01316 class CV_EXPORTS OneWayDescriptorObject : public OneWayDescriptorBase
01317 {
01318 public:
01319
01320
01321
01322
01323
01324
01325
01326
01327 OneWayDescriptorObject(CvSize patch_size, int pose_count, const char* train_path, const char* pca_config,
01328 const char* pca_hr_config = 0, const char* pca_desc_config = 0, int pyr_levels = 1);
01329
01330 OneWayDescriptorObject(CvSize patch_size, int pose_count, const string &pca_filename,
01331 const string &train_path = string (), const string &images_list = string (),
01332 float _scale_min = 0.7f, float _scale_max=1.5f, float _scale_step=1.2f, int pyr_levels = 1);
01333
01334
01335 virtual ~OneWayDescriptorObject();
01336
01337
01338
01339
01340 void Allocate(int train_feature_count, int object_feature_count);
01341
01342
01343 void SetLabeledFeatures(const vector<cv::KeyPoint>& features) {m_train_features = features;};
01344 vector<cv::KeyPoint>& GetLabeledFeatures() {return m_train_features;};
01345 const vector<cv::KeyPoint>& GetLabeledFeatures() const {return m_train_features;};
01346 vector<cv::KeyPoint> _GetLabeledFeatures() const;
01347
01348
01349 int IsDescriptorObject(int desc_idx) const;
01350
01351
01352 int MatchPointToPart(CvPoint pt) const;
01353
01354
01355
01356 int GetDescriptorPart(int desc_idx) const;
01357
01358
01359 void InitializeObjectDescriptors(IplImage* train_image, const vector<cv::KeyPoint>& features,
01360 const char* feature_label, int desc_start_idx = 0, float scale = 1.0f,
01361 int is_background = 0);
01362
01363
01364 int GetObjectFeatureCount() const {return m_object_feature_count;};
01365
01366 protected:
01367 int* m_part_id;
01368 vector<cv::KeyPoint> m_train_features;
01369 int m_object_feature_count;
01370
01371 };
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381 class CV_EXPORTS FeatureDetector
01382 {
01383 public:
01384 virtual ~FeatureDetector();
01385
01386
01387
01388
01389
01390
01391
01392
01393 void detect( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
01394
01395
01396
01397
01398
01399
01400
01401 void detect( const vector<Mat>& images, vector<vector<KeyPoint> >& keypoints, const vector<Mat>& masks=vector<Mat>() ) const;
01402
01403
01404 virtual void read( const FileNode& );
01405
01406 virtual void write( FileStorage& ) const;
01407
01408
01409 virtual bool empty() const;
01410
01411
01412 static Ptr<FeatureDetector> create( const string& detectorType );
01413
01414 protected:
01415 virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const = 0;
01416
01417
01418
01419
01420
01421
01422 static void removeInvalidPoints( const Mat& mask, vector<KeyPoint>& keypoints );
01423 };
01424
01425 class CV_EXPORTS FastFeatureDetector : public FeatureDetector
01426 {
01427 public:
01428 FastFeatureDetector( int threshold=10, bool nonmaxSuppression=true );
01429 virtual void read( const FileNode& fn );
01430 virtual void write( FileStorage& fs ) const;
01431
01432 protected:
01433 virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
01434
01435 int threshold;
01436 bool nonmaxSuppression;
01437 };
01438
01439
01440 class CV_EXPORTS GoodFeaturesToTrackDetector : public FeatureDetector
01441 {
01442 public:
01443 class CV_EXPORTS Params
01444 {
01445 public:
01446 Params( int maxCorners=1000, double qualityLevel=0.01, double minDistance=1.,
01447 int blockSize=3, bool useHarrisDetector=false, double k=0.04 );
01448 void read( const FileNode& fn );
01449 void write( FileStorage& fs ) const;
01450
01451 int maxCorners;
01452 double qualityLevel;
01453 double minDistance;
01454 int blockSize;
01455 bool useHarrisDetector;
01456 double k;
01457 };
01458
01459 GoodFeaturesToTrackDetector( const GoodFeaturesToTrackDetector::Params& params=GoodFeaturesToTrackDetector::Params() );
01460 GoodFeaturesToTrackDetector( int maxCorners, double qualityLevel, double minDistance,
01461 int blockSize=3, bool useHarrisDetector=false, double k=0.04 );
01462 virtual void read( const FileNode& fn );
01463 virtual void write( FileStorage& fs ) const;
01464
01465 protected:
01466 virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
01467
01468 Params params;
01469 };
01470
01471 class CV_EXPORTS MserFeatureDetector : public FeatureDetector
01472 {
01473 public:
01474 MserFeatureDetector( CvMSERParams params=cvMSERParams() );
01475 MserFeatureDetector( int delta, int minArea, int maxArea, double maxVariation, double minDiversity,
01476 int maxEvolution, double areaThreshold, double minMargin, int edgeBlurSize );
01477 virtual void read( const FileNode& fn );
01478 virtual void write( FileStorage& fs ) const;
01479
01480 protected:
01481 virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
01482
01483 MSER mser;
01484 };
01485
01486 class CV_EXPORTS StarFeatureDetector : public FeatureDetector
01487 {
01488 public:
01489 StarFeatureDetector( const CvStarDetectorParams& params=cvStarDetectorParams() );
01490 StarFeatureDetector( int maxSize, int responseThreshold=30, int lineThresholdProjected = 10,
01491 int lineThresholdBinarized=8, int suppressNonmaxSize=5 );
01492 virtual void read( const FileNode& fn );
01493 virtual void write( FileStorage& fs ) const;
01494
01495 protected:
01496 virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
01497
01498 StarDetector star;
01499 };
01500
01501 class CV_EXPORTS SiftFeatureDetector : public FeatureDetector
01502 {
01503 public:
01504 SiftFeatureDetector( const SIFT::DetectorParams& detectorParams=SIFT::DetectorParams(),
01505 const SIFT::CommonParams& commonParams=SIFT::CommonParams() );
01506 SiftFeatureDetector( double threshold, double edgeThreshold,
01507 int nOctaves=SIFT::CommonParams::DEFAULT_NOCTAVES,
01508 int nOctaveLayers=SIFT::CommonParams::DEFAULT_NOCTAVE_LAYERS,
01509 int firstOctave=SIFT::CommonParams::DEFAULT_FIRST_OCTAVE,
01510 int angleMode=SIFT::CommonParams::FIRST_ANGLE );
01511 virtual void read( const FileNode& fn );
01512 virtual void write( FileStorage& fs ) const;
01513
01514 protected:
01515 virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
01516
01517 SIFT sift;
01518 };
01519
01520 class CV_EXPORTS SurfFeatureDetector : public FeatureDetector
01521 {
01522 public:
01523 SurfFeatureDetector( double hessianThreshold=400., int octaves=3, int octaveLayers=4, bool upright=false );
01524 virtual void read( const FileNode& fn );
01525 virtual void write( FileStorage& fs ) const;
01526
01527 protected:
01528 virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
01529
01530 SURF surf;
01531 };
01532
01536 class CV_EXPORTS OrbFeatureDetector : public cv::FeatureDetector
01537 {
01538 public:
01543 OrbFeatureDetector(size_t n_features = 700, ORB::CommonParams params = ORB::CommonParams());
01544
01545 virtual void read(const cv::FileNode&);
01546 virtual void write(cv::FileStorage&) const;
01547
01548 protected:
01549 virtual void
01550 detectImpl(const cv::Mat& image, std::vector<cv::KeyPoint>& keypoints, const cv::Mat& mask = cv::Mat()) const;
01551 private:
01553 mutable ORB orb_;
01555 ORB::CommonParams params_;
01557 unsigned int n_features_;
01558 };
01559
01560 class CV_EXPORTS SimpleBlobDetector : public cv::FeatureDetector
01561 {
01562 public:
01563 struct CV_EXPORTS Params
01564 {
01565 Params();
01566 float thresholdStep;
01567 float minThreshold;
01568 float maxThreshold;
01569 size_t minRepeatability;
01570 float minDistBetweenBlobs;
01571
01572 bool filterByColor;
01573 uchar blobColor;
01574
01575 bool filterByArea;
01576 float minArea, maxArea;
01577
01578 bool filterByCircularity;
01579 float minCircularity, maxCircularity;
01580
01581 bool filterByInertia;
01582 float minInertiaRatio, maxInertiaRatio;
01583
01584 bool filterByConvexity;
01585 float minConvexity, maxConvexity;
01586 };
01587
01588 SimpleBlobDetector(const SimpleBlobDetector::Params ¶meters = SimpleBlobDetector::Params());
01589
01590 protected:
01591 struct CV_EXPORTS Center
01592 {
01593 Point2d location;
01594 double radius;
01595 double confidence;
01596 };
01597
01598 virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
01599 virtual void findBlobs(const cv::Mat &image, const cv::Mat &binaryImage, std::vector<Center> ¢ers) const;
01600
01601 Params params;
01602 };
01603
01604 class CV_EXPORTS DenseFeatureDetector : public FeatureDetector
01605 {
01606 public:
01607 class CV_EXPORTS Params
01608 {
01609 public:
01610 Params( float initFeatureScale=1.f, int featureScaleLevels=1, float featureScaleMul=0.1f,
01611 int initXyStep=6, int initImgBound=0, bool varyXyStepWithScale=true, bool varyImgBoundWithScale=false );
01612 float initFeatureScale;
01613 int featureScaleLevels;
01614 float featureScaleMul;
01615
01616 int initXyStep;
01617 int initImgBound;
01618
01619 bool varyXyStepWithScale;
01620 bool varyImgBoundWithScale;
01621 };
01622
01623 DenseFeatureDetector( const DenseFeatureDetector::Params& params=DenseFeatureDetector::Params() );
01624
01625
01626
01627 protected:
01628 virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
01629
01630 Params params;
01631 };
01632
01633
01634
01635
01636
01637 class CV_EXPORTS GridAdaptedFeatureDetector : public FeatureDetector
01638 {
01639 public:
01640
01641
01642
01643
01644
01645
01646
01647 GridAdaptedFeatureDetector( const Ptr<FeatureDetector>& detector, int maxTotalKeypoints=1000,
01648 int gridRows=4, int gridCols=4 );
01649
01650
01651 virtual bool empty() const;
01652
01653 protected:
01654 virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
01655
01656 Ptr<FeatureDetector> detector;
01657 int maxTotalKeypoints;
01658 int gridRows;
01659 int gridCols;
01660 };
01661
01662
01663
01664
01665
01666 class CV_EXPORTS PyramidAdaptedFeatureDetector : public FeatureDetector
01667 {
01668 public:
01669
01670 PyramidAdaptedFeatureDetector( const Ptr<FeatureDetector>& detector, int maxLevel=2 );
01671
01672
01673 virtual bool empty() const;
01674
01675 protected:
01676 virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
01677
01678 Ptr<FeatureDetector> detector;
01679 int maxLevel;
01680 };
01681
01685 class CV_EXPORTS AdjusterAdapter: public FeatureDetector
01686 {
01687 public:
01690 virtual ~AdjusterAdapter() {}
01695 virtual void tooFew(int min, int n_detected) = 0;
01700 virtual void tooMany(int max, int n_detected) = 0;
01704 virtual bool good() const = 0;
01705
01706 virtual Ptr<AdjusterAdapter> clone() const = 0;
01707
01708 static Ptr<AdjusterAdapter> create( const string& detectorType );
01709 };
01722 class CV_EXPORTS DynamicAdaptedFeatureDetector: public FeatureDetector
01723 {
01724 public:
01725
01732 DynamicAdaptedFeatureDetector( const Ptr<AdjusterAdapter>& adjaster, int min_features=400, int max_features=500, int max_iters=5 );
01733
01734 virtual bool empty() const;
01735
01736 protected:
01737 virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
01738
01739 private:
01740 DynamicAdaptedFeatureDetector& operator=(const DynamicAdaptedFeatureDetector&);
01741 DynamicAdaptedFeatureDetector(const DynamicAdaptedFeatureDetector&);
01742
01743 int escape_iters_;
01744 int min_features_, max_features_;
01745 const Ptr<AdjusterAdapter> adjuster_;
01746 };
01747
01751 class CV_EXPORTS FastAdjuster: public AdjusterAdapter
01752 {
01753 public:
01757 FastAdjuster(int init_thresh=20, bool nonmax=true, int min_thresh=1, int max_thresh=200);
01758
01759 virtual void tooFew(int min, int n_detected);
01760 virtual void tooMany(int max, int n_detected);
01761 virtual bool good() const;
01762
01763 virtual Ptr<AdjusterAdapter> clone() const;
01764
01765 protected:
01766 virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
01767
01768 int thresh_;
01769 bool nonmax_;
01770 int init_thresh_, min_thresh_, max_thresh_;
01771 };
01772
01773
01777 class CV_EXPORTS StarAdjuster: public AdjusterAdapter
01778 {
01779 public:
01780 StarAdjuster(double initial_thresh=30.0, double min_thresh=2., double max_thresh=200.);
01781
01782 virtual void tooFew(int min, int n_detected);
01783 virtual void tooMany(int max, int n_detected);
01784 virtual bool good() const;
01785
01786 virtual Ptr<AdjusterAdapter> clone() const;
01787
01788 protected:
01789 virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
01790
01791 double thresh_, init_thresh_, min_thresh_, max_thresh_;
01792 CvStarDetectorParams params_;
01793 };
01794
01795 class CV_EXPORTS SurfAdjuster: public AdjusterAdapter
01796 {
01797 public:
01798 SurfAdjuster( double initial_thresh=400.f, double min_thresh=2, double max_thresh=1000 );
01799
01800 virtual void tooFew(int min, int n_detected);
01801 virtual void tooMany(int max, int n_detected);
01802 virtual bool good() const;
01803
01804 virtual Ptr<AdjusterAdapter> clone() const;
01805
01806 protected:
01807 virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
01808
01809 double thresh_, init_thresh_, min_thresh_, max_thresh_;
01810 };
01811
01812 CV_EXPORTS Mat windowedMatchingMask( const vector<KeyPoint>& keypoints1, const vector<KeyPoint>& keypoints2,
01813 float maxDeltaX, float maxDeltaY );
01814
01815
01816
01817
01818
01819
01820
01821
01822
01823
01824
01825
01826
01827
01828 class CV_EXPORTS DescriptorExtractor
01829 {
01830 public:
01831 virtual ~DescriptorExtractor();
01832
01833
01834
01835
01836
01837
01838
01839 void compute( const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors ) const;
01840
01841
01842
01843
01844
01845
01846
01847
01848 void compute( const vector<Mat>& images, vector<vector<KeyPoint> >& keypoints, vector<Mat>& descriptors ) const;
01849
01850 virtual void read( const FileNode& );
01851 virtual void write( FileStorage& ) const;
01852
01853 virtual int descriptorSize() const = 0;
01854 virtual int descriptorType() const = 0;
01855
01856 virtual bool empty() const;
01857
01858 static Ptr<DescriptorExtractor> create( const string& descriptorExtractorType );
01859
01860 protected:
01861 virtual void computeImpl( const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors ) const = 0;
01862
01863
01864
01865
01866 static void removeBorderKeypoints( vector<KeyPoint>& keypoints,
01867 Size imageSize, int borderSize );
01868 };
01869
01870
01871
01872
01873 class CV_EXPORTS SiftDescriptorExtractor : public DescriptorExtractor
01874 {
01875 public:
01876 SiftDescriptorExtractor( const SIFT::DescriptorParams& descriptorParams=SIFT::DescriptorParams(),
01877 const SIFT::CommonParams& commonParams=SIFT::CommonParams() );
01878 SiftDescriptorExtractor( double magnification, bool isNormalize=true, bool recalculateAngles=true,
01879 int nOctaves=SIFT::CommonParams::DEFAULT_NOCTAVES,
01880 int nOctaveLayers=SIFT::CommonParams::DEFAULT_NOCTAVE_LAYERS,
01881 int firstOctave=SIFT::CommonParams::DEFAULT_FIRST_OCTAVE,
01882 int angleMode=SIFT::CommonParams::FIRST_ANGLE );
01883
01884 virtual void read( const FileNode &fn );
01885 virtual void write( FileStorage &fs ) const;
01886
01887 virtual int descriptorSize() const;
01888 virtual int descriptorType() const;
01889
01890 protected:
01891 virtual void computeImpl( const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors ) const;
01892
01893 SIFT sift;
01894 };
01895
01896
01897
01898
01899 class CV_EXPORTS SurfDescriptorExtractor : public DescriptorExtractor
01900 {
01901 public:
01902 SurfDescriptorExtractor( int nOctaves=4, int nOctaveLayers=2, bool extended=false, bool upright=false );
01903
01904 virtual void read( const FileNode &fn );
01905 virtual void write( FileStorage &fs ) const;
01906
01907 virtual int descriptorSize() const;
01908 virtual int descriptorType() const;
01909
01910 protected:
01911 virtual void computeImpl( const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors ) const;
01912
01913 SURF surf;
01914 };
01915
01922 class OrbDescriptorExtractor : public cv::DescriptorExtractor
01923 {
01924 public:
01928 OrbDescriptorExtractor(ORB::CommonParams params = ORB::CommonParams());
01929
01931 ~OrbDescriptorExtractor()
01932 {
01933 }
01934
01935 virtual int descriptorSize() const;
01936 virtual int descriptorType() const;
01937
01938 virtual void read(const cv::FileNode&);
01939 virtual void write(cv::FileStorage&) const;
01940
01941 protected:
01942 void computeImpl(const cv::Mat& image, std::vector<cv::KeyPoint>& keypoints, cv::Mat& descriptors) const;
01943 private:
01945 mutable ORB orb_;
01947 ORB::CommonParams params_;
01948 };
01949
01950
01951
01952
01953 template<typename T>
01954 class CV_EXPORTS CalonderDescriptorExtractor : public DescriptorExtractor
01955 {
01956 public:
01957 CalonderDescriptorExtractor( const string& classifierFile );
01958
01959 virtual void read( const FileNode &fn );
01960 virtual void write( FileStorage &fs ) const;
01961
01962 virtual int descriptorSize() const { return classifier_.classes(); }
01963 virtual int descriptorType() const { return DataType<T>::type; }
01964
01965 virtual bool empty() const;
01966
01967 protected:
01968 virtual void computeImpl( const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors ) const;
01969
01970 RTreeClassifier classifier_;
01971 static const int BORDER_SIZE = 16;
01972 };
01973
01974 template<typename T>
01975 CalonderDescriptorExtractor<T>::CalonderDescriptorExtractor(const std::string& classifier_file)
01976 {
01977 classifier_.read( classifier_file.c_str() );
01978 }
01979
01980 template<typename T>
01981 void CalonderDescriptorExtractor<T>::computeImpl( const cv::Mat& image,
01982 std::vector<cv::KeyPoint>& keypoints,
01983 cv::Mat& descriptors) const
01984 {
01985
01986 KeyPointsFilter::runByImageBorder(keypoints, image.size(), BORDER_SIZE);
01987
01989 descriptors.create(keypoints.size(), classifier_.classes(), cv::DataType<T>::type);
01990
01991 int patchSize = RandomizedTree::PATCH_SIZE;
01992 int offset = patchSize / 2;
01993 for (size_t i = 0; i < keypoints.size(); ++i)
01994 {
01995 cv::Point2f pt = keypoints[i].pt;
01996 IplImage ipl = image( Rect((int)(pt.x - offset), (int)(pt.y - offset), patchSize, patchSize) );
01997 classifier_.getSignature( &ipl, descriptors.ptr<T>(i));
01998 }
01999 }
02000
02001 template<typename T>
02002 void CalonderDescriptorExtractor<T>::read( const FileNode& )
02003 {}
02004
02005 template<typename T>
02006 void CalonderDescriptorExtractor<T>::write( FileStorage& ) const
02007 {}
02008
02009 template<typename T>
02010 bool CalonderDescriptorExtractor<T>::empty() const
02011 {
02012 return classifier_.trees_.empty();
02013 }
02014
02015
02016
02017
02018
02019
02020
02021
02022
02023
02024 class CV_EXPORTS OpponentColorDescriptorExtractor : public DescriptorExtractor
02025 {
02026 public:
02027 OpponentColorDescriptorExtractor( const Ptr<DescriptorExtractor>& descriptorExtractor );
02028
02029 virtual void read( const FileNode& );
02030 virtual void write( FileStorage& ) const;
02031
02032 virtual int descriptorSize() const;
02033 virtual int descriptorType() const;
02034
02035 virtual bool empty() const;
02036
02037 protected:
02038 virtual void computeImpl( const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors ) const;
02039
02040 Ptr<DescriptorExtractor> descriptorExtractor;
02041 };
02042
02043
02044
02045
02046 class CV_EXPORTS BriefDescriptorExtractor : public DescriptorExtractor
02047 {
02048 public:
02049 static const int PATCH_SIZE = 48;
02050 static const int KERNEL_SIZE = 9;
02051
02052
02053 BriefDescriptorExtractor( int bytes = 32 );
02054
02055 virtual int descriptorSize() const;
02056 virtual int descriptorType() const;
02057
02059
02060 protected:
02061 virtual void computeImpl(const Mat& image, std::vector<KeyPoint>& keypoints, Mat& descriptors) const;
02062
02063 typedef void(*PixelTestFn)(const Mat&, const std::vector<KeyPoint>&, Mat&);
02064
02065 int bytes_;
02066 PixelTestFn test_fn_;
02067 };
02068
02069
02070
02071
02072 template<typename T>
02073 struct CV_EXPORTS Accumulator
02074 {
02075 typedef T Type;
02076 };
02077
02078 template<> struct Accumulator<unsigned char> { typedef float Type; };
02079 template<> struct Accumulator<unsigned short> { typedef float Type; };
02080 template<> struct Accumulator<char> { typedef float Type; };
02081 template<> struct Accumulator<short> { typedef float Type; };
02082
02083
02084
02085
02086 template<class T>
02087 struct CV_EXPORTS L2
02088 {
02089 typedef T ValueType;
02090 typedef typename Accumulator<T>::Type ResultType;
02091
02092 ResultType operator()( const T* a, const T* b, int size ) const
02093 {
02094 ResultType result = ResultType();
02095 for( int i = 0; i < size; i++ )
02096 {
02097 ResultType diff = (ResultType)(a[i] - b[i]);
02098 result += diff*diff;
02099 }
02100 return (ResultType)sqrt((double)result);
02101 }
02102 };
02103
02104
02105
02106
02107 template<class T>
02108 struct CV_EXPORTS L1
02109 {
02110 typedef T ValueType;
02111 typedef typename Accumulator<T>::Type ResultType;
02112
02113 ResultType operator()( const T* a, const T* b, int size ) const
02114 {
02115 ResultType result = ResultType();
02116 for( int i = 0; i < size; i++ )
02117 {
02118 ResultType diff = a[i] - b[i];
02119 result += (ResultType)fabs( diff );
02120 }
02121 return result;
02122 }
02123 };
02124
02125
02126
02127
02128
02129 struct CV_EXPORTS HammingLUT
02130 {
02131 typedef unsigned char ValueType;
02132 typedef int ResultType;
02133
02136 ResultType operator()( const unsigned char* a, const unsigned char* b, int size ) const;
02137
02143 static unsigned char byteBitsLookUp(unsigned char b);
02144 };
02145
02146
02150 struct CV_EXPORTS Hamming
02151 {
02152 typedef unsigned char ValueType;
02153
02155
02156 typedef int ResultType;
02157
02160 ResultType operator()(const unsigned char* a, const unsigned char* b, int size) const;
02161 };
02162
02163
02164
02165
02166
02167
02168
02169
02170 struct CV_EXPORTS DMatch
02171 {
02172 DMatch() : queryIdx(-1), trainIdx(-1), imgIdx(-1), distance(std::numeric_limits<float>::max()) {}
02173 DMatch( int _queryIdx, int _trainIdx, float _distance ) :
02174 queryIdx(_queryIdx), trainIdx(_trainIdx), imgIdx(-1), distance(_distance) {}
02175 DMatch( int _queryIdx, int _trainIdx, int _imgIdx, float _distance ) :
02176 queryIdx(_queryIdx), trainIdx(_trainIdx), imgIdx(_imgIdx), distance(_distance) {}
02177
02178 int queryIdx;
02179 int trainIdx;
02180 int imgIdx;
02181
02182 float distance;
02183
02184
02185 bool operator<( const DMatch &m ) const
02186 {
02187 return distance < m.distance;
02188 }
02189 };
02190
02191
02192
02193
02194
02195
02196
02197 class CV_EXPORTS DescriptorMatcher
02198 {
02199 public:
02200 virtual ~DescriptorMatcher();
02201
02202
02203
02204
02205
02206 virtual void add( const vector<Mat>& descriptors );
02207
02208
02209
02210 const vector<Mat>& getTrainDescriptors() const;
02211
02212
02213
02214 virtual void clear();
02215
02216
02217
02218
02219 virtual bool empty() const;
02220
02221
02222
02223 virtual bool isMaskSupported() const = 0;
02224
02225
02226
02227
02228
02229
02230
02231
02232
02233
02234
02235
02236 virtual void train();
02237
02238
02239
02240
02241
02242 void match( const Mat& queryDescriptors, const Mat& trainDescriptors,
02243 vector<DMatch>& matches, const Mat& mask=Mat() ) const;
02244
02245
02246
02247
02248 void knnMatch( const Mat& queryDescriptors, const Mat& trainDescriptors,
02249 vector<vector<DMatch> >& matches, int k,
02250 const Mat& mask=Mat(), bool compactResult=false ) const;
02251
02252
02253 void radiusMatch( const Mat& queryDescriptors, const Mat& trainDescriptors,
02254 vector<vector<DMatch> >& matches, float maxDistance,
02255 const Mat& mask=Mat(), bool compactResult=false ) const;
02256
02257
02258
02259
02260 void match( const Mat& queryDescriptors, vector<DMatch>& matches,
02261 const vector<Mat>& masks=vector<Mat>() );
02262 void knnMatch( const Mat& queryDescriptors, vector<vector<DMatch> >& matches, int k,
02263 const vector<Mat>& masks=vector<Mat>(), bool compactResult=false );
02264 void radiusMatch( const Mat& queryDescriptors, vector<vector<DMatch> >& matches, float maxDistance,
02265 const vector<Mat>& masks=vector<Mat>(), bool compactResult=false );
02266
02267
02268 virtual void read( const FileNode& );
02269
02270 virtual void write( FileStorage& ) const;
02271
02272
02273
02274
02275 virtual Ptr<DescriptorMatcher> clone( bool emptyTrainData=false ) const = 0;
02276
02277 static Ptr<DescriptorMatcher> create( const string& descriptorMatcherType );
02278 protected:
02279
02280
02281
02282
02283 class CV_EXPORTS DescriptorCollection
02284 {
02285 public:
02286 DescriptorCollection();
02287 DescriptorCollection( const DescriptorCollection& collection );
02288 virtual ~DescriptorCollection();
02289
02290
02291 void set( const vector<Mat>& descriptors );
02292 virtual void clear();
02293
02294 const Mat& getDescriptors() const;
02295 const Mat getDescriptor( int imgIdx, int localDescIdx ) const;
02296 const Mat getDescriptor( int globalDescIdx ) const;
02297 void getLocalIdx( int globalDescIdx, int& imgIdx, int& localDescIdx ) const;
02298
02299 int size() const;
02300
02301 protected:
02302 Mat mergedDescriptors;
02303 vector<int> startIdxs;
02304 };
02305
02306
02307
02308
02309 virtual void knnMatchImpl( const Mat& queryDescriptors, vector<vector<DMatch> >& matches, int k,
02310 const vector<Mat>& masks=vector<Mat>(), bool compactResult=false ) = 0;
02311 virtual void radiusMatchImpl( const Mat& queryDescriptors, vector<vector<DMatch> >& matches, float maxDistance,
02312 const vector<Mat>& masks=vector<Mat>(), bool compactResult=false ) = 0;
02313
02314 static bool isPossibleMatch( const Mat& mask, int queryIdx, int trainIdx );
02315 static bool isMaskedOut( const vector<Mat>& masks, int queryIdx );
02316
02317 static Mat clone_op( Mat m ) { return m.clone(); }
02318 void checkMasks( const vector<Mat>& masks, int queryDescriptorsCount ) const;
02319
02320
02321 vector<Mat> trainDescCollection;
02322 };
02323
02324
02325
02326
02327
02328
02329
02330
02331
02332
02333 template<class Distance>
02334 class CV_EXPORTS BruteForceMatcher : public DescriptorMatcher
02335 {
02336 public:
02337 BruteForceMatcher( Distance d = Distance() ) : distance(d) {}
02338 virtual ~BruteForceMatcher() {}
02339
02340 virtual bool isMaskSupported() const { return true; }
02341
02342 virtual Ptr<DescriptorMatcher> clone( bool emptyTrainData=false ) const;
02343
02344 protected:
02345 virtual void knnMatchImpl( const Mat& queryDescriptors, vector<vector<DMatch> >& matches, int k,
02346 const vector<Mat>& masks=vector<Mat>(), bool compactResult=false );
02347 virtual void radiusMatchImpl( const Mat& queryDescriptors, vector<vector<DMatch> >& matches, float maxDistance,
02348 const vector<Mat>& masks=vector<Mat>(), bool compactResult=false );
02349
02350 Distance distance;
02351
02352 private:
02353
02354
02355
02356 static void commonKnnMatchImpl( BruteForceMatcher<Distance>& matcher,
02357 const Mat& queryDescriptors, vector<vector<DMatch> >& matches, int k,
02358 const vector<Mat>& masks, bool compactResult );
02359 static void commonRadiusMatchImpl( BruteForceMatcher<Distance>& matcher,
02360 const Mat& queryDescriptors, vector<vector<DMatch> >& matches, float maxDistance,
02361 const vector<Mat>& masks, bool compactResult );
02362 };
02363
02364 template<class Distance>
02365 Ptr<DescriptorMatcher> BruteForceMatcher<Distance>::clone( bool emptyTrainData ) const
02366 {
02367 BruteForceMatcher* matcher = new BruteForceMatcher(distance);
02368 if( !emptyTrainData )
02369 {
02370 std::transform( trainDescCollection.begin(), trainDescCollection.end(),
02371 matcher->trainDescCollection.begin(), clone_op );
02372 }
02373 return matcher;
02374 }
02375
02376 template<class Distance>
02377 void BruteForceMatcher<Distance>::knnMatchImpl( const Mat& queryDescriptors, vector<vector<DMatch> >& matches, int k,
02378 const vector<Mat>& masks, bool compactResult )
02379 {
02380 commonKnnMatchImpl( *this, queryDescriptors, matches, k, masks, compactResult );
02381 }
02382
02383 template<class Distance>
02384 void BruteForceMatcher<Distance>::radiusMatchImpl( const Mat& queryDescriptors, vector<vector<DMatch> >& matches,
02385 float maxDistance, const vector<Mat>& masks, bool compactResult )
02386 {
02387 commonRadiusMatchImpl( *this, queryDescriptors, matches, maxDistance, masks, compactResult );
02388 }
02389
02390 template<class Distance>
02391 inline void BruteForceMatcher<Distance>::commonKnnMatchImpl( BruteForceMatcher<Distance>& matcher,
02392 const Mat& queryDescriptors, vector<vector<DMatch> >& matches, int knn,
02393 const vector<Mat>& masks, bool compactResult )
02394 {
02395 typedef typename Distance::ValueType ValueType;
02396 typedef typename Distance::ResultType DistanceType;
02397 CV_DbgAssert( !queryDescriptors.empty() );
02398 CV_Assert( DataType<ValueType>::type == queryDescriptors.type() );
02399
02400 int dimension = queryDescriptors.cols;
02401 matches.reserve(queryDescriptors.rows);
02402
02403 size_t imgCount = matcher.trainDescCollection.size();
02404 vector<Mat> allDists( imgCount );
02405 for( size_t i = 0; i < imgCount; i++ )
02406 allDists[i] = Mat( 1, matcher.trainDescCollection[i].rows, DataType<DistanceType>::type );
02407
02408 for( int qIdx = 0; qIdx < queryDescriptors.rows; qIdx++ )
02409 {
02410 if( matcher.isMaskedOut( masks, qIdx ) )
02411 {
02412 if( !compactResult )
02413 matches.push_back( vector<DMatch>() );
02414 }
02415 else
02416 {
02417
02418 for( size_t iIdx = 0; iIdx < imgCount; iIdx++ )
02419 {
02420 CV_Assert( DataType<ValueType>::type == matcher.trainDescCollection[iIdx].type() || matcher.trainDescCollection[iIdx].empty() );
02421 CV_Assert( queryDescriptors.cols == matcher.trainDescCollection[iIdx].cols ||
02422 matcher.trainDescCollection[iIdx].empty() );
02423
02424 const ValueType* d1 = (const ValueType*)(queryDescriptors.data + queryDescriptors.step*qIdx);
02425 allDists[iIdx].setTo( Scalar::all(std::numeric_limits<DistanceType>::max()) );
02426 for( int tIdx = 0; tIdx < matcher.trainDescCollection[iIdx].rows; tIdx++ )
02427 {
02428 if( masks.empty() || matcher.isPossibleMatch(masks[iIdx], qIdx, tIdx) )
02429 {
02430 const ValueType* d2 = (const ValueType*)(matcher.trainDescCollection[iIdx].data +
02431 matcher.trainDescCollection[iIdx].step*tIdx);
02432 allDists[iIdx].at<DistanceType>(0, tIdx) = matcher.distance(d1, d2, dimension);
02433 }
02434 }
02435 }
02436
02437
02438 matches.push_back( vector<DMatch>() );
02439 vector<vector<DMatch> >::reverse_iterator curMatches = matches.rbegin();
02440 for( int k = 0; k < knn; k++ )
02441 {
02442 DMatch bestMatch;
02443 bestMatch.distance = std::numeric_limits<float>::max();
02444 for( size_t iIdx = 0; iIdx < imgCount; iIdx++ )
02445 {
02446 if( !allDists[iIdx].empty() )
02447 {
02448 double minVal;
02449 Point minLoc;
02450 minMaxLoc( allDists[iIdx], &minVal, 0, &minLoc, 0 );
02451 if( minVal < bestMatch.distance )
02452 bestMatch = DMatch( qIdx, minLoc.x, (int)iIdx, (float)minVal );
02453 }
02454 }
02455 if( bestMatch.trainIdx == -1 )
02456 break;
02457
02458 allDists[bestMatch.imgIdx].at<DistanceType>(0, bestMatch.trainIdx) = std::numeric_limits<DistanceType>::max();
02459 curMatches->push_back( bestMatch );
02460 }
02461
02462 std::sort( curMatches->begin(), curMatches->end() );
02463 }
02464 }
02465 }
02466
02467 template<class Distance>
02468 inline void BruteForceMatcher<Distance>::commonRadiusMatchImpl( BruteForceMatcher<Distance>& matcher,
02469 const Mat& queryDescriptors, vector<vector<DMatch> >& matches, float maxDistance,
02470 const vector<Mat>& masks, bool compactResult )
02471 {
02472 typedef typename Distance::ValueType ValueType;
02473 typedef typename Distance::ResultType DistanceType;
02474 CV_DbgAssert( !queryDescriptors.empty() );
02475 CV_Assert( DataType<ValueType>::type == queryDescriptors.type() );
02476
02477 int dimension = queryDescriptors.cols;
02478 matches.reserve(queryDescriptors.rows);
02479
02480 size_t imgCount = matcher.trainDescCollection.size();
02481 for( int qIdx = 0; qIdx < queryDescriptors.rows; qIdx++ )
02482 {
02483 if( matcher.isMaskedOut( masks, qIdx ) )
02484 {
02485 if( !compactResult )
02486 matches.push_back( vector<DMatch>() );
02487 }
02488 else
02489 {
02490 matches.push_back( vector<DMatch>() );
02491 vector<vector<DMatch> >::reverse_iterator curMatches = matches.rbegin();
02492 for( size_t iIdx = 0; iIdx < imgCount; iIdx++ )
02493 {
02494 CV_Assert( DataType<ValueType>::type == matcher.trainDescCollection[iIdx].type() ||
02495 matcher.trainDescCollection[iIdx].empty() );
02496 CV_Assert( queryDescriptors.cols == matcher.trainDescCollection[iIdx].cols ||
02497 matcher.trainDescCollection[iIdx].empty() );
02498
02499 const ValueType* d1 = (const ValueType*)(queryDescriptors.data + queryDescriptors.step*qIdx);
02500 for( int tIdx = 0; tIdx < matcher.trainDescCollection[iIdx].rows; tIdx++ )
02501 {
02502 if( masks.empty() || matcher.isPossibleMatch(masks[iIdx], qIdx, tIdx) )
02503 {
02504 const ValueType* d2 = (const ValueType*)(matcher.trainDescCollection[iIdx].data +
02505 matcher.trainDescCollection[iIdx].step*tIdx);
02506 DistanceType d = matcher.distance(d1, d2, dimension);
02507 if( d < maxDistance )
02508 curMatches->push_back( DMatch( qIdx, tIdx, (int)iIdx, (float)d ) );
02509 }
02510 }
02511 }
02512 std::sort( curMatches->begin(), curMatches->end() );
02513 }
02514 }
02515 }
02516
02517
02518
02519
02520 template<>
02521 void BruteForceMatcher<L2<float> >::knnMatchImpl( const Mat& queryDescriptors, vector<vector<DMatch> >& matches, int k,
02522 const vector<Mat>& masks, bool compactResult );
02523 template<>
02524 void BruteForceMatcher<L2<float> >::radiusMatchImpl( const Mat& queryDescriptors, vector<vector<DMatch> >& matches,
02525 float maxDistance, const vector<Mat>& masks, bool compactResult );
02526
02527
02528
02529
02530 class CV_EXPORTS FlannBasedMatcher : public DescriptorMatcher
02531 {
02532 public:
02533 FlannBasedMatcher( const Ptr<flann::IndexParams>& indexParams=new flann::KDTreeIndexParams(),
02534 const Ptr<flann::SearchParams>& searchParams=new flann::SearchParams() );
02535
02536 virtual void add( const vector<Mat>& descriptors );
02537 virtual void clear();
02538
02539 virtual void train();
02540 virtual bool isMaskSupported() const;
02541
02542 virtual Ptr<DescriptorMatcher> clone( bool emptyTrainData=false ) const;
02543
02544 protected:
02545 static void convertToDMatches( const DescriptorCollection& descriptors,
02546 const Mat& indices, const Mat& distances,
02547 vector<vector<DMatch> >& matches );
02548
02549 virtual void knnMatchImpl( const Mat& queryDescriptors, vector<vector<DMatch> >& matches, int k,
02550 const vector<Mat>& masks=vector<Mat>(), bool compactResult=false );
02551 virtual void radiusMatchImpl( const Mat& queryDescriptors, vector<vector<DMatch> >& matches, float maxDistance,
02552 const vector<Mat>& masks=vector<Mat>(), bool compactResult=false );
02553
02554 Ptr<flann::IndexParams> indexParams;
02555 Ptr<flann::SearchParams> searchParams;
02556 Ptr<flann::Index> flannIndex;
02557
02558 DescriptorCollection mergedDescriptors;
02559 int addedDescCount;
02560 };
02561
02562
02563
02564
02565
02566
02567
02568 class GenericDescriptorMatcher;
02569 typedef GenericDescriptorMatcher GenericDescriptorMatch;
02570
02571 class CV_EXPORTS GenericDescriptorMatcher
02572 {
02573 public:
02574 GenericDescriptorMatcher();
02575 virtual ~GenericDescriptorMatcher();
02576
02577
02578
02579
02580
02581
02582
02583
02584
02585
02586
02587 virtual void add( const vector<Mat>& images,
02588 vector<vector<KeyPoint> >& keypoints );
02589
02590 const vector<Mat>& getTrainImages() const;
02591 const vector<vector<KeyPoint> >& getTrainKeypoints() const;
02592
02593
02594
02595
02596 virtual void clear();
02597
02598
02599
02600 virtual bool isMaskSupported() = 0;
02601
02602
02603
02604
02605
02606 virtual void train();
02607
02608
02609
02610
02611
02612
02613
02614
02615
02616 void classify( const Mat& queryImage, vector<KeyPoint>& queryKeypoints,
02617 const Mat& trainImage, vector<KeyPoint>& trainKeypoints ) const;
02618
02619 void classify( const Mat& queryImage, vector<KeyPoint>& queryKeypoints );
02620
02621
02622
02623
02624
02625
02626
02627 void match( const Mat& queryImage, vector<KeyPoint>& queryKeypoints,
02628 const Mat& trainImage, vector<KeyPoint>& trainKeypoints,
02629 vector<DMatch>& matches, const Mat& mask=Mat() ) const;
02630
02631
02632
02633
02634 void knnMatch( const Mat& queryImage, vector<KeyPoint>& queryKeypoints,
02635 const Mat& trainImage, vector<KeyPoint>& trainKeypoints,
02636 vector<vector<DMatch> >& matches, int k,
02637 const Mat& mask=Mat(), bool compactResult=false ) const;
02638
02639 void radiusMatch( const Mat& queryImage, vector<KeyPoint>& queryKeypoints,
02640 const Mat& trainImage, vector<KeyPoint>& trainKeypoints,
02641 vector<vector<DMatch> >& matches, float maxDistance,
02642 const Mat& mask=Mat(), bool compactResult=false ) const;
02643
02644
02645
02646
02647 void match( const Mat& queryImage, vector<KeyPoint>& queryKeypoints,
02648 vector<DMatch>& matches, const vector<Mat>& masks=vector<Mat>() );
02649 void knnMatch( const Mat& queryImage, vector<KeyPoint>& queryKeypoints,
02650 vector<vector<DMatch> >& matches, int k,
02651 const vector<Mat>& masks=vector<Mat>(), bool compactResult=false );
02652 void radiusMatch( const Mat& queryImage, vector<KeyPoint>& queryKeypoints,
02653 vector<vector<DMatch> >& matches, float maxDistance,
02654 const vector<Mat>& masks=vector<Mat>(), bool compactResult=false );
02655
02656
02657 virtual void read( const FileNode& );
02658
02659 virtual void write( FileStorage& ) const;
02660
02661
02662 virtual bool empty() const;
02663
02664
02665
02666
02667 virtual Ptr<GenericDescriptorMatcher> clone( bool emptyTrainData=false ) const = 0;
02668
02669 static Ptr<GenericDescriptorMatcher> create( const string& genericDescritptorMatcherType,
02670 const string ¶msFilename=string() );
02671
02672 protected:
02673
02674
02675
02676 virtual void knnMatchImpl( const Mat& queryImage, vector<KeyPoint>& queryKeypoints,
02677 vector<vector<DMatch> >& matches, int k,
02678 const vector<Mat>& masks, bool compactResult ) = 0;
02679 virtual void radiusMatchImpl( const Mat& queryImage, vector<KeyPoint>& queryKeypoints,
02680 vector<vector<DMatch> >& matches, float maxDistance,
02681 const vector<Mat>& masks, bool compactResult ) = 0;
02682
02683
02684
02685 class CV_EXPORTS KeyPointCollection
02686 {
02687 public:
02688 KeyPointCollection();
02689 KeyPointCollection( const KeyPointCollection& collection );
02690 void add( const vector<Mat>& images, const vector<vector<KeyPoint> >& keypoints );
02691 void clear();
02692
02693
02694 size_t keypointCount() const;
02695 size_t imageCount() const;
02696
02697 const vector<vector<KeyPoint> >& getKeypoints() const;
02698 const vector<KeyPoint>& getKeypoints( int imgIdx ) const;
02699 const KeyPoint& getKeyPoint( int imgIdx, int localPointIdx ) const;
02700 const KeyPoint& getKeyPoint( int globalPointIdx ) const;
02701 void getLocalIdx( int globalPointIdx, int& imgIdx, int& localPointIdx ) const;
02702
02703 const vector<Mat>& getImages() const;
02704 const Mat& getImage( int imgIdx ) const;
02705
02706 protected:
02707 int pointCount;
02708
02709 vector<Mat> images;
02710 vector<vector<KeyPoint> > keypoints;
02711
02712 vector<int> startIndices;
02713
02714 private:
02715 static Mat clone_op( Mat m ) { return m.clone(); }
02716 };
02717
02718 KeyPointCollection trainPointCollection;
02719 };
02720
02721
02722
02723
02724 class OneWayDescriptorMatcher;
02725 typedef OneWayDescriptorMatcher OneWayDescriptorMatch;
02726
02727 class CV_EXPORTS OneWayDescriptorMatcher : public GenericDescriptorMatcher
02728 {
02729 public:
02730 class CV_EXPORTS Params
02731 {
02732 public:
02733 static const int POSE_COUNT = 500;
02734 static const int PATCH_WIDTH = 24;
02735 static const int PATCH_HEIGHT = 24;
02736 static float GET_MIN_SCALE() { return 0.7f; }
02737 static float GET_MAX_SCALE() { return 1.5f; }
02738 static float GET_STEP_SCALE() { return 1.2f; }
02739
02740 Params( int poseCount = POSE_COUNT,
02741 Size patchSize = Size(PATCH_WIDTH, PATCH_HEIGHT),
02742 string pcaFilename = string(),
02743 string trainPath = string(), string trainImagesList = string(),
02744 float minScale = GET_MIN_SCALE(), float maxScale = GET_MAX_SCALE(),
02745 float stepScale = GET_STEP_SCALE() );
02746
02747 int poseCount;
02748 Size patchSize;
02749 string pcaFilename;
02750 string trainPath;
02751 string trainImagesList;
02752
02753 float minScale, maxScale, stepScale;
02754 };
02755
02756 OneWayDescriptorMatcher( const Params& params=Params() );
02757 virtual ~OneWayDescriptorMatcher();
02758
02759 void initialize( const Params& params, const Ptr<OneWayDescriptorBase>& base=Ptr<OneWayDescriptorBase>() );
02760
02761
02762 virtual void clear();
02763
02764 virtual void train();
02765
02766 virtual bool isMaskSupported();
02767
02768 virtual void read( const FileNode &fn );
02769 virtual void write( FileStorage& fs ) const;
02770
02771 virtual bool empty() const;
02772
02773 virtual Ptr<GenericDescriptorMatcher> clone( bool emptyTrainData=false ) const;
02774
02775 protected:
02776
02777
02778
02779
02780
02781
02782 virtual void knnMatchImpl( const Mat& queryImage, vector<KeyPoint>& queryKeypoints,
02783 vector<vector<DMatch> >& matches, int k,
02784 const vector<Mat>& masks, bool compactResult );
02785 virtual void radiusMatchImpl( const Mat& queryImage, vector<KeyPoint>& queryKeypoints,
02786 vector<vector<DMatch> >& matches, float maxDistance,
02787 const vector<Mat>& masks, bool compactResult );
02788
02789 Ptr<OneWayDescriptorBase> base;
02790 Params params;
02791 int prevTrainCount;
02792 };
02793
02794
02795
02796
02797 class FernDescriptorMatcher;
02798 typedef FernDescriptorMatcher FernDescriptorMatch;
02799
02800 class CV_EXPORTS FernDescriptorMatcher : public GenericDescriptorMatcher
02801 {
02802 public:
02803 class CV_EXPORTS Params
02804 {
02805 public:
02806 Params( int nclasses=0,
02807 int patchSize=FernClassifier::PATCH_SIZE,
02808 int signatureSize=FernClassifier::DEFAULT_SIGNATURE_SIZE,
02809 int nstructs=FernClassifier::DEFAULT_STRUCTS,
02810 int structSize=FernClassifier::DEFAULT_STRUCT_SIZE,
02811 int nviews=FernClassifier::DEFAULT_VIEWS,
02812 int compressionMethod=FernClassifier::COMPRESSION_NONE,
02813 const PatchGenerator& patchGenerator=PatchGenerator() );
02814
02815 Params( const string& filename );
02816
02817 int nclasses;
02818 int patchSize;
02819 int signatureSize;
02820 int nstructs;
02821 int structSize;
02822 int nviews;
02823 int compressionMethod;
02824 PatchGenerator patchGenerator;
02825
02826 string filename;
02827 };
02828
02829 FernDescriptorMatcher( const Params& params=Params() );
02830 virtual ~FernDescriptorMatcher();
02831
02832 virtual void clear();
02833
02834 virtual void train();
02835
02836 virtual bool isMaskSupported();
02837
02838 virtual void read( const FileNode &fn );
02839 virtual void write( FileStorage& fs ) const;
02840 virtual bool empty() const;
02841
02842 virtual Ptr<GenericDescriptorMatcher> clone( bool emptyTrainData=false ) const;
02843
02844 protected:
02845 virtual void knnMatchImpl( const Mat& queryImage, vector<KeyPoint>& queryKeypoints,
02846 vector<vector<DMatch> >& matches, int k,
02847 const vector<Mat>& masks, bool compactResult );
02848 virtual void radiusMatchImpl( const Mat& queryImage, vector<KeyPoint>& queryKeypoints,
02849 vector<vector<DMatch> >& matches, float maxDistance,
02850 const vector<Mat>& masks, bool compactResult );
02851
02852 void trainFernClassifier();
02853 void calcBestProbAndMatchIdx( const Mat& image, const Point2f& pt,
02854 float& bestProb, int& bestMatchIdx, vector<float>& signature );
02855 Ptr<FernClassifier> classifier;
02856 Params params;
02857 int prevTrainCount;
02858 };
02859
02860
02861
02862
02863
02864
02865
02866
02867 class VectorDescriptorMatcher;
02868 typedef VectorDescriptorMatcher VectorDescriptorMatch;
02869
02870 class CV_EXPORTS VectorDescriptorMatcher : public GenericDescriptorMatcher
02871 {
02872 public:
02873 VectorDescriptorMatcher( const Ptr<DescriptorExtractor>& extractor, const Ptr<DescriptorMatcher>& matcher );
02874 virtual ~VectorDescriptorMatcher();
02875
02876 virtual void add( const vector<Mat>& imgCollection,
02877 vector<vector<KeyPoint> >& pointCollection );
02878
02879 virtual void clear();
02880
02881 virtual void train();
02882
02883 virtual bool isMaskSupported();
02884
02885 virtual void read( const FileNode& fn );
02886 virtual void write( FileStorage& fs ) const;
02887 virtual bool empty() const;
02888
02889 virtual Ptr<GenericDescriptorMatcher> clone( bool emptyTrainData=false ) const;
02890
02891 protected:
02892 virtual void knnMatchImpl( const Mat& queryImage, vector<KeyPoint>& queryKeypoints,
02893 vector<vector<DMatch> >& matches, int k,
02894 const vector<Mat>& masks, bool compactResult );
02895 virtual void radiusMatchImpl( const Mat& queryImage, vector<KeyPoint>& queryKeypoints,
02896 vector<vector<DMatch> >& matches, float maxDistance,
02897 const vector<Mat>& masks, bool compactResult );
02898
02899 Ptr<DescriptorExtractor> extractor;
02900 Ptr<DescriptorMatcher> matcher;
02901 };
02902
02903
02904
02905
02906 struct CV_EXPORTS DrawMatchesFlags
02907 {
02908 enum{ DEFAULT = 0,
02909
02910
02911
02912
02913 DRAW_OVER_OUTIMG = 1,
02914
02915 NOT_DRAW_SINGLE_POINTS = 2,
02916 DRAW_RICH_KEYPOINTS = 4
02917
02918 };
02919 };
02920
02921
02922 CV_EXPORTS void drawKeypoints( const Mat& image, const vector<KeyPoint>& keypoints, Mat& outImage,
02923 const Scalar& color=Scalar::all(-1), int flags=DrawMatchesFlags::DEFAULT );
02924
02925
02926 CV_EXPORTS void drawMatches( const Mat& img1, const vector<KeyPoint>& keypoints1,
02927 const Mat& img2, const vector<KeyPoint>& keypoints2,
02928 const vector<DMatch>& matches1to2, Mat& outImg,
02929 const Scalar& matchColor=Scalar::all(-1), const Scalar& singlePointColor=Scalar::all(-1),
02930 const vector<char>& matchesMask=vector<char>(), int flags=DrawMatchesFlags::DEFAULT );
02931
02932 CV_EXPORTS void drawMatches( const Mat& img1, const vector<KeyPoint>& keypoints1,
02933 const Mat& img2, const vector<KeyPoint>& keypoints2,
02934 const vector<vector<DMatch> >& matches1to2, Mat& outImg,
02935 const Scalar& matchColor=Scalar::all(-1), const Scalar& singlePointColor=Scalar::all(-1),
02936 const vector<vector<char> >& matchesMask=vector<vector<char> >(), int flags=DrawMatchesFlags::DEFAULT );
02937
02938
02939
02940
02941
02942 CV_EXPORTS void evaluateFeatureDetector( const Mat& img1, const Mat& img2, const Mat& H1to2,
02943 vector<KeyPoint>* keypoints1, vector<KeyPoint>* keypoints2,
02944 float& repeatability, int& correspCount,
02945 const Ptr<FeatureDetector>& fdetector=Ptr<FeatureDetector>() );
02946
02947 CV_EXPORTS void computeRecallPrecisionCurve( const vector<vector<DMatch> >& matches1to2,
02948 const vector<vector<uchar> >& correctMatches1to2Mask,
02949 vector<Point2f>& recallPrecisionCurve );
02950
02951 CV_EXPORTS float getRecall( const vector<Point2f>& recallPrecisionCurve, float l_precision );
02952 CV_EXPORTS int getNearestPoint( const vector<Point2f>& recallPrecisionCurve, float l_precision );
02953
02954 CV_EXPORTS void evaluateGenericDescriptorMatcher( const Mat& img1, const Mat& img2, const Mat& H1to2,
02955 vector<KeyPoint>& keypoints1, vector<KeyPoint>& keypoints2,
02956 vector<vector<DMatch> >* matches1to2, vector<vector<uchar> >* correctMatches1to2Mask,
02957 vector<Point2f>& recallPrecisionCurve,
02958 const Ptr<GenericDescriptorMatcher>& dmatch=Ptr<GenericDescriptorMatcher>() );
02959
02960
02961
02962
02963
02964
02965
02966
02967 class CV_EXPORTS BOWTrainer
02968 {
02969 public:
02970 BOWTrainer();
02971 virtual ~BOWTrainer();
02972
02973 void add( const Mat& descriptors );
02974 const vector<Mat>& getDescriptors() const;
02975 int descripotorsCount() const;
02976
02977 virtual void clear();
02978
02979
02980
02981
02982
02983
02984
02985
02986 virtual Mat cluster() const = 0;
02987 virtual Mat cluster( const Mat& descriptors ) const = 0;
02988
02989 protected:
02990 vector<Mat> descriptors;
02991 int size;
02992 };
02993
02994
02995
02996
02997 class CV_EXPORTS BOWKMeansTrainer : public BOWTrainer
02998 {
02999 public:
03000 BOWKMeansTrainer( int clusterCount, const TermCriteria& termcrit=TermCriteria(),
03001 int attempts=3, int flags=KMEANS_PP_CENTERS );
03002 virtual ~BOWKMeansTrainer();
03003
03004
03005 virtual Mat cluster() const;
03006 virtual Mat cluster( const Mat& descriptors ) const;
03007
03008 protected:
03009
03010 int clusterCount;
03011 TermCriteria termcrit;
03012 int attempts;
03013 int flags;
03014 };
03015
03016
03017
03018
03019 class CV_EXPORTS BOWImgDescriptorExtractor
03020 {
03021 public:
03022 BOWImgDescriptorExtractor( const Ptr<DescriptorExtractor>& dextractor,
03023 const Ptr<DescriptorMatcher>& dmatcher );
03024 virtual ~BOWImgDescriptorExtractor();
03025
03026 void setVocabulary( const Mat& vocabulary );
03027 const Mat& getVocabulary() const;
03028 void compute( const Mat& image, vector<KeyPoint>& keypoints, Mat& imgDescriptor,
03029 vector<vector<int> >* pointIdxsOfClusters=0, Mat* descriptors=0 );
03030
03031
03032 int descriptorSize() const;
03033 int descriptorType() const;
03034
03035 protected:
03036 Mat vocabulary;
03037 Ptr<DescriptorExtractor> dextractor;
03038 Ptr<DescriptorMatcher> dmatcher;
03039 };
03040
03041 }
03042
03043 #endif
03044
03045 #endif
03046
03047