diff --git a/modules/features2d/src/sift.cpp b/modules/features2d/src/sift.cpp index a627502404..850bd4f3f5 100644 --- a/modules/features2d/src/sift.cpp +++ b/modules/features2d/src/sift.cpp @@ -76,6 +76,53 @@ namespace cv { +/*! + SIFT implementation. + + The class implements SIFT algorithm by D. Lowe. + */ +class SIFT_Impl : public SIFT +{ +public: + explicit SIFT_Impl( int nfeatures = 0, int nOctaveLayers = 3, + double contrastThreshold = 0.04, double edgeThreshold = 10, + double sigma = 1.6); + + //! returns the descriptor size in floats (128) + int descriptorSize() const; + + //! returns the descriptor type + int descriptorType() const; + + //! returns the default norm type + int defaultNorm() const; + + //! finds the keypoints and computes descriptors for them using SIFT algorithm. + //! Optionally it can compute descriptors for the user-provided keypoints + void detectAndCompute(InputArray img, InputArray mask, + std::vector& keypoints, + OutputArray descriptors, + bool useProvidedKeypoints = false); + + void buildGaussianPyramid( const Mat& base, std::vector& pyr, int nOctaves ) const; + void buildDoGPyramid( const std::vector& pyr, std::vector& dogpyr ) const; + void findScaleSpaceExtrema( const std::vector& gauss_pyr, const std::vector& dog_pyr, + std::vector& keypoints ) const; + +protected: + CV_PROP_RW int nfeatures; + CV_PROP_RW int nOctaveLayers; + CV_PROP_RW double contrastThreshold; + CV_PROP_RW double edgeThreshold; + CV_PROP_RW double sigma; +}; + +Ptr SIFT::create( int _nfeatures, int _nOctaveLayers, + double _contrastThreshold, double _edgeThreshold, double _sigma ) +{ + return makePtr(_nfeatures, _nOctaveLayers, _contrastThreshold, _edgeThreshold, _sigma); +} + /******************************* Defs and macros *****************************/ // default width of descriptor histogram array @@ -161,7 +208,7 @@ static Mat createInitialImage( const Mat& img, bool doubleImageSize, float sigma } -void SIFT::buildGaussianPyramid( const Mat& base, std::vector& pyr, int nOctaves ) const +void SIFT_Impl::buildGaussianPyramid( const Mat& base, std::vector& pyr, int nOctaves ) const { std::vector sig(nOctaveLayers + 3); pyr.resize(nOctaves*(nOctaveLayers + 3)); @@ -201,7 +248,7 @@ void SIFT::buildGaussianPyramid( const Mat& base, std::vector& pyr, int nOc } -void SIFT::buildDoGPyramid( const std::vector& gpyr, std::vector& dogpyr ) const +void SIFT_Impl::buildDoGPyramid( const std::vector& gpyr, std::vector& dogpyr ) const { int nOctaves = (int)gpyr.size()/(nOctaveLayers + 3); dogpyr.resize( nOctaves*(nOctaveLayers + 2) ); @@ -399,7 +446,7 @@ static bool adjustLocalExtrema( const std::vector& dog_pyr, KeyPoint& kpt, // // Detects features at extrema in DoG scale space. Bad features are discarded // based on contrast and ratio of principal curvatures. -void SIFT::findScaleSpaceExtrema( const std::vector& gauss_pyr, const std::vector& dog_pyr, +void SIFT_Impl::findScaleSpaceExtrema( const std::vector& gauss_pyr, const std::vector& dog_pyr, std::vector& keypoints ) const { int nOctaves = (int)gauss_pyr.size()/(nOctaveLayers + 3); @@ -652,40 +699,33 @@ static void calcDescriptors(const std::vector& gpyr, const std::vector& keypoints) const -{ - (*this)(_image, _mask, keypoints, noArray()); -} - - -void SIFT::operator()(InputArray _image, InputArray _mask, +void SIFT_Impl::detectAndCompute(InputArray _image, InputArray _mask, std::vector& keypoints, OutputArray _descriptors, - bool useProvidedKeypoints) const + bool useProvidedKeypoints) { int firstOctave = -1, actualNOctaves = 0, actualNLayers = 0; Mat image = _image.getMat(), mask = _mask.getMat(); @@ -770,14 +810,4 @@ void SIFT::operator()(InputArray _image, InputArray _mask, } } -void SIFT::detectImpl( InputArray image, std::vector& keypoints, InputArray mask) const -{ - (*this)(image.getMat(), mask.getMat(), keypoints, noArray()); -} - -void SIFT::computeImpl( InputArray image, std::vector& keypoints, OutputArray descriptors) const -{ - (*this)(image, Mat(), keypoints, descriptors, true); -} - }