diff --git a/modules/features2d/doc/object_categorization.rst b/modules/features2d/doc/object_categorization.rst index 826919519..7516e356a 100644 --- a/modules/features2d/doc/object_categorization.rst +++ b/modules/features2d/doc/object_categorization.rst @@ -124,6 +124,7 @@ The class declaration is the following: :: public: BOWImgDescriptorExtractor( const Ptr<DescriptorExtractor>& dextractor, const Ptr<DescriptorMatcher>& dmatcher ); + BOWImgDescriptorExtractor( const Ptr<DescriptorMatcher>& dmatcher ); virtual ~BOWImgDescriptorExtractor(){} void setVocabulary( const Mat& vocabulary ); @@ -132,6 +133,8 @@ The class declaration is the following: :: Mat& imgDescriptor, vector<vector<int> >* pointIdxsOfClusters=0, Mat* descriptors=0 ); + void compute( const Mat& descriptors, Mat& imgDescriptor, + std::vector<std::vector<int> >* pointIdxsOfClusters=0 ); int descriptorSize() const; int descriptorType() const; @@ -147,6 +150,7 @@ BOWImgDescriptorExtractor::BOWImgDescriptorExtractor The constructor. .. ocv:function:: BOWImgDescriptorExtractor::BOWImgDescriptorExtractor( const Ptr<DescriptorExtractor>& dextractor, const Ptr<DescriptorMatcher>& dmatcher ) +.. ocv:function:: BOWImgDescriptorExtractor::BOWImgDescriptorExtractor( const Ptr<DescriptorMatcher>& dmatcher ) :param dextractor: Descriptor extractor that is used to compute descriptors for an input image and its keypoints. @@ -177,11 +181,14 @@ BOWImgDescriptorExtractor::compute Computes an image descriptor using the set visual vocabulary. .. ocv:function:: void BOWImgDescriptorExtractor::compute( const Mat& image, vector<KeyPoint>& keypoints, Mat& imgDescriptor, vector<vector<int> >* pointIdxsOfClusters=0, Mat* descriptors=0 ) +.. ocv:function:: void BOWImgDescriptorExtractor::compute( const Mat& keypointDescriptors, Mat& imgDescriptor, std::vector<std::vector<int> >* pointIdxsOfClusters=0 ) :param image: Image, for which the descriptor is computed. :param keypoints: Keypoints detected in the input image. + :param keypointDescriptors: Computed descriptors to match with vocabulary. + :param imgDescriptor: Computed output image descriptor. :param pointIdxsOfClusters: Indices of keypoints that belong to the cluster. This means that ``pointIdxsOfClusters[i]`` are keypoint indices that belong to the ``i`` -th cluster (word of vocabulary) returned if it is non-zero. diff --git a/modules/features2d/include/opencv2/features2d.hpp b/modules/features2d/include/opencv2/features2d.hpp index 3655ab813..6aad4beb2 100644 --- a/modules/features2d/include/opencv2/features2d.hpp +++ b/modules/features2d/include/opencv2/features2d.hpp @@ -1512,12 +1512,15 @@ class CV_EXPORTS BOWImgDescriptorExtractor public: BOWImgDescriptorExtractor( const Ptr<DescriptorExtractor>& dextractor, const Ptr<DescriptorMatcher>& dmatcher ); + BOWImgDescriptorExtractor( const Ptr<DescriptorMatcher>& dmatcher ); virtual ~BOWImgDescriptorExtractor(); void setVocabulary( const Mat& vocabulary ); const Mat& getVocabulary() const; void compute( const Mat& image, std::vector<KeyPoint>& keypoints, Mat& imgDescriptor, std::vector<std::vector<int> >* pointIdxsOfClusters=0, Mat* descriptors=0 ); + void compute( const Mat& keypointDescriptors, Mat& imgDescriptor, + std::vector<std::vector<int> >* pointIdxsOfClusters=0 ); // compute() is not constant because DescriptorMatcher::match is not constant int descriptorSize() const; diff --git a/modules/features2d/src/bagofwords.cpp b/modules/features2d/src/bagofwords.cpp index a3cfb60a9..2836f5272 100644 --- a/modules/features2d/src/bagofwords.cpp +++ b/modules/features2d/src/bagofwords.cpp @@ -121,6 +121,10 @@ BOWImgDescriptorExtractor::BOWImgDescriptorExtractor( const Ptr<DescriptorExtrac dextractor(_dextractor), dmatcher(_dmatcher) {} +BOWImgDescriptorExtractor::BOWImgDescriptorExtractor( const Ptr<DescriptorMatcher>& _dmatcher ) : + dmatcher(_dmatcher) +{} + BOWImgDescriptorExtractor::~BOWImgDescriptorExtractor() {} @@ -137,22 +141,44 @@ const Mat& BOWImgDescriptorExtractor::getVocabulary() const } void BOWImgDescriptorExtractor::compute( const Mat& image, std::vector<KeyPoint>& keypoints, Mat& imgDescriptor, - std::vector<std::vector<int> >* pointIdxsOfClusters, Mat* _descriptors ) + std::vector<std::vector<int> >* pointIdxsOfClusters, Mat* descriptors ) { imgDescriptor.release(); if( keypoints.empty() ) return; - int clusterCount = descriptorSize(); // = vocabulary.rows - // Compute descriptors for the image. - Mat descriptors; - dextractor->compute( image, keypoints, descriptors ); + Mat _descriptors; + dextractor->compute( image, keypoints, _descriptors ); + + compute( _descriptors, imgDescriptor, pointIdxsOfClusters ); + + // Add the descriptors of image keypoints + if (descriptors) { + *descriptors = _descriptors.clone(); + } +} + +int BOWImgDescriptorExtractor::descriptorSize() const +{ + return vocabulary.empty() ? 0 : vocabulary.rows; +} + +int BOWImgDescriptorExtractor::descriptorType() const +{ + return CV_32FC1; +} + +void BOWImgDescriptorExtractor::compute( const Mat& keypointDescriptors, Mat& imgDescriptor, std::vector<std::vector<int> >* pointIdxsOfClusters ) +{ + CV_Assert( vocabulary.empty() != false ); + + int clusterCount = descriptorSize(); // = vocabulary.rows // Match keypoint descriptors to cluster center (to vocabulary) std::vector<DMatch> matches; - dmatcher->match( descriptors, matches ); + dmatcher->match( keypointDescriptors, matches ); // Compute image descriptor if( pointIdxsOfClusters ) @@ -175,22 +201,7 @@ void BOWImgDescriptorExtractor::compute( const Mat& image, std::vector<KeyPoint> } // Normalize image descriptor. - imgDescriptor /= descriptors.rows; - - // Add the descriptors of image keypoints - if (_descriptors) { - *_descriptors = descriptors.clone(); - } -} - -int BOWImgDescriptorExtractor::descriptorSize() const -{ - return vocabulary.empty() ? 0 : vocabulary.rows; -} - -int BOWImgDescriptorExtractor::descriptorType() const -{ - return CV_32FC1; + imgDescriptor /= keypointDescriptors.rows; } }