1 //warning number '5033' not a valid compiler warning in vc12
2 #if defined(_MSC_VER) && (_MSC_VER > 1800)
3 // eliminating duplicated round() declaration
4 #define HAVE_ROUND 1
5 #pragma warning(push)
6 #pragma warning(disable:5033) // 'register' is no longer a supported storage class
7 #endif
8
9 // #define CVPY_DYNAMIC_INIT
10 // #define Py_DEBUG
11
12 #if defined(CVPY_DYNAMIC_INIT) && !defined(Py_DEBUG)
13 # define Py_LIMITED_API 0x03030000
14 #endif
15
16 #include <cmath>
17 #include <Python.h>
18 #include <limits>
19
20 #if PY_MAJOR_VERSION < 3
21 #undef CVPY_DYNAMIC_INIT
22 #else
23 #define CV_PYTHON_3 1
24 #endif
25
26 #if defined(_MSC_VER) && (_MSC_VER > 1800)
27 #pragma warning(pop)
28 #endif
29
30 #define MODULESTR "cv2"
31 #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
32
33 #include <numpy/ndarrayobject.h>
34
35 #include "opencv2/opencv_modules.hpp"
36 #include "opencv2/core.hpp"
37 #include "opencv2/core/utils/configuration.private.hpp"
38 #include "opencv2/core/utils/logger.hpp"
39 #include "opencv2/core/utils/tls.hpp"
40
41 #include "pyopencv_generated_include.h"
42 #include "opencv2/core/types_c.h"
43 #include "pycompat.hpp"
44 #include <map>
45
46 #include <type_traits> // std::enable_if
47
48 #define CV_HAS_CONVERSION_ERROR(x) (((x) == -1) && PyErr_Occurred())
49
50 static PyObject* opencv_error = NULL;
51
52 class ArgInfo
53 {
54 public:
55 const char* name;
56 bool outputarg;
57 // more fields may be added if necessary
58
ArgInfo(const char * name_,bool outputarg_)59 ArgInfo(const char* name_, bool outputarg_) : name(name_), outputarg(outputarg_) {}
60
61 private:
62 ArgInfo(const ArgInfo&) = delete;
63 ArgInfo& operator=(const ArgInfo&) = delete;
64 };
65
66 template<typename T, class TEnable = void> // TEnable is used for SFINAE checks
67 struct PyOpenCV_Converter
68 {
69 //static inline bool to(PyObject* obj, T& p, const ArgInfo& info);
70 //static inline PyObject* from(const T& src);
71 };
72
73 // exception-safe pyopencv_to
74 template<typename _Tp> static
pyopencv_to_safe(PyObject * obj,_Tp & value,const ArgInfo & info)75 bool pyopencv_to_safe(PyObject* obj, _Tp& value, const ArgInfo& info)
76 {
77 try
78 {
79 return pyopencv_to(obj, value, info);
80 }
81 catch (const std::exception &e)
82 {
83 PyErr_SetString(opencv_error, cv::format("Conversion error: %s, what: %s", info.name, e.what()).c_str());
84 return false;
85 }
86 catch (...)
87 {
88 PyErr_SetString(opencv_error, cv::format("Conversion error: %s", info.name).c_str());
89 return false;
90 }
91 }
92
93 template<typename T> static
pyopencv_to(PyObject * obj,T & p,const ArgInfo & info)94 bool pyopencv_to(PyObject* obj, T& p, const ArgInfo& info) { return PyOpenCV_Converter<T>::to(obj, p, info); }
95
96 template<typename T> static
pyopencv_from(const T & src)97 PyObject* pyopencv_from(const T& src) { return PyOpenCV_Converter<T>::from(src); }
98
isPythonBindingsDebugEnabled()99 static bool isPythonBindingsDebugEnabled()
100 {
101 static bool param_debug = cv::utils::getConfigurationParameterBool("OPENCV_PYTHON_DEBUG", false);
102 return param_debug;
103 }
104
emit_failmsg(PyObject * exc,const char * msg)105 static void emit_failmsg(PyObject * exc, const char *msg)
106 {
107 static bool param_debug = isPythonBindingsDebugEnabled();
108 if (param_debug)
109 {
110 CV_LOG_WARNING(NULL, "Bindings conversion failed: " << msg);
111 }
112 PyErr_SetString(exc, msg);
113 }
114
failmsg(const char * fmt,...)115 static int failmsg(const char *fmt, ...)
116 {
117 char str[1000];
118
119 va_list ap;
120 va_start(ap, fmt);
121 vsnprintf(str, sizeof(str), fmt, ap);
122 va_end(ap);
123
124 emit_failmsg(PyExc_TypeError, str);
125 return 0;
126 }
127
failmsgp(const char * fmt,...)128 static PyObject* failmsgp(const char *fmt, ...)
129 {
130 char str[1000];
131
132 va_list ap;
133 va_start(ap, fmt);
134 vsnprintf(str, sizeof(str), fmt, ap);
135 va_end(ap);
136
137 emit_failmsg(PyExc_TypeError, str);
138 return 0;
139 }
140
141 class PyAllowThreads
142 {
143 public:
PyAllowThreads()144 PyAllowThreads() : _state(PyEval_SaveThread()) {}
~PyAllowThreads()145 ~PyAllowThreads()
146 {
147 PyEval_RestoreThread(_state);
148 }
149 private:
150 PyThreadState* _state;
151 };
152
153 class PyEnsureGIL
154 {
155 public:
PyEnsureGIL()156 PyEnsureGIL() : _state(PyGILState_Ensure()) {}
~PyEnsureGIL()157 ~PyEnsureGIL()
158 {
159 PyGILState_Release(_state);
160 }
161 private:
162 PyGILState_STATE _state;
163 };
164
165 /**
166 * Light weight RAII wrapper for `PyObject*` owning references.
167 * In comparisson to C++11 `std::unique_ptr` with custom deleter, it provides
168 * implicit conversion functions that might be useful to initialize it with
169 * Python functions those returns owning references through the `PyObject**`
170 * e.g. `PyErr_Fetch` or directly pass it to functions those want to borrow
171 * reference to object (doesn't extend object lifetime) e.g. `PyObject_Str`.
172 */
173 class PySafeObject
174 {
175 public:
PySafeObject()176 PySafeObject() : obj_(NULL) {}
177
PySafeObject(PyObject * obj)178 explicit PySafeObject(PyObject* obj) : obj_(obj) {}
179
~PySafeObject()180 ~PySafeObject()
181 {
182 Py_CLEAR(obj_);
183 }
184
operator PyObject*()185 operator PyObject*()
186 {
187 return obj_;
188 }
189
operator PyObject**()190 operator PyObject**()
191 {
192 return &obj_;
193 }
194
release()195 PyObject* release()
196 {
197 PyObject* obj = obj_;
198 obj_ = NULL;
199 return obj;
200 }
201
202 private:
203 PyObject* obj_;
204
205 // Explicitly disable copy operations
206 PySafeObject(const PySafeObject*); // = delete
207 PySafeObject& operator=(const PySafeObject&); // = delete
208 };
209
pyRaiseCVException(const cv::Exception & e)210 static void pyRaiseCVException(const cv::Exception &e)
211 {
212 PyObject_SetAttrString(opencv_error, "file", PyString_FromString(e.file.c_str()));
213 PyObject_SetAttrString(opencv_error, "func", PyString_FromString(e.func.c_str()));
214 PyObject_SetAttrString(opencv_error, "line", PyInt_FromLong(e.line));
215 PyObject_SetAttrString(opencv_error, "code", PyInt_FromLong(e.code));
216 PyObject_SetAttrString(opencv_error, "msg", PyString_FromString(e.msg.c_str()));
217 PyObject_SetAttrString(opencv_error, "err", PyString_FromString(e.err.c_str()));
218 PyErr_SetString(opencv_error, e.what());
219 }
220
221 #define ERRWRAP2(expr) \
222 try \
223 { \
224 PyAllowThreads allowThreads; \
225 expr; \
226 } \
227 catch (const cv::Exception &e) \
228 { \
229 pyRaiseCVException(e); \
230 return 0; \
231 } \
232 catch (const std::exception &e) \
233 { \
234 PyErr_SetString(opencv_error, e.what()); \
235 return 0; \
236 } \
237 catch (...) \
238 { \
239 PyErr_SetString(opencv_error, "Unknown C++ exception from OpenCV code"); \
240 return 0; \
241 }
242
243 using namespace cv;
244
245
246 namespace {
247 template<class T>
asNumpyType()248 NPY_TYPES asNumpyType()
249 {
250 return NPY_OBJECT;
251 }
252
253 template<>
asNumpyType()254 NPY_TYPES asNumpyType<bool>()
255 {
256 return NPY_BOOL;
257 }
258
259 #define CV_GENERATE_INTEGRAL_TYPE_NPY_CONVERSION(src, dst) \
260 template<> \
261 NPY_TYPES asNumpyType<src>() \
262 { \
263 return NPY_##dst; \
264 } \
265 template<> \
266 NPY_TYPES asNumpyType<u##src>() \
267 { \
268 return NPY_U##dst; \
269 }
270
271 CV_GENERATE_INTEGRAL_TYPE_NPY_CONVERSION(int8_t, INT8);
272
273 CV_GENERATE_INTEGRAL_TYPE_NPY_CONVERSION(int16_t, INT16);
274
275 CV_GENERATE_INTEGRAL_TYPE_NPY_CONVERSION(int32_t, INT32);
276
277 CV_GENERATE_INTEGRAL_TYPE_NPY_CONVERSION(int64_t, INT64);
278
279 #undef CV_GENERATE_INTEGRAL_TYPE_NPY_CONVERSION
280
281 template<>
asNumpyType()282 NPY_TYPES asNumpyType<float>()
283 {
284 return NPY_FLOAT;
285 }
286
287 template<>
asNumpyType()288 NPY_TYPES asNumpyType<double>()
289 {
290 return NPY_DOUBLE;
291 }
292
293 template <class T>
getNumpyTypeDescriptor()294 PyArray_Descr* getNumpyTypeDescriptor()
295 {
296 return PyArray_DescrFromType(asNumpyType<T>());
297 }
298
299 template <>
getNumpyTypeDescriptor()300 PyArray_Descr* getNumpyTypeDescriptor<size_t>()
301 {
302 #if SIZE_MAX == ULONG_MAX
303 return PyArray_DescrFromType(NPY_ULONG);
304 #elif SIZE_MAX == ULLONG_MAX
305 return PyArray_DescrFromType(NPY_ULONGLONG);
306 #else
307 return PyArray_DescrFromType(NPY_UINT);
308 #endif
309 }
310
311 template <class T, class U>
isRepresentable(U value)312 bool isRepresentable(U value) {
313 return (std::numeric_limits<T>::min() <= value) && (value <= std::numeric_limits<T>::max());
314 }
315
316 template<class T>
canBeSafelyCasted(PyObject * obj,PyArray_Descr * to)317 bool canBeSafelyCasted(PyObject* obj, PyArray_Descr* to)
318 {
319 return PyArray_CanCastTo(PyArray_DescrFromScalar(obj), to) != 0;
320 }
321
322
323 template<>
canBeSafelyCasted(PyObject * obj,PyArray_Descr * to)324 bool canBeSafelyCasted<size_t>(PyObject* obj, PyArray_Descr* to)
325 {
326 PyArray_Descr* from = PyArray_DescrFromScalar(obj);
327 if (PyArray_CanCastTo(from, to))
328 {
329 return true;
330 }
331 else
332 {
333 // False negative scenarios:
334 // - Signed input is positive so it can be safely cast to unsigned output
335 // - Input has wider limits but value is representable within output limits
336 // - All the above
337 if (PyDataType_ISSIGNED(from))
338 {
339 int64_t input = 0;
340 PyArray_CastScalarToCtype(obj, &input, getNumpyTypeDescriptor<int64_t>());
341 return (input >= 0) && isRepresentable<size_t>(static_cast<uint64_t>(input));
342 }
343 else
344 {
345 uint64_t input = 0;
346 PyArray_CastScalarToCtype(obj, &input, getNumpyTypeDescriptor<uint64_t>());
347 return isRepresentable<size_t>(input);
348 }
349 return false;
350 }
351 }
352
353
354 template<class T>
parseNumpyScalar(PyObject * obj,T & value)355 bool parseNumpyScalar(PyObject* obj, T& value)
356 {
357 if (PyArray_CheckScalar(obj))
358 {
359 // According to the numpy documentation:
360 // There are 21 statically-defined PyArray_Descr objects for the built-in data-types
361 // So descriptor pointer is not owning.
362 PyArray_Descr* to = getNumpyTypeDescriptor<T>();
363 if (canBeSafelyCasted<T>(obj, to))
364 {
365 PyArray_CastScalarToCtype(obj, &value, to);
366 return true;
367 }
368 }
369 return false;
370 }
371
372 TLSData<std::vector<std::string> > conversionErrorsTLS;
373
pyPrepareArgumentConversionErrorsStorage(std::size_t size)374 inline void pyPrepareArgumentConversionErrorsStorage(std::size_t size)
375 {
376 std::vector<std::string>& conversionErrors = conversionErrorsTLS.getRef();
377 conversionErrors.clear();
378 conversionErrors.reserve(size);
379 }
380
pyRaiseCVOverloadException(const std::string & functionName)381 void pyRaiseCVOverloadException(const std::string& functionName)
382 {
383 const std::vector<std::string>& conversionErrors = conversionErrorsTLS.getRef();
384 const std::size_t conversionErrorsCount = conversionErrors.size();
385 if (conversionErrorsCount > 0)
386 {
387 // In modern std libraries small string optimization is used = no dynamic memory allocations,
388 // but it can be applied only for string with length < 18 symbols (in GCC)
389 const std::string bullet = "\n - ";
390
391 // Estimate required buffer size - save dynamic memory allocations = faster
392 std::size_t requiredBufferSize = bullet.size() * conversionErrorsCount;
393 for (std::size_t i = 0; i < conversionErrorsCount; ++i)
394 {
395 requiredBufferSize += conversionErrors[i].size();
396 }
397
398 // Only string concatenation is required so std::string is way faster than
399 // std::ostringstream
400 std::string errorMessage("Overload resolution failed:");
401 errorMessage.reserve(errorMessage.size() + requiredBufferSize);
402 for (std::size_t i = 0; i < conversionErrorsCount; ++i)
403 {
404 errorMessage += bullet;
405 errorMessage += conversionErrors[i];
406 }
407 cv::Exception exception(CV_StsBadArg, errorMessage, functionName, "", -1);
408 pyRaiseCVException(exception);
409 }
410 else
411 {
412 cv::Exception exception(CV_StsInternal, "Overload resolution failed, but no errors reported",
413 functionName, "", -1);
414 pyRaiseCVException(exception);
415 }
416 }
417
pyPopulateArgumentConversionErrors()418 void pyPopulateArgumentConversionErrors()
419 {
420 if (PyErr_Occurred())
421 {
422 PySafeObject exception_type;
423 PySafeObject exception_value;
424 PySafeObject exception_traceback;
425 PyErr_Fetch(exception_type, exception_value, exception_traceback);
426 PyErr_NormalizeException(exception_type, exception_value,
427 exception_traceback);
428
429 PySafeObject exception_message(PyObject_Str(exception_value));
430 std::string message;
431 getUnicodeString(exception_message, message);
432 #ifdef CV_CXX11
433 conversionErrorsTLS.getRef().push_back(std::move(message));
434 #else
435 conversionErrorsTLS.getRef().push_back(message);
436 #endif
437 }
438 }
439
440 struct SafeSeqItem
441 {
442 PyObject * item;
SafeSeqItem__anonb8409a610111::SafeSeqItem443 SafeSeqItem(PyObject *obj, size_t idx) { item = PySequence_GetItem(obj, idx); }
~SafeSeqItem__anonb8409a610111::SafeSeqItem444 ~SafeSeqItem() { Py_XDECREF(item); }
445
446 private:
447 SafeSeqItem(const SafeSeqItem&); // = delete
448 SafeSeqItem& operator=(const SafeSeqItem&); // = delete
449 };
450
451 template <class T>
452 class RefWrapper
453 {
454 public:
RefWrapper(T & item)455 RefWrapper(T& item) : item_(item) {}
456
get()457 T& get() CV_NOEXCEPT { return item_; }
458
459 private:
460 T& item_;
461 };
462
463 // In order to support this conversion on 3.x branch - use custom reference_wrapper
464 // and C-style array instead of std::array<T, N>
465 template <class T, std::size_t N>
parseSequence(PyObject * obj,RefWrapper<T> (& value)[N],const ArgInfo & info)466 bool parseSequence(PyObject* obj, RefWrapper<T> (&value)[N], const ArgInfo& info)
467 {
468 if (!obj || obj == Py_None)
469 {
470 return true;
471 }
472 if (!PySequence_Check(obj))
473 {
474 failmsg("Can't parse '%s'. Input argument doesn't provide sequence "
475 "protocol", info.name);
476 return false;
477 }
478 const std::size_t sequenceSize = PySequence_Size(obj);
479 if (sequenceSize != N)
480 {
481 failmsg("Can't parse '%s'. Expected sequence length %lu, got %lu",
482 info.name, N, sequenceSize);
483 return false;
484 }
485 for (std::size_t i = 0; i < N; ++i)
486 {
487 SafeSeqItem seqItem(obj, i);
488 if (!pyopencv_to(seqItem.item, value[i].get(), info))
489 {
490 failmsg("Can't parse '%s'. Sequence item with index %lu has a "
491 "wrong type", info.name, i);
492 return false;
493 }
494 }
495 return true;
496 }
497 } // namespace
498
499 typedef std::vector<uchar> vector_uchar;
500 typedef std::vector<char> vector_char;
501 typedef std::vector<int> vector_int;
502 typedef std::vector<float> vector_float;
503 typedef std::vector<double> vector_double;
504 typedef std::vector<size_t> vector_size_t;
505 typedef std::vector<Point> vector_Point;
506 typedef std::vector<Point2f> vector_Point2f;
507 typedef std::vector<Point3f> vector_Point3f;
508 typedef std::vector<Size> vector_Size;
509 typedef std::vector<Vec2f> vector_Vec2f;
510 typedef std::vector<Vec3f> vector_Vec3f;
511 typedef std::vector<Vec4f> vector_Vec4f;
512 typedef std::vector<Vec6f> vector_Vec6f;
513 typedef std::vector<Vec4i> vector_Vec4i;
514 typedef std::vector<Rect> vector_Rect;
515 typedef std::vector<Rect2d> vector_Rect2d;
516 typedef std::vector<RotatedRect> vector_RotatedRect;
517 typedef std::vector<KeyPoint> vector_KeyPoint;
518 typedef std::vector<Mat> vector_Mat;
519 typedef std::vector<std::vector<Mat> > vector_vector_Mat;
520 typedef std::vector<UMat> vector_UMat;
521 typedef std::vector<DMatch> vector_DMatch;
522 typedef std::vector<String> vector_String;
523 typedef std::vector<std::string> vector_string;
524 typedef std::vector<Scalar> vector_Scalar;
525
526 typedef std::vector<std::vector<char> > vector_vector_char;
527 typedef std::vector<std::vector<Point> > vector_vector_Point;
528 typedef std::vector<std::vector<Point2f> > vector_vector_Point2f;
529 typedef std::vector<std::vector<Point3f> > vector_vector_Point3f;
530 typedef std::vector<std::vector<DMatch> > vector_vector_DMatch;
531 typedef std::vector<std::vector<KeyPoint> > vector_vector_KeyPoint;
532
533 class NumpyAllocator : public MatAllocator
534 {
535 public:
NumpyAllocator()536 NumpyAllocator() { stdAllocator = Mat::getStdAllocator(); }
~NumpyAllocator()537 ~NumpyAllocator() {}
538
allocate(PyObject * o,int dims,const int * sizes,int type,size_t * step) const539 UMatData* allocate(PyObject* o, int dims, const int* sizes, int type, size_t* step) const
540 {
541 UMatData* u = new UMatData(this);
542 u->data = u->origdata = (uchar*)PyArray_DATA((PyArrayObject*) o);
543 npy_intp* _strides = PyArray_STRIDES((PyArrayObject*) o);
544 for( int i = 0; i < dims - 1; i++ )
545 step[i] = (size_t)_strides[i];
546 step[dims-1] = CV_ELEM_SIZE(type);
547 u->size = sizes[0]*step[0];
548 u->userdata = o;
549 return u;
550 }
551
allocate(int dims0,const int * sizes,int type,void * data,size_t * step,AccessFlag flags,UMatUsageFlags usageFlags) const552 UMatData* allocate(int dims0, const int* sizes, int type, void* data, size_t* step, AccessFlag flags, UMatUsageFlags usageFlags) const CV_OVERRIDE
553 {
554 if( data != 0 )
555 {
556 // issue #6969: CV_Error(Error::StsAssert, "The data should normally be NULL!");
557 // probably this is safe to do in such extreme case
558 return stdAllocator->allocate(dims0, sizes, type, data, step, flags, usageFlags);
559 }
560 PyEnsureGIL gil;
561
562 int depth = CV_MAT_DEPTH(type);
563 int cn = CV_MAT_CN(type);
564 const int f = (int)(sizeof(size_t)/8);
565 int typenum = depth == CV_8U ? NPY_UBYTE : depth == CV_8S ? NPY_BYTE :
566 depth == CV_16U ? NPY_USHORT : depth == CV_16S ? NPY_SHORT :
567 depth == CV_32S ? NPY_INT : depth == CV_32F ? NPY_FLOAT :
568 depth == CV_64F ? NPY_DOUBLE : f*NPY_ULONGLONG + (f^1)*NPY_UINT;
569 int i, dims = dims0;
570 cv::AutoBuffer<npy_intp> _sizes(dims + 1);
571 for( i = 0; i < dims; i++ )
572 _sizes[i] = sizes[i];
573 if( cn > 1 )
574 _sizes[dims++] = cn;
575 PyObject* o = PyArray_SimpleNew(dims, _sizes.data(), typenum);
576 if(!o)
577 CV_Error_(Error::StsError, ("The numpy array of typenum=%d, ndims=%d can not be created", typenum, dims));
578 return allocate(o, dims0, sizes, type, step);
579 }
580
allocate(UMatData * u,AccessFlag accessFlags,UMatUsageFlags usageFlags) const581 bool allocate(UMatData* u, AccessFlag accessFlags, UMatUsageFlags usageFlags) const CV_OVERRIDE
582 {
583 return stdAllocator->allocate(u, accessFlags, usageFlags);
584 }
585
deallocate(UMatData * u) const586 void deallocate(UMatData* u) const CV_OVERRIDE
587 {
588 if(!u)
589 return;
590 PyEnsureGIL gil;
591 CV_Assert(u->urefcount >= 0);
592 CV_Assert(u->refcount >= 0);
593 if(u->refcount == 0)
594 {
595 PyObject* o = (PyObject*)u->userdata;
596 Py_XDECREF(o);
597 delete u;
598 }
599 }
600
601 const MatAllocator* stdAllocator;
602 };
603
604 NumpyAllocator g_numpyAllocator;
605
606
607 enum { ARG_NONE = 0, ARG_MAT = 1, ARG_SCALAR = 2 };
608
isBool(PyObject * obj)609 static bool isBool(PyObject* obj) CV_NOEXCEPT
610 {
611 return PyArray_IsScalar(obj, Bool) || PyBool_Check(obj);
612 }
613
614 // special case, when the converter needs full ArgInfo structure
pyopencv_to(PyObject * o,Mat & m,const ArgInfo & info)615 static bool pyopencv_to(PyObject* o, Mat& m, const ArgInfo& info)
616 {
617 bool allowND = true;
618 if(!o || o == Py_None)
619 {
620 if( !m.data )
621 m.allocator = &g_numpyAllocator;
622 return true;
623 }
624
625 if( PyInt_Check(o) )
626 {
627 double v[] = {static_cast<double>(PyInt_AsLong((PyObject*)o)), 0., 0., 0.};
628 m = Mat(4, 1, CV_64F, v).clone();
629 return true;
630 }
631 if( PyFloat_Check(o) )
632 {
633 double v[] = {PyFloat_AsDouble((PyObject*)o), 0., 0., 0.};
634 m = Mat(4, 1, CV_64F, v).clone();
635 return true;
636 }
637 if( PyTuple_Check(o) )
638 {
639 int i, sz = (int)PyTuple_Size((PyObject*)o);
640 m = Mat(sz, 1, CV_64F);
641 for( i = 0; i < sz; i++ )
642 {
643 PyObject* oi = PyTuple_GetItem(o, i);
644 if( PyInt_Check(oi) )
645 m.at<double>(i) = (double)PyInt_AsLong(oi);
646 else if( PyFloat_Check(oi) )
647 m.at<double>(i) = (double)PyFloat_AsDouble(oi);
648 else
649 {
650 failmsg("%s is not a numerical tuple", info.name);
651 m.release();
652 return false;
653 }
654 }
655 return true;
656 }
657
658 if( !PyArray_Check(o) )
659 {
660 failmsg("%s is not a numpy array, neither a scalar", info.name);
661 return false;
662 }
663
664 PyArrayObject* oarr = (PyArrayObject*) o;
665
666 bool needcopy = false, needcast = false;
667 int typenum = PyArray_TYPE(oarr), new_typenum = typenum;
668 int type = typenum == NPY_UBYTE ? CV_8U :
669 typenum == NPY_BYTE ? CV_8S :
670 typenum == NPY_USHORT ? CV_16U :
671 typenum == NPY_SHORT ? CV_16S :
672 typenum == NPY_INT ? CV_32S :
673 typenum == NPY_INT32 ? CV_32S :
674 typenum == NPY_FLOAT ? CV_32F :
675 typenum == NPY_DOUBLE ? CV_64F : -1;
676
677 if( type < 0 )
678 {
679 if( typenum == NPY_INT64 || typenum == NPY_UINT64 || typenum == NPY_LONG )
680 {
681 needcopy = needcast = true;
682 new_typenum = NPY_INT;
683 type = CV_32S;
684 }
685 else
686 {
687 failmsg("%s data type = %d is not supported", info.name, typenum);
688 return false;
689 }
690 }
691
692 #ifndef CV_MAX_DIM
693 const int CV_MAX_DIM = 32;
694 #endif
695
696 int ndims = PyArray_NDIM(oarr);
697 if(ndims >= CV_MAX_DIM)
698 {
699 failmsg("%s dimensionality (=%d) is too high", info.name, ndims);
700 return false;
701 }
702
703 int size[CV_MAX_DIM+1];
704 size_t step[CV_MAX_DIM+1];
705 size_t elemsize = CV_ELEM_SIZE1(type);
706 const npy_intp* _sizes = PyArray_DIMS(oarr);
707 const npy_intp* _strides = PyArray_STRIDES(oarr);
708 bool ismultichannel = ndims == 3 && _sizes[2] <= CV_CN_MAX;
709
710 for( int i = ndims-1; i >= 0 && !needcopy; i-- )
711 {
712 // these checks handle cases of
713 // a) multi-dimensional (ndims > 2) arrays, as well as simpler 1- and 2-dimensional cases
714 // b) transposed arrays, where _strides[] elements go in non-descending order
715 // c) flipped arrays, where some of _strides[] elements are negative
716 // the _sizes[i] > 1 is needed to avoid spurious copies when NPY_RELAXED_STRIDES is set
717 if( (i == ndims-1 && _sizes[i] > 1 && (size_t)_strides[i] != elemsize) ||
718 (i < ndims-1 && _sizes[i] > 1 && _strides[i] < _strides[i+1]) )
719 needcopy = true;
720 }
721
722 if( ismultichannel && _strides[1] != (npy_intp)elemsize*_sizes[2] )
723 needcopy = true;
724
725 if (needcopy)
726 {
727 if (info.outputarg)
728 {
729 failmsg("Layout of the output array %s is incompatible with cv::Mat (step[ndims-1] != elemsize or step[1] != elemsize*nchannels)", info.name);
730 return false;
731 }
732
733 if( needcast ) {
734 o = PyArray_Cast(oarr, new_typenum);
735 oarr = (PyArrayObject*) o;
736 }
737 else {
738 oarr = PyArray_GETCONTIGUOUS(oarr);
739 o = (PyObject*) oarr;
740 }
741
742 _strides = PyArray_STRIDES(oarr);
743 }
744
745 // Normalize strides in case NPY_RELAXED_STRIDES is set
746 size_t default_step = elemsize;
747 for ( int i = ndims - 1; i >= 0; --i )
748 {
749 size[i] = (int)_sizes[i];
750 if ( size[i] > 1 )
751 {
752 step[i] = (size_t)_strides[i];
753 default_step = step[i] * size[i];
754 }
755 else
756 {
757 step[i] = default_step;
758 default_step *= size[i];
759 }
760 }
761
762 // handle degenerate case
763 if( ndims == 0) {
764 size[ndims] = 1;
765 step[ndims] = elemsize;
766 ndims++;
767 }
768
769 if( ismultichannel )
770 {
771 ndims--;
772 type |= CV_MAKETYPE(0, size[2]);
773 }
774
775 if( ndims > 2 && !allowND )
776 {
777 failmsg("%s has more than 2 dimensions", info.name);
778 return false;
779 }
780
781 m = Mat(ndims, size, type, PyArray_DATA(oarr), step);
782 m.u = g_numpyAllocator.allocate(o, ndims, size, type, step);
783 m.addref();
784
785 if( !needcopy )
786 {
787 Py_INCREF(o);
788 }
789 m.allocator = &g_numpyAllocator;
790
791 return true;
792 }
793
794 template<typename _Tp, int m, int n>
pyopencv_to(PyObject * o,Matx<_Tp,m,n> & mx,const ArgInfo & info)795 bool pyopencv_to(PyObject* o, Matx<_Tp, m, n>& mx, const ArgInfo& info)
796 {
797 Mat tmp;
798 if (!pyopencv_to(o, tmp, info)) {
799 return false;
800 }
801
802 tmp.copyTo(mx);
803 return true;
804 }
805
806 template<typename _Tp, int cn>
pyopencv_to(PyObject * o,Vec<_Tp,cn> & vec,const ArgInfo & info)807 bool pyopencv_to(PyObject* o, Vec<_Tp, cn>& vec, const ArgInfo& info)
808 {
809 return pyopencv_to(o, (Matx<_Tp, cn, 1>&)vec, info);
810 }
811
812 template<>
pyopencv_from(const Mat & m)813 PyObject* pyopencv_from(const Mat& m)
814 {
815 if( !m.data )
816 Py_RETURN_NONE;
817 Mat temp, *p = (Mat*)&m;
818 if(!p->u || p->allocator != &g_numpyAllocator)
819 {
820 temp.allocator = &g_numpyAllocator;
821 ERRWRAP2(m.copyTo(temp));
822 p = &temp;
823 }
824 PyObject* o = (PyObject*)p->u->userdata;
825 Py_INCREF(o);
826 return o;
827 }
828
829 template<typename _Tp, int m, int n>
pyopencv_from(const Matx<_Tp,m,n> & matx)830 PyObject* pyopencv_from(const Matx<_Tp, m, n>& matx)
831 {
832 return pyopencv_from(Mat(matx));
833 }
834
835 template<typename T>
836 struct PyOpenCV_Converter< cv::Ptr<T> >
837 {
fromPyOpenCV_Converter838 static PyObject* from(const cv::Ptr<T>& p)
839 {
840 if (!p)
841 Py_RETURN_NONE;
842 return pyopencv_from(*p);
843 }
toPyOpenCV_Converter844 static bool to(PyObject *o, Ptr<T>& p, const ArgInfo& info)
845 {
846 if (!o || o == Py_None)
847 return true;
848 p = makePtr<T>();
849 return pyopencv_to(o, *p, info);
850 }
851 };
852
853 template<>
pyopencv_to(PyObject * obj,void * & ptr,const ArgInfo & info)854 bool pyopencv_to(PyObject* obj, void*& ptr, const ArgInfo& info)
855 {
856 CV_UNUSED(info);
857 if (!obj || obj == Py_None)
858 return true;
859
860 if (!PyLong_Check(obj))
861 return false;
862 ptr = PyLong_AsVoidPtr(obj);
863 return ptr != NULL && !PyErr_Occurred();
864 }
865
pyopencv_from(void * & ptr)866 static PyObject* pyopencv_from(void*& ptr)
867 {
868 return PyLong_FromVoidPtr(ptr);
869 }
870
pyopencv_to(PyObject * o,Scalar & s,const ArgInfo & info)871 static bool pyopencv_to(PyObject *o, Scalar& s, const ArgInfo& info)
872 {
873 if(!o || o == Py_None)
874 return true;
875 if (PySequence_Check(o)) {
876 if (4 < PySequence_Size(o))
877 {
878 failmsg("Scalar value for argument '%s' is longer than 4", info.name);
879 return false;
880 }
881 for (Py_ssize_t i = 0; i < PySequence_Size(o); i++) {
882 SafeSeqItem item_wrap(o, i);
883 PyObject *item = item_wrap.item;
884 if (PyFloat_Check(item) || PyInt_Check(item)) {
885 s[(int)i] = PyFloat_AsDouble(item);
886 } else {
887 failmsg("Scalar value for argument '%s' is not numeric", info.name);
888 return false;
889 }
890 }
891 } else {
892 if (PyFloat_Check(o) || PyInt_Check(o)) {
893 s[0] = PyFloat_AsDouble(o);
894 } else {
895 failmsg("Scalar value for argument '%s' is not numeric", info.name);
896 return false;
897 }
898 }
899 return true;
900 }
901
902 template<>
pyopencv_from(const Scalar & src)903 PyObject* pyopencv_from(const Scalar& src)
904 {
905 return Py_BuildValue("(dddd)", src[0], src[1], src[2], src[3]);
906 }
907
908 template<>
pyopencv_from(const bool & value)909 PyObject* pyopencv_from(const bool& value)
910 {
911 return PyBool_FromLong(value);
912 }
913
914 template<>
pyopencv_to(PyObject * obj,bool & value,const ArgInfo & info)915 bool pyopencv_to(PyObject* obj, bool& value, const ArgInfo& info)
916 {
917 if (!obj || obj == Py_None)
918 {
919 return true;
920 }
921 if (isBool(obj) || PyArray_IsIntegerScalar(obj))
922 {
923 npy_bool npy_value = NPY_FALSE;
924 const int ret_code = PyArray_BoolConverter(obj, &npy_value);
925 if (ret_code >= 0)
926 {
927 value = (npy_value == NPY_TRUE);
928 return true;
929 }
930 }
931 failmsg("Argument '%s' is not convertable to bool", info.name);
932 return false;
933 }
934
935 template<>
pyopencv_from(const size_t & value)936 PyObject* pyopencv_from(const size_t& value)
937 {
938 return PyLong_FromSize_t(value);
939 }
940
941 template<>
pyopencv_to(PyObject * obj,size_t & value,const ArgInfo & info)942 bool pyopencv_to(PyObject* obj, size_t& value, const ArgInfo& info)
943 {
944 if (!obj || obj == Py_None)
945 {
946 return true;
947 }
948 if (isBool(obj))
949 {
950 failmsg("Argument '%s' must be integer type, not bool", info.name);
951 return false;
952 }
953 if (PyArray_IsIntegerScalar(obj))
954 {
955 if (PyLong_Check(obj))
956 {
957 #if defined(CV_PYTHON_3)
958 value = PyLong_AsSize_t(obj);
959 #else
960 #if ULONG_MAX == SIZE_MAX
961 value = PyLong_AsUnsignedLong(obj);
962 #else
963 value = PyLong_AsUnsignedLongLong(obj);
964 #endif
965 #endif
966 }
967 #if !defined(CV_PYTHON_3)
968 // Python 2.x has PyIntObject which is not a subtype of PyLongObject
969 // Overflow check here is unnecessary because object will be converted to long on the
970 // interpreter side
971 else if (PyInt_Check(obj))
972 {
973 const long res = PyInt_AsLong(obj);
974 if (res < 0) {
975 failmsg("Argument '%s' can not be safely parsed to 'size_t'", info.name);
976 return false;
977 }
978 #if ULONG_MAX == SIZE_MAX
979 value = PyInt_AsUnsignedLongMask(obj);
980 #else
981 value = PyInt_AsUnsignedLongLongMask(obj);
982 #endif
983 }
984 #endif
985 else
986 {
987 const bool isParsed = parseNumpyScalar<size_t>(obj, value);
988 if (!isParsed) {
989 failmsg("Argument '%s' can not be safely parsed to 'size_t'", info.name);
990 return false;
991 }
992 }
993 }
994 else
995 {
996 failmsg("Argument '%s' is required to be an integer", info.name);
997 return false;
998 }
999 return !PyErr_Occurred();
1000 }
1001
1002 template<>
pyopencv_from(const int & value)1003 PyObject* pyopencv_from(const int& value)
1004 {
1005 return PyInt_FromLong(value);
1006 }
1007
1008 template<>
pyopencv_to(PyObject * obj,int & value,const ArgInfo & info)1009 bool pyopencv_to(PyObject* obj, int& value, const ArgInfo& info)
1010 {
1011 if (!obj || obj == Py_None)
1012 {
1013 return true;
1014 }
1015 if (isBool(obj))
1016 {
1017 failmsg("Argument '%s' must be integer, not bool", info.name);
1018 return false;
1019 }
1020 if (PyArray_IsIntegerScalar(obj))
1021 {
1022 value = PyArray_PyIntAsInt(obj);
1023 }
1024 else
1025 {
1026 failmsg("Argument '%s' is required to be an integer", info.name);
1027 return false;
1028 }
1029 return !CV_HAS_CONVERSION_ERROR(value);
1030 }
1031
1032 // There is conflict between "size_t" and "unsigned int".
1033 // They are the same type on some 32-bit platforms.
1034 template<typename T>
1035 struct PyOpenCV_Converter
1036 < T, typename std::enable_if< std::is_same<unsigned int, T>::value && !std::is_same<unsigned int, size_t>::value >::type >
1037 {
fromPyOpenCV_Converter1038 static inline PyObject* from(const unsigned int& value)
1039 {
1040 return PyLong_FromUnsignedLong(value);
1041 }
1042
toPyOpenCV_Converter1043 static inline bool to(PyObject* obj, unsigned int& value, const ArgInfo& info)
1044 {
1045 CV_UNUSED(info);
1046 if(!obj || obj == Py_None)
1047 return true;
1048 if(PyInt_Check(obj))
1049 value = (unsigned int)PyInt_AsLong(obj);
1050 else if(PyLong_Check(obj))
1051 value = (unsigned int)PyLong_AsLong(obj);
1052 else
1053 return false;
1054 return value != (unsigned int)-1 || !PyErr_Occurred();
1055 }
1056 };
1057
1058 template<>
pyopencv_from(const uchar & value)1059 PyObject* pyopencv_from(const uchar& value)
1060 {
1061 return PyInt_FromLong(value);
1062 }
1063
1064 template<>
pyopencv_to(PyObject * obj,uchar & value,const ArgInfo & info)1065 bool pyopencv_to(PyObject* obj, uchar& value, const ArgInfo& info)
1066 {
1067 CV_UNUSED(info);
1068 if(!obj || obj == Py_None)
1069 return true;
1070 int ivalue = (int)PyInt_AsLong(obj);
1071 value = cv::saturate_cast<uchar>(ivalue);
1072 return ivalue != -1 || !PyErr_Occurred();
1073 }
1074
1075 template<>
pyopencv_from(const double & value)1076 PyObject* pyopencv_from(const double& value)
1077 {
1078 return PyFloat_FromDouble(value);
1079 }
1080
1081 template<>
pyopencv_to(PyObject * obj,double & value,const ArgInfo & info)1082 bool pyopencv_to(PyObject* obj, double& value, const ArgInfo& info)
1083 {
1084 if (!obj || obj == Py_None)
1085 {
1086 return true;
1087 }
1088 if (isBool(obj))
1089 {
1090 failmsg("Argument '%s' must be double, not bool", info.name);
1091 return false;
1092 }
1093 if (PyArray_IsPythonNumber(obj))
1094 {
1095 if (PyLong_Check(obj))
1096 {
1097 value = PyLong_AsDouble(obj);
1098 }
1099 else
1100 {
1101 value = PyFloat_AsDouble(obj);
1102 }
1103 }
1104 else if (PyArray_CheckScalar(obj))
1105 {
1106 const bool isParsed = parseNumpyScalar<double>(obj, value);
1107 if (!isParsed) {
1108 failmsg("Argument '%s' can not be safely parsed to 'double'", info.name);
1109 return false;
1110 }
1111 }
1112 else
1113 {
1114 failmsg("Argument '%s' can not be treated as a double", info.name);
1115 return false;
1116 }
1117 return !PyErr_Occurred();
1118 }
1119
1120 template<>
pyopencv_from(const float & value)1121 PyObject* pyopencv_from(const float& value)
1122 {
1123 return PyFloat_FromDouble(value);
1124 }
1125
1126 template<>
pyopencv_to(PyObject * obj,float & value,const ArgInfo & info)1127 bool pyopencv_to(PyObject* obj, float& value, const ArgInfo& info)
1128 {
1129 if (!obj || obj == Py_None)
1130 {
1131 return true;
1132 }
1133 if (isBool(obj))
1134 {
1135 failmsg("Argument '%s' must be float, not bool", info.name);
1136 return false;
1137 }
1138 if (PyArray_IsPythonNumber(obj))
1139 {
1140 if (PyLong_Check(obj))
1141 {
1142 double res = PyLong_AsDouble(obj);
1143 value = static_cast<float>(res);
1144 }
1145 else
1146 {
1147 double res = PyFloat_AsDouble(obj);
1148 value = static_cast<float>(res);
1149 }
1150 }
1151 else if (PyArray_CheckScalar(obj))
1152 {
1153 const bool isParsed = parseNumpyScalar<float>(obj, value);
1154 if (!isParsed) {
1155 failmsg("Argument '%s' can not be safely parsed to 'float'", info.name);
1156 return false;
1157 }
1158 }
1159 else
1160 {
1161 failmsg("Argument '%s' can't be treated as a float", info.name);
1162 return false;
1163 }
1164 return !PyErr_Occurred();
1165 }
1166
1167 template<>
pyopencv_from(const int64 & value)1168 PyObject* pyopencv_from(const int64& value)
1169 {
1170 return PyLong_FromLongLong(value);
1171 }
1172
1173 template<>
pyopencv_from(const String & value)1174 PyObject* pyopencv_from(const String& value)
1175 {
1176 return PyString_FromString(value.empty() ? "" : value.c_str());
1177 }
1178
1179 #if CV_VERSION_MAJOR == 3
1180 template<>
pyopencv_from(const std::string & value)1181 PyObject* pyopencv_from(const std::string& value)
1182 {
1183 return PyString_FromString(value.empty() ? "" : value.c_str());
1184 }
1185 #endif
1186
1187 template<>
pyopencv_to(PyObject * obj,String & value,const ArgInfo & info)1188 bool pyopencv_to(PyObject* obj, String &value, const ArgInfo& info)
1189 {
1190 if(!obj || obj == Py_None)
1191 {
1192 return true;
1193 }
1194 std::string str;
1195 if (getUnicodeString(obj, str))
1196 {
1197 value = str;
1198 return true;
1199 }
1200 else
1201 {
1202 // If error hasn't been already set by Python conversion functions
1203 if (!PyErr_Occurred())
1204 {
1205 // Direct access to underlying slots of PyObjectType is not allowed
1206 // when limited API is enabled
1207 #ifdef Py_LIMITED_API
1208 failmsg("Can't convert object to 'str' for '%s'", info.name);
1209 #else
1210 failmsg("Can't convert object of type '%s' to 'str' for '%s'",
1211 obj->ob_type->tp_name, info.name);
1212 #endif
1213 }
1214 }
1215 return false;
1216 }
1217
1218 template<>
pyopencv_to(PyObject * obj,Size & sz,const ArgInfo & info)1219 bool pyopencv_to(PyObject* obj, Size& sz, const ArgInfo& info)
1220 {
1221 RefWrapper<int> values[] = {RefWrapper<int>(sz.width),
1222 RefWrapper<int>(sz.height)};
1223 return parseSequence(obj, values, info);
1224 }
1225
1226 template<>
pyopencv_from(const Size & sz)1227 PyObject* pyopencv_from(const Size& sz)
1228 {
1229 return Py_BuildValue("(ii)", sz.width, sz.height);
1230 }
1231
1232 template<>
pyopencv_to(PyObject * obj,Size_<float> & sz,const ArgInfo & info)1233 bool pyopencv_to(PyObject* obj, Size_<float>& sz, const ArgInfo& info)
1234 {
1235 RefWrapper<float> values[] = {RefWrapper<float>(sz.width),
1236 RefWrapper<float>(sz.height)};
1237 return parseSequence(obj, values, info);
1238 }
1239
1240 template<>
pyopencv_from(const Size_<float> & sz)1241 PyObject* pyopencv_from(const Size_<float>& sz)
1242 {
1243 return Py_BuildValue("(ff)", sz.width, sz.height);
1244 }
1245
1246 template<>
pyopencv_to(PyObject * obj,Rect & r,const ArgInfo & info)1247 bool pyopencv_to(PyObject* obj, Rect& r, const ArgInfo& info)
1248 {
1249 RefWrapper<int> values[] = {RefWrapper<int>(r.x), RefWrapper<int>(r.y),
1250 RefWrapper<int>(r.width),
1251 RefWrapper<int>(r.height)};
1252 return parseSequence(obj, values, info);
1253 }
1254
1255 template<>
pyopencv_from(const Rect & r)1256 PyObject* pyopencv_from(const Rect& r)
1257 {
1258 return Py_BuildValue("(iiii)", r.x, r.y, r.width, r.height);
1259 }
1260
1261 template<>
pyopencv_to(PyObject * obj,Rect2d & r,const ArgInfo & info)1262 bool pyopencv_to(PyObject* obj, Rect2d& r, const ArgInfo& info)
1263 {
1264 RefWrapper<double> values[] = {
1265 RefWrapper<double>(r.x), RefWrapper<double>(r.y),
1266 RefWrapper<double>(r.width), RefWrapper<double>(r.height)};
1267 return parseSequence(obj, values, info);
1268 }
1269
1270 template<>
pyopencv_from(const Rect2d & r)1271 PyObject* pyopencv_from(const Rect2d& r)
1272 {
1273 return Py_BuildValue("(dddd)", r.x, r.y, r.width, r.height);
1274 }
1275
1276 template<>
pyopencv_to(PyObject * obj,Range & r,const ArgInfo & info)1277 bool pyopencv_to(PyObject* obj, Range& r, const ArgInfo& info)
1278 {
1279 if (!obj || obj == Py_None)
1280 {
1281 return true;
1282 }
1283 if (PyObject_Size(obj) == 0)
1284 {
1285 r = Range::all();
1286 return true;
1287 }
1288 RefWrapper<int> values[] = {RefWrapper<int>(r.start), RefWrapper<int>(r.end)};
1289 return parseSequence(obj, values, info);
1290 }
1291
1292 template<>
pyopencv_from(const Range & r)1293 PyObject* pyopencv_from(const Range& r)
1294 {
1295 return Py_BuildValue("(ii)", r.start, r.end);
1296 }
1297
1298 template<>
pyopencv_to(PyObject * obj,Point & p,const ArgInfo & info)1299 bool pyopencv_to(PyObject* obj, Point& p, const ArgInfo& info)
1300 {
1301 RefWrapper<int> values[] = {RefWrapper<int>(p.x), RefWrapper<int>(p.y)};
1302 return parseSequence(obj, values, info);
1303 }
1304
1305 template <>
pyopencv_to(PyObject * obj,Point2f & p,const ArgInfo & info)1306 bool pyopencv_to(PyObject* obj, Point2f& p, const ArgInfo& info)
1307 {
1308 RefWrapper<float> values[] = {RefWrapper<float>(p.x),
1309 RefWrapper<float>(p.y)};
1310 return parseSequence(obj, values, info);
1311 }
1312
1313 template<>
pyopencv_to(PyObject * obj,Point2d & p,const ArgInfo & info)1314 bool pyopencv_to(PyObject* obj, Point2d& p, const ArgInfo& info)
1315 {
1316 RefWrapper<double> values[] = {RefWrapper<double>(p.x),
1317 RefWrapper<double>(p.y)};
1318 return parseSequence(obj, values, info);
1319 }
1320
1321 template<>
pyopencv_to(PyObject * obj,Point3f & p,const ArgInfo & info)1322 bool pyopencv_to(PyObject* obj, Point3f& p, const ArgInfo& info)
1323 {
1324 RefWrapper<float> values[] = {RefWrapper<float>(p.x),
1325 RefWrapper<float>(p.y),
1326 RefWrapper<float>(p.z)};
1327 return parseSequence(obj, values, info);
1328 }
1329
1330 template<>
pyopencv_to(PyObject * obj,Point3d & p,const ArgInfo & info)1331 bool pyopencv_to(PyObject* obj, Point3d& p, const ArgInfo& info)
1332 {
1333 RefWrapper<double> values[] = {RefWrapper<double>(p.x),
1334 RefWrapper<double>(p.y),
1335 RefWrapper<double>(p.z)};
1336 return parseSequence(obj, values, info);
1337 }
1338
1339 template<>
pyopencv_from(const Point & p)1340 PyObject* pyopencv_from(const Point& p)
1341 {
1342 return Py_BuildValue("(ii)", p.x, p.y);
1343 }
1344
1345 template<>
pyopencv_from(const Point2f & p)1346 PyObject* pyopencv_from(const Point2f& p)
1347 {
1348 return Py_BuildValue("(dd)", p.x, p.y);
1349 }
1350
1351 template<>
pyopencv_from(const Point3f & p)1352 PyObject* pyopencv_from(const Point3f& p)
1353 {
1354 return Py_BuildValue("(ddd)", p.x, p.y, p.z);
1355 }
1356
pyopencv_to(PyObject * obj,Vec4d & v,ArgInfo & info)1357 static bool pyopencv_to(PyObject* obj, Vec4d& v, ArgInfo& info)
1358 {
1359 RefWrapper<double> values[] = {RefWrapper<double>(v[0]), RefWrapper<double>(v[1]),
1360 RefWrapper<double>(v[2]), RefWrapper<double>(v[3])};
1361 return parseSequence(obj, values, info);
1362 }
1363
pyopencv_to(PyObject * obj,Vec4f & v,ArgInfo & info)1364 static bool pyopencv_to(PyObject* obj, Vec4f& v, ArgInfo& info)
1365 {
1366 RefWrapper<float> values[] = {RefWrapper<float>(v[0]), RefWrapper<float>(v[1]),
1367 RefWrapper<float>(v[2]), RefWrapper<float>(v[3])};
1368 return parseSequence(obj, values, info);
1369 }
1370
pyopencv_to(PyObject * obj,Vec4i & v,ArgInfo & info)1371 static bool pyopencv_to(PyObject* obj, Vec4i& v, ArgInfo& info)
1372 {
1373 RefWrapper<int> values[] = {RefWrapper<int>(v[0]), RefWrapper<int>(v[1]),
1374 RefWrapper<int>(v[2]), RefWrapper<int>(v[3])};
1375 return parseSequence(obj, values, info);
1376 }
1377
pyopencv_to(PyObject * obj,Vec3d & v,ArgInfo & info)1378 static bool pyopencv_to(PyObject* obj, Vec3d& v, ArgInfo& info)
1379 {
1380 RefWrapper<double> values[] = {RefWrapper<double>(v[0]),
1381 RefWrapper<double>(v[1]),
1382 RefWrapper<double>(v[2])};
1383 return parseSequence(obj, values, info);
1384 }
1385
pyopencv_to(PyObject * obj,Vec3f & v,ArgInfo & info)1386 static bool pyopencv_to(PyObject* obj, Vec3f& v, ArgInfo& info)
1387 {
1388 RefWrapper<float> values[] = {RefWrapper<float>(v[0]),
1389 RefWrapper<float>(v[1]),
1390 RefWrapper<float>(v[2])};
1391 return parseSequence(obj, values, info);
1392 }
1393
pyopencv_to(PyObject * obj,Vec3i & v,ArgInfo & info)1394 static bool pyopencv_to(PyObject* obj, Vec3i& v, ArgInfo& info)
1395 {
1396 RefWrapper<int> values[] = {RefWrapper<int>(v[0]), RefWrapper<int>(v[1]),
1397 RefWrapper<int>(v[2])};
1398 return parseSequence(obj, values, info);
1399 }
1400
pyopencv_to(PyObject * obj,Vec2d & v,ArgInfo & info)1401 static bool pyopencv_to(PyObject* obj, Vec2d& v, ArgInfo& info)
1402 {
1403 RefWrapper<double> values[] = {RefWrapper<double>(v[0]),
1404 RefWrapper<double>(v[1])};
1405 return parseSequence(obj, values, info);
1406 }
1407
pyopencv_to(PyObject * obj,Vec2f & v,ArgInfo & info)1408 static bool pyopencv_to(PyObject* obj, Vec2f& v, ArgInfo& info)
1409 {
1410 RefWrapper<float> values[] = {RefWrapper<float>(v[0]),
1411 RefWrapper<float>(v[1])};
1412 return parseSequence(obj, values, info);
1413 }
1414
pyopencv_to(PyObject * obj,Vec2i & v,ArgInfo & info)1415 static bool pyopencv_to(PyObject* obj, Vec2i& v, ArgInfo& info)
1416 {
1417 RefWrapper<int> values[] = {RefWrapper<int>(v[0]), RefWrapper<int>(v[1])};
1418 return parseSequence(obj, values, info);
1419 }
1420
1421 template<>
pyopencv_from(const Vec4d & v)1422 PyObject* pyopencv_from(const Vec4d& v)
1423 {
1424 return Py_BuildValue("(dddd)", v[0], v[1], v[2], v[3]);
1425 }
1426
1427 template<>
pyopencv_from(const Vec4f & v)1428 PyObject* pyopencv_from(const Vec4f& v)
1429 {
1430 return Py_BuildValue("(ffff)", v[0], v[1], v[2], v[3]);
1431 }
1432
1433 template<>
pyopencv_from(const Vec4i & v)1434 PyObject* pyopencv_from(const Vec4i& v)
1435 {
1436 return Py_BuildValue("(iiii)", v[0], v[1], v[2], v[3]);
1437 }
1438
1439 template<>
pyopencv_from(const Vec3d & v)1440 PyObject* pyopencv_from(const Vec3d& v)
1441 {
1442 return Py_BuildValue("(ddd)", v[0], v[1], v[2]);
1443 }
1444
1445 template<>
pyopencv_from(const Vec3f & v)1446 PyObject* pyopencv_from(const Vec3f& v)
1447 {
1448 return Py_BuildValue("(fff)", v[0], v[1], v[2]);
1449 }
1450
1451 template<>
pyopencv_from(const Vec3i & v)1452 PyObject* pyopencv_from(const Vec3i& v)
1453 {
1454 return Py_BuildValue("(iii)", v[0], v[1], v[2]);
1455 }
1456
1457 template<>
pyopencv_from(const Vec2d & v)1458 PyObject* pyopencv_from(const Vec2d& v)
1459 {
1460 return Py_BuildValue("(dd)", v[0], v[1]);
1461 }
1462
1463 template<>
pyopencv_from(const Vec2f & v)1464 PyObject* pyopencv_from(const Vec2f& v)
1465 {
1466 return Py_BuildValue("(ff)", v[0], v[1]);
1467 }
1468
1469 template<>
pyopencv_from(const Vec2i & v)1470 PyObject* pyopencv_from(const Vec2i& v)
1471 {
1472 return Py_BuildValue("(ii)", v[0], v[1]);
1473 }
1474
1475 template<>
pyopencv_from(const Point2d & p)1476 PyObject* pyopencv_from(const Point2d& p)
1477 {
1478 return Py_BuildValue("(dd)", p.x, p.y);
1479 }
1480
1481 template<>
pyopencv_from(const Point3d & p)1482 PyObject* pyopencv_from(const Point3d& p)
1483 {
1484 return Py_BuildValue("(ddd)", p.x, p.y, p.z);
1485 }
1486
1487 template<typename _Tp> struct pyopencvVecConverter
1488 {
1489 typedef typename DataType<_Tp>::channel_type _Cp;
copyOneItempyopencvVecConverter1490 static inline bool copyOneItem(PyObject *obj, size_t start, int channels, _Cp * data)
1491 {
1492 for(size_t j = 0; (int)j < channels; j++ )
1493 {
1494 SafeSeqItem sub_item_wrap(obj, start + j);
1495 PyObject* item_ij = sub_item_wrap.item;
1496 if( PyInt_Check(item_ij))
1497 {
1498 int v = (int)PyInt_AsLong(item_ij);
1499 if( v == -1 && PyErr_Occurred() )
1500 return false;
1501 data[j] = saturate_cast<_Cp>(v);
1502 }
1503 else if( PyLong_Check(item_ij))
1504 {
1505 int v = (int)PyLong_AsLong(item_ij);
1506 if( v == -1 && PyErr_Occurred() )
1507 return false;
1508 data[j] = saturate_cast<_Cp>(v);
1509 }
1510 else if( PyFloat_Check(item_ij))
1511 {
1512 double v = PyFloat_AsDouble(item_ij);
1513 if( PyErr_Occurred() )
1514 return false;
1515 data[j] = saturate_cast<_Cp>(v);
1516 }
1517 else
1518 return false;
1519 }
1520 return true;
1521 }
topyopencvVecConverter1522 static bool to(PyObject* obj, std::vector<_Tp>& value, const ArgInfo& info)
1523 {
1524 if(!obj || obj == Py_None)
1525 return true;
1526 if (PyArray_Check(obj))
1527 {
1528 Mat m;
1529 pyopencv_to(obj, m, info);
1530 m.copyTo(value);
1531 return true;
1532 }
1533 else if (PySequence_Check(obj))
1534 {
1535 const int type = traits::Type<_Tp>::value;
1536 const int depth = CV_MAT_DEPTH(type), channels = CV_MAT_CN(type);
1537 size_t i, n = PySequence_Size(obj);
1538 value.resize(n);
1539 for (i = 0; i < n; i++ )
1540 {
1541 SafeSeqItem item_wrap(obj, i);
1542 PyObject* item = item_wrap.item;
1543 _Cp* data = (_Cp*)&value[i];
1544
1545 if( channels == 2 && PyComplex_Check(item) )
1546 {
1547 data[0] = saturate_cast<_Cp>(PyComplex_RealAsDouble(item));
1548 data[1] = saturate_cast<_Cp>(PyComplex_ImagAsDouble(item));
1549 }
1550 else if( channels > 1 )
1551 {
1552 if( PyArray_Check(item))
1553 {
1554 Mat src;
1555 pyopencv_to(item, src, info);
1556 if( src.dims != 2 || src.channels() != 1 ||
1557 ((src.cols != 1 || src.rows != channels) &&
1558 (src.cols != channels || src.rows != 1)))
1559 break;
1560 Mat dst(src.rows, src.cols, depth, data);
1561 src.convertTo(dst, type);
1562 if( dst.data != (uchar*)data )
1563 break;
1564 }
1565 else if (PySequence_Check(item))
1566 {
1567 if (!copyOneItem(item, 0, channels, data))
1568 break;
1569 }
1570 else
1571 {
1572 break;
1573 }
1574 }
1575 else if (channels == 1)
1576 {
1577 if (!copyOneItem(obj, i, channels, data))
1578 break;
1579 }
1580 else
1581 {
1582 break;
1583 }
1584 }
1585 if (i != n)
1586 {
1587 failmsg("Can't convert vector element for '%s', index=%d", info.name, i);
1588 }
1589 return i == n;
1590 }
1591 failmsg("Can't convert object to vector for '%s', unsupported type", info.name);
1592 return false;
1593 }
1594
frompyopencvVecConverter1595 static PyObject* from(const std::vector<_Tp>& value)
1596 {
1597 if(value.empty())
1598 return PyTuple_New(0);
1599 int type = traits::Type<_Tp>::value;
1600 int depth = CV_MAT_DEPTH(type), channels = CV_MAT_CN(type);
1601 Mat src((int)value.size(), channels, depth, (uchar*)&value[0]);
1602 return pyopencv_from(src);
1603 }
1604 };
1605
1606 template<typename _Tp>
pyopencv_to(PyObject * obj,std::vector<_Tp> & value,const ArgInfo & info)1607 bool pyopencv_to(PyObject* obj, std::vector<_Tp>& value, const ArgInfo& info)
1608 {
1609 return pyopencvVecConverter<_Tp>::to(obj, value, info);
1610 }
1611
1612 template<typename _Tp>
pyopencv_from(const std::vector<_Tp> & value)1613 PyObject* pyopencv_from(const std::vector<_Tp>& value)
1614 {
1615 return pyopencvVecConverter<_Tp>::from(value);
1616 }
1617
pyopencv_to_generic_vec(PyObject * obj,std::vector<_Tp> & value,const ArgInfo & info)1618 template<typename _Tp> static inline bool pyopencv_to_generic_vec(PyObject* obj, std::vector<_Tp>& value, const ArgInfo& info)
1619 {
1620 if(!obj || obj == Py_None)
1621 return true;
1622 if (!PySequence_Check(obj))
1623 return false;
1624 size_t n = PySequence_Size(obj);
1625 value.resize(n);
1626 for(size_t i = 0; i < n; i++ )
1627 {
1628 SafeSeqItem item_wrap(obj, i);
1629 if(!pyopencv_to(item_wrap.item, value[i], info))
1630 return false;
1631 }
1632 return true;
1633 }
1634
pyopencv_to_generic_vec(PyObject * obj,std::vector<bool> & value,const ArgInfo & info)1635 template<> inline bool pyopencv_to_generic_vec(PyObject* obj, std::vector<bool>& value, const ArgInfo& info)
1636 {
1637 if(!obj || obj == Py_None)
1638 return true;
1639 if (!PySequence_Check(obj))
1640 return false;
1641 size_t n = PySequence_Size(obj);
1642 value.resize(n);
1643 for(size_t i = 0; i < n; i++ )
1644 {
1645 SafeSeqItem item_wrap(obj, i);
1646 bool elem{};
1647 if(!pyopencv_to(item_wrap.item, elem, info))
1648 return false;
1649 value[i] = elem;
1650 }
1651 return true;
1652 }
1653
pyopencv_from_generic_vec(const std::vector<_Tp> & value)1654 template<typename _Tp> static inline PyObject* pyopencv_from_generic_vec(const std::vector<_Tp>& value)
1655 {
1656 int i, n = (int)value.size();
1657 PyObject* seq = PyList_New(n);
1658 for( i = 0; i < n; i++ )
1659 {
1660 _Tp elem = value[i];
1661 PyObject* item = pyopencv_from(elem);
1662 if(!item)
1663 break;
1664 PyList_SetItem(seq, i, item);
1665 }
1666 if( i < n )
1667 {
1668 Py_DECREF(seq);
1669 return 0;
1670 }
1671 return seq;
1672 }
1673
pyopencv_from_generic_vec(const std::vector<bool> & value)1674 template<> inline PyObject* pyopencv_from_generic_vec(const std::vector<bool>& value)
1675 {
1676 int i, n = (int)value.size();
1677 PyObject* seq = PyList_New(n);
1678 for( i = 0; i < n; i++ )
1679 {
1680 bool elem = value[i];
1681 PyObject* item = pyopencv_from(elem);
1682 if(!item)
1683 break;
1684 PyList_SetItem(seq, i, item);
1685 }
1686 if( i < n )
1687 {
1688 Py_DECREF(seq);
1689 return 0;
1690 }
1691 return seq;
1692 }
1693
1694 template<std::size_t I = 0, typename... Tp>
1695 inline typename std::enable_if<I == sizeof...(Tp), void>::type
convert_to_python_tuple(const std::tuple<Tp...> &,PyObject *)1696 convert_to_python_tuple(const std::tuple<Tp...>&, PyObject*) { }
1697
1698 template<std::size_t I = 0, typename... Tp>
1699 inline typename std::enable_if<I < sizeof...(Tp), void>::type
1700 convert_to_python_tuple(const std::tuple<Tp...>& cpp_tuple, PyObject* py_tuple)
1701 {
1702 PyObject* item = pyopencv_from(std::get<I>(cpp_tuple));
1703
1704 if (!item)
1705 return;
1706
1707 PyTuple_SetItem(py_tuple, I, item);
1708 convert_to_python_tuple<I + 1, Tp...>(cpp_tuple, py_tuple);
1709 }
1710
1711
1712 template<typename... Ts>
pyopencv_from(const std::tuple<Ts...> & cpp_tuple)1713 PyObject* pyopencv_from(const std::tuple<Ts...>& cpp_tuple)
1714 {
1715 size_t size = sizeof...(Ts);
1716 PyObject* py_tuple = PyTuple_New(size);
1717 convert_to_python_tuple(cpp_tuple, py_tuple);
1718 size_t actual_size = PyTuple_Size(py_tuple);
1719
1720 if (actual_size < size)
1721 {
1722 Py_DECREF(py_tuple);
1723 return NULL;
1724 }
1725
1726 return py_tuple;
1727 }
1728
1729 template<>
pyopencv_from(const std::pair<int,double> & src)1730 PyObject* pyopencv_from(const std::pair<int, double>& src)
1731 {
1732 return Py_BuildValue("(id)", src.first, src.second);
1733 }
1734
1735 template<typename _Tp, typename _Tr> struct pyopencvVecConverter<std::pair<_Tp, _Tr> >
1736 {
topyopencvVecConverter1737 static bool to(PyObject* obj, std::vector<std::pair<_Tp, _Tr> >& value, const ArgInfo& info)
1738 {
1739 return pyopencv_to_generic_vec(obj, value, info);
1740 }
1741
frompyopencvVecConverter1742 static PyObject* from(const std::vector<std::pair<_Tp, _Tr> >& value)
1743 {
1744 return pyopencv_from_generic_vec(value);
1745 }
1746 };
1747
1748 template<typename _Tp> struct pyopencvVecConverter<std::vector<_Tp> >
1749 {
topyopencvVecConverter1750 static bool to(PyObject* obj, std::vector<std::vector<_Tp> >& value, const ArgInfo& info)
1751 {
1752 return pyopencv_to_generic_vec(obj, value, info);
1753 }
1754
frompyopencvVecConverter1755 static PyObject* from(const std::vector<std::vector<_Tp> >& value)
1756 {
1757 return pyopencv_from_generic_vec(value);
1758 }
1759 };
1760
1761 template<> struct pyopencvVecConverter<Mat>
1762 {
topyopencvVecConverter1763 static bool to(PyObject* obj, std::vector<Mat>& value, const ArgInfo& info)
1764 {
1765 return pyopencv_to_generic_vec(obj, value, info);
1766 }
1767
frompyopencvVecConverter1768 static PyObject* from(const std::vector<Mat>& value)
1769 {
1770 return pyopencv_from_generic_vec(value);
1771 }
1772 };
1773
1774 template<> struct pyopencvVecConverter<UMat>
1775 {
topyopencvVecConverter1776 static bool to(PyObject* obj, std::vector<UMat>& value, const ArgInfo& info)
1777 {
1778 return pyopencv_to_generic_vec(obj, value, info);
1779 }
1780
frompyopencvVecConverter1781 static PyObject* from(const std::vector<UMat>& value)
1782 {
1783 return pyopencv_from_generic_vec(value);
1784 }
1785 };
1786
1787 template<> struct pyopencvVecConverter<KeyPoint>
1788 {
topyopencvVecConverter1789 static bool to(PyObject* obj, std::vector<KeyPoint>& value, const ArgInfo& info)
1790 {
1791 return pyopencv_to_generic_vec(obj, value, info);
1792 }
1793
frompyopencvVecConverter1794 static PyObject* from(const std::vector<KeyPoint>& value)
1795 {
1796 return pyopencv_from_generic_vec(value);
1797 }
1798 };
1799
1800 template<> struct pyopencvVecConverter<DMatch>
1801 {
topyopencvVecConverter1802 static bool to(PyObject* obj, std::vector<DMatch>& value, const ArgInfo& info)
1803 {
1804 return pyopencv_to_generic_vec(obj, value, info);
1805 }
1806
frompyopencvVecConverter1807 static PyObject* from(const std::vector<DMatch>& value)
1808 {
1809 return pyopencv_from_generic_vec(value);
1810 }
1811 };
1812
1813 template<> struct pyopencvVecConverter<String>
1814 {
topyopencvVecConverter1815 static bool to(PyObject* obj, std::vector<String>& value, const ArgInfo& info)
1816 {
1817 return pyopencv_to_generic_vec(obj, value, info);
1818 }
1819
frompyopencvVecConverter1820 static PyObject* from(const std::vector<String>& value)
1821 {
1822 return pyopencv_from_generic_vec(value);
1823 }
1824 };
1825
1826 template<> struct pyopencvVecConverter<RotatedRect>
1827 {
topyopencvVecConverter1828 static bool to(PyObject* obj, std::vector<RotatedRect>& value, const ArgInfo& info)
1829 {
1830 return pyopencv_to_generic_vec(obj, value, info);
1831 }
frompyopencvVecConverter1832 static PyObject* from(const std::vector<RotatedRect>& value)
1833 {
1834 return pyopencv_from_generic_vec(value);
1835 }
1836 };
1837
1838 template<>
pyopencv_to(PyObject * obj,TermCriteria & dst,const ArgInfo & info)1839 bool pyopencv_to(PyObject* obj, TermCriteria& dst, const ArgInfo& info)
1840 {
1841 if (!obj || obj == Py_None)
1842 {
1843 return true;
1844 }
1845 if (!PySequence_Check(obj))
1846 {
1847 failmsg("Can't parse '%s' as TermCriteria."
1848 "Input argument doesn't provide sequence protocol",
1849 info.name);
1850 return false;
1851 }
1852 const std::size_t sequenceSize = PySequence_Size(obj);
1853 if (sequenceSize != 3) {
1854 failmsg("Can't parse '%s' as TermCriteria. Expected sequence length 3, "
1855 "got %lu",
1856 info.name, sequenceSize);
1857 return false;
1858 }
1859 {
1860 const String typeItemName = format("'%s' criteria type", info.name);
1861 const ArgInfo typeItemInfo(typeItemName.c_str(), false);
1862 SafeSeqItem typeItem(obj, 0);
1863 if (!pyopencv_to(typeItem.item, dst.type, typeItemInfo))
1864 {
1865 return false;
1866 }
1867 }
1868 {
1869 const String maxCountItemName = format("'%s' max count", info.name);
1870 const ArgInfo maxCountItemInfo(maxCountItemName.c_str(), false);
1871 SafeSeqItem maxCountItem(obj, 1);
1872 if (!pyopencv_to(maxCountItem.item, dst.maxCount, maxCountItemInfo))
1873 {
1874 return false;
1875 }
1876 }
1877 {
1878 const String epsilonItemName = format("'%s' epsilon", info.name);
1879 const ArgInfo epsilonItemInfo(epsilonItemName.c_str(), false);
1880 SafeSeqItem epsilonItem(obj, 2);
1881 if (!pyopencv_to(epsilonItem.item, dst.epsilon, epsilonItemInfo))
1882 {
1883 return false;
1884 }
1885 }
1886 return true;
1887 }
1888
1889 template<>
pyopencv_from(const TermCriteria & src)1890 PyObject* pyopencv_from(const TermCriteria& src)
1891 {
1892 return Py_BuildValue("(iid)", src.type, src.maxCount, src.epsilon);
1893 }
1894
1895 template<>
pyopencv_to(PyObject * obj,RotatedRect & dst,const ArgInfo & info)1896 bool pyopencv_to(PyObject* obj, RotatedRect& dst, const ArgInfo& info)
1897 {
1898 if (!obj || obj == Py_None)
1899 {
1900 return true;
1901 }
1902 if (!PySequence_Check(obj))
1903 {
1904 failmsg("Can't parse '%s' as RotatedRect."
1905 "Input argument doesn't provide sequence protocol",
1906 info.name);
1907 return false;
1908 }
1909 const std::size_t sequenceSize = PySequence_Size(obj);
1910 if (sequenceSize != 3)
1911 {
1912 failmsg("Can't parse '%s' as RotatedRect. Expected sequence length 3, got %lu",
1913 info.name, sequenceSize);
1914 return false;
1915 }
1916 {
1917 const String centerItemName = format("'%s' center point", info.name);
1918 const ArgInfo centerItemInfo(centerItemName.c_str(), false);
1919 SafeSeqItem centerItem(obj, 0);
1920 if (!pyopencv_to(centerItem.item, dst.center, centerItemInfo))
1921 {
1922 return false;
1923 }
1924 }
1925 {
1926 const String sizeItemName = format("'%s' size", info.name);
1927 const ArgInfo sizeItemInfo(sizeItemName.c_str(), false);
1928 SafeSeqItem sizeItem(obj, 1);
1929 if (!pyopencv_to(sizeItem.item, dst.size, sizeItemInfo))
1930 {
1931 return false;
1932 }
1933 }
1934 {
1935 const String angleItemName = format("'%s' angle", info.name);
1936 const ArgInfo angleItemInfo(angleItemName.c_str(), false);
1937 SafeSeqItem angleItem(obj, 2);
1938 if (!pyopencv_to(angleItem.item, dst.angle, angleItemInfo))
1939 {
1940 return false;
1941 }
1942 }
1943 return true;
1944 }
1945
1946 template<>
pyopencv_from(const RotatedRect & src)1947 PyObject* pyopencv_from(const RotatedRect& src)
1948 {
1949 return Py_BuildValue("((ff)(ff)f)", src.center.x, src.center.y, src.size.width, src.size.height, src.angle);
1950 }
1951
1952 template<>
pyopencv_from(const Moments & m)1953 PyObject* pyopencv_from(const Moments& m)
1954 {
1955 return Py_BuildValue("{s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d}",
1956 "m00", m.m00, "m10", m.m10, "m01", m.m01,
1957 "m20", m.m20, "m11", m.m11, "m02", m.m02,
1958 "m30", m.m30, "m21", m.m21, "m12", m.m12, "m03", m.m03,
1959 "mu20", m.mu20, "mu11", m.mu11, "mu02", m.mu02,
1960 "mu30", m.mu30, "mu21", m.mu21, "mu12", m.mu12, "mu03", m.mu03,
1961 "nu20", m.nu20, "nu11", m.nu11, "nu02", m.nu02,
1962 "nu30", m.nu30, "nu21", m.nu21, "nu12", m.nu12, "nu03", m.nu03);
1963 }
1964
OnError(int status,const char * func_name,const char * err_msg,const char * file_name,int line,void * userdata)1965 static int OnError(int status, const char *func_name, const char *err_msg, const char *file_name, int line, void *userdata)
1966 {
1967 PyGILState_STATE gstate;
1968 gstate = PyGILState_Ensure();
1969
1970 PyObject *on_error = (PyObject*)userdata;
1971 PyObject *args = Py_BuildValue("isssi", status, func_name, err_msg, file_name, line);
1972
1973 PyObject *r = PyObject_Call(on_error, args, NULL);
1974 if (r == NULL) {
1975 PyErr_Print();
1976 } else {
1977 Py_DECREF(r);
1978 }
1979
1980 Py_DECREF(args);
1981 PyGILState_Release(gstate);
1982
1983 return 0; // The return value isn't used
1984 }
1985
pycvRedirectError(PyObject *,PyObject * args,PyObject * kw)1986 static PyObject *pycvRedirectError(PyObject*, PyObject *args, PyObject *kw)
1987 {
1988 const char *keywords[] = { "on_error", NULL };
1989 PyObject *on_error;
1990
1991 if (!PyArg_ParseTupleAndKeywords(args, kw, "O", (char**)keywords, &on_error))
1992 return NULL;
1993
1994 if ((on_error != Py_None) && !PyCallable_Check(on_error)) {
1995 PyErr_SetString(PyExc_TypeError, "on_error must be callable");
1996 return NULL;
1997 }
1998
1999 // Keep track of the previous handler parameter, so we can decref it when no longer used
2000 static PyObject* last_on_error = NULL;
2001 if (last_on_error) {
2002 Py_DECREF(last_on_error);
2003 last_on_error = NULL;
2004 }
2005
2006 if (on_error == Py_None) {
2007 ERRWRAP2(redirectError(NULL));
2008 } else {
2009 last_on_error = on_error;
2010 Py_INCREF(last_on_error);
2011 ERRWRAP2(redirectError(OnError, last_on_error));
2012 }
2013 Py_RETURN_NONE;
2014 }
2015
OnMouse(int event,int x,int y,int flags,void * param)2016 static void OnMouse(int event, int x, int y, int flags, void* param)
2017 {
2018 PyGILState_STATE gstate;
2019 gstate = PyGILState_Ensure();
2020
2021 PyObject *o = (PyObject*)param;
2022 PyObject *args = Py_BuildValue("iiiiO", event, x, y, flags, PyTuple_GetItem(o, 1));
2023
2024 PyObject *r = PyObject_Call(PyTuple_GetItem(o, 0), args, NULL);
2025 if (r == NULL)
2026 PyErr_Print();
2027 else
2028 Py_DECREF(r);
2029 Py_DECREF(args);
2030 PyGILState_Release(gstate);
2031 }
2032
2033 #ifdef HAVE_OPENCV_HIGHGUI
pycvSetMouseCallback(PyObject *,PyObject * args,PyObject * kw)2034 static PyObject *pycvSetMouseCallback(PyObject*, PyObject *args, PyObject *kw)
2035 {
2036 const char *keywords[] = { "window_name", "on_mouse", "param", NULL };
2037 char* name;
2038 PyObject *on_mouse;
2039 PyObject *param = NULL;
2040
2041 if (!PyArg_ParseTupleAndKeywords(args, kw, "sO|O", (char**)keywords, &name, &on_mouse, ¶m))
2042 return NULL;
2043 if (!PyCallable_Check(on_mouse)) {
2044 PyErr_SetString(PyExc_TypeError, "on_mouse must be callable");
2045 return NULL;
2046 }
2047 if (param == NULL) {
2048 param = Py_None;
2049 }
2050 PyObject* py_callback_info = Py_BuildValue("OO", on_mouse, param);
2051 static std::map<std::string, PyObject*> registered_callbacks;
2052 std::map<std::string, PyObject*>::iterator i = registered_callbacks.find(name);
2053 if (i != registered_callbacks.end())
2054 {
2055 Py_DECREF(i->second);
2056 i->second = py_callback_info;
2057 }
2058 else
2059 {
2060 registered_callbacks.insert(std::pair<std::string, PyObject*>(std::string(name), py_callback_info));
2061 }
2062 ERRWRAP2(setMouseCallback(name, OnMouse, py_callback_info));
2063 Py_RETURN_NONE;
2064 }
2065 #endif
2066
OnChange(int pos,void * param)2067 static void OnChange(int pos, void *param)
2068 {
2069 PyGILState_STATE gstate;
2070 gstate = PyGILState_Ensure();
2071
2072 PyObject *o = (PyObject*)param;
2073 PyObject *args = Py_BuildValue("(i)", pos);
2074 PyObject *r = PyObject_Call(PyTuple_GetItem(o, 0), args, NULL);
2075 if (r == NULL)
2076 PyErr_Print();
2077 else
2078 Py_DECREF(r);
2079 Py_DECREF(args);
2080 PyGILState_Release(gstate);
2081 }
2082
2083 #ifdef HAVE_OPENCV_HIGHGUI
pycvCreateTrackbar(PyObject *,PyObject * args)2084 static PyObject *pycvCreateTrackbar(PyObject*, PyObject *args)
2085 {
2086 PyObject *on_change;
2087 char* trackbar_name;
2088 char* window_name;
2089 int *value = new int;
2090 int count;
2091
2092 if (!PyArg_ParseTuple(args, "ssiiO", &trackbar_name, &window_name, value, &count, &on_change))
2093 return NULL;
2094 if (!PyCallable_Check(on_change)) {
2095 PyErr_SetString(PyExc_TypeError, "on_change must be callable");
2096 return NULL;
2097 }
2098 PyObject* py_callback_info = Py_BuildValue("OO", on_change, Py_None);
2099 std::string name = std::string(window_name) + ":" + std::string(trackbar_name);
2100 static std::map<std::string, PyObject*> registered_callbacks;
2101 std::map<std::string, PyObject*>::iterator i = registered_callbacks.find(name);
2102 if (i != registered_callbacks.end())
2103 {
2104 Py_DECREF(i->second);
2105 i->second = py_callback_info;
2106 }
2107 else
2108 {
2109 registered_callbacks.insert(std::pair<std::string, PyObject*>(name, py_callback_info));
2110 }
2111 ERRWRAP2(createTrackbar(trackbar_name, window_name, value, count, OnChange, py_callback_info));
2112 Py_RETURN_NONE;
2113 }
2114
OnButtonChange(int state,void * param)2115 static void OnButtonChange(int state, void *param)
2116 {
2117 PyGILState_STATE gstate;
2118 gstate = PyGILState_Ensure();
2119
2120 PyObject *o = (PyObject*)param;
2121 PyObject *args;
2122 if(PyTuple_GetItem(o, 1) != NULL)
2123 {
2124 args = Py_BuildValue("(iO)", state, PyTuple_GetItem(o,1));
2125 }
2126 else
2127 {
2128 args = Py_BuildValue("(i)", state);
2129 }
2130
2131 PyObject *r = PyObject_Call(PyTuple_GetItem(o, 0), args, NULL);
2132 if (r == NULL)
2133 PyErr_Print();
2134 else
2135 Py_DECREF(r);
2136 Py_DECREF(args);
2137 PyGILState_Release(gstate);
2138 }
2139
pycvCreateButton(PyObject *,PyObject * args,PyObject * kw)2140 static PyObject *pycvCreateButton(PyObject*, PyObject *args, PyObject *kw)
2141 {
2142 const char* keywords[] = {"buttonName", "onChange", "userData", "buttonType", "initialButtonState", NULL};
2143 PyObject *on_change;
2144 PyObject *userdata = NULL;
2145 char* button_name;
2146 int button_type = 0;
2147 int initial_button_state = 0;
2148
2149 if (!PyArg_ParseTupleAndKeywords(args, kw, "sO|Oii", (char**)keywords, &button_name, &on_change, &userdata, &button_type, &initial_button_state))
2150 return NULL;
2151 if (!PyCallable_Check(on_change)) {
2152 PyErr_SetString(PyExc_TypeError, "onChange must be callable");
2153 return NULL;
2154 }
2155 if (userdata == NULL) {
2156 userdata = Py_None;
2157 }
2158
2159 PyObject* py_callback_info = Py_BuildValue("OO", on_change, userdata);
2160 std::string name(button_name);
2161
2162 static std::map<std::string, PyObject*> registered_callbacks;
2163 std::map<std::string, PyObject*>::iterator i = registered_callbacks.find(name);
2164 if (i != registered_callbacks.end())
2165 {
2166 Py_DECREF(i->second);
2167 i->second = py_callback_info;
2168 }
2169 else
2170 {
2171 registered_callbacks.insert(std::pair<std::string, PyObject*>(name, py_callback_info));
2172 }
2173 ERRWRAP2(createButton(button_name, OnButtonChange, py_callback_info, button_type, initial_button_state != 0));
2174 Py_RETURN_NONE;
2175 }
2176 #endif
2177
2178 ///////////////////////////////////////////////////////////////////////////////////////
2179
convert_to_char(PyObject * o,char * dst,const ArgInfo & info)2180 static int convert_to_char(PyObject *o, char *dst, const ArgInfo& info)
2181 {
2182 std::string str;
2183 if (getUnicodeString(o, str))
2184 {
2185 *dst = str[0];
2186 return 1;
2187 }
2188 (*dst) = 0;
2189 return failmsg("Expected single character string for argument '%s'", info.name);
2190 }
2191
2192 #ifdef __GNUC__
2193 # pragma GCC diagnostic ignored "-Wunused-parameter"
2194 # pragma GCC diagnostic ignored "-Wmissing-field-initializers"
2195 #endif
2196
2197
2198 #include "pyopencv_generated_enums.h"
2199
2200 #ifdef CVPY_DYNAMIC_INIT
2201 #define CVPY_TYPE(WNAME, NAME, STORAGE, SNAME, _1, _2) CVPY_TYPE_DECLARE_DYNAMIC(WNAME, NAME, STORAGE, SNAME)
2202 #else
2203 #define CVPY_TYPE(WNAME, NAME, STORAGE, SNAME, _1, _2) CVPY_TYPE_DECLARE(WNAME, NAME, STORAGE, SNAME)
2204 #endif
2205 #include "pyopencv_generated_types.h"
2206 #undef CVPY_TYPE
2207 #include "pyopencv_custom_headers.h"
2208
2209 #include "pyopencv_generated_types_content.h"
2210 #include "pyopencv_generated_funcs.h"
2211
2212 static PyMethodDef special_methods[] = {
2213 {"redirectError", CV_PY_FN_WITH_KW(pycvRedirectError), "redirectError(onError) -> None"},
2214 #ifdef HAVE_OPENCV_HIGHGUI
2215 {"createTrackbar", (PyCFunction)pycvCreateTrackbar, METH_VARARGS, "createTrackbar(trackbarName, windowName, value, count, onChange) -> None"},
2216 {"createButton", CV_PY_FN_WITH_KW(pycvCreateButton), "createButton(buttonName, onChange [, userData, buttonType, initialButtonState]) -> None"},
2217 {"setMouseCallback", CV_PY_FN_WITH_KW(pycvSetMouseCallback), "setMouseCallback(windowName, onMouse [, param]) -> None"},
2218 #endif
2219 #ifdef HAVE_OPENCV_DNN
2220 {"dnn_registerLayer", CV_PY_FN_WITH_KW(pyopencv_cv_dnn_registerLayer), "registerLayer(type, class) -> None"},
2221 {"dnn_unregisterLayer", CV_PY_FN_WITH_KW(pyopencv_cv_dnn_unregisterLayer), "unregisterLayer(type) -> None"},
2222 #endif
2223 {NULL, NULL},
2224 };
2225
2226 /************************************************************************/
2227 /* Module init */
2228
2229 struct ConstDef
2230 {
2231 const char * name;
2232 long long val;
2233 };
2234
init_submodule(PyObject * root,const char * name,PyMethodDef * methods,ConstDef * consts)2235 static void init_submodule(PyObject * root, const char * name, PyMethodDef * methods, ConstDef * consts)
2236 {
2237 // traverse and create nested submodules
2238 std::string s = name;
2239 size_t i = s.find('.');
2240 while (i < s.length() && i != std::string::npos)
2241 {
2242 size_t j = s.find('.', i);
2243 if (j == std::string::npos)
2244 j = s.length();
2245 std::string short_name = s.substr(i, j-i);
2246 std::string full_name = s.substr(0, j);
2247 i = j+1;
2248
2249 PyObject * d = PyModule_GetDict(root);
2250 PyObject * submod = PyDict_GetItemString(d, short_name.c_str());
2251 if (submod == NULL)
2252 {
2253 submod = PyImport_AddModule(full_name.c_str());
2254 PyDict_SetItemString(d, short_name.c_str(), submod);
2255 }
2256
2257 if (short_name != "")
2258 root = submod;
2259 }
2260
2261 // populate module's dict
2262 PyObject * d = PyModule_GetDict(root);
2263 for (PyMethodDef * m = methods; m->ml_name != NULL; ++m)
2264 {
2265 PyObject * method_obj = PyCFunction_NewEx(m, NULL, NULL);
2266 PyDict_SetItemString(d, m->ml_name, method_obj);
2267 Py_DECREF(method_obj);
2268 }
2269 for (ConstDef * c = consts; c->name != NULL; ++c)
2270 {
2271 PyDict_SetItemString(d, c->name, PyLong_FromLongLong(c->val));
2272 }
2273
2274 }
2275
2276 #include "pyopencv_generated_modules_content.h"
2277
init_body(PyObject * m)2278 static bool init_body(PyObject * m)
2279 {
2280 #define CVPY_MODULE(NAMESTR, NAME) \
2281 init_submodule(m, MODULESTR NAMESTR, methods_##NAME, consts_##NAME)
2282 #include "pyopencv_generated_modules.h"
2283 #undef CVPY_MODULE
2284
2285 #ifdef CVPY_DYNAMIC_INIT
2286 #define CVPY_TYPE(WNAME, NAME, _1, _2, BASE, CONSTRUCTOR) CVPY_TYPE_INIT_DYNAMIC(WNAME, NAME, return false, BASE, CONSTRUCTOR)
2287 PyObject * pyopencv_NoBase_TypePtr = NULL;
2288 #else
2289 #define CVPY_TYPE(WNAME, NAME, _1, _2, BASE, CONSTRUCTOR) CVPY_TYPE_INIT_STATIC(WNAME, NAME, return false, BASE, CONSTRUCTOR)
2290 PyTypeObject * pyopencv_NoBase_TypePtr = NULL;
2291 #endif
2292 #include "pyopencv_generated_types.h"
2293 #undef CVPY_TYPE
2294
2295 PyObject* d = PyModule_GetDict(m);
2296
2297
2298 PyDict_SetItemString(d, "__version__", PyString_FromString(CV_VERSION));
2299
2300 PyObject *opencv_error_dict = PyDict_New();
2301 PyDict_SetItemString(opencv_error_dict, "file", Py_None);
2302 PyDict_SetItemString(opencv_error_dict, "func", Py_None);
2303 PyDict_SetItemString(opencv_error_dict, "line", Py_None);
2304 PyDict_SetItemString(opencv_error_dict, "code", Py_None);
2305 PyDict_SetItemString(opencv_error_dict, "msg", Py_None);
2306 PyDict_SetItemString(opencv_error_dict, "err", Py_None);
2307 opencv_error = PyErr_NewException((char*)MODULESTR".error", NULL, opencv_error_dict);
2308 Py_DECREF(opencv_error_dict);
2309 PyDict_SetItemString(d, "error", opencv_error);
2310
2311
2312 #define PUBLISH(I) PyDict_SetItemString(d, #I, PyInt_FromLong(I))
2313 PUBLISH(CV_8U);
2314 PUBLISH(CV_8UC1);
2315 PUBLISH(CV_8UC2);
2316 PUBLISH(CV_8UC3);
2317 PUBLISH(CV_8UC4);
2318 PUBLISH(CV_8S);
2319 PUBLISH(CV_8SC1);
2320 PUBLISH(CV_8SC2);
2321 PUBLISH(CV_8SC3);
2322 PUBLISH(CV_8SC4);
2323 PUBLISH(CV_16U);
2324 PUBLISH(CV_16UC1);
2325 PUBLISH(CV_16UC2);
2326 PUBLISH(CV_16UC3);
2327 PUBLISH(CV_16UC4);
2328 PUBLISH(CV_16S);
2329 PUBLISH(CV_16SC1);
2330 PUBLISH(CV_16SC2);
2331 PUBLISH(CV_16SC3);
2332 PUBLISH(CV_16SC4);
2333 PUBLISH(CV_32S);
2334 PUBLISH(CV_32SC1);
2335 PUBLISH(CV_32SC2);
2336 PUBLISH(CV_32SC3);
2337 PUBLISH(CV_32SC4);
2338 PUBLISH(CV_32F);
2339 PUBLISH(CV_32FC1);
2340 PUBLISH(CV_32FC2);
2341 PUBLISH(CV_32FC3);
2342 PUBLISH(CV_32FC4);
2343 PUBLISH(CV_64F);
2344 PUBLISH(CV_64FC1);
2345 PUBLISH(CV_64FC2);
2346 PUBLISH(CV_64FC3);
2347 PUBLISH(CV_64FC4);
2348 #undef PUBLISH
2349
2350 return true;
2351 }
2352
2353 #if defined(__GNUC__)
2354 #pragma GCC visibility push(default)
2355 #endif
2356
2357 #if defined(CV_PYTHON_3)
2358 // === Python 3
2359
2360 static struct PyModuleDef cv2_moduledef =
2361 {
2362 PyModuleDef_HEAD_INIT,
2363 MODULESTR,
2364 "Python wrapper for OpenCV.",
2365 -1, /* size of per-interpreter state of the module,
2366 or -1 if the module keeps state in global variables. */
2367 special_methods
2368 };
2369
2370 PyMODINIT_FUNC PyInit_cv2();
PyInit_cv2()2371 PyObject* PyInit_cv2()
2372 {
2373 import_array(); // from numpy
2374 PyObject* m = PyModule_Create(&cv2_moduledef);
2375 if (!init_body(m))
2376 return NULL;
2377 return m;
2378 }
2379
2380 #else
2381 // === Python 2
2382 PyMODINIT_FUNC initcv2();
initcv2()2383 void initcv2()
2384 {
2385 import_array(); // from numpy
2386 PyObject* m = Py_InitModule(MODULESTR, special_methods);
2387 init_body(m);
2388 }
2389
2390 #endif
2391