handling Ptr<> arguments and return values in Python wrappers

partially wrapped features2d framework
added feature_homography.py sample
This commit is contained in:
Alexander Mordvintsev
2011-09-07 09:38:22 +00:00
parent 2ef4e2eeb7
commit d50cc51070
4 changed files with 161 additions and 34 deletions

View File

@@ -64,9 +64,15 @@ typedef vector<Vec4i> vector_Vec4i;
typedef vector<Rect> vector_Rect;
typedef vector<KeyPoint> vector_KeyPoint;
typedef vector<Mat> vector_Mat;
typedef vector<DMatch> vector_DMatch;
typedef vector<vector<Point> > vector_vector_Point;
typedef vector<vector<Point2f> > vector_vector_Point2f;
typedef vector<vector<Point3f> > vector_vector_Point3f;
typedef vector<vector<DMatch> > vector_vector_DMatch;
typedef Ptr<FeatureDetector> Ptr_FeatureDetector;
typedef Ptr<DescriptorExtractor> Ptr_DescriptorExtractor;
typedef Ptr<DescriptorMatcher> Ptr_DescriptorMatcher;
static PyObject* failmsgp(const char *fmt, ...)
{
@@ -312,6 +318,14 @@ static PyObject* pyopencv_from(size_t value)
return PyLong_FromUnsignedLong((unsigned long)value);
}
static bool pyopencv_to(PyObject* obj, size_t& value, const char* name = "<unknown>")
{
if(!obj || obj == Py_None)
return true;
value = (int)PyLong_AsUnsignedLong(obj);
return value != -1 || !PyErr_Occurred();
}
static PyObject* pyopencv_from(int value)
{
return PyInt_FromLong(value);
@@ -605,6 +619,7 @@ template<typename _Tp> static inline PyObject* pyopencv_from(const vector<_Tp>&
}
static PyObject* pyopencv_from(const KeyPoint&);
static PyObject* pyopencv_from(const DMatch&);
template<typename _Tp> static inline bool pyopencv_to_generic_vec(PyObject* obj, vector<_Tp>& value, const char* name="<unknown>")
{
@@ -689,6 +704,19 @@ template<> struct pyopencvVecConverter<KeyPoint>
}
};
template<> struct pyopencvVecConverter<DMatch>
{
static bool to(PyObject* obj, vector<DMatch>& value, const char* name="<unknown>")
{
return pyopencv_to_generic_vec(obj, value, name);
}
static PyObject* from(const vector<DMatch>& value)
{
return pyopencv_from_generic_vec(value);
}
};
static inline bool pyopencv_to(PyObject *obj, CvTermCriteria& dst, const char *name="<unknown>")
{

View File

@@ -7,7 +7,11 @@ gen_template_check_self = Template(""" if(!PyObject_TypeCheck(self, &pyopencv
""")
gen_template_call_constructor = Template("""self = PyObject_NEW(pyopencv_${name}_t, &pyopencv_${name}_Type);
if(self) ERRWRAP2(self->v = $op$cname""")
new (&(self->v)) Ptr<$cname>(); // init Ptr with placement new
if(self) ERRWRAP2(self->v = new $cname""")
gen_template_simple_call_constructor = Template("""self = PyObject_NEW(pyopencv_${name}_t, &pyopencv_${name}_Type);
if(self) ERRWRAP2(self->v = $cname""")
gen_template_parse_args = Template("""const char* keywords[] = { $kw_list, NULL };
if( PyArg_ParseTupleAndKeywords(args, kw, "$fmtspec", (char**)keywords, $parse_arglist)$code_cvt )""")
@@ -66,7 +70,7 @@ gen_template_type_decl = Template("""
struct pyopencv_${name}_t
{
PyObject_HEAD
${cname}* v;
Ptr<${cname}> v;
};
static PyTypeObject pyopencv_${name}_Type =
@@ -79,9 +83,31 @@ static PyTypeObject pyopencv_${name}_Type =
static void pyopencv_${name}_dealloc(PyObject* self)
{
delete ((pyopencv_${name}_t*)self)->v;
((pyopencv_${name}_t*)self)->v = NULL;
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
m->v = r;
return (PyObject*)m;
}
static bool pyopencv_to(PyObject* src, Ptr<${cname}>& dst, const char* name="<unknown>")
{
if( src == NULL || src == Py_None )
return true;
if(!PyObject_TypeCheck(src, &pyopencv_${name}_Type))
{
failmsg("Expected ${cname} for argument '%s'", name);
return false;
}
dst = ((pyopencv_${name}_t*)src)->v;
return true;
}
""")
gen_template_map_type_cvt = Template("""
@@ -490,10 +516,10 @@ class FuncInfo(object):
if self.isconstructor:
code_decl += " pyopencv_%s_t* self = 0;\n" % selfinfo.name
op = "new "
templ = gen_template_call_constructor
if selfinfo.issimple:
op = ""
code_fcall = gen_template_call_constructor.substitute(name=selfinfo.name, cname=selfinfo.cname, op=op)
templ = gen_template_simple_call_constructor
code_fcall = templ.substitute(name=selfinfo.name, cname=selfinfo.cname)
else:
code_fcall = "ERRWRAP2( "
if v.rettype: