Merge pull request #7056 from ludv1x:python-extra-bindings

This commit is contained in:
Maksim Shabunin 2016-08-16 13:00:30 +00:00
commit d1d8c7d8a6
8 changed files with 132 additions and 136 deletions

View File

@ -142,5 +142,6 @@ public:
So these are the major extension macros available in OpenCV. Typically, a developer has to put
proper macros in their appropriate positions. Rest is done by generator scripts. Sometimes, there
may be an exceptional cases where generator scripts cannot create the wrappers. Such functions need
to be handled manually. But most of the time, a code written according to OpenCV coding guidelines
will be automatically wrapped by generator scripts.
to be handled manually, to do this write your own pyopencv_*.hpp extending headers and put them into
misc/python subdirectory of your module. But most of the time, a code written according to OpenCV
coding guidelines will be automatically wrapped by generator scripts.

View File

@ -0,0 +1,3 @@
#ifdef HAVE_OPENCV_FEATURES2D
typedef SimpleBlobDetector::Params SimpleBlobDetector_Params;
#endif

View File

@ -0,0 +1,79 @@
#ifdef HAVE_OPENCV_FLANN
typedef cvflann::flann_distance_t cvflann_flann_distance_t;
typedef cvflann::flann_algorithm_t cvflann_flann_algorithm_t;
template<>
PyObject* pyopencv_from(const cvflann_flann_algorithm_t& value)
{
return PyInt_FromLong(int(value));
}
template<>
PyObject* pyopencv_from(const cvflann_flann_distance_t& value)
{
return PyInt_FromLong(int(value));
}
template<>
bool pyopencv_to(PyObject *o, cv::flann::IndexParams& p, const char *name)
{
(void)name;
bool ok = true;
PyObject* key = NULL;
PyObject* item = NULL;
Py_ssize_t pos = 0;
if(PyDict_Check(o)) {
while(PyDict_Next(o, &pos, &key, &item)) {
if( !PyString_Check(key) ) {
ok = false;
break;
}
String k = PyString_AsString(key);
if( PyString_Check(item) )
{
const char* value = PyString_AsString(item);
p.setString(k, value);
}
else if( !!PyBool_Check(item) )
p.setBool(k, item == Py_True);
else if( PyInt_Check(item) )
{
int value = (int)PyInt_AsLong(item);
if( strcmp(k.c_str(), "algorithm") == 0 )
p.setAlgorithm(value);
else
p.setInt(k, value);
}
else if( PyFloat_Check(item) )
{
double value = PyFloat_AsDouble(item);
p.setDouble(k, value);
}
else
{
ok = false;
break;
}
}
}
return ok && !PyErr_Occurred();
}
template<>
bool pyopencv_to(PyObject* obj, cv::flann::SearchParams & value, const char * name)
{
return pyopencv_to<cv::flann::IndexParams>(obj, value, name);
}
template<>
bool pyopencv_to(PyObject *o, cvflann::flann_distance_t& dist, const char *name)
{
int d = (int)dist;
bool ok = pyopencv_to(o, d, name);
dist = (cvflann::flann_distance_t)d;
return ok;
}
#endif

View File

@ -0,0 +1,22 @@
template<>
bool pyopencv_to(PyObject *obj, CvTermCriteria& dst, const char *name)
{
(void)name;
if(!obj)
return true;
return PyArg_ParseTuple(obj, "iid", &dst.type, &dst.max_iter, &dst.epsilon) > 0;
}
template<>
bool pyopencv_to(PyObject* obj, CvSlice& r, const char* name)
{
(void)name;
if(!obj || obj == Py_None)
return true;
if(PyObject_Size(obj) == 0)
{
r = CV_WHOLE_SEQ;
return true;
}
return PyArg_ParseTuple(obj, "ii", &r.start_index, &r.end_index) > 0;
}

View File

@ -24,8 +24,11 @@ foreach(m ${OPENCV_MODULES_BUILD})
endforeach()
set(opencv_hdrs "")
set(opencv_userdef_hdrs "")
foreach(m ${OPENCV_PYTHON_MODULES})
list(APPEND opencv_hdrs ${OPENCV_MODULE_${m}_HEADERS})
file(GLOB userdef_hdrs ${OPENCV_MODULE_${m}_LOCATION}/misc/python/pyopencv*.hpp)
list(APPEND opencv_userdef_hdrs ${userdef_hdrs})
endforeach(m)
# header blacklist
@ -52,7 +55,13 @@ add_custom_command(
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/headers.txt
DEPENDS ${opencv_hdrs})
ocv_add_library(${the_module} MODULE ${PYTHON_SOURCE_DIR}/src2/cv2.cpp ${cv2_generated_hdrs})
set(cv2_custom_hdr "${CMAKE_CURRENT_BINARY_DIR}/pyopencv_custom_headers.h")
file(WRITE ${cv2_custom_hdr} "//user-defined headers\n")
foreach(uh ${opencv_userdef_hdrs})
file(APPEND ${cv2_custom_hdr} "#include \"${uh}\"\n")
endforeach(uh)
ocv_add_library(${the_module} MODULE ${PYTHON_SOURCE_DIR}/src2/cv2.cpp ${cv2_generated_hdrs} ${opencv_userdef_hdrs} ${cv2_custom_hdr})
if(APPLE)
set_target_properties(${the_module} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")

View File

@ -111,19 +111,6 @@ typedef std::vector<std::vector<Point2f> > vector_vector_Point2f;
typedef std::vector<std::vector<Point3f> > vector_vector_Point3f;
typedef std::vector<std::vector<DMatch> > vector_vector_DMatch;
#ifdef HAVE_OPENCV_FEATURES2D
typedef SimpleBlobDetector::Params SimpleBlobDetector_Params;
#endif
#ifdef HAVE_OPENCV_FLANN
typedef cvflann::flann_distance_t cvflann_flann_distance_t;
typedef cvflann::flann_algorithm_t cvflann_flann_algorithm_t;
#endif
#ifdef HAVE_OPENCV_STITCHING
typedef Stitcher::Status Status;
#endif
static PyObject* failmsgp(const char *fmt, ...)
{
char str[1000];
@ -469,14 +456,6 @@ PyObject* pyopencv_from(const bool& value)
return PyBool_FromLong(value);
}
#ifdef HAVE_OPENCV_STITCHING
template<>
PyObject* pyopencv_from(const Status& value)
{
return PyInt_FromLong(value);
}
#endif
template<>
bool pyopencv_to(PyObject* obj, bool& value, const char* name)
{
@ -512,20 +491,6 @@ PyObject* pyopencv_from(const int& value)
return PyInt_FromLong(value);
}
#ifdef HAVE_OPENCV_FLANN
template<>
PyObject* pyopencv_from(const cvflann_flann_algorithm_t& value)
{
return PyInt_FromLong(int(value));
}
template<>
PyObject* pyopencv_from(const cvflann_flann_distance_t& value)
{
return PyInt_FromLong(int(value));
}
#endif
template<>
bool pyopencv_to(PyObject* obj, int& value, const char* name)
{
@ -1094,62 +1059,6 @@ PyObject* pyopencv_from(const Moments& m)
"nu30", m.nu30, "nu21", m.nu21, "nu12", m.nu12, "nu03", m.nu03);
}
#ifdef HAVE_OPENCV_FLANN
template<>
bool pyopencv_to(PyObject *o, cv::flann::IndexParams& p, const char *name)
{
(void)name;
bool ok = true;
PyObject* key = NULL;
PyObject* item = NULL;
Py_ssize_t pos = 0;
if(PyDict_Check(o)) {
while(PyDict_Next(o, &pos, &key, &item)) {
if( !PyString_Check(key) ) {
ok = false;
break;
}
String k = PyString_AsString(key);
if( PyString_Check(item) )
{
const char* value = PyString_AsString(item);
p.setString(k, value);
}
else if( !!PyBool_Check(item) )
p.setBool(k, item == Py_True);
else if( PyInt_Check(item) )
{
int value = (int)PyInt_AsLong(item);
if( strcmp(k.c_str(), "algorithm") == 0 )
p.setAlgorithm(value);
else
p.setInt(k, value);
}
else if( PyFloat_Check(item) )
{
double value = PyFloat_AsDouble(item);
p.setDouble(k, value);
}
else
{
ok = false;
break;
}
}
}
return ok && !PyErr_Occurred();
}
template<>
bool pyopencv_to(PyObject* obj, cv::flann::SearchParams & value, const char * name)
{
return pyopencv_to<cv::flann::IndexParams>(obj, value, name);
}
#endif
template <typename T>
bool pyopencv_to(PyObject *o, Ptr<T>& p, const char *name)
{
@ -1157,45 +1066,7 @@ bool pyopencv_to(PyObject *o, Ptr<T>& p, const char *name)
return pyopencv_to(o, *p, name);
}
#ifdef HAVE_OPENCV_FLANN
template<>
bool pyopencv_to(PyObject *o, cvflann::flann_distance_t& dist, const char *name)
{
int d = (int)dist;
bool ok = pyopencv_to(o, d, name);
dist = (cvflann::flann_distance_t)d;
return ok;
}
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////
// TODO: REMOVE used only by ml wrapper
template<>
bool pyopencv_to(PyObject *obj, CvTermCriteria& dst, const char *name)
{
(void)name;
if(!obj)
return true;
return PyArg_ParseTuple(obj, "iid", &dst.type, &dst.max_iter, &dst.epsilon) > 0;
}
template<>
bool pyopencv_to(PyObject* obj, CvSlice& r, const char* name)
{
(void)name;
if(!obj || obj == Py_None)
return true;
if(PyObject_Size(obj) == 0)
{
r = CV_WHOLE_SEQ;
return true;
}
return PyArg_ParseTuple(obj, "ii", &r.start_index, &r.end_index) > 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
#include "pyopencv_custom_headers.h"
static void OnMouse(int event, int x, int y, int flags, void* param)
{

View File

@ -30,7 +30,7 @@ gen_template_call_constructor = Template("""self->v.reset(new ${cname}${args})""
gen_template_simple_call_constructor_prelude = Template("""self = PyObject_NEW(pyopencv_${name}_t, &pyopencv_${name}_Type);
if(self) """)
gen_template_simple_call_constructor = Template("""self->v = ${cname}${args}""")
gen_template_simple_call_constructor = Template("""new (&(self->v)) ${cname}${args}""")
gen_template_parse_args = Template("""const char* keywords[] = { $kw_list, NULL };
if( PyArg_ParseTupleAndKeywords(args, kw, "$fmtspec", (char**)keywords, $parse_arglist)$code_cvt )""")
@ -74,13 +74,14 @@ static PyTypeObject pyopencv_${name}_Type =
static void pyopencv_${name}_dealloc(PyObject* self)
{
((pyopencv_${name}_t*)self)->v.${cname}::~${sname}();
PyObject_Del(self);
}
template<> PyObject* pyopencv_from(const ${cname}& r)
{
pyopencv_${name}_t *m = PyObject_NEW(pyopencv_${name}_t, &pyopencv_${name}_Type);
m->v = r;
new (&m->v) ${cname}(r); //Copy constructor
return (PyObject*)m;
}
@ -258,6 +259,7 @@ class ClassInfo(object):
def __init__(self, name, decl=None):
self.cname = name.replace(".", "::")
self.name = self.wname = normalize_class_name(name)
self.sname = name[name.rfind('.') + 1:]
self.ismap = False
self.issimple = False
self.isalgorithm = False
@ -904,7 +906,7 @@ 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, sname=classinfo.sname,
cname1=("cv::Algorithm" if classinfo.isalgorithm else classinfo.cname)))
# register classes in the same order as they have been declared.

View File

@ -0,0 +1,9 @@
#ifdef HAVE_OPENCV_STITCHING
typedef Stitcher::Status Status;
template<>
PyObject* pyopencv_from(const Status& value)
{
return PyInt_FromLong(value);
}
#endif