From be028d07749079ab7a8dfc2f1157e459a426e4c2 Mon Sep 17 00:00:00 2001 From: abratchik Date: Fri, 7 Oct 2016 23:58:57 +0400 Subject: [PATCH 1/2] fix for #7420, #7421 --- .../features2d/include/opencv2/features2d.hpp | 52 ++++++-- .../misc/java/src/cpp/features2d_manual.hpp | 114 ------------------ modules/features2d/src/matchers.cpp | 45 +++++++ modules/java/generator/gen_java.py | 2 +- 4 files changed, 88 insertions(+), 125 deletions(-) diff --git a/modules/features2d/include/opencv2/features2d.hpp b/modules/features2d/include/opencv2/features2d.hpp index 633729f2e1..0fcdc33e48 100644 --- a/modules/features2d/include/opencv2/features2d.hpp +++ b/modules/features2d/include/opencv2/features2d.hpp @@ -771,6 +771,15 @@ an image set. class CV_EXPORTS_W DescriptorMatcher : public Algorithm { public: + enum + { + FLANNBASED = 1, + BRUTEFORCE = 2, + BRUTEFORCE_L1 = 3, + BRUTEFORCE_HAMMING = 4, + BRUTEFORCE_HAMMINGLUT = 5, + BRUTEFORCE_SL2 = 6 + }; virtual ~DescriptorMatcher(); /** @brief Adds descriptors to train a CPU(trainDescCollectionis) or GPU(utrainDescCollectionis) descriptor @@ -868,7 +877,7 @@ public: query descriptor and the training descriptor is equal or smaller than maxDistance. Found matches are returned in the distance increasing order. */ - void radiusMatch( InputArray queryDescriptors, InputArray trainDescriptors, + CV_WRAP void radiusMatch( InputArray queryDescriptors, InputArray trainDescriptors, std::vector >& matches, float maxDistance, InputArray mask=noArray(), bool compactResult=false ) const; @@ -909,6 +918,18 @@ public: void radiusMatch( InputArray queryDescriptors, std::vector >& matches, float maxDistance, InputArrayOfArrays masks=noArray(), bool compactResult=false ); + + CV_WRAP void write( const String& fileName ) const + { + FileStorage fs(fileName, FileStorage::WRITE); + write(fs); + } + + CV_WRAP void read( const String& fileName ) + { + FileStorage fs(fileName, FileStorage::READ); + read(fs.root()); + } // Reads matcher object from a file node virtual void read( const FileNode& ); // Writes matcher object to a file storage @@ -920,7 +941,7 @@ public: that is, copies both parameters and train data. If emptyTrainData is true, the method creates an object copy with the current parameters but with empty train data. */ - virtual Ptr clone( bool emptyTrainData=false ) const = 0; + CV_WRAP virtual Ptr clone( bool emptyTrainData=false ) const = 0; /** @brief Creates a descriptor matcher of a given type with the default parameters (using default constructor). @@ -934,6 +955,9 @@ public: - `FlannBased` */ CV_WRAP static Ptr create( const String& descriptorMatcherType ); + + CV_WRAP static Ptr create( int matcherType ); + protected: /** * Class to work with descriptors from several images as with one merged matrix. @@ -990,8 +1014,17 @@ sets. class CV_EXPORTS_W BFMatcher : public DescriptorMatcher { public: - /** @brief Brute-force matcher constructor. + /** @brief Brute-force matcher constructor (obsolete). Please use BFMatcher.create() + * + * + */ + CV_WRAP BFMatcher( int _normType=NORM_L2, bool _crossCheck=false ); + + virtual ~BFMatcher() {} + + virtual bool isMaskSupported() const { return true; } + /* @brief Brute-force matcher create method. @param normType One of NORM_L1, NORM_L2, NORM_HAMMING, NORM_HAMMING2. L1 and L2 norms are preferable choices for SIFT and SURF descriptors, NORM_HAMMING should be used with ORB, BRISK and BRIEF, NORM_HAMMING2 should be used with ORB when WTA_K==3 or 4 (see ORB::ORB constructor @@ -1002,12 +1035,9 @@ public: matcher's collection is the nearest and vice versa, i.e. the BFMatcher will only return consistent pairs. Such technique usually produces best results with minimal number of outliers when there are enough matches. This is alternative to the ratio test, used by D. Lowe in SIFT paper. - */ - CV_WRAP BFMatcher( int normType=NORM_L2, bool crossCheck=false ); - virtual ~BFMatcher() {} - - virtual bool isMaskSupported() const { return true; } - + */ + CV_WRAP static Ptr create( int _normType=NORM_L2, bool _crossCheck=false ) ; + virtual Ptr clone( bool emptyTrainData=false ) const; protected: virtual void knnMatchImpl( InputArray queryDescriptors, std::vector >& matches, int k, @@ -1030,7 +1060,7 @@ matches of descriptor sets because flann::Index does not support this. : class CV_EXPORTS_W FlannBasedMatcher : public DescriptorMatcher { public: - CV_WRAP FlannBasedMatcher( const Ptr& indexParams=makePtr(), + FlannBasedMatcher( const Ptr& indexParams=makePtr(), const Ptr& searchParams=makePtr() ); virtual void add( InputArrayOfArrays descriptors ); @@ -1044,6 +1074,8 @@ public: virtual void train(); virtual bool isMaskSupported() const; + CV_WRAP static Ptr create(); + virtual Ptr clone( bool emptyTrainData=false ) const; protected: static void convertToDMatches( const DescriptorCollection& descriptors, diff --git a/modules/features2d/misc/java/src/cpp/features2d_manual.hpp b/modules/features2d/misc/java/src/cpp/features2d_manual.hpp index 85b9489a28..d43928d205 100644 --- a/modules/features2d/misc/java/src/cpp/features2d_manual.hpp +++ b/modules/features2d/misc/java/src/cpp/features2d_manual.hpp @@ -178,120 +178,6 @@ private: Ptr wrapped; }; -class CV_EXPORTS_AS(DescriptorMatcher) javaDescriptorMatcher -{ -public: - CV_WRAP bool isMaskSupported() const - { return wrapped->isMaskSupported(); } - - CV_WRAP void add( const std::vector& descriptors ) - { return wrapped->add(descriptors); } - - CV_WRAP const std::vector& getTrainDescriptors() const - { return wrapped->getTrainDescriptors(); } - - CV_WRAP void clear() - { return wrapped->clear(); } - - CV_WRAP bool empty() const - { return wrapped->empty(); } - - CV_WRAP void train() - { return wrapped->train(); } - - CV_WRAP void match( const Mat& queryDescriptors, const Mat& trainDescriptors, - CV_OUT std::vector& matches, const Mat& mask=Mat() ) const - { return wrapped->match(queryDescriptors, trainDescriptors, matches, mask); } - - CV_WRAP void knnMatch( const Mat& queryDescriptors, const Mat& trainDescriptors, - CV_OUT std::vector >& matches, int k, - const Mat& mask=Mat(), bool compactResult=false ) const - { return wrapped->knnMatch(queryDescriptors, trainDescriptors, matches, k, mask, compactResult); } - - CV_WRAP void radiusMatch( const Mat& queryDescriptors, const Mat& trainDescriptors, - CV_OUT std::vector >& matches, float maxDistance, - const Mat& mask=Mat(), bool compactResult=false ) const - { return wrapped->radiusMatch(queryDescriptors, trainDescriptors, matches, maxDistance, mask, compactResult); } - - CV_WRAP void match( const Mat& queryDescriptors, CV_OUT std::vector& matches, - const std::vector& masks=std::vector() ) - { return wrapped->match(queryDescriptors, matches, masks); } - - CV_WRAP void knnMatch( const Mat& queryDescriptors, CV_OUT std::vector >& matches, int k, - const std::vector& masks=std::vector(), bool compactResult=false ) - { return wrapped->knnMatch(queryDescriptors, matches, k, masks, compactResult); } - - CV_WRAP void radiusMatch( const Mat& queryDescriptors, CV_OUT std::vector >& matches, float maxDistance, - const std::vector& masks=std::vector(), bool compactResult=false ) - { return wrapped->radiusMatch(queryDescriptors, matches, maxDistance, masks, compactResult); } - - enum - { - FLANNBASED = 1, - BRUTEFORCE = 2, - BRUTEFORCE_L1 = 3, - BRUTEFORCE_HAMMING = 4, - BRUTEFORCE_HAMMINGLUT = 5, - BRUTEFORCE_SL2 = 6 - }; - - CV_WRAP_AS(clone) javaDescriptorMatcher* jclone( bool emptyTrainData=false ) const - { - return new javaDescriptorMatcher(wrapped->clone(emptyTrainData)); - } - - //supported: FlannBased, BruteForce, BruteForce-L1, BruteForce-Hamming, BruteForce-HammingLUT - CV_WRAP static javaDescriptorMatcher* create( int matcherType ) - { - String name; - - switch(matcherType) - { - case FLANNBASED: - name = "FlannBased"; - break; - case BRUTEFORCE: - name = "BruteForce"; - break; - case BRUTEFORCE_L1: - name = "BruteForce-L1"; - break; - case BRUTEFORCE_HAMMING: - name = "BruteForce-Hamming"; - break; - case BRUTEFORCE_HAMMINGLUT: - name = "BruteForce-HammingLUT"; - break; - case BRUTEFORCE_SL2: - name = "BruteForce-SL2"; - break; - default: - CV_Error( Error::StsBadArg, "Specified descriptor matcher type is not supported." ); - break; - } - - return new javaDescriptorMatcher(DescriptorMatcher::create(name)); - } - - CV_WRAP void write( const String& fileName ) const - { - FileStorage fs(fileName, FileStorage::WRITE); - wrapped->write(fs); - } - - CV_WRAP void read( const String& fileName ) - { - FileStorage fs(fileName, FileStorage::READ); - wrapped->read(fs.root()); - } - -private: - javaDescriptorMatcher(Ptr _wrapped) : wrapped(_wrapped) - {} - - Ptr wrapped; -}; - class CV_EXPORTS_AS(DescriptorExtractor) javaDescriptorExtractor { public: diff --git a/modules/features2d/src/matchers.cpp b/modules/features2d/src/matchers.cpp index f0b1d610bc..5ec1f675b8 100644 --- a/modules/features2d/src/matchers.cpp +++ b/modules/features2d/src/matchers.cpp @@ -696,6 +696,11 @@ BFMatcher::BFMatcher( int _normType, bool _crossCheck ) crossCheck = _crossCheck; } +Ptr BFMatcher::create(int _normType, bool _crossCheck ) +{ + return makePtr(_normType, _crossCheck); +} + Ptr BFMatcher::clone( bool emptyTrainData ) const { Ptr matcher = makePtr(normType, crossCheck); @@ -1031,6 +1036,41 @@ Ptr DescriptorMatcher::create( const String& descriptorMatche return dm; } +Ptr DescriptorMatcher::create(int matcherType) +{ + + + String name; + + switch(matcherType) + { + case FLANNBASED: + name = "FlannBased"; + break; + case BRUTEFORCE: + name = "BruteForce"; + break; + case BRUTEFORCE_L1: + name = "BruteForce-L1"; + break; + case BRUTEFORCE_HAMMING: + name = "BruteForce-Hamming"; + break; + case BRUTEFORCE_HAMMINGLUT: + name = "BruteForce-HammingLUT"; + break; + case BRUTEFORCE_SL2: + name = "BruteForce-SL2"; + break; + default: + CV_Error( Error::StsBadArg, "Specified descriptor matcher type is not supported." ); + break; + } + + return DescriptorMatcher::create(name); + +} + /* * Flann based matcher @@ -1042,6 +1082,11 @@ FlannBasedMatcher::FlannBasedMatcher( const Ptr& _indexParam CV_Assert( _searchParams ); } +Ptr FlannBasedMatcher::create() +{ + return makePtr(); +} + void FlannBasedMatcher::add( InputArrayOfArrays _descriptors ) { DescriptorMatcher::add( _descriptors ); diff --git a/modules/java/generator/gen_java.py b/modules/java/generator/gen_java.py index c9b7423026..6039cdb8e6 100755 --- a/modules/java/generator/gen_java.py +++ b/modules/java/generator/gen_java.py @@ -14,7 +14,7 @@ class_ignore_list = ( #core "FileNode", "FileStorage", "KDTree", "KeyPoint", "DMatch", #features2d - "SimpleBlobDetector", "FlannBasedMatcher", "DescriptorMatcher" + "SimpleBlobDetector" ) const_ignore_list = ( From 789b35d813848ebddcaf484858c6c7d5532858d7 Mon Sep 17 00:00:00 2001 From: abratchik Date: Sat, 8 Oct 2016 02:13:01 +0400 Subject: [PATCH 2/2] improved fix for java wrapper generator (gen_java.py) to avoid generation of java methods with duplicate signatures(v3) --- .../features2d/include/opencv2/features2d.hpp | 24 +++++++------- modules/features2d/src/matchers.cpp | 10 +++--- modules/java/generator/gen_java.py | 32 +++++++++++++------ 3 files changed, 40 insertions(+), 26 deletions(-) diff --git a/modules/features2d/include/opencv2/features2d.hpp b/modules/features2d/include/opencv2/features2d.hpp index 0fcdc33e48..29f263b4aa 100644 --- a/modules/features2d/include/opencv2/features2d.hpp +++ b/modules/features2d/include/opencv2/features2d.hpp @@ -918,7 +918,7 @@ public: void radiusMatch( InputArray queryDescriptors, std::vector >& matches, float maxDistance, InputArrayOfArrays masks=noArray(), bool compactResult=false ); - + CV_WRAP void write( const String& fileName ) const { FileStorage fs(fileName, FileStorage::WRITE); @@ -955,9 +955,9 @@ public: - `FlannBased` */ CV_WRAP static Ptr create( const String& descriptorMatcherType ); - + CV_WRAP static Ptr create( int matcherType ); - + protected: /** * Class to work with descriptors from several images as with one merged matrix. @@ -1015,11 +1015,11 @@ class CV_EXPORTS_W BFMatcher : public DescriptorMatcher { public: /** @brief Brute-force matcher constructor (obsolete). Please use BFMatcher.create() - * - * + * + * */ - CV_WRAP BFMatcher( int _normType=NORM_L2, bool _crossCheck=false ); - + CV_WRAP BFMatcher( int normType=NORM_L2, bool crossCheck=false ); + virtual ~BFMatcher() {} virtual bool isMaskSupported() const { return true; } @@ -1035,9 +1035,9 @@ public: matcher's collection is the nearest and vice versa, i.e. the BFMatcher will only return consistent pairs. Such technique usually produces best results with minimal number of outliers when there are enough matches. This is alternative to the ratio test, used by D. Lowe in SIFT paper. - */ - CV_WRAP static Ptr create( int _normType=NORM_L2, bool _crossCheck=false ) ; - + */ + CV_WRAP static Ptr create( int normType=NORM_L2, bool crossCheck=false ) ; + virtual Ptr clone( bool emptyTrainData=false ) const; protected: virtual void knnMatchImpl( InputArray queryDescriptors, std::vector >& matches, int k, @@ -1060,7 +1060,7 @@ matches of descriptor sets because flann::Index does not support this. : class CV_EXPORTS_W FlannBasedMatcher : public DescriptorMatcher { public: - FlannBasedMatcher( const Ptr& indexParams=makePtr(), + CV_WRAP FlannBasedMatcher( const Ptr& indexParams=makePtr(), const Ptr& searchParams=makePtr() ); virtual void add( InputArrayOfArrays descriptors ); @@ -1075,7 +1075,7 @@ public: virtual bool isMaskSupported() const; CV_WRAP static Ptr create(); - + virtual Ptr clone( bool emptyTrainData=false ) const; protected: static void convertToDMatches( const DescriptorCollection& descriptors, diff --git a/modules/features2d/src/matchers.cpp b/modules/features2d/src/matchers.cpp index 5ec1f675b8..4e9a7b417c 100644 --- a/modules/features2d/src/matchers.cpp +++ b/modules/features2d/src/matchers.cpp @@ -696,7 +696,7 @@ BFMatcher::BFMatcher( int _normType, bool _crossCheck ) crossCheck = _crossCheck; } -Ptr BFMatcher::create(int _normType, bool _crossCheck ) +Ptr BFMatcher::create(int _normType, bool _crossCheck ) { return makePtr(_normType, _crossCheck); } @@ -1038,8 +1038,8 @@ Ptr DescriptorMatcher::create( const String& descriptorMatche Ptr DescriptorMatcher::create(int matcherType) { - - + + String name; switch(matcherType) @@ -1068,7 +1068,7 @@ Ptr DescriptorMatcher::create(int matcherType) } return DescriptorMatcher::create(name); - + } @@ -1082,7 +1082,7 @@ FlannBasedMatcher::FlannBasedMatcher( const Ptr& _indexParam CV_Assert( _searchParams ); } -Ptr FlannBasedMatcher::create() +Ptr FlannBasedMatcher::create() { return makePtr(); } diff --git a/modules/java/generator/gen_java.py b/modules/java/generator/gen_java.py index 6039cdb8e6..7c7303961d 100755 --- a/modules/java/generator/gen_java.py +++ b/modules/java/generator/gen_java.py @@ -1155,6 +1155,7 @@ class JavaWrapperGenerator(object): # java args args = fi.args[:] # copy + j_signatures=[] suffix_counter = int(ci.methods_suffixes.get(fi.jname, -1)) while True: suffix_counter += 1 @@ -1233,6 +1234,25 @@ class JavaWrapperGenerator(object): i += 1 j_epilogue.append( "if("+a.name+"!=null){ " + "; ".join(set_vals) + "; } ") + # calculate java method signature to check for uniqueness + j_args = [] + for a in args: + if not a.ctype: #hidden + continue + jt = type_dict[a.ctype]["j_type"] + if a.out and a.ctype in ('bool', 'int', 'long', 'float', 'double'): + jt += '[]' + j_args.append( jt + ' ' + a.name ) + j_signature = type_dict[fi.ctype]["j_type"] + " " + \ + fi.jname + "(" + ", ".join(j_args) + ")" + logging.info("java: " + j_signature) + + if(j_signature in j_signatures): + if args: + pop(args) + continue + else: + break # java part: # private java NATIVE method decl @@ -1297,15 +1317,6 @@ class JavaWrapperGenerator(object): if fi.classname: static = fi.static - j_args = [] - for a in args: - if not a.ctype: #hidden - continue - jt = type_dict[a.ctype]["j_type"] - if a.out and a.ctype in ('bool', 'int', 'long', 'float', 'double'): - jt += '[]' - j_args.append( jt + ' ' + a.name ) - j_code.write( Template(\ """ public $static $j_type $j_name($j_args) { @@ -1448,6 +1459,9 @@ JNIEXPORT $rtype JNICALL Java_org_opencv_${module}_${clazz}_$fname namespace = ('using namespace ' + ci.namespace.replace('.', '::') + ';') if ci.namespace else '' ) ) + # adding method signature to dictionarry + j_signatures.append(j_signature) + # processing args with default values if not args or not args[-1].defval: break