Commit 601e9af9 authored by Maria Dimashova's avatar Maria Dimashova

added match()

parent 411e1607
...@@ -1659,6 +1659,8 @@ public: ...@@ -1659,6 +1659,8 @@ public:
*/ */
void match( const Mat& query, const Mat& mask, vector<DMatch>& matches ) const; void match( const Mat& query, const Mat& mask, vector<DMatch>& matches ) const;
void match( const Mat& query, const Mat& train, vector<DMatch>& matches, const Mat& mask ) const;
/* /*
* Find many matches for each descriptor from a query set * Find many matches for each descriptor from a query set
* *
...@@ -1686,21 +1688,21 @@ public: ...@@ -1686,21 +1688,21 @@ public:
virtual void clear(); virtual void clear();
protected: protected:
Mat train; Mat m_train;
/* /*
* Find matches; match() calls this. Must be implemented by the subclass. * Find matches; match() calls this. Must be implemented by the subclass.
* The mask may be empty. * The mask may be empty.
*/ */
virtual void matchImpl( const Mat& query, const Mat& mask, vector<int>& matches ) const = 0; virtual void matchImpl( const Mat& query, const Mat& train, vector<int>& matches, const Mat& mask ) const = 0;
/* /*
* Find matches; match() calls this. Must be implemented by the subclass. * Find matches; match() calls this. Must be implemented by the subclass.
* The mask may be empty. * The mask may be empty.
*/ */
virtual void matchImpl( const Mat& query, const Mat& mask, vector<DMatch>& matches ) const = 0; virtual void matchImpl( const Mat& query, const Mat& train, vector<DMatch>& matches, const Mat& mask ) const = 0;
virtual void matchImpl( const Mat& query, const Mat& mask, vector<vector<DMatch> >& matches, float threshold ) const = 0; virtual void matchImpl( const Mat& query, const Mat& train, vector<vector<DMatch> >& matches, float threshold, const Mat& mask ) const = 0;
static bool possibleMatch( const Mat& mask, int index_1, int index_2 ) static bool possibleMatch( const Mat& mask, int index_1, int index_2 )
...@@ -1725,20 +1727,20 @@ public: ...@@ -1725,20 +1727,20 @@ public:
BruteForceMatcher( Distance d = Distance() ) : distance(d) {} BruteForceMatcher( Distance d = Distance() ) : distance(d) {}
virtual void index() {} virtual void index() {}
protected: protected:
virtual void matchImpl( const Mat& query, const Mat& mask, vector<int>& matches ) const; virtual void matchImpl( const Mat& query, const Mat& train, vector<int>& matches, const Mat& mask ) const;
virtual void matchImpl( const Mat& query, const Mat& mask, vector<DMatch>& matches ) const; virtual void matchImpl( const Mat& query, const Mat& train, vector<DMatch>& matches, const Mat& mask ) const;
virtual void matchImpl( const Mat& query, const Mat& mask, vector<vector<DMatch> >& matches, float threshold ) const; virtual void matchImpl( const Mat& query, const Mat& train, vector<vector<DMatch> >& matches, float threshold, const Mat& mask ) const;
Distance distance; Distance distance;
}; };
template<class Distance> inline template<class Distance> inline
void BruteForceMatcher<Distance>::matchImpl( const Mat& query, const Mat& mask, vector<int>& matches ) const void BruteForceMatcher<Distance>::matchImpl( const Mat& query, const Mat& train, vector<int>& matches, const Mat& mask ) const
{ {
vector<DMatch> fullMatches; vector<DMatch> fullMatches;
matchImpl( query, mask, fullMatches); matchImpl( query, train, fullMatches, mask );
matches.clear(); matches.clear();
matches.resize( fullMatches.size() ); matches.resize( fullMatches.size() );
for( size_t i=0;i<fullMatches.size();i++) for( size_t i=0;i<fullMatches.size();i++)
...@@ -1748,7 +1750,7 @@ void BruteForceMatcher<Distance>::matchImpl( const Mat& query, const Mat& mask, ...@@ -1748,7 +1750,7 @@ void BruteForceMatcher<Distance>::matchImpl( const Mat& query, const Mat& mask,
} }
template<class Distance> inline template<class Distance> inline
void BruteForceMatcher<Distance>::matchImpl( const Mat& query, const Mat& mask, vector<DMatch>& matches ) const void BruteForceMatcher<Distance>::matchImpl( const Mat& query, const Mat& train, vector<DMatch>& matches, const Mat& mask ) const
{ {
typedef typename Distance::ValueType ValueType; typedef typename Distance::ValueType ValueType;
typedef typename Distance::ResultType DistanceType; typedef typename Distance::ResultType DistanceType;
...@@ -1795,7 +1797,8 @@ void BruteForceMatcher<Distance>::matchImpl( const Mat& query, const Mat& mask, ...@@ -1795,7 +1797,8 @@ void BruteForceMatcher<Distance>::matchImpl( const Mat& query, const Mat& mask,
} }
template<class Distance> inline template<class Distance> inline
void BruteForceMatcher<Distance>::matchImpl( const Mat& query, const Mat& mask, vector<vector<DMatch> >& matches, float threshold ) const void BruteForceMatcher<Distance>::matchImpl( const Mat& query, const Mat& train, vector<vector<DMatch> >& matches,
float threshold, const Mat& mask ) const
{ {
typedef typename Distance::ValueType ValueType; typedef typename Distance::ValueType ValueType;
typedef typename Distance::ResultType DistanceType; typedef typename Distance::ResultType DistanceType;
...@@ -1804,7 +1807,7 @@ void BruteForceMatcher<Distance>::matchImpl( const Mat& query, const Mat& mask, ...@@ -1804,7 +1807,7 @@ void BruteForceMatcher<Distance>::matchImpl( const Mat& query, const Mat& mask,
assert( query.cols == train.cols || query.empty() || train.empty() ); assert( query.cols == train.cols || query.empty() || train.empty() );
assert( DataType<ValueType>::type == query.type() || query.empty() ); assert( DataType<ValueType>::type == query.type() || query.empty() );
assert( DataType<ValueType>::type == train.type() || train.empty() ); assert( DataType<ValueType>::type == train.type() || train.empty() );
int dimension = query.cols; int dimension = query.cols;
matches.clear(); matches.clear();
...@@ -1834,7 +1837,7 @@ void BruteForceMatcher<Distance>::matchImpl( const Mat& query, const Mat& mask, ...@@ -1834,7 +1837,7 @@ void BruteForceMatcher<Distance>::matchImpl( const Mat& query, const Mat& mask,
} }
template<> template<>
void BruteForceMatcher<L2<float> >::matchImpl( const Mat& query, const Mat& mask, vector<DMatch>& matches ) const; void BruteForceMatcher<L2<float> >::matchImpl( const Mat& query, const Mat& train, vector<DMatch>& matches, const Mat& mask) const;
CV_EXPORTS Ptr<DescriptorMatcher> createDescriptorMatcher( const string& descriptorMatcherType ); CV_EXPORTS Ptr<DescriptorMatcher> createDescriptorMatcher( const string& descriptorMatcherType );
......
...@@ -431,65 +431,70 @@ Ptr<DescriptorMatcher> createDescriptorMatcher( const string& descriptorMatcherT ...@@ -431,65 +431,70 @@ Ptr<DescriptorMatcher> createDescriptorMatcher( const string& descriptorMatcherT
\****************************************************************************************/ \****************************************************************************************/
void DescriptorMatcher::add( const Mat& descriptors ) void DescriptorMatcher::add( const Mat& descriptors )
{ {
if( train.empty() ) if( m_train.empty() )
{ {
train = descriptors; m_train = descriptors;
} }
else else
{ {
// merge train and descriptors // merge train and descriptors
Mat m( train.rows + descriptors.rows, train.cols, CV_32F ); Mat m( m_train.rows + descriptors.rows, m_train.cols, CV_32F );
Mat m1 = m.rowRange( 0, train.rows ); Mat m1 = m.rowRange( 0, m_train.rows );
train.copyTo( m1 ); m_train.copyTo( m1 );
Mat m2 = m.rowRange( train.rows + 1, m.rows ); Mat m2 = m.rowRange( m_train.rows + 1, m.rows );
descriptors.copyTo( m2 ); descriptors.copyTo( m2 );
train = m; m_train = m;
} }
} }
void DescriptorMatcher::match( const Mat& query, vector<int>& matches ) const void DescriptorMatcher::match( const Mat& query, vector<int>& matches ) const
{ {
matchImpl( query, Mat(), matches ); matchImpl( query, m_train, matches, Mat() );
} }
void DescriptorMatcher::match( const Mat& query, const Mat& mask, void DescriptorMatcher::match( const Mat& query, const Mat& mask,
vector<int>& matches ) const vector<int>& matches ) const
{ {
matchImpl( query, mask, matches ); matchImpl( query, m_train, matches, mask );
} }
void DescriptorMatcher::match( const Mat& query, vector<DMatch>& matches ) const void DescriptorMatcher::match( const Mat& query, vector<DMatch>& matches ) const
{ {
matchImpl( query, Mat(), matches ); matchImpl( query, m_train, matches, Mat() );
} }
void DescriptorMatcher::match( const Mat& query, const Mat& mask, void DescriptorMatcher::match( const Mat& query, const Mat& mask,
vector<DMatch>& matches ) const vector<DMatch>& matches ) const
{ {
matchImpl( query, mask, matches ); matchImpl( query, m_train, matches, mask );
}
void DescriptorMatcher::match( const Mat& query, const Mat& train, vector<DMatch>& matches, const Mat& mask ) const
{
matchImpl( query, train, matches, mask );
} }
void DescriptorMatcher::match( const Mat& query, vector<vector<DMatch> >& matches, float threshold ) const void DescriptorMatcher::match( const Mat& query, vector<vector<DMatch> >& matches, float threshold ) const
{ {
matchImpl( query, Mat(), matches, threshold ); matchImpl( query, m_train, matches, threshold, Mat() );
} }
void DescriptorMatcher::match( const Mat& query, const Mat& mask, void DescriptorMatcher::match( const Mat& query, const Mat& mask,
vector<vector<DMatch> >& matches, float threshold ) const vector<vector<DMatch> >& matches, float threshold ) const
{ {
matchImpl( query, mask, matches, threshold ); matchImpl( query, m_train, matches, threshold, mask );
} }
void DescriptorMatcher::clear() void DescriptorMatcher::clear()
{ {
train.release(); m_train.release();
} }
/* /*
* BruteForceMatcher L2 specialization * BruteForceMatcher L2 specialization
*/ */
template<> template<>
void BruteForceMatcher<L2<float> >::matchImpl( const Mat& query, const Mat& mask, vector<DMatch>& matches ) const void BruteForceMatcher<L2<float> >::matchImpl( const Mat& query, const Mat& train, vector<DMatch>& matches, const Mat& mask ) const
{ {
assert( mask.empty() || (mask.rows == query.rows && mask.cols == train.rows) ); assert( mask.empty() || (mask.rows == query.rows && mask.cols == train.rows) );
assert( query.cols == train.cols || query.empty() || train.empty() ); assert( query.cols == train.cols || query.empty() || train.empty() );
......
...@@ -64,10 +64,8 @@ void doIteration( const Mat& img1, Mat& img2, bool isWarpPerspective, ...@@ -64,10 +64,8 @@ void doIteration( const Mat& img1, Mat& img2, bool isWarpPerspective,
cout << ">" << endl; cout << ">" << endl;
cout << "< Matching descriptors..." << endl; cout << "< Matching descriptors..." << endl;
vector<int> matches; vector<DMatch> matches;
descriptorMatcher->clear(); descriptorMatcher->match( descriptors1, descriptors2, matches, Mat() );
descriptorMatcher->add( descriptors2 );
descriptorMatcher->match( descriptors1, matches );
cout << ">" << endl; cout << ">" << endl;
if( !H12.empty() ) if( !H12.empty() )
...@@ -81,11 +79,15 @@ void doIteration( const Mat& img1, Mat& img2, bool isWarpPerspective, ...@@ -81,11 +79,15 @@ void doIteration( const Mat& img1, Mat& img2, bool isWarpPerspective,
cout << ">" << endl; cout << ">" << endl;
} }
vector<int> trainIdxs( matches.size() );
for( size_t i = 0; i < matches.size(); i++ )
trainIdxs[i] = matches[i].indexTrain;
if( !isWarpPerspective && ransacReprojThreshold >= 0 ) if( !isWarpPerspective && ransacReprojThreshold >= 0 )
{ {
cout << "< Computing homography (RANSAC)..." << endl; cout << "< Computing homography (RANSAC)..." << endl;
vector<Point2f> points1; KeyPoint::convert(keypoints1, points1); vector<Point2f> points1; KeyPoint::convert(keypoints1, points1);
vector<Point2f> points2; KeyPoint::convert(keypoints2, points2, matches); vector<Point2f> points2; KeyPoint::convert(keypoints2, points2, trainIdxs);
H12 = findHomography( Mat(points1), Mat(points2), CV_RANSAC, ransacReprojThreshold ); H12 = findHomography( Mat(points1), Mat(points2), CV_RANSAC, ransacReprojThreshold );
cout << ">" << endl; cout << ">" << endl;
} }
...@@ -95,9 +97,8 @@ void doIteration( const Mat& img1, Mat& img2, bool isWarpPerspective, ...@@ -95,9 +97,8 @@ void doIteration( const Mat& img1, Mat& img2, bool isWarpPerspective,
{ {
vector<char> matchesMask( matches.size(), 0 ); vector<char> matchesMask( matches.size(), 0 );
vector<Point2f> points1; KeyPoint::convert(keypoints1, points1); vector<Point2f> points1; KeyPoint::convert(keypoints1, points1);
vector<Point2f> points2; KeyPoint::convert(keypoints2, points2, matches); vector<Point2f> points2; KeyPoint::convert(keypoints2, points2, trainIdxs);
Mat points1t; perspectiveTransform(Mat(points1), points1t, H12); Mat points1t; perspectiveTransform(Mat(points1), points1t, H12);
vector<int>::const_iterator mit = matches.begin();
for( size_t i1 = 0; i1 < points1.size(); i1++ ) for( size_t i1 = 0; i1 < points1.size(); i1++ )
{ {
if( norm(points2[i1] - points1t.at<Point2f>(i1,0)) < 4 ) // inlier if( norm(points2[i1] - points1t.at<Point2f>(i1,0)) < 4 ) // inlier
......
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