Ptr<DescriptorMatcher> dmatcher;
};
+/*
+ * Class to match image descriptors using bag of visual words.
+ */
+class CV_EXPORTS BOWImgDescriptorMatcher
+{
+public:
+ BOWImgDescriptorMatcher( const Ptr<DescriptorMatcher>& _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<DescriptorMatcher> dmatcher;
+
+private:
+ int _type;
+};
+
+
} /* namespace cv */
#endif
return CV_32FC1;
}
+BOWImgDescriptorMatcher::BOWImgDescriptorMatcher( const Ptr<DescriptorMatcher>& _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<Mat>(1, vocabulary) );
+}
+
+const Mat& BOWImgDescriptorMatcher::getVocabulary() const
+{
+ return vocabulary;
+}
+
+void BOWImgDescriptorMatcher::compute( const Mat & descriptors, Mat& vocDescriptor, std::vector<std::vector<int> > * 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<DMatch> matches;
+ dmatcher->match( _descriptors, matches );
+
+ // Compute image descriptor
+ if( pointIdxsOfClusters )
+ {
+ pointIdxsOfClusters->clear();
+ pointIdxsOfClusters->resize(clusterCount);
+ }
+
+ vocDescriptor = Mat::zeros( 1, clusterCount, descriptorType() );
+ float *dptr = (float*)vocDescriptor.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.
+ vocDescriptor /= descriptors.rows;
+}
+
+int BOWImgDescriptorMatcher::descriptorSize() const
+{
+ return vocabulary.empty() ? 0 : vocabulary.rows;
+}
+
+int BOWImgDescriptorMatcher::descriptorType() const
+{
+ return _type;
+}
+
}