Implement cv.gin and multiple output for python
This commit is contained in:
@@ -1,3 +1,8 @@
|
||||
#ifndef OPENCV_GAPI_PYOPENCV_GAPI_HPP
|
||||
#define OPENCV_GAPI_PYOPENCV_GAPI_HPP
|
||||
|
||||
#ifdef HAVE_OPENCV_GAPI
|
||||
|
||||
using gapi_GKernelPackage = cv::gapi::GKernelPackage;
|
||||
|
||||
template<>
|
||||
@@ -12,6 +17,67 @@ PyObject* pyopencv_from(const std::vector<GCompileArg>& value)
|
||||
return pyopencv_from_generic_vec(value);
|
||||
}
|
||||
|
||||
template<>
|
||||
bool pyopencv_to(PyObject* obj, GRunArgs& value, const ArgInfo& info)
|
||||
{
|
||||
return pyopencv_to_generic_vec(obj, value, info);
|
||||
}
|
||||
|
||||
static PyObject* from_grunarg(const GRunArg& v)
|
||||
{
|
||||
switch (v.index())
|
||||
{
|
||||
case GRunArg::index_of<cv::Mat>():
|
||||
{
|
||||
const auto& m = util::get<cv::Mat>(v);
|
||||
return pyopencv_from(m);
|
||||
}
|
||||
|
||||
case GRunArg::index_of<cv::Scalar>():
|
||||
{
|
||||
const auto& s = util::get<cv::Scalar>(v);
|
||||
return pyopencv_from(s);
|
||||
}
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
GAPI_Assert(false);
|
||||
}
|
||||
|
||||
template<>
|
||||
PyObject* pyopencv_from(const GRunArgs& value)
|
||||
{
|
||||
size_t i, n = value.size();
|
||||
|
||||
// NB: It doesn't make sense to return list with a single element
|
||||
if (n == 1)
|
||||
{
|
||||
PyObject* item = from_grunarg(value[0]);
|
||||
if(!item)
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "Failed to unpack GRunArgs");
|
||||
return NULL;
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
PyObject* list = PyList_New(n);
|
||||
for(i = 0; i < n; ++i)
|
||||
{
|
||||
PyObject* item = from_grunarg(value[i]);
|
||||
if(!item)
|
||||
{
|
||||
Py_DECREF(list);
|
||||
PyErr_SetString(PyExc_TypeError, "Failed to unpack GRunArgs");
|
||||
return NULL;
|
||||
}
|
||||
PyList_SetItem(list, i, item);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static PyObject* extract_proto_args(PyObject* py_args, PyObject* kw)
|
||||
{
|
||||
@@ -19,13 +85,19 @@ static PyObject* extract_proto_args(PyObject* py_args, PyObject* kw)
|
||||
|
||||
GProtoArgs args;
|
||||
Py_ssize_t size = PyTuple_Size(py_args);
|
||||
for (int i = 0; i < size; ++i) {
|
||||
for (int i = 0; i < size; ++i)
|
||||
{
|
||||
PyObject* item = PyTuple_GetItem(py_args, i);
|
||||
if (PyObject_TypeCheck(item, reinterpret_cast<PyTypeObject*>(pyopencv_GScalar_TypePtr))) {
|
||||
if (PyObject_TypeCheck(item, reinterpret_cast<PyTypeObject*>(pyopencv_GScalar_TypePtr)))
|
||||
{
|
||||
args.emplace_back(reinterpret_cast<pyopencv_GScalar_t*>(item)->v);
|
||||
} else if (PyObject_TypeCheck(item, reinterpret_cast<PyTypeObject*>(pyopencv_GMat_TypePtr))) {
|
||||
}
|
||||
else if (PyObject_TypeCheck(item, reinterpret_cast<PyTypeObject*>(pyopencv_GMat_TypePtr)))
|
||||
{
|
||||
args.emplace_back(reinterpret_cast<pyopencv_GMat_t*>(item)->v);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "cv.GIn() supports only cv.GMat and cv.GScalar");
|
||||
return NULL;
|
||||
}
|
||||
@@ -43,3 +115,51 @@ static PyObject* pyopencv_cv_GOut(PyObject* , PyObject* py_args, PyObject* kw)
|
||||
{
|
||||
return extract_proto_args<GProtoOutputArgs>(py_args, kw);
|
||||
}
|
||||
|
||||
static PyObject* pyopencv_cv_gin(PyObject* , PyObject* py_args, PyObject* kw)
|
||||
{
|
||||
using namespace cv;
|
||||
|
||||
GRunArgs args;
|
||||
Py_ssize_t size = PyTuple_Size(py_args);
|
||||
for (int i = 0; i < size; ++i)
|
||||
{
|
||||
PyObject* item = PyTuple_GetItem(py_args, i);
|
||||
if (PyTuple_Check(item))
|
||||
{
|
||||
cv::Scalar s;
|
||||
if (pyopencv_to(item, s, ArgInfo("scalar", true)))
|
||||
{
|
||||
args.emplace_back(s);
|
||||
}
|
||||
else
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "Failed convert tuple to cv::Scalar");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else if (PyArray_Check(item))
|
||||
{
|
||||
cv::Mat m;
|
||||
if (pyopencv_to(item, m, ArgInfo("mat", true)))
|
||||
{
|
||||
args.emplace_back(m);
|
||||
}
|
||||
else
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "Failed convert array to cv::Mat");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pyopencv_from_generic_vec(args);
|
||||
}
|
||||
|
||||
static PyObject* pyopencv_cv_gout(PyObject* o, PyObject* py_args, PyObject* kw)
|
||||
{
|
||||
return pyopencv_cv_gin(o, py_args, kw);
|
||||
}
|
||||
|
||||
#endif // HAVE_OPENCV_GAPI
|
||||
#endif // OPENCV_GAPI_PYOPENCV_GAPI_HPP
|
||||
|
||||
@@ -4,9 +4,11 @@
|
||||
namespace cv
|
||||
{
|
||||
GAPI_EXPORTS_W GCompileArgs compile_args(gapi::GKernelPackage pkg);
|
||||
|
||||
class GAPI_EXPORTS_W_SIMPLE GProtoArg { };
|
||||
class GAPI_EXPORTS_W_SIMPLE GProtoInputArgs { };
|
||||
class GAPI_EXPORTS_W_SIMPLE GProtoOutputArgs { };
|
||||
class GAPI_EXPORTS_W_SIMPLE GRunArg { };
|
||||
|
||||
using GProtoInputArgs = GIOProtoArgs<In_Tag>;
|
||||
using GProtoOutputArgs = GIOProtoArgs<Out_Tag>;
|
||||
|
||||
@@ -33,7 +33,7 @@ class gapi_core_test(NewOpenCVTests):
|
||||
comp = cv.GComputation(cv.GIn(g_in1, g_in2), cv.GOut(g_out))
|
||||
|
||||
for pkg in pkgs:
|
||||
actual = comp.apply(in1, in2, args=cv.compile_args(pkg))
|
||||
actual = comp.apply(cv.gin(in1, in2), args=cv.compile_args(pkg))
|
||||
# Comparison
|
||||
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF))
|
||||
|
||||
@@ -51,10 +51,51 @@ class gapi_core_test(NewOpenCVTests):
|
||||
comp = cv.GComputation(g_in, g_out)
|
||||
|
||||
for pkg in pkgs:
|
||||
actual = comp.apply(in_mat, args=cv.compile_args(pkg))
|
||||
actual = comp.apply(cv.gin(in_mat), args=cv.compile_args(pkg))
|
||||
# Comparison
|
||||
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF))
|
||||
|
||||
|
||||
def test_split3(self):
|
||||
sz = (1280, 720, 3)
|
||||
in_mat = np.random.randint(0, 100, sz).astype(np.uint8)
|
||||
|
||||
# OpenCV
|
||||
expected = cv.split(in_mat)
|
||||
|
||||
# G-API
|
||||
g_in = cv.GMat()
|
||||
b, g, r = cv.gapi.split3(g_in)
|
||||
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(b, g, r))
|
||||
|
||||
for pkg in pkgs:
|
||||
actual = comp.apply(cv.gin(in_mat), args=cv.compile_args(pkg))
|
||||
# Comparison
|
||||
for e, a in zip(expected, actual):
|
||||
self.assertEqual(0.0, cv.norm(e, a, cv.NORM_INF))
|
||||
|
||||
|
||||
def test_threshold(self):
|
||||
sz = (1280, 720)
|
||||
in_mat = np.random.randint(0, 100, sz).astype(np.uint8)
|
||||
rand_int = np.random.randint(0, 50)
|
||||
maxv = (rand_int, rand_int)
|
||||
|
||||
# OpenCV
|
||||
expected_thresh, expected_mat = cv.threshold(in_mat, maxv[0], maxv[0], cv.THRESH_TRIANGLE)
|
||||
|
||||
# G-API
|
||||
g_in = cv.GMat()
|
||||
g_sc = cv.GScalar()
|
||||
mat, threshold = cv.gapi.threshold(g_in, g_sc, cv.THRESH_TRIANGLE)
|
||||
comp = cv.GComputation(cv.GIn(g_in, g_sc), cv.GOut(mat, threshold))
|
||||
|
||||
for pkg in pkgs:
|
||||
actual_mat, actual_thresh = comp.apply(cv.gin(in_mat, maxv), args=cv.compile_args(pkg))
|
||||
# Comparison
|
||||
self.assertEqual(0.0, cv.norm(expected_mat, actual_mat, cv.NORM_INF))
|
||||
self.assertEqual(expected_thresh, actual_thresh[0])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
NewOpenCVTests.bootstrap()
|
||||
|
||||
@@ -33,7 +33,7 @@ class gapi_sample_pipelines(NewOpenCVTests):
|
||||
comp = cv.GComputation(g_in, g_out)
|
||||
|
||||
for pkg in pkgs:
|
||||
actual = comp.apply(in_mat, args=cv.compile_args(pkg))
|
||||
actual = comp.apply(cv.gin(in_mat), args=cv.compile_args(pkg))
|
||||
# Comparison
|
||||
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user