Commit add94f9b authored by Ilya Lysenkov's avatar Ilya Lysenkov

Added L1 distance code and used factory functions in evaluation framework

parent 4bcd81f8
......@@ -1507,6 +1507,27 @@ struct CV_EXPORTS L2
}
};
/*
* Manhattan distance (city block distance) functor
*/
template<class T>
struct CV_EXPORTS L1
{
typedef T ValueType;
typedef typename Accumulator<T>::Type ResultType;
ResultType operator()( const T* a, const T* b, int size ) const
{
ResultType result = ResultType();
for( int i = 0; i < size; i++ )
{
ResultType diff = a[i] - b[i];
result += fabs( diff );
}
return result;
}
};
/****************************************************************************************\
* DMatch *
......@@ -1755,6 +1776,7 @@ void BruteForceMatcher<Distance>::matchImpl( const Mat& descriptors_1, const Mat
{
vector<DMatch> matchings;
matchImpl( descriptors_1, descriptors_2, mask, matchings);
matches.clear();
matches.resize( matchings.size() );
for( size_t i=0;i<matchings.size();i++)
{
......@@ -1776,6 +1798,7 @@ void BruteForceMatcher<Distance>::matchImpl( const Mat& descriptors_1, const Mat
assert( DataType<ValueType>::type == descriptors_2.type() || descriptors_2.empty() );
int dimension = descriptors_1.cols;
matches.clear();
matches.resize(descriptors_1.rows);
for( int i = 0; i < descriptors_1.rows; i++ )
......@@ -1823,6 +1846,7 @@ void BruteForceMatcher<Distance>::matchImpl( const Mat& descriptors_1, const Mat
assert( DataType<ValueType>::type == descriptors_2.type() || descriptors_2.empty() );
int dimension = descriptors_1.cols;
matches.clear();
matches.resize( descriptors_1.rows );
for( int i = 0; i < descriptors_1.rows; i++ )
......@@ -1931,8 +1955,6 @@ public:
// Writes match object to a file storage
virtual void write( FileStorage& fs ) const {};
static GenericDescriptorMatch* CreateDescriptorMatch( const string &alg_name, const string &params_filename = string () );
protected:
KeyPointCollection collection;
};
......@@ -1998,6 +2020,8 @@ public:
virtual void match( const Mat& image, vector<KeyPoint>& points, vector<DMatch>& matches );
virtual void match( const Mat& image, vector<KeyPoint>& points, vector<vector<DMatch> >& matches, float threshold);
// Classify a set of keypoints. The same as match, but returns point classes rather than indices
virtual void classify( const Mat& image, vector<KeyPoint>& points );
......@@ -2146,6 +2170,7 @@ protected:
Params params;
};
GenericDescriptorMatch* createDescriptorMatch( const string& genericDescritptorMatchType, const string &paramsFilename = string () );
/****************************************************************************************\
* VectorDescriptorMatch *
\****************************************************************************************/
......@@ -2159,7 +2184,7 @@ class CV_EXPORTS VectorDescriptorMatch : public GenericDescriptorMatch
public:
using GenericDescriptorMatch::add;
VectorDescriptorMatch( const Extractor& _extractor = Extractor(), const Matcher& _matcher = Matcher() ) :
VectorDescriptorMatch( Extractor *_extractor = 0, Matcher * _matcher = 0 ) :
extractor(_extractor), matcher(_matcher) {}
~VectorDescriptorMatch() {}
......@@ -2171,8 +2196,8 @@ public:
virtual void add( const Mat& image, vector<KeyPoint>& keypoints )
{
Mat descriptors;
extractor.compute( image, keypoints, descriptors );
matcher.add( descriptors );
extractor->compute( image, keypoints, descriptors );
matcher->add( descriptors );
collection.add( Mat(), keypoints );
};
......@@ -2181,47 +2206,47 @@ public:
virtual void match( const Mat& image, vector<KeyPoint>& points, vector<int>& keypointIndices )
{
Mat descriptors;
extractor.compute( image, points, descriptors );
extractor->compute( image, points, descriptors );
matcher.match( descriptors, keypointIndices );
matcher->match( descriptors, keypointIndices );
};
virtual void match( const Mat& image, vector<KeyPoint>& points, vector<DMatch>& matches )
{
Mat descriptors;
extractor.compute( image, points, descriptors );
extractor->compute( image, points, descriptors );
matcher.match( descriptors, matches );
matcher->match( descriptors, matches );
}
virtual void match( const Mat& image, vector<KeyPoint>& points, vector<vector<DMatch> >& matches, float threshold )
{
Mat descriptors;
extractor.compute( image, points, descriptors );
extractor->compute( image, points, descriptors );
matcher.match( descriptors, matches, threshold );
matcher->match( descriptors, matches, threshold );
}
virtual void clear()
{
GenericDescriptorMatch::clear();
matcher.clear();
matcher->clear();
}
virtual void read (const FileNode& fn)
{
GenericDescriptorMatch::read(fn);
extractor.read (fn);
extractor->read (fn);
}
virtual void write (FileStorage& fs) const
{
GenericDescriptorMatch::write(fs);
extractor.write (fs);
extractor->write (fs);
}
protected:
Extractor extractor;
Matcher matcher;
Ptr<Extractor> extractor;
Ptr<Matcher> matcher;
//vector<int> classIds;
};
......
......@@ -40,6 +40,7 @@
//M*/
#include "precomp.hpp"
#include <stdio.h>
//#define _KDTREE
......@@ -254,6 +255,10 @@ DescriptorMatcher* createDescriptorMatcher( const string& descriptorMatcherType
{
dm = new BruteForceMatcher<L2<float> >();
}
else if ( !descriptorMatcherType.compare( "BruteForce-L1" ) )
{
dm = new BruteForceMatcher<L1<float> >();
}
else
{
//CV_Error( CV_StsBadArg, "unsupported descriptor matcher type");
......@@ -330,27 +335,27 @@ void GenericDescriptorMatch::clear()
collection.clear();
}
GenericDescriptorMatch* GenericDescriptorMatch::CreateDescriptorMatch( const string &alg_name, const string &params_filename )
GenericDescriptorMatch* createDescriptorMatch( const string& genericDescritptorMatchType, const string &paramsFilename )
{
GenericDescriptorMatch *descriptorMatch = 0;
if( ! alg_name.compare ("one_way") )
if( ! genericDescritptorMatchType.compare ("ONEWAY") )
{
descriptorMatch = new OneWayDescriptorMatch ();
}
else if( ! alg_name.compare ("fern") )
else if( ! genericDescritptorMatchType.compare ("FERN") )
{
FernDescriptorMatch::Params params;
params.signatureSize = INT_MAX;
params.signatureSize = numeric_limits<int>::max();
descriptorMatch = new FernDescriptorMatch (params);
}
else if( ! alg_name.compare ("calonder") )
else if( ! genericDescritptorMatchType.compare ("CALONDER") )
{
descriptorMatch = new CalonderDescriptorMatch ();
}
if( !params_filename.empty() && descriptorMatch != 0 )
if( !paramsFilename.empty() && descriptorMatch != 0 )
{
FileStorage fs = FileStorage( params_filename, FileStorage::READ );
FileStorage fs = FileStorage( paramsFilename, FileStorage::READ );
if( fs.isOpened() )
{
descriptorMatch->read( fs.root() );
......@@ -460,6 +465,76 @@ void OneWayDescriptorMatch::match( const Mat& image, vector<KeyPoint>& points, v
}
}
void OneWayDescriptorMatch::match( const Mat& image, vector<KeyPoint>& points, vector<vector<DMatch> >& matches, float threshold )
{
matches.clear();
matches.resize( points.size() );
IplImage _image = image;
vector<DMatch> dmatches;
match( image, points, dmatches );
for( size_t i=0;i<matches.size();i++ )
{
matches[i].push_back( dmatches[i] );
}
/*
printf("Start matching %d points\n", points.size());
//std::cout << "Start matching " << points.size() << "points\n";
assert(collection.images.size() == 1);
int n = collection.points[0].size();
printf("n = %d\n", n);
for( size_t i = 0; i < points.size(); i++ )
{
//printf("Matching %d\n", i);
//int poseIdx = -1;
DMatch match;
match.indexQuery = i;
match.indexTrain = -1;
CvPoint pt = points[i].pt;
CvRect roi = cvRect(cvRound(pt.x - 24/4),
cvRound(pt.y - 24/4),
24/2, 24/2);
cvSetImageROI(&_image, roi);
std::vector<int> desc_idxs;
std::vector<int> pose_idxs;
std::vector<float> distances;
std::vector<float> _scales;
base->FindDescriptor(&_image, n, desc_idxs, pose_idxs, distances, _scales);
cvResetImageROI(&_image);
for( int j=0;j<n;j++ )
{
match.indexTrain = desc_idxs[j];
match.distance = distances[j];
matches[i].push_back( match );
}
//sort( matches[i].begin(), matches[i].end(), compareIndexTrain );
//for( int j=0;j<n;j++ )
//{
//printf( "%d %f; ",matches[i][j].indexTrain, matches[i][j].distance);
//}
//printf("\n\n\n");
//base->FindDescriptor( &_image, 100, points[i].pt, match.indexTrain, poseIdx, match.distance );
//matches[i].push_back( match );
}
*/
}
void OneWayDescriptorMatch::read( const FileNode &fn )
{
base = new OneWayDescriptorObject( params.patchSize, params.poseCount, string (), string (), string (),
......
......@@ -344,6 +344,11 @@ FeatureDetector* createDetector( const string& detectorType )
5/*edge_blur_size*/ );
}
else if( !detectorType.compare( "GFTT" ) )
{
fd = new GoodFeaturesToTrackDetector( 1000/*maxCorners*/, 0.01/*qualityLevel*/, 1./*minDistance*/,
3/*int _blockSize*/, false/*useHarrisDetector*/, 0.04/*k*/ );
}
else if( !detectorType.compare( "HARRIS" ) )
{
fd = new GoodFeaturesToTrackDetector( 1000/*maxCorners*/, 0.01/*qualityLevel*/, 1./*minDistance*/,
3/*int _blockSize*/, true/*useHarrisDetector*/, 0.04/*k*/ );
......
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