mirror of
https://github.com/opencv/opencv_contrib.git
synced 2025-10-18 17:24:28 +08:00
Merge pull request #2501 from alalek:sift_optimization_1
This commit is contained in:
72
modules/xfeatures2d/perf/perf_sift.cpp
Normal file
72
modules/xfeatures2d/perf/perf_sift.cpp
Normal file
@@ -0,0 +1,72 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
#include "perf_precomp.hpp"
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
typedef perf::TestBaseWithParam<std::string> sift;
|
||||
|
||||
#define SIFT_IMAGES \
|
||||
"cv/detectors_descriptors_evaluation/images_datasets/leuven/img1.png",\
|
||||
"stitching/a3.png"
|
||||
|
||||
PERF_TEST_P(sift, detect, testing::Values(SIFT_IMAGES))
|
||||
{
|
||||
string filename = getDataPath(GetParam());
|
||||
Mat frame = imread(filename, IMREAD_GRAYSCALE);
|
||||
ASSERT_FALSE(frame.empty()) << "Unable to load source image " << filename;
|
||||
|
||||
Mat mask;
|
||||
declare.in(frame).time(90);
|
||||
Ptr<SIFT> detector = SIFT::create();
|
||||
vector<KeyPoint> points;
|
||||
|
||||
PERF_SAMPLE_BEGIN();
|
||||
detector->detect(frame, points, mask);
|
||||
PERF_SAMPLE_END();
|
||||
|
||||
SANITY_CHECK_NOTHING();
|
||||
}
|
||||
|
||||
PERF_TEST_P(sift, extract, testing::Values(SIFT_IMAGES))
|
||||
{
|
||||
string filename = getDataPath(GetParam());
|
||||
Mat frame = imread(filename, IMREAD_GRAYSCALE);
|
||||
ASSERT_FALSE(frame.empty()) << "Unable to load source image " << filename;
|
||||
|
||||
Mat mask;
|
||||
declare.in(frame).time(90);
|
||||
|
||||
Ptr<SIFT> detector = SIFT::create();
|
||||
vector<KeyPoint> points;
|
||||
Mat descriptors;
|
||||
detector->detect(frame, points, mask);
|
||||
|
||||
PERF_SAMPLE_BEGIN();
|
||||
detector->compute(frame, points, descriptors);
|
||||
PERF_SAMPLE_END();
|
||||
|
||||
SANITY_CHECK_NOTHING();
|
||||
}
|
||||
|
||||
PERF_TEST_P(sift, full, testing::Values(SIFT_IMAGES))
|
||||
{
|
||||
string filename = getDataPath(GetParam());
|
||||
Mat frame = imread(filename, IMREAD_GRAYSCALE);
|
||||
ASSERT_FALSE(frame.empty()) << "Unable to load source image " << filename;
|
||||
|
||||
Mat mask;
|
||||
declare.in(frame).time(90);
|
||||
Ptr<SIFT> detector = SIFT::create();
|
||||
vector<KeyPoint> points;
|
||||
Mat descriptors;
|
||||
|
||||
PERF_SAMPLE_BEGIN();
|
||||
detector->detectAndCompute(frame, mask, points, descriptors, false);
|
||||
PERF_SAMPLE_END();
|
||||
|
||||
SANITY_CHECK_NOTHING();
|
||||
}
|
||||
|
||||
}} // namespace
|
@@ -158,6 +158,7 @@ protected:
|
||||
Ptr<SIFT> SIFT::create( int _nfeatures, int _nOctaveLayers,
|
||||
double _contrastThreshold, double _edgeThreshold, double _sigma )
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
return makePtr<SIFT_Impl>(_nfeatures, _nOctaveLayers, _contrastThreshold, _edgeThreshold, _sigma);
|
||||
}
|
||||
|
||||
@@ -221,6 +222,8 @@ unpackOctave(const KeyPoint& kpt, int& octave, int& layer, float& scale)
|
||||
|
||||
static Mat createInitialImage( const Mat& img, bool doubleImageSize, float sigma )
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
|
||||
Mat gray, gray_fpt;
|
||||
if( img.channels() == 3 || img.channels() == 4 )
|
||||
{
|
||||
@@ -241,20 +244,24 @@ static Mat createInitialImage( const Mat& img, bool doubleImageSize, float sigma
|
||||
#else
|
||||
resize(gray_fpt, dbl, Size(gray_fpt.cols*2, gray_fpt.rows*2), 0, 0, INTER_LINEAR);
|
||||
#endif
|
||||
GaussianBlur(dbl, dbl, Size(), sig_diff, sig_diff);
|
||||
return dbl;
|
||||
Mat result;
|
||||
GaussianBlur(dbl, result, Size(), sig_diff, sig_diff);
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
sig_diff = sqrtf( std::max(sigma * sigma - SIFT_INIT_SIGMA * SIFT_INIT_SIGMA, 0.01f) );
|
||||
GaussianBlur(gray_fpt, gray_fpt, Size(), sig_diff, sig_diff);
|
||||
return gray_fpt;
|
||||
Mat result;
|
||||
GaussianBlur(gray_fpt, result, Size(), sig_diff, sig_diff);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SIFT_Impl::buildGaussianPyramid( const Mat& base, std::vector<Mat>& pyr, int nOctaves ) const
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
|
||||
std::vector<double> sig(nOctaveLayers + 3);
|
||||
pyr.resize(nOctaves*(nOctaveLayers + 3));
|
||||
|
||||
@@ -306,6 +313,8 @@ public:
|
||||
|
||||
void operator()( const cv::Range& range ) const CV_OVERRIDE
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
|
||||
const int begin = range.start;
|
||||
const int end = range.end;
|
||||
|
||||
@@ -329,6 +338,8 @@ private:
|
||||
|
||||
void SIFT_Impl::buildDoGPyramid( const std::vector<Mat>& gpyr, std::vector<Mat>& dogpyr ) const
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
|
||||
int nOctaves = (int)gpyr.size()/(nOctaveLayers + 3);
|
||||
dogpyr.resize( nOctaves*(nOctaveLayers + 2) );
|
||||
|
||||
@@ -339,6 +350,8 @@ void SIFT_Impl::buildDoGPyramid( const std::vector<Mat>& gpyr, std::vector<Mat>&
|
||||
static float calcOrientationHist( const Mat& img, Point pt, int radius,
|
||||
float sigma, float* hist, int n )
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
|
||||
int i, j, k, len = (radius*2+1)*(radius*2+1);
|
||||
|
||||
float expf_scale = -1.f/(2.f * sigma * sigma);
|
||||
@@ -477,6 +490,8 @@ static bool adjustLocalExtrema( const std::vector<Mat>& dog_pyr, KeyPoint& kpt,
|
||||
int& layer, int& r, int& c, int nOctaveLayers,
|
||||
float contrastThreshold, float edgeThreshold, float sigma )
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
|
||||
const float img_scale = 1.f/(255*SIFT_FIXPT_SCALE);
|
||||
const float deriv_scale = img_scale*0.5f;
|
||||
const float second_deriv_scale = img_scale;
|
||||
@@ -609,6 +624,8 @@ public:
|
||||
tls_kpts_struct(_tls_kpts_struct) { }
|
||||
void operator()( const cv::Range& range ) const CV_OVERRIDE
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
|
||||
const int begin = range.start;
|
||||
const int end = range.end;
|
||||
|
||||
@@ -653,6 +670,8 @@ public:
|
||||
val <= prevptr[c-step-1] && val <= prevptr[c-step] && val <= prevptr[c-step+1] &&
|
||||
val <= prevptr[c+step-1] && val <= prevptr[c+step] && val <= prevptr[c+step+1])))
|
||||
{
|
||||
CV_TRACE_REGION("pixel_candidate");
|
||||
|
||||
int r1 = r, c1 = c, layer = i;
|
||||
if( !adjustLocalExtrema(dog_pyr, kpt, o, layer, r1, c1,
|
||||
nOctaveLayers, (float)contrastThreshold,
|
||||
@@ -705,6 +724,8 @@ private:
|
||||
void SIFT_Impl::findScaleSpaceExtrema( const std::vector<Mat>& gauss_pyr, const std::vector<Mat>& dog_pyr,
|
||||
std::vector<KeyPoint>& keypoints ) const
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
|
||||
const int nOctaves = (int)gauss_pyr.size()/(nOctaveLayers + 3);
|
||||
const int threshold = cvFloor(0.5 * contrastThreshold / nOctaveLayers * 255 * SIFT_FIXPT_SCALE);
|
||||
|
||||
@@ -740,6 +761,8 @@ void SIFT_Impl::findScaleSpaceExtrema( const std::vector<Mat>& gauss_pyr, const
|
||||
static void calcSIFTDescriptor( const Mat& img, Point2f ptf, float ori, float scl,
|
||||
int d, int n, float* dst )
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
|
||||
Point pt(cvRound(ptf.x), cvRound(ptf.y));
|
||||
float cos_t = cosf(ori*(float)(CV_PI/180));
|
||||
float sin_t = sinf(ori*(float)(CV_PI/180));
|
||||
@@ -1050,6 +1073,8 @@ public:
|
||||
|
||||
void operator()( const cv::Range& range ) const CV_OVERRIDE
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
|
||||
const int begin = range.start;
|
||||
const int end = range.end;
|
||||
|
||||
@@ -1083,6 +1108,7 @@ private:
|
||||
static void calcDescriptors(const std::vector<Mat>& gpyr, const std::vector<KeyPoint>& keypoints,
|
||||
Mat& descriptors, int nOctaveLayers, int firstOctave )
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
parallel_for_(Range(0, static_cast<int>(keypoints.size())), calcDescriptorsComputer(gpyr, keypoints, descriptors, nOctaveLayers, firstOctave));
|
||||
}
|
||||
|
||||
@@ -1116,6 +1142,8 @@ void SIFT_Impl::detectAndCompute(InputArray _image, InputArray _mask,
|
||||
OutputArray _descriptors,
|
||||
bool useProvidedKeypoints)
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
|
||||
int firstOctave = -1, actualNOctaves = 0, actualNLayers = 0;
|
||||
Mat image = _image.getMat(), mask = _mask.getMat();
|
||||
|
||||
|
Reference in New Issue
Block a user