From: Anatoliy Talamanov Date: Tue, 15 Sep 2020 11:49:35 +0000 (+0300) Subject: Support tuple for python bindings X-Git-Tag: submit/tizen/20210224.033012~2^2~46^2~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=521844378420bfaa9e5031542a832727c289b2eb;p=platform%2Fupstream%2Fopencv.git Support tuple for python bindings --- diff --git a/modules/gapi/include/opencv2/gapi/core.hpp b/modules/gapi/include/opencv2/gapi/core.hpp index 5b9fb5a..a4db7e1 100644 --- a/modules/gapi/include/opencv2/gapi/core.hpp +++ b/modules/gapi/include/opencv2/gapi/core.hpp @@ -1434,7 +1434,7 @@ All output matrices must be in @ref CV_8UC1. @sa merge3, merge4 */ GAPI_EXPORTS std::tuple split4(const GMat& src); -GAPI_EXPORTS std::tuple split3(const GMat& src); +GAPI_EXPORTS_W std::tuple split3(const GMat& src); /** @brief Applies a generic geometrical transformation to an image. diff --git a/modules/gapi/include/opencv2/gapi/gcomputation.hpp b/modules/gapi/include/opencv2/gapi/gcomputation.hpp index d6b8561..bae2ad7 100644 --- a/modules/gapi/include/opencv2/gapi/gcomputation.hpp +++ b/modules/gapi/include/opencv2/gapi/gcomputation.hpp @@ -172,7 +172,7 @@ public: * @param in input GMat of the defined unary computation * @param out output GMat of the defined unary computation */ - GComputation(GMat in, GMat out); // Unary overload + GAPI_WRAP GComputation(GMat in, GMat out); // Unary overload /** * @brief Defines an unary (one input -- one output) computation diff --git a/modules/gapi/misc/python/test/test_gapi_sample_pipelines.py b/modules/gapi/misc/python/test/test_gapi_sample_pipelines.py new file mode 100644 index 0000000..d24a0de --- /dev/null +++ b/modules/gapi/misc/python/test/test_gapi_sample_pipelines.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python + +import numpy as np +import cv2 as cv + +from tests_common import NewOpenCVTests + + +# Plaidml is an optional backend +pkgs = [ + cv.gapi.core.ocl.kernels(), + cv.gapi.core.cpu.kernels(), + cv.gapi.core.fluid.kernels() + # cv.gapi.core.plaidml.kernels() + ] + + +class gapi_sample_pipelines(NewOpenCVTests): + + # NB: This test check multiple outputs for operation + def test_mean_over_r(self): + sz = (100, 100, 3) + in_mat = np.random.randint(0, 100, sz).astype(np.uint8) + + # # OpenCV + _, _, r_ch = cv.split(in_mat) + expected = cv.mean(r_ch) + + # G-API + g_in = cv.GMat() + b, g, r = cv.gapi.split3(g_in) + g_out = cv.gapi.mean(r) + comp = cv.GComputation(g_in, g_out) + + actual = comp.apply(in_mat) + + for pkg in pkgs: + actual = comp.apply(in_mat, args=cv.compile_args(pkg)) + # Comparison + self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF)) + + +if __name__ == '__main__': + NewOpenCVTests.bootstrap() diff --git a/modules/python/src2/cv2.cpp b/modules/python/src2/cv2.cpp index 89dcbda..3d49a95 100644 --- a/modules/python/src2/cv2.cpp +++ b/modules/python/src2/cv2.cpp @@ -1486,6 +1486,41 @@ template static inline PyObject* pyopencv_from_generic_vec(const s return seq; } +template +inline typename std::enable_if::type +convert_to_python_tuple(const std::tuple&, PyObject*) { } + +template +inline typename std::enable_if::type +convert_to_python_tuple(const std::tuple& cpp_tuple, PyObject* py_tuple) +{ + PyObject* item = pyopencv_from(std::get(cpp_tuple)); + + if (!item) + return; + + PyTuple_SET_ITEM(py_tuple, I, item); + convert_to_python_tuple(cpp_tuple, py_tuple); +} + + +template +PyObject* pyopencv_from(const std::tuple& cpp_tuple) +{ + size_t size = sizeof...(Ts); + PyObject* py_tuple = PyTuple_New(size); + convert_to_python_tuple(cpp_tuple, py_tuple); + size_t actual_size = PyTuple_Size(py_tuple); + + if (actual_size < size) + { + Py_DECREF(py_tuple); + return NULL; + } + + return py_tuple; +} + template<> PyObject* pyopencv_from(const std::pair& src) {