@@ -569,92 +569,164 @@ static bool adjustLocalExtrema( const std::vector<Mat>& dog_pyr, KeyPoint& kpt,
569
569
}
570
570
571
571
572
- //
573
- // Detects features at extrema in DoG scale space. Bad features are discarded
574
- // based on contrast and ratio of principal curvatures.
575
- void SIFT_Impl::findScaleSpaceExtrema ( const std::vector<Mat>& gauss_pyr, const std::vector<Mat>& dog_pyr,
576
- std::vector<KeyPoint>& keypoints ) const
572
+ class findScaleSpaceExtremaComputer : public ParallelLoopBody
577
573
{
578
- int nOctaves = (int )gauss_pyr.size ()/(nOctaveLayers + 3 );
579
- int threshold = cvFloor (0.5 * contrastThreshold / nOctaveLayers * 255 * SIFT_FIXPT_SCALE);
580
- const int n = SIFT_ORI_HIST_BINS;
581
- float hist[n];
582
- KeyPoint kpt;
574
+ public:
575
+ findScaleSpaceExtremaComputer (
576
+ int _o,
577
+ int _i,
578
+ int _threshold,
579
+ int _idx,
580
+ int _step,
581
+ int _cols,
582
+ int _nOctaveLayers,
583
+ double _contrastThreshold,
584
+ double _edgeThreshold,
585
+ double _sigma,
586
+ const std::vector<Mat>& _gauss_pyr,
587
+ const std::vector<Mat>& _dog_pyr,
588
+ TLSData<std::vector<KeyPoint> > &_tls_kpts_struct)
589
+
590
+ : o(_o),
591
+ i (_i),
592
+ threshold(_threshold),
593
+ idx(_idx),
594
+ step(_step),
595
+ cols(_cols),
596
+ nOctaveLayers(_nOctaveLayers),
597
+ contrastThreshold(_contrastThreshold),
598
+ edgeThreshold(_edgeThreshold),
599
+ sigma(_sigma),
600
+ gauss_pyr(_gauss_pyr),
601
+ dog_pyr(_dog_pyr),
602
+ tls_kpts_struct(_tls_kpts_struct) { }
603
+ void operator ()( const cv::Range& range ) const
604
+ {
605
+ const int begin = range.start ;
606
+ const int end = range.end ;
583
607
584
- keypoints.clear ();
608
+ static const int n = SIFT_ORI_HIST_BINS;
609
+ float hist[n];
585
610
586
- for ( int o = 0 ; o < nOctaves; o++ )
587
- for ( int i = 1 ; i <= nOctaveLayers; i++ )
611
+ const Mat& img = dog_pyr[idx];
612
+ const Mat& prev = dog_pyr[idx-1 ];
613
+ const Mat& next = dog_pyr[idx+1 ];
614
+
615
+ std::vector<KeyPoint> *tls_kpts = tls_kpts_struct.get ();
616
+
617
+ KeyPoint kpt;
618
+ for ( int r = begin; r < end; r++)
588
619
{
589
- int idx = o*(nOctaveLayers+2 )+i;
590
- const Mat& img = dog_pyr[idx];
591
- const Mat& prev = dog_pyr[idx-1 ];
592
- const Mat& next = dog_pyr[idx+1 ];
593
- int step = (int )img.step1 ();
594
- int rows = img.rows , cols = img.cols ;
620
+ const sift_wt* currptr = img.ptr <sift_wt>(r);
621
+ const sift_wt* prevptr = prev.ptr <sift_wt>(r);
622
+ const sift_wt* nextptr = next.ptr <sift_wt>(r);
595
623
596
- for ( int r = SIFT_IMG_BORDER; r < rows -SIFT_IMG_BORDER; r ++)
624
+ for ( int c = SIFT_IMG_BORDER; c < cols -SIFT_IMG_BORDER; c ++)
597
625
{
598
- const sift_wt* currptr = img.ptr <sift_wt>(r);
599
- const sift_wt* prevptr = prev.ptr <sift_wt>(r);
600
- const sift_wt* nextptr = next.ptr <sift_wt>(r);
601
-
602
- for ( int c = SIFT_IMG_BORDER; c < cols-SIFT_IMG_BORDER; c++)
626
+ sift_wt val = currptr[c];
627
+
628
+ // find local extrema with pixel accuracy
629
+ if ( std::abs (val) > threshold &&
630
+ ((val > 0 && val >= currptr[c-1 ] && val >= currptr[c+1 ] &&
631
+ val >= currptr[c-step-1 ] && val >= currptr[c-step] && val >= currptr[c-step+1 ] &&
632
+ val >= currptr[c+step-1 ] && val >= currptr[c+step] && val >= currptr[c+step+1 ] &&
633
+ val >= nextptr[c] && val >= nextptr[c-1 ] && val >= nextptr[c+1 ] &&
634
+ val >= nextptr[c-step-1 ] && val >= nextptr[c-step] && val >= nextptr[c-step+1 ] &&
635
+ val >= nextptr[c+step-1 ] && val >= nextptr[c+step] && val >= nextptr[c+step+1 ] &&
636
+ val >= prevptr[c] && val >= prevptr[c-1 ] && val >= prevptr[c+1 ] &&
637
+ val >= prevptr[c-step-1 ] && val >= prevptr[c-step] && val >= prevptr[c-step+1 ] &&
638
+ val >= prevptr[c+step-1 ] && val >= prevptr[c+step] && val >= prevptr[c+step+1 ]) ||
639
+ (val < 0 && val <= currptr[c-1 ] && val <= currptr[c+1 ] &&
640
+ val <= currptr[c-step-1 ] && val <= currptr[c-step] && val <= currptr[c-step+1 ] &&
641
+ val <= currptr[c+step-1 ] && val <= currptr[c+step] && val <= currptr[c+step+1 ] &&
642
+ val <= nextptr[c] && val <= nextptr[c-1 ] && val <= nextptr[c+1 ] &&
643
+ val <= nextptr[c-step-1 ] && val <= nextptr[c-step] && val <= nextptr[c-step+1 ] &&
644
+ val <= nextptr[c+step-1 ] && val <= nextptr[c+step] && val <= nextptr[c+step+1 ] &&
645
+ val <= prevptr[c] && val <= prevptr[c-1 ] && val <= prevptr[c+1 ] &&
646
+ val <= prevptr[c-step-1 ] && val <= prevptr[c-step] && val <= prevptr[c-step+1 ] &&
647
+ val <= prevptr[c+step-1 ] && val <= prevptr[c+step] && val <= prevptr[c+step+1 ])))
603
648
{
604
- sift_wt val = currptr[c];
605
-
606
- // find local extrema with pixel accuracy
607
- if ( std::abs (val) > threshold &&
608
- ((val > 0 && val >= currptr[c-1 ] && val >= currptr[c+1 ] &&
609
- val >= currptr[c-step-1 ] && val >= currptr[c-step] && val >= currptr[c-step+1 ] &&
610
- val >= currptr[c+step-1 ] && val >= currptr[c+step] && val >= currptr[c+step+1 ] &&
611
- val >= nextptr[c] && val >= nextptr[c-1 ] && val >= nextptr[c+1 ] &&
612
- val >= nextptr[c-step-1 ] && val >= nextptr[c-step] && val >= nextptr[c-step+1 ] &&
613
- val >= nextptr[c+step-1 ] && val >= nextptr[c+step] && val >= nextptr[c+step+1 ] &&
614
- val >= prevptr[c] && val >= prevptr[c-1 ] && val >= prevptr[c+1 ] &&
615
- val >= prevptr[c-step-1 ] && val >= prevptr[c-step] && val >= prevptr[c-step+1 ] &&
616
- val >= prevptr[c+step-1 ] && val >= prevptr[c+step] && val >= prevptr[c+step+1 ]) ||
617
- (val < 0 && val <= currptr[c-1 ] && val <= currptr[c+1 ] &&
618
- val <= currptr[c-step-1 ] && val <= currptr[c-step] && val <= currptr[c-step+1 ] &&
619
- val <= currptr[c+step-1 ] && val <= currptr[c+step] && val <= currptr[c+step+1 ] &&
620
- val <= nextptr[c] && val <= nextptr[c-1 ] && val <= nextptr[c+1 ] &&
621
- val <= nextptr[c-step-1 ] && val <= nextptr[c-step] && val <= nextptr[c-step+1 ] &&
622
- val <= nextptr[c+step-1 ] && val <= nextptr[c+step] && val <= nextptr[c+step+1 ] &&
623
- val <= prevptr[c] && val <= prevptr[c-1 ] && val <= prevptr[c+1 ] &&
624
- val <= prevptr[c-step-1 ] && val <= prevptr[c-step] && val <= prevptr[c-step+1 ] &&
625
- val <= prevptr[c+step-1 ] && val <= prevptr[c+step] && val <= prevptr[c+step+1 ])))
649
+ int r1 = r, c1 = c, layer = i;
650
+ if ( !adjustLocalExtrema (dog_pyr, kpt, o, layer, r1, c1,
651
+ nOctaveLayers, (float )contrastThreshold,
652
+ (float )edgeThreshold, (float )sigma) )
653
+ continue ;
654
+ float scl_octv = kpt.size *0 .5f /(1 << o);
655
+ float omax = calcOrientationHist (gauss_pyr[o*(nOctaveLayers+3 ) + layer],
656
+ Point (c1, r1),
657
+ cvRound (SIFT_ORI_RADIUS * scl_octv),
658
+ SIFT_ORI_SIG_FCTR * scl_octv,
659
+ hist, n);
660
+ float mag_thr = (float )(omax * SIFT_ORI_PEAK_RATIO);
661
+ for ( int j = 0 ; j < n; j++ )
626
662
{
627
- int r1 = r, c1 = c, layer = i;
628
- if ( !adjustLocalExtrema (dog_pyr, kpt, o, layer, r1, c1,
629
- nOctaveLayers, (float )contrastThreshold,
630
- (float )edgeThreshold, (float )sigma) )
631
- continue ;
632
- float scl_octv = kpt.size *0 .5f /(1 << o);
633
- float omax = calcOrientationHist (gauss_pyr[o*(nOctaveLayers+3 ) + layer],
634
- Point (c1, r1),
635
- cvRound (SIFT_ORI_RADIUS * scl_octv),
636
- SIFT_ORI_SIG_FCTR * scl_octv,
637
- hist, n);
638
- float mag_thr = (float )(omax * SIFT_ORI_PEAK_RATIO);
639
- for ( int j = 0 ; j < n; j++ )
640
- {
641
- int l = j > 0 ? j - 1 : n - 1 ;
642
- int r2 = j < n-1 ? j + 1 : 0 ;
663
+ int l = j > 0 ? j - 1 : n - 1 ;
664
+ int r2 = j < n-1 ? j + 1 : 0 ;
643
665
644
- if ( hist[j] > hist[l] && hist[j] > hist[r2] && hist[j] >= mag_thr )
666
+ if ( hist[j] > hist[l] && hist[j] > hist[r2] && hist[j] >= mag_thr )
667
+ {
668
+ float bin = j + 0 .5f * (hist[l]-hist[r2]) / (hist[l] - 2 *hist[j] + hist[r2]);
669
+ bin = bin < 0 ? n + bin : bin >= n ? bin - n : bin;
670
+ kpt.angle = 360 .f - (float )((360 .f /n) * bin);
671
+ if (std::abs (kpt.angle - 360 .f ) < FLT_EPSILON)
672
+ kpt.angle = 0 .f ;
645
673
{
646
- float bin = j + 0 .5f * (hist[l]-hist[r2]) / (hist[l] - 2 *hist[j] + hist[r2]);
647
- bin = bin < 0 ? n + bin : bin >= n ? bin - n : bin;
648
- kpt.angle = 360 .f - (float )((360 .f /n) * bin);
649
- if (std::abs (kpt.angle - 360 .f ) < FLT_EPSILON)
650
- kpt.angle = 0 .f ;
651
- keypoints.push_back (kpt);
674
+ tls_kpts->push_back (kpt);
652
675
}
653
676
}
654
677
}
655
678
}
656
679
}
657
680
}
681
+ }
682
+ private:
683
+ int o, i;
684
+ int threshold;
685
+ int idx, step, cols;
686
+ int nOctaveLayers;
687
+ double contrastThreshold;
688
+ double edgeThreshold;
689
+ double sigma;
690
+ const std::vector<Mat>& gauss_pyr;
691
+ const std::vector<Mat>& dog_pyr;
692
+ TLSData<std::vector<KeyPoint> > &tls_kpts_struct;
693
+ };
694
+
695
+ //
696
+ // Detects features at extrema in DoG scale space. Bad features are discarded
697
+ // based on contrast and ratio of principal curvatures.
698
+ void SIFT_Impl::findScaleSpaceExtrema ( const std::vector<Mat>& gauss_pyr, const std::vector<Mat>& dog_pyr,
699
+ std::vector<KeyPoint>& keypoints ) const
700
+ {
701
+ const int nOctaves = (int )gauss_pyr.size ()/(nOctaveLayers + 3 );
702
+ const int threshold = cvFloor (0.5 * contrastThreshold / nOctaveLayers * 255 * SIFT_FIXPT_SCALE);
703
+
704
+ keypoints.clear ();
705
+ TLSData<std::vector<KeyPoint> > tls_kpts_struct;
706
+
707
+ for ( int o = 0 ; o < nOctaves; o++ )
708
+ for ( int i = 1 ; i <= nOctaveLayers; i++ )
709
+ {
710
+ const int idx = o*(nOctaveLayers+2 )+i;
711
+ const Mat& img = dog_pyr[idx];
712
+ const int step = (int )img.step1 ();
713
+ const int rows = img.rows , cols = img.cols ;
714
+
715
+ parallel_for_ (Range (SIFT_IMG_BORDER, rows-SIFT_IMG_BORDER),
716
+ findScaleSpaceExtremaComputer (
717
+ o, i, threshold, idx, step, cols,
718
+ nOctaveLayers,
719
+ contrastThreshold,
720
+ edgeThreshold,
721
+ sigma,
722
+ gauss_pyr, dog_pyr, tls_kpts_struct));
723
+ }
724
+
725
+ std::vector<std::vector<KeyPoint>*> kpt_vecs;
726
+ tls_kpts_struct.gather (kpt_vecs);
727
+ for (size_t i = 0 ; i < kpt_vecs.size (); ++i) {
728
+ keypoints.insert (keypoints.end (), kpt_vecs[i]->begin (), kpt_vecs[i]->end ());
729
+ }
658
730
}
659
731
660
732
@@ -1081,7 +1153,7 @@ void SIFT_Impl::detectAndCompute(InputArray _image, InputArray _mask,
1081
1153
{
1082
1154
// t = (double)getTickCount();
1083
1155
findScaleSpaceExtrema (gpyr, dogpyr, keypoints);
1084
- KeyPointsFilter::removeDuplicated ( keypoints );
1156
+ KeyPointsFilter::removeDuplicatedSorted ( keypoints );
1085
1157
1086
1158
if ( nfeatures > 0 )
1087
1159
KeyPointsFilter::retainBest (keypoints, nfeatures);
0 commit comments