From 3700f9e1e932ca1aaa15db70534cb78b6e44ce05 Mon Sep 17 00:00:00 2001 From: Dmitry Kurtaev Date: Fri, 7 Jun 2024 20:39:44 +0300 Subject: [PATCH] Merge pull request #25709 from dkurt:wrap_addLayer * Wrap dnn addLayer * Add typing stubs --- modules/dnn/include/opencv2/dnn/dnn.hpp | 4 ++-- modules/dnn/misc/python/pyopencv_dnn.hpp | 16 ++++++++++++++++ modules/dnn/misc/python/test/test_dnn.py | 16 ++++++++++++++++ .../typing_stubs_generation/predefined_types.py | 7 +++++++ 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/modules/dnn/include/opencv2/dnn/dnn.hpp b/modules/dnn/include/opencv2/dnn/dnn.hpp index fd91290104..b516f80bde 100644 --- a/modules/dnn/include/opencv2/dnn/dnn.hpp +++ b/modules/dnn/include/opencv2/dnn/dnn.hpp @@ -533,7 +533,7 @@ CV__DNN_INLINE_NS_BEGIN * @param params parameters which will be used to initialize the creating layer. * @returns unique identifier of created layer, or -1 if a failure will happen. */ - int addLayer(const String &name, const String &type, const int &dtype, LayerParams ¶ms); + CV_WRAP int addLayer(const String &name, const String &type, const int &dtype, LayerParams ¶ms); /** @overload Datatype of output blobs set to default CV_32F */ int addLayer(const String &name, const String &type, LayerParams ¶ms); @@ -541,7 +541,7 @@ CV__DNN_INLINE_NS_BEGIN /** @brief Adds new layer and connects its first input to the first output of previously added layer. * @see addLayer() */ - int addLayerToPrev(const String &name, const String &type, const int &dtype, LayerParams ¶ms); + CV_WRAP int addLayerToPrev(const String &name, const String &type, const int &dtype, LayerParams ¶ms); /** @overload */ int addLayerToPrev(const String &name, const String &type, LayerParams ¶ms); diff --git a/modules/dnn/misc/python/pyopencv_dnn.hpp b/modules/dnn/misc/python/pyopencv_dnn.hpp index d729cd8b97..0fc0c45e82 100644 --- a/modules/dnn/misc/python/pyopencv_dnn.hpp +++ b/modules/dnn/misc/python/pyopencv_dnn.hpp @@ -71,6 +71,22 @@ PyObject* pyopencv_from(const dnn::LayerParams& lp) return dict; } +template<> +bool pyopencv_to(PyObject *o, dnn::LayerParams &lp, const ArgInfo& info) +{ + CV_Assert(PyDict_Check(o)); + PyObject *key, *value; + Py_ssize_t pos = 0; + std::string keyName; + while (PyDict_Next(o, &pos, &key, &value)) { + getUnicodeString(key, keyName); + dnn::DictValue dv; + pyopencv_to(value, dv, info); + lp.set(keyName, dv); + } + return true; +} + template<> PyObject* pyopencv_from(const std::vector &t) { diff --git a/modules/dnn/misc/python/test/test_dnn.py b/modules/dnn/misc/python/test/test_dnn.py index da3409c3b3..e3cc376dd2 100644 --- a/modules/dnn/misc/python/test/test_dnn.py +++ b/modules/dnn/misc/python/test/test_dnn.py @@ -480,5 +480,21 @@ class dnn_test(NewOpenCVTests): params.scalefactor = 2.0 self.assertEqual(params.scalefactor, (2.0, 0.0, 0.0, 0.0)) + def test_net_builder(self): + net = cv.dnn.Net() + params = { + "kernel_w": 3, + "kernel_h": 3, + "stride_w": 3, + "stride_h": 3, + "pool": "max", + } + net.addLayerToPrev("pool", "Pooling", cv.CV_32F, params) + + inp = np.random.standard_normal([1, 2, 9, 12]).astype(np.float32) + net.setInput(inp) + out = net.forward() + self.assertEqual(out.shape, (1, 2, 3, 4)) + if __name__ == '__main__': NewOpenCVTests.bootstrap() diff --git a/modules/python/src2/typing_stubs_generation/predefined_types.py b/modules/python/src2/typing_stubs_generation/predefined_types.py index f5ba0bc29e..5aed93c8b0 100644 --- a/modules/python/src2/typing_stubs_generation/predefined_types.py +++ b/modules/python/src2/typing_stubs_generation/predefined_types.py @@ -194,6 +194,13 @@ _PREDEFINED_TYPES = ( export_name="ExtractMetaCallback" ), AliasTypeNode.class_("LayerId", "DictValue"), + AliasTypeNode.dict_("LayerParams", + key_type=PrimitiveTypeNode.str_(), + value_type=UnionTypeNode("DictValue", items=( + PrimitiveTypeNode.int_(), + PrimitiveTypeNode.float_(), + PrimitiveTypeNode.str_()) + )), PrimitiveTypeNode.int_("cvflann_flann_distance_t"), PrimitiveTypeNode.int_("flann_flann_distance_t"), PrimitiveTypeNode.int_("cvflann_flann_algorithm_t"),