From c8776e6ebd14b0928905b37a1a24b0138c1789a4 Mon Sep 17 00:00:00 2001 From: Ruslan Garnov Date: Wed, 11 Mar 2020 15:45:35 +0300 Subject: [PATCH] Added GFrame --- .../include/opencv2/gapi/cpu/gcpukernel.hpp | 4 ++ modules/gapi/include/opencv2/gapi/gkernel.hpp | 3 + modules/gapi/include/opencv2/gapi/gmat.hpp | 6 ++ modules/gapi/include/opencv2/gapi/gproto.hpp | 1 + .../include/opencv2/gapi/gtype_traits.hpp | 6 ++ modules/gapi/src/api/gproto.cpp | 7 ++- modules/gapi/src/compiler/gcompiler.cpp | 1 + modules/gapi/test/gapi_frame_tests.cpp | 61 +++++++++++++++++++ .../gapi/test/internal/gapi_int_garg_test.cpp | 1 + 9 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 modules/gapi/test/gapi_frame_tests.cpp diff --git a/modules/gapi/include/opencv2/gapi/cpu/gcpukernel.hpp b/modules/gapi/include/opencv2/gapi/cpu/gcpukernel.hpp index 59090cc502..764e085b4e 100644 --- a/modules/gapi/include/opencv2/gapi/cpu/gcpukernel.hpp +++ b/modules/gapi/include/opencv2/gapi/cpu/gcpukernel.hpp @@ -153,6 +153,10 @@ template<> struct get_in { static cv::Mat get(GCPUContext &ctx, int idx) { return get_in::get(ctx, idx); } }; +template<> struct get_in +{ + static cv::Mat get(GCPUContext &ctx, int idx) { return get_in::get(ctx, idx); } +}; template<> struct get_in { static cv::Scalar get(GCPUContext &ctx, int idx) { return ctx.inVal(idx); } diff --git a/modules/gapi/include/opencv2/gapi/gkernel.hpp b/modules/gapi/include/opencv2/gapi/gkernel.hpp index becd7796e2..478d7d34d1 100644 --- a/modules/gapi/include/opencv2/gapi/gkernel.hpp +++ b/modules/gapi/include/opencv2/gapi/gkernel.hpp @@ -90,6 +90,7 @@ namespace detail template struct MetaType; template<> struct MetaType { using type = GMatDesc; }; template<> struct MetaType { using type = GMatDesc; }; + template<> struct MetaType { using type = GMatDesc; }; template<> struct MetaType { using type = GScalarDesc; }; template struct MetaType > { using type = GArrayDesc; }; template struct MetaType > { using type = GOpaqueDesc; }; @@ -220,6 +221,8 @@ public: using InArgs = std::tuple; using OutArgs = std::tuple; + static_assert(!cv::detail::contains::value, "Values of GFrame type can't be used as operation outputs"); + static R on(Args... args) { cv::GCall call(GKernel{K::id(), K::tag(), &K::getOutMeta, {detail::GTypeTraits::shape}}); diff --git a/modules/gapi/include/opencv2/gapi/gmat.hpp b/modules/gapi/include/opencv2/gapi/gmat.hpp index ffe1c07206..eed9364b61 100644 --- a/modules/gapi/include/opencv2/gapi/gmat.hpp +++ b/modules/gapi/include/opencv2/gapi/gmat.hpp @@ -65,6 +65,12 @@ public: using GMat::GMat; }; +class GAPI_EXPORTS GFrame : public GMat +{ +public: + using GMat::GMat; +}; + namespace gapi { namespace own { class Mat; }}//gapi::own diff --git a/modules/gapi/include/opencv2/gapi/gproto.hpp b/modules/gapi/include/opencv2/gapi/gproto.hpp index 921a588305..885819903b 100644 --- a/modules/gapi/include/opencv2/gapi/gproto.hpp +++ b/modules/gapi/include/opencv2/gapi/gproto.hpp @@ -36,6 +36,7 @@ namespace cv { using GProtoArg = util::variant < GMat , GMatP + , GFrame , GScalar , detail::GArrayU // instead of GArray , detail::GOpaqueU // instead of GOpaque diff --git a/modules/gapi/include/opencv2/gapi/gtype_traits.hpp b/modules/gapi/include/opencv2/gapi/gtype_traits.hpp index 85bcb69bac..fbdac15d9f 100644 --- a/modules/gapi/include/opencv2/gapi/gtype_traits.hpp +++ b/modules/gapi/include/opencv2/gapi/gtype_traits.hpp @@ -36,6 +36,7 @@ namespace detail GOBJREF, // reference to object GMAT, // a cv::GMat GMATP, // a cv::GMatP + GFRAME, // a cv::GFrame GSCALAR, // a cv::GScalar GARRAY, // a cv::GArrayU (note - exactly GArrayU, not GArray!) GOPAQUE, // a cv::GOpaqueU (note - exactly GOpaqueU, not GOpaque!) @@ -60,6 +61,11 @@ namespace detail static constexpr const ArgKind kind = ArgKind::GMATP; static constexpr const GShape shape = GShape::GMAT; }; + template<> struct GTypeTraits + { + static constexpr const ArgKind kind = ArgKind::GFRAME; + static constexpr const GShape shape = GShape::GMAT; + }; template<> struct GTypeTraits { static constexpr const ArgKind kind = ArgKind::GSCALAR; diff --git a/modules/gapi/src/api/gproto.cpp b/modules/gapi/src/api/gproto.cpp index d6a68d5f03..1fdd9e3776 100644 --- a/modules/gapi/src/api/gproto.cpp +++ b/modules/gapi/src/api/gproto.cpp @@ -28,6 +28,9 @@ const cv::GOrigin& cv::gimpl::proto::origin_of(const cv::GProtoArg &arg) case cv::GProtoArg::index_of(): return util::get(arg).priv(); + case cv::GProtoArg::index_of(): + return util::get(arg).priv(); + case cv::GProtoArg::index_of(): return util::get(arg).priv(); @@ -60,6 +63,7 @@ bool cv::gimpl::proto::is_dynamic(const cv::GArg& arg) { case detail::ArgKind::GMAT: case detail::ArgKind::GMATP: + case detail::ArgKind::GFRAME: case detail::ArgKind::GSCALAR: case detail::ArgKind::GARRAY: case detail::ArgKind::GOPAQUE: @@ -87,9 +91,10 @@ cv::GProtoArg cv::gimpl::proto::rewrap(const cv::GArg &arg) { case detail::ArgKind::GMAT: return GProtoArg(arg.get()); case detail::ArgKind::GMATP: return GProtoArg(arg.get()); + case detail::ArgKind::GFRAME: return GProtoArg(arg.get()); case detail::ArgKind::GSCALAR: return GProtoArg(arg.get()); case detail::ArgKind::GARRAY: return GProtoArg(arg.get()); - case detail::ArgKind::GOPAQUE: return GProtoArg(arg.get()); + case detail::ArgKind::GOPAQUE: return GProtoArg(arg.get()); default: util::throw_error(std::logic_error("Unsupported GArg type")); } } diff --git a/modules/gapi/src/compiler/gcompiler.cpp b/modules/gapi/src/compiler/gcompiler.cpp index 1ee710c235..92db768c5c 100644 --- a/modules/gapi/src/compiler/gcompiler.cpp +++ b/modules/gapi/src/compiler/gcompiler.cpp @@ -324,6 +324,7 @@ void cv::gimpl::GCompiler::validateInputMeta() // FIXME: Auto-generate methods like this from traits: case GProtoArg::index_of(): case GProtoArg::index_of(): + case GProtoArg::index_of(): return util::holds_alternative(meta); case GProtoArg::index_of(): diff --git a/modules/gapi/test/gapi_frame_tests.cpp b/modules/gapi/test/gapi_frame_tests.cpp new file mode 100644 index 0000000000..3b03ee0592 --- /dev/null +++ b/modules/gapi/test/gapi_frame_tests.cpp @@ -0,0 +1,61 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2020 Intel Corporation + +#include "test_precomp.hpp" + +#include + +namespace opencv_test +{ + +G_API_OP(GBlurFrame, , "test.blur_frame") { + static GMatDesc outMeta(GMatDesc in) { + return in; + } +}; + +GAPI_OCV_KERNEL(OCVBlurFrame, GBlurFrame) +{ + static void run(const cv::Mat& in, cv::Mat& out) { + cv::blur(in, out, cv::Size{3,3}); + } +}; + +struct GFrameTest : public ::testing::Test +{ + cv::Size sz{32,32}; + cv::Mat in_mat; + cv::Mat out_mat; + cv::Mat out_mat_ocv; + + GFrameTest() + : in_mat(cv::Mat(sz, CV_8UC1)) + , out_mat(cv::Mat::zeros(sz, CV_8UC1)) + , out_mat_ocv(cv::Mat::zeros(sz, CV_8UC1)) + { + cv::randn(in_mat, cv::Scalar::all(127.0f), cv::Scalar::all(40.f)); + cv::blur(in_mat, out_mat_ocv, cv::Size{3,3}); + } + + void check() + { + EXPECT_EQ(0, cvtest::norm(out_mat, out_mat_ocv, NORM_INF)); + } +}; + +TEST_F(GFrameTest, Input) +{ + cv::GFrame in; + auto out = GBlurFrame::on(in); + cv::GComputation c(cv::GIn(in), cv::GOut(out)); + + auto pkg = cv::gapi::kernels(); + c.apply(cv::gin(in_mat), cv::gout(out_mat), cv::compile_args(pkg)); + + check(); +} + +} // namespace opencv_test diff --git a/modules/gapi/test/internal/gapi_int_garg_test.cpp b/modules/gapi/test/internal/gapi_int_garg_test.cpp index aad112309c..a8793721af 100644 --- a/modules/gapi/test/internal/gapi_int_garg_test.cpp +++ b/modules/gapi/test/internal/gapi_int_garg_test.cpp @@ -32,6 +32,7 @@ using GArg_Test_Types = ::testing::Types // G-API types Expected , Expected + , Expected , Expected , Expected, cv::detail::ArgKind::GARRAY> , Expected, cv::detail::ArgKind::GARRAY>