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

This commit is contained in:
Vadim Pisarevsky 2012-09-11 16:47:25 +04:00
parent e975259c06
commit 84087a8566
5 changed files with 34 additions and 10 deletions

View File

@ -264,7 +264,7 @@ public:
bool useProvidedKeypoints=false ) const = 0;
// Create feature detector and descriptor extractor by name.
static Ptr<Feature2D> create( const string& name );
CV_WRAP static Ptr<Feature2D> create( const string& name );
};
/*!

View File

@ -44,6 +44,11 @@
using namespace cv;
Ptr<Feature2D> Feature2D::create( const string& feature2DType )
{
return Algorithm::create<Feature2D>("Feature2D." + feature2DType);
}
/////////////////////// AlgorithmInfo for various detector & descriptors ////////////////////////////
/* NOTE!!!

View File

@ -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(), "");
}
*/

View File

@ -121,6 +121,7 @@ typedef vector<vector<DMatch> > vector_vector_DMatch;
typedef Ptr<Algorithm> Ptr_Algorithm;
typedef Ptr<FeatureDetector> Ptr_FeatureDetector;
typedef Ptr<DescriptorExtractor> Ptr_DescriptorExtractor;
typedef Ptr<Feature2D> Ptr_Feature2D;
typedef Ptr<DescriptorMatcher> Ptr_DescriptorMatcher;
typedef SimpleBlobDetector::Params SimpleBlobDetector_Params;

View File

@ -6,6 +6,11 @@ gen_template_check_self = Template(""" if(!PyObject_TypeCheck(self, &pyopencv
$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);
new (&(self->v)) Ptr<$cname>(); // init Ptr with placement new
if(self) ERRWRAP2(self->v = new $cname""")
@ -70,7 +75,7 @@ gen_template_type_decl = Template("""
struct pyopencv_${name}_t
{
PyObject_HEAD
Ptr<${cname}> v;
Ptr<${cname1}> v;
};
static PyTypeObject pyopencv_${name}_Type =
@ -83,14 +88,14 @@ static PyTypeObject pyopencv_${name}_Type =
static void pyopencv_${name}_dealloc(PyObject* self)
{
((pyopencv_${name}_t*)self)->v = NULL;
((pyopencv_${name}_t*)self)->v.release();
PyObject_Del(self);
}
static PyObject* pyopencv_from(const Ptr<${cname}>& r)
{
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;
return (PyObject*)m;
}
@ -207,6 +212,7 @@ class ClassInfo(object):
self.name = self.wname = normalize_class_name(name)
self.ismap = False
self.issimple = False
self.isalgorithm = False
self.methods = {}
self.props = []
self.consts = {}
@ -222,6 +228,8 @@ class ClassInfo(object):
#return sys.exit(-1)
if self.bases and self.bases[0].startswith("cv::"):
self.bases[0] = self.bases[0][4:]
if self.bases and self.bases[0] == "Algorithm":
self.isalgorithm = True
for m in decl[2]:
if m.startswith("="):
self.wname = m[1:]
@ -510,6 +518,9 @@ class FuncInfo(object):
amp = ""
if selfinfo.issimple:
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
@ -675,6 +686,8 @@ class PythonWrapperGenerator(object):
% (classinfo.name, classinfo.cname)
sys.exit(-1)
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):
constinfo = ConstInfo(name, decl[1])
@ -770,7 +783,8 @@ class PythonWrapperGenerator(object):
templ = gen_template_simple_type_decl
else:
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.
# this way, base classes will be registered in Python before their derivatives.
@ -813,6 +827,3 @@ if __name__ == "__main__":
srcfiles = sys.argv[2:]
generator = PythonWrapperGenerator()
generator.gen(srcfiles, dstdir)