mirror of
https://github.com/opencv/opencv.git
synced 2024-11-28 05:06:29 +08:00
added tests for some detectors; made features2d object create functions as static classes methods; fixed OpponentColorDescriptorExtractor, BriefDescriptorExtractor (on rgb); renamed DynamicDetector
This commit is contained in:
parent
9ad7a1c927
commit
7e5c11a920
@ -1250,11 +1250,14 @@ public:
|
|||||||
*/
|
*/
|
||||||
void detect( const vector<Mat>& images, vector<vector<KeyPoint> >& keypoints, const vector<Mat>& masks=vector<Mat>() ) const;
|
void detect( const vector<Mat>& images, vector<vector<KeyPoint> >& keypoints, const vector<Mat>& masks=vector<Mat>() ) const;
|
||||||
|
|
||||||
// Read detector object from a file node
|
// Read detector object from a file node.
|
||||||
virtual void read( const FileNode& );
|
virtual void read( const FileNode& );
|
||||||
// Read detector object from a file node
|
// Read detector object from a file node.
|
||||||
virtual void write( FileStorage& ) const;
|
virtual void write( FileStorage& ) const;
|
||||||
|
|
||||||
|
// Create feature detector by detector name.
|
||||||
|
static Ptr<FeatureDetector> create( const string& detectorType );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const = 0;
|
virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const = 0;
|
||||||
/*
|
/*
|
||||||
@ -1416,7 +1419,7 @@ public:
|
|||||||
* gridRows Grid rows count.
|
* gridRows Grid rows count.
|
||||||
* gridCols Grid column count.
|
* gridCols Grid column count.
|
||||||
*/
|
*/
|
||||||
GridAdaptedFeatureDetector( const Ptr<FeatureDetector>& detector, int maxTotalKeypoints,
|
GridAdaptedFeatureDetector( const Ptr<FeatureDetector>& detector, int maxTotalKeypoints=1000,
|
||||||
int gridRows=4, int gridCols=4 );
|
int gridRows=4, int gridCols=4 );
|
||||||
|
|
||||||
// TODO implement read/write
|
// TODO implement read/write
|
||||||
@ -1448,19 +1451,15 @@ protected:
|
|||||||
int levels;
|
int levels;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/** \brief A feature detector parameter adjuster, this is used by the DynamicAdaptedFeatureDetector
|
||||||
* Dynamic Feature Detectors
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** \brief A feature detector parameter adjuster, this is used by the DynamicDetector
|
|
||||||
* and is a wrapper for FeatureDetector that allow them to be adjusted after a detection
|
* and is a wrapper for FeatureDetector that allow them to be adjusted after a detection
|
||||||
*/
|
*/
|
||||||
class CV_EXPORTS AdjusterAdapter: public FeatureDetector {
|
class CV_EXPORTS AdjusterAdapter: public FeatureDetector
|
||||||
public:
|
{
|
||||||
|
public:
|
||||||
/** pure virtual interface
|
/** pure virtual interface
|
||||||
*/
|
*/
|
||||||
virtual ~AdjusterAdapter() {
|
virtual ~AdjusterAdapter() {}
|
||||||
}
|
|
||||||
/** too few features were detected so, adjust the detector params accordingly
|
/** too few features were detected so, adjust the detector params accordingly
|
||||||
* \param min the minimum number of desired features
|
* \param min the minimum number of desired features
|
||||||
* \param n_detected the number previously detected
|
* \param n_detected the number previously detected
|
||||||
@ -1475,6 +1474,8 @@ public:
|
|||||||
* \return false if the parameters can't be adjusted any more
|
* \return false if the parameters can't be adjusted any more
|
||||||
*/
|
*/
|
||||||
virtual bool good() const = 0;
|
virtual bool good() const = 0;
|
||||||
|
|
||||||
|
static Ptr<AdjusterAdapter> create( const string& detectorType );
|
||||||
};
|
};
|
||||||
/** \brief an adaptively adjusting detector that iteratively detects until the desired number
|
/** \brief an adaptively adjusting detector that iteratively detects until the desired number
|
||||||
* of features are detected.
|
* of features are detected.
|
||||||
@ -1485,24 +1486,24 @@ public:
|
|||||||
* sample usage:
|
* sample usage:
|
||||||
//will create a detector that attempts to find 100 - 110 FAST Keypoints, and will at most run
|
//will create a detector that attempts to find 100 - 110 FAST Keypoints, and will at most run
|
||||||
//FAST feature detection 10 times until that number of keypoints are found
|
//FAST feature detection 10 times until that number of keypoints are found
|
||||||
Ptr<FeatureDetector> detector(new DynamicDetector (100, 110, 10,new FastAdjuster(20,true)));
|
Ptr<FeatureDetector> detector(new DynamicAdaptedFeatureDetector(new FastAdjuster(20,true),100, 110, 10));
|
||||||
|
|
||||||
*/
|
*/
|
||||||
class CV_EXPORTS DynamicDetector: public FeatureDetector {
|
class CV_EXPORTS DynamicAdaptedFeatureDetector: public FeatureDetector
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** \param min_features the minimum desired features
|
/** \param adjaster an AdjusterAdapter that will do the detection and parameter adjustment
|
||||||
* \param max_features the maximum desired number of features
|
* \param max_features the maximum desired number of features
|
||||||
* \param max_iters the maximum number of times to try to adjust the feature detector params
|
* \param max_iters the maximum number of times to try to adjust the feature detector params
|
||||||
* for the FastAdjuster this can be high, but with Star or Surf this can get time consuming
|
* for the FastAdjuster this can be high, but with Star or Surf this can get time consuming
|
||||||
* \param a an AdjusterAdapter that will do the detection and parameter adjustment
|
* \param min_features the minimum desired features
|
||||||
*/
|
*/
|
||||||
DynamicDetector(int min_features, int max_features, int max_iters,
|
DynamicAdaptedFeatureDetector( const Ptr<AdjusterAdapter>& adjaster, int min_features=400, int max_features=500, int max_iters=5 );
|
||||||
const Ptr<AdjusterAdapter>& a);
|
|
||||||
protected:
|
protected:
|
||||||
virtual void detectImpl(const cv::Mat& image,
|
virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
|
||||||
std::vector<cv::KeyPoint>& keypoints, const cv::Mat& mask =
|
|
||||||
cv::Mat()) const;
|
|
||||||
private:
|
private:
|
||||||
int escape_iters_;
|
int escape_iters_;
|
||||||
int min_features_, max_features_;
|
int min_features_, max_features_;
|
||||||
@ -1512,7 +1513,8 @@ private:
|
|||||||
/**\brief an adjust for the FAST detector. This will basically decrement or increment the
|
/**\brief an adjust for the FAST detector. This will basically decrement or increment the
|
||||||
* threshhold by 1
|
* threshhold by 1
|
||||||
*/
|
*/
|
||||||
class CV_EXPORTS FastAdjuster: public AdjusterAdapter {
|
class CV_EXPORTS FastAdjuster: public AdjusterAdapter
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
/**\param init_thresh the initial threshhold to start with, default = 20
|
/**\param init_thresh the initial threshhold to start with, default = 20
|
||||||
* \param nonmax whether to use non max or not for fast feature detection
|
* \param nonmax whether to use non max or not for fast feature detection
|
||||||
@ -1521,50 +1523,50 @@ public:
|
|||||||
virtual void tooFew(int min, int n_detected);
|
virtual void tooFew(int min, int n_detected);
|
||||||
virtual void tooMany(int max, int n_detected);
|
virtual void tooMany(int max, int n_detected);
|
||||||
virtual bool good() const;
|
virtual bool good() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void detectImpl(const cv::Mat& image,
|
virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
|
||||||
std::vector<cv::KeyPoint>& keypoints, const cv::Mat& mask =
|
|
||||||
cv::Mat()) const;
|
|
||||||
int thresh_;
|
int thresh_;
|
||||||
bool nonmax_;
|
bool nonmax_;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/** An adjuster for StarFeatureDetector, this one adjusts the responseThreshold for now
|
/** An adjuster for StarFeatureDetector, this one adjusts the responseThreshold for now
|
||||||
* TODO find a faster way to converge the parameters for Star - use CvStarDetectorParams
|
* TODO find a faster way to converge the parameters for Star - use CvStarDetectorParams
|
||||||
*/
|
*/
|
||||||
struct CV_EXPORTS StarAdjuster: public AdjusterAdapter {
|
class CV_EXPORTS StarAdjuster: public AdjusterAdapter
|
||||||
|
{
|
||||||
|
public:
|
||||||
StarAdjuster(double initial_thresh = 30.0);
|
StarAdjuster(double initial_thresh = 30.0);
|
||||||
virtual void tooFew(int min, int n_detected);
|
virtual void tooFew(int min, int n_detected);
|
||||||
virtual void tooMany(int max, int n_detected);
|
virtual void tooMany(int max, int n_detected);
|
||||||
virtual bool good() const;
|
virtual bool good() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void detectImpl(const cv::Mat& image,
|
virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
|
||||||
std::vector<cv::KeyPoint>& keypoints, const cv::Mat& mask =
|
|
||||||
cv::Mat()) const;
|
|
||||||
double thresh_;
|
double thresh_;
|
||||||
CvStarDetectorParams params_; //todo use these instead of thresh_
|
CvStarDetectorParams params_; //todo use these instead of thresh_
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CV_EXPORTS SurfAdjuster: public AdjusterAdapter {
|
class CV_EXPORTS SurfAdjuster: public AdjusterAdapter
|
||||||
SurfAdjuster();
|
{
|
||||||
|
public:
|
||||||
|
SurfAdjuster();
|
||||||
virtual void tooFew(int min, int n_detected);
|
virtual void tooFew(int min, int n_detected);
|
||||||
virtual void tooMany(int max, int n_detected);
|
virtual void tooMany(int max, int n_detected);
|
||||||
virtual bool good() const;
|
virtual bool good() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void detectImpl(const cv::Mat& image,
|
virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
|
||||||
std::vector<cv::KeyPoint>& keypoints, const cv::Mat& mask =
|
|
||||||
cv::Mat()) const;
|
|
||||||
double thresh_;
|
double thresh_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
CV_EXPORTS Mat windowedMatchingMask( const vector<KeyPoint>& keypoints1, const vector<KeyPoint>& keypoints2,
|
CV_EXPORTS Mat windowedMatchingMask( const vector<KeyPoint>& keypoints1, const vector<KeyPoint>& keypoints2,
|
||||||
float maxDeltaX, float maxDeltaY );
|
float maxDeltaX, float maxDeltaY );
|
||||||
|
|
||||||
CV_EXPORTS Ptr<FeatureDetector> createFeatureDetector( const string& detectorType );
|
|
||||||
|
|
||||||
/****************************************************************************************\
|
/****************************************************************************************\
|
||||||
* DescriptorExtractor *
|
* DescriptorExtractor *
|
||||||
\****************************************************************************************/
|
\****************************************************************************************/
|
||||||
@ -1606,6 +1608,8 @@ public:
|
|||||||
virtual int descriptorSize() const = 0;
|
virtual int descriptorSize() const = 0;
|
||||||
virtual int descriptorType() const = 0;
|
virtual int descriptorType() const = 0;
|
||||||
|
|
||||||
|
static Ptr<DescriptorExtractor> create( const string& descriptorExtractorType );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void computeImpl( const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors ) const = 0;
|
virtual void computeImpl( const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors ) const = 0;
|
||||||
|
|
||||||
@ -1771,8 +1775,6 @@ protected:
|
|||||||
PixelTestFn test_fn_;
|
PixelTestFn test_fn_;
|
||||||
};
|
};
|
||||||
|
|
||||||
CV_EXPORTS Ptr<DescriptorExtractor> createDescriptorExtractor( const string& descriptorExtractorType );
|
|
||||||
|
|
||||||
/****************************************************************************************\
|
/****************************************************************************************\
|
||||||
* Distance *
|
* Distance *
|
||||||
\****************************************************************************************/
|
\****************************************************************************************/
|
||||||
@ -1981,6 +1983,7 @@ public:
|
|||||||
// but with empty train data.
|
// but with empty train data.
|
||||||
virtual Ptr<DescriptorMatcher> clone( bool emptyTrainData=false ) const = 0;
|
virtual Ptr<DescriptorMatcher> clone( bool emptyTrainData=false ) const = 0;
|
||||||
|
|
||||||
|
static Ptr<DescriptorMatcher> create( const string& descriptorMatcherType );
|
||||||
protected:
|
protected:
|
||||||
/*
|
/*
|
||||||
* Class to work with descriptors from several images as with one merged matrix.
|
* Class to work with descriptors from several images as with one merged matrix.
|
||||||
@ -2265,9 +2268,6 @@ protected:
|
|||||||
int addedDescCount;
|
int addedDescCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
CV_EXPORTS Ptr<DescriptorMatcher> createDescriptorMatcher( const string& descriptorMatcherType );
|
|
||||||
|
|
||||||
/****************************************************************************************\
|
/****************************************************************************************\
|
||||||
* GenericDescriptorMatcher *
|
* GenericDescriptorMatcher *
|
||||||
\****************************************************************************************/
|
\****************************************************************************************/
|
||||||
@ -2372,6 +2372,9 @@ public:
|
|||||||
// but with empty train data.
|
// but with empty train data.
|
||||||
virtual Ptr<GenericDescriptorMatcher> clone( bool emptyTrainData=false ) const = 0;
|
virtual Ptr<GenericDescriptorMatcher> clone( bool emptyTrainData=false ) const = 0;
|
||||||
|
|
||||||
|
static Ptr<GenericDescriptorMatcher> create( const string& genericDescritptorMatcherType,
|
||||||
|
const string ¶msFilename=string() );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// In fact the matching is implemented only by the following two methods. These methods suppose
|
// In fact the matching is implemented only by the following two methods. These methods suppose
|
||||||
// that the class object has been trained already. Public match methods call these methods
|
// that the class object has been trained already. Public match methods call these methods
|
||||||
@ -2557,9 +2560,6 @@ protected:
|
|||||||
int prevTrainCount;
|
int prevTrainCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
CV_EXPORTS Ptr<GenericDescriptorMatcher> createGenericDescriptorMatcher( const string& genericDescritptorMatcherType,
|
|
||||||
const string ¶msFilename = string () );
|
|
||||||
|
|
||||||
/****************************************************************************************\
|
/****************************************************************************************\
|
||||||
* VectorDescriptorMatcher *
|
* VectorDescriptorMatcher *
|
||||||
\****************************************************************************************/
|
\****************************************************************************************/
|
||||||
|
@ -92,15 +92,17 @@ void pixelTests64(const Mat& sum, const std::vector<KeyPoint>& keypoints, Mat& d
|
|||||||
|
|
||||||
namespace cv
|
namespace cv
|
||||||
{
|
{
|
||||||
|
|
||||||
HammingLUT::ResultType HammingLUT::operator()( const unsigned char* a, const unsigned char* b, int size ) const
|
HammingLUT::ResultType HammingLUT::operator()( const unsigned char* a, const unsigned char* b, int size ) const
|
||||||
{
|
{
|
||||||
ResultType result = 0;
|
ResultType result = 0;
|
||||||
for (int i = 0; i < size; i++)
|
for (int i = 0; i < size; i++)
|
||||||
{
|
{
|
||||||
result += byteBitsLookUp(a[i] ^ b[i]);
|
result += byteBitsLookUp(a[i] ^ b[i]);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Hamming::ResultType Hamming::operator()(const unsigned char* a, const unsigned char* b, int size) const
|
Hamming::ResultType Hamming::operator()(const unsigned char* a, const unsigned char* b, int size) const
|
||||||
{
|
{
|
||||||
#if __GNUC__
|
#if __GNUC__
|
||||||
@ -116,6 +118,7 @@ Hamming::ResultType Hamming::operator()(const unsigned char* a, const unsigned c
|
|||||||
return HammingLUT()(a,b,size);
|
return HammingLUT()(a,b,size);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
BriefDescriptorExtractor::BriefDescriptorExtractor(int bytes) :
|
BriefDescriptorExtractor::BriefDescriptorExtractor(int bytes) :
|
||||||
bytes_(bytes), test_fn_(NULL)
|
bytes_(bytes), test_fn_(NULL)
|
||||||
{
|
{
|
||||||
@ -150,12 +153,15 @@ void BriefDescriptorExtractor::computeImpl(const Mat& image, std::vector<KeyPoin
|
|||||||
// Construct integral image for fast smoothing (box filter)
|
// Construct integral image for fast smoothing (box filter)
|
||||||
Mat sum;
|
Mat sum;
|
||||||
|
|
||||||
|
Mat grayImage = image;
|
||||||
|
if( image.type() != CV_8U ) cvtColor( image, grayImage, CV_BGR2GRAY );
|
||||||
|
|
||||||
///TODO allow the user to pass in a precomputed integral image
|
///TODO allow the user to pass in a precomputed integral image
|
||||||
//if(image.type() == CV_32S)
|
//if(image.type() == CV_32S)
|
||||||
// sum = image;
|
// sum = image;
|
||||||
//else
|
//else
|
||||||
|
|
||||||
integral(image, sum, CV_32S);
|
integral( grayImage, sum, CV_32S);
|
||||||
|
|
||||||
//Remove keypoints very close to the border
|
//Remove keypoints very close to the border
|
||||||
removeBorderKeypoints(keypoints, image.size(), PATCH_SIZE/2 + KERNEL_SIZE/2);
|
removeBorderKeypoints(keypoints, image.size(), PATCH_SIZE/2 + KERNEL_SIZE/2);
|
||||||
|
@ -109,6 +109,31 @@ void DescriptorExtractor::removeBorderKeypoints( vector<KeyPoint>& keypoints,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ptr<DescriptorExtractor> DescriptorExtractor::create(const string& descriptorExtractorType)
|
||||||
|
{
|
||||||
|
DescriptorExtractor* de = 0;
|
||||||
|
|
||||||
|
int pos = 0;
|
||||||
|
if (!descriptorExtractorType.compare("SIFT"))
|
||||||
|
{
|
||||||
|
de = new SiftDescriptorExtractor();
|
||||||
|
}
|
||||||
|
else if (!descriptorExtractorType.compare("SURF"))
|
||||||
|
{
|
||||||
|
de = new SurfDescriptorExtractor();
|
||||||
|
}
|
||||||
|
else if (!descriptorExtractorType.compare("BRIEF"))
|
||||||
|
{
|
||||||
|
de = new BriefDescriptorExtractor();
|
||||||
|
}
|
||||||
|
else if ( (pos=descriptorExtractorType.find("Opponent")) == 0)
|
||||||
|
{
|
||||||
|
pos += string("Opponent").size();
|
||||||
|
de = new OpponentColorDescriptorExtractor( DescriptorExtractor::create(descriptorExtractorType.substr(pos)) );
|
||||||
|
}
|
||||||
|
return de;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************************\
|
/****************************************************************************************\
|
||||||
* SiftDescriptorExtractor *
|
* SiftDescriptorExtractor *
|
||||||
\****************************************************************************************/
|
\****************************************************************************************/
|
||||||
@ -231,7 +256,9 @@ int SurfDescriptorExtractor::descriptorType() const
|
|||||||
\****************************************************************************************/
|
\****************************************************************************************/
|
||||||
OpponentColorDescriptorExtractor::OpponentColorDescriptorExtractor( const Ptr<DescriptorExtractor>& _descriptorExtractor ) :
|
OpponentColorDescriptorExtractor::OpponentColorDescriptorExtractor( const Ptr<DescriptorExtractor>& _descriptorExtractor ) :
|
||||||
descriptorExtractor(_descriptorExtractor)
|
descriptorExtractor(_descriptorExtractor)
|
||||||
{}
|
{
|
||||||
|
CV_Assert( !descriptorExtractor.empty() );
|
||||||
|
}
|
||||||
|
|
||||||
void convertBGRImageToOpponentColorSpace( const Mat& bgrImage, vector<Mat>& opponentChannels )
|
void convertBGRImageToOpponentColorSpace( const Mat& bgrImage, vector<Mat>& opponentChannels )
|
||||||
{
|
{
|
||||||
@ -305,7 +332,7 @@ void OpponentColorDescriptorExtractor::computeImpl( const Mat& bgrImage, vector<
|
|||||||
// Compute descriptors three times, once for each Opponent channel
|
// Compute descriptors three times, once for each Opponent channel
|
||||||
// and concatenate into a single color surf descriptor
|
// and concatenate into a single color surf descriptor
|
||||||
int descriptorSize = descriptorExtractor->descriptorSize();
|
int descriptorSize = descriptorExtractor->descriptorSize();
|
||||||
descriptors.create( static_cast<int>(keypoints.size()), 3*descriptorSize, CV_32FC1 );
|
descriptors.create( static_cast<int>(keypoints.size()), 3*descriptorSize, descriptorExtractor->descriptorType() );
|
||||||
for( int i = 0; i < 3/*channel count*/; i++ )
|
for( int i = 0; i < 3/*channel count*/; i++ )
|
||||||
{
|
{
|
||||||
CV_Assert( opponentChannels[i].type() == CV_8UC1 );
|
CV_Assert( opponentChannels[i].type() == CV_8UC1 );
|
||||||
@ -333,34 +360,5 @@ int OpponentColorDescriptorExtractor::descriptorType() const
|
|||||||
{
|
{
|
||||||
return descriptorExtractor->descriptorType();
|
return descriptorExtractor->descriptorType();
|
||||||
}
|
}
|
||||||
/****************************************************************************************\
|
|
||||||
* Factory function for descriptor extractor creating *
|
|
||||||
\****************************************************************************************/
|
|
||||||
|
|
||||||
Ptr<DescriptorExtractor> createDescriptorExtractor(const string& descriptorExtractorType)
|
|
||||||
{
|
|
||||||
DescriptorExtractor* de = 0;
|
|
||||||
if (!descriptorExtractorType.compare("SIFT"))
|
|
||||||
{
|
|
||||||
de = new SiftDescriptorExtractor();
|
|
||||||
}
|
|
||||||
else if (!descriptorExtractorType.compare("SURF"))
|
|
||||||
{
|
|
||||||
de = new SurfDescriptorExtractor();
|
|
||||||
}
|
|
||||||
else if (!descriptorExtractorType.compare("OpponentSIFT"))
|
|
||||||
{
|
|
||||||
de = new OpponentColorDescriptorExtractor(new SiftDescriptorExtractor);
|
|
||||||
}
|
|
||||||
else if (!descriptorExtractorType.compare("OpponentSURF"))
|
|
||||||
{
|
|
||||||
de = new OpponentColorDescriptorExtractor(new SurfDescriptorExtractor);
|
|
||||||
}
|
|
||||||
else if (!descriptorExtractorType.compare("BRIEF"))
|
|
||||||
{
|
|
||||||
de = new BriefDescriptorExtractor();
|
|
||||||
}
|
|
||||||
return de;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -97,6 +97,60 @@ void FeatureDetector::read( const FileNode& )
|
|||||||
void FeatureDetector::write( FileStorage& ) const
|
void FeatureDetector::write( FileStorage& ) const
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
Ptr<FeatureDetector> FeatureDetector::create( const string& detectorType )
|
||||||
|
{
|
||||||
|
FeatureDetector* fd = 0;
|
||||||
|
int pos = 0;
|
||||||
|
|
||||||
|
if( !detectorType.compare( "FAST" ) )
|
||||||
|
{
|
||||||
|
fd = new FastFeatureDetector();
|
||||||
|
}
|
||||||
|
else if( !detectorType.compare( "STAR" ) )
|
||||||
|
{
|
||||||
|
fd = new StarFeatureDetector();
|
||||||
|
}
|
||||||
|
else if( !detectorType.compare( "SIFT" ) )
|
||||||
|
{
|
||||||
|
fd = new SiftFeatureDetector();
|
||||||
|
}
|
||||||
|
else if( !detectorType.compare( "SURF" ) )
|
||||||
|
{
|
||||||
|
fd = new SurfFeatureDetector();
|
||||||
|
}
|
||||||
|
else if( !detectorType.compare( "MSER" ) )
|
||||||
|
{
|
||||||
|
fd = new MserFeatureDetector();
|
||||||
|
}
|
||||||
|
else if( !detectorType.compare( "GFTT" ) )
|
||||||
|
{
|
||||||
|
fd = new GoodFeaturesToTrackDetector();
|
||||||
|
}
|
||||||
|
else if( !detectorType.compare( "HARRIS" ) )
|
||||||
|
{
|
||||||
|
GoodFeaturesToTrackDetector::Params params;
|
||||||
|
params.useHarrisDetector = true;
|
||||||
|
fd = new GoodFeaturesToTrackDetector(params);
|
||||||
|
}
|
||||||
|
else if( (pos=detectorType.find("Grid")) == 0 )
|
||||||
|
{
|
||||||
|
pos += string("Grid").size();
|
||||||
|
fd = new GridAdaptedFeatureDetector( FeatureDetector::create(detectorType.substr(pos)) );
|
||||||
|
}
|
||||||
|
else if( (pos=detectorType.find("Pyramid")) == 0 )
|
||||||
|
{
|
||||||
|
pos += string("Pyramid").size();
|
||||||
|
fd = new PyramidAdaptedFeatureDetector( FeatureDetector::create(detectorType.substr(pos)) );
|
||||||
|
}
|
||||||
|
else if( (pos=detectorType.find("Dynamic")) == 0 )
|
||||||
|
{
|
||||||
|
pos += string("Dynamic").size();
|
||||||
|
fd = new DynamicAdaptedFeatureDetector( AdjusterAdapter::create(detectorType.substr(pos)) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FastFeatureDetector
|
* FastFeatureDetector
|
||||||
*/
|
*/
|
||||||
@ -519,53 +573,4 @@ void PyramidAdaptedFeatureDetector::detectImpl( const Mat& image, vector<KeyPoin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ptr<FeatureDetector> createFeatureDetector( const string& detectorType )
|
|
||||||
{
|
|
||||||
FeatureDetector* fd = 0;
|
|
||||||
if( !detectorType.compare( "FAST" ) )
|
|
||||||
{
|
|
||||||
fd = new FastFeatureDetector();
|
|
||||||
}
|
|
||||||
else if( !detectorType.compare( "DynamicFAST" ) )
|
|
||||||
{
|
|
||||||
fd = new DynamicDetector(400,500,5,new FastAdjuster());
|
|
||||||
}
|
|
||||||
else if( !detectorType.compare( "STAR" ) )
|
|
||||||
{
|
|
||||||
fd = new StarFeatureDetector();
|
|
||||||
}
|
|
||||||
else if( !detectorType.compare( "DynamicSTAR" ) )
|
|
||||||
{
|
|
||||||
fd = new DynamicDetector(400,500,5,new StarAdjuster());
|
|
||||||
}
|
|
||||||
else if( !detectorType.compare( "SIFT" ) )
|
|
||||||
{
|
|
||||||
fd = new SiftFeatureDetector(SIFT::DetectorParams::GET_DEFAULT_THRESHOLD(),
|
|
||||||
SIFT::DetectorParams::GET_DEFAULT_EDGE_THRESHOLD());
|
|
||||||
}
|
|
||||||
else if( !detectorType.compare( "SURF" ) )
|
|
||||||
{
|
|
||||||
fd = new SurfFeatureDetector();
|
|
||||||
}
|
|
||||||
else if( !detectorType.compare( "DynamicSURF" ) )
|
|
||||||
{
|
|
||||||
fd =new DynamicDetector(400,500,5,new SurfAdjuster());
|
|
||||||
}
|
|
||||||
else if( !detectorType.compare( "MSER" ) )
|
|
||||||
{
|
|
||||||
fd = new MserFeatureDetector();
|
|
||||||
}
|
|
||||||
else if( !detectorType.compare( "GFTT" ) )
|
|
||||||
{
|
|
||||||
fd = new GoodFeaturesToTrackDetector();
|
|
||||||
}
|
|
||||||
else if( !detectorType.compare( "HARRIS" ) )
|
|
||||||
{
|
|
||||||
GoodFeaturesToTrackDetector::Params params;
|
|
||||||
params.useHarrisDetector = true;
|
|
||||||
fd = new GoodFeaturesToTrackDetector(params);
|
|
||||||
}
|
|
||||||
return fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -41,14 +41,16 @@
|
|||||||
//M*/
|
//M*/
|
||||||
|
|
||||||
#include "precomp.hpp"
|
#include "precomp.hpp"
|
||||||
namespace cv {
|
namespace cv
|
||||||
DynamicDetector::DynamicDetector(int min_features,
|
{
|
||||||
int max_features, int max_iters, const Ptr<AdjusterAdapter>& a) :
|
|
||||||
escape_iters_(max_iters), min_features_(min_features), max_features_(
|
DynamicAdaptedFeatureDetector::DynamicAdaptedFeatureDetector(const Ptr<AdjusterAdapter>& a,
|
||||||
max_features), adjuster_(a) {
|
int min_features, int max_features, int max_iters ) :
|
||||||
}
|
escape_iters_(max_iters), min_features_(min_features), max_features_(max_features), adjuster_(a)
|
||||||
void DynamicDetector::detectImpl(const cv::Mat& image, std::vector<
|
{}
|
||||||
cv::KeyPoint>& keypoints, const cv::Mat& mask) const {
|
|
||||||
|
void DynamicAdaptedFeatureDetector::detectImpl(const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask) const
|
||||||
|
{
|
||||||
//for oscillation testing
|
//for oscillation testing
|
||||||
bool down = false;
|
bool down = false;
|
||||||
bool up = false;
|
bool up = false;
|
||||||
@ -62,88 +64,131 @@ void DynamicDetector::detectImpl(const cv::Mat& image, std::vector<
|
|||||||
//break if the desired number hasn't been reached.
|
//break if the desired number hasn't been reached.
|
||||||
int iter_count = escape_iters_;
|
int iter_count = escape_iters_;
|
||||||
|
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
keypoints.clear();
|
keypoints.clear();
|
||||||
|
|
||||||
//the adjuster takes care of calling the detector with updated parameters
|
//the adjuster takes care of calling the detector with updated parameters
|
||||||
adjuster.detect(image, keypoints,mask);
|
adjuster.detect(image, keypoints,mask);
|
||||||
|
|
||||||
if (int(keypoints.size()) < min_features_) {
|
if (int(keypoints.size()) < min_features_)
|
||||||
|
{
|
||||||
down = true;
|
down = true;
|
||||||
adjuster.tooFew(min_features_, keypoints.size());
|
adjuster.tooFew(min_features_, keypoints.size());
|
||||||
} else if (int(keypoints.size()) > max_features_) {
|
}
|
||||||
|
else if (int(keypoints.size()) > max_features_)
|
||||||
|
{
|
||||||
up = true;
|
up = true;
|
||||||
adjuster.tooMany(max_features_, keypoints.size());
|
adjuster.tooMany(max_features_, keypoints.size());
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
thresh_good = true;
|
thresh_good = true;
|
||||||
} while (--iter_count >= 0 && !(down && up) && !thresh_good
|
}
|
||||||
&& adjuster.good());
|
while (--iter_count >= 0 && !(down && up) && !thresh_good && adjuster.good());
|
||||||
}
|
}
|
||||||
|
|
||||||
FastAdjuster::FastAdjuster(int init_thresh, bool nonmax) :
|
FastAdjuster::FastAdjuster(int init_thresh, bool nonmax) :
|
||||||
thresh_(init_thresh), nonmax_(nonmax) {
|
thresh_(init_thresh), nonmax_(nonmax)
|
||||||
}
|
{}
|
||||||
void FastAdjuster::detectImpl(const cv::Mat& image,
|
|
||||||
std::vector<cv::KeyPoint>& keypoints, const cv::Mat& mask) const {
|
void FastAdjuster::detectImpl(const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask) const
|
||||||
|
{
|
||||||
FastFeatureDetector(thresh_, nonmax_).detect(image, keypoints, mask);
|
FastFeatureDetector(thresh_, nonmax_).detect(image, keypoints, mask);
|
||||||
}
|
}
|
||||||
void FastAdjuster::tooFew(int min, int n_detected) {
|
|
||||||
|
void FastAdjuster::tooFew(int min, int n_detected)
|
||||||
|
{
|
||||||
//fast is easy to adjust
|
//fast is easy to adjust
|
||||||
thresh_--;
|
thresh_--;
|
||||||
}
|
}
|
||||||
void FastAdjuster::tooMany(int max, int n_detected) {
|
|
||||||
|
void FastAdjuster::tooMany(int max, int n_detected)
|
||||||
|
{
|
||||||
//fast is easy to adjust
|
//fast is easy to adjust
|
||||||
thresh_++;
|
thresh_++;
|
||||||
}
|
}
|
||||||
|
|
||||||
//return whether or not the threshhold is beyond
|
//return whether or not the threshhold is beyond
|
||||||
//a useful point
|
//a useful point
|
||||||
bool FastAdjuster::good() const {
|
bool FastAdjuster::good() const
|
||||||
|
{
|
||||||
return (thresh_ > 1) && (thresh_ < 200);
|
return (thresh_ > 1) && (thresh_ < 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
StarAdjuster::StarAdjuster(double initial_thresh) :
|
StarAdjuster::StarAdjuster(double initial_thresh) :
|
||||||
thresh_(initial_thresh) {
|
thresh_(initial_thresh)
|
||||||
}
|
{}
|
||||||
void StarAdjuster::detectImpl(const cv::Mat& image,
|
|
||||||
std::vector<cv::KeyPoint>& keypoints, const cv::Mat& mask) const {
|
void StarAdjuster::detectImpl(const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask) const
|
||||||
|
{
|
||||||
StarFeatureDetector detector_tmp(16, thresh_, 10, 8, 3);
|
StarFeatureDetector detector_tmp(16, thresh_, 10, 8, 3);
|
||||||
detector_tmp.detect(image, keypoints, mask);
|
detector_tmp.detect(image, keypoints, mask);
|
||||||
}
|
}
|
||||||
void StarAdjuster::tooFew(int min, int n_detected) {
|
|
||||||
|
void StarAdjuster::tooFew(int min, int n_detected)
|
||||||
|
{
|
||||||
thresh_ *= 0.9;
|
thresh_ *= 0.9;
|
||||||
if (thresh_ < 1.1)
|
if (thresh_ < 1.1)
|
||||||
thresh_ = 1.1;
|
thresh_ = 1.1;
|
||||||
}
|
}
|
||||||
void StarAdjuster::tooMany(int max, int n_detected) {
|
|
||||||
|
void StarAdjuster::tooMany(int max, int n_detected)
|
||||||
|
{
|
||||||
thresh_ *= 1.1;
|
thresh_ *= 1.1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StarAdjuster::good() const {
|
bool StarAdjuster::good() const
|
||||||
|
{
|
||||||
return (thresh_ > 2) && (thresh_ < 200);
|
return (thresh_ > 2) && (thresh_ < 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
SurfAdjuster::SurfAdjuster() :
|
SurfAdjuster::SurfAdjuster() :
|
||||||
thresh_(400.0) {
|
thresh_(400.0)
|
||||||
}
|
{}
|
||||||
void SurfAdjuster::detectImpl(const cv::Mat& image,
|
|
||||||
std::vector<cv::KeyPoint>& keypoints, const cv::Mat& mask) const {
|
void SurfAdjuster::detectImpl(const Mat& image, vector<KeyPoint>& keypoints, const cv::Mat& mask) const
|
||||||
|
{
|
||||||
SurfFeatureDetector detector_tmp(thresh_);
|
SurfFeatureDetector detector_tmp(thresh_);
|
||||||
detector_tmp.detect(image, keypoints, mask);
|
detector_tmp.detect(image, keypoints, mask);
|
||||||
}
|
}
|
||||||
void SurfAdjuster::tooFew(int min, int n_detected) {
|
|
||||||
|
void SurfAdjuster::tooFew(int min, int n_detected)
|
||||||
|
{
|
||||||
thresh_ *= 0.9;
|
thresh_ *= 0.9;
|
||||||
if (thresh_ < 1.1)
|
if (thresh_ < 1.1)
|
||||||
thresh_ = 1.1;
|
thresh_ = 1.1;
|
||||||
}
|
}
|
||||||
void SurfAdjuster::tooMany(int max, int n_detected) {
|
|
||||||
|
void SurfAdjuster::tooMany(int max, int n_detected)
|
||||||
|
{
|
||||||
thresh_ *= 1.1;
|
thresh_ *= 1.1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//return whether or not the threshhold is beyond
|
//return whether or not the threshhold is beyond
|
||||||
//a useful point
|
//a useful point
|
||||||
bool SurfAdjuster::good() const {
|
bool SurfAdjuster::good() const
|
||||||
|
{
|
||||||
return (thresh_ > 2) && (thresh_ < 1000);
|
return (thresh_ > 2) && (thresh_ < 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ptr<AdjusterAdapter> AdjusterAdapter::create( const string& detectorType )
|
||||||
|
{
|
||||||
|
Ptr<AdjusterAdapter> adapter;
|
||||||
|
|
||||||
|
if( !detectorType.compare( "FAST" ) )
|
||||||
|
{
|
||||||
|
adapter = new FastAdjuster();
|
||||||
|
}
|
||||||
|
else if( !detectorType.compare( "STAR" ) )
|
||||||
|
{
|
||||||
|
adapter = new StarAdjuster();
|
||||||
|
}
|
||||||
|
else if( !detectorType.compare( "SURF" ) )
|
||||||
|
{
|
||||||
|
adapter = new SurfAdjuster();
|
||||||
|
}
|
||||||
|
|
||||||
|
return adapter;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -322,7 +322,39 @@ bool DescriptorMatcher::isMaskedOut( const vector<Mat>& masks, int queryIdx )
|
|||||||
return !masks.empty() && outCount == masks.size() ;
|
return !masks.empty() && outCount == masks.size() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Factory function for DescriptorMatcher creating
|
||||||
|
*/
|
||||||
|
Ptr<DescriptorMatcher> DescriptorMatcher::create( const string& descriptorMatcherType )
|
||||||
|
{
|
||||||
|
DescriptorMatcher* dm = 0;
|
||||||
|
if( !descriptorMatcherType.compare( "FlannBased" ) )
|
||||||
|
{
|
||||||
|
dm = new FlannBasedMatcher();
|
||||||
|
}
|
||||||
|
else if( !descriptorMatcherType.compare( "BruteForce" ) ) // L2
|
||||||
|
{
|
||||||
|
dm = new BruteForceMatcher<L2<float> >();
|
||||||
|
}
|
||||||
|
else if( !descriptorMatcherType.compare( "BruteForce-L1" ) )
|
||||||
|
{
|
||||||
|
dm = new BruteForceMatcher<L1<float> >();
|
||||||
|
}
|
||||||
|
else if( !descriptorMatcherType.compare("BruteForce-Hamming") )
|
||||||
|
{
|
||||||
|
dm = new BruteForceMatcher<Hamming>();
|
||||||
|
}
|
||||||
|
else if( !descriptorMatcherType.compare( "BruteForce-HammingLUT") )
|
||||||
|
{
|
||||||
|
dm = new BruteForceMatcher<HammingLUT>();
|
||||||
|
}
|
||||||
|
|
||||||
|
return dm;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* BruteForce L2 specialization
|
||||||
|
*/
|
||||||
template<>
|
template<>
|
||||||
void BruteForceMatcher<L2<float> >::knnMatchImpl( const Mat& queryDescriptors, vector<vector<DMatch> >& matches, int knn,
|
void BruteForceMatcher<L2<float> >::knnMatchImpl( const Mat& queryDescriptors, vector<vector<DMatch> >& matches, int knn,
|
||||||
const vector<Mat>& masks, bool compactResult )
|
const vector<Mat>& masks, bool compactResult )
|
||||||
@ -585,36 +617,6 @@ void FlannBasedMatcher::radiusMatchImpl( const Mat& queryDescriptors, vector<vec
|
|||||||
convertToDMatches( mergedDescriptors, indices, dists, matches );
|
convertToDMatches( mergedDescriptors, indices, dists, matches );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Factory function for DescriptorMatcher creating
|
|
||||||
*/
|
|
||||||
Ptr<DescriptorMatcher> createDescriptorMatcher( const string& descriptorMatcherType )
|
|
||||||
{
|
|
||||||
DescriptorMatcher* dm = 0;
|
|
||||||
if( !descriptorMatcherType.compare( "FlannBased" ) )
|
|
||||||
{
|
|
||||||
dm = new FlannBasedMatcher();
|
|
||||||
}
|
|
||||||
else if( !descriptorMatcherType.compare( "BruteForce" ) ) // L2
|
|
||||||
{
|
|
||||||
dm = new BruteForceMatcher<L2<float> >();
|
|
||||||
}
|
|
||||||
else if( !descriptorMatcherType.compare( "BruteForce-L1" ) )
|
|
||||||
{
|
|
||||||
dm = new BruteForceMatcher<L1<float> >();
|
|
||||||
}
|
|
||||||
else if( !descriptorMatcherType.compare("BruteForce-Hamming") )
|
|
||||||
{
|
|
||||||
dm = new BruteForceMatcher<Hamming>();
|
|
||||||
}
|
|
||||||
else if( !descriptorMatcherType.compare( "BruteForce-HammingLUT") )
|
|
||||||
{
|
|
||||||
dm = new BruteForceMatcher<HammingLUT>();
|
|
||||||
}
|
|
||||||
|
|
||||||
return dm;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************************\
|
/****************************************************************************************\
|
||||||
* GenericDescriptorMatcher *
|
* GenericDescriptorMatcher *
|
||||||
\****************************************************************************************/
|
\****************************************************************************************/
|
||||||
@ -847,6 +849,34 @@ void GenericDescriptorMatcher::read( const FileNode& )
|
|||||||
void GenericDescriptorMatcher::write( FileStorage& ) const
|
void GenericDescriptorMatcher::write( FileStorage& ) const
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Factory function for GenericDescriptorMatch creating
|
||||||
|
*/
|
||||||
|
Ptr<GenericDescriptorMatcher> GenericDescriptorMatcher::create( const string& genericDescritptorMatcherType,
|
||||||
|
const string ¶msFilename )
|
||||||
|
{
|
||||||
|
Ptr<GenericDescriptorMatcher> descriptorMatcher;
|
||||||
|
if( ! genericDescritptorMatcherType.compare("ONEWAY") )
|
||||||
|
{
|
||||||
|
descriptorMatcher = new OneWayDescriptorMatcher();
|
||||||
|
}
|
||||||
|
else if( ! genericDescritptorMatcherType.compare("FERN") )
|
||||||
|
{
|
||||||
|
descriptorMatcher = new FernDescriptorMatcher();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !paramsFilename.empty() && !descriptorMatcher.empty() )
|
||||||
|
{
|
||||||
|
FileStorage fs = FileStorage( paramsFilename, FileStorage::READ );
|
||||||
|
if( fs.isOpened() )
|
||||||
|
{
|
||||||
|
descriptorMatcher->read( fs.root() );
|
||||||
|
fs.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return descriptorMatcher;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************************\
|
/****************************************************************************************\
|
||||||
* OneWayDescriptorMatcher *
|
* OneWayDescriptorMatcher *
|
||||||
\****************************************************************************************/
|
\****************************************************************************************/
|
||||||
@ -1238,32 +1268,4 @@ Ptr<GenericDescriptorMatcher> VectorDescriptorMatcher::clone( bool emptyTrainDat
|
|||||||
return new VectorDescriptorMatcher( extractor, matcher->clone(emptyTrainData) );
|
return new VectorDescriptorMatcher( extractor, matcher->clone(emptyTrainData) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Factory function for GenericDescriptorMatch creating
|
|
||||||
*/
|
|
||||||
Ptr<GenericDescriptorMatcher> createGenericDescriptorMatcher( const string& genericDescritptorMatcherType,
|
|
||||||
const string ¶msFilename )
|
|
||||||
{
|
|
||||||
Ptr<GenericDescriptorMatcher> descriptorMatcher;
|
|
||||||
if( ! genericDescritptorMatcherType.compare("ONEWAY") )
|
|
||||||
{
|
|
||||||
descriptorMatcher = new OneWayDescriptorMatcher();
|
|
||||||
}
|
|
||||||
else if( ! genericDescritptorMatcherType.compare("FERN") )
|
|
||||||
{
|
|
||||||
descriptorMatcher = new FernDescriptorMatcher();
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !paramsFilename.empty() && !descriptorMatcher.empty() )
|
|
||||||
{
|
|
||||||
FileStorage fs = FileStorage( paramsFilename, FileStorage::READ );
|
|
||||||
if( fs.isOpened() )
|
|
||||||
{
|
|
||||||
descriptorMatcher->read( fs.root() );
|
|
||||||
fs.release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return descriptorMatcher;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2552,8 +2552,8 @@ int main(int argc, char** argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create detector, descriptor, matcher.
|
// Create detector, descriptor, matcher.
|
||||||
Ptr<FeatureDetector> featureDetector = createFeatureDetector( ddmParams.detectorType );
|
Ptr<FeatureDetector> featureDetector = FeatureDetector::create( ddmParams.detectorType );
|
||||||
Ptr<DescriptorExtractor> descExtractor = createDescriptorExtractor( ddmParams.descriptorType );
|
Ptr<DescriptorExtractor> descExtractor = DescriptorExtractor::create( ddmParams.descriptorType );
|
||||||
Ptr<BOWImgDescriptorExtractor> bowExtractor;
|
Ptr<BOWImgDescriptorExtractor> bowExtractor;
|
||||||
if( featureDetector.empty() || descExtractor.empty() )
|
if( featureDetector.empty() || descExtractor.empty() )
|
||||||
{
|
{
|
||||||
@ -2561,7 +2561,7 @@ int main(int argc, char** argv)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
Ptr<DescriptorMatcher> descMatcher = createDescriptorMatcher( ddmParams.matcherType );
|
Ptr<DescriptorMatcher> descMatcher = DescriptorMatcher::create( ddmParams.matcherType );
|
||||||
if( featureDetector.empty() || descExtractor.empty() || descMatcher.empty() )
|
if( featureDetector.empty() || descExtractor.empty() || descMatcher.empty() )
|
||||||
{
|
{
|
||||||
cout << "descMatcher was not created" << endl;
|
cout << "descMatcher was not created" << endl;
|
||||||
|
@ -651,8 +651,8 @@ int main(int argc, char** argv)
|
|||||||
Size calibratedImageSize;
|
Size calibratedImageSize;
|
||||||
readCameraMatrix(intrinsicsFilename, cameraMatrix, distCoeffs, calibratedImageSize);
|
readCameraMatrix(intrinsicsFilename, cameraMatrix, distCoeffs, calibratedImageSize);
|
||||||
|
|
||||||
Ptr<FeatureDetector> detector = createFeatureDetector(detectorName);
|
Ptr<FeatureDetector> detector = FeatureDetector::create(detectorName);
|
||||||
Ptr<DescriptorExtractor> descriptorExtractor = createDescriptorExtractor(descriptorExtractorName);
|
Ptr<DescriptorExtractor> descriptorExtractor = DescriptorExtractor::create(descriptorExtractorName);
|
||||||
|
|
||||||
string modelIndexFilename = format("%s_segm/frame_index.yml", modelName);
|
string modelIndexFilename = format("%s_segm/frame_index.yml", modelName);
|
||||||
if(!readModelViews( modelIndexFilename, modelBox, imageList, roiList, poseList))
|
if(!readModelViews( modelIndexFilename, modelBox, imageList, roiList, poseList))
|
||||||
|
@ -223,9 +223,9 @@ int main(int argc, char** argv)
|
|||||||
ransacReprojThreshold = atof(argv[7]);
|
ransacReprojThreshold = atof(argv[7]);
|
||||||
|
|
||||||
cout << "< Creating detector, descriptor extractor and descriptor matcher ..." << endl;
|
cout << "< Creating detector, descriptor extractor and descriptor matcher ..." << endl;
|
||||||
Ptr<FeatureDetector> detector = createFeatureDetector( argv[1] );
|
Ptr<FeatureDetector> detector = FeatureDetector::create( argv[1] );
|
||||||
Ptr<DescriptorExtractor> descriptorExtractor = createDescriptorExtractor( argv[2] );
|
Ptr<DescriptorExtractor> descriptorExtractor = DescriptorExtractor::create( argv[2] );
|
||||||
Ptr<DescriptorMatcher> descriptorMatcher = createDescriptorMatcher( argv[3] );
|
Ptr<DescriptorMatcher> descriptorMatcher = DescriptorMatcher::create( argv[3] );
|
||||||
int mactherFilterType = getMatcherFilterType( argv[4] );
|
int mactherFilterType = getMatcherFilterType( argv[4] );
|
||||||
bool eval = !isWarpPerspective ? false : (atoi(argv[6]) == 0 ? false : true);
|
bool eval = !isWarpPerspective ? false : (atoi(argv[6]) == 0 ? false : true);
|
||||||
cout << ">" << endl;
|
cout << ">" << endl;
|
||||||
|
@ -29,7 +29,7 @@ int main(int argc, char** argv)
|
|||||||
std::string alg_name = std::string(argv[3]);
|
std::string alg_name = std::string(argv[3]);
|
||||||
std::string params_filename = std::string(argv[4]);
|
std::string params_filename = std::string(argv[4]);
|
||||||
|
|
||||||
Ptr<GenericDescriptorMatcher> descriptorMatcher = createGenericDescriptorMatcher(alg_name, params_filename);
|
Ptr<GenericDescriptorMatcher> descriptorMatcher = GenericDescriptorMatcher::create(alg_name, params_filename);
|
||||||
if( descriptorMatcher == 0 )
|
if( descriptorMatcher == 0 )
|
||||||
{
|
{
|
||||||
printf ("Cannot create descriptor\n");
|
printf ("Cannot create descriptor\n");
|
||||||
|
@ -62,9 +62,9 @@ bool createDetectorDescriptorMatcher( const string& detectorType, const string&
|
|||||||
Ptr<DescriptorMatcher>& descriptorMatcher )
|
Ptr<DescriptorMatcher>& descriptorMatcher )
|
||||||
{
|
{
|
||||||
cout << "< Creating feature detector, descriptor extractor and descriptor matcher ..." << endl;
|
cout << "< Creating feature detector, descriptor extractor and descriptor matcher ..." << endl;
|
||||||
featureDetector = createFeatureDetector( detectorType );
|
featureDetector = FeatureDetector::create( detectorType );
|
||||||
descriptorExtractor = createDescriptorExtractor( descriptorType );
|
descriptorExtractor = DescriptorExtractor::create( descriptorType );
|
||||||
descriptorMatcher = createDescriptorMatcher( matcherType );
|
descriptorMatcher = DescriptorMatcher::create( matcherType );
|
||||||
cout << ">" << endl;
|
cout << ">" << endl;
|
||||||
|
|
||||||
bool isCreated = !( featureDetector.empty() || descriptorExtractor.empty() || descriptorMatcher.empty() );
|
bool isCreated = !( featureDetector.empty() || descriptorExtractor.empty() || descriptorMatcher.empty() );
|
||||||
|
@ -686,8 +686,8 @@ inline void readKeypoints( FileStorage& fs, vector<KeyPoint>& keypoints, int img
|
|||||||
|
|
||||||
void DetectorQualityTest::readAlgorithm ()
|
void DetectorQualityTest::readAlgorithm ()
|
||||||
{
|
{
|
||||||
defaultDetector = createFeatureDetector( algName );
|
defaultDetector = FeatureDetector::create( algName );
|
||||||
specificDetector = createFeatureDetector( algName );
|
specificDetector = FeatureDetector::create( algName );
|
||||||
if( defaultDetector == 0 )
|
if( defaultDetector == 0 )
|
||||||
{
|
{
|
||||||
ts->printf(CvTS::LOG, "Algorithm can not be read\n");
|
ts->printf(CvTS::LOG, "Algorithm can not be read\n");
|
||||||
@ -960,13 +960,13 @@ void DescriptorQualityTest::writePlotData( int di ) const
|
|||||||
|
|
||||||
void DescriptorQualityTest::readAlgorithm( )
|
void DescriptorQualityTest::readAlgorithm( )
|
||||||
{
|
{
|
||||||
defaultDescMatcher = createGenericDescriptorMatcher( algName );
|
defaultDescMatcher = GenericDescriptorMatcher::create( algName );
|
||||||
specificDescMatcher = createGenericDescriptorMatcher( algName );
|
specificDescMatcher = GenericDescriptorMatcher::create( algName );
|
||||||
|
|
||||||
if( defaultDescMatcher == 0 )
|
if( defaultDescMatcher == 0 )
|
||||||
{
|
{
|
||||||
Ptr<DescriptorExtractor> extractor = createDescriptorExtractor( algName );
|
Ptr<DescriptorExtractor> extractor = DescriptorExtractor::create( algName );
|
||||||
Ptr<DescriptorMatcher> matcher = createDescriptorMatcher( matcherName );
|
Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create( matcherName );
|
||||||
defaultDescMatcher = new VectorDescriptorMatch( extractor, matcher );
|
defaultDescMatcher = new VectorDescriptorMatch( extractor, matcher );
|
||||||
specificDescMatcher = new VectorDescriptorMatch( extractor, matcher );
|
specificDescMatcher = new VectorDescriptorMatch( extractor, matcher );
|
||||||
|
|
||||||
|
@ -73,6 +73,7 @@ protected:
|
|||||||
|
|
||||||
void CV_FeatureDetectorTest::emptyDataTest()
|
void CV_FeatureDetectorTest::emptyDataTest()
|
||||||
{
|
{
|
||||||
|
// One image.
|
||||||
Mat image;
|
Mat image;
|
||||||
vector<KeyPoint> keypoints;
|
vector<KeyPoint> keypoints;
|
||||||
try
|
try
|
||||||
@ -81,14 +82,28 @@ void CV_FeatureDetectorTest::emptyDataTest()
|
|||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
ts->printf( CvTS::LOG, "emptyDataTest: Detect() on empty image must not generate exception\n" );
|
ts->printf( CvTS::LOG, "detect() on empty image must not generate exception (1)\n" );
|
||||||
ts->set_failed_test_info( CvTS::FAIL_INVALID_OUTPUT );
|
ts->set_failed_test_info( CvTS::FAIL_INVALID_OUTPUT );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !keypoints.empty() )
|
if( !keypoints.empty() )
|
||||||
{
|
{
|
||||||
ts->printf( CvTS::LOG, "emptyDataTest: Detect() on empty image must return empty keypoints vector\n" );
|
ts->printf( CvTS::LOG, "detect() on empty image must return empty keypoints vector (1)\n" );
|
||||||
|
ts->set_failed_test_info( CvTS::FAIL_INVALID_OUTPUT );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Several images.
|
||||||
|
vector<Mat> images;
|
||||||
|
vector<vector<KeyPoint> > keypointCollection;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
fdetector->detect( images, keypointCollection );
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
ts->printf( CvTS::LOG, "detect() on empty image vector must not generate exception (2)\n" );
|
||||||
ts->set_failed_test_info( CvTS::FAIL_INVALID_OUTPUT );
|
ts->set_failed_test_info( CvTS::FAIL_INVALID_OUTPUT );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -120,7 +135,7 @@ void CV_FeatureDetectorTest::compareKeypointSets( const vector<KeyPoint>& validK
|
|||||||
{
|
{
|
||||||
ts->printf( CvTS::LOG, "Bad keypoints count ratio (validCount = %d, calcCount = %d)!\n",
|
ts->printf( CvTS::LOG, "Bad keypoints count ratio (validCount = %d, calcCount = %d)!\n",
|
||||||
validKeypoints.size(), calcKeypoints.size() );
|
validKeypoints.size(), calcKeypoints.size() );
|
||||||
ts->set_failed_test_info( CvTS::FAIL_BAD_ACCURACY );
|
ts->set_failed_test_info( CvTS::FAIL_INVALID_OUTPUT );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,7 +161,7 @@ void CV_FeatureDetectorTest::compareKeypointSets( const vector<KeyPoint>& validK
|
|||||||
if( !isSimilarKeypoints( validKeypoints[v], calcKeypoints[nearestIdx] ) )
|
if( !isSimilarKeypoints( validKeypoints[v], calcKeypoints[nearestIdx] ) )
|
||||||
badPointCount++;
|
badPointCount++;
|
||||||
}
|
}
|
||||||
ts->printf( CvTS::LOG, "regressionTest: badPointCount = %d; validPointCount = %d; calcPointCount = %d\n",
|
ts->printf( CvTS::LOG, "badPointCount = %d; validPointCount = %d; calcPointCount = %d\n",
|
||||||
badPointCount, validKeypoints.size(), calcKeypoints.size() );
|
badPointCount, validKeypoints.size(), calcKeypoints.size() );
|
||||||
if( badPointCount > 0.9 * commonPointCount )
|
if( badPointCount > 0.9 * commonPointCount )
|
||||||
{
|
{
|
||||||
@ -164,7 +179,7 @@ void CV_FeatureDetectorTest::regressionTest()
|
|||||||
string resFilename = string(ts->get_data_path()) + DETECTOR_DIR + "/" + string(name) + ".xml.gz";
|
string resFilename = string(ts->get_data_path()) + DETECTOR_DIR + "/" + string(name) + ".xml.gz";
|
||||||
|
|
||||||
// Read the test image.
|
// Read the test image.
|
||||||
Mat image = imread( imgFilename, 0 );
|
Mat image = imread( imgFilename );
|
||||||
if( image.empty() )
|
if( image.empty() )
|
||||||
{
|
{
|
||||||
ts->printf( CvTS::LOG, "image %s can not be read \n", imgFilename.c_str() );
|
ts->printf( CvTS::LOG, "image %s can not be read \n", imgFilename.c_str() );
|
||||||
@ -241,8 +256,9 @@ static void writeMatInBin( const Mat& mat, const string& filename )
|
|||||||
fwrite( (void*)&mat.rows, sizeof(int), 1, f );
|
fwrite( (void*)&mat.rows, sizeof(int), 1, f );
|
||||||
fwrite( (void*)&mat.cols, sizeof(int), 1, f );
|
fwrite( (void*)&mat.cols, sizeof(int), 1, f );
|
||||||
fwrite( (void*)&type, sizeof(int), 1, f );
|
fwrite( (void*)&type, sizeof(int), 1, f );
|
||||||
fwrite( (void*)&mat.step, sizeof(int), 1, f );
|
int dataSize = mat.step * mat.rows * mat.channels();
|
||||||
fwrite( (void*)mat.data, 1, mat.step*mat.rows, f );
|
fwrite( (void*)&dataSize, sizeof(int), 1, f );
|
||||||
|
fwrite( (void*)mat.data, 1, dataSize, f );
|
||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -252,14 +268,14 @@ static Mat readMatFromBin( const string& filename )
|
|||||||
FILE* f = fopen( filename.c_str(), "rb" );
|
FILE* f = fopen( filename.c_str(), "rb" );
|
||||||
if( f )
|
if( f )
|
||||||
{
|
{
|
||||||
int rows, cols, type, step;
|
int rows, cols, type, dataSize;
|
||||||
fread( (void*)&rows, sizeof(int), 1, f );
|
fread( (void*)&rows, sizeof(int), 1, f );
|
||||||
fread( (void*)&cols, sizeof(int), 1, f );
|
fread( (void*)&cols, sizeof(int), 1, f );
|
||||||
fread( (void*)&type, sizeof(int), 1, f );
|
fread( (void*)&type, sizeof(int), 1, f );
|
||||||
fread( (void*)&step, sizeof(int), 1, f );
|
fread( (void*)&dataSize, sizeof(int), 1, f );
|
||||||
|
|
||||||
uchar* data = (uchar*)cvAlloc(step*rows);
|
uchar* data = (uchar*)cvAlloc(dataSize);
|
||||||
fread( (void*)data, 1, step*rows, f );
|
fread( (void*)data, 1, dataSize, f );
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
return Mat( rows, cols, type, data );
|
return Mat( rows, cols, type, data );
|
||||||
@ -300,7 +316,7 @@ protected:
|
|||||||
if( dist > maxDistDif)
|
if( dist > maxDistDif)
|
||||||
{
|
{
|
||||||
stringstream ss;
|
stringstream ss;
|
||||||
ss << "Discance between valid and computed " << y << "-descriptors > " << maxDistDif << endl;
|
ss << "Discance between valid and computed " << y << "-descriptors " << dist << ">" << maxDistDif << endl;
|
||||||
ts->printf(CvTS::LOG, ss.str().c_str() );
|
ts->printf(CvTS::LOG, ss.str().c_str() );
|
||||||
ts->set_failed_test_info( CvTS::FAIL_BAD_ACCURACY );
|
ts->set_failed_test_info( CvTS::FAIL_BAD_ACCURACY );
|
||||||
return;
|
return;
|
||||||
@ -309,13 +325,15 @@ protected:
|
|||||||
maxDist = dist;
|
maxDist = dist;
|
||||||
}
|
}
|
||||||
stringstream ss;
|
stringstream ss;
|
||||||
ss << "regressionTest: Max discance between valid and computed descriptors " << maxDist << endl;
|
ss << "Max distance between valid and computed descriptors " << maxDist << endl;
|
||||||
ts->printf(CvTS::LOG, ss.str().c_str() );
|
ts->printf(CvTS::LOG, ss.str().c_str() );
|
||||||
}
|
}
|
||||||
|
|
||||||
void emptyDataTest()
|
void emptyDataTest()
|
||||||
{
|
{
|
||||||
assert( !dextractor.empty() );
|
assert( !dextractor.empty() );
|
||||||
|
|
||||||
|
// One image.
|
||||||
Mat image;
|
Mat image;
|
||||||
vector<KeyPoint> keypoints;
|
vector<KeyPoint> keypoints;
|
||||||
Mat descriptors;
|
Mat descriptors;
|
||||||
@ -326,7 +344,7 @@ protected:
|
|||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
ts->printf( CvTS::LOG, "emptyDataTest: compute() on empty image and empty keypoints must not generate exception\n");
|
ts->printf( CvTS::LOG, "compute() on empty image and empty keypoints must not generate exception (1)\n");
|
||||||
ts->set_failed_test_info( CvTS::FAIL_INVALID_TEST_DATA );
|
ts->set_failed_test_info( CvTS::FAIL_INVALID_TEST_DATA );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -337,7 +355,21 @@ protected:
|
|||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
ts->printf( CvTS::LOG, "emptyDataTest: compute() on nonempty image and empty keypoints must not generate exception\n");
|
ts->printf( CvTS::LOG, "compute() on nonempty image and empty keypoints must not generate exception (1)\n");
|
||||||
|
ts->set_failed_test_info( CvTS::FAIL_INVALID_TEST_DATA );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Several images.
|
||||||
|
vector<Mat> images;
|
||||||
|
vector<vector<KeyPoint> > keypointsCollection;
|
||||||
|
vector<Mat> descriptorsCollection;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
dextractor->compute( images, keypointsCollection, descriptorsCollection );
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
ts->printf( CvTS::LOG, "compute() on empty images and empty keypoints collection must not generate exception (2)\n");
|
||||||
ts->set_failed_test_info( CvTS::FAIL_INVALID_TEST_DATA );
|
ts->set_failed_test_info( CvTS::FAIL_INVALID_TEST_DATA );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -348,7 +380,8 @@ protected:
|
|||||||
|
|
||||||
// Read the test image.
|
// Read the test image.
|
||||||
string imgFilename = string(ts->get_data_path()) + FEATURES2D_DIR + "/" + IMAGE_FILENAME;
|
string imgFilename = string(ts->get_data_path()) + FEATURES2D_DIR + "/" + IMAGE_FILENAME;
|
||||||
Mat img = imread( imgFilename, 0 );
|
|
||||||
|
Mat img = imread( imgFilename );
|
||||||
if( img.empty() )
|
if( img.empty() )
|
||||||
{
|
{
|
||||||
ts->printf( CvTS::LOG, "image %s can not be read\n", imgFilename.c_str() );
|
ts->printf( CvTS::LOG, "image %s can not be read\n", imgFilename.c_str() );
|
||||||
@ -366,7 +399,7 @@ protected:
|
|||||||
double t = (double)getTickCount();
|
double t = (double)getTickCount();
|
||||||
dextractor->compute( img, keypoints, calcDescriptors );
|
dextractor->compute( img, keypoints, calcDescriptors );
|
||||||
t = getTickCount() - t;
|
t = getTickCount() - t;
|
||||||
ts->printf(CvTS::LOG, "\nregressionTest: Average time of computiting one descriptor = %g ms (previous time = %g ms)\n", t/((double)cvGetTickFrequency()*1000.)/calcDescriptors.rows, prevTime );
|
ts->printf(CvTS::LOG, "\nAverage time of computiting one descriptor = %g ms (previous time = %g ms)\n", t/((double)cvGetTickFrequency()*1000.)/calcDescriptors.rows, prevTime );
|
||||||
|
|
||||||
if( calcDescriptors.rows != (int)keypoints.size() )
|
if( calcDescriptors.rows != (int)keypoints.size() )
|
||||||
{
|
{
|
||||||
@ -486,13 +519,20 @@ protected:
|
|||||||
virtual void run( int );
|
virtual void run( int );
|
||||||
void generateData( Mat& query, Mat& train );
|
void generateData( Mat& query, Mat& train );
|
||||||
|
|
||||||
int testMatch( const Mat& query, const Mat& train );
|
void emptyDataTest();
|
||||||
int testKnnMatch( const Mat& query, const Mat& train );
|
void matchTest( const Mat& query, const Mat& train );
|
||||||
int testRadiusMatch( const Mat& query, const Mat& train );
|
void knnMatchTest( const Mat& query, const Mat& train );
|
||||||
|
void radiusMatchTest( const Mat& query, const Mat& train );
|
||||||
|
|
||||||
Ptr<DescriptorMatcher> dmatcher;
|
Ptr<DescriptorMatcher> dmatcher;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void CV_DescriptorMatcherTest::emptyDataTest()
|
||||||
|
{
|
||||||
|
assert( !dmatcher.empty() );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void CV_DescriptorMatcherTest::generateData( Mat& query, Mat& train )
|
void CV_DescriptorMatcherTest::generateData( Mat& query, Mat& train )
|
||||||
{
|
{
|
||||||
RNG& rng = theRNG();
|
RNG& rng = theRNG();
|
||||||
@ -525,21 +565,19 @@ void CV_DescriptorMatcherTest::generateData( Mat& query, Mat& train )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int CV_DescriptorMatcherTest::testMatch( const Mat& query, const Mat& train )
|
void CV_DescriptorMatcherTest::matchTest( const Mat& query, const Mat& train )
|
||||||
{
|
{
|
||||||
dmatcher->clear();
|
dmatcher->clear();
|
||||||
|
|
||||||
// test const version of match()
|
// test const version of match()
|
||||||
int res = CvTS::OK;
|
|
||||||
{
|
{
|
||||||
vector<DMatch> matches;
|
vector<DMatch> matches;
|
||||||
dmatcher->match( query, train, matches );
|
dmatcher->match( query, train, matches );
|
||||||
|
|
||||||
int curRes = CvTS::OK;
|
|
||||||
if( (int)matches.size() != queryDescCount )
|
if( (int)matches.size() != queryDescCount )
|
||||||
{
|
{
|
||||||
curRes = CvTS::FAIL_INVALID_OUTPUT;
|
|
||||||
ts->printf(CvTS::LOG, "Incorrect matches count while test match() function (1)\n");
|
ts->printf(CvTS::LOG, "Incorrect matches count while test match() function (1)\n");
|
||||||
|
ts->set_failed_test_info( CvTS::FAIL_INVALID_OUTPUT );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -552,12 +590,11 @@ int CV_DescriptorMatcherTest::testMatch( const Mat& query, const Mat& train )
|
|||||||
}
|
}
|
||||||
if( (float)badCount > (float)queryDescCount*badPart )
|
if( (float)badCount > (float)queryDescCount*badPart )
|
||||||
{
|
{
|
||||||
curRes = CvTS::FAIL_INVALID_OUTPUT;
|
|
||||||
ts->printf( CvTS::LOG, "%f - too large bad matches part while test match() function (1)\n",
|
ts->printf( CvTS::LOG, "%f - too large bad matches part while test match() function (1)\n",
|
||||||
(float)badCount/(float)queryDescCount );
|
(float)badCount/(float)queryDescCount );
|
||||||
|
ts->set_failed_test_info( CvTS::FAIL_INVALID_OUTPUT );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res = curRes != CvTS::OK ? curRes : res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// test version of match() with add()
|
// test version of match() with add()
|
||||||
@ -577,11 +614,10 @@ int CV_DescriptorMatcherTest::testMatch( const Mat& query, const Mat& train )
|
|||||||
|
|
||||||
dmatcher->match( query, matches, masks );
|
dmatcher->match( query, matches, masks );
|
||||||
|
|
||||||
int curRes = CvTS::OK;
|
|
||||||
if( (int)matches.size() != queryDescCount )
|
if( (int)matches.size() != queryDescCount )
|
||||||
{
|
{
|
||||||
curRes = CvTS::FAIL_INVALID_OUTPUT;
|
|
||||||
ts->printf(CvTS::LOG, "Incorrect matches count while test match() function (2)\n");
|
ts->printf(CvTS::LOG, "Incorrect matches count while test match() function (2)\n");
|
||||||
|
ts->set_failed_test_info( CvTS::FAIL_INVALID_OUTPUT );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -607,30 +643,27 @@ int CV_DescriptorMatcherTest::testMatch( const Mat& query, const Mat& train )
|
|||||||
{
|
{
|
||||||
ts->printf( CvTS::LOG, "%f - too large bad matches part while test match() function (2)\n",
|
ts->printf( CvTS::LOG, "%f - too large bad matches part while test match() function (2)\n",
|
||||||
(float)badCount/(float)queryDescCount );
|
(float)badCount/(float)queryDescCount );
|
||||||
|
ts->set_failed_test_info( CvTS::FAIL_BAD_ACCURACY );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res = curRes != CvTS::OK ? curRes : res;
|
|
||||||
}
|
}
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int CV_DescriptorMatcherTest::testKnnMatch( const Mat& query, const Mat& train )
|
void CV_DescriptorMatcherTest::knnMatchTest( const Mat& query, const Mat& train )
|
||||||
{
|
{
|
||||||
dmatcher->clear();
|
dmatcher->clear();
|
||||||
|
|
||||||
// test const version of knnMatch()
|
// test const version of knnMatch()
|
||||||
int res = CvTS::OK;
|
|
||||||
{
|
{
|
||||||
const int knn = 3;
|
const int knn = 3;
|
||||||
|
|
||||||
vector<vector<DMatch> > matches;
|
vector<vector<DMatch> > matches;
|
||||||
dmatcher->knnMatch( query, train, matches, knn );
|
dmatcher->knnMatch( query, train, matches, knn );
|
||||||
|
|
||||||
int curRes = CvTS::OK;
|
|
||||||
if( (int)matches.size() != queryDescCount )
|
if( (int)matches.size() != queryDescCount )
|
||||||
{
|
{
|
||||||
curRes = CvTS::FAIL_INVALID_OUTPUT;
|
|
||||||
ts->printf(CvTS::LOG, "Incorrect matches count while test knnMatch() function (1)\n");
|
ts->printf(CvTS::LOG, "Incorrect matches count while test knnMatch() function (1)\n");
|
||||||
|
ts->set_failed_test_info( CvTS::FAIL_INVALID_OUTPUT );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -653,12 +686,11 @@ int CV_DescriptorMatcherTest::testKnnMatch( const Mat& query, const Mat& train )
|
|||||||
}
|
}
|
||||||
if( (float)badCount > (float)queryDescCount*badPart )
|
if( (float)badCount > (float)queryDescCount*badPart )
|
||||||
{
|
{
|
||||||
curRes = CvTS::FAIL_INVALID_OUTPUT;
|
|
||||||
ts->printf( CvTS::LOG, "%f - too large bad matches part while test knnMatch() function (1)\n",
|
ts->printf( CvTS::LOG, "%f - too large bad matches part while test knnMatch() function (1)\n",
|
||||||
(float)badCount/(float)queryDescCount );
|
(float)badCount/(float)queryDescCount );
|
||||||
|
ts->set_failed_test_info( CvTS::FAIL_INVALID_OUTPUT );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res = curRes != CvTS::OK ? curRes : res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// test version of knnMatch() with add()
|
// test version of knnMatch() with add()
|
||||||
@ -679,11 +711,10 @@ int CV_DescriptorMatcherTest::testKnnMatch( const Mat& query, const Mat& train )
|
|||||||
|
|
||||||
dmatcher->knnMatch( query, matches, knn, masks );
|
dmatcher->knnMatch( query, matches, knn, masks );
|
||||||
|
|
||||||
int curRes = CvTS::OK;
|
|
||||||
if( (int)matches.size() != queryDescCount )
|
if( (int)matches.size() != queryDescCount )
|
||||||
{
|
{
|
||||||
curRes = CvTS::FAIL_INVALID_OUTPUT;
|
|
||||||
ts->printf(CvTS::LOG, "Incorrect matches count while test knnMatch() function (2)\n");
|
ts->printf(CvTS::LOG, "Incorrect matches count while test knnMatch() function (2)\n");
|
||||||
|
ts->set_failed_test_info( CvTS::FAIL_INVALID_OUTPUT );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -721,28 +752,25 @@ int CV_DescriptorMatcherTest::testKnnMatch( const Mat& query, const Mat& train )
|
|||||||
{
|
{
|
||||||
ts->printf( CvTS::LOG, "%f - too large bad matches part while test knnMatch() function (2)\n",
|
ts->printf( CvTS::LOG, "%f - too large bad matches part while test knnMatch() function (2)\n",
|
||||||
(float)badCount/(float)queryDescCount );
|
(float)badCount/(float)queryDescCount );
|
||||||
|
ts->set_failed_test_info( CvTS::FAIL_BAD_ACCURACY );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res = curRes != CvTS::OK ? curRes : res;
|
|
||||||
}
|
}
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int CV_DescriptorMatcherTest::testRadiusMatch( const Mat& query, const Mat& train )
|
void CV_DescriptorMatcherTest::radiusMatchTest( const Mat& query, const Mat& train )
|
||||||
{
|
{
|
||||||
dmatcher->clear();
|
dmatcher->clear();
|
||||||
// test const version of match()
|
// test const version of match()
|
||||||
int res = CvTS::OK;
|
|
||||||
{
|
{
|
||||||
const float radius = 1.f/countFactor;
|
const float radius = 1.f/countFactor;
|
||||||
vector<vector<DMatch> > matches;
|
vector<vector<DMatch> > matches;
|
||||||
dmatcher->radiusMatch( query, train, matches, radius );
|
dmatcher->radiusMatch( query, train, matches, radius );
|
||||||
|
|
||||||
int curRes = CvTS::OK;
|
|
||||||
if( (int)matches.size() != queryDescCount )
|
if( (int)matches.size() != queryDescCount )
|
||||||
{
|
{
|
||||||
curRes = CvTS::FAIL_INVALID_OUTPUT;
|
|
||||||
ts->printf(CvTS::LOG, "Incorrect matches count while test radiusMatch() function (1)\n");
|
ts->printf(CvTS::LOG, "Incorrect matches count while test radiusMatch() function (1)\n");
|
||||||
|
ts->set_failed_test_info( CvTS::FAIL_INVALID_OUTPUT );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -760,12 +788,11 @@ int CV_DescriptorMatcherTest::testRadiusMatch( const Mat& query, const Mat& trai
|
|||||||
}
|
}
|
||||||
if( (float)badCount > (float)queryDescCount*badPart )
|
if( (float)badCount > (float)queryDescCount*badPart )
|
||||||
{
|
{
|
||||||
curRes = CvTS::FAIL_INVALID_OUTPUT;
|
|
||||||
ts->printf( CvTS::LOG, "%f - too large bad matches part while test radiusMatch() function (1)\n",
|
ts->printf( CvTS::LOG, "%f - too large bad matches part while test radiusMatch() function (1)\n",
|
||||||
(float)badCount/(float)queryDescCount );
|
(float)badCount/(float)queryDescCount );
|
||||||
|
ts->set_failed_test_info( CvTS::FAIL_INVALID_OUTPUT );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res = curRes != CvTS::OK ? curRes : res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// test version of match() with add()
|
// test version of match() with add()
|
||||||
@ -790,10 +817,9 @@ int CV_DescriptorMatcherTest::testRadiusMatch( const Mat& query, const Mat& trai
|
|||||||
int curRes = CvTS::OK;
|
int curRes = CvTS::OK;
|
||||||
if( (int)matches.size() != queryDescCount )
|
if( (int)matches.size() != queryDescCount )
|
||||||
{
|
{
|
||||||
curRes = CvTS::FAIL_INVALID_OUTPUT;
|
|
||||||
ts->printf(CvTS::LOG, "Incorrect matches count while test radiusMatch() function (1)\n");
|
ts->printf(CvTS::LOG, "Incorrect matches count while test radiusMatch() function (1)\n");
|
||||||
|
ts->set_failed_test_info( CvTS::FAIL_INVALID_OUTPUT );
|
||||||
}
|
}
|
||||||
res = curRes != CvTS::OK ? curRes : res;
|
|
||||||
|
|
||||||
int badCount = 0;
|
int badCount = 0;
|
||||||
int shift = dmatcher->isMaskSupported() ? 1 : 0;
|
int shift = dmatcher->isMaskSupported() ? 1 : 0;
|
||||||
@ -831,10 +857,9 @@ int CV_DescriptorMatcherTest::testRadiusMatch( const Mat& query, const Mat& trai
|
|||||||
curRes = CvTS::FAIL_INVALID_OUTPUT;
|
curRes = CvTS::FAIL_INVALID_OUTPUT;
|
||||||
ts->printf( CvTS::LOG, "%f - too large bad matches part while test radiusMatch() function (2)\n",
|
ts->printf( CvTS::LOG, "%f - too large bad matches part while test radiusMatch() function (2)\n",
|
||||||
(float)badCount/(float)queryDescCount );
|
(float)badCount/(float)queryDescCount );
|
||||||
|
ts->set_failed_test_info( CvTS::FAIL_BAD_ACCURACY );
|
||||||
}
|
}
|
||||||
res = curRes != CvTS::OK ? curRes : res;
|
|
||||||
}
|
}
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CV_DescriptorMatcherTest::run( int )
|
void CV_DescriptorMatcherTest::run( int )
|
||||||
@ -842,18 +867,11 @@ void CV_DescriptorMatcherTest::run( int )
|
|||||||
Mat query, train;
|
Mat query, train;
|
||||||
generateData( query, train );
|
generateData( query, train );
|
||||||
|
|
||||||
int res = CvTS::OK, curRes;
|
matchTest( query, train );
|
||||||
|
|
||||||
curRes = testMatch( query, train );
|
knnMatchTest( query, train );
|
||||||
res = curRes != CvTS::OK ? curRes : res;
|
|
||||||
|
|
||||||
curRes = testKnnMatch( query, train );
|
radiusMatchTest( query, train );
|
||||||
res = curRes != CvTS::OK ? curRes : res;
|
|
||||||
|
|
||||||
curRes = testRadiusMatch( query, train );
|
|
||||||
res = curRes != CvTS::OK ? curRes : res;
|
|
||||||
|
|
||||||
ts->set_failed_test_info( res );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************************\
|
/****************************************************************************************\
|
||||||
@ -862,31 +880,33 @@ void CV_DescriptorMatcherTest::run( int )
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Detectors
|
* Detectors
|
||||||
* "detector-fast, detector-gftt, detector-harris, detector-mser, detector-sift, detector-star, detector-surf"
|
* "detector-fast, detector-gftt, detector-harris, detector-mser, detector-sift, detector-star, detector-surf, detector-grid-fast, detector-pyramid-fast"
|
||||||
*/
|
*/
|
||||||
CV_FeatureDetectorTest fastTest( "detector-fast", createFeatureDetector("FAST") );
|
CV_FeatureDetectorTest fastTest( "detector-fast", FeatureDetector::create("FAST") );
|
||||||
CV_FeatureDetectorTest gfttTest( "detector-gftt", createFeatureDetector("GFTT") );
|
CV_FeatureDetectorTest gfttTest( "detector-gftt", FeatureDetector::create("GFTT") );
|
||||||
CV_FeatureDetectorTest harrisTest( "detector-harris", createFeatureDetector("HARRIS") );
|
CV_FeatureDetectorTest harrisTest( "detector-harris", FeatureDetector::create("HARRIS") );
|
||||||
CV_FeatureDetectorTest mserTest( "detector-mser", createFeatureDetector("MSER") );
|
CV_FeatureDetectorTest mserTest( "detector-mser", FeatureDetector::create("MSER") );
|
||||||
CV_FeatureDetectorTest siftTest( "detector-sift", createFeatureDetector("SIFT") );
|
CV_FeatureDetectorTest siftTest( "detector-sift", FeatureDetector::create("SIFT") );
|
||||||
CV_FeatureDetectorTest starTest( "detector-star", createFeatureDetector("STAR") );
|
CV_FeatureDetectorTest starTest( "detector-star", FeatureDetector::create("STAR") );
|
||||||
CV_FeatureDetectorTest surfTest( "detector-surf", createFeatureDetector("SURF") );
|
CV_FeatureDetectorTest surfTest( "detector-surf", FeatureDetector::create("SURF") );
|
||||||
|
CV_FeatureDetectorTest gridFastfTest( "detector-grid-fast", FeatureDetector::create("GridFAST") );
|
||||||
|
CV_FeatureDetectorTest pyramidFastTest( "detector-pyramid-fast", FeatureDetector::create("PyramidFAST") );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Descriptors
|
* Descriptors
|
||||||
* "descriptor-sift, descriptor-surf, descriptor-calonder-uchar, descriptor-calonder-float, descriptor-brief"
|
* "descriptor-sift, descriptor-surf, descriptor-calonder-uchar, descriptor-calonder-float, descriptor-brief, descriptor-opponent-sift, descriptor-opponent-surf"
|
||||||
*/
|
*/
|
||||||
CV_DescriptorExtractorTest<L2<float> > siftDescriptorTest( "descriptor-sift", 0.03f,
|
CV_DescriptorExtractorTest<L2<float> > siftDescriptorTest( "descriptor-sift", 0.03f,
|
||||||
createDescriptorExtractor("SIFT"), 8.06652f );
|
DescriptorExtractor::create("SIFT"), 8.06652f );
|
||||||
CV_DescriptorExtractorTest<L2<float> > surfDescriptorTest( "descriptor-surf", 0.035f,
|
CV_DescriptorExtractorTest<L2<float> > surfDescriptorTest( "descriptor-surf", 0.035f,
|
||||||
createDescriptorExtractor("SURF"), 0.147372f );
|
DescriptorExtractor::create("SURF"), 0.147372f );
|
||||||
CV_DescriptorExtractorTest<Hamming> briefDescriptorTest( "descriptor-brief", 1,
|
CV_DescriptorExtractorTest<Hamming> briefDescriptorTest( "descriptor-brief", 1,
|
||||||
createDescriptorExtractor("BRIEF"), 0.00527548 );
|
DescriptorExtractor::create("BRIEF"), 0.00527548 );
|
||||||
|
|
||||||
//CV_DescriptorExtractorTest oppSiftDescriptorTest( "descriptor-opponent-sift", 0.008f,
|
CV_DescriptorExtractorTest<L2<float> > oppSiftDescriptorTest( "descriptor-opponent-sift", 0.008f,
|
||||||
// createDescriptorExtractor("OpponentSIFT"), 8.06652f );
|
DescriptorExtractor::create("OpponentSIFT"), 8.06652f );
|
||||||
//CV_DescriptorExtractorTest oppurfDescriptorTest( "descriptor-opponent-surf", 0.02f,
|
CV_DescriptorExtractorTest<L2<float> > oppurfDescriptorTest( "descriptor-opponent-surf", 0.02f,
|
||||||
// createDescriptorExtractor("OpponentSURF"), 0.147372f );
|
DescriptorExtractor::create("OpponentSURF"), 0.147372f );
|
||||||
|
|
||||||
#if CV_SSE2
|
#if CV_SSE2
|
||||||
CV_CalonderDescriptorExtractorTest<uchar, L2<uchar> > ucharCalonderTest( "descriptor-calonder-uchar",
|
CV_CalonderDescriptorExtractorTest<uchar, L2<uchar> > ucharCalonderTest( "descriptor-calonder-uchar",
|
||||||
@ -899,8 +919,10 @@ CV_CalonderDescriptorExtractorTest<float, L2<float> > floatCalonderTest( "descri
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Matchers
|
* Matchers
|
||||||
|
* "descriptor-matcher-brute-force, descriptor-matcher-flann-based"
|
||||||
*/
|
*/
|
||||||
CV_DescriptorMatcherTest bruteForceMatcherTest( "descriptor-matcher-brute-force",
|
CV_DescriptorMatcherTest bruteForceMatcherTest( "descriptor-matcher-brute-force",
|
||||||
new BruteForceMatcher<L2<float> >, 0.01f );
|
new BruteForceMatcher<L2<float> >, 0.01f );
|
||||||
CV_DescriptorMatcherTest flannBasedMatcherTest( "descriptor-matcher-flann-based",
|
CV_DescriptorMatcherTest flannBasedMatcherTest( "descriptor-matcher-flann-based",
|
||||||
new FlannBasedMatcher, 0.04f );
|
new FlannBasedMatcher, 0.04f );
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user