|
|
@ -569,31 +569,53 @@ static bool adjustLocalExtrema( const std::vector<Mat>& dog_pyr, KeyPoint& kpt, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
class findScaleSpaceExtremaComputer : public ParallelLoopBody |
|
|
|
// Detects features at extrema in DoG scale space. Bad features are discarded
|
|
|
|
|
|
|
|
// based on contrast and ratio of principal curvatures.
|
|
|
|
|
|
|
|
void SIFT_Impl::findScaleSpaceExtrema( const std::vector<Mat>& gauss_pyr, const std::vector<Mat>& dog_pyr, |
|
|
|
|
|
|
|
std::vector<KeyPoint>& keypoints ) const |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
int nOctaves = (int)gauss_pyr.size()/(nOctaveLayers + 3); |
|
|
|
public: |
|
|
|
int threshold = cvFloor(0.5 * contrastThreshold / nOctaveLayers * 255 * SIFT_FIXPT_SCALE); |
|
|
|
findScaleSpaceExtremaComputer( |
|
|
|
const int n = SIFT_ORI_HIST_BINS; |
|
|
|
int _o, |
|
|
|
float hist[n]; |
|
|
|
int _i, |
|
|
|
KeyPoint kpt; |
|
|
|
int _threshold, |
|
|
|
|
|
|
|
int _idx, |
|
|
|
|
|
|
|
int _step, |
|
|
|
|
|
|
|
int _cols, |
|
|
|
|
|
|
|
int _nOctaveLayers, |
|
|
|
|
|
|
|
double _contrastThreshold, |
|
|
|
|
|
|
|
double _edgeThreshold, |
|
|
|
|
|
|
|
double _sigma, |
|
|
|
|
|
|
|
const std::vector<Mat>& _gauss_pyr, |
|
|
|
|
|
|
|
const std::vector<Mat>& _dog_pyr, |
|
|
|
|
|
|
|
TLSData<std::vector<KeyPoint> > &_tls_kpts_struct) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
: o(_o), |
|
|
|
|
|
|
|
i(_i), |
|
|
|
|
|
|
|
threshold(_threshold), |
|
|
|
|
|
|
|
idx(_idx), |
|
|
|
|
|
|
|
step(_step), |
|
|
|
|
|
|
|
cols(_cols), |
|
|
|
|
|
|
|
nOctaveLayers(_nOctaveLayers), |
|
|
|
|
|
|
|
contrastThreshold(_contrastThreshold), |
|
|
|
|
|
|
|
edgeThreshold(_edgeThreshold), |
|
|
|
|
|
|
|
sigma(_sigma), |
|
|
|
|
|
|
|
gauss_pyr(_gauss_pyr), |
|
|
|
|
|
|
|
dog_pyr(_dog_pyr), |
|
|
|
|
|
|
|
tls_kpts_struct(_tls_kpts_struct) { } |
|
|
|
|
|
|
|
void operator()( const cv::Range& range ) const |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
const int begin = range.start; |
|
|
|
|
|
|
|
const int end = range.end; |
|
|
|
|
|
|
|
|
|
|
|
keypoints.clear(); |
|
|
|
static const int n = SIFT_ORI_HIST_BINS; |
|
|
|
|
|
|
|
float hist[n]; |
|
|
|
|
|
|
|
|
|
|
|
for( int o = 0; o < nOctaves; o++ ) |
|
|
|
|
|
|
|
for( int i = 1; i <= nOctaveLayers; i++ ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
int idx = o*(nOctaveLayers+2)+i; |
|
|
|
|
|
|
|
const Mat& img = dog_pyr[idx]; |
|
|
|
const Mat& img = dog_pyr[idx]; |
|
|
|
const Mat& prev = dog_pyr[idx-1]; |
|
|
|
const Mat& prev = dog_pyr[idx-1]; |
|
|
|
const Mat& next = dog_pyr[idx+1]; |
|
|
|
const Mat& next = dog_pyr[idx+1]; |
|
|
|
int step = (int)img.step1(); |
|
|
|
|
|
|
|
int rows = img.rows, cols = img.cols; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for( int r = SIFT_IMG_BORDER; r < rows-SIFT_IMG_BORDER; r++) |
|
|
|
std::vector<KeyPoint> *tls_kpts = tls_kpts_struct.get(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
KeyPoint kpt; |
|
|
|
|
|
|
|
for( int r = begin; r < end; r++) |
|
|
|
{ |
|
|
|
{ |
|
|
|
const sift_wt* currptr = img.ptr<sift_wt>(r); |
|
|
|
const sift_wt* currptr = img.ptr<sift_wt>(r); |
|
|
|
const sift_wt* prevptr = prev.ptr<sift_wt>(r); |
|
|
|
const sift_wt* prevptr = prev.ptr<sift_wt>(r); |
|
|
@ -648,7 +670,8 @@ void SIFT_Impl::findScaleSpaceExtrema( const std::vector<Mat>& gauss_pyr, const |
|
|
|
kpt.angle = 360.f - (float)((360.f/n) * bin); |
|
|
|
kpt.angle = 360.f - (float)((360.f/n) * bin); |
|
|
|
if(std::abs(kpt.angle - 360.f) < FLT_EPSILON) |
|
|
|
if(std::abs(kpt.angle - 360.f) < FLT_EPSILON) |
|
|
|
kpt.angle = 0.f; |
|
|
|
kpt.angle = 0.f; |
|
|
|
keypoints.push_back(kpt); |
|
|
|
{ |
|
|
|
|
|
|
|
tls_kpts->push_back(kpt); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -656,6 +679,55 @@ void SIFT_Impl::findScaleSpaceExtrema( const std::vector<Mat>& gauss_pyr, const |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private: |
|
|
|
|
|
|
|
int o, i; |
|
|
|
|
|
|
|
int threshold; |
|
|
|
|
|
|
|
int idx, step, cols; |
|
|
|
|
|
|
|
int nOctaveLayers; |
|
|
|
|
|
|
|
double contrastThreshold; |
|
|
|
|
|
|
|
double edgeThreshold; |
|
|
|
|
|
|
|
double sigma; |
|
|
|
|
|
|
|
const std::vector<Mat>& gauss_pyr; |
|
|
|
|
|
|
|
const std::vector<Mat>& dog_pyr; |
|
|
|
|
|
|
|
TLSData<std::vector<KeyPoint> > &tls_kpts_struct; |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// Detects features at extrema in DoG scale space. Bad features are discarded
|
|
|
|
|
|
|
|
// based on contrast and ratio of principal curvatures.
|
|
|
|
|
|
|
|
void SIFT_Impl::findScaleSpaceExtrema( const std::vector<Mat>& gauss_pyr, const std::vector<Mat>& dog_pyr, |
|
|
|
|
|
|
|
std::vector<KeyPoint>& keypoints ) const |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
const int nOctaves = (int)gauss_pyr.size()/(nOctaveLayers + 3); |
|
|
|
|
|
|
|
const int threshold = cvFloor(0.5 * contrastThreshold / nOctaveLayers * 255 * SIFT_FIXPT_SCALE); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
keypoints.clear(); |
|
|
|
|
|
|
|
TLSData<std::vector<KeyPoint> > tls_kpts_struct; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for( int o = 0; o < nOctaves; o++ ) |
|
|
|
|
|
|
|
for( int i = 1; i <= nOctaveLayers; i++ ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
const int idx = o*(nOctaveLayers+2)+i; |
|
|
|
|
|
|
|
const Mat& img = dog_pyr[idx]; |
|
|
|
|
|
|
|
const int step = (int)img.step1(); |
|
|
|
|
|
|
|
const int rows = img.rows, cols = img.cols; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
parallel_for_(Range(SIFT_IMG_BORDER, rows-SIFT_IMG_BORDER), |
|
|
|
|
|
|
|
findScaleSpaceExtremaComputer( |
|
|
|
|
|
|
|
o, i, threshold, idx, step, cols, |
|
|
|
|
|
|
|
nOctaveLayers, |
|
|
|
|
|
|
|
contrastThreshold, |
|
|
|
|
|
|
|
edgeThreshold, |
|
|
|
|
|
|
|
sigma, |
|
|
|
|
|
|
|
gauss_pyr, dog_pyr, tls_kpts_struct)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<std::vector<KeyPoint>*> kpt_vecs; |
|
|
|
|
|
|
|
tls_kpts_struct.gather(kpt_vecs); |
|
|
|
|
|
|
|
for (size_t i = 0; i < kpt_vecs.size(); ++i) { |
|
|
|
|
|
|
|
keypoints.insert(keypoints.end(), kpt_vecs[i]->begin(), kpt_vecs[i]->end()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void calcSIFTDescriptor( const Mat& img, Point2f ptf, float ori, float scl, |
|
|
|
static void calcSIFTDescriptor( const Mat& img, Point2f ptf, float ori, float scl, |
|
|
@ -1081,7 +1153,7 @@ void SIFT_Impl::detectAndCompute(InputArray _image, InputArray _mask, |
|
|
|
{ |
|
|
|
{ |
|
|
|
//t = (double)getTickCount();
|
|
|
|
//t = (double)getTickCount();
|
|
|
|
findScaleSpaceExtrema(gpyr, dogpyr, keypoints); |
|
|
|
findScaleSpaceExtrema(gpyr, dogpyr, keypoints); |
|
|
|
KeyPointsFilter::removeDuplicated( keypoints ); |
|
|
|
KeyPointsFilter::removeDuplicatedSorted( keypoints ); |
|
|
|
|
|
|
|
|
|
|
|
if( nfeatures > 0 ) |
|
|
|
if( nfeatures > 0 ) |
|
|
|
KeyPointsFilter::retainBest(keypoints, nfeatures); |
|
|
|
KeyPointsFilter::retainBest(keypoints, nfeatures); |
|
|
|