parent
c1101a02ee
commit
593e78c5d0
9 changed files with 707 additions and 1 deletions
@ -1,3 +1,4 @@ |
||||
set(the_description "Contributed/Experimental Algorithms for Salient 2D Features Detection") |
||||
ocv_define_module(xfeatures2d opencv_core opencv_imgproc opencv_features2d opencv_calib3d opencv_shape opencv_highgui opencv_videoio opencv_ml |
||||
OPTIONAL opencv_cudaarithm WRAP python java) |
||||
include(cmake/download_vgg.cmake) |
@ -0,0 +1,23 @@ |
||||
|
||||
set(OPENCV_3RDPARTY_COMMIT "fccf7cd6a4b12079f73bbfb21745f9babcd4eb1d") |
||||
set(FILE_HASH_VGG_48 "e8d0dcd54d1bcfdc29203d011a797179") |
||||
set(FILE_HASH_VGG_64 "7126a5d9a8884ebca5aea5d63d677225") |
||||
set(FILE_HASH_VGG_80 "7cd47228edec52b6d82f46511af325c5") |
||||
set(FILE_HASH_VGG_120 "151805e03568c9f490a5e3a872777b75") |
||||
|
||||
|
||||
set(VGG_DOWNLOAD_URL ${OPENCV_CONTRIB_VGG_URL};$ENV{OPENCV_CONTRIB_VGG_URL};https://raw.githubusercontent.com/Itseez/opencv_3rdparty/${OPENCV_3RDPARTY_COMMIT}/) |
||||
|
||||
function(vgg_download file id) |
||||
message(STATUS "Check contents of ${file} ...") |
||||
ocv_download(PACKAGE ${file} |
||||
HASH ${FILE_HASH_${id}} |
||||
URL ${VGG_DOWNLOAD_URL} |
||||
DESTINATION_DIR ${CMAKE_CURRENT_LIST_DIR}/../src |
||||
DOWNLOAD_DIR ${CMAKE_CURRENT_LIST_DIR}/.download) |
||||
endfunction() |
||||
|
||||
vgg_download(vgg_generated_48.i VGG_48) |
||||
vgg_download(vgg_generated_64.i VGG_64) |
||||
vgg_download(vgg_generated_80.i VGG_80) |
||||
vgg_download(vgg_generated_120.i VGG_120) |
@ -0,0 +1,35 @@ |
||||
#include "perf_precomp.hpp" |
||||
|
||||
using namespace std; |
||||
using namespace cv; |
||||
using namespace cv::xfeatures2d; |
||||
using namespace perf; |
||||
using std::tr1::make_tuple; |
||||
using std::tr1::get; |
||||
|
||||
typedef perf::TestBaseWithParam<std::string> vgg; |
||||
|
||||
#define VGG_IMAGES \ |
||||
"cv/detectors_descriptors_evaluation/images_datasets/leuven/img1.png",\
|
||||
"stitching/a3.png" |
||||
|
||||
PERF_TEST_P(vgg, extract, testing::Values(VGG_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<KAZE> detector = KAZE::create(); |
||||
vector<KeyPoint> points; |
||||
detector->detect(frame, points, mask); |
||||
|
||||
Ptr<VGG> descriptor = VGG::create(); |
||||
Mat_<float> descriptors; |
||||
// compute keypoints descriptor
|
||||
TEST_CYCLE() descriptor->compute(frame, points, descriptors); |
||||
|
||||
SANITY_CHECK_NOTHING(); |
||||
} |
@ -0,0 +1,522 @@ |
||||
/*********************************************************************
|
||||
* Software License Agreement (BSD License) |
||||
* |
||||
* Copyright (c) 2014, 2015 |
||||
* |
||||
* Karen Simonyan <karen at robots dot ox dot ac dot uk> |
||||
* Andrea Vedaldi <vedaldi at robots dot ox dot ac dot uk> |
||||
* Andrew Zisserman <az at robots dot ox dot ac dot uk> |
||||
* |
||||
* Visual Geometry Group |
||||
* Department of Engineering Science, University of Oxford |
||||
* |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions |
||||
* are met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions 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. |
||||
* * Neither the name of the copyright holders nor the names of its |
||||
* contributors may 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 |
||||
* COPYRIGHT OWNER 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. |
||||
*********************************************************************/ |
||||
|
||||
/*
|
||||
|
||||
"Learning Local Feature Descriptors Using Convex Optimisation", |
||||
Simonyan, K. and Vedaldi, A. and Zisserman, A., |
||||
IEEE Transactions on Pattern Analysis and Machine Intelligence, 2014 |
||||
|
||||
"Discriminative Learning of Local Image Descriptors", |
||||
Matthew A. Brown, Gang Hua, Simon A. J. Winder, |
||||
IEEE Transactions on Pattern Analysis and Machine Intelligence, 2011 |
||||
|
||||
OpenCV port by: Cristian Balint <cristian dot balint at gmail dot com> |
||||
|
||||
*/ |
||||
|
||||
#include "precomp.hpp" |
||||
|
||||
|
||||
|
||||
using namespace cv; |
||||
using namespace std; |
||||
|
||||
|
||||
namespace cv |
||||
{ |
||||
namespace xfeatures2d |
||||
{ |
||||
|
||||
/*
|
||||
!VGG implementation |
||||
*/ |
||||
class VGG_Impl : public VGG |
||||
{ |
||||
|
||||
public: |
||||
|
||||
// constructor
|
||||
explicit VGG_Impl( int desc = VGG::VGG_80, float isigma = 1.4f, |
||||
bool img_normalize = true, bool use_scale_orientation = true, |
||||
float scale_factor = 6.25f, bool dsc_normalize = false ); |
||||
|
||||
// destructor
|
||||
virtual ~VGG_Impl(); |
||||
|
||||
// returns the descriptor length in bytes
|
||||
virtual int descriptorSize() const { return m_descriptor_size; }; |
||||
|
||||
// returns the descriptor type
|
||||
virtual int descriptorType() const { return CV_32F; } |
||||
|
||||
// returns the default norm type
|
||||
virtual int defaultNorm() const { return NORM_L2; } |
||||
|
||||
// compute descriptors given keypoints
|
||||
virtual void compute( InputArray image, vector<KeyPoint>& keypoints, OutputArray descriptors ); |
||||
|
||||
protected: |
||||
|
||||
/*
|
||||
* VGG parameters |
||||
*/ |
||||
|
||||
int m_descriptor_size; |
||||
|
||||
// gauss sigma
|
||||
float m_isigma; |
||||
|
||||
// angle bins
|
||||
int m_anglebins; |
||||
|
||||
// sample window
|
||||
float m_scale_factor; |
||||
|
||||
/*
|
||||
* VGG switches |
||||
*/ |
||||
|
||||
// normalize image
|
||||
bool m_img_normalize; |
||||
|
||||
// switch to enable sample by keypoints orientation
|
||||
bool m_use_scale_orientation; |
||||
|
||||
// normalize desc
|
||||
bool m_dsc_normalize; |
||||
|
||||
/*
|
||||
* VGG arrays |
||||
*/ |
||||
|
||||
// image
|
||||
Mat m_image; |
||||
|
||||
// pool regions & proj
|
||||
Mat m_PRFilters, m_Proj; |
||||
|
||||
private: |
||||
|
||||
/*
|
||||
* VGG functions |
||||
*/ |
||||
|
||||
// initialize parameters
|
||||
inline void ini_params( const int PRrows, const int PRcols, |
||||
const unsigned int PRidx[], const unsigned int PRidxSize, const unsigned int PR[], |
||||
const int PJrows, const int PJcols, |
||||
const unsigned int PJidx[], const unsigned int PJidxSize, const unsigned int PJ[] ); |
||||
|
||||
}; // END VGG_Impl CLASS
|
||||
|
||||
// -------------------------------------------------
|
||||
/* VGG internal routines */ |
||||
|
||||
// sample 64x64 patch from image given keypoint
|
||||
static inline void get_patch( const KeyPoint kp, Mat& Patch, const Mat& image, |
||||
const bool use_scale_orientation, const float scale_factor ) |
||||
{ |
||||
// scale & radians
|
||||
float scale = kp.size / 64.0f * scale_factor; |
||||
const float angle = (kp.angle == -1) |
||||
? 0 : ( (kp.angle)*(float)CV_PI ) / 180.f; |
||||
|
||||
// transforms
|
||||
const float tsin = sin(angle) * scale; |
||||
const float tcos = cos(angle) * scale; |
||||
|
||||
const float half_cols = (float)Patch.cols / 2.0f; |
||||
const float half_rows = (float)Patch.rows / 2.0f; |
||||
|
||||
// sample form original image
|
||||
for ( int x = 0; x < Patch.cols; x++ ) |
||||
{ |
||||
for ( int y = 0; y < Patch.rows; y++ ) |
||||
{ |
||||
if ( use_scale_orientation ) |
||||
{ |
||||
const float xoff = x - half_cols; |
||||
const float yoff = y - half_rows; |
||||
// the rotation shifts & scale
|
||||
int img_x = int( (kp.pt.x + 0.5f) + xoff*tcos - yoff*tsin ); |
||||
int img_y = int( (kp.pt.y + 0.5f) + xoff*tsin + yoff*tcos ); |
||||
// sample only within image
|
||||
if ( ( img_x < image.cols ) && ( img_x >= 0 ) |
||||
&& ( img_y < image.rows ) && ( img_y >= 0 ) ) |
||||
Patch.at<float>( y, x ) = image.at<float>( img_y, img_x ); |
||||
else |
||||
Patch.at<float>( y, x ) = 0.0f; |
||||
} |
||||
else |
||||
{ |
||||
const float xoff = x - half_cols; |
||||
const float yoff = y - half_rows; |
||||
// the samples from image
|
||||
int img_x = int( kp.pt.x + 0.5f + xoff ); |
||||
int img_y = int( kp.pt.y + 0.5f + yoff ); |
||||
// sample only within image
|
||||
if ( ( img_x < image.cols ) && ( img_x >= 0 ) |
||||
&& ( img_y < image.rows ) && ( img_y >= 0 ) ) |
||||
Patch.at<float>( y, x ) = image.at<float>( img_y, img_x ); |
||||
else |
||||
Patch.at<float>( y, x ) = 0.0f; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
// get descriptor given 64x64 image patch
|
||||
static void get_desc( const Mat Patch, Mat& PatchTrans, int anglebins, bool img_normalize ) |
||||
{ |
||||
Mat Ix, Iy; |
||||
// % compute gradient
|
||||
float kparam[3] = { -1, 0, 1 }; |
||||
Mat Kernel( 1, 3, CV_32F, &kparam ); |
||||
filter2D( Patch, Ix, CV_32F, Kernel, Point( -1, -1 ), 0, BORDER_REPLICATE ); |
||||
filter2D( Patch, Iy, CV_32F, Kernel.t(), Point( -1, -1 ), 0, BORDER_REPLICATE ); |
||||
|
||||
Mat GMag, GAngle; |
||||
|
||||
// % gradient magnitude
|
||||
// % GMag = sqrt(Ix .^ 2 + Iy .^ 2);
|
||||
magnitude( Ix, Iy, GMag ); |
||||
|
||||
// % gradient orientation: [0; 2 * pi]
|
||||
// % GAngle = atan2(Iy, Ix) + pi;
|
||||
//phase( Ix, Iy, GAngle, false ); //<- opencv is buggy
|
||||
GAngle = Mat( GMag.rows, GMag.cols, CV_32F ); |
||||
for ( int i = 0; i < (int)GAngle.total(); i++ ) |
||||
GAngle.at<float>(i) = atan2( Iy.at<float>(i), Ix.at<float>(i) ) + (float)CV_PI; |
||||
|
||||
// % soft-assignment of gradients to the orientation histogram
|
||||
float AngleStep = 2.0f * (float) CV_PI / (float) anglebins; |
||||
Mat GAngleRatio = GAngle / AngleStep - 0.5f; |
||||
|
||||
// % Offset1 = mod(GAngleRatio, 1);
|
||||
Mat Offset1( GAngleRatio.rows, GAngleRatio.cols, CV_32F ); |
||||
for ( int i = 0; i < (int)GAngleRatio.total(); i++ ) |
||||
Offset1.at<float>(i) = GAngleRatio.at<float>(i) - floor( GAngleRatio.at<float>(i) ); |
||||
|
||||
Mat w1 = 1.0f - Offset1.t(); |
||||
Mat w2 = Offset1.t(); |
||||
|
||||
Mat Bin1( GAngleRatio.rows, GAngleRatio.cols, CV_8U ); |
||||
Mat Bin2( GAngleRatio.rows, GAngleRatio.cols, CV_8U ); |
||||
|
||||
// % Bin1 = ceil(GAngleRatio);
|
||||
// % Bin1(Bin1 == 0) = Params.nAngleBins;
|
||||
for ( int i = 0; i < (int)GAngleRatio.total(); i++ ) |
||||
{ |
||||
if ( ceil( GAngleRatio.at<float>(i) - 1.0f) == -1.0f ) |
||||
Bin1.at<uchar>(i) = (uchar) anglebins - 1; |
||||
else |
||||
Bin1.at<uchar>(i) = (uchar) ceil( GAngleRatio.at<float>(i) - 1.0f ); |
||||
} |
||||
|
||||
// % Bin2 = Bin1 + 1;
|
||||
// % Bin2(Bin2 > Params.nAngleBins) = 1;
|
||||
for ( int i = 0; i < (int)GAngleRatio.total(); i++ ) |
||||
{ |
||||
if ( ( Bin1.at<uchar>(i) + 1 ) > anglebins - 1 ) |
||||
Bin2.at<uchar>(i) = 0; |
||||
else |
||||
Bin2.at<uchar>(i) = Bin1.at<uchar>(i) + 1; |
||||
} |
||||
|
||||
// normalize
|
||||
if ( img_normalize ) |
||||
{ |
||||
// % Quantile = 0.8;
|
||||
float q = 0.8f; |
||||
|
||||
// % T = quantile(GMag(:), Quantile);
|
||||
Mat GMagSorted; |
||||
sort( GMag.reshape( 0, 1 ), GMagSorted, SORT_ASCENDING ); |
||||
|
||||
int n = GMagSorted.cols; |
||||
// scipy/stats/mstats_basic.py#L1718 mquantiles()
|
||||
// m = alphap + p*(1.-alphap-betap)
|
||||
// alphap = 0.5 betap = 0.5 => (m = 0.5)
|
||||
// aleph = (n*p + m)
|
||||
float aleph = ( n * q + 0.5f ); |
||||
int k = cvFloor( aleph ); |
||||
if ( k >= n - 1 ) k = n - 1; |
||||
if ( k <= 1 ) k = 1; |
||||
|
||||
float gamma = aleph - k; |
||||
if ( gamma >= 1.0f ) gamma = 1.0f; |
||||
if ( gamma <= 0.0f ) gamma = 0.0f; |
||||
// quantile out from distribution
|
||||
float T = ( 1.0f - gamma ) * GMagSorted.at<float>( k - 1 ) |
||||
+ gamma * GMagSorted.at<float>( k ); |
||||
|
||||
// avoid NaN
|
||||
if ( T != 0.0f ) GMag /= ( T / anglebins ); |
||||
} |
||||
|
||||
Mat Bin1T = Bin1.t(); |
||||
Mat Bin2T = Bin2.t(); |
||||
Mat GMagT = GMag.t(); |
||||
|
||||
// % feature channels
|
||||
PatchTrans = Mat( (int)Patch.total(), anglebins, CV_32F, Scalar::all(0) ); |
||||
|
||||
for ( int i = 0; i < anglebins; i++ ) |
||||
{ |
||||
for ( int p = 0; p < (int)Patch.total(); p++ ) |
||||
{ |
||||
if ( Bin1T.at<uchar>(p) == i ) |
||||
PatchTrans.at<float>(p,i) = w1.at<float>(p) * GMagT.at<float>(p); |
||||
if ( Bin2T.at<uchar>(p) == i ) |
||||
PatchTrans.at<float>(p,i) = w2.at<float>(p) * GMagT.at<float>(p); |
||||
} |
||||
} |
||||
} |
||||
|
||||
// -------------------------------------------------
|
||||
/* VGG interface implementation */ |
||||
|
||||
struct ComputeDescInvoker : ParallelLoopBody |
||||
{ |
||||
ComputeDescInvoker( const Mat& _image, Mat* _descriptors, |
||||
const vector<KeyPoint>& _keypoints, |
||||
const Mat& _PRFilters, const Mat& _Proj, |
||||
const int _anglebins, const bool _img_normalize, |
||||
const bool _use_scale_orientation, const float _scale_factor ) |
||||
{ |
||||
image = _image; |
||||
keypoints = _keypoints; |
||||
descriptors = _descriptors; |
||||
|
||||
Proj = _Proj; |
||||
PRFilters = _PRFilters; |
||||
|
||||
anglebins = _anglebins; |
||||
scale_factor = _scale_factor; |
||||
img_normalize = _img_normalize; |
||||
use_scale_orientation = _use_scale_orientation; |
||||
} |
||||
|
||||
void operator ()(const cv::Range& range) const |
||||
{ |
||||
Mat Desc, PatchTrans; |
||||
Mat Patch( 64, 64, CV_32F ); |
||||
for (int k = range.start; k < range.end; k++) |
||||
{ |
||||
// sample patch from image
|
||||
get_patch( keypoints[k], Patch, image, use_scale_orientation, scale_factor ); |
||||
// compute transform
|
||||
get_desc( Patch, PatchTrans, anglebins, img_normalize ); |
||||
// pool features
|
||||
Desc = PRFilters * PatchTrans; |
||||
// crop
|
||||
min( Desc, 1.0f, Desc ); |
||||
// reshape
|
||||
Desc = Desc.reshape( 1, (int)Desc.total() ); |
||||
// project
|
||||
descriptors->row( k ) = Desc.t() * Proj.t(); |
||||
} |
||||
} |
||||
|
||||
Mat image; |
||||
Mat *descriptors; |
||||
vector<KeyPoint> keypoints; |
||||
|
||||
Mat Proj; |
||||
Mat PRFilters; |
||||
|
||||
int anglebins; |
||||
float scale_factor; |
||||
bool img_normalize; |
||||
bool use_scale_orientation; |
||||
}; |
||||
|
||||
// descriptor computation using keypoints
|
||||
void VGG_Impl::compute( InputArray _image, vector<KeyPoint>& keypoints, OutputArray _descriptors ) |
||||
{ |
||||
// do nothing if no image
|
||||
if( _image.getMat().empty() ) |
||||
return; |
||||
|
||||
m_image = _image.getMat().clone(); |
||||
|
||||
// Only 8bit images
|
||||
CV_Assert( m_image.depth() == CV_8U ); |
||||
|
||||
// convert to gray inplace
|
||||
if( m_image.channels() > 1 ) |
||||
cvtColor( m_image, m_image, COLOR_BGR2GRAY ); |
||||
|
||||
//convert
|
||||
Mat image; |
||||
m_image.convertTo( image, CV_32F ); |
||||
m_image = image; |
||||
image.release(); |
||||
|
||||
// smooth whole image
|
||||
GaussianBlur( m_image, m_image, Size( 0, 0 ), m_isigma, m_isigma, BORDER_REPLICATE ); |
||||
|
||||
// allocate array
|
||||
_descriptors.create( (int) keypoints.size(), m_descriptor_size, CV_32F ); |
||||
|
||||
// prepare descriptors
|
||||
Mat descriptors = _descriptors.getMat(); |
||||
descriptors.setTo( Scalar(0) ); |
||||
|
||||
parallel_for_( Range( 0, (int) keypoints.size() ), |
||||
ComputeDescInvoker( m_image, &descriptors, keypoints, m_PRFilters, m_Proj, |
||||
m_anglebins, m_img_normalize, m_use_scale_orientation, |
||||
m_scale_factor ) |
||||
); |
||||
|
||||
// normalize desc
|
||||
if ( m_dsc_normalize ) |
||||
{ |
||||
normalize( descriptors, descriptors, 0.0f, 255.0f, NORM_MINMAX, CV_32F ); |
||||
descriptors.convertTo( _descriptors, CV_8U ); |
||||
} |
||||
} |
||||
|
||||
void VGG_Impl::ini_params( const int PRrows, const int PRcols, |
||||
const unsigned int PRidx[], const unsigned int PRidxSize, |
||||
const unsigned int PR[], |
||||
const int PJrows, const int PJcols, |
||||
const unsigned int PJidx[], const unsigned int PJidxSize, |
||||
const unsigned int PJ[] ) |
||||
{ |
||||
int idx; |
||||
|
||||
// initialize pool-region matrix
|
||||
m_PRFilters = Mat::zeros( PRrows, PRcols, CV_32F ); |
||||
// initialize projection matrix
|
||||
m_Proj = Mat::zeros( PJrows, PJcols, CV_32F ); |
||||
|
||||
idx = 0; |
||||
// fill sparse pool-region matrix
|
||||
for ( size_t i = 0; i < PRidxSize; i=i+2 ) |
||||
{ |
||||
for ( size_t k = 0; k < PRidx[i+1]; k++ ) |
||||
{ |
||||
// expand floats from hex blobs
|
||||
m_PRFilters.at<float>( PRidx[i] + (int)k ) = *(float *)&PR[idx]; |
||||
idx++; |
||||
} |
||||
} |
||||
|
||||
idx = 0; |
||||
// fill sparse projection matrix
|
||||
for ( size_t i = 0; i < PJidxSize; i=i+2 ) |
||||
{ |
||||
for ( size_t k = 0; k < PJidx[i+1]; k++ ) |
||||
{ |
||||
// expand floats from hex blobs
|
||||
m_Proj.at<float>( PJidx[i] + (int)k ) = *(float *)&PJ[idx]; |
||||
idx++; |
||||
} |
||||
} |
||||
} |
||||
|
||||
// constructor
|
||||
VGG_Impl::VGG_Impl( int _desc, float _isigma, bool _img_normalize, |
||||
bool _use_scale_orientation, float _scale_factor, bool _dsc_normalize ) |
||||
: m_isigma( _isigma ), m_scale_factor( _scale_factor ), |
||||
m_img_normalize( _img_normalize ), |
||||
m_use_scale_orientation( _use_scale_orientation ), |
||||
m_dsc_normalize( _dsc_normalize ) |
||||
{ |
||||
// constant
|
||||
m_anglebins = 8; |
||||
|
||||
// desc type
|
||||
switch ( _desc ) |
||||
{ |
||||
case VGG::VGG_120: |
||||
{ |
||||
#include "vgg_generated_120.i" |
||||
ini_params( PRrows, PRcols, PRidx, sizeof(PRidx)/sizeof(PRidx[0]), PR, |
||||
PJrows, PJcols, PJidx, sizeof(PJidx)/sizeof(PJidx[0]), PJ ); |
||||
} |
||||
break; |
||||
case VGG::VGG_80: |
||||
{ |
||||
#include "vgg_generated_80.i" |
||||
ini_params( PRrows, PRcols, PRidx, sizeof(PRidx)/sizeof(PRidx[0]), PR, |
||||
PJrows, PJcols, PJidx, sizeof(PJidx)/sizeof(PJidx[0]), PJ ); |
||||
} |
||||
break; |
||||
case VGG::VGG_64: |
||||
{ |
||||
#include "vgg_generated_64.i" |
||||
ini_params( PRrows, PRcols, PRidx, sizeof(PRidx)/sizeof(PRidx[0]), PR, |
||||
PJrows, PJcols, PJidx, sizeof(PJidx)/sizeof(PJidx[0]), PJ ); |
||||
} |
||||
break; |
||||
case VGG::VGG_48: |
||||
{ |
||||
|
||||
#include "vgg_generated_48.i" |
||||
ini_params( PRrows, PRcols, PRidx, sizeof(PRidx)/sizeof(PRidx[0]), PR, |
||||
PJrows, PJcols, PJidx, sizeof(PJidx)/sizeof(PJidx[0]), PJ ); |
||||
} |
||||
break; |
||||
default: |
||||
CV_Error( Error::StsInternal, "Unknown Descriptor Type." ); |
||||
} |
||||
|
||||
// set desc size
|
||||
m_descriptor_size = m_Proj.rows; |
||||
} |
||||
|
||||
// destructor
|
||||
VGG_Impl::~VGG_Impl() |
||||
{ |
||||
} |
||||
|
||||
Ptr<VGG> VGG::create( int desc, float isigma, bool img_normalize, bool use_scale_orientation, |
||||
float scale_factor, bool dsc_normalize ) |
||||
{ |
||||
return makePtr<VGG_Impl>( desc, isigma, img_normalize, use_scale_orientation, scale_factor, dsc_normalize ); |
||||
} |
||||
|
||||
|
||||
} // END NAMESPACE XFEATURES2D
|
||||
} // END NAMESPACE CV
|
Loading…
Reference in new issue