Commit 84087a85 authored by Vadim Pisarevsky's avatar Vadim Pisarevsky

fixed crash in Python's SURF wrapper (bug #2325)

parent e975259c
...@@ -264,7 +264,7 @@ public: ...@@ -264,7 +264,7 @@ public:
bool useProvidedKeypoints=false ) const = 0; bool useProvidedKeypoints=false ) const = 0;
// Create feature detector and descriptor extractor by name. // Create feature detector and descriptor extractor by name.
static Ptr<Feature2D> create( const string& name ); CV_WRAP static Ptr<Feature2D> create( const string& name );
}; };
/*! /*!
......
...@@ -44,6 +44,11 @@ ...@@ -44,6 +44,11 @@
using namespace cv; using namespace cv;
Ptr<Feature2D> Feature2D::create( const string& feature2DType )
{
return Algorithm::create<Feature2D>("Feature2D." + feature2DType);
}
/////////////////////// AlgorithmInfo for various detector & descriptors //////////////////////////// /////////////////////// AlgorithmInfo for various detector & descriptors ////////////////////////////
/* NOTE!!! /* NOTE!!!
......
...@@ -1079,3 +1079,10 @@ TEST(Features2d_BruteForceDescriptorMatcher_knnMatch, regression) ...@@ -1079,3 +1079,10 @@ TEST(Features2d_BruteForceDescriptorMatcher_knnMatch, regression)
} }
} }
} }
/*TEST(Features2d_DescriptorExtractorParamTest, regression)
{
Ptr<DescriptorExtractor> s = DescriptorExtractor::create("SURF");
ASSERT_STREQ(s->paramHelp("extended").c_str(), "");
}
*/
\ No newline at end of file
...@@ -121,6 +121,7 @@ typedef vector<vector<DMatch> > vector_vector_DMatch; ...@@ -121,6 +121,7 @@ typedef vector<vector<DMatch> > vector_vector_DMatch;
typedef Ptr<Algorithm> Ptr_Algorithm; typedef Ptr<Algorithm> Ptr_Algorithm;
typedef Ptr<FeatureDetector> Ptr_FeatureDetector; typedef Ptr<FeatureDetector> Ptr_FeatureDetector;
typedef Ptr<DescriptorExtractor> Ptr_DescriptorExtractor; typedef Ptr<DescriptorExtractor> Ptr_DescriptorExtractor;
typedef Ptr<Feature2D> Ptr_Feature2D;
typedef Ptr<DescriptorMatcher> Ptr_DescriptorMatcher; typedef Ptr<DescriptorMatcher> Ptr_DescriptorMatcher;
typedef SimpleBlobDetector::Params SimpleBlobDetector_Params; typedef SimpleBlobDetector::Params SimpleBlobDetector_Params;
......
...@@ -6,6 +6,11 @@ gen_template_check_self = Template(""" if(!PyObject_TypeCheck(self, &pyopencv ...@@ -6,6 +6,11 @@ gen_template_check_self = Template(""" if(!PyObject_TypeCheck(self, &pyopencv
$cname* _self_ = ${amp}((pyopencv_${name}_t*)self)->v; $cname* _self_ = ${amp}((pyopencv_${name}_t*)self)->v;
""") """)
gen_template_check_self_algo = Template(""" if(!PyObject_TypeCheck(self, &pyopencv_${name}_Type))
return failmsgp("Incorrect type of self (must be '${name}' or its derivative)");
$cname* _self_ = dynamic_cast<$cname*>(${amp}((pyopencv_${name}_t*)self)->v.obj);
""")
gen_template_call_constructor = Template("""self = PyObject_NEW(pyopencv_${name}_t, &pyopencv_${name}_Type); gen_template_call_constructor = Template("""self = PyObject_NEW(pyopencv_${name}_t, &pyopencv_${name}_Type);
new (&(self->v)) Ptr<$cname>(); // init Ptr with placement new new (&(self->v)) Ptr<$cname>(); // init Ptr with placement new
if(self) ERRWRAP2(self->v = new $cname""") if(self) ERRWRAP2(self->v = new $cname""")
...@@ -70,7 +75,7 @@ gen_template_type_decl = Template(""" ...@@ -70,7 +75,7 @@ gen_template_type_decl = Template("""
struct pyopencv_${name}_t struct pyopencv_${name}_t
{ {
PyObject_HEAD PyObject_HEAD
Ptr<${cname}> v; Ptr<${cname1}> v;
}; };
static PyTypeObject pyopencv_${name}_Type = static PyTypeObject pyopencv_${name}_Type =
...@@ -83,14 +88,14 @@ static PyTypeObject pyopencv_${name}_Type = ...@@ -83,14 +88,14 @@ static PyTypeObject pyopencv_${name}_Type =
static void pyopencv_${name}_dealloc(PyObject* self) static void pyopencv_${name}_dealloc(PyObject* self)
{ {
((pyopencv_${name}_t*)self)->v = NULL; ((pyopencv_${name}_t*)self)->v.release();
PyObject_Del(self); PyObject_Del(self);
} }
static PyObject* pyopencv_from(const Ptr<${cname}>& r) static PyObject* pyopencv_from(const Ptr<${cname}>& r)
{ {
pyopencv_${name}_t *m = PyObject_NEW(pyopencv_${name}_t, &pyopencv_${name}_Type); pyopencv_${name}_t *m = PyObject_NEW(pyopencv_${name}_t, &pyopencv_${name}_Type);
new (&(m->v)) Ptr<$cname>(); // init Ptr with placement new new (&(m->v)) Ptr<$cname1>(); // init Ptr with placement new
m->v = r; m->v = r;
return (PyObject*)m; return (PyObject*)m;
} }
...@@ -207,6 +212,7 @@ class ClassInfo(object): ...@@ -207,6 +212,7 @@ class ClassInfo(object):
self.name = self.wname = normalize_class_name(name) self.name = self.wname = normalize_class_name(name)
self.ismap = False self.ismap = False
self.issimple = False self.issimple = False
self.isalgorithm = False
self.methods = {} self.methods = {}
self.props = [] self.props = []
self.consts = {} self.consts = {}
...@@ -222,6 +228,8 @@ class ClassInfo(object): ...@@ -222,6 +228,8 @@ class ClassInfo(object):
#return sys.exit(-1) #return sys.exit(-1)
if self.bases and self.bases[0].startswith("cv::"): if self.bases and self.bases[0].startswith("cv::"):
self.bases[0] = self.bases[0][4:] self.bases[0] = self.bases[0][4:]
if self.bases and self.bases[0] == "Algorithm":
self.isalgorithm = True
for m in decl[2]: for m in decl[2]:
if m.startswith("="): if m.startswith("="):
self.wname = m[1:] self.wname = m[1:]
...@@ -510,7 +518,10 @@ class FuncInfo(object): ...@@ -510,7 +518,10 @@ class FuncInfo(object):
amp = "" amp = ""
if selfinfo.issimple: if selfinfo.issimple:
amp = "&" amp = "&"
code += gen_template_check_self.substitute(name=selfinfo.name, cname=selfinfo.cname, amp=amp) if selfinfo.isalgorithm:
code += gen_template_check_self_algo.substitute(name=selfinfo.name, cname=selfinfo.cname, amp=amp)
else:
code += gen_template_check_self.substitute(name=selfinfo.name, cname=selfinfo.cname, amp=amp)
fullname = selfinfo.wname + "." + fullname fullname = selfinfo.wname + "." + fullname
all_code_variants = [] all_code_variants = []
...@@ -675,6 +686,8 @@ class PythonWrapperGenerator(object): ...@@ -675,6 +686,8 @@ class PythonWrapperGenerator(object):
% (classinfo.name, classinfo.cname) % (classinfo.name, classinfo.cname)
sys.exit(-1) sys.exit(-1)
self.classes[classinfo.name] = classinfo self.classes[classinfo.name] = classinfo
if classinfo.bases and not classinfo.isalgorithm:
classinfo.isalgorithm = self.classes[classinfo.bases[0]].isalgorithm
def add_const(self, name, decl): def add_const(self, name, decl):
constinfo = ConstInfo(name, decl[1]) constinfo = ConstInfo(name, decl[1])
...@@ -770,8 +783,9 @@ class PythonWrapperGenerator(object): ...@@ -770,8 +783,9 @@ class PythonWrapperGenerator(object):
templ = gen_template_simple_type_decl templ = gen_template_simple_type_decl
else: else:
templ = gen_template_type_decl templ = gen_template_type_decl
self.code_types.write(templ.substitute(name=name, wname=classinfo.wname, cname=classinfo.cname)) self.code_types.write(templ.substitute(name=name, wname=classinfo.wname, cname=classinfo.cname,
cname1=("cv::Algorithm" if classinfo.isalgorithm else classinfo.cname)))
# register classes in the same order as they have been declared. # register classes in the same order as they have been declared.
# this way, base classes will be registered in Python before their derivatives. # this way, base classes will be registered in Python before their derivatives.
classlist1 = [(classinfo.decl_idx, name, classinfo) for name, classinfo in classlist] classlist1 = [(classinfo.decl_idx, name, classinfo) for name, classinfo in classlist]
...@@ -813,6 +827,3 @@ if __name__ == "__main__": ...@@ -813,6 +827,3 @@ if __name__ == "__main__":
srcfiles = sys.argv[2:] srcfiles = sys.argv[2:]
generator = PythonWrapperGenerator() generator = PythonWrapperGenerator()
generator.gen(srcfiles, dstdir) generator.gen(srcfiles, dstdir)
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