merged 2.4 into trunk
This commit is contained in:
@@ -5,90 +5,45 @@ SIFT
|
||||
----
|
||||
.. ocv:class:: SIFT
|
||||
|
||||
Class for extracting keypoints and computing descriptors using the Scale Invariant Feature Transform (SIFT) approach. ::
|
||||
Class for extracting keypoints and computing descriptors using the Scale Invariant Feature Transform (SIFT) algorithm by D. Lowe [Lowe04]_.
|
||||
|
||||
class CV_EXPORTS SIFT
|
||||
{
|
||||
public:
|
||||
struct CommonParams
|
||||
{
|
||||
static const int DEFAULT_NOCTAVES = 4;
|
||||
static const int DEFAULT_NOCTAVE_LAYERS = 3;
|
||||
static const int DEFAULT_FIRST_OCTAVE = -1;
|
||||
enum{ FIRST_ANGLE = 0, AVERAGE_ANGLE = 1 };
|
||||
|
||||
CommonParams();
|
||||
CommonParams( int _nOctaves, int _nOctaveLayers, int _firstOctave,
|
||||
int _angleMode );
|
||||
int nOctaves, nOctaveLayers, firstOctave;
|
||||
int angleMode;
|
||||
};
|
||||
|
||||
struct DetectorParams
|
||||
{
|
||||
static double GET_DEFAULT_THRESHOLD()
|
||||
{ return 0.04 / SIFT::CommonParams::DEFAULT_NOCTAVE_LAYERS / 2.0; }
|
||||
static double GET_DEFAULT_EDGE_THRESHOLD() { return 10.0; }
|
||||
|
||||
DetectorParams();
|
||||
DetectorParams( double _threshold, double _edgeThreshold );
|
||||
double threshold, edgeThreshold;
|
||||
};
|
||||
|
||||
struct DescriptorParams
|
||||
{
|
||||
static double GET_DEFAULT_MAGNIFICATION() { return 3.0; }
|
||||
static const bool DEFAULT_IS_NORMALIZE = true;
|
||||
static const int DESCRIPTOR_SIZE = 128;
|
||||
|
||||
DescriptorParams();
|
||||
DescriptorParams( double _magnification, bool _isNormalize,
|
||||
bool _recalculateAngles );
|
||||
double magnification;
|
||||
bool isNormalize;
|
||||
bool recalculateAngles;
|
||||
};
|
||||
|
||||
SIFT();
|
||||
//! sift-detector constructor
|
||||
SIFT( double _threshold, double _edgeThreshold,
|
||||
int _nOctaves=CommonParams::DEFAULT_NOCTAVES,
|
||||
int _nOctaveLayers=CommonParams::DEFAULT_NOCTAVE_LAYERS,
|
||||
int _firstOctave=CommonParams::DEFAULT_FIRST_OCTAVE,
|
||||
int _angleMode=CommonParams::FIRST_ANGLE );
|
||||
//! sift-descriptor constructor
|
||||
SIFT( double _magnification, bool _isNormalize=true,
|
||||
bool _recalculateAngles = true,
|
||||
int _nOctaves=CommonParams::DEFAULT_NOCTAVES,
|
||||
int _nOctaveLayers=CommonParams::DEFAULT_NOCTAVE_LAYERS,
|
||||
int _firstOctave=CommonParams::DEFAULT_FIRST_OCTAVE,
|
||||
int _angleMode=CommonParams::FIRST_ANGLE );
|
||||
SIFT( const CommonParams& _commParams,
|
||||
const DetectorParams& _detectorParams = DetectorParams(),
|
||||
const DescriptorParams& _descriptorParams = DescriptorParams() );
|
||||
|
||||
//! returns the descriptor size in floats (128)
|
||||
int descriptorSize() const { return DescriptorParams::DESCRIPTOR_SIZE; }
|
||||
//! finds the keypoints using the SIFT algorithm
|
||||
void operator()(const Mat& img, const Mat& mask,
|
||||
vector<KeyPoint>& keypoints) const;
|
||||
//! finds the keypoints and computes descriptors for them using SIFT algorithm.
|
||||
//! Optionally it can compute descriptors for the user-provided keypoints
|
||||
void operator()(const Mat& img, const Mat& mask,
|
||||
vector<KeyPoint>& keypoints,
|
||||
Mat& descriptors,
|
||||
bool useProvidedKeypoints=false) const;
|
||||
|
||||
CommonParams getCommonParams () const { return commParams; }
|
||||
DetectorParams getDetectorParams () const { return detectorParams; }
|
||||
DescriptorParams getDescriptorParams () const { return descriptorParams; }
|
||||
protected:
|
||||
...
|
||||
};
|
||||
.. [Lowe04] Lowe, D. G., “Distinctive Image Features from Scale-Invariant Keypoints”, International Journal of Computer Vision, 60, 2, pp. 91-110, 2004.
|
||||
|
||||
|
||||
SIFT::SIFT
|
||||
----------
|
||||
The SIFT constructors.
|
||||
|
||||
.. ocv:function:: SIFT::SIFT( int nfeatures=0, int nOctaveLayers=3, double contrastThreshold=0.04, double edgeThreshold=10, double sigma=1.6)
|
||||
|
||||
:param nfeatures: The number of best features to retain. The features are ranked by their scores (measured in SIFT algorithm as the local contrast)
|
||||
|
||||
:param nOctaveLayers: The number of layers in each octave. 3 is the value used in D. Lowe paper. The number of octaves is computed automatically from the image resolution.
|
||||
|
||||
: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.
|
||||
|
||||
: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).
|
||||
|
||||
:param sigma: The sigma of the Gaussian applied to the input image at the octave #0. If your image is captured with a weak camera with soft lenses, you might want to reduce the number.
|
||||
|
||||
|
||||
SIFT::operator ()
|
||||
-----------------
|
||||
Extract features and computes their descriptors using SIFT algorithm
|
||||
|
||||
.. ocv:function:: void SIFT::operator()(InputArray image, InputArray mask, vector<KeyPoint>& keypoints, OutputArray descriptors, bool useProvidedKeypoints=false)
|
||||
|
||||
:param image: Input 8-bit grayscale image
|
||||
|
||||
:param mask: Optional input mask that marks the regions where we should detect features.
|
||||
|
||||
:param keypoints: The input/output vector of keypoints
|
||||
|
||||
:param descriptors: The output matrix of descriptors. Pass ``cv::noArray()`` if you do not need them.
|
||||
|
||||
:param useProvidedKeypoints: Boolean flag. If it is true, the keypoint detector is not run. Instead, the provided vector of keypoints is used and the algorithm just computes their descriptors.
|
||||
|
||||
|
||||
SURF
|
||||
----
|
||||
.. ocv:class:: SURF
|
||||
@@ -146,8 +101,8 @@ SURF::operator()
|
||||
----------------
|
||||
Detects keypoints and computes SURF descriptors for them.
|
||||
|
||||
.. ocv:function:: void SURF::operator()(const Mat& image, const Mat& mask, vector<KeyPoint>& keypoints)
|
||||
.. ocv:function:: void SURF::operator()(const Mat& image, const Mat& mask, vector<KeyPoint>& keypoints, vector<float>& descriptors, bool useProvidedKeypoints=false)
|
||||
.. ocv:function:: void SURF::operator()(InputArray image, InputArray mask, vector<KeyPoint>& keypoints) const
|
||||
.. ocv:function:: void SURF::operator()(InputArray image, InputArray mask, vector<KeyPoint>& keypoints, OutputArray descriptors, bool useProvidedKeypoints=false)
|
||||
|
||||
.. ocv:pyfunction:: cv2.SURF.detect(img, mask) -> keypoints
|
||||
.. ocv:pyfunction:: cv2.SURF.detect(img, mask[, useProvidedKeypoints]) -> keypoints, descriptors
|
||||
@@ -162,7 +117,7 @@ Detects keypoints and computes SURF descriptors for them.
|
||||
|
||||
:param keypoints: The input/output vector of keypoints
|
||||
|
||||
:param descriptors: The output concatenated vectors of descriptors. Each descriptor is 64- or 128-element vector, as returned by ``SURF::descriptorSize()``. So the total size of ``descriptors`` will be ``keypoints.size()*descriptorSize()``.
|
||||
:param descriptors: The output matrix of descriptors. Pass ``cv::noArray()`` if you do not need them.
|
||||
|
||||
:param useProvidedKeypoints: Boolean flag. If it is true, the keypoint detector is not run. Instead, the provided vector of keypoints is used and the algorithm just computes their descriptors.
|
||||
|
||||
|
118
modules/nonfree/src/nonfree_init.cpp
Normal file
118
modules/nonfree/src/nonfree_init.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp"
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static Algorithm* createSURF()
|
||||
{
|
||||
return new SURF;
|
||||
}
|
||||
|
||||
static AlgorithmInfo& surf_info()
|
||||
{
|
||||
static AlgorithmInfo surf_info_var("Feature2D.SURF", createSURF);
|
||||
return surf_info_var;
|
||||
}
|
||||
|
||||
static AlgorithmInfo& surf_info_auto = surf_info();
|
||||
|
||||
AlgorithmInfo* SURF::info() const
|
||||
{
|
||||
static volatile bool initialized = false;
|
||||
if( !initialized )
|
||||
{
|
||||
SURF obj;
|
||||
surf_info().addParam(obj, "hessianThreshold", obj.hessianThreshold);
|
||||
surf_info().addParam(obj, "nOctaves", obj.nOctaves);
|
||||
surf_info().addParam(obj, "nOctaveLayers", obj.nOctaveLayers);
|
||||
surf_info().addParam(obj, "extended", obj.extended);
|
||||
surf_info().addParam(obj, "upright", obj.upright);
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
return &surf_info();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static Algorithm* createSIFT() { return new SIFT; }
|
||||
|
||||
static AlgorithmInfo& sift_info()
|
||||
{
|
||||
static AlgorithmInfo sift_info_var("Feature2D.SIFT", createSIFT);
|
||||
return sift_info_var;
|
||||
}
|
||||
|
||||
static AlgorithmInfo& sift_info_auto = sift_info();
|
||||
|
||||
AlgorithmInfo* SIFT::info() const
|
||||
{
|
||||
static volatile bool initialized = false;
|
||||
if( !initialized )
|
||||
{
|
||||
SIFT obj;
|
||||
sift_info().addParam(obj, "nFeatures", obj.nfeatures);
|
||||
sift_info().addParam(obj, "nOctaveLayers", obj.nOctaveLayers);
|
||||
sift_info().addParam(obj, "contrastThreshold", obj.contrastThreshold);
|
||||
sift_info().addParam(obj, "edgeThreshold", obj.edgeThreshold);
|
||||
sift_info().addParam(obj, "sigma", obj.sigma);
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
return &sift_info();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool initModule_nonfree(void)
|
||||
{
|
||||
Ptr<Algorithm> sift = createSIFT(), surf = createSURF();
|
||||
return sift->info() != 0 && surf->info() != 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -7,10 +7,11 @@
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// Intel License Agreement
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
@@ -23,7 +24,7 @@
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of Intel Corporation may not be used to endorse or promote products
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
|
@@ -7,10 +7,11 @@
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// Intel License Agreement
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
@@ -23,7 +24,7 @@
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of Intel Corporation may not be used to endorse or promote products
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
|
@@ -443,6 +443,22 @@ struct SURFFindInvoker
|
||||
float hessianThreshold;
|
||||
};
|
||||
|
||||
struct KeypointGreater
|
||||
{
|
||||
inline bool operator()(const KeyPoint& kp1, const KeyPoint& kp2) const
|
||||
{
|
||||
if(kp1.response > kp2.response) return true;
|
||||
if(kp1.response < kp2.response) return false;
|
||||
if(kp1.size > kp2.size) return true;
|
||||
if(kp1.size < kp2.size) return false;
|
||||
if(kp1.octave > kp2.octave) return true;
|
||||
if(kp1.octave < kp2.octave) return false;
|
||||
if(kp1.pt.y < kp2.pt.y) return false;
|
||||
if(kp1.pt.y > kp2.pt.y) return true;
|
||||
return kp1.pt.x < kp2.pt.y;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static void fastHessianDetector( const Mat& sum, const Mat& mask_sum, vector<KeyPoint>& keypoints,
|
||||
int nOctaves, int nOctaveLayers, float hessianThreshold )
|
||||
@@ -490,6 +506,8 @@ static void fastHessianDetector( const Mat& sum, const Mat& mask_sum, vector<Key
|
||||
SURFFindInvoker(sum, mask_sum, dets, traces, sizes,
|
||||
sampleSteps, middleIndices, keypoints,
|
||||
nOctaveLayers, hessianThreshold) );
|
||||
|
||||
std::sort(keypoints.begin(), keypoints.end(), KeypointGreater());
|
||||
}
|
||||
|
||||
|
||||
@@ -938,76 +956,6 @@ void SURF::detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat&
|
||||
void SURF::computeImpl( const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors) const
|
||||
{
|
||||
(*this)(image, Mat(), keypoints, descriptors, true);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static Algorithm* createSURF()
|
||||
{
|
||||
return new SURF;
|
||||
}
|
||||
|
||||
static AlgorithmInfo& surf_info()
|
||||
{
|
||||
static AlgorithmInfo surf_info_var("Feature2D.SURF", createSURF);
|
||||
return surf_info_var;
|
||||
}
|
||||
|
||||
static AlgorithmInfo& surf_info_auto = surf_info();
|
||||
|
||||
AlgorithmInfo* SURF::info() const
|
||||
{
|
||||
static volatile bool initialized = false;
|
||||
if( !initialized )
|
||||
{
|
||||
SURF obj;
|
||||
surf_info().addParam(obj, "hessianThreshold", obj.hessianThreshold);
|
||||
surf_info().addParam(obj, "nOctaves", obj.nOctaves);
|
||||
surf_info().addParam(obj, "nOctaveLayers", obj.nOctaveLayers);
|
||||
surf_info().addParam(obj, "extended", obj.extended);
|
||||
surf_info().addParam(obj, "upright", obj.upright);
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
return &surf_info();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static Algorithm* createSIFT() { return new SIFT; }
|
||||
|
||||
static AlgorithmInfo& sift_info()
|
||||
{
|
||||
static AlgorithmInfo sift_info_var("Feature2D.SIFT", createSIFT);
|
||||
return sift_info_var;
|
||||
}
|
||||
|
||||
static AlgorithmInfo& sift_info_auto = sift_info();
|
||||
|
||||
AlgorithmInfo* SIFT::info() const
|
||||
{
|
||||
static volatile bool initialized = false;
|
||||
if( !initialized )
|
||||
{
|
||||
SIFT obj;
|
||||
sift_info().addParam(obj, "nFeatures", obj.nfeatures);
|
||||
sift_info().addParam(obj, "nOctaveLayers", obj.nOctaveLayers);
|
||||
sift_info().addParam(obj, "contrastThreshold", obj.contrastThreshold);
|
||||
sift_info().addParam(obj, "edgeThreshold", obj.edgeThreshold);
|
||||
sift_info().addParam(obj, "sigma", obj.sigma);
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
return &sift_info();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool initModule_nonfree(void)
|
||||
{
|
||||
Ptr<Algorithm> sift = createSIFT(), surf = createSURF();
|
||||
return sift->info() != 0 && surf->info() != 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -302,6 +302,8 @@ protected:
|
||||
if( validDescriptors.size != calcDescriptors.size || validDescriptors.type() != calcDescriptors.type() )
|
||||
{
|
||||
ts->printf(cvtest::TS::LOG, "Valid and computed descriptors matrices must have the same size and type.\n");
|
||||
ts->printf(cvtest::TS::LOG, "Valid size is (%d x %d) actual size is (%d x %d).\n", validDescriptors.rows, validDescriptors.cols, calcDescriptors.rows, calcDescriptors.cols);
|
||||
ts->printf(cvtest::TS::LOG, "Valid type is %d actual type is %d.\n", validDescriptors.type(), calcDescriptors.type());
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA );
|
||||
return;
|
||||
}
|
||||
@@ -992,21 +994,21 @@ TEST( Features2d_DescriptorExtractor_SIFT, regression )
|
||||
|
||||
TEST( Features2d_DescriptorExtractor_SURF, regression )
|
||||
{
|
||||
CV_DescriptorExtractorTest<L2<float> > test( "descriptor-surf", 0.035f,
|
||||
CV_DescriptorExtractorTest<L2<float> > test( "descriptor-surf", 0.05f,
|
||||
DescriptorExtractor::create("SURF"), 0.147372f );
|
||||
test.safe_run();
|
||||
}
|
||||
|
||||
/*TEST( Features2d_DescriptorExtractor_OpponentSIFT, regression )
|
||||
TEST( Features2d_DescriptorExtractor_OpponentSIFT, regression )
|
||||
{
|
||||
CV_DescriptorExtractorTest<L2<float> > test( "descriptor-opponent-sift", 0.18f,
|
||||
DescriptorExtractor::create("OpponentSIFT"), 8.06652f );
|
||||
test.safe_run();
|
||||
}*/
|
||||
}
|
||||
|
||||
TEST( Features2d_DescriptorExtractor_OpponentSURF, regression )
|
||||
{
|
||||
CV_DescriptorExtractorTest<L2<float> > test( "descriptor-opponent-surf", 0.18f,
|
||||
CV_DescriptorExtractorTest<L2<float> > test( "descriptor-opponent-surf", 0.3f,
|
||||
DescriptorExtractor::create("OpponentSURF"), 0.147372f );
|
||||
test.safe_run();
|
||||
}
|
||||
@@ -1066,11 +1068,11 @@ TEST(Features2d_BruteForceDescriptorMatcher_knnMatch, regression)
|
||||
matcher->knnMatch(descQ, descT, matches, k);
|
||||
|
||||
//cout << "\nBest " << k << " matches to " << descT.rows << " train desc-s." << endl;
|
||||
ASSERT_EQ(descQ.rows, matches.size());
|
||||
ASSERT_EQ(descQ.rows, static_cast<int>(matches.size()));
|
||||
for(size_t i = 0; i<matches.size(); i++)
|
||||
{
|
||||
//cout << "\nmatches[" << i << "].size()==" << matches[i].size() << endl;
|
||||
ASSERT_GT(min(k, descT.rows), static_cast<int>(matches[i].size()));
|
||||
ASSERT_GE(min(k, descT.rows), static_cast<int>(matches[i].size()));
|
||||
for(size_t j = 0; j<matches[i].size(); j++)
|
||||
{
|
||||
//cout << "\t" << matches[i][j].queryIdx << " -> " << matches[i][j].trainIdx << endl;
|
||||
|
Reference in New Issue
Block a user