added BOWTrainer::add()

pull/13383/head
Maria Dimashova 15 years ago
parent fb7aa43feb
commit 13b535ac19
  1. 38
      modules/features2d/include/opencv2/features2d/features2d.hpp
  2. 64
      modules/features2d/src/bagofwords.cpp
  3. 6
      modules/features2d/src/detectors.cpp

@ -1356,7 +1356,7 @@ protected:
CV_EXPORTS Ptr<FeatureDetector> createFeatureDetector( const string& detectorType ); CV_EXPORTS Ptr<FeatureDetector> createFeatureDetector( const string& detectorType );
class DenseFeatureDetector : public FeatureDetector class CV_EXPORTS DenseFeatureDetector : public FeatureDetector
{ {
public: public:
DenseFeatureDetector() : initFeatureScale(1), featureScaleLevels(1), featureScaleMul(0.1f), DenseFeatureDetector() : initFeatureScale(1), featureScaleLevels(1), featureScaleMul(0.1f),
@ -1368,7 +1368,7 @@ public:
protected: protected:
virtual void detectImpl( const Mat& image, const Mat& mask, vector<KeyPoint>& keypoints ) const = 0; virtual void detectImpl( const Mat& image, const Mat& mask, vector<KeyPoint>& keypoints ) const;
float initFeatureScale; float initFeatureScale;
int featureScaleLevels; int featureScaleLevels;
@ -1379,7 +1379,6 @@ protected:
bool varyXyStepWithScale; bool varyXyStepWithScale;
bool varyImgBoundWithScale; bool varyImgBoundWithScale;
}; };
/* /*
@ -2240,31 +2239,47 @@ CV_EXPORTS void evaluateGenericDescriptorMatcher( const Mat& img1, const Mat& im
/* /*
* Abstract base class for training of a 'bag of visual words' vocabulary from a set of descriptors * Abstract base class for training of a 'bag of visual words' vocabulary from a set of descriptors
*/ */
class BOWTrainer class CV_EXPORTS BOWTrainer
{ {
public: public:
void add( const Mat& descriptors );
const vector<Mat>& getDescriptors() const { return descriptors; }
int descripotorsCount() const { return descriptors.empty() ? 0 : size; }
virtual void clear();
/* /*
* Train visual words vocabulary, that is cluster training descriptors and * Train visual words vocabulary, that is cluster training descriptors and
* compute cluster centers. * compute cluster centers.
* Returns cluster centers.
* *
* descriptors Training descriptors computed on images keypoints. * descriptors Training descriptors computed on images keypoints.
* vocabulary Vocabulary is cluster centers.
*/ */
virtual void cluster( const Mat& descriptors, Mat& vocabulary ) = 0; virtual Mat cluster() const = 0;
virtual Mat cluster( const Mat& descriptors ) const = 0;
protected:
vector<Mat> descriptors;
int size;
}; };
/* /*
* This is BOWTrainer using cv::kmeans to get vocabulary. * This is BOWTrainer using cv::kmeans to get vocabulary.
*/ */
class BOWKMeansTrainer : public BOWTrainer class CV_EXPORTS BOWKMeansTrainer : public BOWTrainer
{ {
public: public:
BOWKMeansTrainer( int clusterCount, const TermCriteria& termcrit=TermCriteria(), BOWKMeansTrainer( int clusterCount, const TermCriteria& termcrit=TermCriteria(),
int attempts=3, int flags=KMEANS_PP_CENTERS ); int attempts=3, int flags=KMEANS_PP_CENTERS );
virtual void cluster( const Mat& descriptors, Mat& vocabulary );
// Returns trained vocabulary (i.e. cluster centers).
virtual Mat cluster() const;
virtual Mat cluster( const Mat& descriptors ) const;
protected: protected:
int clusterCount; int clusterCount;
TermCriteria termcrit; TermCriteria termcrit;
int attempts; int attempts;
@ -2274,14 +2289,15 @@ protected:
/* /*
* Class to compute image descriptor using bad of visual words. * Class to compute image descriptor using bad of visual words.
*/ */
class BOWImgDescriptorExtractor class CV_EXPORTS BOWImgDescriptorExtractor
{ {
public: public:
BOWImgDescriptorExtractor( const Ptr<DescriptorExtractor>& dextractor, BOWImgDescriptorExtractor( const Ptr<DescriptorExtractor>& dextractor,
const Ptr<DescriptorMatcher>& dmatcher ); const Ptr<DescriptorMatcher>& dmatcher );
void set( const Mat& vocabulary ); void setVocabulary( const Mat& vocabulary );
const Mat& getVocabulary() const { return vocabulary; }
void compute( const Mat& image, vector<KeyPoint>& keypoints, Mat& imgDescriptor, void compute( const Mat& image, vector<KeyPoint>& keypoints, Mat& imgDescriptor,
vector<vector<int> >& pointIdxsInClusters ); vector<vector<int> >* pointIdxsInClusters=0 ) const;
int descriptorSize() const { return vocabulary.empty() ? 0 : vocabulary.rows; } int descriptorSize() const { return vocabulary.empty() ? 0 : vocabulary.rows; }
int descriptorType() const { return CV_32FC1; } int descriptorType() const { return CV_32FC1; }

@ -46,15 +46,56 @@ using namespace std;
namespace cv namespace cv
{ {
void BOWTrainer::add( const Mat& _descriptors )
{
CV_Assert( !_descriptors.empty() );
if( !descriptors.empty() )
{
CV_Assert( descriptors[0].cols == _descriptors.cols );
CV_Assert( descriptors[0].type() == _descriptors.type() );
size += _descriptors.rows;
}
else
{
size = _descriptors.rows;
}
descriptors.push_back(_descriptors);
}
void BOWTrainer::clear()
{
descriptors.clear();
}
BOWKMeansTrainer::BOWKMeansTrainer( int _clusterCount, const TermCriteria& _termcrit, BOWKMeansTrainer::BOWKMeansTrainer( int _clusterCount, const TermCriteria& _termcrit,
int _attempts, int _flags ) : int _attempts, int _flags ) :
clusterCount(_clusterCount), termcrit(_termcrit), attempts(_attempts), flags(_flags) clusterCount(_clusterCount), termcrit(_termcrit), attempts(_attempts), flags(_flags)
{} {}
void BOWKMeansTrainer::cluster( const Mat& descriptors, Mat& vocabulary ) Mat BOWKMeansTrainer::cluster() const
{ {
Mat labels; CV_Assert( !descriptors.empty() );
int descCount = 0;
for( size_t i = 0; i < descriptors.size(); i++ )
descCount += descriptors[i].rows;
Mat mergedDescriptors( descCount, descriptors[0].cols, descriptors[0].type() );
for( size_t i = 0, start = 0; i < descriptors.size(); i++ )
{
Mat submut = mergedDescriptors.rowRange(start, descriptors[i].rows);
descriptors[i].copyTo(submut);
start += descriptors[i].rows;
}
return cluster( mergedDescriptors );
}
Mat BOWKMeansTrainer::cluster( const Mat& descriptors ) const
{
Mat labels, vocabulary;
kmeans( descriptors, clusterCount, labels, termcrit, attempts, flags, &vocabulary ); kmeans( descriptors, clusterCount, labels, termcrit, attempts, flags, &vocabulary );
return vocabulary;
} }
@ -63,7 +104,7 @@ BOWImgDescriptorExtractor::BOWImgDescriptorExtractor( const Ptr<DescriptorExtrac
dextractor(_dextractor), dmatcher(_dmatcher) dextractor(_dextractor), dmatcher(_dmatcher)
{} {}
void BOWImgDescriptorExtractor::set( const Mat& _vocabulary ) void BOWImgDescriptorExtractor::setVocabulary( const Mat& _vocabulary )
{ {
dmatcher->clear(); dmatcher->clear();
vocabulary = _vocabulary; vocabulary = _vocabulary;
@ -71,8 +112,13 @@ void BOWImgDescriptorExtractor::set( const Mat& _vocabulary )
} }
void BOWImgDescriptorExtractor::compute( const Mat& image, vector<KeyPoint>& keypoints, Mat& imgDescriptor, void BOWImgDescriptorExtractor::compute( const Mat& image, vector<KeyPoint>& keypoints, Mat& imgDescriptor,
vector<vector<int> >& pointIdxsInClusters ) vector<vector<int> >* pointIdxsOfClusters ) const
{ {
imgDescriptor.release();
if( keypoints.empty() )
return;
int clusterCount = descriptorSize(); // = vocabulary.rows int clusterCount = descriptorSize(); // = vocabulary.rows
// Compute descriptors for the image. // Compute descriptors for the image.
@ -84,7 +130,12 @@ void BOWImgDescriptorExtractor::compute( const Mat& image, vector<KeyPoint>& key
dmatcher->match( descriptors, matches ); dmatcher->match( descriptors, matches );
// Compute image descriptor // Compute image descriptor
pointIdxsInClusters = vector<vector<int> >(clusterCount); if( pointIdxsOfClusters )
{
pointIdxsOfClusters->clear();
pointIdxsOfClusters->resize(clusterCount);
}
imgDescriptor = Mat( 1, clusterCount, descriptorType(), Scalar::all(0.0) ); imgDescriptor = Mat( 1, clusterCount, descriptorType(), Scalar::all(0.0) );
float *dptr = (float*)imgDescriptor.data; float *dptr = (float*)imgDescriptor.data;
for( size_t i = 0; i < matches.size(); i++ ) for( size_t i = 0; i < matches.size(); i++ )
@ -94,7 +145,8 @@ void BOWImgDescriptorExtractor::compute( const Mat& image, vector<KeyPoint>& key
CV_Assert( queryIdx == (int)i ); CV_Assert( queryIdx == (int)i );
dptr[trainIdx] = dptr[trainIdx] + 1.f; dptr[trainIdx] = dptr[trainIdx] + 1.f;
pointIdxsInClusters[trainIdx].push_back( queryIdx ); if( pointIdxsOfClusters )
(*pointIdxsOfClusters)[trainIdx].push_back( queryIdx );
} }
// Normalize image descriptor. // Normalize image descriptor.

@ -335,7 +335,7 @@ void SurfFeatureDetector::detectImpl( const Mat& image, const Mat& mask,
} }
/* /*
* GridAdaptedFeatureDetector * DenseFeatureDetector
*/ */
void DenseFeatureDetector::detectImpl( const Mat& image, const Mat& mask, vector<KeyPoint>& keypoints ) const void DenseFeatureDetector::detectImpl( const Mat& image, const Mat& mask, vector<KeyPoint>& keypoints ) const
{ {
@ -461,7 +461,7 @@ Ptr<FeatureDetector> createFeatureDetector( const string& detectorType )
FeatureDetector* fd = 0; FeatureDetector* fd = 0;
if( !detectorType.compare( "FAST" ) ) if( !detectorType.compare( "FAST" ) )
{ {
fd = new FastFeatureDetector( 10/*threshold*/, true/*nonmax_suppression*/ ); fd = new FastFeatureDetector( 30/*threshold*/, true/*nonmax_suppression*/ );
} }
else if( !detectorType.compare( "STAR" ) ) else if( !detectorType.compare( "STAR" ) )
{ {
@ -475,7 +475,7 @@ Ptr<FeatureDetector> createFeatureDetector( const string& detectorType )
} }
else if( !detectorType.compare( "SURF" ) ) else if( !detectorType.compare( "SURF" ) )
{ {
fd = new SurfFeatureDetector( 400./*hessian_threshold*/, 3 /*octaves*/, 4/*octave_layers*/ ); fd = new SurfFeatureDetector( 500./*hessian_threshold*/, 3 /*octaves*/, 4/*octave_layers*/ );
} }
else if( !detectorType.compare( "MSER" ) ) else if( !detectorType.compare( "MSER" ) )
{ {

Loading…
Cancel
Save