cv2.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. // must be defined before importing numpy headers
  2. // https://numpy.org/doc/1.17/reference/c-api.array.html#importing-the-api
  3. #define PY_ARRAY_UNIQUE_SYMBOL opencv_ARRAY_API
  4. #include "cv2.hpp"
  5. #include "opencv2/opencv_modules.hpp"
  6. #include "opencv2/core.hpp"
  7. #include "opencv2/core/utils/logger.hpp"
  8. #include "pyopencv_generated_include.h"
  9. #include "opencv2/core/types_c.h"
  10. #include "cv2_util.hpp"
  11. #include "cv2_numpy.hpp"
  12. #include "cv2_convert.hpp"
  13. #include "cv2_highgui.hpp"
  14. using namespace cv;
  15. typedef std::vector<uchar> vector_uchar;
  16. typedef std::vector<char> vector_char;
  17. typedef std::vector<int> vector_int;
  18. typedef std::vector<float> vector_float;
  19. typedef std::vector<double> vector_double;
  20. typedef std::vector<size_t> vector_size_t;
  21. typedef std::vector<Point> vector_Point;
  22. typedef std::vector<Point2f> vector_Point2f;
  23. typedef std::vector<Point3f> vector_Point3f;
  24. typedef std::vector<Size> vector_Size;
  25. typedef std::vector<Vec2f> vector_Vec2f;
  26. typedef std::vector<Vec3f> vector_Vec3f;
  27. typedef std::vector<Vec4f> vector_Vec4f;
  28. typedef std::vector<Vec6f> vector_Vec6f;
  29. typedef std::vector<Vec4i> vector_Vec4i;
  30. typedef std::vector<Rect> vector_Rect;
  31. typedef std::vector<Rect2d> vector_Rect2d;
  32. typedef std::vector<RotatedRect> vector_RotatedRect;
  33. typedef std::vector<KeyPoint> vector_KeyPoint;
  34. typedef std::vector<Mat> vector_Mat;
  35. typedef std::vector<std::vector<Mat> > vector_vector_Mat;
  36. typedef std::vector<UMat> vector_UMat;
  37. typedef std::vector<DMatch> vector_DMatch;
  38. typedef std::vector<String> vector_String;
  39. typedef std::vector<std::string> vector_string;
  40. typedef std::vector<Scalar> vector_Scalar;
  41. typedef std::vector<std::vector<char> > vector_vector_char;
  42. typedef std::vector<std::vector<Point> > vector_vector_Point;
  43. typedef std::vector<std::vector<Point2f> > vector_vector_Point2f;
  44. typedef std::vector<std::vector<Point3f> > vector_vector_Point3f;
  45. typedef std::vector<std::vector<DMatch> > vector_vector_DMatch;
  46. typedef std::vector<std::vector<KeyPoint> > vector_vector_KeyPoint;
  47. // enum { ARG_NONE = 0, ARG_MAT = 1, ARG_SCALAR = 2 };
  48. ///////////////////////////////////////////////////////////////////////////////////////
  49. static int convert_to_char(PyObject *o, char *dst, const ArgInfo& info)
  50. {
  51. std::string str;
  52. if (getUnicodeString(o, str))
  53. {
  54. *dst = str[0];
  55. return 1;
  56. }
  57. (*dst) = 0;
  58. return failmsg("Expected single character string for argument '%s'", info.name);
  59. }
  60. #ifdef __GNUC__
  61. # pragma GCC diagnostic ignored "-Wunused-parameter"
  62. # pragma GCC diagnostic ignored "-Wmissing-field-initializers"
  63. #endif
  64. #include "pyopencv_generated_enums.h"
  65. #ifdef CVPY_DYNAMIC_INIT
  66. #define CVPY_TYPE(WNAME, NAME, STORAGE, SNAME, _1, _2) CVPY_TYPE_DECLARE_DYNAMIC(WNAME, NAME, STORAGE, SNAME)
  67. #else
  68. #define CVPY_TYPE(WNAME, NAME, STORAGE, SNAME, _1, _2) CVPY_TYPE_DECLARE(WNAME, NAME, STORAGE, SNAME)
  69. #endif
  70. #include "pyopencv_generated_types.h"
  71. #undef CVPY_TYPE
  72. #include "pyopencv_custom_headers.h"
  73. #include "pyopencv_generated_types_content.h"
  74. #include "pyopencv_generated_funcs.h"
  75. static PyObject* pycvRegisterMatType(PyObject *self, PyObject *value)
  76. {
  77. CV_LOG_DEBUG(NULL, cv::format("pycvRegisterMatType %p %p\n", self, value));
  78. if (0 == PyType_Check(value))
  79. {
  80. PyErr_SetString(PyExc_TypeError, "Type argument is expected");
  81. return NULL;
  82. }
  83. Py_INCREF(value);
  84. pyopencv_Mat_TypePtr = (PyTypeObject*)value;
  85. Py_RETURN_NONE;
  86. }
  87. static PyMethodDef special_methods[] = {
  88. {"_registerMatType", (PyCFunction)(pycvRegisterMatType), METH_O, "_registerMatType(cv.Mat) -> None (Internal)"},
  89. {"redirectError", CV_PY_FN_WITH_KW(pycvRedirectError), "redirectError(onError) -> None"},
  90. #ifdef HAVE_OPENCV_HIGHGUI
  91. {"createTrackbar", (PyCFunction)pycvCreateTrackbar, METH_VARARGS, "createTrackbar(trackbarName, windowName, value, count, onChange) -> None"},
  92. {"createButton", CV_PY_FN_WITH_KW(pycvCreateButton), "createButton(buttonName, onChange [, userData, buttonType, initialButtonState]) -> None"},
  93. {"setMouseCallback", CV_PY_FN_WITH_KW(pycvSetMouseCallback), "setMouseCallback(windowName, onMouse [, param]) -> None"},
  94. #endif
  95. #ifdef HAVE_OPENCV_DNN
  96. {"dnn_registerLayer", CV_PY_FN_WITH_KW(pyopencv_cv_dnn_registerLayer), "registerLayer(type, class) -> None"},
  97. {"dnn_unregisterLayer", CV_PY_FN_WITH_KW(pyopencv_cv_dnn_unregisterLayer), "unregisterLayer(type) -> None"},
  98. #endif
  99. {NULL, NULL},
  100. };
  101. /************************************************************************/
  102. /* Module init */
  103. struct ConstDef
  104. {
  105. const char * name;
  106. long long val;
  107. };
  108. static inline bool strStartsWith(const std::string& str, const std::string& prefix) {
  109. return prefix.empty() || \
  110. (str.size() >= prefix.size() && std::memcmp(str.data(), prefix.data(), prefix.size()) == 0);
  111. }
  112. static inline bool strEndsWith(const std::string& str, char symbol) {
  113. return !str.empty() && str[str.size() - 1] == symbol;
  114. }
  115. /**
  116. * \brief Creates a submodule of the `root`. Missing parents submodules
  117. * are created as needed. If name equals to parent module name than
  118. * borrowed reference to parent module is returned (no reference counting
  119. * are done).
  120. * Submodule lifetime is managed by the parent module.
  121. * If nested submodules are created than the lifetime is managed by the
  122. * predecessor submodule in a list.
  123. *
  124. * \param parent_module Parent module object.
  125. * \param name Submodule name.
  126. * \return borrowed reference to the created submodule.
  127. * If any of submodules can't be created than NULL is returned.
  128. */
  129. static PyObject* createSubmodule(PyObject* parent_module, const std::string& name)
  130. {
  131. if (!parent_module)
  132. {
  133. return PyErr_Format(PyExc_ImportError,
  134. "Bindings generation error. "
  135. "Parent module is NULL during the submodule '%s' creation",
  136. name.c_str()
  137. );
  138. }
  139. if (strEndsWith(name, '.'))
  140. {
  141. return PyErr_Format(PyExc_ImportError,
  142. "Bindings generation error. "
  143. "Submodule can't end with a dot. Got: %s", name.c_str()
  144. );
  145. }
  146. const std::string parent_name = PyModule_GetName(parent_module);
  147. /// Special case handling when caller tries to register a submodule of the parent module with
  148. /// the same name
  149. if (name == parent_name) {
  150. return parent_module;
  151. }
  152. if (!strStartsWith(name, parent_name))
  153. {
  154. return PyErr_Format(PyExc_ImportError,
  155. "Bindings generation error. "
  156. "Submodule name should always start with a parent module name. "
  157. "Parent name: %s. Submodule name: %s", parent_name.c_str(),
  158. name.c_str()
  159. );
  160. }
  161. size_t submodule_name_end = name.find('.', parent_name.size() + 1);
  162. /// There is no intermediate submodules in the provided name
  163. if (submodule_name_end == std::string::npos)
  164. {
  165. submodule_name_end = name.size();
  166. }
  167. PyObject* submodule = parent_module;
  168. for (size_t submodule_name_start = parent_name.size() + 1;
  169. submodule_name_start < name.size(); )
  170. {
  171. const std::string submodule_name = name.substr(submodule_name_start,
  172. submodule_name_end - submodule_name_start);
  173. const std::string full_submodule_name = name.substr(0, submodule_name_end);
  174. PyObject* parent_module_dict = PyModule_GetDict(submodule);
  175. /// If submodule already exists it can be found in the parent module dictionary,
  176. /// otherwise it should be added to it.
  177. submodule = PyDict_GetItemString(parent_module_dict,
  178. submodule_name.c_str());
  179. if (!submodule)
  180. {
  181. /// Populates global modules dictionary and returns borrowed reference to it
  182. submodule = PyImport_AddModule(full_submodule_name.c_str());
  183. if (!submodule)
  184. {
  185. /// Return `PyImport_AddModule` NULL with an exception set on failure.
  186. return NULL;
  187. }
  188. /// Populates parent module dictionary. Submodule lifetime should be managed
  189. /// by the global modules dictionary and parent module dictionary, so Py_DECREF after
  190. /// successfull call to the `PyDict_SetItemString` is redundant.
  191. if (PyDict_SetItemString(parent_module_dict, submodule_name.c_str(), submodule) < 0) {
  192. return PyErr_Format(PyExc_ImportError,
  193. "Can't register a submodule '%s' (full name: '%s')",
  194. submodule_name.c_str(), full_submodule_name.c_str()
  195. );
  196. }
  197. }
  198. submodule_name_start = submodule_name_end + 1;
  199. submodule_name_end = name.find('.', submodule_name_start);
  200. if (submodule_name_end == std::string::npos) {
  201. submodule_name_end = name.size();
  202. }
  203. }
  204. return submodule;
  205. }
  206. static bool init_submodule(PyObject * root, const char * name, PyMethodDef * methods, ConstDef * consts)
  207. {
  208. // traverse and create nested submodules
  209. PyObject* submodule = createSubmodule(root, name);
  210. if (!submodule)
  211. {
  212. return false;
  213. }
  214. // populate module's dict
  215. PyObject * d = PyModule_GetDict(submodule);
  216. for (PyMethodDef * m = methods; m->ml_name != NULL; ++m)
  217. {
  218. PyObject * method_obj = PyCFunction_NewEx(m, NULL, NULL);
  219. if (PyDict_SetItemString(d, m->ml_name, method_obj) < 0)
  220. {
  221. PyErr_Format(PyExc_ImportError,
  222. "Can't register function %s in module: %s", m->ml_name, name
  223. );
  224. Py_CLEAR(method_obj);
  225. return false;
  226. }
  227. Py_DECREF(method_obj);
  228. }
  229. for (ConstDef * c = consts; c->name != NULL; ++c)
  230. {
  231. PyObject* const_obj = PyLong_FromLongLong(c->val);
  232. if (PyDict_SetItemString(d, c->name, const_obj) < 0)
  233. {
  234. PyErr_Format(PyExc_ImportError,
  235. "Can't register constant %s in module %s", c->name, name
  236. );
  237. Py_CLEAR(const_obj);
  238. return false;
  239. }
  240. Py_DECREF(const_obj);
  241. }
  242. return true;
  243. }
  244. #include "pyopencv_generated_modules_content.h"
  245. static bool init_body(PyObject * m)
  246. {
  247. #define CVPY_MODULE(NAMESTR, NAME) \
  248. if (!init_submodule(m, MODULESTR NAMESTR, methods_##NAME, consts_##NAME)) \
  249. { \
  250. return false; \
  251. }
  252. #include "pyopencv_generated_modules.h"
  253. #undef CVPY_MODULE
  254. #ifdef CVPY_DYNAMIC_INIT
  255. #define CVPY_TYPE(WNAME, NAME, _1, _2, BASE, CONSTRUCTOR) CVPY_TYPE_INIT_DYNAMIC(WNAME, NAME, return false, BASE, CONSTRUCTOR)
  256. PyObject * pyopencv_NoBase_TypePtr = NULL;
  257. #else
  258. #define CVPY_TYPE(WNAME, NAME, _1, _2, BASE, CONSTRUCTOR) CVPY_TYPE_INIT_STATIC(WNAME, NAME, return false, BASE, CONSTRUCTOR)
  259. PyTypeObject * pyopencv_NoBase_TypePtr = NULL;
  260. #endif
  261. #include "pyopencv_generated_types.h"
  262. #undef CVPY_TYPE
  263. PyObject* d = PyModule_GetDict(m);
  264. PyObject* version_obj = PyString_FromString(CV_VERSION);
  265. if (PyDict_SetItemString(d, "__version__", version_obj) < 0) {
  266. PyErr_SetString(PyExc_ImportError, "Can't update module version");
  267. Py_CLEAR(version_obj);
  268. return false;
  269. }
  270. Py_DECREF(version_obj);
  271. PyObject *opencv_error_dict = PyDict_New();
  272. PyDict_SetItemString(opencv_error_dict, "file", Py_None);
  273. PyDict_SetItemString(opencv_error_dict, "func", Py_None);
  274. PyDict_SetItemString(opencv_error_dict, "line", Py_None);
  275. PyDict_SetItemString(opencv_error_dict, "code", Py_None);
  276. PyDict_SetItemString(opencv_error_dict, "msg", Py_None);
  277. PyDict_SetItemString(opencv_error_dict, "err", Py_None);
  278. opencv_error = PyErr_NewException((char*)MODULESTR".error", NULL, opencv_error_dict);
  279. Py_DECREF(opencv_error_dict);
  280. PyDict_SetItemString(d, "error", opencv_error);
  281. #define PUBLISH_(I, var_name, type_obj) \
  282. PyObject* type_obj = PyInt_FromLong(I); \
  283. if (PyDict_SetItemString(d, var_name, type_obj) < 0) \
  284. { \
  285. PyErr_SetString(PyExc_ImportError, "Can't register " var_name " constant"); \
  286. Py_CLEAR(type_obj); \
  287. return false; \
  288. } \
  289. Py_DECREF(type_obj);
  290. #define PUBLISH(I) PUBLISH_(I, #I, I ## _obj)
  291. PUBLISH(CV_8U);
  292. PUBLISH(CV_8UC1);
  293. PUBLISH(CV_8UC2);
  294. PUBLISH(CV_8UC3);
  295. PUBLISH(CV_8UC4);
  296. PUBLISH(CV_8S);
  297. PUBLISH(CV_8SC1);
  298. PUBLISH(CV_8SC2);
  299. PUBLISH(CV_8SC3);
  300. PUBLISH(CV_8SC4);
  301. PUBLISH(CV_16U);
  302. PUBLISH(CV_16UC1);
  303. PUBLISH(CV_16UC2);
  304. PUBLISH(CV_16UC3);
  305. PUBLISH(CV_16UC4);
  306. PUBLISH(CV_16S);
  307. PUBLISH(CV_16SC1);
  308. PUBLISH(CV_16SC2);
  309. PUBLISH(CV_16SC3);
  310. PUBLISH(CV_16SC4);
  311. PUBLISH(CV_32S);
  312. PUBLISH(CV_32SC1);
  313. PUBLISH(CV_32SC2);
  314. PUBLISH(CV_32SC3);
  315. PUBLISH(CV_32SC4);
  316. PUBLISH(CV_32F);
  317. PUBLISH(CV_32FC1);
  318. PUBLISH(CV_32FC2);
  319. PUBLISH(CV_32FC3);
  320. PUBLISH(CV_32FC4);
  321. PUBLISH(CV_64F);
  322. PUBLISH(CV_64FC1);
  323. PUBLISH(CV_64FC2);
  324. PUBLISH(CV_64FC3);
  325. PUBLISH(CV_64FC4);
  326. #undef PUBLISH_
  327. #undef PUBLISH
  328. return true;
  329. }
  330. #if defined(__GNUC__)
  331. #pragma GCC visibility push(default)
  332. #endif
  333. #if defined(CV_PYTHON_3)
  334. // === Python 3
  335. static struct PyModuleDef cv2_moduledef =
  336. {
  337. PyModuleDef_HEAD_INIT,
  338. MODULESTR,
  339. "Python wrapper for OpenCV.",
  340. -1, /* size of per-interpreter state of the module,
  341. or -1 if the module keeps state in global variables. */
  342. special_methods
  343. };
  344. PyMODINIT_FUNC PyInit_cv2();
  345. PyObject* PyInit_cv2()
  346. {
  347. import_array(); // from numpy
  348. PyObject* m = PyModule_Create(&cv2_moduledef);
  349. if (!init_body(m))
  350. return NULL;
  351. return m;
  352. }
  353. #else
  354. // === Python 2
  355. PyMODINIT_FUNC initcv2();
  356. void initcv2()
  357. {
  358. import_array(); // from numpy
  359. PyObject* m = Py_InitModule(MODULESTR, special_methods);
  360. init_body(m);
  361. }
  362. #endif