mirror of
https://github.com/opencv/opencv.git
synced 2025-06-06 17:03:18 +08:00
Implement cv.gin and multiple output for python
This commit is contained in:
parent
295afd5882
commit
e998d89e88
@ -1331,7 +1331,7 @@ GAPI_EXPORTS GMat threshold(const GMat& src, const GScalar& thresh, const GScala
|
|||||||
This function applicable for all threshold types except CV_THRESH_OTSU and CV_THRESH_TRIANGLE
|
This function applicable for all threshold types except CV_THRESH_OTSU and CV_THRESH_TRIANGLE
|
||||||
@note Function textual ID is "org.opencv.core.matrixop.thresholdOT"
|
@note Function textual ID is "org.opencv.core.matrixop.thresholdOT"
|
||||||
*/
|
*/
|
||||||
GAPI_EXPORTS std::tuple<GMat, GScalar> threshold(const GMat& src, const GScalar& maxval, int type);
|
GAPI_EXPORTS_W std::tuple<GMat, GScalar> threshold(const GMat& src, const GScalar& maxval, int type);
|
||||||
|
|
||||||
/** @brief Applies a range-level threshold to each matrix element.
|
/** @brief Applies a range-level threshold to each matrix element.
|
||||||
|
|
||||||
|
@ -259,6 +259,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
void apply(GRunArgs &&ins, GRunArgsP &&outs, GCompileArgs &&args = {}); // Arg-to-arg overload
|
void apply(GRunArgs &&ins, GRunArgsP &&outs, GCompileArgs &&args = {}); // Arg-to-arg overload
|
||||||
|
|
||||||
|
/// @private -- Exclude this function from OpenCV documentation
|
||||||
|
GAPI_WRAP GRunArgs apply(GRunArgs &&ins, GCompileArgs &&args = {});
|
||||||
|
|
||||||
/// @private -- Exclude this function from OpenCV documentation
|
/// @private -- Exclude this function from OpenCV documentation
|
||||||
void apply(const std::vector<cv::Mat>& ins, // Compatibility overload
|
void apply(const std::vector<cv::Mat>& ins, // Compatibility overload
|
||||||
const std::vector<cv::Mat>& outs,
|
const std::vector<cv::Mat>& outs,
|
||||||
@ -286,7 +289,7 @@ public:
|
|||||||
* @param args compilation arguments for underlying compilation
|
* @param args compilation arguments for underlying compilation
|
||||||
* process.
|
* process.
|
||||||
*/
|
*/
|
||||||
GAPI_WRAP void apply(cv::Mat in, CV_OUT cv::Scalar &out, GCompileArgs &&args = {}); // Unary overload (scalar)
|
void apply(cv::Mat in, cv::Scalar &out, GCompileArgs &&args = {}); // Unary overload (scalar)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Execute a binary computation (with compilation on the fly)
|
* @brief Execute a binary computation (with compilation on the fly)
|
||||||
@ -298,7 +301,7 @@ public:
|
|||||||
* @param args compilation arguments for underlying compilation
|
* @param args compilation arguments for underlying compilation
|
||||||
* process.
|
* process.
|
||||||
*/
|
*/
|
||||||
GAPI_WRAP void apply(cv::Mat in1, cv::Mat in2, CV_OUT cv::Mat &out, GCompileArgs &&args = {}); // Binary overload
|
void apply(cv::Mat in1, cv::Mat in2, cv::Mat &out, GCompileArgs &&args = {}); // Binary overload
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Execute an binary computation (with compilation on the fly)
|
* @brief Execute an binary computation (with compilation on the fly)
|
||||||
@ -528,6 +531,7 @@ protected:
|
|||||||
GCompileArgs comp_args = std::get<sizeof...(Ts)-1>(meta_and_compile_args);
|
GCompileArgs comp_args = std::get<sizeof...(Ts)-1>(meta_and_compile_args);
|
||||||
return compileStreaming(std::move(meta_args), std::move(comp_args));
|
return compileStreaming(std::move(meta_args), std::move(comp_args));
|
||||||
}
|
}
|
||||||
|
void recompile(GMetaArgs&& in_metas, GCompileArgs &&args);
|
||||||
/// @private
|
/// @private
|
||||||
std::shared_ptr<Priv> m_priv;
|
std::shared_ptr<Priv> m_priv;
|
||||||
};
|
};
|
||||||
|
@ -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;
|
using gapi_GKernelPackage = cv::gapi::GKernelPackage;
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
@ -12,6 +17,67 @@ PyObject* pyopencv_from(const std::vector<GCompileArg>& value)
|
|||||||
return pyopencv_from_generic_vec(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>
|
template <typename T>
|
||||||
static PyObject* extract_proto_args(PyObject* py_args, PyObject* kw)
|
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;
|
GProtoArgs args;
|
||||||
Py_ssize_t size = PyTuple_Size(py_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);
|
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);
|
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);
|
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");
|
PyErr_SetString(PyExc_TypeError, "cv.GIn() supports only cv.GMat and cv.GScalar");
|
||||||
return NULL;
|
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);
|
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
|
namespace cv
|
||||||
{
|
{
|
||||||
GAPI_EXPORTS_W GCompileArgs compile_args(gapi::GKernelPackage pkg);
|
GAPI_EXPORTS_W GCompileArgs compile_args(gapi::GKernelPackage pkg);
|
||||||
|
|
||||||
class GAPI_EXPORTS_W_SIMPLE GProtoArg { };
|
class GAPI_EXPORTS_W_SIMPLE GProtoArg { };
|
||||||
class GAPI_EXPORTS_W_SIMPLE GProtoInputArgs { };
|
class GAPI_EXPORTS_W_SIMPLE GProtoInputArgs { };
|
||||||
class GAPI_EXPORTS_W_SIMPLE GProtoOutputArgs { };
|
class GAPI_EXPORTS_W_SIMPLE GProtoOutputArgs { };
|
||||||
|
class GAPI_EXPORTS_W_SIMPLE GRunArg { };
|
||||||
|
|
||||||
using GProtoInputArgs = GIOProtoArgs<In_Tag>;
|
using GProtoInputArgs = GIOProtoArgs<In_Tag>;
|
||||||
using GProtoOutputArgs = GIOProtoArgs<Out_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))
|
comp = cv.GComputation(cv.GIn(g_in1, g_in2), cv.GOut(g_out))
|
||||||
|
|
||||||
for pkg in pkgs:
|
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
|
# Comparison
|
||||||
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF))
|
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)
|
comp = cv.GComputation(g_in, g_out)
|
||||||
|
|
||||||
for pkg in pkgs:
|
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
|
# Comparison
|
||||||
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF))
|
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__':
|
if __name__ == '__main__':
|
||||||
NewOpenCVTests.bootstrap()
|
NewOpenCVTests.bootstrap()
|
||||||
|
@ -33,7 +33,7 @@ class gapi_sample_pipelines(NewOpenCVTests):
|
|||||||
comp = cv.GComputation(g_in, g_out)
|
comp = cv.GComputation(g_in, g_out)
|
||||||
|
|
||||||
for pkg in pkgs:
|
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
|
# Comparison
|
||||||
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF))
|
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF))
|
||||||
|
|
||||||
|
@ -129,15 +129,14 @@ static bool formats_are_same(const cv::GMetaArgs& metas1, const cv::GMetaArgs& m
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void cv::GComputation::apply(GRunArgs &&ins, GRunArgsP &&outs, GCompileArgs &&args)
|
void cv::GComputation::recompile(GMetaArgs&& in_metas, GCompileArgs &&args)
|
||||||
{
|
{
|
||||||
const auto in_metas = descr_of(ins);
|
|
||||||
// FIXME Graph should be recompiled when GCompileArgs have changed
|
// FIXME Graph should be recompiled when GCompileArgs have changed
|
||||||
if (m_priv->m_lastMetas != in_metas)
|
if (m_priv->m_lastMetas != in_metas)
|
||||||
{
|
{
|
||||||
if (m_priv->m_lastCompiled &&
|
if (m_priv->m_lastCompiled &&
|
||||||
m_priv->m_lastCompiled.canReshape() &&
|
m_priv->m_lastCompiled.canReshape() &&
|
||||||
formats_are_same(m_priv->m_lastMetas, in_metas))
|
formats_are_same(m_priv->m_lastMetas, in_metas))
|
||||||
{
|
{
|
||||||
m_priv->m_lastCompiled.reshape(in_metas, args);
|
m_priv->m_lastCompiled.reshape(in_metas, args);
|
||||||
}
|
}
|
||||||
@ -148,6 +147,11 @@ void cv::GComputation::apply(GRunArgs &&ins, GRunArgsP &&outs, GCompileArgs &&ar
|
|||||||
}
|
}
|
||||||
m_priv->m_lastMetas = in_metas;
|
m_priv->m_lastMetas = in_metas;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cv::GComputation::apply(GRunArgs &&ins, GRunArgsP &&outs, GCompileArgs &&args)
|
||||||
|
{
|
||||||
|
recompile(descr_of(ins), std::move(args));
|
||||||
m_priv->m_lastCompiled(std::move(ins), std::move(outs));
|
m_priv->m_lastCompiled(std::move(ins), std::move(outs));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,6 +169,41 @@ void cv::GComputation::apply(const std::vector<cv::Mat> &ins,
|
|||||||
apply(std::move(call_ins), std::move(call_outs), std::move(args));
|
apply(std::move(call_ins), std::move(call_outs), std::move(args));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NB: This overload is called from python code
|
||||||
|
cv::GRunArgs cv::GComputation::apply(GRunArgs &&ins, GCompileArgs &&args)
|
||||||
|
{
|
||||||
|
recompile(descr_of(ins), std::move(args));
|
||||||
|
|
||||||
|
const auto& out_metas = m_priv->m_lastCompiled.outMetas();
|
||||||
|
GRunArgs run_args;
|
||||||
|
GRunArgsP outs;
|
||||||
|
run_args.reserve(out_metas.size());
|
||||||
|
outs.reserve(out_metas.size());
|
||||||
|
|
||||||
|
for (auto&& meta : out_metas)
|
||||||
|
{
|
||||||
|
switch (meta.index())
|
||||||
|
{
|
||||||
|
case cv::GMetaArg::index_of<cv::GMatDesc>():
|
||||||
|
{
|
||||||
|
run_args.emplace_back(cv::Mat{});
|
||||||
|
outs.emplace_back(&cv::util::get<cv::Mat>(run_args.back()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case cv::GMetaArg::index_of<cv::GScalarDesc>():
|
||||||
|
{
|
||||||
|
run_args.emplace_back(cv::Scalar{});
|
||||||
|
outs.emplace_back(&cv::util::get<cv::Scalar>(run_args.back()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
util::throw_error(std::logic_error("Only cv::GMat and cv::GScalar are supported for python output"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_priv->m_lastCompiled(std::move(ins), std::move(outs));
|
||||||
|
return run_args;
|
||||||
|
}
|
||||||
|
|
||||||
#if !defined(GAPI_STANDALONE)
|
#if !defined(GAPI_STANDALONE)
|
||||||
void cv::GComputation::apply(cv::Mat in, cv::Mat &out, GCompileArgs &&args)
|
void cv::GComputation::apply(cv::Mat in, cv::Mat &out, GCompileArgs &&args)
|
||||||
{
|
{
|
||||||
|
@ -6,6 +6,9 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "test_precomp.hpp"
|
#include "test_precomp.hpp"
|
||||||
|
|
||||||
|
#include <opencv2/gapi/s11n.hpp>
|
||||||
|
|
||||||
#include <opencv2/gapi/cpu/gcpukernel.hpp>
|
#include <opencv2/gapi/cpu/gcpukernel.hpp>
|
||||||
#include <ade/util/zip_range.hpp>
|
#include <ade/util/zip_range.hpp>
|
||||||
|
|
||||||
@ -87,6 +90,51 @@ namespace opencv_test
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// NB: Check an apply specifically designed to be called from Python,
|
||||||
|
// but can also be used from C++
|
||||||
|
struct GComputationPythonApplyTest: public ::testing::Test
|
||||||
|
{
|
||||||
|
cv::Size sz;
|
||||||
|
MatType type;
|
||||||
|
cv::Mat in_mat1, in_mat2, out_mat_ocv;
|
||||||
|
cv::GComputation m_c;
|
||||||
|
|
||||||
|
GComputationPythonApplyTest() : sz(cv::Size(300,300)), type(CV_8UC1),
|
||||||
|
in_mat1(sz, type), in_mat2(sz, type), out_mat_ocv(sz, type),
|
||||||
|
m_c([&](){
|
||||||
|
cv::GMat in1, in2;
|
||||||
|
cv::GMat out = in1 + in2;
|
||||||
|
return cv::GComputation(cv::GIn(in1, in2), cv::GOut(out));
|
||||||
|
})
|
||||||
|
{
|
||||||
|
cv::randu(in_mat1, cv::Scalar::all(0), cv::Scalar::all(255));
|
||||||
|
cv::randu(in_mat2, cv::Scalar::all(0), cv::Scalar::all(255));
|
||||||
|
out_mat_ocv = in_mat1 + in_mat2;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(GComputationPythonApplyTest, WithoutSerialization)
|
||||||
|
{
|
||||||
|
auto output = m_c.apply(cv::gin(in_mat1, in_mat2));
|
||||||
|
EXPECT_EQ(1u, output.size());
|
||||||
|
|
||||||
|
const auto& out_mat_gapi = cv::util::get<cv::Mat>(output[0]);
|
||||||
|
EXPECT_EQ(0, cvtest::norm(out_mat_ocv, out_mat_gapi, NORM_INF));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(GComputationPythonApplyTest, WithSerialization)
|
||||||
|
{
|
||||||
|
auto p = cv::gapi::serialize(m_c);
|
||||||
|
auto c = cv::gapi::deserialize<cv::GComputation>(p);
|
||||||
|
|
||||||
|
auto output = c.apply(cv::gin(in_mat1, in_mat2));
|
||||||
|
EXPECT_EQ(1u, output.size());
|
||||||
|
|
||||||
|
const auto& out_mat_gapi = cv::util::get<cv::Mat>(output[0]);
|
||||||
|
EXPECT_EQ(0, cvtest::norm(out_mat_ocv, out_mat_gapi, NORM_INF));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(GComputationApplyTest, ThrowDontPassCustomKernel)
|
TEST_F(GComputationApplyTest, ThrowDontPassCustomKernel)
|
||||||
|
@ -1954,6 +1954,7 @@ static PyMethodDef special_methods[] = {
|
|||||||
#ifdef HAVE_OPENCV_GAPI
|
#ifdef HAVE_OPENCV_GAPI
|
||||||
{"GIn", CV_PY_FN_WITH_KW(pyopencv_cv_GIn), "GIn(...) -> GInputProtoArgs"},
|
{"GIn", CV_PY_FN_WITH_KW(pyopencv_cv_GIn), "GIn(...) -> GInputProtoArgs"},
|
||||||
{"GOut", CV_PY_FN_WITH_KW(pyopencv_cv_GOut), "GOut(...) -> GOutputProtoArgs"},
|
{"GOut", CV_PY_FN_WITH_KW(pyopencv_cv_GOut), "GOut(...) -> GOutputProtoArgs"},
|
||||||
|
{"gin", CV_PY_FN_WITH_KW(pyopencv_cv_gin), "gin(...) -> GRunArgs"},
|
||||||
#endif
|
#endif
|
||||||
{NULL, NULL},
|
{NULL, NULL},
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user