Commit c69312ea authored by Vadim Pisarevsky's avatar Vadim Pisarevsky

fixed #2580, #2210. some work on #2025.

modified SIFT to 1) double image before finding keypoints, 2) use floating-point internally instead of 16-bit integers, 3) set the keypoint response to the abs(interpolated_DoG_value). step 1) increases the number of detected keypoints significantly and together with 2) and 3) it improves some detection benchmarks. On the other hand, the stability of the small keypoints is lower, so the rotation and scale invariance tests now struggle a bit. In 2.5 need to make this feature optional and add some more intelligence to the algorithm.

added test that finds a planar object using SIFT.
parent ab8d92e1
......@@ -3,4 +3,4 @@ if(BUILD_ANDROID_PACKAGE)
endif()
set(the_description "Functionality with possible limitations on the use")
ocv_define_module(nonfree opencv_imgproc opencv_features2d)
ocv_define_module(nonfree opencv_imgproc opencv_features2d opencv_calib3d)
This diff is collapsed.
......@@ -40,6 +40,7 @@
//M*/
#include "test_precomp.hpp"
#include "opencv2/calib3d/calib3d.hpp"
using namespace std;
using namespace cv;
......@@ -1085,4 +1086,59 @@ TEST(Features2d_BruteForceDescriptorMatcher_knnMatch, regression)
Ptr<DescriptorExtractor> s = DescriptorExtractor::create("SURF");
ASSERT_STREQ(s->paramHelp("extended").c_str(), "");
}
*/
\ No newline at end of file
*/
class CV_DetectPlanarTest : public cvtest::BaseTest
{
public:
CV_DetectPlanarTest(const string& _fname, int _min_ninliers) : fname(_fname), min_ninliers(_min_ninliers) {}
protected:
void run(int)
{
Ptr<Feature2D> f = Algorithm::create<Feature2D>("Feature2D." + fname);
if(f.empty())
return;
string path = string(ts->get_data_path()) + "detectors_descriptors_evaluation/planar/";
string imgname1 = path + "box.png";
string imgname2 = path + "box_in_scene.png";
Mat img1 = imread(imgname1, 0);
Mat img2 = imread(imgname2, 0);
if( img1.empty() || img2.empty() )
{
ts->printf( cvtest::TS::LOG, "missing %s and/or %s\n", imgname1.c_str(), imgname2.c_str());
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA );
return;
}
vector<KeyPoint> kpt1, kpt2;
Mat d1, d2;
f->operator()(img1, Mat(), kpt1, d1);
f->operator()(img1, Mat(), kpt2, d2);
vector<DMatch> matches;
BFMatcher(NORM_L2, true).match(d1, d2, matches);
vector<Point2f> pt1, pt2;
for( size_t i = 0; i < matches.size(); i++ ) {
pt1.push_back(kpt1[matches[i].queryIdx].pt);
pt2.push_back(kpt2[matches[i].trainIdx].pt);
}
Mat inliers, H = findHomography(pt1, pt2, RANSAC, 10, inliers);
int ninliers = countNonZero(inliers);
if( ninliers < min_ninliers )
{
ts->printf( cvtest::TS::LOG, "too little inliers (%d) vs expected %d\n", ninliers, min_ninliers);
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA );
return;
}
}
string fname;
int min_ninliers;
};
TEST(Features2d_SIFTHomographyTest, regression) { CV_DetectPlanarTest test("SIFT", 80); test.safe_run(); }
//TEST(Features2d_SURFHomographyTest, regression) { CV_DetectPlanarTest test("SURF", 80); test.safe_run(); }
......@@ -186,6 +186,20 @@ void matchKeyPoints(const vector<KeyPoint>& keypoints0, const Mat& H,
}
}
static void removeVerySmallKeypoints(vector<KeyPoint>& keypoints)
{
size_t i, j = 0, n = keypoints.size();
for( i = 0; i < n; i++ )
{
if( (keypoints[i].octave & 128) != 0 )
;
else
keypoints[j++] = keypoints[i];
}
keypoints.resize(j);
}
class DetectorRotationInvarianceTest : public cvtest::BaseTest
{
public:
......@@ -216,6 +230,7 @@ protected:
vector<KeyPoint> keypoints0;
featureDetector->detect(image0, keypoints0);
removeVerySmallKeypoints(keypoints0);
if(keypoints0.size() < 15)
CV_Error(CV_StsAssert, "Detector gives too few points in a test image\n");
......@@ -226,6 +241,7 @@ protected:
vector<KeyPoint> keypoints1;
featureDetector->detect(image1, keypoints1, mask1);
removeVerySmallKeypoints(keypoints1);
vector<DMatch> matches;
matchKeyPoints(keypoints0, H, keypoints1, matches);
......@@ -329,6 +345,7 @@ protected:
vector<KeyPoint> keypoints0;
Mat descriptors0;
featureDetector->detect(image0, keypoints0);
removeVerySmallKeypoints(keypoints0);
if(keypoints0.size() < 15)
CV_Error(CV_StsAssert, "Detector gives too few points in a test image\n");
descriptorExtractor->compute(image0, keypoints0, descriptors0);
......@@ -382,6 +399,7 @@ protected:
float minDescInliersRatio;
};
class DetectorScaleInvarianceTest : public cvtest::BaseTest
{
public:
......@@ -412,6 +430,7 @@ protected:
vector<KeyPoint> keypoints0;
featureDetector->detect(image0, keypoints0);
removeVerySmallKeypoints(keypoints0);
if(keypoints0.size() < 15)
CV_Error(CV_StsAssert, "Detector gives too few points in a test image\n");
......@@ -423,6 +442,7 @@ protected:
vector<KeyPoint> keypoints1, osiKeypoints1; // osi - original size image
featureDetector->detect(image1, keypoints1);
removeVerySmallKeypoints(keypoints1);
if(keypoints1.size() < 15)
CV_Error(CV_StsAssert, "Detector gives too few points in a test image\n");
......@@ -531,6 +551,7 @@ protected:
vector<KeyPoint> keypoints0;
featureDetector->detect(image0, keypoints0);
removeVerySmallKeypoints(keypoints0);
if(keypoints0.size() < 15)
CV_Error(CV_StsAssert, "Detector gives too few points in a test image\n");
Mat descriptors0;
......@@ -603,8 +624,8 @@ TEST(Features2d_RotationInvariance_Detector_SURF, regression)
TEST(Features2d_RotationInvariance_Detector_SIFT, regression)
{
DetectorRotationInvarianceTest test(Algorithm::create<FeatureDetector>("Feature2D.SIFT"),
0.75f,
0.76f);
0.45f,
0.70f);
test.safe_run();
}
......@@ -665,7 +686,7 @@ TEST(Features2d_ScaleInvariance_Descriptor_SIFT, regression)
DescriptorScaleInvarianceTest test(Algorithm::create<FeatureDetector>("Feature2D.SIFT"),
Algorithm::create<DescriptorExtractor>("Feature2D.SIFT"),
NORM_L1,
0.87f);
0.78f);
test.safe_run();
}
......
......@@ -221,6 +221,8 @@ static void doIteration( const Mat& img1, Mat& img2, bool isWarpPerspective,
drawMatches( img1, keypoints1, img2, keypoints2, filteredMatches, drawImg, CV_RGB(0, 0, 255), CV_RGB(255, 0, 0), matchesMask,
DrawMatchesFlags::DRAW_OVER_OUTIMG | DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );
#endif
printf("Number of inliers: %d\n", countNonZero(matchesMask));
}
else
drawMatches( img1, keypoints1, img2, keypoints2, filteredMatches, drawImg );
......
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