diff --git a/modules/features2d/src/sift.cpp b/modules/features2d/src/sift.cpp index ac5e3055cf..61e9999533 100644 --- a/modules/features2d/src/sift.cpp +++ b/modules/features2d/src/sift.cpp @@ -2130,6 +2130,70 @@ bool computeKeypointOrientations( VL::Sift& sift, const VL::Sift::Keypoint& keyp return false; } + +struct KeyPoint_LessThan +{ + KeyPoint_LessThan(const vector& _kp) : kp(&_kp) {} + bool operator()(int i, int j) const + { + const KeyPoint& kp1 = (*kp)[i]; + const KeyPoint& kp2 = (*kp)[j]; + if( kp1.pt.x != kp2.pt.x ) + return kp1.pt.x < kp2.pt.x; + if( kp1.pt.y != kp2.pt.y ) + return kp1.pt.y < kp2.pt.y; + if( kp1.size != kp2.size ) + return kp1.size > kp2.size; + if( kp1.size != kp2.size ) + return kp1.size > kp2.size; + if( kp1.angle != kp2.angle ) + return kp1.angle < kp2.angle; + if( kp1.response != kp2.response ) + return kp1.response > kp2.response; + if( kp1.octave != kp2.octave ) + return kp1.octave > kp2.octave; + if( kp1.class_id != kp2.class_id ) + return kp1.class_id > kp2.class_id; + + return i < j; + } + const vector* kp; +}; + + +static void removeDuplicatedKeypoints(vector& keypoints) +{ + int i, j, n = (int)keypoints.size(); + vector kpidx(n); + vector mask(n, (uchar)1); + + for( i = 0; i < n; i++ ) + kpidx[i] = i; + std::sort(kpidx.begin(), kpidx.end(), KeyPoint_LessThan(keypoints)); + for( i = 1, j = 0; i < n; i++ ) + { + KeyPoint& kp1 = keypoints[kpidx[i]]; + KeyPoint& kp2 = keypoints[kpidx[j]]; + if( kp1.pt.x != kp2.pt.x || kp1.pt.y != kp2.pt.y || + kp1.size != kp2.size || kp1.angle != kp2.angle ) + j = i; + else + mask[kpidx[i]] = 0; + } + + for( i = j = 0; i < n; i++ ) + { + if( mask[i] ) + { + if( i != j ) + keypoints[j] = keypoints[i]; + j++; + } + } + keypoints.resize(j); +} + + // detectors void SIFT::operator()(const Mat& img, const Mat& mask, vector& keypoints) const @@ -2160,6 +2224,7 @@ void SIFT::operator()(const Mat& img, const Mat& mask, keypoints.push_back( vlKeypointToOcv(vlsift, *iter, angleVal*a_180divPI) ); } } + removeDuplicatedKeypoints(keypoints); } struct InvalidKeypoint