Path: blob/master/modules/features2d/src/bagofwords.cpp
16337 views
/*M///////////////////////////////////////////////////////////////////////////////////////1//2// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.3//4// By downloading, copying, installing or using the software you agree to this license.5// If you do not agree to this license, do not download, install,6// copy or use the software.7//8//9// Intel License Agreement10// For Open Source Computer Vision Library11//12// Copyright (C) 2000, Intel Corporation, all rights reserved.13// Third party copyrights are property of their respective owners.14//15// Redistribution and use in source and binary forms, with or without modification,16// are permitted provided that the following conditions are met:17//18// * Redistribution's of source code must retain the above copyright notice,19// this list of conditions and the following disclaimer.20//21// * Redistribution's in binary form must reproduce the above copyright notice,22// this list of conditions and the following disclaimer in the documentation23// and/or other materials provided with the distribution.24//25// * The name of Intel Corporation may not be used to endorse or promote products26// derived from this software without specific prior written permission.27//28// This software is provided by the copyright holders and contributors "as is" and29// any express or implied warranties, including, but not limited to, the implied30// warranties of merchantability and fitness for a particular purpose are disclaimed.31// In no event shall the Intel Corporation or contributors be liable for any direct,32// indirect, incidental, special, exemplary, or consequential damages33// (including, but not limited to, procurement of substitute goods or services;34// loss of use, data, or profits; or business interruption) however caused35// and on any theory of liability, whether in contract, strict liability,36// or tort (including negligence or otherwise) arising in any way out of37// the use of this software, even if advised of the possibility of such damage.38//39//M*/4041#include "precomp.hpp"4243namespace cv44{4546BOWTrainer::BOWTrainer() : size(0)47{}4849BOWTrainer::~BOWTrainer()50{}5152void BOWTrainer::add( const Mat& _descriptors )53{54CV_Assert( !_descriptors.empty() );55if( !descriptors.empty() )56{57CV_Assert( descriptors[0].cols == _descriptors.cols );58CV_Assert( descriptors[0].type() == _descriptors.type() );59size += _descriptors.rows;60}61else62{63size = _descriptors.rows;64}6566descriptors.push_back(_descriptors);67}6869const std::vector<Mat>& BOWTrainer::getDescriptors() const70{71return descriptors;72}7374int BOWTrainer::descriptorsCount() const75{76return descriptors.empty() ? 0 : size;77}7879void BOWTrainer::clear()80{81descriptors.clear();82}8384BOWKMeansTrainer::BOWKMeansTrainer( int _clusterCount, const TermCriteria& _termcrit,85int _attempts, int _flags ) :86clusterCount(_clusterCount), termcrit(_termcrit), attempts(_attempts), flags(_flags)87{}8889Mat BOWKMeansTrainer::cluster() const90{91CV_INSTRUMENT_REGION();9293CV_Assert( !descriptors.empty() );9495Mat mergedDescriptors( descriptorsCount(), descriptors[0].cols, descriptors[0].type() );96for( size_t i = 0, start = 0; i < descriptors.size(); i++ )97{98Mat submut = mergedDescriptors.rowRange((int)start, (int)(start + descriptors[i].rows));99descriptors[i].copyTo(submut);100start += descriptors[i].rows;101}102return cluster( mergedDescriptors );103}104105BOWKMeansTrainer::~BOWKMeansTrainer()106{}107108Mat BOWKMeansTrainer::cluster( const Mat& _descriptors ) const109{110CV_INSTRUMENT_REGION();111112Mat labels, vocabulary;113kmeans( _descriptors, clusterCount, labels, termcrit, attempts, flags, vocabulary );114return vocabulary;115}116117118BOWImgDescriptorExtractor::BOWImgDescriptorExtractor( const Ptr<DescriptorExtractor>& _dextractor,119const Ptr<DescriptorMatcher>& _dmatcher ) :120dextractor(_dextractor), dmatcher(_dmatcher)121{}122123BOWImgDescriptorExtractor::BOWImgDescriptorExtractor( const Ptr<DescriptorMatcher>& _dmatcher ) :124dmatcher(_dmatcher)125{}126127BOWImgDescriptorExtractor::~BOWImgDescriptorExtractor()128{}129130void BOWImgDescriptorExtractor::setVocabulary( const Mat& _vocabulary )131{132dmatcher->clear();133vocabulary = _vocabulary;134dmatcher->add( std::vector<Mat>(1, vocabulary) );135}136137const Mat& BOWImgDescriptorExtractor::getVocabulary() const138{139return vocabulary;140}141142void BOWImgDescriptorExtractor::compute( InputArray image, std::vector<KeyPoint>& keypoints, OutputArray imgDescriptor,143std::vector<std::vector<int> >* pointIdxsOfClusters, Mat* descriptors )144{145CV_INSTRUMENT_REGION();146147imgDescriptor.release();148149if( keypoints.empty() )150return;151152// Compute descriptors for the image.153Mat _descriptors;154dextractor->compute( image, keypoints, _descriptors );155156compute( _descriptors, imgDescriptor, pointIdxsOfClusters );157158// Add the descriptors of image keypoints159if (descriptors) {160*descriptors = _descriptors.clone();161}162}163164int BOWImgDescriptorExtractor::descriptorSize() const165{166return vocabulary.empty() ? 0 : vocabulary.rows;167}168169int BOWImgDescriptorExtractor::descriptorType() const170{171return CV_32FC1;172}173174void BOWImgDescriptorExtractor::compute( InputArray keypointDescriptors, OutputArray _imgDescriptor, std::vector<std::vector<int> >* pointIdxsOfClusters )175{176CV_INSTRUMENT_REGION();177178CV_Assert( !vocabulary.empty() );179CV_Assert(!keypointDescriptors.empty());180181int clusterCount = descriptorSize(); // = vocabulary.rows182183// Match keypoint descriptors to cluster center (to vocabulary)184std::vector<DMatch> matches;185dmatcher->match( keypointDescriptors, matches );186187// Compute image descriptor188if( pointIdxsOfClusters )189{190pointIdxsOfClusters->clear();191pointIdxsOfClusters->resize(clusterCount);192}193194_imgDescriptor.create(1, clusterCount, descriptorType());195_imgDescriptor.setTo(Scalar::all(0));196197Mat imgDescriptor = _imgDescriptor.getMat();198199float *dptr = imgDescriptor.ptr<float>();200for( size_t i = 0; i < matches.size(); i++ )201{202int queryIdx = matches[i].queryIdx;203int trainIdx = matches[i].trainIdx; // cluster index204CV_Assert( queryIdx == (int)i );205206dptr[trainIdx] = dptr[trainIdx] + 1.f;207if( pointIdxsOfClusters )208(*pointIdxsOfClusters)[trainIdx].push_back( queryIdx );209}210211// Normalize image descriptor.212imgDescriptor /= keypointDescriptors.size().height;213}214215}216217218