From 464985205c3a011dec5a789adb38f7a50ebf9df9 Mon Sep 17 00:00:00 2001 From: Mathieu Barnachon Date: Thu, 5 Sep 2013 16:05:54 +1200 Subject: [PATCH] Update PR after mdim review. --- .../features2d/doc/object_categorization.rst | 7 ++ .../features2d/include/opencv2/features2d.hpp | 38 +-------- modules/features2d/src/bagofwords.cpp | 85 +++---------------- 3 files changed, 22 insertions(+), 108 deletions(-) diff --git a/modules/features2d/doc/object_categorization.rst b/modules/features2d/doc/object_categorization.rst index 73089ce7ad..3cde0ec5bd 100644 --- a/modules/features2d/doc/object_categorization.rst +++ b/modules/features2d/doc/object_categorization.rst @@ -118,6 +118,7 @@ The class declaration is the following: :: public: BOWImgDescriptorExtractor( const Ptr& dextractor, const Ptr& dmatcher ); + BOWImgDescriptorExtractor( const Ptr& dmatcher ); virtual ~BOWImgDescriptorExtractor(){} void setVocabulary( const Mat& vocabulary ); @@ -126,6 +127,8 @@ The class declaration is the following: :: Mat& imgDescriptor, vector >* pointIdxsOfClusters=0, Mat* descriptors=0 ); + void compute( const Mat& descriptors, Mat& imgDescriptor, + std::vector >* pointIdxsOfClusters=0 ); int descriptorSize() const; int descriptorType() const; @@ -141,6 +144,7 @@ BOWImgDescriptorExtractor::BOWImgDescriptorExtractor The constructor. .. ocv:function:: BOWImgDescriptorExtractor::BOWImgDescriptorExtractor( const Ptr& dextractor, const Ptr& dmatcher ) +.. ocv:function:: BOWImgDescriptorExtractor::BOWImgDescriptorExtractor( const Ptr& dmatcher ) :param dextractor: Descriptor extractor that is used to compute descriptors for an input image and its keypoints. @@ -171,11 +175,14 @@ BOWImgDescriptorExtractor::compute Computes an image descriptor using the set visual vocabulary. .. ocv:function:: void BOWImgDescriptorExtractor::compute( const Mat& image, vector& keypoints, Mat& imgDescriptor, vector >* pointIdxsOfClusters=0, Mat* descriptors=0 ) +.. ocv:function:: void BOWImgDescriptorExtractor::compute( const Mat& descriptors, Mat& imgDescriptor, std::vector >* pointIdxsOfClusters ) :param image: Image, for which the descriptor is computed. :param keypoints: Keypoints detected in the input image. + :param descriptors: 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 2474dd5940..d189b7e8ed 100644 --- a/modules/features2d/include/opencv2/features2d.hpp +++ b/modules/features2d/include/opencv2/features2d.hpp @@ -1502,12 +1502,15 @@ class CV_EXPORTS BOWImgDescriptorExtractor public: BOWImgDescriptorExtractor( const Ptr& dextractor, const Ptr& dmatcher ); + BOWImgDescriptorExtractor( const Ptr& dmatcher ); virtual ~BOWImgDescriptorExtractor(); void setVocabulary( const Mat& vocabulary ); const Mat& getVocabulary() const; void compute( const Mat& image, std::vector& keypoints, Mat& imgDescriptor, std::vector >* pointIdxsOfClusters=0, Mat* descriptors=0 ); + void compute( const Mat& keypointDescriptors, Mat& imgDescriptor, + std::vector >* pointIdxsOfClusters=0 ); // compute() is not constant because DescriptorMatcher::match is not constant int descriptorSize() const; @@ -1519,41 +1522,6 @@ protected: Ptr dmatcher; }; -/* - * Class to match image descriptors using bag of visual words. - */ -class CV_EXPORTS BOWImgDescriptorMatcher -{ -public: - BOWImgDescriptorMatcher( const Ptr& _dmatcher ); - virtual ~BOWImgDescriptorMatcher(); - - /* - * Compute the matching of the current descriptor according to the vocabulary. - * - * vocDescriptor the descriptors to match - * pointIdxsOfClusters vector of matching - */ - void compute( const Mat & descriptors, Mat& vocDescriptor, std::vector< std::vector< int > > * pointIdxsOfClusters = 0 ); - - /* - * Set the vocabulary - */ - void setVocabulary( const Mat& vocabulary ); - const Mat& getVocabulary() const; - - int descriptorSize() const; - int descriptorType() const; - -protected: - Mat vocabulary; - Ptr dmatcher; - -private: - int _type; -}; - - } /* namespace cv */ #endif diff --git a/modules/features2d/src/bagofwords.cpp b/modules/features2d/src/bagofwords.cpp index 5ef8b5c4bb..11f8c4ba37 100644 --- a/modules/features2d/src/bagofwords.cpp +++ b/modules/features2d/src/bagofwords.cpp @@ -121,6 +121,10 @@ BOWImgDescriptorExtractor::BOWImgDescriptorExtractor( const Ptr& _dmatcher ) : + dmatcher(_dmatcher) +{} + BOWImgDescriptorExtractor::~BOWImgDescriptorExtractor() {} @@ -144,38 +148,11 @@ void BOWImgDescriptorExtractor::compute( const Mat& image, std::vector if( keypoints.empty() ) return; - int clusterCount = descriptorSize(); // = vocabulary.rows - // Compute descriptors for the image. Mat descriptors; dextractor->compute( image, keypoints, descriptors ); - // Match keypoint descriptors to cluster center (to vocabulary) - std::vector matches; - dmatcher->match( descriptors, matches ); - - // Compute image descriptor - if( pointIdxsOfClusters ) - { - pointIdxsOfClusters->clear(); - pointIdxsOfClusters->resize(clusterCount); - } - - imgDescriptor = Mat( 1, clusterCount, descriptorType(), Scalar::all(0.0) ); - float *dptr = (float*)imgDescriptor.data; - for( size_t i = 0; i < matches.size(); i++ ) - { - int queryIdx = matches[i].queryIdx; - int trainIdx = matches[i].trainIdx; // cluster index - CV_Assert( queryIdx == (int)i ); - - dptr[trainIdx] = dptr[trainIdx] + 1.f; - if( pointIdxsOfClusters ) - (*pointIdxsOfClusters)[trainIdx].push_back( queryIdx ); - } - - // Normalize image descriptor. - imgDescriptor /= descriptors.rows; + compute( descriptors, imgDescriptor, pointIdxsOfClusters ); // Add the descriptors of image keypoints if (_descriptors) { @@ -193,44 +170,16 @@ int BOWImgDescriptorExtractor::descriptorType() const return CV_32FC1; } -BOWImgDescriptorMatcher::BOWImgDescriptorMatcher( const Ptr& _dmatcher ) : - dmatcher(_dmatcher), - _type( -1 ) -{} - -BOWImgDescriptorMatcher::~BOWImgDescriptorMatcher() -{} - -void BOWImgDescriptorMatcher::setVocabulary( const Mat& _vocabulary ) -{ - dmatcher->clear(); - CV_Assert( _vocabulary.type() == CV_32F ); - vocabulary = _vocabulary; - dmatcher->add( std::vector(1, vocabulary) ); -} - -const Mat& BOWImgDescriptorMatcher::getVocabulary() const +void BOWImgDescriptorExtractor::compute( const Mat& descriptors, Mat& imgDescriptor, std::vector >* pointIdxsOfClusters ) { - return vocabulary; -} + CV_Assert( vocabulary.empty() != false ); -void BOWImgDescriptorMatcher::compute( const Mat & descriptors, Mat& vocDescriptor, std::vector > * pointIdxsOfClusters ) -{ - vocDescriptor.release(); - int clusterCount = descriptorSize(); // = vocabulary.rows - _type = descriptors.type(); - - Mat _descriptors; - if( _type != CV_32F ) - descriptors.convertTo( _descriptors, CV_32F ); - else - descriptors.copyTo( _descriptors ); // Match keypoint descriptors to cluster center (to vocabulary) std::vector matches; - dmatcher->match( _descriptors, matches ); - + dmatcher->match( descriptors, matches ); + // Compute image descriptor if( pointIdxsOfClusters ) { @@ -238,8 +187,8 @@ void BOWImgDescriptorMatcher::compute( const Mat & descriptors, Mat& vocDescript pointIdxsOfClusters->resize(clusterCount); } - vocDescriptor = Mat::zeros( 1, clusterCount, descriptorType() ); - float *dptr = (float*)vocDescriptor.data; + imgDescriptor = Mat( 1, clusterCount, descriptorType(), Scalar::all(0.0) ); + float *dptr = (float*)imgDescriptor.data; for( size_t i = 0; i < matches.size(); i++ ) { int queryIdx = matches[i].queryIdx; @@ -252,17 +201,7 @@ void BOWImgDescriptorMatcher::compute( const Mat & descriptors, Mat& vocDescript } // Normalize image descriptor. - vocDescriptor /= descriptors.rows; -} - -int BOWImgDescriptorMatcher::descriptorSize() const -{ - return vocabulary.empty() ? 0 : vocabulary.rows; -} - -int BOWImgDescriptorMatcher::descriptorType() const -{ - return _type; + imgDescriptor /= descriptors.rows; } }