From f7cab121fe2954c67b343b3b7805e1c092812093 Mon Sep 17 00:00:00 2001 From: Ruslan Garnov Date: Wed, 16 Dec 2020 14:18:08 +0300 Subject: [PATCH] Merge pull request #19112 from rgarnov:rg/generic_copy_kernel Generic copy kernel * Moved RMat wrapping of cv::Mats to StreamingInput * Generalized GCopy kernel * Generic GCopy kernel: applied review comments --- modules/gapi/include/opencv2/gapi/core.hpp | 19 ------ .../include/opencv2/gapi/streaming/format.hpp | 40 ++++++----- .../perf/cpu/gapi_core_perf_tests_fluid.cpp | 5 -- .../perf/gpu/gapi_core_perf_tests_gpu.cpp | 5 -- modules/gapi/src/api/kernels_core.cpp | 5 -- modules/gapi/src/api/kernels_streaming.cpp | 4 -- modules/gapi/src/backends/cpu/gcpucore.cpp | 9 --- .../gapi/src/backends/fluid/gfluidcore.cpp | 35 ---------- modules/gapi/src/backends/ocl/goclcore.cpp | 9 --- .../backends/streaming/gstreamingbackend.cpp | 32 ++++++++- .../backends/streaming/gstreamingbackend.hpp | 28 +++++++- modules/gapi/src/compiler/gcompiler.cpp | 8 ++- modules/gapi/src/compiler/gislandmodel.cpp | 18 +---- modules/gapi/src/executor/gexecutor.cpp | 24 +++++-- .../gapi/src/executor/gstreamingexecutor.cpp | 11 ++- .../gapi/test/cpu/gapi_core_tests_fluid.cpp | 8 --- modules/gapi/test/gpu/gapi_core_tests_gpu.cpp | 8 --- .../internal/gapi_int_island_fusion_tests.cpp | 6 +- .../test/streaming/gapi_streaming_tests.cpp | 67 ++++++++++++------- 19 files changed, 161 insertions(+), 180 deletions(-) diff --git a/modules/gapi/include/opencv2/gapi/core.hpp b/modules/gapi/include/opencv2/gapi/core.hpp index 6fca437d5a..bd1507b14c 100644 --- a/modules/gapi/include/opencv2/gapi/core.hpp +++ b/modules/gapi/include/opencv2/gapi/core.hpp @@ -451,12 +451,6 @@ namespace core { } }; - G_TYPED_KERNEL(GCopy, , "org.opencv.core.transform.copy") { - static GMatDesc outMeta(GMatDesc in) { - return in; - } - }; - G_TYPED_KERNEL(GConcatHor, , "org.opencv.imgproc.transform.concatHor") { static GMatDesc outMeta(GMatDesc l, GMatDesc r) { return l.withSizeDelta(+r.size.width, 0); @@ -1667,19 +1661,6 @@ Output matrix must be of the same depth as input one, size is specified by given */ GAPI_EXPORTS GMat crop(const GMat& src, const Rect& rect); -/** @brief Copies a matrix. - -Copies an input array. Works as a regular Mat::clone but happens in-graph. -Mainly is used to workaround some existing limitations (e.g. to forward an input frame to outputs -in the streaming mode). Will be deprecated and removed in the future. - -@note Function textual ID is "org.opencv.core.transform.copy" - -@param src input matrix. -@sa crop -*/ -GAPI_EXPORTS GMat copy(const GMat& src); - /** @brief Applies horizontal concatenation to given matrices. The function horizontally concatenates two GMat matrices (with the same number of rows). diff --git a/modules/gapi/include/opencv2/gapi/streaming/format.hpp b/modules/gapi/include/opencv2/gapi/streaming/format.hpp index 4be25f220c..d450d56a59 100644 --- a/modules/gapi/include/opencv2/gapi/streaming/format.hpp +++ b/modules/gapi/include/opencv2/gapi/streaming/format.hpp @@ -15,26 +15,11 @@ namespace streaming { GAPI_EXPORTS cv::gapi::GKernelPackage kernels(); -// FIXME: Make a generic kernel -G_API_OP(GCopy, , "org.opencv.streaming.copy") -{ - static GFrameDesc outMeta(const GFrameDesc& in) { return in; } -}; - G_API_OP(GBGR, , "org.opencv.streaming.BGR") { static GMatDesc outMeta(const GFrameDesc& in) { return GMatDesc{CV_8U, 3, in.size}; } }; -/** @brief Gets copy from the input frame - -@note Function textual ID is "org.opencv.streaming.copy" - -@param in Input frame -@return Copy of the input frame -*/ -GAPI_EXPORTS cv::GFrame copy(const cv::GFrame& in); - /** @brief Gets bgr plane from input frame @note Function textual ID is "org.opencv.streaming.BGR" @@ -42,9 +27,32 @@ GAPI_EXPORTS cv::GFrame copy(const cv::GFrame& in); @param in Input frame @return Image in BGR format */ -GAPI_EXPORTS cv::GMat BGR (const cv::GFrame& in); +GAPI_EXPORTS cv::GMat BGR(const cv::GFrame& in); } // namespace streaming + +/** @brief Makes a copy of the input image. Note that this copy may be not real +(no actual data copied). Use this function to maintain graph contracts, +e.g when graph's input needs to be passed directly to output, like in Streaming mode. + +@note Function textual ID is "org.opencv.streaming.copy" + +@param in Input image +@return Copy of the input +*/ +GAPI_EXPORTS cv::GMat copy(const cv::GMat& in); + +/** @brief Makes a copy of the input frame. Note that this copy may be not real +(no actual data copied). Use this function to maintain graph contracts, +e.g when graph's input needs to be passed directly to output, like in Streaming mode. + +@note Function textual ID is "org.opencv.streaming.copy" + +@param in Input frame +@return Copy of the input +*/ +GAPI_EXPORTS cv::GFrame copy(const cv::GFrame& in); + } // namespace gapi } // namespace cv diff --git a/modules/gapi/perf/cpu/gapi_core_perf_tests_fluid.cpp b/modules/gapi/perf/cpu/gapi_core_perf_tests_fluid.cpp index 2234353c1f..874b75b679 100644 --- a/modules/gapi/perf/cpu/gapi_core_perf_tests_fluid.cpp +++ b/modules/gapi/perf/cpu/gapi_core_perf_tests_fluid.cpp @@ -233,11 +233,6 @@ INSTANTIATE_TEST_CASE_P(Split3PerfTestFluid, Split3PerfTest, // Values(cv::Rect(10, 8, 20, 35), cv::Rect(4, 10, 37, 50)), // Values(cv::compile_args(CORE_FLUID)))); -// INSTANTIATE_TEST_CASE_P(CopyPerfTestFluid, CopyPerfTest, -// Combine(Values(szSmall128, szVGA, sz720p, sz1080p), -// Values(CV_8UC1, CV_8UC3, CV_16UC1, CV_16SC1, CV_32FC1), -// Values(cv::compile_args(CORE_FLUID)))); - // INSTANTIATE_TEST_CASE_P(ConcatHorPerfTestFluid, ConcatHorPerfTest, // Combine(Values(szSmall128, szVGA, sz720p, sz1080p), // Values(CV_8UC1, CV_8UC3, CV_16UC1, CV_16SC1, CV_32FC1), diff --git a/modules/gapi/perf/gpu/gapi_core_perf_tests_gpu.cpp b/modules/gapi/perf/gpu/gapi_core_perf_tests_gpu.cpp index 2d8c254cd2..955799634c 100644 --- a/modules/gapi/perf/gpu/gapi_core_perf_tests_gpu.cpp +++ b/modules/gapi/perf/gpu/gapi_core_perf_tests_gpu.cpp @@ -232,11 +232,6 @@ INSTANTIATE_TEST_CASE_P(CropPerfTestGPU, CropPerfTest, Values(cv::Rect(10, 8, 20, 35), cv::Rect(4, 10, 37, 50)), Values(cv::compile_args(CORE_GPU)))); -INSTANTIATE_TEST_CASE_P(CopyPerfTestGPU, CopyPerfTest, - Combine(Values( szSmall128, szVGA, sz720p, sz1080p ), - Values( CV_8UC1, CV_8UC3, CV_16UC1, CV_16SC1, CV_32FC1 ), - Values(cv::compile_args(CORE_GPU)))); - INSTANTIATE_TEST_CASE_P(ConcatHorPerfTestGPU, ConcatHorPerfTest, Combine(Values( szSmall128, szVGA, sz720p, sz1080p ), Values( CV_8UC1, CV_8UC3, CV_16UC1, CV_16SC1, CV_32FC1 ), diff --git a/modules/gapi/src/api/kernels_core.cpp b/modules/gapi/src/api/kernels_core.cpp index 15af915bdd..8ff992a0aa 100644 --- a/modules/gapi/src/api/kernels_core.cpp +++ b/modules/gapi/src/api/kernels_core.cpp @@ -328,11 +328,6 @@ GMat crop(const GMat& src, const Rect& rect) return core::GCrop::on(src, rect); } -GMat copy(const GMat& src) -{ - return core::GCopy::on(src); -} - GMat concatHor(const GMat& src1, const GMat& src2) { return core::GConcatHor::on(src1, src2); diff --git a/modules/gapi/src/api/kernels_streaming.cpp b/modules/gapi/src/api/kernels_streaming.cpp index 66bf27260d..25045eafbd 100644 --- a/modules/gapi/src/api/kernels_streaming.cpp +++ b/modules/gapi/src/api/kernels_streaming.cpp @@ -75,10 +75,6 @@ cv::GMat cv::gapi::streaming::desync(const cv::GMat &g) { // object will feed both branches of the streaming executable. } -cv::GFrame cv::gapi::streaming::copy(const cv::GFrame& in) { - return cv::gapi::streaming::GCopy::on(in); -} - cv::GMat cv::gapi::streaming::BGR(const cv::GFrame& in) { return cv::gapi::streaming::GBGR::on(in); } diff --git a/modules/gapi/src/backends/cpu/gcpucore.cpp b/modules/gapi/src/backends/cpu/gcpucore.cpp index 3e6ce1c1d4..5c358f5672 100644 --- a/modules/gapi/src/backends/cpu/gcpucore.cpp +++ b/modules/gapi/src/backends/cpu/gcpucore.cpp @@ -510,14 +510,6 @@ GAPI_OCV_KERNEL(GCPUCrop, cv::gapi::core::GCrop) } }; -GAPI_OCV_KERNEL(GCPUCopy, cv::gapi::core::GCopy) -{ - static void run(const cv::Mat& in, cv::Mat& out) - { - in.copyTo(out); - } -}; - GAPI_OCV_KERNEL(GCPUConcatHor, cv::gapi::core::GConcatHor) { static void run(const cv::Mat& in1, const cv::Mat& in2, cv::Mat& out) @@ -762,7 +754,6 @@ cv::gapi::GKernelPackage cv::gapi::core::cpu::kernels() , GCPURemap , GCPUFlip , GCPUCrop - , GCPUCopy , GCPUConcatHor , GCPUConcatVert , GCPULUT diff --git a/modules/gapi/src/backends/fluid/gfluidcore.cpp b/modules/gapi/src/backends/fluid/gfluidcore.cpp index edc91f0179..468b7940ce 100644 --- a/modules/gapi/src/backends/fluid/gfluidcore.cpp +++ b/modules/gapi/src/backends/fluid/gfluidcore.cpp @@ -2675,40 +2675,6 @@ GAPI_FLUID_KERNEL(GFluidSqrt, cv::gapi::core::GSqrt, false) } }; -GAPI_FLUID_KERNEL(GFluidCopy, cv::gapi::core::GCopy, false) -{ - static const int Window = 1; - - static void run(const View &src, Buffer &dst) - { - const auto *in = src.InLine(0); - auto *out = dst.OutLine(); - - GAPI_DbgAssert(dst.length() == src.length()); - GAPI_DbgAssert(dst.meta().chan == src.meta().chan); - GAPI_DbgAssert(dst.meta().depth == src.meta().depth); - - int width = src.length(); - int elem_size = CV_ELEM_SIZE(CV_MAKETYPE(src.meta().depth, src.meta().chan)); - - int w = 0; // cycle counter - - #if CV_SIMD128 - for (; w <= width*elem_size-16; w+=16) - { - v_uint8x16 a; - a = v_load(&in[w]); - v_store(&out[w], a); - } - #endif - - for (; w < width*elem_size; w++) - { - out[w] = in[w]; - } - } -}; - } // namespace fliud } // namespace gapi } // namespace cv @@ -2768,7 +2734,6 @@ cv::gapi::GKernelPackage cv::gapi::core::fluid::kernels() ,GFluidInRange ,GFluidResize ,GFluidSqrt - ,GFluidCopy #if 0 ,GFluidMean -- not fluid ,GFluidSum -- not fluid diff --git a/modules/gapi/src/backends/ocl/goclcore.cpp b/modules/gapi/src/backends/ocl/goclcore.cpp index 61e03340fb..afe211dc7e 100644 --- a/modules/gapi/src/backends/ocl/goclcore.cpp +++ b/modules/gapi/src/backends/ocl/goclcore.cpp @@ -490,14 +490,6 @@ GAPI_OCL_KERNEL(GOCLCrop, cv::gapi::core::GCrop) } }; -GAPI_OCL_KERNEL(GOCLCopy, cv::gapi::core::GCopy) -{ - static void run(const cv::UMat& in, cv::UMat& out) - { - in.copyTo(out); - } -}; - GAPI_OCL_KERNEL(GOCLConcatHor, cv::gapi::core::GConcatHor) { static void run(const cv::UMat& in1, const cv::UMat& in2, cv::UMat& out) @@ -590,7 +582,6 @@ cv::gapi::GKernelPackage cv::gapi::core::ocl::kernels() , GOCLRemap , GOCLFlip , GOCLCrop - , GOCLCopy , GOCLConcatHor , GOCLConcatVert , GOCLLUT diff --git a/modules/gapi/src/backends/streaming/gstreamingbackend.cpp b/modules/gapi/src/backends/streaming/gstreamingbackend.cpp index 5f6dbab356..d11d8b9203 100644 --- a/modules/gapi/src/backends/streaming/gstreamingbackend.cpp +++ b/modules/gapi/src/backends/streaming/gstreamingbackend.cpp @@ -137,7 +137,12 @@ cv::gapi::GBackend cv::gapi::streaming::backend() cv::gapi::GKernelPackage cv::gapi::streaming::kernels() { - return cv::gapi::kernels(); + return cv::gapi::kernels(); +} + +cv::gapi::GKernelPackage cv::gimpl::streaming::kernels() +{ + return cv::gapi::kernels(); } void cv::gimpl::Copy::Actor::run(cv::gimpl::GIslandExecutable::IInput &in, @@ -153,8 +158,21 @@ void cv::gimpl::Copy::Actor::run(cv::gimpl::GIslandExecutable::IInput &in, const cv::GRunArgs &in_args = cv::util::get(in_msg); GAPI_Assert(in_args.size() == 1u); - cv::GRunArgP out_arg = out.get(0); - *cv::util::get(out_arg) = cv::util::get(in_args[0]); + const auto& in_arg = in_args[0]; + auto out_arg = out.get(0); + using cv::util::get; + switch (in_arg.index()) { + case cv::GRunArg::index_of(): + *get(out_arg) = get(in_arg); + break; + case cv::GRunArg::index_of(): + *get(out_arg) = get(in_arg); + break; + // FIXME: Add support for remaining types + default: + GAPI_Assert(false && "Copy: unsupported data type"); + } + out.meta(out_arg, in_arg.meta); out.post(std::move(out_arg)); } @@ -197,3 +215,11 @@ void cv::gimpl::BGR::Actor::run(cv::gimpl::GIslandExecutable::IInput &in, } out.post(std::move(out_arg)); } + +cv::GMat cv::gapi::copy(const cv::GMat& in) { + return cv::gimpl::streaming::GCopy::on(in); +} + +cv::GFrame cv::gapi::copy(const cv::GFrame& in) { + return cv::gimpl::streaming::GCopy::on(in); +} diff --git a/modules/gapi/src/backends/streaming/gstreamingbackend.hpp b/modules/gapi/src/backends/streaming/gstreamingbackend.hpp index 31e8e24555..28b15792b2 100644 --- a/modules/gapi/src/backends/streaming/gstreamingbackend.hpp +++ b/modules/gapi/src/backends/streaming/gstreamingbackend.hpp @@ -12,11 +12,37 @@ #include "gstreamingkernel.hpp" namespace cv { +namespace gapi { +namespace streaming { + +cv::gapi::GBackend backend(); + +}} // namespace gapi::streaming + namespace gimpl { +namespace streaming { + +cv::gapi::GKernelPackage kernels(); + +struct GCopy final : public cv::detail::NoTag +{ + static constexpr const char* id() { return "org.opencv.streaming.copy"; } + + static GMetaArgs getOutMeta(const GMetaArgs &in_meta, const GArgs&) { + GAPI_Assert(in_meta.size() == 1u); + return in_meta; + } + + template static T on(const T& arg) { + return cv::GKernelType>::on(arg); + } +}; + +} // namespace streaming struct Copy: public cv::detail::KernelTag { - using API = cv::gapi::streaming::GCopy; + using API = streaming::GCopy; static gapi::GBackend backend() { return cv::gapi::streaming::backend(); } diff --git a/modules/gapi/src/compiler/gcompiler.cpp b/modules/gapi/src/compiler/gcompiler.cpp index 1f1cbf9dbf..34585e2b3c 100644 --- a/modules/gapi/src/compiler/gcompiler.cpp +++ b/modules/gapi/src/compiler/gcompiler.cpp @@ -36,6 +36,7 @@ #include "executor/gstreamingexecutor.hpp" #include "backends/common/gbackend.hpp" #include "backends/common/gmetabackend.hpp" +#include "backends/streaming/gstreamingbackend.hpp" // #if !defined(GAPI_STANDALONE) @@ -60,8 +61,11 @@ namespace for (const auto &b : pkg.backends()) { aux_pkg = combine(aux_pkg, b.priv().auxiliaryKernels()); } - // Always include built-in meta<> implementation - return combine(pkg, aux_pkg, cv::gimpl::meta::kernels()); + // Always include built-in meta<> and copy implementation + return combine(pkg, + aux_pkg, + cv::gimpl::meta::kernels(), + cv::gimpl::streaming::kernels()); }; auto has_use_only = cv::gapi::getCompileArg(args); diff --git a/modules/gapi/src/compiler/gislandmodel.cpp b/modules/gapi/src/compiler/gislandmodel.cpp index 4d0feaea71..fb2457a191 100644 --- a/modules/gapi/src/compiler/gislandmodel.cpp +++ b/modules/gapi/src/compiler/gislandmodel.cpp @@ -18,7 +18,6 @@ #include "compiler/gmodel.hpp" #include "compiler/gislandmodel.hpp" #include "compiler/gmodel.hpp" -#include "backends/common/gbackend.hpp" // RMatAdapter #include "logger.hpp" // GAPI_LOG @@ -357,22 +356,7 @@ void GIslandExecutable::run(GIslandExecutable::IInput &in, GIslandExecutable::IO for (auto &&it: ade::util::zip(ade::util::toRange(in_desc), ade::util::toRange(in_vector))) { - const cv::GRunArg& in_data_orig = std::get<1>(it); - cv::GRunArg in_data; - switch (in_data_orig.index()) - { - case cv::GRunArg::index_of(): - // FIXME: This whole construct is ugly, from - // its writing to a need in this in general - in_data = cv::GRunArg{ cv::make_rmat(cv::util::get(in_data_orig)) - , in_data_orig.meta - }; - break; - default: - in_data = in_data_orig; - break; - } - in_objs.emplace_back(std::get<0>(it), std::move(in_data)); + in_objs.emplace_back(std::get<0>(it), std::get<1>(it)); } for (auto &&it: ade::util::indexed(ade::util::toRange(out_desc))) { diff --git a/modules/gapi/src/executor/gexecutor.cpp b/modules/gapi/src/executor/gexecutor.cpp index 66f3b24771..2702e47547 100644 --- a/modules/gapi/src/executor/gexecutor.cpp +++ b/modules/gapi/src/executor/gexecutor.cpp @@ -146,16 +146,26 @@ void writeBackExec(const Mag& mag, const RcDesc &rc, GRunArgP &g_arg) writeBack(mag, rc, g_arg); return; } - auto checkOutArgData = [&](const uchar* out_arg_data) { - //simply check that memory was not reallocated, i.e. - //both Mat and View pointing to the same memory - auto mag_data = mag.template slot().at(rc.id).get()->data(); - GAPI_Assert((out_arg_data == mag_data) && " data for output parameters was reallocated ?"); - }; switch (g_arg.index()) { - case GRunArgP::index_of() : checkOutArgData(util::get(g_arg)->data); break; + case GRunArgP::index_of() : { + // If there is a copy intrinsic at the end of the graph + // we need to actualy copy the data to the user buffer + // since output runarg was optimized to simply point + // to the input of the copy kernel + // FIXME: + // Rework, find a better way to check if there should be + // a real copy (add a pass to StreamingBackend?) + auto& out_mat = *util::get(g_arg); + const auto& rmat = mag.template slot().at(rc.id); + auto mag_data = rmat.get()->data(); + if (out_mat.data != mag_data) { + auto view = rmat.access(RMat::Access::R); + asMat(view).copyTo(out_mat); + } + break; + } case GRunArgP::index_of() : /* do nothing */ break; default: util::throw_error(std::logic_error("content type of the runtime argument does not match to resource description ?")); } diff --git a/modules/gapi/src/executor/gstreamingexecutor.cpp b/modules/gapi/src/executor/gstreamingexecutor.cpp index cfb4a527df..ba58cfde60 100644 --- a/modules/gapi/src/executor/gstreamingexecutor.cpp +++ b/modules/gapi/src/executor/gstreamingexecutor.cpp @@ -20,6 +20,7 @@ #include "api/gproto_priv.hpp" // ptr(GRunArgP) #include "compiler/passes/passes.hpp" #include "backends/common/gbackend.hpp" // createMat +#include "backends/streaming/gstreamingbackend.hpp" // GCopy #include "compiler/gcompiler.hpp" // for compileIslands #include "executor/gstreamingexecutor.hpp" @@ -535,6 +536,14 @@ class StreamingInput final: public cv::gimpl::GIslandExecutable::IInput // Stop case return cv::gimpl::StreamMsg{cv::gimpl::EndOfStream{}}; } + // Wrap all input cv::Mats with RMats + for (auto& arg : isl_input_args) { + if (arg.index() == cv::GRunArg::index_of()) { + arg = cv::GRunArg{ cv::make_rmat(cv::util::get(arg)) + , arg.meta + }; + } + } return cv::gimpl::StreamMsg{std::move(isl_input_args)}; } virtual cv::gimpl::StreamMsg try_get() override @@ -1000,7 +1009,7 @@ cv::gimpl::GStreamingExecutor::GStreamingExecutor(std::unique_ptr && GAPI_Assert(GModel::Graph(*m_orig_graph) .metadata(*isl->in_ops().begin()) .get() - .k.name == cv::gapi::core::GCopy::id()); + .k.name == cv::gimpl::streaming::GCopy::id()); #endif // GAPI_STANDALONE for (auto out_nh : nh->outNodes()) { for (auto out_eh : out_nh->outEdges()) { diff --git a/modules/gapi/test/cpu/gapi_core_tests_fluid.cpp b/modules/gapi/test/cpu/gapi_core_tests_fluid.cpp index 8162e01f50..87e447aae6 100644 --- a/modules/gapi/test/cpu/gapi_core_tests_fluid.cpp +++ b/modules/gapi/test/cpu/gapi_core_tests_fluid.cpp @@ -433,12 +433,4 @@ INSTANTIATE_TEST_CASE_P(ReInitOutTestFluid, ReInitOutTest, Values(CORE_FLUID), Values(cv::Size(640, 400), cv::Size(10, 480)))); - -INSTANTIATE_TEST_CASE_P(CopyTestFluid, CopyTest, - Combine(Values( CV_8UC1, CV_8UC3, CV_16UC1, CV_16SC1, CV_32FC1 ), - Values(cv::Size(1280, 720), - cv::Size(640, 480), - cv::Size(128, 128)), - Values(-1), - Values(CORE_FLUID))); } diff --git a/modules/gapi/test/gpu/gapi_core_tests_gpu.cpp b/modules/gapi/test/gpu/gapi_core_tests_gpu.cpp index 1bd076a480..4e5efe6d3f 100644 --- a/modules/gapi/test/gpu/gapi_core_tests_gpu.cpp +++ b/modules/gapi/test/gpu/gapi_core_tests_gpu.cpp @@ -359,14 +359,6 @@ INSTANTIATE_TEST_CASE_P(CropTestGPU, CropTest, Values(CORE_GPU), Values(cv::Rect(10, 8, 20, 35), cv::Rect(4, 10, 37, 50)))); -INSTANTIATE_TEST_CASE_P(CopyTestGPU, CopyTest, - Combine(Values( CV_8UC1, CV_8UC3, CV_16UC1, CV_16SC1, CV_32FC1 ), - Values(cv::Size(1280, 720), - cv::Size(640, 480), - cv::Size(128, 128)), - Values(-1), - Values(CORE_GPU))); - INSTANTIATE_TEST_CASE_P(LUTTestGPU, LUTTest, Combine(Values(CV_8UC1, CV_8UC3), Values(cv::Size(1280, 720), diff --git a/modules/gapi/test/internal/gapi_int_island_fusion_tests.cpp b/modules/gapi/test/internal/gapi_int_island_fusion_tests.cpp index 723e42a6df..073be2381a 100644 --- a/modules/gapi/test/internal/gapi_int_island_fusion_tests.cpp +++ b/modules/gapi/test/internal/gapi_int_island_fusion_tests.cpp @@ -527,6 +527,7 @@ TEST(IslandFusion, Test_Desync_NoFuse) ////////////////////////////////////////////////////////////////// // Compile the graph in "regular" mode, it should produce a single island + // Note: with copy moved to a separate backend there is always 3 islands in this test { using namespace cv::gimpl; @@ -544,11 +545,12 @@ TEST(IslandFusion, Test_Desync_NoFuse) const auto num_isl = std::count_if(gim.nodes().begin(), gim.nodes().end(), is_island); - EXPECT_EQ(1, num_isl); + EXPECT_EQ(3, num_isl); } ////////////////////////////////////////////////////////////////// // Now compile the graph in the streaming mode. // It has to produce two islands + // Note: with copy moved to a separate backend there is always 3 islands in this test { using namespace cv::gimpl; @@ -567,7 +569,7 @@ TEST(IslandFusion, Test_Desync_NoFuse) const auto num_isl = std::count_if(gim.nodes().begin(), gim.nodes().end(), is_island); - EXPECT_EQ(2, num_isl); + EXPECT_EQ(3, num_isl); } } diff --git a/modules/gapi/test/streaming/gapi_streaming_tests.cpp b/modules/gapi/test/streaming/gapi_streaming_tests.cpp index 527f682dfe..b1865aace9 100644 --- a/modules/gapi/test/streaming/gapi_streaming_tests.cpp +++ b/modules/gapi/test/streaming/gapi_streaming_tests.cpp @@ -1645,37 +1645,20 @@ TEST(GAPI_Streaming_Desync, StartStop_Stress) { } } -GAPI_FLUID_KERNEL(FluidCopy, cv::gapi::core::GCopy, false) { - static const int Window = 1; - - static void run(const cv::gapi::fluid::View &in, - cv::gapi::fluid::Buffer &out) { - const uint8_t *in_ptr = in.InLineB(0); - uint8_t *out_ptr = out.OutLineB(0); - - const auto in_type = CV_MAKETYPE(in.meta().depth, in.meta().chan); - const auto out_type = CV_MAKETYPE(out.meta().depth, out.meta().chan); - GAPI_Assert(in_type == out_type); - std::copy_n(in_ptr, in.length()*CV_ELEM_SIZE(in_type), out_ptr); - } -}; - - TEST(GAPI_Streaming_Desync, DesyncObjectConsumedByTwoIslandsViaSeparateDesync) { // See comment in the implementation of cv::gapi::streaming::desync (.cpp) cv::GMat in; cv::GMat tmp = cv::gapi::boxFilter(in, -1, cv::Size(3,3)); cv::GMat tmp1 = cv::gapi::streaming::desync(tmp); - cv::GMat out1 = cv::gapi::copy(tmp1); // ran via Fluid backend + cv::GMat out1 = cv::gapi::copy(tmp1); // ran via Streaming backend cv::GMat tmp2 = cv::gapi::streaming::desync(tmp); cv::GMat out2 = tmp2 * 0.5; // ran via OCV backend auto c = cv::GComputation(cv::GIn(in), cv::GOut(out1, out2)); - auto p = cv::gapi::kernels(); - EXPECT_NO_THROW(c.compileStreaming(cv::compile_args(p))); + EXPECT_NO_THROW(c.compileStreaming()); } TEST(GAPI_Streaming_Desync, DesyncObjectConsumedByTwoIslandsViaSameDesync) { @@ -1684,13 +1667,12 @@ TEST(GAPI_Streaming_Desync, DesyncObjectConsumedByTwoIslandsViaSameDesync) { cv::GMat tmp = cv::gapi::boxFilter(in, -1, cv::Size(3,3)); cv::GMat tmp1 = cv::gapi::streaming::desync(tmp); - cv::GMat out1 = cv::gapi::copy(tmp1); // ran via Fluid backend + cv::GMat out1 = cv::gapi::copy(tmp1); // ran via Streaming backend cv::GMat out2 = out1 - 0.5*tmp1; // ran via OCV backend auto c = cv::GComputation(cv::GIn(in), cv::GOut(out1, out2)); - auto p = cv::gapi::kernels(); - EXPECT_NO_THROW(c.compileStreaming(cv::compile_args(p))); + EXPECT_NO_THROW(c.compileStreaming()); } TEST(GAPI_Streaming, CopyFrame) @@ -1699,7 +1681,7 @@ TEST(GAPI_Streaming, CopyFrame) std::string filepath = findDataFile("cv/video/768x576.avi"); cv::GFrame in; - auto out = cv::gapi::streaming::copy(in); + auto out = cv::gapi::copy(in); cv::GComputation comp(cv::GIn(in), cv::GOut(out)); @@ -1732,13 +1714,50 @@ TEST(GAPI_Streaming, CopyFrame) } } +TEST(GAPI_Streaming, CopyMat) +{ + initTestDataPath(); + std::string filepath = findDataFile("cv/video/768x576.avi"); + + cv::GMat in; + auto out = cv::gapi::copy(in); + + cv::GComputation comp(cv::GIn(in), cv::GOut(out)); + + auto cc = comp.compileStreaming(); + try { + cc.setSource(filepath); + } catch(...) { + throw SkipTestException("Video file can not be opened"); + } + + cv::VideoCapture cap; + cap.open(filepath); + if (!cap.isOpened()) + throw SkipTestException("Video file can not be opened"); + + cv::Mat out_mat; + cv::Mat ocv_mat; + std::size_t num_frames = 0u; + std::size_t max_frames = 10u; + + cc.start(); + while (cc.pull(cv::gout(out_mat)) && num_frames < max_frames) + { + num_frames++; + cap >> ocv_mat; + + EXPECT_EQ(0, cvtest::norm(ocv_mat, out_mat, NORM_INF)); + } +} + TEST(GAPI_Streaming, Reshape) { initTestDataPath(); std::string filepath = findDataFile("cv/video/768x576.avi"); cv::GFrame in; - auto out = cv::gapi::streaming::copy(in); + auto out = cv::gapi::copy(in); cv::GComputation comp(cv::GIn(in), cv::GOut(out));