pyopencv_dnn.hpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. #ifdef HAVE_OPENCV_DNN
  2. typedef dnn::DictValue LayerId;
  3. typedef std::vector<dnn::MatShape> vector_MatShape;
  4. typedef std::vector<std::vector<dnn::MatShape> > vector_vector_MatShape;
  5. template<>
  6. bool pyopencv_to(PyObject *o, dnn::DictValue &dv, const ArgInfo& info)
  7. {
  8. CV_UNUSED(info);
  9. if (!o || o == Py_None)
  10. return true; //Current state will be used
  11. else if (PyLong_Check(o))
  12. {
  13. dv = dnn::DictValue((int64)PyLong_AsLongLong(o));
  14. return true;
  15. }
  16. else if (PyInt_Check(o))
  17. {
  18. dv = dnn::DictValue((int64)PyInt_AS_LONG(o));
  19. return true;
  20. }
  21. else if (PyFloat_Check(o))
  22. {
  23. dv = dnn::DictValue(PyFloat_AsDouble(o));
  24. return true;
  25. }
  26. else
  27. {
  28. std::string str;
  29. if (getUnicodeString(o, str))
  30. {
  31. dv = dnn::DictValue(str);
  32. return true;
  33. }
  34. }
  35. return false;
  36. }
  37. template<typename T>
  38. PyObject* pyopencv_from(const dnn::DictValue &dv)
  39. {
  40. if (dv.size() > 1)
  41. {
  42. std::vector<T> vec(dv.size());
  43. for (int i = 0; i < dv.size(); ++i)
  44. vec[i] = dv.get<T>(i);
  45. return pyopencv_from_generic_vec(vec);
  46. }
  47. else
  48. return pyopencv_from(dv.get<T>());
  49. }
  50. template<>
  51. PyObject* pyopencv_from(const dnn::DictValue &dv)
  52. {
  53. if (dv.isInt()) return pyopencv_from<int>(dv);
  54. if (dv.isReal()) return pyopencv_from<float>(dv);
  55. if (dv.isString()) return pyopencv_from<String>(dv);
  56. CV_Error(Error::StsNotImplemented, "Unknown value type");
  57. return NULL;
  58. }
  59. template<>
  60. PyObject* pyopencv_from(const dnn::LayerParams& lp)
  61. {
  62. PyObject* dict = PyDict_New();
  63. for (std::map<String, dnn::DictValue>::const_iterator it = lp.begin(); it != lp.end(); ++it)
  64. {
  65. CV_Assert(!PyDict_SetItemString(dict, it->first.c_str(), pyopencv_from(it->second)));
  66. }
  67. return dict;
  68. }
  69. template<>
  70. PyObject* pyopencv_from(const std::vector<dnn::Target> &t)
  71. {
  72. return pyopencv_from(std::vector<int>(t.begin(), t.end()));
  73. }
  74. class pycvLayer CV_FINAL : public dnn::Layer
  75. {
  76. public:
  77. pycvLayer(const dnn::LayerParams &params, PyObject* pyLayer) : Layer(params)
  78. {
  79. PyGILState_STATE gstate;
  80. gstate = PyGILState_Ensure();
  81. PyObject* args = PyTuple_New(2);
  82. CV_Assert(!PyTuple_SetItem(args, 0, pyopencv_from(params)));
  83. CV_Assert(!PyTuple_SetItem(args, 1, pyopencv_from(params.blobs)));
  84. o = PyObject_CallObject(pyLayer, args);
  85. Py_DECREF(args);
  86. PyGILState_Release(gstate);
  87. if (!o)
  88. CV_Error(Error::StsError, "Failed to create an instance of custom layer");
  89. }
  90. static void registerLayer(const std::string& type, PyObject* o)
  91. {
  92. std::map<std::string, std::vector<PyObject*> >::iterator it = pyLayers.find(type);
  93. if (it != pyLayers.end())
  94. it->second.push_back(o);
  95. else
  96. pyLayers[type] = std::vector<PyObject*>(1, o);
  97. }
  98. static void unregisterLayer(const std::string& type)
  99. {
  100. std::map<std::string, std::vector<PyObject*> >::iterator it = pyLayers.find(type);
  101. if (it != pyLayers.end())
  102. {
  103. if (it->second.size() > 1)
  104. it->second.pop_back();
  105. else
  106. pyLayers.erase(it);
  107. }
  108. }
  109. static Ptr<dnn::Layer> create(dnn::LayerParams &params)
  110. {
  111. std::map<std::string, std::vector<PyObject*> >::iterator it = pyLayers.find(params.type);
  112. if (it == pyLayers.end())
  113. CV_Error(Error::StsNotImplemented, "Layer with a type \"" + params.type +
  114. "\" is not implemented");
  115. CV_Assert(!it->second.empty());
  116. return Ptr<dnn::Layer>(new pycvLayer(params, it->second.back()));
  117. }
  118. virtual bool getMemoryShapes(const std::vector<std::vector<int> > &inputs,
  119. const int,
  120. std::vector<std::vector<int> > &outputs,
  121. std::vector<std::vector<int> > &) const CV_OVERRIDE
  122. {
  123. PyGILState_STATE gstate;
  124. gstate = PyGILState_Ensure();
  125. PyObject* args = PyList_New(inputs.size());
  126. for(size_t i = 0; i < inputs.size(); ++i)
  127. PyList_SetItem(args, i, pyopencv_from_generic_vec(inputs[i]));
  128. PyObject* res = PyObject_CallMethodObjArgs(o, PyString_FromString("getMemoryShapes"), args, NULL);
  129. Py_DECREF(args);
  130. PyGILState_Release(gstate);
  131. if (!res)
  132. CV_Error(Error::StsNotImplemented, "Failed to call \"getMemoryShapes\" method");
  133. CV_Assert(pyopencv_to_generic_vec(res, outputs, ArgInfo("", 0)));
  134. return false;
  135. }
  136. virtual void forward(InputArrayOfArrays inputs_arr, OutputArrayOfArrays outputs_arr, OutputArrayOfArrays) CV_OVERRIDE
  137. {
  138. PyGILState_STATE gstate;
  139. gstate = PyGILState_Ensure();
  140. std::vector<Mat> inputs, outputs;
  141. inputs_arr.getMatVector(inputs);
  142. outputs_arr.getMatVector(outputs);
  143. PyObject* args = pyopencv_from(inputs);
  144. PyObject* res = PyObject_CallMethodObjArgs(o, PyString_FromString("forward"), args, NULL);
  145. Py_DECREF(args);
  146. if (!res)
  147. CV_Error(Error::StsNotImplemented, "Failed to call \"forward\" method");
  148. std::vector<Mat> pyOutputs;
  149. CV_Assert(pyopencv_to(res, pyOutputs, ArgInfo("", 0)));
  150. Py_DECREF(res);
  151. PyGILState_Release(gstate);
  152. CV_Assert(pyOutputs.size() == outputs.size());
  153. for (size_t i = 0; i < outputs.size(); ++i)
  154. {
  155. CV_Assert(pyOutputs[i].size == outputs[i].size);
  156. CV_Assert(pyOutputs[i].type() == outputs[i].type());
  157. pyOutputs[i].copyTo(outputs[i]);
  158. }
  159. }
  160. private:
  161. // Map layers types to python classes.
  162. static std::map<std::string, std::vector<PyObject*> > pyLayers;
  163. PyObject* o; // Instance of implemented python layer.
  164. };
  165. std::map<std::string, std::vector<PyObject*> > pycvLayer::pyLayers;
  166. static PyObject *pyopencv_cv_dnn_registerLayer(PyObject*, PyObject *args, PyObject *kw)
  167. {
  168. const char *keywords[] = { "type", "class", NULL };
  169. char* layerType;
  170. PyObject *classInstance;
  171. if (!PyArg_ParseTupleAndKeywords(args, kw, "sO", (char**)keywords, &layerType, &classInstance))
  172. return NULL;
  173. if (!PyCallable_Check(classInstance)) {
  174. PyErr_SetString(PyExc_TypeError, "class must be callable");
  175. return NULL;
  176. }
  177. pycvLayer::registerLayer(layerType, classInstance);
  178. dnn::LayerFactory::registerLayer(layerType, pycvLayer::create);
  179. Py_RETURN_NONE;
  180. }
  181. static PyObject *pyopencv_cv_dnn_unregisterLayer(PyObject*, PyObject *args, PyObject *kw)
  182. {
  183. const char *keywords[] = { "type", NULL };
  184. char* layerType;
  185. if (!PyArg_ParseTupleAndKeywords(args, kw, "s", (char**)keywords, &layerType))
  186. return NULL;
  187. pycvLayer::unregisterLayer(layerType);
  188. dnn::LayerFactory::unregisterLayer(layerType);
  189. Py_RETURN_NONE;
  190. }
  191. #endif // HAVE_OPENCV_DNN