Path: blob/master/modules/gapi/test/common/gapi_compoundkernel_tests.cpp
16354 views
// This file is part of OpenCV project.1// It is subject to the license terms in the LICENSE file found in the top-level directory2// of this distribution and at http://opencv.org/license.html.3//4// Copyright (C) 2018 Intel Corporation567// FIXME: move out from Common89#include "test_precomp.hpp"10#include "opencv2/gapi/cpu/core.hpp"1112#include <ade/util/algorithm.hpp>1314namespace opencv_test15{16namespace17{18G_TYPED_KERNEL(GCompoundDoubleAddC, <GMat(GMat, GScalar)>, "org.opencv.test.compound_double_addC")19{20static GMatDesc outMeta(GMatDesc in, GScalarDesc) { return in; }21};2223GAPI_COMPOUND_KERNEL(GCompoundDoubleAddCImpl, GCompoundDoubleAddC)24{25static GMat expand(cv::GMat in, cv::GScalar s)26{27return cv::gapi::addC(cv::gapi::addC(in, s), s);28}29};3031G_TYPED_KERNEL(GCompoundAddC, <GMat(GMat, GScalar)>, "org.opencv.test.compound_addC")32{33static GMatDesc outMeta(GMatDesc in, GScalarDesc) { return in; }34};3536GAPI_COMPOUND_KERNEL(GCompoundAddCImpl, GCompoundAddC)37{38static GMat expand(cv::GMat in, cv::GScalar s)39{40return cv::gapi::addC(in, s);41}42};4344using GMat3 = std::tuple<GMat,GMat,GMat>;45using GMat2 = std::tuple<GMat,GMat>;4647G_TYPED_KERNEL_M(GCompoundMergeWithSplit, <GMat3(GMat, GMat, GMat)>, "org.opencv.test.compound_merge_split")48{49static std::tuple<GMatDesc,GMatDesc,GMatDesc> outMeta(GMatDesc a, GMatDesc b, GMatDesc c)50{51return std::make_tuple(a, b, c);52}53};5455GAPI_COMPOUND_KERNEL(GCompoundMergeWithSplitImpl, GCompoundMergeWithSplit)56{57static GMat3 expand(cv::GMat a, cv::GMat b, cv::GMat c)58{59return cv::gapi::split3(cv::gapi::merge3(a, b, c));60}61};6263G_TYPED_KERNEL(GCompoundAddWithAddC, <GMat(GMat, GMat, GScalar)>, "org.opencv.test.compound_add_with_addc")64{65static GMatDesc outMeta(GMatDesc in, GMatDesc, GScalarDesc)66{67return in;68}69};7071GAPI_COMPOUND_KERNEL(GCompoundAddWithAddCImpl, GCompoundAddWithAddC)72{73static GMat expand(cv::GMat in1, cv::GMat in2, cv::GScalar s)74{75return cv::gapi::addC(cv::gapi::add(in1, in2), s);76}77};7879G_TYPED_KERNEL_M(GCompoundSplitWithAdd, <GMat2(GMat)>, "org.opencv.test.compound_split_with_add")80{81static std::tuple<GMatDesc, GMatDesc> outMeta(GMatDesc in)82{83const auto out_depth = in.depth;84const auto out_desc = in.withType(out_depth, 1);85return std::make_tuple(out_desc, out_desc);86}87};8889GAPI_COMPOUND_KERNEL(GCompoundSplitWithAddImpl, GCompoundSplitWithAdd)90{91static GMat2 expand(cv::GMat in)92{93cv::GMat a, b, c;94std::tie(a, b, c) = cv::gapi::split3(in);95return std::make_tuple(cv::gapi::add(a, b), c);96}97};9899G_TYPED_KERNEL_M(GCompoundParallelAddC, <GMat2(GMat, GScalar)>, "org.opencv.test.compound_parallel_addc")100{101static std::tuple<GMatDesc, GMatDesc> outMeta(GMatDesc in, GScalarDesc)102{103return std::make_tuple(in, in);104}105};106107GAPI_COMPOUND_KERNEL(GCompoundParallelAddCImpl, GCompoundParallelAddC)108{109static GMat2 expand(cv::GMat in, cv::GScalar s)110{111return std::make_tuple(cv::gapi::addC(in, s), cv::gapi::addC(in, s));112}113};114115GAPI_COMPOUND_KERNEL(GCompoundAddImpl, cv::gapi::core::GAdd)116{117static GMat expand(cv::GMat in1, cv::GMat in2, int)118{119return cv::gapi::sub(cv::gapi::sub(in1, in2), in2);120}121};122123G_TYPED_KERNEL(GCompoundAddWithAddCWithDoubleAddC, <GMat(GMat, GMat, GScalar)>, "org.opencv.test.compound_add_with_addC_with_double_addC")124{125static GMatDesc outMeta(GMatDesc in, GMatDesc, GScalarDesc)126{127return in;128}129};130131GAPI_COMPOUND_KERNEL(GCompoundAddWithAddCWithDoubleAddCImpl, GCompoundAddWithAddCWithDoubleAddC)132{133static GMat expand(cv::GMat in1, cv::GMat in2, cv::GScalar s)134{135return GCompoundDoubleAddC::on(GCompoundAddWithAddC::on(in1, in2, s), s);136}137};138139using GDoubleArray = cv::GArray<double>;140G_TYPED_KERNEL(GNegateArray, <GDoubleArray(GDoubleArray)>, "org.opencv.test.negate_array")141{142static GArrayDesc outMeta(const GArrayDesc&) { return empty_array_desc(); }143};144145GAPI_OCV_KERNEL(GNegateArrayImpl, GNegateArray)146{147static void run(const std::vector<double>& in, std::vector<double>& out)148{149ade::util::transform(in, std::back_inserter(out), std::negate<double>());150}151};152153G_TYPED_KERNEL(GMaxInArray, <GScalar(GDoubleArray)>, "org.opencv.test.max_in_array")154{155static GScalarDesc outMeta(const GArrayDesc&) { return empty_scalar_desc(); }156};157158GAPI_OCV_KERNEL(GMaxInArrayImpl, GMaxInArray)159{160static void run(const std::vector<double>& in, cv::Scalar& out)161{162out = *std::max_element(in.begin(), in.end());163}164};165166G_TYPED_KERNEL(GCompoundMaxInArray, <GScalar(GDoubleArray)>, "org.opencv.test.compound_max_in_array")167{168static GScalarDesc outMeta(const GArrayDesc&) { return empty_scalar_desc(); }169};170171GAPI_COMPOUND_KERNEL(GCompoundMaxInArrayImpl, GCompoundMaxInArray)172{173static GScalar expand(GDoubleArray in)174{175return GMaxInArray::on(in);176}177};178179G_TYPED_KERNEL(GCompoundNegateArray, <GDoubleArray(GDoubleArray)>, "org.opencv.test.compound_negate_array")180{181static GArrayDesc outMeta(const GArrayDesc&) { return empty_array_desc(); }182};183184GAPI_COMPOUND_KERNEL(GCompoundNegateArrayImpl, GCompoundNegateArray)185{186static GDoubleArray expand(GDoubleArray in)187{188return GNegateArray::on(in);189}190};191192G_TYPED_KERNEL(SetDiagKernel, <GMat(GMat, GDoubleArray)>, "org.opencv.test.empty_kernel")193{194static GMatDesc outMeta(GMatDesc in, GArrayDesc) { return in; }195};196197void setDiag(cv::Mat& in, const std::vector<double>& diag)198{199GAPI_Assert(in.rows == static_cast<int>(diag.size()));200GAPI_Assert(in.cols == static_cast<int>(diag.size()));201for (int i = 0; i < in.rows; ++i)202{203in.at<uchar>(i, i) = static_cast<uchar>(diag[i]);204}205}206207GAPI_OCV_KERNEL(SetDiagKernelImpl, SetDiagKernel)208{209static void run(const cv::Mat& in, const std::vector<double>& v, cv::Mat& out)210{211in.copyTo(out);212setDiag(out, v);213}214};215216G_TYPED_KERNEL(GCompoundGMatGArrayGMat, <GMat(GMat, GDoubleArray, GMat)>, "org.opencv.test.compound_gmat_garray_gmat")217{218static GMatDesc outMeta(GMatDesc in, GArrayDesc, GMatDesc) { return in; }219};220221GAPI_COMPOUND_KERNEL(GCompoundGMatGArrayGMatImpl, GCompoundGMatGArrayGMat)222{223static GMat expand(GMat a, GDoubleArray b, GMat c)224{225return SetDiagKernel::on(cv::gapi::add(a, c), b);226}227};228229} // namespace230231// FIXME avoid cv::combine that use custom and default kernels together232TEST(GCompoundKernel, ReplaceDefaultKernel)233{234cv::GMat in1, in2;235auto out = cv::gapi::add(in1, in2);236const auto custom_pkg = cv::gapi::kernels<GCompoundAddImpl>();237const auto full_pkg = cv::gapi::combine(cv::gapi::core::cpu::kernels(), custom_pkg, cv::unite_policy::REPLACE);238cv::GComputation comp(cv::GIn(in1, in2), cv::GOut(out));239cv::Mat in_mat1 = cv::Mat::eye(3, 3, CV_8UC1),240in_mat2 = cv::Mat::eye(3, 3, CV_8UC1),241out_mat(3, 3, CV_8UC1),242ref_mat(3, 3, CV_8UC1);243244comp.apply(cv::gin(in_mat1, in_mat2), cv::gout(out_mat), cv::compile_args(full_pkg));245ref_mat = in_mat1 - in_mat2 - in_mat2;246247EXPECT_EQ(0, cv::countNonZero(out_mat != ref_mat));248}249250TEST(GCompoundKernel, DoubleAddC)251{252cv::GMat in1, in2;253cv::GScalar s;254auto add_res = cv::gapi::add(in1, in2);255auto super = GCompoundDoubleAddC::on(add_res, s);256auto out = cv::gapi::addC(super, s);257258const auto custom_pkg = cv::gapi::kernels<GCompoundDoubleAddCImpl>();259const auto full_pkg = cv::gapi::combine(custom_pkg, cv::gapi::core::cpu::kernels(), cv::unite_policy::KEEP);260cv::GComputation comp(cv::GIn(in1, in2, s), cv::GOut(out));261262cv::Mat in_mat1 = cv::Mat::eye(3, 3, CV_8UC1),263in_mat2 = cv::Mat::eye(3, 3, CV_8UC1),264out_mat(3, 3, CV_8UC1),265ref_mat(3, 3, CV_8UC1);266267cv::Scalar scalar = 2;268269comp.apply(cv::gin(in_mat1, in_mat2, scalar), cv::gout(out_mat), cv::compile_args(full_pkg));270ref_mat = in_mat1 + in_mat2 + scalar + scalar + scalar;271272EXPECT_EQ(0, cv::countNonZero(out_mat != ref_mat));273}274275TEST(GCompoundKernel, AddC)276{277cv::GMat in1, in2;278cv::GScalar s;279auto add_res = cv::gapi::add(in1, in2);280auto super = GCompoundAddC::on(add_res, s);281auto out = cv::gapi::addC(super, s);282283const auto custom_pkg = cv::gapi::kernels<GCompoundAddCImpl>();284const auto full_pkg = cv::gapi::combine(custom_pkg, cv::gapi::core::cpu::kernels(), cv::unite_policy::KEEP);285cv::GComputation comp(cv::GIn(in1, in2, s), cv::GOut(out));286287cv::Mat in_mat1 = cv::Mat::eye(3, 3, CV_8UC1),288in_mat2 = cv::Mat::eye(3, 3, CV_8UC1),289out_mat(3, 3, CV_8UC1),290ref_mat(3, 3, CV_8UC1);291292cv::Scalar scalar = 2;293294comp.apply(cv::gin(in_mat1, in_mat2, scalar), cv::gout(out_mat), cv::compile_args(full_pkg));295ref_mat = in_mat1 + in_mat2 + scalar + scalar;296297EXPECT_EQ(0, cv::countNonZero(out_mat != ref_mat));298}299300TEST(GCompoundKernel, MergeWithSplit)301{302cv::GMat in, a1, b1, c1,303a2, b2, c2;304305std::tie(a1, b1, c1) = cv::gapi::split3(in);306std::tie(a2, b2, c2) = GCompoundMergeWithSplit::on(a1, b1, c1);307auto out = cv::gapi::merge3(a2, b2, c2);308309const auto custom_pkg = cv::gapi::kernels<GCompoundMergeWithSplitImpl>();310const auto full_pkg = cv::gapi::combine(custom_pkg, cv::gapi::core::cpu::kernels(), cv::unite_policy::KEEP);311cv::GComputation comp(cv::GIn(in), cv::GOut(out));312313cv::Mat in_mat = cv::Mat::eye(3, 3, CV_8UC3), out_mat, ref_mat;314comp.apply(cv::gin(in_mat), cv::gout(out_mat), cv::compile_args(full_pkg));315ref_mat = in_mat;316317EXPECT_EQ(0, cv::countNonZero(out_mat != ref_mat));318}319320TEST(GCompoundKernel, AddWithAddC)321{322cv::GMat in1, in2;323cv::GScalar s;324auto out = GCompoundAddWithAddC::on(in1, in2, s);325326const auto custom_pkg = cv::gapi::kernels<GCompoundAddWithAddCImpl>();327const auto full_pkg = cv::gapi::combine(custom_pkg, cv::gapi::core::cpu::kernels(), cv::unite_policy::KEEP);328cv::GComputation comp(cv::GIn(in1, in2, s), cv::GOut(out));329330cv::Mat in_mat1 = cv::Mat::eye(3, 3, CV_8UC1),331in_mat2 = cv::Mat::eye(3, 3, CV_8UC1),332out_mat(3, 3, CV_8UC1),333ref_mat(3, 3, CV_8UC1);334335cv::Scalar scalar = 2;336337comp.apply(cv::gin(in_mat1, in_mat2, scalar), cv::gout(out_mat), cv::compile_args(full_pkg));338ref_mat = in_mat1 + in_mat2 + scalar;339340EXPECT_EQ(0, cv::countNonZero(out_mat != ref_mat));341}342343TEST(GCompoundKernel, SplitWithAdd)344{345cv::GMat in, out1, out2;346std::tie(out1, out2) = GCompoundSplitWithAdd::on(in);347348const auto custom_pkg = cv::gapi::kernels<GCompoundSplitWithAddImpl>();349const auto full_pkg = cv::gapi::combine(custom_pkg, cv::gapi::core::cpu::kernels(), cv::unite_policy::KEEP);350cv::GComputation comp(cv::GIn(in), cv::GOut(out1, out2));351352cv::Mat in_mat = cv::Mat::eye(3, 3, CV_8UC3),353out_mat1(3, 3, CV_8UC1),354out_mat2(3, 3, CV_8UC1),355ref_mat1(3, 3, CV_8UC1),356ref_mat2(3, 3, CV_8UC1);357358comp.apply(cv::gin(in_mat), cv::gout(out_mat1, out_mat2), cv::compile_args(full_pkg));359360std::vector<cv::Mat> channels(3);361cv::split(in_mat, channels);362363ref_mat1 = channels[0] + channels[1];364ref_mat2 = channels[2];365366EXPECT_EQ(0, cv::countNonZero(out_mat1 != ref_mat1));367EXPECT_EQ(0, cv::countNonZero(out_mat2 != ref_mat2));368}369370TEST(GCompoundKernel, ParallelAddC)371{372cv::GMat in1, out1, out2;373cv::GScalar in2;374std::tie(out1, out2) = GCompoundParallelAddC::on(in1, in2);375376const auto custom_pkg = cv::gapi::kernels<GCompoundParallelAddCImpl>();377const auto full_pkg = cv::gapi::combine(custom_pkg, cv::gapi::core::cpu::kernels(), cv::unite_policy::KEEP);378cv::GComputation comp(cv::GIn(in1, in2), cv::GOut(out1, out2));379380cv::Mat in_mat = cv::Mat::eye(3, 3, CV_8UC1),381out_mat1(3, 3, CV_8UC1),382out_mat2(3, 3, CV_8UC1),383ref_mat1(3, 3, CV_8UC1),384ref_mat2(3, 3, CV_8UC1);385386cv::Scalar scalar = 2;387388comp.apply(cv::gin(in_mat, scalar), cv::gout(out_mat1, out_mat2), cv::compile_args(full_pkg));389390ref_mat1 = in_mat + scalar;391ref_mat2 = in_mat + scalar;392393EXPECT_EQ(0, cv::countNonZero(out_mat1 != ref_mat1));394EXPECT_EQ(0, cv::countNonZero(out_mat2 != ref_mat2));395}396397TEST(GCompoundKernel, GCompundKernelAndDefaultUseOneData)398{399cv::GMat in1, in2;400cv::GScalar s;401auto out = cv::gapi::add(GCompoundAddWithAddC::on(in1, in2, s), cv::gapi::addC(in2, s));402403const auto custom_pkg = cv::gapi::kernels<GCompoundAddWithAddCImpl>();404const auto full_pkg = cv::gapi::combine(custom_pkg, cv::gapi::core::cpu::kernels(), cv::unite_policy::KEEP);405cv::GComputation comp(cv::GIn(in1, in2, s), cv::GOut(out));406407cv::Mat in_mat1 = cv::Mat::eye(3, 3, CV_8UC1),408in_mat2 = cv::Mat::eye(3, 3, CV_8UC1),409out_mat(3, 3, CV_8UC1),410ref_mat(3, 3, CV_8UC1);411412cv::Scalar scalar = 2;413414comp.apply(cv::gin(in_mat1, in_mat2, scalar), cv::gout(out_mat), cv::compile_args(full_pkg));415ref_mat = in_mat1 + in_mat2 + scalar + in_mat2 + scalar;416417EXPECT_EQ(0, cv::countNonZero(out_mat != ref_mat));418}419420TEST(GCompoundKernel, CompoundExpandedToCompound)421{422cv::GMat in1, in2;423cv::GScalar s;424auto out = GCompoundAddWithAddCWithDoubleAddC::on(in1, in2, s);425426const auto custom_pkg = cv::gapi::kernels<GCompoundAddWithAddCWithDoubleAddCImpl,427GCompoundAddWithAddCImpl,428GCompoundDoubleAddCImpl>();429430const auto full_pkg = cv::gapi::combine(custom_pkg, cv::gapi::core::cpu::kernels(), cv::unite_policy::KEEP);431cv::GComputation comp(cv::GIn(in1, in2, s), cv::GOut(out));432433cv::Mat in_mat1 = cv::Mat::eye(3, 3, CV_8UC1),434in_mat2 = cv::Mat::eye(3, 3, CV_8UC1),435out_mat(3, 3, CV_8UC1),436ref_mat(3, 3, CV_8UC1);437438cv::Scalar scalar = 2;439440comp.apply(cv::gin(in_mat1, in_mat2, scalar), cv::gout(out_mat), cv::compile_args(full_pkg));441ref_mat = in_mat1 + in_mat2 + scalar + scalar + scalar;442443EXPECT_EQ(0, cv::countNonZero(out_mat != ref_mat));444}445446TEST(GCompoundKernel, MaxInArray)447{448GDoubleArray in;449auto out = GCompoundMaxInArray::on(in);450const auto custom_pkg = cv::gapi::kernels<GCompoundMaxInArrayImpl, GMaxInArrayImpl>();451const auto full_pkg = cv::gapi::combine(custom_pkg, cv::gapi::core::cpu::kernels(), cv::unite_policy::KEEP);452cv::GComputation comp(cv::GIn(in), cv::GOut(out));453std::vector<double> v = { 1, 5, -2, 3, 10, 2};454cv::Scalar out_scl;455cv::Scalar ref_scl(*std::max_element(v.begin(), v.end()));456457comp.apply(cv::gin(v), cv::gout(out_scl), cv::compile_args(full_pkg));458459EXPECT_EQ(out_scl, ref_scl);460}461462TEST(GCompoundKernel, NegateArray)463{464GDoubleArray in;465GDoubleArray out = GCompoundNegateArray::on(in);466const auto custom_pkg = cv::gapi::kernels<GCompoundNegateArrayImpl, GNegateArrayImpl>();467const auto full_pkg = cv::gapi::combine(custom_pkg, cv::gapi::core::cpu::kernels(), cv::unite_policy::KEEP);468cv::GComputation comp(cv::GIn(in), cv::GOut(out));469std::vector<double> in_v = {1, 5, -2, -10, 3};470std::vector<double> out_v;471std::vector<double> ref_v;472ade::util::transform(in_v, std::back_inserter(ref_v), std::negate<double>());473474comp.apply(cv::gin(in_v), cv::gout(out_v), cv::compile_args(full_pkg));475476EXPECT_EQ(out_v, ref_v);477}478479TEST(GCompoundKernel, RightGArrayHandle)480{481cv::GMat in[2];482GDoubleArray a;483cv::GMat out = GCompoundGMatGArrayGMat::on(in[0], a, in[1]);484const auto custom_pkg = cv::gapi::kernels<GCompoundGMatGArrayGMatImpl, SetDiagKernelImpl>();485const auto full_pkg = cv::gapi::combine(custom_pkg, cv::gapi::core::cpu::kernels(), cv::unite_policy::KEEP);486cv::GComputation comp(cv::GIn(in[0], a, in[1]), cv::GOut(out));487std::vector<double> in_v(3, 1.0);488cv::Mat in_mat1 = cv::Mat::eye(cv::Size(3, 3), CV_8UC1),489in_mat2 = cv::Mat::eye(cv::Size(3, 3), CV_8UC1),490out_mat;491cv::Mat ref_mat= in_mat1 + in_mat2;492setDiag(ref_mat, in_v);493494comp.apply(cv::gin(in_mat1, in_v, in_mat2), cv::gout(out_mat), cv::compile_args(full_pkg));495496EXPECT_EQ(0, cv::countNonZero(out_mat != ref_mat));497498}499} // opencv_test500501502