This source file includes following definitions.
- add
 
- getDescriptors
 
- descriptorsCount
 
- clear
 
- flags
 
- cluster
 
- cluster
 
- dmatcher
 
- setVocabulary
 
- getVocabulary
 
- compute
 
- descriptorSize
 
- descriptorType
 
- compute
 
#include "precomp.hpp"
namespace cv
{
BOWTrainer::BOWTrainer() : size(0)
{}
BOWTrainer::~BOWTrainer()
{}
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);
}
const std::vector<Mat>& BOWTrainer::getDescriptors() const
{
    return descriptors;
}
int BOWTrainer::descriptorsCount() const
{
    return descriptors.empty() ? 0 : size;
}
void BOWTrainer::clear()
{
    descriptors.clear();
}
BOWKMeansTrainer::BOWKMeansTrainer( int _clusterCount, const TermCriteria& _termcrit,
                                    int _attempts, int _flags ) :
    clusterCount(_clusterCount), termcrit(_termcrit), attempts(_attempts), flags(_flags)
{}
Mat BOWKMeansTrainer::cluster() const
{
    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((int)start, (int)(start + descriptors[i].rows));
        descriptors[i].copyTo(submut);
        start += descriptors[i].rows;
    }
    return cluster( mergedDescriptors );
}
BOWKMeansTrainer::~BOWKMeansTrainer()
{}
Mat BOWKMeansTrainer::cluster( const Mat& _descriptors ) const
{
    Mat labels, vocabulary;
    kmeans( _descriptors, clusterCount, labels, termcrit, attempts, flags, vocabulary );
    return vocabulary;
}
BOWImgDescriptorExtractor::BOWImgDescriptorExtractor( const Ptr<DescriptorExtractor>& _dextractor,
                                                      const Ptr<DescriptorMatcher>& _dmatcher ) :
    dextractor(_dextractor), dmatcher(_dmatcher)
{}
BOWImgDescriptorExtractor::BOWImgDescriptorExtractor( const Ptr<DescriptorMatcher>& _dmatcher ) :
    dmatcher(_dmatcher)
{}
BOWImgDescriptorExtractor::~BOWImgDescriptorExtractor()
{}
void BOWImgDescriptorExtractor::setVocabulary( const Mat& _vocabulary )
{
    dmatcher->clear();
    vocabulary = _vocabulary;
    dmatcher->add( std::vector<Mat>(1, vocabulary) );
}
const Mat& BOWImgDescriptorExtractor::getVocabulary() const
{
    return vocabulary;
}
void BOWImgDescriptorExtractor::compute( InputArray image, std::vector<KeyPoint>& keypoints, OutputArray imgDescriptor,
                                         std::vector<std::vector<int> >* pointIdxsOfClusters, Mat* descriptors )
{
    imgDescriptor.release();
    if( keypoints.empty() )
        return;
    
    Mat _descriptors;
    dextractor->compute( image, keypoints, _descriptors );
    compute( _descriptors, imgDescriptor, pointIdxsOfClusters );
    
    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( InputArray keypointDescriptors, OutputArray _imgDescriptor, std::vector<std::vector<int> >* pointIdxsOfClusters )
{
    CV_Assert( !vocabulary.empty() );
    int clusterCount = descriptorSize(); 
    
    std::vector<DMatch> matches;
    dmatcher->match( keypointDescriptors, matches );
    
    if( pointIdxsOfClusters )
    {
        pointIdxsOfClusters->clear();
        pointIdxsOfClusters->resize(clusterCount);
    }
    _imgDescriptor.create(1, clusterCount, descriptorType());
    _imgDescriptor.setTo(Scalar::all(0));
    Mat imgDescriptor = _imgDescriptor.getMat();
    float *dptr = imgDescriptor.ptr<float>();
    for( size_t i = 0; i < matches.size(); i++ )
    {
        int queryIdx = matches[i].queryIdx;
        int trainIdx = matches[i].trainIdx; 
        CV_Assert( queryIdx == (int)i );
        dptr[trainIdx] = dptr[trainIdx] + 1.f;
        if( pointIdxsOfClusters )
            (*pointIdxsOfClusters)[trainIdx].push_back( queryIdx );
    }
    
    imgDescriptor /= keypointDescriptors.size().height;
}
}