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
This commit is contained in:
parent
50baf76cc2
commit
f7cab121fe
@ -451,12 +451,6 @@ namespace core {
|
||||
}
|
||||
};
|
||||
|
||||
G_TYPED_KERNEL(GCopy, <GMat(GMat)>, "org.opencv.core.transform.copy") {
|
||||
static GMatDesc outMeta(GMatDesc in) {
|
||||
return in;
|
||||
}
|
||||
};
|
||||
|
||||
G_TYPED_KERNEL(GConcatHor, <GMat(GMat, GMat)>, "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).
|
||||
|
||||
@ -15,26 +15,11 @@ namespace streaming {
|
||||
|
||||
GAPI_EXPORTS cv::gapi::GKernelPackage kernels();
|
||||
|
||||
// FIXME: Make a generic kernel
|
||||
G_API_OP(GCopy, <GFrame(GFrame)>, "org.opencv.streaming.copy")
|
||||
{
|
||||
static GFrameDesc outMeta(const GFrameDesc& in) { return in; }
|
||||
};
|
||||
|
||||
G_API_OP(GBGR, <GMat(GFrame)>, "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
|
||||
|
||||
|
||||
@ -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),
|
||||
|
||||
@ -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 ),
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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<uchar>(0);
|
||||
auto *out = dst.OutLine<uchar>();
|
||||
|
||||
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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -137,7 +137,12 @@ cv::gapi::GBackend cv::gapi::streaming::backend()
|
||||
|
||||
cv::gapi::GKernelPackage cv::gapi::streaming::kernels()
|
||||
{
|
||||
return cv::gapi::kernels<cv::gimpl::Copy, cv::gimpl::BGR>();
|
||||
return cv::gapi::kernels<cv::gimpl::BGR>();
|
||||
}
|
||||
|
||||
cv::gapi::GKernelPackage cv::gimpl::streaming::kernels()
|
||||
{
|
||||
return cv::gapi::kernels<cv::gimpl::Copy>();
|
||||
}
|
||||
|
||||
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<cv::GRunArgs>(in_msg);
|
||||
GAPI_Assert(in_args.size() == 1u);
|
||||
|
||||
cv::GRunArgP out_arg = out.get(0);
|
||||
*cv::util::get<cv::MediaFrame*>(out_arg) = cv::util::get<cv::MediaFrame>(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<cv::RMat>():
|
||||
*get<cv::RMat*>(out_arg) = get<cv::RMat>(in_arg);
|
||||
break;
|
||||
case cv::GRunArg::index_of<cv::MediaFrame>():
|
||||
*get<cv::MediaFrame*>(out_arg) = get<cv::MediaFrame>(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<cv::GMat>(in);
|
||||
}
|
||||
|
||||
cv::GFrame cv::gapi::copy(const cv::GFrame& in) {
|
||||
return cv::gimpl::streaming::GCopy::on<cv::GFrame>(in);
|
||||
}
|
||||
|
||||
@ -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<typename T> static T on(const T& arg) {
|
||||
return cv::GKernelType<GCopy, std::function<T(T)>>::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(); }
|
||||
|
||||
|
||||
@ -36,6 +36,7 @@
|
||||
#include "executor/gstreamingexecutor.hpp"
|
||||
#include "backends/common/gbackend.hpp"
|
||||
#include "backends/common/gmetabackend.hpp"
|
||||
#include "backends/streaming/gstreamingbackend.hpp"
|
||||
|
||||
// <FIXME:>
|
||||
#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<cv::gapi::use_only>(args);
|
||||
|
||||
@ -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<cv::Mat>():
|
||||
// FIXME: This whole construct is ugly, from
|
||||
// its writing to a need in this in general
|
||||
in_data = cv::GRunArg{ cv::make_rmat<cv::gimpl::RMatAdapter>(cv::util::get<cv::Mat>(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)))
|
||||
{
|
||||
|
||||
@ -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<cv::RMat>().at(rc.id).get<RMatAdapter>()->data();
|
||||
GAPI_Assert((out_arg_data == mag_data) && " data for output parameters was reallocated ?");
|
||||
};
|
||||
|
||||
switch (g_arg.index())
|
||||
{
|
||||
case GRunArgP::index_of<cv::Mat*>() : checkOutArgData(util::get<cv::Mat*>(g_arg)->data); break;
|
||||
case GRunArgP::index_of<cv::Mat*>() : {
|
||||
// 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<cv::Mat*>(g_arg);
|
||||
const auto& rmat = mag.template slot<cv::RMat>().at(rc.id);
|
||||
auto mag_data = rmat.get<RMatAdapter>()->data();
|
||||
if (out_mat.data != mag_data) {
|
||||
auto view = rmat.access(RMat::Access::R);
|
||||
asMat(view).copyTo(out_mat);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GRunArgP::index_of<cv::RMat*>() : /* do nothing */ break;
|
||||
default: util::throw_error(std::logic_error("content type of the runtime argument does not match to resource description ?"));
|
||||
}
|
||||
|
||||
@ -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<cv::Mat>()) {
|
||||
arg = cv::GRunArg{ cv::make_rmat<cv::gimpl::RMatAdapter>(cv::util::get<cv::Mat>(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<ade::Graph> &&
|
||||
GAPI_Assert(GModel::Graph(*m_orig_graph)
|
||||
.metadata(*isl->in_ops().begin())
|
||||
.get<cv::gimpl::Op>()
|
||||
.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()) {
|
||||
|
||||
@ -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)));
|
||||
}
|
||||
|
||||
@ -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),
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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<FluidCopy>();
|
||||
|
||||
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<FluidCopy>();
|
||||
|
||||
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<cv::gapi::wip::GCaptureSource>(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));
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user