Commit 43c98188 authored by Mathieu Barnachon's avatar Mathieu Barnachon

Adding class for BOW image matcher (Feature #3005).

Same prototype as BOWImgDescriptorExtractor, but do only the matching.
If the feature is accepted, the BOWImgDescriptorExtractor and BOWImgDescriptorMatcher should probably refactor with inheritance.
Add a class to compute the keypoints, descriptors and matching from an image should be added to.
parent 4ed9b1ca
......@@ -1519,6 +1519,41 @@ protected:
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
......@@ -193,4 +193,76 @@ int BOWImgDescriptorExtractor::descriptorType() const
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;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment