Commit 9b4c6826 authored by Maria Dimashova's avatar Maria Dimashova

added empty() method to common features2d classes; fixed #831

parent fa446e7e
...@@ -523,6 +523,7 @@ public: ...@@ -523,6 +523,7 @@ public:
virtual int operator()(const Mat& img, Point2f kpt, vector<float>& signature) const; virtual int operator()(const Mat& img, Point2f kpt, vector<float>& signature) const;
virtual int operator()(const Mat& patch, vector<float>& signature) const; virtual int operator()(const Mat& patch, vector<float>& signature) const;
virtual void clear(); virtual void clear();
virtual bool empty() const;
void setVerbose(bool verbose); void setVerbose(bool verbose);
int getClassCount() const; int getClassCount() const;
...@@ -1086,6 +1087,8 @@ public: ...@@ -1086,6 +1087,8 @@ public:
// GetPCAFilename: get default PCA filename // GetPCAFilename: get default PCA filename
static string GetPCAFilename () { return "pca.yml"; } static string GetPCAFilename () { return "pca.yml"; }
virtual bool empty() const { return m_train_feature_count <= 0 ? true : false; }
protected: protected:
CvSize m_patch_size; // patch size CvSize m_patch_size; // patch size
int m_pose_count; // the number of poses for each descriptor int m_pose_count; // the number of poses for each descriptor
...@@ -1212,6 +1215,9 @@ public: ...@@ -1212,6 +1215,9 @@ public:
// Read detector object from a file node. // Read detector object from a file node.
virtual void write( FileStorage& ) const; virtual void write( FileStorage& ) const;
// Return true if detector object is empty
virtual bool empty() const;
// Create feature detector by detector name. // Create feature detector by detector name.
static Ptr<FeatureDetector> create( const string& detectorType ); static Ptr<FeatureDetector> create( const string& detectorType );
...@@ -1359,18 +1365,19 @@ public: ...@@ -1359,18 +1365,19 @@ public:
}; };
SimpleBlobDetector(const SimpleBlobDetector::Params &parameters = SimpleBlobDetector::Params()); SimpleBlobDetector(const SimpleBlobDetector::Params &parameters = SimpleBlobDetector::Params());
protected: protected:
struct CV_EXPORTS Center struct CV_EXPORTS Center
{ {
cv::Point2d location; Point2d location;
double radius; double radius;
double confidence; double confidence;
}; };
virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const; virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
virtual void findBlobs(const cv::Mat &image, const cv::Mat &binaryImage, std::vector<Center> &centers) const; virtual void findBlobs(const cv::Mat &image, const cv::Mat &binaryImage, std::vector<Center> &centers) const;
cv::Point2d computeGrayscaleCentroid(const cv::Mat &image, const std::vector<cv::Point> &contour) const; Point2d computeGrayscaleCentroid(const cv::Mat &image, const std::vector<cv::Point> &contour) const;
Params params; Params params;
}; };
...@@ -1422,6 +1429,7 @@ public: ...@@ -1422,6 +1429,7 @@ public:
int gridRows=4, int gridCols=4 ); int gridRows=4, int gridCols=4 );
// TODO implement read/write // TODO implement read/write
virtual bool empty() const;
protected: protected:
virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const; virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
...@@ -1442,6 +1450,7 @@ public: ...@@ -1442,6 +1450,7 @@ public:
PyramidAdaptedFeatureDetector( const Ptr<FeatureDetector>& detector, int levels=2 ); PyramidAdaptedFeatureDetector( const Ptr<FeatureDetector>& detector, int levels=2 );
// TODO implement read/write // TODO implement read/write
virtual bool empty() const;
protected: protected:
virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const; virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
...@@ -1500,6 +1509,8 @@ public: ...@@ -1500,6 +1509,8 @@ public:
*/ */
DynamicAdaptedFeatureDetector( const Ptr<AdjusterAdapter>& adjaster, int min_features=400, int max_features=500, int max_iters=5 ); DynamicAdaptedFeatureDetector( const Ptr<AdjusterAdapter>& adjaster, int min_features=400, int max_features=500, int max_iters=5 );
virtual bool empty() const;
protected: protected:
virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const; virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
...@@ -1607,6 +1618,8 @@ public: ...@@ -1607,6 +1618,8 @@ public:
virtual int descriptorSize() const = 0; virtual int descriptorSize() const = 0;
virtual int descriptorType() const = 0; virtual int descriptorType() const = 0;
virtual bool empty() const;
static Ptr<DescriptorExtractor> create( const string& descriptorExtractorType ); static Ptr<DescriptorExtractor> create( const string& descriptorExtractorType );
protected: protected:
...@@ -1680,6 +1693,8 @@ public: ...@@ -1680,6 +1693,8 @@ public:
virtual int descriptorSize() const { return classifier_.classes(); } virtual int descriptorSize() const { return classifier_.classes(); }
virtual int descriptorType() const { return DataType<T>::type; } virtual int descriptorType() const { return DataType<T>::type; }
virtual bool empty() const;
protected: protected:
virtual void computeImpl( const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors ) const; virtual void computeImpl( const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors ) const;
...@@ -1722,6 +1737,12 @@ template<typename T> ...@@ -1722,6 +1737,12 @@ template<typename T>
void CalonderDescriptorExtractor<T>::write( FileStorage& ) const void CalonderDescriptorExtractor<T>::write( FileStorage& ) const
{} {}
template<typename T>
bool CalonderDescriptorExtractor<T>::empty() const
{
return classifier_.trees_.empty();
}
/* /*
* OpponentColorDescriptorExtractor * OpponentColorDescriptorExtractor
* *
...@@ -1742,6 +1763,8 @@ public: ...@@ -1742,6 +1763,8 @@ public:
virtual int descriptorSize() const; virtual int descriptorSize() const;
virtual int descriptorType() const; virtual int descriptorType() const;
virtual bool empty() const;
protected: protected:
virtual void computeImpl( const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors ) const; virtual void computeImpl( const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors ) const;
...@@ -1766,7 +1789,7 @@ public: ...@@ -1766,7 +1789,7 @@ public:
/// @todo read and write for brief /// @todo read and write for brief
protected: protected:
virtual void computeImpl(const Mat& image, std::vector<KeyPoint>& keypoints, Mat& descriptors) const; virtual void computeImpl(const Mat& image, std::vector<KeyPoint>& keypoints, Mat& descriptors) const;
typedef void(*PixelTestFn)(const Mat&, const std::vector<KeyPoint>&, Mat&); typedef void(*PixelTestFn)(const Mat&, const std::vector<KeyPoint>&, Mat&);
...@@ -1924,7 +1947,7 @@ public: ...@@ -1924,7 +1947,7 @@ public:
/* /*
* Return true if there are not train descriptors in collection. * Return true if there are not train descriptors in collection.
*/ */
bool empty() const; virtual bool empty() const;
/* /*
* Return true if the matcher supports mask in match methods. * Return true if the matcher supports mask in match methods.
*/ */
...@@ -2366,6 +2389,9 @@ public: ...@@ -2366,6 +2389,9 @@ public:
// Writes matcher object to a file storage // Writes matcher object to a file storage
virtual void write( FileStorage& ) const; virtual void write( FileStorage& ) const;
// Return true if matching object is empty (e.g. feature detector or descriptor matcher are empty)
virtual bool empty() const;
// Clone the matcher. If emptyTrainData is false the method create deep copy of the object, i.e. copies // Clone the matcher. If emptyTrainData is false the method create deep copy of the object, i.e. copies
// both parameters and train data. If emptyTrainData is true the method create object copy with current parameters // both parameters and train data. If emptyTrainData is true the method create object copy with current parameters
// but with empty train data. // but with empty train data.
...@@ -2473,6 +2499,8 @@ public: ...@@ -2473,6 +2499,8 @@ public:
virtual void read( const FileNode &fn ); virtual void read( const FileNode &fn );
virtual void write( FileStorage& fs ) const; virtual void write( FileStorage& fs ) const;
virtual bool empty() const;
virtual Ptr<GenericDescriptorMatcher> clone( bool emptyTrainData=false ) const; virtual Ptr<GenericDescriptorMatcher> clone( bool emptyTrainData=false ) const;
protected: protected:
...@@ -2540,6 +2568,7 @@ public: ...@@ -2540,6 +2568,7 @@ public:
virtual void read( const FileNode &fn ); virtual void read( const FileNode &fn );
virtual void write( FileStorage& fs ) const; virtual void write( FileStorage& fs ) const;
virtual bool empty() const;
virtual Ptr<GenericDescriptorMatcher> clone( bool emptyTrainData=false ) const; virtual Ptr<GenericDescriptorMatcher> clone( bool emptyTrainData=false ) const;
...@@ -2586,6 +2615,7 @@ public: ...@@ -2586,6 +2615,7 @@ public:
virtual void read( const FileNode& fn ); virtual void read( const FileNode& fn );
virtual void write( FileStorage& fs ) const; virtual void write( FileStorage& fs ) const;
virtual bool empty() const;
virtual Ptr<GenericDescriptorMatcher> clone( bool emptyTrainData=false ) const; virtual Ptr<GenericDescriptorMatcher> clone( bool emptyTrainData=false ) const;
......
...@@ -860,8 +860,11 @@ int RTreeClassifier::countNonZeroElements(float *vec, int n, double tol) ...@@ -860,8 +860,11 @@ int RTreeClassifier::countNonZeroElements(float *vec, int n, double tol)
void RTreeClassifier::read(const char* file_name) void RTreeClassifier::read(const char* file_name)
{ {
std::ifstream file(file_name, std::ifstream::binary); std::ifstream file(file_name, std::ifstream::binary);
read(file); if( file.is_open() )
file.close(); {
read(file);
file.close();
}
} }
void RTreeClassifier::read(std::istream &is) void RTreeClassifier::read(std::istream &is)
......
...@@ -96,6 +96,11 @@ void DescriptorExtractor::read( const FileNode& ) ...@@ -96,6 +96,11 @@ void DescriptorExtractor::read( const FileNode& )
void DescriptorExtractor::write( FileStorage& ) const void DescriptorExtractor::write( FileStorage& ) const
{} {}
bool DescriptorExtractor::empty() const
{
return false;
}
void DescriptorExtractor::removeBorderKeypoints( vector<KeyPoint>& keypoints, void DescriptorExtractor::removeBorderKeypoints( vector<KeyPoint>& keypoints,
Size imageSize, int borderSize ) Size imageSize, int borderSize )
{ {
...@@ -361,4 +366,9 @@ int OpponentColorDescriptorExtractor::descriptorType() const ...@@ -361,4 +366,9 @@ int OpponentColorDescriptorExtractor::descriptorType() const
return descriptorExtractor->descriptorType(); return descriptorExtractor->descriptorType();
} }
bool OpponentColorDescriptorExtractor::empty() const
{
return descriptorExtractor.empty() || (DescriptorExtractor*)(descriptorExtractor)->empty();
}
} }
...@@ -96,6 +96,11 @@ void FeatureDetector::read( const FileNode& ) ...@@ -96,6 +96,11 @@ void FeatureDetector::read( const FileNode& )
void FeatureDetector::write( FileStorage& ) const void FeatureDetector::write( FileStorage& ) const
{} {}
bool FeatureDetector::empty() const
{
return false;
}
Ptr<FeatureDetector> FeatureDetector::create( const string& detectorType ) Ptr<FeatureDetector> FeatureDetector::create( const string& detectorType )
{ {
FeatureDetector* fd = 0; FeatureDetector* fd = 0;
...@@ -488,6 +493,11 @@ GridAdaptedFeatureDetector::GridAdaptedFeatureDetector( const Ptr<FeatureDetecto ...@@ -488,6 +493,11 @@ GridAdaptedFeatureDetector::GridAdaptedFeatureDetector( const Ptr<FeatureDetecto
: detector(_detector), maxTotalKeypoints(_maxTotalKeypoints), gridRows(_gridRows), gridCols(_gridCols) : detector(_detector), maxTotalKeypoints(_maxTotalKeypoints), gridRows(_gridRows), gridCols(_gridCols)
{} {}
bool GridAdaptedFeatureDetector::empty() const
{
return detector.empty() || (FeatureDetector*)detector->empty();
}
struct ResponseComparator struct ResponseComparator
{ {
bool operator() (const KeyPoint& a, const KeyPoint& b) bool operator() (const KeyPoint& a, const KeyPoint& b)
...@@ -544,6 +554,11 @@ PyramidAdaptedFeatureDetector::PyramidAdaptedFeatureDetector( const Ptr<FeatureD ...@@ -544,6 +554,11 @@ PyramidAdaptedFeatureDetector::PyramidAdaptedFeatureDetector( const Ptr<FeatureD
: detector(_detector), levels(_levels) : detector(_detector), levels(_levels)
{} {}
bool PyramidAdaptedFeatureDetector::empty() const
{
return detector.empty() || (FeatureDetector*)detector->empty();
}
void PyramidAdaptedFeatureDetector::detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask ) const void PyramidAdaptedFeatureDetector::detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask ) const
{ {
Mat src = image; Mat src = image;
......
...@@ -213,7 +213,7 @@ void DescriptorMatcher::clear() ...@@ -213,7 +213,7 @@ void DescriptorMatcher::clear()
bool DescriptorMatcher::empty() const bool DescriptorMatcher::empty() const
{ {
return trainDescCollection.size() == 0; return trainDescCollection.empty();
} }
void DescriptorMatcher::train() void DescriptorMatcher::train()
...@@ -848,6 +848,11 @@ void GenericDescriptorMatcher::read( const FileNode& ) ...@@ -848,6 +848,11 @@ void GenericDescriptorMatcher::read( const FileNode& )
void GenericDescriptorMatcher::write( FileStorage& ) const void GenericDescriptorMatcher::write( FileStorage& ) const
{} {}
bool GenericDescriptorMatcher::empty() const
{
return true;
}
/* /*
* Factory function for GenericDescriptorMatch creating * Factory function for GenericDescriptorMatch creating
*/ */
...@@ -994,13 +999,18 @@ void OneWayDescriptorMatcher::write( FileStorage& fs ) const ...@@ -994,13 +999,18 @@ void OneWayDescriptorMatcher::write( FileStorage& fs ) const
base->Write (fs); base->Write (fs);
} }
bool OneWayDescriptorMatcher::empty() const
{
return base.empty() || base->empty();
}
Ptr<GenericDescriptorMatcher> OneWayDescriptorMatcher::clone( bool emptyTrainData ) const Ptr<GenericDescriptorMatcher> OneWayDescriptorMatcher::clone( bool emptyTrainData ) const
{ {
OneWayDescriptorMatcher* matcher = new OneWayDescriptorMatcher( params ); OneWayDescriptorMatcher* matcher = new OneWayDescriptorMatcher( params );
if( !emptyTrainData ) if( !emptyTrainData )
{ {
CV_Error( CV_StsNotImplemented, "deep clone dunctionality is not implemented, because " CV_Error( CV_StsNotImplemented, "deep clone functionality is not implemented, because "
"OneWayDescriptorBase has not copy constructor or clone method "); "OneWayDescriptorBase has not copy constructor or clone method ");
//matcher->base; //matcher->base;
...@@ -1175,6 +1185,11 @@ void FernDescriptorMatcher::write( FileStorage& fs ) const ...@@ -1175,6 +1185,11 @@ void FernDescriptorMatcher::write( FileStorage& fs ) const
// classifier->write(fs); // classifier->write(fs);
} }
bool FernDescriptorMatcher::empty() const
{
return classifier.empty() || classifier->empty();
}
Ptr<GenericDescriptorMatcher> FernDescriptorMatcher::clone( bool emptyTrainData ) const Ptr<GenericDescriptorMatcher> FernDescriptorMatcher::clone( bool emptyTrainData ) const
{ {
FernDescriptorMatcher* matcher = new FernDescriptorMatcher( params ); FernDescriptorMatcher* matcher = new FernDescriptorMatcher( params );
...@@ -1262,6 +1277,12 @@ void VectorDescriptorMatcher::write (FileStorage& fs) const ...@@ -1262,6 +1277,12 @@ void VectorDescriptorMatcher::write (FileStorage& fs) const
extractor->write (fs); extractor->write (fs);
} }
bool VectorDescriptorMatcher::empty() const
{
return extractor.empty() || extractor->empty() ||
matcher.empty() || matcher->empty();
}
Ptr<GenericDescriptorMatcher> VectorDescriptorMatcher::clone( bool emptyTrainData ) const Ptr<GenericDescriptorMatcher> VectorDescriptorMatcher::clone( bool emptyTrainData ) const
{ {
// TODO clone extractor // TODO clone extractor
......
...@@ -771,6 +771,10 @@ void FernClassifier::clear() ...@@ -771,6 +771,10 @@ void FernClassifier::clear()
vector<float>().swap(posteriors); vector<float>().swap(posteriors);
} }
bool FernClassifier::empty() const
{
return features.empty();
}
int FernClassifier::getLeaf(int fern, const Mat& _patch) const int FernClassifier::getLeaf(int fern, const Mat& _patch) const
{ {
......
...@@ -73,6 +73,8 @@ protected: ...@@ -73,6 +73,8 @@ protected:
void CV_FeatureDetectorTest::emptyDataTest() void CV_FeatureDetectorTest::emptyDataTest()
{ {
assert( !fdetector.empty() && !fdetector->empty() );
// One image. // One image.
Mat image; Mat image;
vector<KeyPoint> keypoints; vector<KeyPoint> keypoints;
...@@ -172,7 +174,7 @@ void CV_FeatureDetectorTest::compareKeypointSets( const vector<KeyPoint>& validK ...@@ -172,7 +174,7 @@ void CV_FeatureDetectorTest::compareKeypointSets( const vector<KeyPoint>& validK
void CV_FeatureDetectorTest::regressionTest() void CV_FeatureDetectorTest::regressionTest()
{ {
assert( !fdetector.empty() ); assert( !fdetector.empty() && !fdetector->empty() );
string imgFilename = string(ts->get_data_path()) + FEATURES2D_DIR + "/" + IMAGE_FILENAME; string imgFilename = string(ts->get_data_path()) + FEATURES2D_DIR + "/" + IMAGE_FILENAME;
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";
...@@ -229,7 +231,7 @@ void CV_FeatureDetectorTest::regressionTest() ...@@ -229,7 +231,7 @@ void CV_FeatureDetectorTest::regressionTest()
void CV_FeatureDetectorTest::run( int /*start_from*/ ) void CV_FeatureDetectorTest::run( int /*start_from*/ )
{ {
if( fdetector.empty() ) if( fdetector.empty() || fdetector->empty() )
{ {
ts->printf( CvTS::LOG, "Feature detector is empty.\n" ); ts->printf( CvTS::LOG, "Feature detector is empty.\n" );
ts->set_failed_test_info( CvTS::FAIL_INVALID_TEST_DATA ); ts->set_failed_test_info( CvTS::FAIL_INVALID_TEST_DATA );
...@@ -293,7 +295,7 @@ public: ...@@ -293,7 +295,7 @@ public:
CvTest( testName, "cv::DescriptorExtractor::compute" ), CvTest( testName, "cv::DescriptorExtractor::compute" ),
maxDist(_maxDist), prevTime(_prevTime), dextractor(_dextractor), distance(d) {} maxDist(_maxDist), prevTime(_prevTime), dextractor(_dextractor), distance(d) {}
protected: protected:
virtual void createDescriptorExtractor() {} virtual void createDescriptorExtractor(){}
void compareDescriptors( const Mat& validDescriptors, const Mat& calcDescriptors ) void compareDescriptors( const Mat& validDescriptors, const Mat& calcDescriptors )
{ {
...@@ -329,7 +331,7 @@ protected: ...@@ -329,7 +331,7 @@ protected:
void emptyDataTest() void emptyDataTest()
{ {
assert( !dextractor.empty() ); assert( !dextractor.empty() && !dextractor->empty() );
// One image. // One image.
Mat image; Mat image;
...@@ -374,7 +376,7 @@ protected: ...@@ -374,7 +376,7 @@ protected:
void regressionTest() void regressionTest()
{ {
assert( !dextractor.empty() ); assert( !dextractor.empty() && !dextractor->empty() );
// 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;
...@@ -449,7 +451,7 @@ protected: ...@@ -449,7 +451,7 @@ protected:
void run(int) void run(int)
{ {
createDescriptorExtractor(); createDescriptorExtractor();
if( dextractor.empty() ) if( dextractor.empty() || dextractor->empty() )
{ {
ts->printf(CvTS::LOG, "Descriptor extractor is empty.\n"); ts->printf(CvTS::LOG, "Descriptor extractor is empty.\n");
ts->set_failed_test_info( CvTS::FAIL_INVALID_TEST_DATA ); ts->set_failed_test_info( CvTS::FAIL_INVALID_TEST_DATA );
...@@ -495,9 +497,16 @@ public: ...@@ -495,9 +497,16 @@ public:
protected: protected:
virtual void createDescriptorExtractor() virtual void createDescriptorExtractor()
{ {
string filename = string(CV_DescriptorExtractorTest<Distance>::ts->get_data_path()) +
FEATURES2D_DIR + "/calonder_classifier.rtc";
CV_DescriptorExtractorTest<Distance>::dextractor = CV_DescriptorExtractorTest<Distance>::dextractor =
new CalonderDescriptorExtractor<T>( string(CV_DescriptorExtractorTest<Distance>::ts->get_data_path()) + new CalonderDescriptorExtractor<T>( filename );
FEATURES2D_DIR + "/calonder_classifier.rtc"); if( CV_DescriptorExtractorTest<Distance>::dextractor->empty() )
{
stringstream ss; ss << "Calonder descriptor extractor can not be loaded from file" << filename<< endl;
CV_DescriptorExtractorTest<Distance>::ts->printf( CvTS::LOG, ss.str().c_str() );
CV_DescriptorExtractorTest<Distance>::ts->set_failed_test_info( CvTS::FAIL_INVALID_TEST_DATA );
}
} }
}; };
...@@ -531,7 +540,8 @@ private: ...@@ -531,7 +540,8 @@ private:
void CV_DescriptorMatcherTest::emptyDataTest() void CV_DescriptorMatcherTest::emptyDataTest()
{ {
assert( !dmatcher.empty() ); assert( !dmatcher.empty() && !dmatcher->empty() );
Mat queryDescriptors, trainDescriptors, mask; Mat queryDescriptors, trainDescriptors, mask;
vector<Mat> trainDescriptorCollection, masks; vector<Mat> trainDescriptorCollection, masks;
vector<DMatch> matches; vector<DMatch> matches;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment