Skip to content

Commit

Permalink
Merge pull request opencv#17618 from Yosshi999:gsoc_sift-better-test
Browse files Browse the repository at this point in the history
Added/Fixed testcases for SIFT

* merge perf_sift into conventional perf tests

* Fix disabled SIFT scale invariance tests

allows trainIdx duplication in matching scaled keypoints
  • Loading branch information
Yosshi999 authored Jun 25, 2020
1 parent 6259ba1 commit 4064d4c
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 97 deletions.
6 changes: 6 additions & 0 deletions modules/features2d/include/opencv2/features2d.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,10 @@ class CV_EXPORTS_W SIFT : public Feature2D
@param contrastThreshold The contrast threshold used to filter out weak features in semi-uniform
(low-contrast) regions. The larger the threshold, the less features are produced by the detector.
@note The contrast threshold will be divided by nOctaveLayers when the filtering is applied. When
nOctaveLayers is set to default and if you want to use the value used in D. Lowe paper, 0.03, set
this argument to 0.09.
@param edgeThreshold The threshold used to filter out edge-like features. Note that the its meaning
is different from the contrastThreshold, i.e. the larger the edgeThreshold, the less features are
filtered out (more features are retained).
Expand All @@ -271,6 +275,8 @@ class CV_EXPORTS_W SIFT : public Feature2D
CV_WRAP static Ptr<SIFT> create(int nfeatures = 0, int nOctaveLayers = 3,
double contrastThreshold = 0.04, double edgeThreshold = 10,
double sigma = 1.6);

CV_WRAP virtual String getDefaultName() const CV_OVERRIDE;
};

typedef SIFT SiftFeatureDetector;
Expand Down
5 changes: 4 additions & 1 deletion modules/features2d/perf/perf_feature2d.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ namespace opencv_test
ORB_DEFAULT, ORB_1500_13_1, \
AKAZE_DEFAULT, AKAZE_DESCRIPTOR_KAZE, \
BRISK_DEFAULT, \
KAZE_DEFAULT
KAZE_DEFAULT, \
SIFT_DEFAULT

#define CV_ENUM_EXPAND(name, ...) CV_ENUM(name, __VA_ARGS__)

Expand Down Expand Up @@ -77,6 +78,8 @@ static inline Ptr<Feature2D> getFeature2D(Feature2DType type)
return KAZE::create();
case MSER_DEFAULT:
return MSER::create();
case SIFT_DEFAULT:
return SIFT::create();
default:
return Ptr<Feature2D>();
}
Expand Down
85 changes: 0 additions & 85 deletions modules/features2d/perf/perf_sift.cpp

This file was deleted.

5 changes: 5 additions & 0 deletions modules/features2d/src/sift.dispatch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,11 @@ Ptr<SIFT> SIFT::create( int _nfeatures, int _nOctaveLayers,
return makePtr<SIFT_Impl>(_nfeatures, _nOctaveLayers, _contrastThreshold, _edgeThreshold, _sigma);
}

String SIFT::getDefaultName() const
{
return (Feature2D::getDefaultName() + ".SIFT");
}

static inline void
unpackOctave(const KeyPoint& kpt, int& octave, int& layer, float& scale)
{
Expand Down
29 changes: 26 additions & 3 deletions modules/features2d/test/test_descriptors_invariance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,26 @@ const static std::string IMAGE_TSUKUBA = "features2d/tsukuba.png";
const static std::string IMAGE_BIKES = "detectors_descriptors_evaluation/images_datasets/bikes/img1.png";
#define Value(...) Values(String_FeatureDetector_DescriptorExtractor_Float_t(__VA_ARGS__))

static
void SetSuitableSIFTOctave(vector<KeyPoint>& keypoints,
int firstOctave = -1, int nOctaveLayers = 3, double sigma = 1.6)
{
for (size_t i = 0; i < keypoints.size(); i++ )
{
int octv, layer;
KeyPoint& kpt = keypoints[i];
double octv_layer = std::log(kpt.size / sigma) / std::log(2.) - 1;
octv = cvFloor(octv_layer);
layer = cvRound( (octv_layer - octv) * nOctaveLayers );
if (octv < firstOctave)
{
octv = firstOctave;
layer = 0;
}
kpt.octave = (layer << 8) | (octv & 255);
}
}

static
void rotateKeyPoints(const vector<KeyPoint>& src, const Mat& H, float angle, vector<KeyPoint>& dst)
{
Expand Down Expand Up @@ -132,6 +152,10 @@ TEST_P(DescriptorScaleInvariance, scale)

vector<KeyPoint> keypoints1;
scaleKeyPoints(keypoints0, keypoints1, 1.0f/scale);
if (featureDetector->getDefaultName() == "Feature2D.SIFT")
{
SetSuitableSIFTOctave(keypoints1);
}
Mat descriptors1;
descriptorExtractor->compute(image1, keypoints1, descriptors1);

Expand Down Expand Up @@ -186,9 +210,8 @@ INSTANTIATE_TEST_CASE_P(AKAZE_DESCRIPTOR_KAZE, DescriptorRotationInvariance,
* Descriptor's scale invariance check
*/

// TODO: Expected: (descInliersRatio) >= (minInliersRatio), actual: 0.330378 vs 0.78
INSTANTIATE_TEST_CASE_P(DISABLED_SIFT, DescriptorScaleInvariance,
Value(IMAGE_BIKES, SIFT::create(), SIFT::create(), 0.78f));
INSTANTIATE_TEST_CASE_P(SIFT, DescriptorScaleInvariance,
Value(IMAGE_BIKES, SIFT::create(0, 3, 0.09), SIFT::create(0, 3, 0.09), 0.78f));

INSTANTIATE_TEST_CASE_P(AKAZE, DescriptorScaleInvariance,
Value(IMAGE_BIKES, AKAZE::create(), AKAZE::create(), 0.6f));
Expand Down
10 changes: 2 additions & 8 deletions modules/features2d/test/test_detectors_invariance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,13 @@ void matchKeyPoints(const vector<KeyPoint>& keypoints0, const Mat& H,
perspectiveTransform(Mat(points0), points0t, H);

matches.clear();
vector<uchar> usedMask(keypoints1.size(), 0);
for(int i0 = 0; i0 < static_cast<int>(keypoints0.size()); i0++)
{
int nearestPointIndex = -1;
float maxIntersectRatio = 0.f;
const float r0 = 0.5f * keypoints0[i0].size;
for(size_t i1 = 0; i1 < keypoints1.size(); i1++)
{
if(nearestPointIndex >= 0 && usedMask[i1])
continue;

float r1 = 0.5f * keypoints1[i1].size;
float intersectRatio = calcIntersectRatio(points0t.at<Point2f>(i0), r0,
Expand All @@ -51,8 +48,6 @@ void matchKeyPoints(const vector<KeyPoint>& keypoints0, const Mat& H,
}

matches.push_back(DMatch(i0, nearestPointIndex, maxIntersectRatio));
if(nearestPointIndex >= 0)
usedMask[nearestPointIndex] = 1;
}
}

Expand Down Expand Up @@ -239,9 +234,8 @@ INSTANTIATE_TEST_CASE_P(AKAZE_DESCRIPTOR_KAZE, DetectorRotationInvariance,
* Detector's scale invariance check
*/

// TODO: Expected: (keyPointMatchesRatio) >= (minKeyPointMatchesRatio), actual: 0.596752 vs 0.69
INSTANTIATE_TEST_CASE_P(DISABLED_SIFT, DetectorScaleInvariance,
Value(IMAGE_BIKES, SIFT::create(), 0.69f, 0.98f));
INSTANTIATE_TEST_CASE_P(SIFT, DetectorScaleInvariance,
Value(IMAGE_BIKES, SIFT::create(0, 3, 0.09), 0.69f, 0.98f));

INSTANTIATE_TEST_CASE_P(BRISK, DetectorScaleInvariance,
Value(IMAGE_BIKES, BRISK::create(), 0.08f, 0.49f));
Expand Down

0 comments on commit 4064d4c

Please sign in to comment.