mirror of
https://github.com/opencv/opencv.git
synced 2024-11-29 13:47:32 +08:00
Merge pull request #14736 from mshabunin:minimal-python-3
This commit is contained in:
commit
b3e6c97d98
@ -21,16 +21,19 @@ bool pyopencv_to(PyObject *o, dnn::DictValue &dv, const char *name)
|
|||||||
}
|
}
|
||||||
else if (PyFloat_Check(o))
|
else if (PyFloat_Check(o))
|
||||||
{
|
{
|
||||||
dv = dnn::DictValue(PyFloat_AS_DOUBLE(o));
|
dv = dnn::DictValue(PyFloat_AsDouble(o));
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (PyString_Check(o))
|
|
||||||
{
|
|
||||||
dv = dnn::DictValue(String(PyString_AsString(o)));
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return false;
|
{
|
||||||
|
std::string str;
|
||||||
|
if (getUnicodeString(o, str))
|
||||||
|
{
|
||||||
|
dv = dnn::DictValue(str);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
@ -134,7 +137,7 @@ public:
|
|||||||
|
|
||||||
PyObject* args = PyList_New(inputs.size());
|
PyObject* args = PyList_New(inputs.size());
|
||||||
for(size_t i = 0; i < inputs.size(); ++i)
|
for(size_t i = 0; i < inputs.size(); ++i)
|
||||||
PyList_SET_ITEM(args, i, pyopencv_from_generic_vec(inputs[i]));
|
PyList_SetItem(args, i, pyopencv_from_generic_vec(inputs[i]));
|
||||||
|
|
||||||
PyObject* res = PyObject_CallMethodObjArgs(o, PyString_FromString("getMemoryShapes"), args, NULL);
|
PyObject* res = PyObject_CallMethodObjArgs(o, PyString_FromString("getMemoryShapes"), args, NULL);
|
||||||
Py_DECREF(args);
|
Py_DECREF(args);
|
||||||
|
@ -27,20 +27,20 @@ bool pyopencv_to(PyObject *o, cv::flann::IndexParams& p, const char *name)
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
if(PyDict_Check(o)) {
|
if(PyDict_Check(o)) {
|
||||||
while(PyDict_Next(o, &pos, &key, &item)) {
|
while(PyDict_Next(o, &pos, &key, &item))
|
||||||
if( !PyString_Check(key) ) {
|
{
|
||||||
|
// get key
|
||||||
|
std::string k;
|
||||||
|
if (!getUnicodeString(key, k))
|
||||||
|
{
|
||||||
ok = false;
|
ok = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// get value
|
||||||
String k = PyString_AsString(key);
|
if( !!PyBool_Check(item) )
|
||||||
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);
|
p.setBool(k, item == Py_True);
|
||||||
|
}
|
||||||
else if( PyInt_Check(item) )
|
else if( PyInt_Check(item) )
|
||||||
{
|
{
|
||||||
int value = (int)PyInt_AsLong(item);
|
int value = (int)PyInt_AsLong(item);
|
||||||
@ -56,8 +56,13 @@ bool pyopencv_to(PyObject *o, cv::flann::IndexParams& p, const char *name)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ok = false;
|
std::string val_str;
|
||||||
break;
|
if (!getUnicodeString(item, val_str))
|
||||||
|
{
|
||||||
|
ok = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
p.setString(k, val_str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -79,4 +84,4 @@ bool pyopencv_to(PyObject *o, cvflann::flann_distance_t& dist, const char *name)
|
|||||||
dist = (cvflann::flann_distance_t)d;
|
dist = (cvflann::flann_distance_t)d;
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -51,11 +51,13 @@ if(NOT HAVE_CUDA)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(cv2_generated_files
|
set(cv2_generated_files
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_include.h"
|
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_enums.h"
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_funcs.h"
|
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_funcs.h"
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_include.h"
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_modules.h"
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_modules_content.h"
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_types.h"
|
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_types.h"
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_type_reg.h"
|
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_types_content.h"
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_ns_reg.h"
|
|
||||||
"${OPENCV_PYTHON_SIGNATURES_FILE}"
|
"${OPENCV_PYTHON_SIGNATURES_FILE}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -24,6 +24,22 @@ if(TARGET gen_opencv_python_source)
|
|||||||
add_dependencies(${the_module} gen_opencv_python_source)
|
add_dependencies(${the_module} gen_opencv_python_source)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
ocv_assert(${PYTHON}_VERSION_MAJOR)
|
||||||
|
ocv_assert(${PYTHON}_VERSION_MINOR)
|
||||||
|
|
||||||
|
if(${PYTHON}_LIMITED_API)
|
||||||
|
# support only python3.3+
|
||||||
|
ocv_assert(${PYTHON}_VERSION_MAJOR EQUAL 3 AND ${PYTHON}_VERSION_MINOR GREATER 2)
|
||||||
|
target_compile_definitions(${the_module} PRIVATE CVPY_DYNAMIC_INIT)
|
||||||
|
if(WIN32)
|
||||||
|
string(REPLACE
|
||||||
|
"python${${PYTHON}_VERSION_MAJOR}${${PYTHON}_VERSION_MINOR}.lib"
|
||||||
|
"python${${PYTHON}_VERSION_MAJOR}.lib"
|
||||||
|
${PYTHON}_LIBRARIES
|
||||||
|
"${${PYTHON}_LIBRARIES}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
set_target_properties(${the_module} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
|
set_target_properties(${the_module} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
|
||||||
elseif(WIN32 OR OPENCV_FORCE_PYTHON_LIBS)
|
elseif(WIN32 OR OPENCV_FORCE_PYTHON_LIBS)
|
||||||
@ -54,6 +70,13 @@ else()
|
|||||||
if(NOT PYTHON_CVPY_PROCESS EQUAL 0)
|
if(NOT PYTHON_CVPY_PROCESS EQUAL 0)
|
||||||
set(CVPY_SUFFIX ".so")
|
set(CVPY_SUFFIX ".so")
|
||||||
endif()
|
endif()
|
||||||
|
if(${PYTHON}_LIMITED_API)
|
||||||
|
if(WIN32)
|
||||||
|
string(REGEX REPLACE "\\.[^\\.]*\\." "." CVPY_SUFFIX "${CVPY_SUFFIX}")
|
||||||
|
else()
|
||||||
|
string(REGEX REPLACE "\\.[^\\.]*\\." ".abi${${PYTHON}_VERSION_MAJOR}." CVPY_SUFFIX "${CVPY_SUFFIX}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
ocv_update(OPENCV_PYTHON_EXTENSION_BUILD_PATH "${LIBRARY_OUTPUT_PATH}/${MODULE_INSTALL_SUBDIR}")
|
ocv_update(OPENCV_PYTHON_EXTENSION_BUILD_PATH "${LIBRARY_OUTPUT_PATH}/${MODULE_INSTALL_SUBDIR}")
|
||||||
@ -111,9 +134,6 @@ else()
|
|||||||
set(PYTHON_INSTALL_ARCHIVE ARCHIVE DESTINATION ${${PYTHON}_PACKAGES_PATH} COMPONENT python)
|
set(PYTHON_INSTALL_ARCHIVE ARCHIVE DESTINATION ${${PYTHON}_PACKAGES_PATH} COMPONENT python)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
ocv_assert(${PYTHON}_VERSION_MAJOR)
|
|
||||||
ocv_assert(${PYTHON}_VERSION_MINOR)
|
|
||||||
|
|
||||||
set(__python_loader_subdir "")
|
set(__python_loader_subdir "")
|
||||||
if(NOT OPENCV_SKIP_PYTHON_LOADER)
|
if(NOT OPENCV_SKIP_PYTHON_LOADER)
|
||||||
set(__python_loader_subdir "cv2/")
|
set(__python_loader_subdir "cv2/")
|
||||||
|
@ -2,6 +2,14 @@ if(NOT PYTHON3_INCLUDE_PATH OR NOT PYTHON3_NUMPY_INCLUDE_DIRS)
|
|||||||
ocv_module_disable(python3)
|
ocv_module_disable(python3)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Problem in numpy >=1.15 <1.17
|
||||||
|
if(PYTHON3_LIMITED_API
|
||||||
|
AND NOT PYTHON3_NUMPY_VERSION VERSION_LESS "1.15"
|
||||||
|
AND PYTHON3_NUMPY_VERSION VERSION_LESS "1.17"
|
||||||
|
)
|
||||||
|
set(PYTHON3_LIMITED_API OFF)
|
||||||
|
endif()
|
||||||
|
|
||||||
set(the_description "The python3 bindings")
|
set(the_description "The python3 bindings")
|
||||||
set(MODULE_NAME python3)
|
set(MODULE_NAME python3)
|
||||||
set(MODULE_INSTALL_SUBDIR python3)
|
set(MODULE_INSTALL_SUBDIR python3)
|
||||||
|
@ -5,12 +5,35 @@
|
|||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable:5033) // 'register' is no longer a supported storage class
|
#pragma warning(disable:5033) // 'register' is no longer a supported storage class
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// #define CVPY_DYNAMIC_INIT
|
||||||
|
// #define Py_DEBUG
|
||||||
|
|
||||||
|
#if defined(CVPY_DYNAMIC_INIT) && !defined(Py_DEBUG)
|
||||||
|
# define Py_LIMITED_API 0x03030000
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
|
|
||||||
|
#if PY_MAJOR_VERSION < 3
|
||||||
|
#undef CVPY_DYNAMIC_INIT
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(_MSC_VER) && (_MSC_VER > 1800)
|
#if defined(_MSC_VER) && (_MSC_VER > 1800)
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define MODULESTR "cv2"
|
||||||
|
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
|
||||||
|
#include <numpy/ndarrayobject.h>
|
||||||
|
|
||||||
|
#include "pyopencv_generated_include.h"
|
||||||
|
#include "opencv2/core/types_c.h"
|
||||||
|
#include "opencv2/opencv_modules.hpp"
|
||||||
|
#include "pycompat.hpp"
|
||||||
|
#include <map>
|
||||||
|
|
||||||
template<typename T, class TEnable = void> // TEnable is used for SFINAE checks
|
template<typename T, class TEnable = void> // TEnable is used for SFINAE checks
|
||||||
struct PyOpenCV_Converter
|
struct PyOpenCV_Converter
|
||||||
{
|
{
|
||||||
@ -24,95 +47,6 @@ bool pyopencv_to(PyObject* obj, T& p, const char* name = "<unknown>") { return P
|
|||||||
template<typename T> static
|
template<typename T> static
|
||||||
PyObject* pyopencv_from(const T& src) { return PyOpenCV_Converter<T>::from(src); }
|
PyObject* pyopencv_from(const T& src) { return PyOpenCV_Converter<T>::from(src); }
|
||||||
|
|
||||||
|
|
||||||
#define CV_PY_FN_WITH_KW_(fn, flags) (PyCFunction)(void*)(PyCFunctionWithKeywords)(fn), (flags) | METH_VARARGS | METH_KEYWORDS
|
|
||||||
#define CV_PY_FN_NOARGS_(fn, flags) (PyCFunction)(fn), (flags) | METH_NOARGS
|
|
||||||
|
|
||||||
#define CV_PY_FN_WITH_KW(fn) CV_PY_FN_WITH_KW_(fn, 0)
|
|
||||||
#define CV_PY_FN_NOARGS(fn) CV_PY_FN_NOARGS_(fn, 0)
|
|
||||||
|
|
||||||
|
|
||||||
#define MODULESTR "cv2"
|
|
||||||
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
|
|
||||||
#include <numpy/ndarrayobject.h>
|
|
||||||
|
|
||||||
#if PY_MAJOR_VERSION >= 3
|
|
||||||
# define CV_PYTHON_TYPE_HEAD_INIT() PyVarObject_HEAD_INIT(&PyType_Type, 0)
|
|
||||||
#else
|
|
||||||
# define CV_PYTHON_TYPE_HEAD_INIT() PyObject_HEAD_INIT(&PyType_Type) 0,
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CV_PY_TO_CLASS(TYPE) \
|
|
||||||
template<> \
|
|
||||||
bool pyopencv_to(PyObject* dst, TYPE& src, const char* name) \
|
|
||||||
{ \
|
|
||||||
if (!dst || dst == Py_None) \
|
|
||||||
return true; \
|
|
||||||
Ptr<TYPE> ptr; \
|
|
||||||
\
|
|
||||||
if (!pyopencv_to(dst, ptr, name)) return false; \
|
|
||||||
src = *ptr; \
|
|
||||||
return true; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define CV_PY_FROM_CLASS(TYPE) \
|
|
||||||
template<> \
|
|
||||||
PyObject* pyopencv_from(const TYPE& src) \
|
|
||||||
{ \
|
|
||||||
Ptr<TYPE> ptr(new TYPE()); \
|
|
||||||
\
|
|
||||||
*ptr = src; \
|
|
||||||
return pyopencv_from(ptr); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define CV_PY_TO_CLASS_PTR(TYPE) \
|
|
||||||
template<> \
|
|
||||||
bool pyopencv_to(PyObject* dst, TYPE*& src, const char* name) \
|
|
||||||
{ \
|
|
||||||
if (!dst || dst == Py_None) \
|
|
||||||
return true; \
|
|
||||||
Ptr<TYPE> ptr; \
|
|
||||||
\
|
|
||||||
if (!pyopencv_to(dst, ptr, name)) return false; \
|
|
||||||
src = ptr; \
|
|
||||||
return true; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define CV_PY_FROM_CLASS_PTR(TYPE) \
|
|
||||||
static PyObject* pyopencv_from(TYPE*& src) \
|
|
||||||
{ \
|
|
||||||
return pyopencv_from(Ptr<TYPE>(src)); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define CV_PY_TO_ENUM(TYPE) \
|
|
||||||
template<> \
|
|
||||||
bool pyopencv_to(PyObject* dst, TYPE& src, const char* name) \
|
|
||||||
{ \
|
|
||||||
if (!dst || dst == Py_None) \
|
|
||||||
return true; \
|
|
||||||
int underlying = 0; \
|
|
||||||
\
|
|
||||||
if (!pyopencv_to(dst, underlying, name)) return false; \
|
|
||||||
src = static_cast<TYPE>(underlying); \
|
|
||||||
return true; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define CV_PY_FROM_ENUM(TYPE) \
|
|
||||||
template<> \
|
|
||||||
PyObject* pyopencv_from(const TYPE& src) \
|
|
||||||
{ \
|
|
||||||
return pyopencv_from(static_cast<int>(src)); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "pyopencv_generated_include.h"
|
|
||||||
#include "opencv2/core/types_c.h"
|
|
||||||
|
|
||||||
#include "opencv2/opencv_modules.hpp"
|
|
||||||
|
|
||||||
#include "pycompat.hpp"
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
static PyObject* opencv_error = NULL;
|
static PyObject* opencv_error = NULL;
|
||||||
|
|
||||||
static int failmsg(const char *fmt, ...)
|
static int failmsg(const char *fmt, ...)
|
||||||
@ -337,7 +271,7 @@ static bool pyopencv_to(PyObject* o, Mat& m, const ArgInfo info)
|
|||||||
m = Mat(sz, 1, CV_64F);
|
m = Mat(sz, 1, CV_64F);
|
||||||
for( i = 0; i < sz; i++ )
|
for( i = 0; i < sz; i++ )
|
||||||
{
|
{
|
||||||
PyObject* oi = PyTuple_GET_ITEM(o, i);
|
PyObject* oi = PyTuple_GetItem(o, i);
|
||||||
if( PyInt_Check(oi) )
|
if( PyInt_Check(oi) )
|
||||||
m.at<double>(i) = (double)PyInt_AsLong(oi);
|
m.at<double>(i) = (double)PyInt_AsLong(oi);
|
||||||
else if( PyFloat_Check(oi) )
|
else if( PyFloat_Check(oi) )
|
||||||
@ -571,21 +505,26 @@ static PyObject* pyopencv_from(void*& ptr)
|
|||||||
return PyLong_FromVoidPtr(ptr);
|
return PyLong_FromVoidPtr(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct SafeSeqItem
|
||||||
|
{
|
||||||
|
PyObject * item;
|
||||||
|
SafeSeqItem(PyObject *obj, size_t idx) { item = PySequence_GetItem(obj, idx); }
|
||||||
|
~SafeSeqItem() { Py_XDECREF(item); }
|
||||||
|
};
|
||||||
|
|
||||||
static bool pyopencv_to(PyObject *o, Scalar& s, const ArgInfo info)
|
static bool pyopencv_to(PyObject *o, Scalar& s, const ArgInfo info)
|
||||||
{
|
{
|
||||||
if(!o || o == Py_None)
|
if(!o || o == Py_None)
|
||||||
return true;
|
return true;
|
||||||
if (PySequence_Check(o)) {
|
if (PySequence_Check(o)) {
|
||||||
PyObject *fi = PySequence_Fast(o, info.name);
|
if (4 < PySequence_Size(o))
|
||||||
if (fi == NULL)
|
|
||||||
return false;
|
|
||||||
if (4 < PySequence_Fast_GET_SIZE(fi))
|
|
||||||
{
|
{
|
||||||
failmsg("Scalar value for argument '%s' is longer than 4", info.name);
|
failmsg("Scalar value for argument '%s' is longer than 4", info.name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) {
|
for (Py_ssize_t i = 0; i < PySequence_Size(o); i++) {
|
||||||
PyObject *item = PySequence_Fast_GET_ITEM(fi, i);
|
SafeSeqItem item_wrap(o, i);
|
||||||
|
PyObject *item = item_wrap.item;
|
||||||
if (PyFloat_Check(item) || PyInt_Check(item)) {
|
if (PyFloat_Check(item) || PyInt_Check(item)) {
|
||||||
s[(int)i] = PyFloat_AsDouble(item);
|
s[(int)i] = PyFloat_AsDouble(item);
|
||||||
} else {
|
} else {
|
||||||
@ -593,7 +532,6 @@ static bool pyopencv_to(PyObject *o, Scalar& s, const ArgInfo info)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Py_DECREF(fi);
|
|
||||||
} else {
|
} else {
|
||||||
if (PyFloat_Check(o) || PyInt_Check(o)) {
|
if (PyFloat_Check(o) || PyInt_Check(o)) {
|
||||||
s[0] = PyFloat_AsDouble(o);
|
s[0] = PyFloat_AsDouble(o);
|
||||||
@ -741,16 +679,18 @@ PyObject* pyopencv_from(const String& value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
bool pyopencv_to(PyObject* obj, String& value, const char* name)
|
bool pyopencv_to(PyObject* obj, String &value, const char* name)
|
||||||
{
|
{
|
||||||
CV_UNUSED(name);
|
CV_UNUSED(name);
|
||||||
if(!obj || obj == Py_None)
|
if(!obj || obj == Py_None)
|
||||||
return true;
|
return true;
|
||||||
const char* str = PyString_AsString(obj);
|
std::string str;
|
||||||
if(!str)
|
if (getUnicodeString(obj, str))
|
||||||
return false;
|
{
|
||||||
value = String(str);
|
value = str;
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
@ -821,36 +761,31 @@ bool pyopencv_to(PyObject* obj, Range& r, const char* name)
|
|||||||
return true;
|
return true;
|
||||||
while (PySequence_Check(obj))
|
while (PySequence_Check(obj))
|
||||||
{
|
{
|
||||||
PyObject *fi = PySequence_Fast(obj, name);
|
if (2 != PySequence_Size(obj))
|
||||||
if (fi == NULL)
|
|
||||||
break;
|
|
||||||
if (2 != PySequence_Fast_GET_SIZE(fi))
|
|
||||||
{
|
{
|
||||||
failmsg("Range value for argument '%s' is longer than 2", name);
|
failmsg("Range value for argument '%s' is longer than 2", name);
|
||||||
Py_DECREF(fi);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
PyObject *item = PySequence_Fast_GET_ITEM(fi, 0);
|
SafeSeqItem item_wrap(obj, 0);
|
||||||
|
PyObject *item = item_wrap.item;
|
||||||
if (PyInt_Check(item)) {
|
if (PyInt_Check(item)) {
|
||||||
r.start = (int)PyInt_AsLong(item);
|
r.start = (int)PyInt_AsLong(item);
|
||||||
} else {
|
} else {
|
||||||
failmsg("Range.start value for argument '%s' is not integer", name);
|
failmsg("Range.start value for argument '%s' is not integer", name);
|
||||||
Py_DECREF(fi);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
PyObject *item = PySequence_Fast_GET_ITEM(fi, 1);
|
SafeSeqItem item_wrap(obj, 1);
|
||||||
|
PyObject *item = item_wrap.item;
|
||||||
if (PyInt_Check(item)) {
|
if (PyInt_Check(item)) {
|
||||||
r.end = (int)PyInt_AsLong(item);
|
r.end = (int)PyInt_AsLong(item);
|
||||||
} else {
|
} else {
|
||||||
failmsg("Range.end value for argument '%s' is not integer", name);
|
failmsg("Range.end value for argument '%s' is not integer", name);
|
||||||
Py_DECREF(fi);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Py_DECREF(fi);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if(PyObject_Size(obj) == 0)
|
if(PyObject_Size(obj) == 0)
|
||||||
@ -873,11 +808,10 @@ bool pyopencv_to(PyObject* obj, Point& p, const char* name)
|
|||||||
CV_UNUSED(name);
|
CV_UNUSED(name);
|
||||||
if(!obj || obj == Py_None)
|
if(!obj || obj == Py_None)
|
||||||
return true;
|
return true;
|
||||||
if(!!PyComplex_CheckExact(obj))
|
if(PyComplex_Check(obj))
|
||||||
{
|
{
|
||||||
Py_complex c = PyComplex_AsCComplex(obj);
|
p.x = saturate_cast<int>(PyComplex_RealAsDouble(obj));
|
||||||
p.x = saturate_cast<int>(c.real);
|
p.y = saturate_cast<int>(PyComplex_ImagAsDouble(obj));
|
||||||
p.y = saturate_cast<int>(c.imag);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return PyArg_ParseTuple(obj, "ii", &p.x, &p.y) > 0;
|
return PyArg_ParseTuple(obj, "ii", &p.x, &p.y) > 0;
|
||||||
@ -889,11 +823,10 @@ bool pyopencv_to(PyObject* obj, Point2f& p, const char* name)
|
|||||||
CV_UNUSED(name);
|
CV_UNUSED(name);
|
||||||
if(!obj || obj == Py_None)
|
if(!obj || obj == Py_None)
|
||||||
return true;
|
return true;
|
||||||
if(!!PyComplex_CheckExact(obj))
|
if (PyComplex_Check(obj))
|
||||||
{
|
{
|
||||||
Py_complex c = PyComplex_AsCComplex(obj);
|
p.x = saturate_cast<float>(PyComplex_RealAsDouble(obj));
|
||||||
p.x = saturate_cast<float>(c.real);
|
p.y = saturate_cast<float>(PyComplex_ImagAsDouble(obj));
|
||||||
p.y = saturate_cast<float>(c.imag);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return PyArg_ParseTuple(obj, "ff", &p.x, &p.y) > 0;
|
return PyArg_ParseTuple(obj, "ff", &p.x, &p.y) > 0;
|
||||||
@ -905,11 +838,10 @@ bool pyopencv_to(PyObject* obj, Point2d& p, const char* name)
|
|||||||
CV_UNUSED(name);
|
CV_UNUSED(name);
|
||||||
if(!obj || obj == Py_None)
|
if(!obj || obj == Py_None)
|
||||||
return true;
|
return true;
|
||||||
if(!!PyComplex_CheckExact(obj))
|
if(PyComplex_Check(obj))
|
||||||
{
|
{
|
||||||
Py_complex c = PyComplex_AsCComplex(obj);
|
p.x = PyComplex_RealAsDouble(obj);
|
||||||
p.x = saturate_cast<double>(c.real);
|
p.y = PyComplex_ImagAsDouble(obj);
|
||||||
p.y = saturate_cast<double>(c.imag);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return PyArg_ParseTuple(obj, "dd", &p.x, &p.y) > 0;
|
return PyArg_ParseTuple(obj, "dd", &p.x, &p.y) > 0;
|
||||||
@ -1136,9 +1068,41 @@ PyObject* pyopencv_from(const Point3d& p)
|
|||||||
|
|
||||||
template<typename _Tp> struct pyopencvVecConverter
|
template<typename _Tp> struct pyopencvVecConverter
|
||||||
{
|
{
|
||||||
|
typedef typename DataType<_Tp>::channel_type _Cp;
|
||||||
|
static inline bool copyOneItem(PyObject *obj, size_t start, int channels, _Cp * data)
|
||||||
|
{
|
||||||
|
for(size_t j = 0; (int)j < channels; j++ )
|
||||||
|
{
|
||||||
|
SafeSeqItem sub_item_wrap(obj, start + j);
|
||||||
|
PyObject* item_ij = sub_item_wrap.item;
|
||||||
|
if( PyInt_Check(item_ij))
|
||||||
|
{
|
||||||
|
int v = (int)PyInt_AsLong(item_ij);
|
||||||
|
if( v == -1 && PyErr_Occurred() )
|
||||||
|
return false;
|
||||||
|
data[j] = saturate_cast<_Cp>(v);
|
||||||
|
}
|
||||||
|
else if( PyLong_Check(item_ij))
|
||||||
|
{
|
||||||
|
int v = (int)PyLong_AsLong(item_ij);
|
||||||
|
if( v == -1 && PyErr_Occurred() )
|
||||||
|
return false;
|
||||||
|
data[j] = saturate_cast<_Cp>(v);
|
||||||
|
}
|
||||||
|
else if( PyFloat_Check(item_ij))
|
||||||
|
{
|
||||||
|
double v = PyFloat_AsDouble(item_ij);
|
||||||
|
if( PyErr_Occurred() )
|
||||||
|
return false;
|
||||||
|
data[j] = saturate_cast<_Cp>(v);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
static bool to(PyObject* obj, std::vector<_Tp>& value, const ArgInfo info)
|
static bool to(PyObject* obj, std::vector<_Tp>& value, const ArgInfo info)
|
||||||
{
|
{
|
||||||
typedef typename DataType<_Tp>::channel_type _Cp;
|
|
||||||
if(!obj || obj == Py_None)
|
if(!obj || obj == Py_None)
|
||||||
return true;
|
return true;
|
||||||
if (PyArray_Check(obj))
|
if (PyArray_Check(obj))
|
||||||
@ -1146,92 +1110,63 @@ template<typename _Tp> struct pyopencvVecConverter
|
|||||||
Mat m;
|
Mat m;
|
||||||
pyopencv_to(obj, m, info);
|
pyopencv_to(obj, m, info);
|
||||||
m.copyTo(value);
|
m.copyTo(value);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
if (!PySequence_Check(obj))
|
else if (PySequence_Check(obj))
|
||||||
return false;
|
|
||||||
PyObject *seq = PySequence_Fast(obj, info.name);
|
|
||||||
if (seq == NULL)
|
|
||||||
return false;
|
|
||||||
int i, j, n = (int)PySequence_Fast_GET_SIZE(seq);
|
|
||||||
value.resize(n);
|
|
||||||
|
|
||||||
int type = traits::Type<_Tp>::value;
|
|
||||||
int depth = CV_MAT_DEPTH(type), channels = CV_MAT_CN(type);
|
|
||||||
PyObject** items = PySequence_Fast_ITEMS(seq);
|
|
||||||
|
|
||||||
for( i = 0; i < n; i++ )
|
|
||||||
{
|
{
|
||||||
PyObject* item = items[i];
|
const int type = traits::Type<_Tp>::value;
|
||||||
PyObject* seq_i = 0;
|
const int depth = CV_MAT_DEPTH(type), channels = CV_MAT_CN(type);
|
||||||
PyObject** items_i = &item;
|
size_t i, n = PySequence_Size(obj);
|
||||||
_Cp* data = (_Cp*)&value[i];
|
value.resize(n);
|
||||||
|
for (i = 0; i < n; i++ )
|
||||||
if( channels == 2 && PyComplex_CheckExact(item) )
|
|
||||||
{
|
{
|
||||||
Py_complex c = PyComplex_AsCComplex(obj);
|
SafeSeqItem item_wrap(obj, i);
|
||||||
data[0] = saturate_cast<_Cp>(c.real);
|
PyObject* item = item_wrap.item;
|
||||||
data[1] = saturate_cast<_Cp>(c.imag);
|
_Cp* data = (_Cp*)&value[i];
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if( channels > 1 )
|
|
||||||
{
|
|
||||||
if( PyArray_Check(item))
|
|
||||||
{
|
|
||||||
Mat src;
|
|
||||||
pyopencv_to(item, src, info);
|
|
||||||
if( src.dims != 2 || src.channels() != 1 ||
|
|
||||||
((src.cols != 1 || src.rows != channels) &&
|
|
||||||
(src.cols != channels || src.rows != 1)))
|
|
||||||
break;
|
|
||||||
Mat dst(src.rows, src.cols, depth, data);
|
|
||||||
src.convertTo(dst, type);
|
|
||||||
if( dst.data != (uchar*)data )
|
|
||||||
break;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
seq_i = PySequence_Fast(item, info.name);
|
if( channels == 2 && PyComplex_Check(item) )
|
||||||
if( !seq_i || (int)PySequence_Fast_GET_SIZE(seq_i) != channels )
|
|
||||||
{
|
{
|
||||||
Py_XDECREF(seq_i);
|
data[0] = saturate_cast<_Cp>(PyComplex_RealAsDouble(item));
|
||||||
break;
|
data[1] = saturate_cast<_Cp>(PyComplex_ImagAsDouble(item));
|
||||||
}
|
}
|
||||||
items_i = PySequence_Fast_ITEMS(seq_i);
|
else if( channels > 1 )
|
||||||
}
|
|
||||||
|
|
||||||
for( j = 0; j < channels; j++ )
|
|
||||||
{
|
|
||||||
PyObject* item_ij = items_i[j];
|
|
||||||
if( PyInt_Check(item_ij))
|
|
||||||
{
|
{
|
||||||
int v = (int)PyInt_AsLong(item_ij);
|
if( PyArray_Check(item))
|
||||||
if( v == -1 && PyErr_Occurred() )
|
{
|
||||||
|
Mat src;
|
||||||
|
pyopencv_to(item, src, info);
|
||||||
|
if( src.dims != 2 || src.channels() != 1 ||
|
||||||
|
((src.cols != 1 || src.rows != channels) &&
|
||||||
|
(src.cols != channels || src.rows != 1)))
|
||||||
|
break;
|
||||||
|
Mat dst(src.rows, src.cols, depth, data);
|
||||||
|
src.convertTo(dst, type);
|
||||||
|
if( dst.data != (uchar*)data )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (PySequence_Check(item))
|
||||||
|
{
|
||||||
|
if (!copyOneItem(item, 0, channels, data))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
data[j] = saturate_cast<_Cp>(v);
|
}
|
||||||
}
|
}
|
||||||
else if( PyLong_Check(item_ij))
|
else if (channels == 1)
|
||||||
{
|
{
|
||||||
int v = (int)PyLong_AsLong(item_ij);
|
if (!copyOneItem(obj, i, channels, data))
|
||||||
if( v == -1 && PyErr_Occurred() )
|
|
||||||
break;
|
break;
|
||||||
data[j] = saturate_cast<_Cp>(v);
|
|
||||||
}
|
|
||||||
else if( PyFloat_Check(item_ij))
|
|
||||||
{
|
|
||||||
double v = PyFloat_AsDouble(item_ij);
|
|
||||||
if( PyErr_Occurred() )
|
|
||||||
break;
|
|
||||||
data[j] = saturate_cast<_Cp>(v);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Py_XDECREF(seq_i);
|
return i == n;
|
||||||
if( j < channels )
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
Py_DECREF(seq);
|
return false;
|
||||||
return i == n;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject* from(const std::vector<_Tp>& value)
|
static PyObject* from(const std::vector<_Tp>& value)
|
||||||
@ -1263,22 +1198,15 @@ template<typename _Tp> static inline bool pyopencv_to_generic_vec(PyObject* obj,
|
|||||||
return true;
|
return true;
|
||||||
if (!PySequence_Check(obj))
|
if (!PySequence_Check(obj))
|
||||||
return false;
|
return false;
|
||||||
PyObject *seq = PySequence_Fast(obj, info.name);
|
size_t n = PySequence_Size(obj);
|
||||||
if (seq == NULL)
|
|
||||||
return false;
|
|
||||||
int i, n = (int)PySequence_Fast_GET_SIZE(seq);
|
|
||||||
value.resize(n);
|
value.resize(n);
|
||||||
|
for(size_t i = 0; i < n; i++ )
|
||||||
PyObject** items = PySequence_Fast_ITEMS(seq);
|
|
||||||
|
|
||||||
for( i = 0; i < n; i++ )
|
|
||||||
{
|
{
|
||||||
PyObject* item = items[i];
|
SafeSeqItem item_wrap(obj, i);
|
||||||
if(!pyopencv_to(item, value[i], info))
|
if(!pyopencv_to(item_wrap.item, value[i], info))
|
||||||
break;
|
return false;
|
||||||
}
|
}
|
||||||
Py_DECREF(seq);
|
return true;
|
||||||
return i == n;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename _Tp> static inline PyObject* pyopencv_from_generic_vec(const std::vector<_Tp>& value)
|
template<typename _Tp> static inline PyObject* pyopencv_from_generic_vec(const std::vector<_Tp>& value)
|
||||||
@ -1290,7 +1218,7 @@ template<typename _Tp> static inline PyObject* pyopencv_from_generic_vec(const s
|
|||||||
PyObject* item = pyopencv_from(value[i]);
|
PyObject* item = pyopencv_from(value[i]);
|
||||||
if(!item)
|
if(!item)
|
||||||
break;
|
break;
|
||||||
PyList_SET_ITEM(seq, i, item);
|
PyList_SetItem(seq, i, item);
|
||||||
}
|
}
|
||||||
if( i < n )
|
if( i < n )
|
||||||
{
|
{
|
||||||
@ -1669,31 +1597,37 @@ static PyObject *pycvCreateButton(PyObject*, PyObject *args, PyObject *kw)
|
|||||||
|
|
||||||
static int convert_to_char(PyObject *o, char *dst, const char *name = "no_name")
|
static int convert_to_char(PyObject *o, char *dst, const char *name = "no_name")
|
||||||
{
|
{
|
||||||
if (PyString_Check(o) && PyString_Size(o) == 1) {
|
std::string str;
|
||||||
*dst = PyString_AsString(o)[0];
|
if (getUnicodeString(o, str))
|
||||||
return 1;
|
{
|
||||||
} else {
|
*dst = str[0];
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
(*dst) = 0;
|
(*dst) = 0;
|
||||||
return failmsg("Expected single character string for argument '%s'", name);
|
return failmsg("Expected single character string for argument '%s'", name);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PY_MAJOR_VERSION >= 3
|
|
||||||
#define MKTYPE2(NAME) pyopencv_##NAME##_specials(); if (!to_ok(&pyopencv_##NAME##_Type)) return NULL;
|
|
||||||
#else
|
|
||||||
#define MKTYPE2(NAME) pyopencv_##NAME##_specials(); if (!to_ok(&pyopencv_##NAME##_Type)) return
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
# pragma GCC diagnostic ignored "-Wunused-parameter"
|
# pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||||
# pragma GCC diagnostic ignored "-Wmissing-field-initializers"
|
# pragma GCC diagnostic ignored "-Wmissing-field-initializers"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include "pyopencv_generated_enums.h"
|
#include "pyopencv_generated_enums.h"
|
||||||
#include "pyopencv_custom_headers.h"
|
#include "pyopencv_custom_headers.h"
|
||||||
|
|
||||||
|
#ifdef CVPY_DYNAMIC_INIT
|
||||||
|
#define CVPY_TYPE(NAME, STORAGE, SNAME, _1, _2) CVPY_TYPE_DECLARE_DYNAMIC(NAME, STORAGE, SNAME)
|
||||||
|
#else
|
||||||
|
#define CVPY_TYPE(NAME, STORAGE, SNAME, _1, _2) CVPY_TYPE_DECLARE(NAME, STORAGE, SNAME)
|
||||||
|
#endif
|
||||||
#include "pyopencv_generated_types.h"
|
#include "pyopencv_generated_types.h"
|
||||||
|
#undef CVPY_TYPE
|
||||||
|
|
||||||
|
#include "pyopencv_generated_types_content.h"
|
||||||
#include "pyopencv_generated_funcs.h"
|
#include "pyopencv_generated_funcs.h"
|
||||||
|
|
||||||
|
|
||||||
static PyMethodDef special_methods[] = {
|
static PyMethodDef special_methods[] = {
|
||||||
{"redirectError", CV_PY_FN_WITH_KW(pycvRedirectError), "redirectError(onError) -> None"},
|
{"redirectError", CV_PY_FN_WITH_KW(pycvRedirectError), "redirectError(onError) -> None"},
|
||||||
#ifdef HAVE_OPENCV_HIGHGUI
|
#ifdef HAVE_OPENCV_HIGHGUI
|
||||||
@ -1758,23 +1692,90 @@ static void init_submodule(PyObject * root, const char * name, PyMethodDef * met
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "pyopencv_generated_ns_reg.h"
|
#include "pyopencv_generated_modules_content.h"
|
||||||
|
|
||||||
static int to_ok(PyTypeObject *to)
|
static bool init_body(PyObject * m)
|
||||||
{
|
{
|
||||||
to->tp_alloc = PyType_GenericAlloc;
|
#define CVPY_MODULE(NAMESTR, NAME) \
|
||||||
to->tp_new = PyType_GenericNew;
|
init_submodule(m, MODULESTR NAMESTR, methods_##NAME, consts_##NAME)
|
||||||
to->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
|
#include "pyopencv_generated_modules.h"
|
||||||
return (PyType_Ready(to) == 0);
|
#undef CVPY_MODULE
|
||||||
}
|
|
||||||
|
|
||||||
|
#ifdef CVPY_DYNAMIC_INIT
|
||||||
|
#define CVPY_TYPE(NAME, _1, _2, BASE, CONSTRUCTOR) CVPY_TYPE_INIT_DYNAMIC(NAME, return false, BASE, CONSTRUCTOR)
|
||||||
|
PyObject * pyopencv_NoBase_TypePtr = NULL;
|
||||||
|
#else
|
||||||
|
#define CVPY_TYPE(NAME, _1, _2, BASE, CONSTRUCTOR) CVPY_TYPE_INIT_STATIC(NAME, return false, BASE, CONSTRUCTOR)
|
||||||
|
PyTypeObject * pyopencv_NoBase_TypePtr = NULL;
|
||||||
|
#endif
|
||||||
|
#include "pyopencv_generated_types.h"
|
||||||
|
#undef CVPY_TYPE
|
||||||
|
|
||||||
|
PyObject* d = PyModule_GetDict(m);
|
||||||
|
|
||||||
|
|
||||||
|
PyDict_SetItemString(d, "__version__", PyString_FromString(CV_VERSION));
|
||||||
|
|
||||||
|
PyObject *opencv_error_dict = PyDict_New();
|
||||||
|
PyDict_SetItemString(opencv_error_dict, "file", Py_None);
|
||||||
|
PyDict_SetItemString(opencv_error_dict, "func", Py_None);
|
||||||
|
PyDict_SetItemString(opencv_error_dict, "line", Py_None);
|
||||||
|
PyDict_SetItemString(opencv_error_dict, "code", Py_None);
|
||||||
|
PyDict_SetItemString(opencv_error_dict, "msg", Py_None);
|
||||||
|
PyDict_SetItemString(opencv_error_dict, "err", Py_None);
|
||||||
|
opencv_error = PyErr_NewException((char*)MODULESTR".error", NULL, opencv_error_dict);
|
||||||
|
Py_DECREF(opencv_error_dict);
|
||||||
|
PyDict_SetItemString(d, "error", opencv_error);
|
||||||
|
|
||||||
|
|
||||||
|
#define PUBLISH(I) PyDict_SetItemString(d, #I, PyInt_FromLong(I))
|
||||||
|
PUBLISH(CV_8U);
|
||||||
|
PUBLISH(CV_8UC1);
|
||||||
|
PUBLISH(CV_8UC2);
|
||||||
|
PUBLISH(CV_8UC3);
|
||||||
|
PUBLISH(CV_8UC4);
|
||||||
|
PUBLISH(CV_8S);
|
||||||
|
PUBLISH(CV_8SC1);
|
||||||
|
PUBLISH(CV_8SC2);
|
||||||
|
PUBLISH(CV_8SC3);
|
||||||
|
PUBLISH(CV_8SC4);
|
||||||
|
PUBLISH(CV_16U);
|
||||||
|
PUBLISH(CV_16UC1);
|
||||||
|
PUBLISH(CV_16UC2);
|
||||||
|
PUBLISH(CV_16UC3);
|
||||||
|
PUBLISH(CV_16UC4);
|
||||||
|
PUBLISH(CV_16S);
|
||||||
|
PUBLISH(CV_16SC1);
|
||||||
|
PUBLISH(CV_16SC2);
|
||||||
|
PUBLISH(CV_16SC3);
|
||||||
|
PUBLISH(CV_16SC4);
|
||||||
|
PUBLISH(CV_32S);
|
||||||
|
PUBLISH(CV_32SC1);
|
||||||
|
PUBLISH(CV_32SC2);
|
||||||
|
PUBLISH(CV_32SC3);
|
||||||
|
PUBLISH(CV_32SC4);
|
||||||
|
PUBLISH(CV_32F);
|
||||||
|
PUBLISH(CV_32FC1);
|
||||||
|
PUBLISH(CV_32FC2);
|
||||||
|
PUBLISH(CV_32FC3);
|
||||||
|
PUBLISH(CV_32FC4);
|
||||||
|
PUBLISH(CV_64F);
|
||||||
|
PUBLISH(CV_64FC1);
|
||||||
|
PUBLISH(CV_64FC2);
|
||||||
|
PUBLISH(CV_64FC3);
|
||||||
|
PUBLISH(CV_64FC4);
|
||||||
|
#undef PUBLISH
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
#pragma GCC visibility push(default)
|
#pragma GCC visibility push(default)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if PY_MAJOR_VERSION >= 3
|
#if PY_MAJOR_VERSION >= 3
|
||||||
PyMODINIT_FUNC PyInit_cv2();
|
// === Python 3
|
||||||
|
|
||||||
static struct PyModuleDef cv2_moduledef =
|
static struct PyModuleDef cv2_moduledef =
|
||||||
{
|
{
|
||||||
PyModuleDef_HEAD_INIT,
|
PyModuleDef_HEAD_INIT,
|
||||||
@ -1785,92 +1786,24 @@ static struct PyModuleDef cv2_moduledef =
|
|||||||
special_methods
|
special_methods
|
||||||
};
|
};
|
||||||
|
|
||||||
|
PyMODINIT_FUNC PyInit_cv2();
|
||||||
PyObject* PyInit_cv2()
|
PyObject* PyInit_cv2()
|
||||||
#else
|
|
||||||
PyMODINIT_FUNC initcv2();
|
|
||||||
|
|
||||||
void initcv2()
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
import_array();
|
import_array(); // from numpy
|
||||||
|
PyObject* m = PyModule_Create(&cv2_moduledef);
|
||||||
#include "pyopencv_generated_type_reg.h"
|
if (!init_body(m))
|
||||||
|
return NULL;
|
||||||
#if PY_MAJOR_VERSION >= 3
|
|
||||||
PyObject* m = PyModule_Create(&cv2_moduledef);
|
|
||||||
#else
|
|
||||||
PyObject* m = Py_InitModule(MODULESTR, special_methods);
|
|
||||||
#endif
|
|
||||||
init_submodules(m); // from "pyopencv_generated_ns_reg.h"
|
|
||||||
|
|
||||||
PyObject* d = PyModule_GetDict(m);
|
|
||||||
|
|
||||||
PyDict_SetItemString(d, "__version__", PyString_FromString(CV_VERSION));
|
|
||||||
|
|
||||||
PyObject *opencv_error_dict = PyDict_New();
|
|
||||||
PyDict_SetItemString(opencv_error_dict, "file", Py_None);
|
|
||||||
PyDict_SetItemString(opencv_error_dict, "func", Py_None);
|
|
||||||
PyDict_SetItemString(opencv_error_dict, "line", Py_None);
|
|
||||||
PyDict_SetItemString(opencv_error_dict, "code", Py_None);
|
|
||||||
PyDict_SetItemString(opencv_error_dict, "msg", Py_None);
|
|
||||||
PyDict_SetItemString(opencv_error_dict, "err", Py_None);
|
|
||||||
opencv_error = PyErr_NewException((char*)MODULESTR".error", NULL, opencv_error_dict);
|
|
||||||
Py_DECREF(opencv_error_dict);
|
|
||||||
PyDict_SetItemString(d, "error", opencv_error);
|
|
||||||
|
|
||||||
#if PY_MAJOR_VERSION >= 3
|
|
||||||
#define PUBLISH_OBJECT(name, type) Py_INCREF(&type);\
|
|
||||||
PyModule_AddObject(m, name, (PyObject *)&type);
|
|
||||||
#else
|
|
||||||
// Unrolled Py_INCREF(&type) without (PyObject*) cast
|
|
||||||
// due to "warning: dereferencing type-punned pointer will break strict-aliasing rules"
|
|
||||||
#define PUBLISH_OBJECT(name, type) _Py_INC_REFTOTAL _Py_REF_DEBUG_COMMA (&type)->ob_refcnt++;\
|
|
||||||
PyModule_AddObject(m, name, (PyObject *)&type);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "pyopencv_generated_type_publish.h"
|
|
||||||
|
|
||||||
#define PUBLISH(I) PyDict_SetItemString(d, #I, PyInt_FromLong(I))
|
|
||||||
//#define PUBLISHU(I) PyDict_SetItemString(d, #I, PyLong_FromUnsignedLong(I))
|
|
||||||
#define PUBLISH2(I, value) PyDict_SetItemString(d, #I, PyLong_FromLong(value))
|
|
||||||
|
|
||||||
PUBLISH(CV_8U);
|
|
||||||
PUBLISH(CV_8UC1);
|
|
||||||
PUBLISH(CV_8UC2);
|
|
||||||
PUBLISH(CV_8UC3);
|
|
||||||
PUBLISH(CV_8UC4);
|
|
||||||
PUBLISH(CV_8S);
|
|
||||||
PUBLISH(CV_8SC1);
|
|
||||||
PUBLISH(CV_8SC2);
|
|
||||||
PUBLISH(CV_8SC3);
|
|
||||||
PUBLISH(CV_8SC4);
|
|
||||||
PUBLISH(CV_16U);
|
|
||||||
PUBLISH(CV_16UC1);
|
|
||||||
PUBLISH(CV_16UC2);
|
|
||||||
PUBLISH(CV_16UC3);
|
|
||||||
PUBLISH(CV_16UC4);
|
|
||||||
PUBLISH(CV_16S);
|
|
||||||
PUBLISH(CV_16SC1);
|
|
||||||
PUBLISH(CV_16SC2);
|
|
||||||
PUBLISH(CV_16SC3);
|
|
||||||
PUBLISH(CV_16SC4);
|
|
||||||
PUBLISH(CV_32S);
|
|
||||||
PUBLISH(CV_32SC1);
|
|
||||||
PUBLISH(CV_32SC2);
|
|
||||||
PUBLISH(CV_32SC3);
|
|
||||||
PUBLISH(CV_32SC4);
|
|
||||||
PUBLISH(CV_32F);
|
|
||||||
PUBLISH(CV_32FC1);
|
|
||||||
PUBLISH(CV_32FC2);
|
|
||||||
PUBLISH(CV_32FC3);
|
|
||||||
PUBLISH(CV_32FC4);
|
|
||||||
PUBLISH(CV_64F);
|
|
||||||
PUBLISH(CV_64FC1);
|
|
||||||
PUBLISH(CV_64FC2);
|
|
||||||
PUBLISH(CV_64FC3);
|
|
||||||
PUBLISH(CV_64FC4);
|
|
||||||
|
|
||||||
#if PY_MAJOR_VERSION >= 3
|
|
||||||
return m;
|
return m;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
// === Python 2
|
||||||
|
PyMODINIT_FUNC initcv2();
|
||||||
|
void initcv2()
|
||||||
|
{
|
||||||
|
import_array(); // from numpy
|
||||||
|
PyObject* m = Py_InitModule(MODULESTR, special_methods);
|
||||||
|
init_body(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -16,20 +16,12 @@ ignored_arg_types = ["RNG*"]
|
|||||||
|
|
||||||
pass_by_val_types = ["Point*", "Point2f*", "Rect*", "String*", "double*", "float*", "int*"]
|
pass_by_val_types = ["Point*", "Point2f*", "Rect*", "String*", "double*", "float*", "int*"]
|
||||||
|
|
||||||
gen_template_check_self = Template(""" $cname* _self_ = NULL;
|
gen_template_check_self = Template("""
|
||||||
if(PyObject_TypeCheck(self, &pyopencv_${name}_Type))
|
${cname} * self1 = 0;
|
||||||
_self_ = ${amp}((pyopencv_${name}_t*)self)->v${get};
|
if (!pyopencv_${name}_getp(self, self1))
|
||||||
if (!_self_)
|
|
||||||
return failmsgp("Incorrect type of self (must be '${name}' or its derivative)");
|
return failmsgp("Incorrect type of self (must be '${name}' or its derivative)");
|
||||||
|
${pname} _self_ = ${cvt}(self1);
|
||||||
""")
|
""")
|
||||||
|
|
||||||
gen_template_check_self_algo = Template(""" $cname* _self_ = NULL;
|
|
||||||
if(PyObject_TypeCheck(self, &pyopencv_${name}_Type))
|
|
||||||
_self_ = dynamic_cast<$cname*>(${amp}((pyopencv_${name}_t*)self)->v.get());
|
|
||||||
if (!_self_)
|
|
||||||
return failmsgp("Incorrect type of self (must be '${name}' or its derivative)");
|
|
||||||
""")
|
|
||||||
|
|
||||||
gen_template_call_constructor_prelude = Template("""new (&(self->v)) Ptr<$cname>(); // init Ptr with placement new
|
gen_template_call_constructor_prelude = Template("""new (&(self->v)) Ptr<$cname>(); // init Ptr with placement new
|
||||||
if(self) """)
|
if(self) """)
|
||||||
|
|
||||||
@ -50,53 +42,6 @@ gen_template_func_body = Template("""$code_decl
|
|||||||
}
|
}
|
||||||
""")
|
""")
|
||||||
|
|
||||||
head_init_str = "CV_PYTHON_TYPE_HEAD_INIT()"
|
|
||||||
|
|
||||||
gen_template_simple_type_decl = Template("""
|
|
||||||
struct pyopencv_${name}_t
|
|
||||||
{
|
|
||||||
PyObject_HEAD
|
|
||||||
${cname} v;
|
|
||||||
};
|
|
||||||
|
|
||||||
static PyTypeObject pyopencv_${name}_Type =
|
|
||||||
{
|
|
||||||
%s
|
|
||||||
MODULESTR".$wname",
|
|
||||||
sizeof(pyopencv_${name}_t),
|
|
||||||
};
|
|
||||||
|
|
||||||
static void pyopencv_${name}_dealloc(PyObject* self)
|
|
||||||
{
|
|
||||||
((pyopencv_${name}_t*)self)->v.${cname}::~${sname}();
|
|
||||||
PyObject_Del(self);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct PyOpenCV_Converter< ${cname} >
|
|
||||||
{
|
|
||||||
static PyObject* from(const ${cname}& r)
|
|
||||||
{
|
|
||||||
pyopencv_${name}_t *m = PyObject_NEW(pyopencv_${name}_t, &pyopencv_${name}_Type);
|
|
||||||
new (&m->v) ${cname}(r); //Copy constructor
|
|
||||||
return (PyObject*)m;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool to(PyObject* src, ${cname}& dst, const char* name)
|
|
||||||
{
|
|
||||||
if(!src || src == Py_None)
|
|
||||||
return true;
|
|
||||||
if(PyObject_TypeCheck(src, &pyopencv_${name}_Type))
|
|
||||||
{
|
|
||||||
dst = ((pyopencv_${name}_t*)src)->v;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
failmsg("Expected ${cname} for argument '%%s'", name);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
""" % head_init_str)
|
|
||||||
|
|
||||||
gen_template_mappable = Template("""
|
gen_template_mappable = Template("""
|
||||||
{
|
{
|
||||||
${mappable} _src;
|
${mappable} _src;
|
||||||
@ -108,43 +53,23 @@ gen_template_mappable = Template("""
|
|||||||
""")
|
""")
|
||||||
|
|
||||||
gen_template_type_decl = Template("""
|
gen_template_type_decl = Template("""
|
||||||
struct pyopencv_${name}_t
|
// Converter (${name})
|
||||||
{
|
|
||||||
PyObject_HEAD
|
|
||||||
Ptr<${cname1}> v;
|
|
||||||
};
|
|
||||||
|
|
||||||
static PyTypeObject pyopencv_${name}_Type =
|
|
||||||
{
|
|
||||||
%s
|
|
||||||
MODULESTR".$wname",
|
|
||||||
sizeof(pyopencv_${name}_t),
|
|
||||||
};
|
|
||||||
|
|
||||||
static void pyopencv_${name}_dealloc(PyObject* self)
|
|
||||||
{
|
|
||||||
((pyopencv_${name}_t*)self)->v.release();
|
|
||||||
PyObject_Del(self);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct PyOpenCV_Converter< Ptr<${cname}> >
|
struct PyOpenCV_Converter< ${cname} >
|
||||||
{
|
{
|
||||||
static PyObject* from(const Ptr<${cname}>& r)
|
static PyObject* from(const ${cname}& r)
|
||||||
{
|
{
|
||||||
pyopencv_${name}_t *m = PyObject_NEW(pyopencv_${name}_t, &pyopencv_${name}_Type);
|
return pyopencv_${name}_Instance(r);
|
||||||
new (&(m->v)) Ptr<$cname1>(); // init Ptr with placement new
|
|
||||||
m->v = r;
|
|
||||||
return (PyObject*)m;
|
|
||||||
}
|
}
|
||||||
|
static bool to(PyObject* src, ${cname}& dst, const char* name)
|
||||||
static bool to(PyObject* src, Ptr<${cname}>& dst, const char* name)
|
|
||||||
{
|
{
|
||||||
if(!src || src == Py_None)
|
if(!src || src == Py_None)
|
||||||
return true;
|
return true;
|
||||||
if(PyObject_TypeCheck(src, &pyopencv_${name}_Type))
|
${cname} * dst_;
|
||||||
|
if (pyopencv_${name}_getp(src, dst_))
|
||||||
{
|
{
|
||||||
dst = ((pyopencv_${name}_t*)src)->v.dynamicCast<${cname}>();
|
dst = *dst_;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
${mappable_code}
|
${mappable_code}
|
||||||
@ -153,10 +78,11 @@ struct PyOpenCV_Converter< Ptr<${cname}> >
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
""" % head_init_str)
|
""")
|
||||||
|
|
||||||
gen_template_map_type_cvt = Template("""
|
gen_template_map_type_cvt = Template("""
|
||||||
template<> bool pyopencv_to(PyObject* src, ${cname}& dst, const char* name);
|
template<> bool pyopencv_to(PyObject* src, ${cname}& dst, const char* name);
|
||||||
|
|
||||||
""")
|
""")
|
||||||
|
|
||||||
gen_template_set_prop_from_map = Template("""
|
gen_template_set_prop_from_map = Template("""
|
||||||
@ -169,37 +95,26 @@ gen_template_set_prop_from_map = Template("""
|
|||||||
}""")
|
}""")
|
||||||
|
|
||||||
gen_template_type_impl = Template("""
|
gen_template_type_impl = Template("""
|
||||||
static PyObject* pyopencv_${name}_repr(PyObject* self)
|
// GetSet (${name})
|
||||||
{
|
|
||||||
char str[1000];
|
|
||||||
sprintf(str, "<$wname %p>", self);
|
|
||||||
return PyString_FromString(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
${getset_code}
|
${getset_code}
|
||||||
|
|
||||||
|
// Methods (${name})
|
||||||
|
|
||||||
|
${methods_code}
|
||||||
|
|
||||||
|
// Tables (${name})
|
||||||
|
|
||||||
static PyGetSetDef pyopencv_${name}_getseters[] =
|
static PyGetSetDef pyopencv_${name}_getseters[] =
|
||||||
{${getset_inits}
|
{${getset_inits}
|
||||||
{NULL} /* Sentinel */
|
{NULL} /* Sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
${methods_code}
|
|
||||||
|
|
||||||
static PyMethodDef pyopencv_${name}_methods[] =
|
static PyMethodDef pyopencv_${name}_methods[] =
|
||||||
{
|
{
|
||||||
${methods_inits}
|
${methods_inits}
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
static void pyopencv_${name}_specials(void)
|
|
||||||
{
|
|
||||||
pyopencv_${name}_Type.tp_base = ${baseptr};
|
|
||||||
pyopencv_${name}_Type.tp_dealloc = pyopencv_${name}_dealloc;
|
|
||||||
pyopencv_${name}_Type.tp_repr = pyopencv_${name}_repr;
|
|
||||||
pyopencv_${name}_Type.tp_getset = pyopencv_${name}_getseters;
|
|
||||||
pyopencv_${name}_Type.tp_init = (initproc)${constructor};
|
|
||||||
pyopencv_${name}_Type.tp_methods = pyopencv_${name}_methods;${extra_specials}
|
|
||||||
}
|
|
||||||
""")
|
""")
|
||||||
|
|
||||||
|
|
||||||
@ -373,20 +288,29 @@ class ClassInfo(object):
|
|||||||
methods_code.write(m.gen_code(codegen))
|
methods_code.write(m.gen_code(codegen))
|
||||||
methods_inits.write(m.get_tab_entry())
|
methods_inits.write(m.get_tab_entry())
|
||||||
|
|
||||||
baseptr = "NULL"
|
code = gen_template_type_impl.substitute(name=self.name, wname=self.wname, cname=self.cname,
|
||||||
|
getset_code=getset_code.getvalue(), getset_inits=getset_inits.getvalue(),
|
||||||
|
methods_code=methods_code.getvalue(), methods_inits=methods_inits.getvalue())
|
||||||
|
|
||||||
|
return code
|
||||||
|
|
||||||
|
def gen_def(self, codegen):
|
||||||
|
all_classes = codegen.classes
|
||||||
|
baseptr = "NoBase"
|
||||||
if self.base and self.base in all_classes:
|
if self.base and self.base in all_classes:
|
||||||
baseptr = "&pyopencv_" + all_classes[self.base].name + "_Type"
|
baseptr = all_classes[self.base].name
|
||||||
|
|
||||||
constructor_name = "0"
|
constructor_name = "0"
|
||||||
if self.constructor is not None:
|
if self.constructor is not None:
|
||||||
constructor_name = self.constructor.get_wrapper_name()
|
constructor_name = self.constructor.get_wrapper_name()
|
||||||
|
|
||||||
code = gen_template_type_impl.substitute(name=self.name, wname=self.wname, cname=self.cname,
|
return "CVPY_TYPE({}, {}, {}, {}, {});\n".format(
|
||||||
getset_code=getset_code.getvalue(), getset_inits=getset_inits.getvalue(),
|
self.name,
|
||||||
methods_code=methods_code.getvalue(), methods_inits=methods_inits.getvalue(),
|
self.cname if self.issimple else "Ptr<{}>".format(self.cname),
|
||||||
baseptr=baseptr, constructor=constructor_name, extra_specials="")
|
self.sname if self.issimple else "Ptr",
|
||||||
|
baseptr,
|
||||||
return code
|
constructor_name
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def handle_ptr(tp):
|
def handle_ptr(tp):
|
||||||
@ -634,7 +558,7 @@ class FuncInfo(object):
|
|||||||
code = "%s\n{\n" % (proto,)
|
code = "%s\n{\n" % (proto,)
|
||||||
code += " using namespace %s;\n\n" % self.namespace.replace('.', '::')
|
code += " using namespace %s;\n\n" % self.namespace.replace('.', '::')
|
||||||
|
|
||||||
selfinfo = ClassInfo("")
|
selfinfo = None
|
||||||
ismethod = self.classname != "" and not self.isconstructor
|
ismethod = self.classname != "" and not self.isconstructor
|
||||||
# full name is needed for error diagnostic in PyArg_ParseTupleAndKeywords
|
# full name is needed for error diagnostic in PyArg_ParseTupleAndKeywords
|
||||||
fullname = self.name
|
fullname = self.name
|
||||||
@ -642,14 +566,13 @@ class FuncInfo(object):
|
|||||||
if self.classname:
|
if self.classname:
|
||||||
selfinfo = all_classes[self.classname]
|
selfinfo = all_classes[self.classname]
|
||||||
if not self.isconstructor:
|
if not self.isconstructor:
|
||||||
amp = "&" if selfinfo.issimple else ""
|
if not self.is_static:
|
||||||
if self.is_static:
|
code += gen_template_check_self.substitute(
|
||||||
pass
|
name=selfinfo.name,
|
||||||
elif selfinfo.isalgorithm:
|
cname=selfinfo.cname if selfinfo.issimple else "Ptr<{}>".format(selfinfo.cname),
|
||||||
code += gen_template_check_self_algo.substitute(name=selfinfo.name, cname=selfinfo.cname, amp=amp)
|
pname=(selfinfo.cname + '*') if selfinfo.issimple else "Ptr<{}>".format(selfinfo.cname),
|
||||||
else:
|
cvt='' if selfinfo.issimple else '*'
|
||||||
get = "" if selfinfo.issimple else ".get()"
|
)
|
||||||
code += gen_template_check_self.substitute(name=selfinfo.name, cname=selfinfo.cname, amp=amp, get=get)
|
|
||||||
fullname = selfinfo.wname + "." + fullname
|
fullname = selfinfo.wname + "." + fullname
|
||||||
|
|
||||||
all_code_variants = []
|
all_code_variants = []
|
||||||
@ -871,8 +794,8 @@ class PythonWrapperGenerator(object):
|
|||||||
self.code_enums = StringIO()
|
self.code_enums = StringIO()
|
||||||
self.code_types = StringIO()
|
self.code_types = StringIO()
|
||||||
self.code_funcs = StringIO()
|
self.code_funcs = StringIO()
|
||||||
self.code_type_reg = StringIO()
|
|
||||||
self.code_ns_reg = StringIO()
|
self.code_ns_reg = StringIO()
|
||||||
|
self.code_ns_init = StringIO()
|
||||||
self.code_type_publish = StringIO()
|
self.code_type_publish = StringIO()
|
||||||
self.py_signatures = dict()
|
self.py_signatures = dict()
|
||||||
self.class_idx = 0
|
self.class_idx = 0
|
||||||
@ -1013,14 +936,6 @@ class PythonWrapperGenerator(object):
|
|||||||
self.code_ns_reg.write(' {"%s", static_cast<long>(%s)},\n'%(compat_name, cname))
|
self.code_ns_reg.write(' {"%s", static_cast<long>(%s)},\n'%(compat_name, cname))
|
||||||
self.code_ns_reg.write(' {NULL, 0}\n};\n\n')
|
self.code_ns_reg.write(' {NULL, 0}\n};\n\n')
|
||||||
|
|
||||||
def gen_namespaces_reg(self):
|
|
||||||
self.code_ns_reg.write('static void init_submodules(PyObject * root) \n{\n')
|
|
||||||
for ns_name in sorted(self.namespaces):
|
|
||||||
if ns_name.split('.')[0] == 'cv':
|
|
||||||
wname = normalize_class_name(ns_name)
|
|
||||||
self.code_ns_reg.write(' init_submodule(root, MODULESTR"%s", methods_%s, consts_%s);\n' % (ns_name[2:], wname, wname))
|
|
||||||
self.code_ns_reg.write('};\n')
|
|
||||||
|
|
||||||
def gen_enum_reg(self, enum_name):
|
def gen_enum_reg(self, enum_name):
|
||||||
name_seg = enum_name.split(".")
|
name_seg = enum_name.split(".")
|
||||||
is_enum_class = False
|
is_enum_class = False
|
||||||
@ -1113,18 +1028,22 @@ class PythonWrapperGenerator(object):
|
|||||||
classlist = list(self.classes.items())
|
classlist = list(self.classes.items())
|
||||||
classlist.sort()
|
classlist.sort()
|
||||||
for name, classinfo in classlist:
|
for name, classinfo in classlist:
|
||||||
|
self.code_types.write("//{}\n".format(80*"="))
|
||||||
|
self.code_types.write("// {} ({})\n".format(name, 'Map' if classinfo.ismap else 'Generic'))
|
||||||
|
self.code_types.write("//{}\n".format(80*"="))
|
||||||
|
self.code_types.write(classinfo.gen_code(self))
|
||||||
if classinfo.ismap:
|
if classinfo.ismap:
|
||||||
self.code_types.write(gen_template_map_type_cvt.substitute(name=name, cname=classinfo.cname))
|
self.code_types.write(gen_template_map_type_cvt.substitute(name=classinfo.name, cname=classinfo.cname))
|
||||||
else:
|
else:
|
||||||
if classinfo.issimple:
|
|
||||||
templ = gen_template_simple_type_decl
|
|
||||||
else:
|
|
||||||
templ = gen_template_type_decl
|
|
||||||
mappable_code = "\n".join([
|
mappable_code = "\n".join([
|
||||||
gen_template_mappable.substitute(cname=classinfo.cname, mappable=mappable)
|
gen_template_mappable.substitute(cname=classinfo.cname, mappable=mappable)
|
||||||
for mappable in classinfo.mappables])
|
for mappable in classinfo.mappables])
|
||||||
self.code_types.write(templ.substitute(name=name, wname=classinfo.wname, cname=classinfo.cname, sname=classinfo.sname,
|
code = gen_template_type_decl.substitute(
|
||||||
cname1=("cv::Algorithm" if classinfo.isalgorithm else classinfo.cname), mappable_code=mappable_code))
|
name=classinfo.name,
|
||||||
|
cname=classinfo.cname if classinfo.issimple else "Ptr<{}>".format(classinfo.cname),
|
||||||
|
mappable_code=mappable_code
|
||||||
|
)
|
||||||
|
self.code_types.write(code)
|
||||||
|
|
||||||
# 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.
|
||||||
@ -1132,11 +1051,10 @@ class PythonWrapperGenerator(object):
|
|||||||
classlist1.sort()
|
classlist1.sort()
|
||||||
|
|
||||||
for decl_idx, name, classinfo in classlist1:
|
for decl_idx, name, classinfo in classlist1:
|
||||||
code = classinfo.gen_code(self)
|
if classinfo.ismap:
|
||||||
self.code_types.write(code)
|
continue
|
||||||
if not classinfo.ismap:
|
self.code_type_publish.write(classinfo.gen_def(self))
|
||||||
self.code_type_reg.write("MKTYPE2(%s);\n" % (classinfo.name,) )
|
|
||||||
self.code_type_publish.write("PUBLISH_OBJECT(\"{name}\", pyopencv_{name}_Type);\n".format(name=classinfo.name))
|
|
||||||
|
|
||||||
# step 3: generate the code for all the global functions
|
# step 3: generate the code for all the global functions
|
||||||
for ns_name, ns in sorted(self.namespaces.items()):
|
for ns_name, ns in sorted(self.namespaces.items()):
|
||||||
@ -1148,7 +1066,7 @@ class PythonWrapperGenerator(object):
|
|||||||
code = func.gen_code(self)
|
code = func.gen_code(self)
|
||||||
self.code_funcs.write(code)
|
self.code_funcs.write(code)
|
||||||
self.gen_namespace(ns_name)
|
self.gen_namespace(ns_name)
|
||||||
self.gen_namespaces_reg()
|
self.code_ns_init.write('CVPY_MODULE("{}", {});\n'.format(ns_name[2:], normalize_class_name(ns_name)))
|
||||||
|
|
||||||
# step 4: generate the code for enum types
|
# step 4: generate the code for enum types
|
||||||
enumlist = list(self.enums.values())
|
enumlist = list(self.enums.values())
|
||||||
@ -1166,10 +1084,10 @@ class PythonWrapperGenerator(object):
|
|||||||
self.save(output_path, "pyopencv_generated_include.h", self.code_include)
|
self.save(output_path, "pyopencv_generated_include.h", self.code_include)
|
||||||
self.save(output_path, "pyopencv_generated_funcs.h", self.code_funcs)
|
self.save(output_path, "pyopencv_generated_funcs.h", self.code_funcs)
|
||||||
self.save(output_path, "pyopencv_generated_enums.h", self.code_enums)
|
self.save(output_path, "pyopencv_generated_enums.h", self.code_enums)
|
||||||
self.save(output_path, "pyopencv_generated_types.h", self.code_types)
|
self.save(output_path, "pyopencv_generated_types.h", self.code_type_publish)
|
||||||
self.save(output_path, "pyopencv_generated_type_reg.h", self.code_type_reg)
|
self.save(output_path, "pyopencv_generated_types_content.h", self.code_types)
|
||||||
self.save(output_path, "pyopencv_generated_ns_reg.h", self.code_ns_reg)
|
self.save(output_path, "pyopencv_generated_modules.h", self.code_ns_init)
|
||||||
self.save(output_path, "pyopencv_generated_type_publish.h", self.code_type_publish)
|
self.save(output_path, "pyopencv_generated_modules_content.h", self.code_ns_reg)
|
||||||
self.save_json(output_path, "pyopencv_signatures.json", self.py_signatures)
|
self.save_json(output_path, "pyopencv_signatures.json", self.py_signatures)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
#define __PYCOMPAT_HPP__
|
#define __PYCOMPAT_HPP__
|
||||||
|
|
||||||
#if PY_MAJOR_VERSION >= 3
|
#if PY_MAJOR_VERSION >= 3
|
||||||
|
|
||||||
// Python3 treats all ints as longs, PyInt_X functions have been removed.
|
// Python3 treats all ints as longs, PyInt_X functions have been removed.
|
||||||
#define PyInt_Check PyLong_Check
|
#define PyInt_Check PyLong_Check
|
||||||
#define PyInt_CheckExact PyLong_CheckExact
|
#define PyInt_CheckExact PyLong_CheckExact
|
||||||
@ -53,18 +54,266 @@
|
|||||||
#define PyInt_FromLong PyLong_FromLong
|
#define PyInt_FromLong PyLong_FromLong
|
||||||
#define PyNumber_Int PyNumber_Long
|
#define PyNumber_Int PyNumber_Long
|
||||||
|
|
||||||
// Python3 strings are unicode, these defines mimic the Python2 functionality.
|
|
||||||
#define PyString_Check PyUnicode_Check
|
|
||||||
#define PyString_FromString PyUnicode_FromString
|
#define PyString_FromString PyUnicode_FromString
|
||||||
#define PyString_FromStringAndSize PyUnicode_FromStringAndSize
|
#define PyString_FromStringAndSize PyUnicode_FromStringAndSize
|
||||||
#define PyString_Size PyUnicode_GET_SIZE
|
|
||||||
|
|
||||||
// PyUnicode_AsUTF8 isn't available until Python 3.3
|
#endif // PY_MAJOR >=3
|
||||||
#if (PY_VERSION_HEX < 0x03030000)
|
|
||||||
#define PyString_AsString _PyUnicode_AsString
|
static inline bool getUnicodeString(PyObject * obj, std::string &str)
|
||||||
|
{
|
||||||
|
bool res = false;
|
||||||
|
if (PyUnicode_Check(obj))
|
||||||
|
{
|
||||||
|
PyObject * bytes = PyUnicode_AsUTF8String(obj);
|
||||||
|
if (PyBytes_Check(bytes))
|
||||||
|
{
|
||||||
|
const char * raw = PyBytes_AsString(bytes);
|
||||||
|
if (raw)
|
||||||
|
{
|
||||||
|
str = std::string(raw);
|
||||||
|
res = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Py_XDECREF(bytes);
|
||||||
|
}
|
||||||
|
#if PY_MAJOR_VERSION < 3
|
||||||
|
else if (PyString_Check(obj))
|
||||||
|
{
|
||||||
|
const char * raw = PyString_AsString(obj);
|
||||||
|
if (raw)
|
||||||
|
{
|
||||||
|
str = std::string(raw);
|
||||||
|
res = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================================================
|
||||||
|
|
||||||
|
#define CV_PY_FN_WITH_KW_(fn, flags) (PyCFunction)(void*)(PyCFunctionWithKeywords)(fn), (flags) | METH_VARARGS | METH_KEYWORDS
|
||||||
|
#define CV_PY_FN_NOARGS_(fn, flags) (PyCFunction)(fn), (flags) | METH_NOARGS
|
||||||
|
|
||||||
|
#define CV_PY_FN_WITH_KW(fn) CV_PY_FN_WITH_KW_(fn, 0)
|
||||||
|
#define CV_PY_FN_NOARGS(fn) CV_PY_FN_NOARGS_(fn, 0)
|
||||||
|
|
||||||
|
#define CV_PY_TO_CLASS(TYPE) \
|
||||||
|
template<> \
|
||||||
|
bool pyopencv_to(PyObject* dst, TYPE& src, const char* name) \
|
||||||
|
{ \
|
||||||
|
if (!dst || dst == Py_None) \
|
||||||
|
return true; \
|
||||||
|
Ptr<TYPE> ptr; \
|
||||||
|
\
|
||||||
|
if (!pyopencv_to(dst, ptr, name)) return false; \
|
||||||
|
src = *ptr; \
|
||||||
|
return true; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CV_PY_FROM_CLASS(TYPE) \
|
||||||
|
template<> \
|
||||||
|
PyObject* pyopencv_from(const TYPE& src) \
|
||||||
|
{ \
|
||||||
|
Ptr<TYPE> ptr(new TYPE()); \
|
||||||
|
\
|
||||||
|
*ptr = src; \
|
||||||
|
return pyopencv_from(ptr); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CV_PY_TO_CLASS_PTR(TYPE) \
|
||||||
|
template<> \
|
||||||
|
bool pyopencv_to(PyObject* dst, TYPE*& src, const char* name) \
|
||||||
|
{ \
|
||||||
|
if (!dst || dst == Py_None) \
|
||||||
|
return true; \
|
||||||
|
Ptr<TYPE> ptr; \
|
||||||
|
\
|
||||||
|
if (!pyopencv_to(dst, ptr, name)) return false; \
|
||||||
|
src = ptr; \
|
||||||
|
return true; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CV_PY_FROM_CLASS_PTR(TYPE) \
|
||||||
|
static PyObject* pyopencv_from(TYPE*& src) \
|
||||||
|
{ \
|
||||||
|
return pyopencv_from(Ptr<TYPE>(src)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CV_PY_TO_ENUM(TYPE) \
|
||||||
|
template<> \
|
||||||
|
bool pyopencv_to(PyObject* dst, TYPE& src, const char* name) \
|
||||||
|
{ \
|
||||||
|
if (!dst || dst == Py_None) \
|
||||||
|
return true; \
|
||||||
|
int underlying = 0; \
|
||||||
|
\
|
||||||
|
if (!pyopencv_to(dst, underlying, name)) return false; \
|
||||||
|
src = static_cast<TYPE>(underlying); \
|
||||||
|
return true; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CV_PY_FROM_ENUM(TYPE) \
|
||||||
|
template<> \
|
||||||
|
PyObject* pyopencv_from(const TYPE& src) \
|
||||||
|
{ \
|
||||||
|
return pyopencv_from(static_cast<int>(src)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================================================
|
||||||
|
|
||||||
|
#if PY_MAJOR_VERSION >= 3
|
||||||
|
#define CVPY_TYPE_HEAD PyVarObject_HEAD_INIT(&PyType_Type, 0)
|
||||||
|
#define CVPY_TYPE_INCREF(T) Py_INCREF(T)
|
||||||
#else
|
#else
|
||||||
#define PyString_AsString PyUnicode_AsUTF8
|
#define CVPY_TYPE_HEAD PyObject_HEAD_INIT(&PyType_Type) 0,
|
||||||
#endif
|
#define CVPY_TYPE_INCREF(T) _Py_INC_REFTOTAL _Py_REF_DEBUG_COMMA (T)->ob_refcnt++
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define CVPY_TYPE_DECLARE(NAME, STORAGE, SNAME) \
|
||||||
|
struct pyopencv_##NAME##_t \
|
||||||
|
{ \
|
||||||
|
PyObject_HEAD \
|
||||||
|
STORAGE v; \
|
||||||
|
}; \
|
||||||
|
static PyTypeObject pyopencv_##NAME##_TypeXXX = \
|
||||||
|
{ \
|
||||||
|
CVPY_TYPE_HEAD \
|
||||||
|
MODULESTR"."#NAME, \
|
||||||
|
sizeof(pyopencv_##NAME##_t), \
|
||||||
|
}; \
|
||||||
|
static PyTypeObject * pyopencv_##NAME##_TypePtr = &pyopencv_##NAME##_TypeXXX; \
|
||||||
|
static bool pyopencv_##NAME##_getp(PyObject * self, STORAGE * & dst) \
|
||||||
|
{ \
|
||||||
|
if (PyObject_TypeCheck(self, pyopencv_##NAME##_TypePtr)) \
|
||||||
|
{ \
|
||||||
|
dst = &(((pyopencv_##NAME##_t*)self)->v); \
|
||||||
|
return true; \
|
||||||
|
} \
|
||||||
|
return false; \
|
||||||
|
} \
|
||||||
|
static PyObject * pyopencv_##NAME##_Instance(const STORAGE &r) \
|
||||||
|
{ \
|
||||||
|
pyopencv_##NAME##_t *m = PyObject_NEW(pyopencv_##NAME##_t, pyopencv_##NAME##_TypePtr); \
|
||||||
|
new (&(m->v)) STORAGE(r); \
|
||||||
|
return (PyObject*)m; \
|
||||||
|
} \
|
||||||
|
static void pyopencv_##NAME##_dealloc(PyObject* self) \
|
||||||
|
{ \
|
||||||
|
((pyopencv_##NAME##_t*)self)->v.STORAGE::~SNAME(); \
|
||||||
|
PyObject_Del(self); \
|
||||||
|
} \
|
||||||
|
static PyObject* pyopencv_##NAME##_repr(PyObject* self) \
|
||||||
|
{ \
|
||||||
|
char str[1000]; \
|
||||||
|
sprintf(str, "<"#NAME" %p>", self); \
|
||||||
|
return PyString_FromString(str); \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define CVPY_TYPE_INIT_STATIC(NAME, ERROR_HANDLER, BASE, CONSTRUCTOR) \
|
||||||
|
{ \
|
||||||
|
pyopencv_##NAME##_TypePtr->tp_base = pyopencv_##BASE##_TypePtr; \
|
||||||
|
pyopencv_##NAME##_TypePtr->tp_dealloc = pyopencv_##NAME##_dealloc; \
|
||||||
|
pyopencv_##NAME##_TypePtr->tp_repr = pyopencv_##NAME##_repr; \
|
||||||
|
pyopencv_##NAME##_TypePtr->tp_getset = pyopencv_##NAME##_getseters; \
|
||||||
|
pyopencv_##NAME##_TypePtr->tp_init = (initproc) CONSTRUCTOR; \
|
||||||
|
pyopencv_##NAME##_TypePtr->tp_methods = pyopencv_##NAME##_methods; \
|
||||||
|
pyopencv_##NAME##_TypePtr->tp_alloc = PyType_GenericAlloc; \
|
||||||
|
pyopencv_##NAME##_TypePtr->tp_new = PyType_GenericNew; \
|
||||||
|
pyopencv_##NAME##_TypePtr->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE; \
|
||||||
|
if (PyType_Ready(pyopencv_##NAME##_TypePtr) != 0) \
|
||||||
|
{ \
|
||||||
|
ERROR_HANDLER; \
|
||||||
|
} \
|
||||||
|
CVPY_TYPE_INCREF(pyopencv_##NAME##_TypePtr); \
|
||||||
|
PyModule_AddObject(m, #NAME, (PyObject *)pyopencv_##NAME##_TypePtr); \
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================================================
|
||||||
|
|
||||||
|
#define CVPY_TYPE_DECLARE_DYNAMIC(NAME, STORAGE, SNAME) \
|
||||||
|
struct pyopencv_##NAME##_t \
|
||||||
|
{ \
|
||||||
|
PyObject_HEAD \
|
||||||
|
STORAGE v; \
|
||||||
|
}; \
|
||||||
|
static PyObject * pyopencv_##NAME##_TypePtr = 0; \
|
||||||
|
static bool pyopencv_##NAME##_getp(PyObject * self, STORAGE * & dst) \
|
||||||
|
{ \
|
||||||
|
if (PyObject_TypeCheck(self, (PyTypeObject*)pyopencv_##NAME##_TypePtr)) \
|
||||||
|
{ \
|
||||||
|
dst = &(((pyopencv_##NAME##_t*)self)->v); \
|
||||||
|
return true; \
|
||||||
|
} \
|
||||||
|
return false; \
|
||||||
|
} \
|
||||||
|
static PyObject * pyopencv_##NAME##_Instance(const STORAGE &r) \
|
||||||
|
{ \
|
||||||
|
pyopencv_##NAME##_t *m = PyObject_New(pyopencv_##NAME##_t, (PyTypeObject*)pyopencv_##NAME##_TypePtr); \
|
||||||
|
new (&(m->v)) STORAGE(r); \
|
||||||
|
return (PyObject*)m; \
|
||||||
|
} \
|
||||||
|
static void pyopencv_##NAME##_dealloc(PyObject* self) \
|
||||||
|
{ \
|
||||||
|
((pyopencv_##NAME##_t*)self)->v.STORAGE::~SNAME(); \
|
||||||
|
PyObject_Del(self); \
|
||||||
|
} \
|
||||||
|
static PyObject* pyopencv_##NAME##_repr(PyObject* self) \
|
||||||
|
{ \
|
||||||
|
char str[1000]; \
|
||||||
|
sprintf(str, "<"#NAME" %p>", self); \
|
||||||
|
return PyString_FromString(str); \
|
||||||
|
} \
|
||||||
|
static PyType_Slot pyopencv_##NAME##_Slots[] = \
|
||||||
|
{ \
|
||||||
|
{Py_tp_dealloc, 0}, \
|
||||||
|
{Py_tp_repr, 0}, \
|
||||||
|
{Py_tp_getset, 0}, \
|
||||||
|
{Py_tp_init, 0}, \
|
||||||
|
{Py_tp_methods, 0}, \
|
||||||
|
{Py_tp_alloc, 0}, \
|
||||||
|
{Py_tp_new, 0}, \
|
||||||
|
{0, 0} \
|
||||||
|
}; \
|
||||||
|
static PyType_Spec pyopencv_##NAME##_Spec = \
|
||||||
|
{ \
|
||||||
|
MODULESTR"."#NAME, \
|
||||||
|
sizeof(pyopencv_##NAME##_t), \
|
||||||
|
0, \
|
||||||
|
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, \
|
||||||
|
pyopencv_##NAME##_Slots \
|
||||||
|
};
|
||||||
|
|
||||||
|
#define CVPY_TYPE_INIT_DYNAMIC(NAME, ERROR_HANDLER, BASE, CONSTRUCTOR) \
|
||||||
|
{ \
|
||||||
|
pyopencv_##NAME##_Slots[0].pfunc /*tp_dealloc*/ = (void*)pyopencv_##NAME##_dealloc; \
|
||||||
|
pyopencv_##NAME##_Slots[1].pfunc /*tp_repr*/ = (void*)pyopencv_##NAME##_repr; \
|
||||||
|
pyopencv_##NAME##_Slots[2].pfunc /*tp_getset*/ = (void*)pyopencv_##NAME##_getseters; \
|
||||||
|
pyopencv_##NAME##_Slots[3].pfunc /*tp_init*/ = (void*) CONSTRUCTOR; \
|
||||||
|
pyopencv_##NAME##_Slots[4].pfunc /*tp_methods*/ = pyopencv_##NAME##_methods; \
|
||||||
|
pyopencv_##NAME##_Slots[5].pfunc /*tp_alloc*/ = (void*)PyType_GenericAlloc; \
|
||||||
|
pyopencv_##NAME##_Slots[6].pfunc /*tp_new*/ = (void*)PyType_GenericNew; \
|
||||||
|
PyObject * bases = 0; \
|
||||||
|
if (pyopencv_##BASE##_TypePtr) \
|
||||||
|
bases = PyTuple_Pack(1, pyopencv_##BASE##_TypePtr); \
|
||||||
|
pyopencv_##NAME##_TypePtr = PyType_FromSpecWithBases(&pyopencv_##NAME##_Spec, bases); \
|
||||||
|
if (!pyopencv_##NAME##_TypePtr) \
|
||||||
|
{ \
|
||||||
|
printf("Failed to init: " #NAME ", base (" #BASE ")" "\n"); \
|
||||||
|
ERROR_HANDLER; \
|
||||||
|
} \
|
||||||
|
PyModule_AddObject(m, #NAME, (PyObject *)pyopencv_##NAME##_TypePtr); \
|
||||||
|
}
|
||||||
|
|
||||||
|
// Debug module load:
|
||||||
|
//
|
||||||
|
// else \
|
||||||
|
// { \
|
||||||
|
// printf("Init: " #NAME ", base (" #BASE ") -> %p" "\n", pyopencv_##NAME##_TypePtr); \
|
||||||
|
// } \
|
||||||
|
|
||||||
|
|
||||||
#endif // END HEADER GUARD
|
#endif // END HEADER GUARD
|
||||||
|
Loading…
Reference in New Issue
Block a user