added match()
This commit is contained in:
parent
411e16074e
commit
601e9af9f8
@ -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:
|
|||||||
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:
|
|||||||
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,
|
|||||||
}
|
}
|
||||||
|
|
||||||
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,
|
|||||||
}
|
}
|
||||||
|
|
||||||
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,
|
|||||||
|
|
||||||
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,
|
|||||||
}
|
}
|
||||||
|
|
||||||
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
|
|||||||
\****************************************************************************************/
|
\****************************************************************************************/
|
||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
{
|
{
|
||||||
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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user