From 400eb371893adbb4b4c09f70239d5bde5d55b06d Mon Sep 17 00:00:00 2001 From: Maria Dimashova Date: Tue, 15 Jun 2010 15:19:11 +0000 Subject: [PATCH] added parameter keypointIndexes to KeyPoint::convert, updated sample --- .../include/opencv2/features2d/features2d.hpp | 5 ++- modules/features2d/src/keypoint.cpp | 38 +++++++++++------ samples/cpp/descriptor_extractor_matcher.cpp | 42 ++++++------------- 3 files changed, 42 insertions(+), 43 deletions(-) diff --git a/modules/features2d/include/opencv2/features2d/features2d.hpp b/modules/features2d/include/opencv2/features2d/features2d.hpp index a106d670a..9b940d378 100644 --- a/modules/features2d/include/opencv2/features2d/features2d.hpp +++ b/modules/features2d/include/opencv2/features2d/features2d.hpp @@ -221,9 +221,10 @@ public: : pt(x, y), size(_size), angle(_angle), response(_response), octave(_octave), class_id(_class_id) {} //! converts vector of keypoints to vector of points - static void convert(const std::vector& u, std::vector& v); + static void convert(const std::vector& keypoints, std::vector& points2f, + const std::vector& keypointIndexes=std::vector()); //! converts vector of points to the vector of keypoints, where each keypoint is assigned the same size and the same orientation - static void convert(const std::vector& u, std::vector& v, + static void convert(const std::vector& points2f, std::vector& keypoints, float size=1, float response=1, int octave=0, int class_id=-1); Point2f pt; //!< coordinates of the keypoints float size; //!< diameter of the meaningfull keypoint neighborhood diff --git a/modules/features2d/src/keypoint.cpp b/modules/features2d/src/keypoint.cpp index 0265004c8..71c035aaf 100644 --- a/modules/features2d/src/keypoint.cpp +++ b/modules/features2d/src/keypoint.cpp @@ -76,23 +76,37 @@ void read(const FileNode& node, vector& keypoints) } -void KeyPoint::convert(const std::vector& u, std::vector& v) +void KeyPoint::convert(const std::vector& keypoints, std::vector& points2f, + const vector& keypointIndexes) { - size_t i, sz = u.size(); - v.resize(sz); - - for( i = 0; i < sz; i++ ) - v[i] = u[i].pt; + if( keypointIndexes.empty() ) + { + points2f.resize( keypoints.size() ); + for( size_t i = 0; i < keypoints.size(); i++ ) + points2f[i] = keypoints[i].pt; + } + else + { + points2f.resize( keypointIndexes.size() ); + for( size_t i = 0; i < keypointIndexes.size(); i++ ) + { + int idx = keypointIndexes[i]; + if( idx >= 0 ) + points2f[i] = keypoints[idx].pt; + else + { + CV_Error( CV_StsBadArg, "keypointIndexes has element < 0. TODO: process this case" ); + //points2f[i] = Point2f(-1, -1); + } + } + } } -void KeyPoint::convert( const std::vector& u, std::vector& v, +void KeyPoint::convert( const std::vector& points2f, std::vector& keypoints, float size, float response, int octave, int class_id ) { - size_t i, sz = u.size(); - v.resize(sz); - - for( i = 0; i < sz; i++ ) - v[i] = KeyPoint(u[i], size, -1, response, octave, class_id); + for( size_t i = 0; i < points2f.size(); i++ ) + keypoints[i] = KeyPoint(points2f[i], size, -1, response, octave, class_id); } } diff --git a/samples/cpp/descriptor_extractor_matcher.cpp b/samples/cpp/descriptor_extractor_matcher.cpp index 87644addb..4e27108ee 100644 --- a/samples/cpp/descriptor_extractor_matcher.cpp +++ b/samples/cpp/descriptor_extractor_matcher.cpp @@ -5,21 +5,9 @@ #include "opencv2/features2d/features2d.hpp" #include - using namespace cv; using namespace std; -inline Point2f applyHomography( const Mat_& H, const Point2f& pt ) -{ - double z = H(2,0)*pt.x + H(2,1)*pt.y + H(2,2); - if( z ) - { - double w = 1./z; - return Point2f( (H(0,0)*pt.x + H(0,1)*pt.y + H(0,2))*w, (H(1,0)*pt.x + H(1,1)*pt.y + H(1,2))*w ); - } - return Point2f( numeric_limits::max(), numeric_limits::max() ); -} - void warpPerspectiveRand( const Mat& src, Mat& dst, Mat& H, RNG* rng ) { H.create(3, 3, CV_32FC1); @@ -74,40 +62,36 @@ void doIteration( const Mat& img1, Mat& img2, bool isWarpPerspective, if( !isWarpPerspective && ransacReprojThreshold >= 0 ) { cout << "< Computing homography (RANSAC)..." << endl; - vector points1(matches.size()), points2(matches.size()); - for( size_t i = 0; i < matches.size(); i++ ) - { - points1[i] = keypoints1[i].pt; - points2[i] = keypoints2[matches[i]].pt; - } + vector points1; KeyPoint::convert(keypoints1, points1); + vector points2; KeyPoint::convert(keypoints2, points2, matches); H12 = findHomography( Mat(points1), Mat(points2), CV_RANSAC, ransacReprojThreshold ); cout << ">" << endl; } Mat drawImg; - if( !H12.empty() ) + if( !H12.empty() ) // filter outliers { vector matchesMask( matches.size(), 0 ); + vector points1; KeyPoint::convert(keypoints1, points1); + vector points2; KeyPoint::convert(keypoints2, points2, matches); + Mat points1t; perspectiveTransform(Mat(points1), points1t, H12); vector::const_iterator mit = matches.begin(); - for( size_t i1 = 0; mit != matches.end(); ++mit, i1++ ) + for( size_t i1 = 0; i1 < points1.size(); i1++ ) { - Point2f pt1 = keypoints1[i1].pt, - pt2 = keypoints2[*mit].pt; - if( norm(pt2 - applyHomography(H12, pt1)) < 4 ) // inlier + if( norm(points2[i1] - points1t.at(i1,0)) < 4 ) // inlier matchesMask[i1] = 1; } // draw inliers drawMatches( img1, keypoints1, img2, keypoints2, matches, drawImg, CV_RGB(0, 255, 0), CV_RGB(0, 0, 255), matchesMask ); - // draw outliers - /*for( size_t i1 = 0; i1 < matchesMask.size(); i1++ ) +#if 0 // draw outliers + for( size_t i1 = 0; i1 < matchesMask.size(); i1++ ) matchesMask[i1] = !matchesMask[i1]; drawMatches( img1, keypoints1, img2, keypoints2, matches, drawImg, CV_RGB(0, 0, 255), CV_RGB(255, 0, 0), matchesMask, - DrawMatchesFlags::DRAW_OVER_OUTIMG | DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );*/ + DrawMatchesFlags::DRAW_OVER_OUTIMG | DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS ) +#endif } else - { - drawMatches( img1, keypoints1, img2, keypoints2, matches, drawImg, CV_RGB(0, 255, 0) ); - } + drawMatches( img1, keypoints1, img2, keypoints2, matches, drawImg ); imshow( winName, drawImg ); }