cv2_highgui.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. #include "cv2_highgui.hpp"
  2. #ifdef HAVE_OPENCV_HIGHGUI
  3. #include "cv2_util.hpp"
  4. #include "opencv2/highgui.hpp"
  5. #include <map>
  6. using namespace cv;
  7. //======================================================================================================================
  8. static void OnMouse(int event, int x, int y, int flags, void* param)
  9. {
  10. PyGILState_STATE gstate;
  11. gstate = PyGILState_Ensure();
  12. PyObject *o = (PyObject*)param;
  13. PyObject *args = Py_BuildValue("iiiiO", event, x, y, flags, PyTuple_GetItem(o, 1));
  14. PyObject *r = PyObject_Call(PyTuple_GetItem(o, 0), args, NULL);
  15. if (r == NULL)
  16. PyErr_Print();
  17. else
  18. Py_DECREF(r);
  19. Py_DECREF(args);
  20. PyGILState_Release(gstate);
  21. }
  22. PyObject *pycvSetMouseCallback(PyObject*, PyObject *args, PyObject *kw)
  23. {
  24. const char *keywords[] = { "window_name", "on_mouse", "param", NULL };
  25. char* name;
  26. PyObject *on_mouse;
  27. PyObject *param = NULL;
  28. if (!PyArg_ParseTupleAndKeywords(args, kw, "sO|O", (char**)keywords, &name, &on_mouse, &param))
  29. return NULL;
  30. if (!PyCallable_Check(on_mouse)) {
  31. PyErr_SetString(PyExc_TypeError, "on_mouse must be callable");
  32. return NULL;
  33. }
  34. if (param == NULL) {
  35. param = Py_None;
  36. }
  37. PyObject* py_callback_info = Py_BuildValue("OO", on_mouse, param);
  38. static std::map<std::string, PyObject*> registered_callbacks;
  39. std::map<std::string, PyObject*>::iterator i = registered_callbacks.find(name);
  40. if (i != registered_callbacks.end())
  41. {
  42. Py_DECREF(i->second);
  43. i->second = py_callback_info;
  44. }
  45. else
  46. {
  47. registered_callbacks.insert(std::pair<std::string, PyObject*>(std::string(name), py_callback_info));
  48. }
  49. ERRWRAP2(setMouseCallback(name, OnMouse, py_callback_info));
  50. Py_RETURN_NONE;
  51. }
  52. //======================================================================================================================
  53. static void OnChange(int pos, void *param)
  54. {
  55. PyGILState_STATE gstate;
  56. gstate = PyGILState_Ensure();
  57. PyObject *o = (PyObject*)param;
  58. PyObject *args = Py_BuildValue("(i)", pos);
  59. PyObject *r = PyObject_Call(PyTuple_GetItem(o, 0), args, NULL);
  60. if (r == NULL)
  61. PyErr_Print();
  62. else
  63. Py_DECREF(r);
  64. Py_DECREF(args);
  65. PyGILState_Release(gstate);
  66. }
  67. // workaround for #20408, use nullptr, set value later
  68. static int _createTrackbar(const String &trackbar_name, const String &window_name, int value, int count,
  69. TrackbarCallback onChange, PyObject* py_callback_info)
  70. {
  71. int n = createTrackbar(trackbar_name, window_name, NULL, count, onChange, py_callback_info);
  72. setTrackbarPos(trackbar_name, window_name, value);
  73. return n;
  74. }
  75. PyObject *pycvCreateTrackbar(PyObject*, PyObject *args)
  76. {
  77. PyObject *on_change;
  78. char* trackbar_name;
  79. char* window_name;
  80. int value;
  81. int count;
  82. if (!PyArg_ParseTuple(args, "ssiiO", &trackbar_name, &window_name, &value, &count, &on_change))
  83. return NULL;
  84. if (!PyCallable_Check(on_change)) {
  85. PyErr_SetString(PyExc_TypeError, "on_change must be callable");
  86. return NULL;
  87. }
  88. PyObject* py_callback_info = Py_BuildValue("OO", on_change, Py_None);
  89. std::string name = std::string(window_name) + ":" + std::string(trackbar_name);
  90. static std::map<std::string, PyObject*> registered_callbacks;
  91. std::map<std::string, PyObject*>::iterator i = registered_callbacks.find(name);
  92. if (i != registered_callbacks.end())
  93. {
  94. Py_DECREF(i->second);
  95. i->second = py_callback_info;
  96. }
  97. else
  98. {
  99. registered_callbacks.insert(std::pair<std::string, PyObject*>(name, py_callback_info));
  100. }
  101. ERRWRAP2(_createTrackbar(trackbar_name, window_name, value, count, OnChange, py_callback_info));
  102. Py_RETURN_NONE;
  103. }
  104. //======================================================================================================================
  105. static void OnButtonChange(int state, void *param)
  106. {
  107. PyGILState_STATE gstate;
  108. gstate = PyGILState_Ensure();
  109. PyObject *o = (PyObject*)param;
  110. PyObject *args;
  111. if(PyTuple_GetItem(o, 1) != NULL)
  112. {
  113. args = Py_BuildValue("(iO)", state, PyTuple_GetItem(o,1));
  114. }
  115. else
  116. {
  117. args = Py_BuildValue("(i)", state);
  118. }
  119. PyObject *r = PyObject_Call(PyTuple_GetItem(o, 0), args, NULL);
  120. if (r == NULL)
  121. PyErr_Print();
  122. else
  123. Py_DECREF(r);
  124. Py_DECREF(args);
  125. PyGILState_Release(gstate);
  126. }
  127. PyObject *pycvCreateButton(PyObject*, PyObject *args, PyObject *kw)
  128. {
  129. const char* keywords[] = {"buttonName", "onChange", "userData", "buttonType", "initialButtonState", NULL};
  130. PyObject *on_change;
  131. PyObject *userdata = NULL;
  132. char* button_name;
  133. int button_type = 0;
  134. int initial_button_state = 0;
  135. if (!PyArg_ParseTupleAndKeywords(args, kw, "sO|Oii", (char**)keywords, &button_name, &on_change, &userdata, &button_type, &initial_button_state))
  136. return NULL;
  137. if (!PyCallable_Check(on_change)) {
  138. PyErr_SetString(PyExc_TypeError, "onChange must be callable");
  139. return NULL;
  140. }
  141. if (userdata == NULL) {
  142. userdata = Py_None;
  143. }
  144. PyObject* py_callback_info = Py_BuildValue("OO", on_change, userdata);
  145. std::string name(button_name);
  146. static std::map<std::string, PyObject*> registered_callbacks;
  147. std::map<std::string, PyObject*>::iterator i = registered_callbacks.find(name);
  148. if (i != registered_callbacks.end())
  149. {
  150. Py_DECREF(i->second);
  151. i->second = py_callback_info;
  152. }
  153. else
  154. {
  155. registered_callbacks.insert(std::pair<std::string, PyObject*>(name, py_callback_info));
  156. }
  157. ERRWRAP2(createButton(button_name, OnButtonChange, py_callback_info, button_type, initial_button_state != 0));
  158. Py_RETURN_NONE;
  159. }
  160. #endif // HAVE_OPENCV_HIGHGUI