mirror of
https://github.com/opencv/opencv.git
synced 2026-07-29 23:33:05 +04:00
moved nonfree and a part of features2d to opencv_contrib/xfeatures2d
This commit is contained in:
@@ -50,26 +50,7 @@
|
||||
namespace cv
|
||||
{
|
||||
|
||||
Mat windowedMatchingMask( const std::vector<KeyPoint>& keypoints1, const std::vector<KeyPoint>& keypoints2,
|
||||
float maxDeltaX, float maxDeltaY )
|
||||
{
|
||||
if( keypoints1.empty() || keypoints2.empty() )
|
||||
return Mat();
|
||||
|
||||
int n1 = (int)keypoints1.size(), n2 = (int)keypoints2.size();
|
||||
Mat mask( n1, n2, CV_8UC1 );
|
||||
for( int i = 0; i < n1; i++ )
|
||||
{
|
||||
for( int j = 0; j < n2; j++ )
|
||||
{
|
||||
Point2f diff = keypoints2[j].pt - keypoints1[i].pt;
|
||||
mask.at<uchar>(i, j) = std::abs(diff.x) < maxDeltaX && std::abs(diff.y) < maxDeltaY;
|
||||
}
|
||||
}
|
||||
return mask;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////ocl functions for BFMatcher ///////////////////////////////////////////////////////////////
|
||||
/////////////////////// ocl functions for BFMatcher ///////////////////////////
|
||||
|
||||
static void ensureSizeIsEnough(int rows, int cols, int type, UMat &m)
|
||||
{
|
||||
@@ -1507,382 +1488,4 @@ void FlannBasedMatcher::radiusMatchImpl( InputArray _queryDescriptors, std::vect
|
||||
convertToDMatches( mergedDescriptors, indices, dists, matches );
|
||||
}
|
||||
|
||||
/****************************************************************************************\
|
||||
* GenericDescriptorMatcher *
|
||||
\****************************************************************************************/
|
||||
/*
|
||||
* KeyPointCollection
|
||||
*/
|
||||
GenericDescriptorMatcher::KeyPointCollection::KeyPointCollection() : pointCount(0)
|
||||
{}
|
||||
|
||||
GenericDescriptorMatcher::KeyPointCollection::KeyPointCollection( const KeyPointCollection& collection )
|
||||
{
|
||||
pointCount = collection.pointCount;
|
||||
|
||||
std::transform( collection.images.begin(), collection.images.end(), images.begin(), clone_op );
|
||||
|
||||
keypoints.resize( collection.keypoints.size() );
|
||||
for( size_t i = 0; i < keypoints.size(); i++ )
|
||||
std::copy( collection.keypoints[i].begin(), collection.keypoints[i].end(), keypoints[i].begin() );
|
||||
|
||||
std::copy( collection.startIndices.begin(), collection.startIndices.end(), startIndices.begin() );
|
||||
}
|
||||
|
||||
void GenericDescriptorMatcher::KeyPointCollection::add( const std::vector<Mat>& _images,
|
||||
const std::vector<std::vector<KeyPoint> >& _points )
|
||||
{
|
||||
CV_Assert( !_images.empty() );
|
||||
CV_Assert( _images.size() == _points.size() );
|
||||
|
||||
images.insert( images.end(), _images.begin(), _images.end() );
|
||||
keypoints.insert( keypoints.end(), _points.begin(), _points.end() );
|
||||
for( size_t i = 0; i < _points.size(); i++ )
|
||||
pointCount += (int)_points[i].size();
|
||||
|
||||
size_t prevSize = startIndices.size(), addSize = _images.size();
|
||||
startIndices.resize( prevSize + addSize );
|
||||
|
||||
if( prevSize == 0 )
|
||||
startIndices[prevSize] = 0; //first
|
||||
else
|
||||
startIndices[prevSize] = (int)(startIndices[prevSize-1] + keypoints[prevSize-1].size());
|
||||
|
||||
for( size_t i = prevSize + 1; i < prevSize + addSize; i++ )
|
||||
{
|
||||
startIndices[i] = (int)(startIndices[i - 1] + keypoints[i - 1].size());
|
||||
}
|
||||
}
|
||||
|
||||
void GenericDescriptorMatcher::KeyPointCollection::clear()
|
||||
{
|
||||
pointCount = 0;
|
||||
|
||||
images.clear();
|
||||
keypoints.clear();
|
||||
startIndices.clear();
|
||||
}
|
||||
|
||||
size_t GenericDescriptorMatcher::KeyPointCollection::keypointCount() const
|
||||
{
|
||||
return pointCount;
|
||||
}
|
||||
|
||||
size_t GenericDescriptorMatcher::KeyPointCollection::imageCount() const
|
||||
{
|
||||
return images.size();
|
||||
}
|
||||
|
||||
const std::vector<std::vector<KeyPoint> >& GenericDescriptorMatcher::KeyPointCollection::getKeypoints() const
|
||||
{
|
||||
return keypoints;
|
||||
}
|
||||
|
||||
const std::vector<KeyPoint>& GenericDescriptorMatcher::KeyPointCollection::getKeypoints( int imgIdx ) const
|
||||
{
|
||||
CV_Assert( imgIdx < (int)imageCount() );
|
||||
return keypoints[imgIdx];
|
||||
}
|
||||
|
||||
const KeyPoint& GenericDescriptorMatcher::KeyPointCollection::getKeyPoint( int imgIdx, int localPointIdx ) const
|
||||
{
|
||||
CV_Assert( imgIdx < (int)images.size() );
|
||||
CV_Assert( localPointIdx < (int)keypoints[imgIdx].size() );
|
||||
return keypoints[imgIdx][localPointIdx];
|
||||
}
|
||||
|
||||
const KeyPoint& GenericDescriptorMatcher::KeyPointCollection::getKeyPoint( int globalPointIdx ) const
|
||||
{
|
||||
int imgIdx, localPointIdx;
|
||||
getLocalIdx( globalPointIdx, imgIdx, localPointIdx );
|
||||
return keypoints[imgIdx][localPointIdx];
|
||||
}
|
||||
|
||||
void GenericDescriptorMatcher::KeyPointCollection::getLocalIdx( int globalPointIdx, int& imgIdx, int& localPointIdx ) const
|
||||
{
|
||||
imgIdx = -1;
|
||||
CV_Assert( globalPointIdx < (int)keypointCount() );
|
||||
for( size_t i = 1; i < startIndices.size(); i++ )
|
||||
{
|
||||
if( globalPointIdx < startIndices[i] )
|
||||
{
|
||||
imgIdx = (int)(i - 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
imgIdx = imgIdx == -1 ? (int)(startIndices.size() - 1) : imgIdx;
|
||||
localPointIdx = globalPointIdx - startIndices[imgIdx];
|
||||
}
|
||||
|
||||
const std::vector<Mat>& GenericDescriptorMatcher::KeyPointCollection::getImages() const
|
||||
{
|
||||
return images;
|
||||
}
|
||||
|
||||
const Mat& GenericDescriptorMatcher::KeyPointCollection::getImage( int imgIdx ) const
|
||||
{
|
||||
CV_Assert( imgIdx < (int)imageCount() );
|
||||
return images[imgIdx];
|
||||
}
|
||||
|
||||
/*
|
||||
* GenericDescriptorMatcher
|
||||
*/
|
||||
GenericDescriptorMatcher::GenericDescriptorMatcher()
|
||||
{}
|
||||
|
||||
GenericDescriptorMatcher::~GenericDescriptorMatcher()
|
||||
{}
|
||||
|
||||
void GenericDescriptorMatcher::add( InputArrayOfArrays _images,
|
||||
std::vector<std::vector<KeyPoint> >& keypoints )
|
||||
{
|
||||
std::vector<Mat> images;
|
||||
_images.getMatVector(images);
|
||||
CV_Assert( !images.empty() );
|
||||
CV_Assert( images.size() == keypoints.size() );
|
||||
|
||||
for( size_t i = 0; i < images.size(); i++ )
|
||||
{
|
||||
CV_Assert( !images[i].empty() );
|
||||
KeyPointsFilter::runByImageBorder( keypoints[i], images[i].size(), 0 );
|
||||
KeyPointsFilter::runByKeypointSize( keypoints[i], std::numeric_limits<float>::epsilon() );
|
||||
}
|
||||
|
||||
trainPointCollection.add( images, keypoints );
|
||||
}
|
||||
|
||||
const std::vector<Mat>& GenericDescriptorMatcher::getTrainImages() const
|
||||
{
|
||||
return trainPointCollection.getImages();
|
||||
}
|
||||
|
||||
const std::vector<std::vector<KeyPoint> >& GenericDescriptorMatcher::getTrainKeypoints() const
|
||||
{
|
||||
return trainPointCollection.getKeypoints();
|
||||
}
|
||||
|
||||
void GenericDescriptorMatcher::clear()
|
||||
{
|
||||
trainPointCollection.clear();
|
||||
}
|
||||
|
||||
void GenericDescriptorMatcher::train()
|
||||
{}
|
||||
|
||||
void GenericDescriptorMatcher::classify( InputArray queryImage, std::vector<KeyPoint>& queryKeypoints,
|
||||
InputArray trainImage, std::vector<KeyPoint>& trainKeypoints ) const
|
||||
{
|
||||
std::vector<DMatch> matches;
|
||||
match( queryImage, queryKeypoints, trainImage, trainKeypoints, matches );
|
||||
|
||||
// remap keypoint indices to descriptors
|
||||
for( size_t i = 0; i < matches.size(); i++ )
|
||||
queryKeypoints[matches[i].queryIdx].class_id = trainKeypoints[matches[i].trainIdx].class_id;
|
||||
}
|
||||
|
||||
void GenericDescriptorMatcher::classify( InputArray queryImage, std::vector<KeyPoint>& queryKeypoints )
|
||||
{
|
||||
std::vector<DMatch> matches;
|
||||
match( queryImage, queryKeypoints, matches );
|
||||
|
||||
// remap keypoint indices to descriptors
|
||||
for( size_t i = 0; i < matches.size(); i++ )
|
||||
queryKeypoints[matches[i].queryIdx].class_id = trainPointCollection.getKeyPoint( matches[i].trainIdx, matches[i].trainIdx ).class_id;
|
||||
}
|
||||
|
||||
void GenericDescriptorMatcher::match( InputArray queryImage, std::vector<KeyPoint>& queryKeypoints,
|
||||
InputArray _trainImage, std::vector<KeyPoint>& trainKeypoints,
|
||||
std::vector<DMatch>& matches, InputArray mask ) const
|
||||
{
|
||||
Mat trainImage = _trainImage.getMat();
|
||||
Ptr<GenericDescriptorMatcher> tempMatcher = clone( true );
|
||||
std::vector<std::vector<KeyPoint> > vecTrainPoints(1, trainKeypoints);
|
||||
tempMatcher->add( std::vector<Mat>(1, trainImage), vecTrainPoints );
|
||||
tempMatcher->match( queryImage, queryKeypoints, matches, std::vector<Mat>(1, mask.getMat()) );
|
||||
vecTrainPoints[0].swap( trainKeypoints );
|
||||
}
|
||||
|
||||
void GenericDescriptorMatcher::knnMatch( InputArray queryImage, std::vector<KeyPoint>& queryKeypoints,
|
||||
InputArray _trainImage, std::vector<KeyPoint>& trainKeypoints,
|
||||
std::vector<std::vector<DMatch> >& matches, int knn, InputArray mask, bool compactResult ) const
|
||||
{
|
||||
Mat trainImage = _trainImage.getMat();
|
||||
Ptr<GenericDescriptorMatcher> tempMatcher = clone( true );
|
||||
std::vector<std::vector<KeyPoint> > vecTrainPoints(1, trainKeypoints);
|
||||
tempMatcher->add( std::vector<Mat>(1, trainImage), vecTrainPoints );
|
||||
tempMatcher->knnMatch( queryImage, queryKeypoints, matches, knn, std::vector<Mat>(1, mask.getMat()), compactResult );
|
||||
vecTrainPoints[0].swap( trainKeypoints );
|
||||
}
|
||||
|
||||
void GenericDescriptorMatcher::radiusMatch( InputArray queryImage, std::vector<KeyPoint>& queryKeypoints,
|
||||
InputArray _trainImage, std::vector<KeyPoint>& trainKeypoints,
|
||||
std::vector<std::vector<DMatch> >& matches, float maxDistance,
|
||||
InputArray mask, bool compactResult ) const
|
||||
{
|
||||
Mat trainImage = _trainImage.getMat();
|
||||
Ptr<GenericDescriptorMatcher> tempMatcher = clone( true );
|
||||
std::vector<std::vector<KeyPoint> > vecTrainPoints(1, trainKeypoints);
|
||||
tempMatcher->add( std::vector<Mat>(1, trainImage), vecTrainPoints );
|
||||
tempMatcher->radiusMatch( queryImage, queryKeypoints, matches, maxDistance, std::vector<Mat>(1, mask.getMat()), compactResult );
|
||||
vecTrainPoints[0].swap( trainKeypoints );
|
||||
}
|
||||
|
||||
void GenericDescriptorMatcher::match( InputArray queryImage, std::vector<KeyPoint>& queryKeypoints,
|
||||
std::vector<DMatch>& matches, InputArrayOfArrays masks )
|
||||
{
|
||||
std::vector<std::vector<DMatch> > knnMatches;
|
||||
knnMatch( queryImage, queryKeypoints, knnMatches, 1, masks, false );
|
||||
convertMatches( knnMatches, matches );
|
||||
}
|
||||
|
||||
void GenericDescriptorMatcher::knnMatch( InputArray queryImage, std::vector<KeyPoint>& queryKeypoints,
|
||||
std::vector<std::vector<DMatch> >& matches, int knn,
|
||||
InputArrayOfArrays masks, bool compactResult )
|
||||
{
|
||||
matches.clear();
|
||||
|
||||
if( queryImage.empty() || queryKeypoints.empty() )
|
||||
return;
|
||||
|
||||
KeyPointsFilter::runByImageBorder( queryKeypoints, queryImage.size(), 0 );
|
||||
KeyPointsFilter::runByKeypointSize( queryKeypoints, std::numeric_limits<float>::epsilon() );
|
||||
|
||||
train();
|
||||
knnMatchImpl( queryImage, queryKeypoints, matches, knn, masks, compactResult );
|
||||
}
|
||||
|
||||
void GenericDescriptorMatcher::radiusMatch( InputArray queryImage, std::vector<KeyPoint>& queryKeypoints,
|
||||
std::vector<std::vector<DMatch> >& matches, float maxDistance,
|
||||
InputArrayOfArrays masks, bool compactResult )
|
||||
{
|
||||
matches.clear();
|
||||
|
||||
if( queryImage.empty() || queryKeypoints.empty() )
|
||||
return;
|
||||
|
||||
KeyPointsFilter::runByImageBorder( queryKeypoints, queryImage.size(), 0 );
|
||||
KeyPointsFilter::runByKeypointSize( queryKeypoints, std::numeric_limits<float>::epsilon() );
|
||||
|
||||
train();
|
||||
radiusMatchImpl( queryImage, queryKeypoints, matches, maxDistance, masks, compactResult );
|
||||
}
|
||||
|
||||
void GenericDescriptorMatcher::read( const FileNode& )
|
||||
{}
|
||||
|
||||
void GenericDescriptorMatcher::write( FileStorage& ) const
|
||||
{}
|
||||
|
||||
bool GenericDescriptorMatcher::empty() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Factory function for GenericDescriptorMatch creating
|
||||
*/
|
||||
Ptr<GenericDescriptorMatcher> GenericDescriptorMatcher::create( const String& genericDescritptorMatcherType,
|
||||
const String ¶msFilename )
|
||||
{
|
||||
Ptr<GenericDescriptorMatcher> descriptorMatcher =
|
||||
Algorithm::create<GenericDescriptorMatcher>("DescriptorMatcher." + genericDescritptorMatcherType);
|
||||
|
||||
if( !paramsFilename.empty() && descriptorMatcher )
|
||||
{
|
||||
FileStorage fs = FileStorage( paramsFilename, FileStorage::READ );
|
||||
if( fs.isOpened() )
|
||||
{
|
||||
descriptorMatcher->read( fs.root() );
|
||||
fs.release();
|
||||
}
|
||||
}
|
||||
return descriptorMatcher;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************************\
|
||||
* VectorDescriptorMatcher *
|
||||
\****************************************************************************************/
|
||||
VectorDescriptorMatcher::VectorDescriptorMatcher( const Ptr<DescriptorExtractor>& _extractor,
|
||||
const Ptr<DescriptorMatcher>& _matcher )
|
||||
: extractor( _extractor ), matcher( _matcher )
|
||||
{
|
||||
CV_Assert( extractor && matcher );
|
||||
}
|
||||
|
||||
VectorDescriptorMatcher::~VectorDescriptorMatcher()
|
||||
{}
|
||||
|
||||
void VectorDescriptorMatcher::add( InputArrayOfArrays _imgCollection,
|
||||
std::vector<std::vector<KeyPoint> >& pointCollection )
|
||||
{
|
||||
std::vector<Mat> imgCollection, descriptors;
|
||||
_imgCollection.getMatVector(imgCollection);
|
||||
extractor->compute( imgCollection, pointCollection, descriptors );
|
||||
|
||||
matcher->add( descriptors );
|
||||
|
||||
trainPointCollection.add( imgCollection, pointCollection );
|
||||
}
|
||||
|
||||
void VectorDescriptorMatcher::clear()
|
||||
{
|
||||
//extractor->clear();
|
||||
matcher->clear();
|
||||
GenericDescriptorMatcher::clear();
|
||||
}
|
||||
|
||||
void VectorDescriptorMatcher::train()
|
||||
{
|
||||
matcher->train();
|
||||
}
|
||||
|
||||
bool VectorDescriptorMatcher::isMaskSupported()
|
||||
{
|
||||
return matcher->isMaskSupported();
|
||||
}
|
||||
|
||||
void VectorDescriptorMatcher::knnMatchImpl( InputArray queryImage, std::vector<KeyPoint>& queryKeypoints,
|
||||
std::vector<std::vector<DMatch> >& matches, int knn,
|
||||
InputArrayOfArrays masks, bool compactResult )
|
||||
{
|
||||
Mat queryDescriptors;
|
||||
extractor->compute( queryImage, queryKeypoints, queryDescriptors );
|
||||
matcher->knnMatch( queryDescriptors, matches, knn, masks, compactResult );
|
||||
}
|
||||
|
||||
void VectorDescriptorMatcher::radiusMatchImpl( InputArray queryImage, std::vector<KeyPoint>& queryKeypoints,
|
||||
std::vector<std::vector<DMatch> >& matches, float maxDistance,
|
||||
InputArrayOfArrays masks, bool compactResult )
|
||||
{
|
||||
Mat queryDescriptors;
|
||||
extractor->compute( queryImage, queryKeypoints, queryDescriptors );
|
||||
matcher->radiusMatch( queryDescriptors, matches, maxDistance, masks, compactResult );
|
||||
}
|
||||
|
||||
void VectorDescriptorMatcher::read( const FileNode& fn )
|
||||
{
|
||||
GenericDescriptorMatcher::read(fn);
|
||||
extractor->read(fn);
|
||||
}
|
||||
|
||||
void VectorDescriptorMatcher::write (FileStorage& fs) const
|
||||
{
|
||||
GenericDescriptorMatcher::write(fs);
|
||||
extractor->write (fs);
|
||||
}
|
||||
|
||||
bool VectorDescriptorMatcher::empty() const
|
||||
{
|
||||
return !extractor || extractor->empty() ||
|
||||
!matcher || matcher->empty();
|
||||
}
|
||||
|
||||
Ptr<GenericDescriptorMatcher> VectorDescriptorMatcher::clone( bool emptyTrainData ) const
|
||||
{
|
||||
// TODO clone extractor
|
||||
return makePtr<VectorDescriptorMatcher>( extractor, matcher->clone(emptyTrainData) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user