*/
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
*
virtual void clear();
protected:
- Mat train;
+ Mat m_train;
/*
* Find matches; match() calls this. Must be implemented by the subclass.
* 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.
* 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 )
BruteForceMatcher( Distance d = Distance() ) : distance(d) {}
virtual void index() {}
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;
};
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;
- matchImpl( query, mask, fullMatches);
+ matchImpl( query, train, fullMatches, mask );
matches.clear();
matches.resize( fullMatches.size() );
for( size_t i=0;i<fullMatches.size();i++)
}
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::ResultType DistanceType;
}
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::ResultType DistanceType;
assert( query.cols == train.cols || query.empty() || train.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;
matches.clear();
}
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 );
\****************************************************************************************/
void DescriptorMatcher::add( const Mat& descriptors )
{
- if( train.empty() )
+ if( m_train.empty() )
{
- train = descriptors;
+ m_train = descriptors;
}
else
{
// merge train and descriptors
- Mat m( train.rows + descriptors.rows, train.cols, CV_32F );
- Mat m1 = m.rowRange( 0, train.rows );
- train.copyTo( m1 );
- Mat m2 = m.rowRange( train.rows + 1, m.rows );
+ Mat m( m_train.rows + descriptors.rows, m_train.cols, CV_32F );
+ Mat m1 = m.rowRange( 0, m_train.rows );
+ m_train.copyTo( m1 );
+ Mat m2 = m.rowRange( m_train.rows + 1, m.rows );
descriptors.copyTo( m2 );
- train = m;
+ m_train = m;
}
}
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,
vector<int>& matches ) const
{
- matchImpl( query, mask, matches );
+ matchImpl( query, m_train, matches, mask );
}
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,
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
{
- matchImpl( query, Mat(), matches, threshold );
+ matchImpl( query, m_train, matches, threshold, Mat() );
}
void DescriptorMatcher::match( const Mat& query, const Mat& mask,
vector<vector<DMatch> >& matches, float threshold ) const
{
- matchImpl( query, mask, matches, threshold );
+ matchImpl( query, m_train, matches, threshold, mask );
}
void DescriptorMatcher::clear()
{
- train.release();
+ m_train.release();
}
/*
* BruteForceMatcher L2 specialization
*/
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( query.cols == train.cols || query.empty() || train.empty() );
cout << ">" << endl;
cout << "< Matching descriptors..." << endl;
- vector<int> matches;
- descriptorMatcher->clear();
- descriptorMatcher->add( descriptors2 );
- descriptorMatcher->match( descriptors1, matches );
+ vector<DMatch> matches;
+ descriptorMatcher->match( descriptors1, descriptors2, matches, Mat() );
cout << ">" << endl;
if( !H12.empty() )
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 )
{
cout << "< Computing homography (RANSAC)..." << endl;
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 );
cout << ">" << endl;
}
{
vector<char> matchesMask( matches.size(), 0 );
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);
- vector<int>::const_iterator mit = matches.begin();
for( size_t i1 = 0; i1 < points1.size(); i1++ )
{
if( norm(points2[i1] - points1t.at<Point2f>(i1,0)) < 4 ) // inlier