// 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) 2018 Intel Corporation // FIXME: move out from Common #include "../test_precomp.hpp" #include #include namespace opencv_test { namespace { G_TYPED_KERNEL(GCompoundDoubleAddC, , "org.opencv.test.compound_double_addC") { static GMatDesc outMeta(GMatDesc in, GScalarDesc) { return in; } }; GAPI_COMPOUND_KERNEL(GCompoundDoubleAddCImpl, GCompoundDoubleAddC) { static GMat expand(cv::GMat in, cv::GScalar s) { return cv::gapi::addC(cv::gapi::addC(in, s), s); } }; G_TYPED_KERNEL(GCompoundAddC, , "org.opencv.test.compound_addC") { static GMatDesc outMeta(GMatDesc in, GScalarDesc) { return in; } }; GAPI_COMPOUND_KERNEL(GCompoundAddCImpl, GCompoundAddC) { static GMat expand(cv::GMat in, cv::GScalar s) { return cv::gapi::addC(in, s); } }; using GMat3 = std::tuple; using GMat2 = std::tuple; G_TYPED_KERNEL_M(GCompoundMergeWithSplit, , "org.opencv.test.compound_merge_split") { static std::tuple outMeta(GMatDesc a, GMatDesc b, GMatDesc c) { return std::make_tuple(a, b, c); } }; GAPI_COMPOUND_KERNEL(GCompoundMergeWithSplitImpl, GCompoundMergeWithSplit) { static GMat3 expand(cv::GMat a, cv::GMat b, cv::GMat c) { return cv::gapi::split3(cv::gapi::merge3(a, b, c)); } }; G_TYPED_KERNEL(GCompoundAddWithAddC, , "org.opencv.test.compound_add_with_addc") { static GMatDesc outMeta(GMatDesc in, GMatDesc, GScalarDesc) { return in; } }; GAPI_COMPOUND_KERNEL(GCompoundAddWithAddCImpl, GCompoundAddWithAddC) { static GMat expand(cv::GMat in1, cv::GMat in2, cv::GScalar s) { return cv::gapi::addC(cv::gapi::add(in1, in2), s); } }; G_TYPED_KERNEL_M(GCompoundSplitWithAdd, , "org.opencv.test.compound_split_with_add") { static std::tuple outMeta(GMatDesc in) { const auto out_depth = in.depth; const auto out_desc = in.withType(out_depth, 1); return std::make_tuple(out_desc, out_desc); } }; GAPI_COMPOUND_KERNEL(GCompoundSplitWithAddImpl, GCompoundSplitWithAdd) { static GMat2 expand(cv::GMat in) { cv::GMat a, b, c; std::tie(a, b, c) = cv::gapi::split3(in); return std::make_tuple(cv::gapi::add(a, b), c); } }; G_TYPED_KERNEL_M(GCompoundParallelAddC, , "org.opencv.test.compound_parallel_addc") { static std::tuple outMeta(GMatDesc in, GScalarDesc) { return std::make_tuple(in, in); } }; GAPI_COMPOUND_KERNEL(GCompoundParallelAddCImpl, GCompoundParallelAddC) { static GMat2 expand(cv::GMat in, cv::GScalar s) { return std::make_tuple(cv::gapi::addC(in, s), cv::gapi::addC(in, s)); } }; GAPI_COMPOUND_KERNEL(GCompoundAddImpl, cv::gapi::core::GAdd) { static GMat expand(cv::GMat in1, cv::GMat in2, int) { return cv::gapi::sub(cv::gapi::sub(in1, in2), in2); } }; G_TYPED_KERNEL(GCompoundAddWithAddCWithDoubleAddC, , "org.opencv.test.compound_add_with_addC_with_double_addC") { static GMatDesc outMeta(GMatDesc in, GMatDesc, GScalarDesc) { return in; } }; GAPI_COMPOUND_KERNEL(GCompoundAddWithAddCWithDoubleAddCImpl, GCompoundAddWithAddCWithDoubleAddC) { static GMat expand(cv::GMat in1, cv::GMat in2, cv::GScalar s) { return GCompoundDoubleAddC::on(GCompoundAddWithAddC::on(in1, in2, s), s); } }; using GDoubleArray = cv::GArray; G_TYPED_KERNEL(GNegateArray, , "org.opencv.test.negate_array") { static GArrayDesc outMeta(const GArrayDesc&) { return empty_array_desc(); } }; GAPI_OCV_KERNEL(GNegateArrayImpl, GNegateArray) { static void run(const std::vector& in, std::vector& out) { ade::util::transform(in, std::back_inserter(out), std::negate()); } }; G_TYPED_KERNEL(GMaxInArray, , "org.opencv.test.max_in_array") { static GScalarDesc outMeta(const GArrayDesc&) { return empty_scalar_desc(); } }; GAPI_OCV_KERNEL(GMaxInArrayImpl, GMaxInArray) { static void run(const std::vector& in, cv::Scalar& out) { out = *std::max_element(in.begin(), in.end()); } }; G_TYPED_KERNEL(GCompoundMaxInArray, , "org.opencv.test.compound_max_in_array") { static GScalarDesc outMeta(const GArrayDesc&) { return empty_scalar_desc(); } }; GAPI_COMPOUND_KERNEL(GCompoundMaxInArrayImpl, GCompoundMaxInArray) { static GScalar expand(GDoubleArray in) { return GMaxInArray::on(in); } }; G_TYPED_KERNEL(GCompoundNegateArray, , "org.opencv.test.compound_negate_array") { static GArrayDesc outMeta(const GArrayDesc&) { return empty_array_desc(); } }; GAPI_COMPOUND_KERNEL(GCompoundNegateArrayImpl, GCompoundNegateArray) { static GDoubleArray expand(GDoubleArray in) { return GNegateArray::on(in); } }; G_TYPED_KERNEL(SetDiagKernel, , "org.opencv.test.empty_kernel") { static GMatDesc outMeta(GMatDesc in, GArrayDesc) { return in; } }; void setDiag(cv::Mat& in, const std::vector& diag) { GAPI_Assert(in.rows == static_cast(diag.size())); GAPI_Assert(in.cols == static_cast(diag.size())); for (int i = 0; i < in.rows; ++i) { in.at(i, i) = static_cast(diag[i]); } } GAPI_OCV_KERNEL(SetDiagKernelImpl, SetDiagKernel) { static void run(const cv::Mat& in, const std::vector& v, cv::Mat& out) { in.copyTo(out); setDiag(out, v); } }; G_TYPED_KERNEL(GCompoundGMatGArrayGMat, , "org.opencv.test.compound_gmat_garray_gmat") { static GMatDesc outMeta(GMatDesc in, GArrayDesc, GMatDesc) { return in; } }; GAPI_COMPOUND_KERNEL(GCompoundGMatGArrayGMatImpl, GCompoundGMatGArrayGMat) { static GMat expand(GMat a, GDoubleArray b, GMat c) { return SetDiagKernel::on(cv::gapi::add(a, c), b); } }; G_TYPED_KERNEL(GToInterleaved, , "org.opencv.test.to_interleaved") { static GMatDesc outMeta(GMatDesc in) { GAPI_Assert(in.planar == true); GAPI_Assert(in.chan == 3); return in.asInterleaved(); } }; G_TYPED_KERNEL(GToPlanar, , "org.opencv.test.to_planar") { static GMatDesc outMeta(GMatDesc in) { GAPI_Assert(in.planar == false); GAPI_Assert(in.chan == 3); return in.asPlanar(); } }; GAPI_OCV_KERNEL(GToInterleavedImpl, GToInterleaved) { static void run(const cv::Mat& in, cv::Mat& out) { constexpr int inPlanesCount = 3; int inPlaneHeight = in.rows / inPlanesCount; std::vector inPlanes(inPlanesCount); for (int i = 0; i < inPlanesCount; ++i) { int startRow = i * inPlaneHeight; int endRow = startRow + inPlaneHeight; inPlanes[i] = in.rowRange(startRow, endRow); } cv::merge(inPlanes, out); } }; GAPI_OCV_KERNEL(GToPlanarImpl, GToPlanar) { static void run(const cv::Mat& in, cv::Mat& out) { std::vector inPlanes; cv::split(in, inPlanes); cv::vconcat(inPlanes, out); } }; G_TYPED_KERNEL(GCompoundToInterleavedToPlanar, , "org.opencv.test.compound_to_interleaved_to_planar") { static GMatDesc outMeta(GMatDesc in) { GAPI_Assert(in.planar == true); GAPI_Assert(in.chan == 3); return in; } }; GAPI_COMPOUND_KERNEL(GCompoundToInterleavedToPlanarImpl, GCompoundToInterleavedToPlanar) { static GMatP expand(cv::GMatP in) { return GToPlanar::on(GToInterleaved::on(in)); } }; } // namespace // FIXME avoid cv::combine that use custom and default kernels together TEST(GCompoundKernel, ReplaceDefaultKernel) { cv::GMat in1, in2; auto out = cv::gapi::add(in1, in2); const auto custom_pkg = cv::gapi::kernels(); const auto full_pkg = cv::gapi::combine(cv::gapi::core::cpu::kernels(), custom_pkg); cv::GComputation comp(cv::GIn(in1, in2), cv::GOut(out)); cv::Mat in_mat1 = cv::Mat::eye(3, 3, CV_8UC1), in_mat2 = cv::Mat::eye(3, 3, CV_8UC1), out_mat(3, 3, CV_8UC1), ref_mat(3, 3, CV_8UC1); comp.apply(cv::gin(in_mat1, in_mat2), cv::gout(out_mat), cv::compile_args(full_pkg)); ref_mat = in_mat1 - in_mat2 - in_mat2; EXPECT_EQ(0, cvtest::norm(out_mat, ref_mat, NORM_INF)); } TEST(GCompoundKernel, DoubleAddC) { cv::GMat in1, in2; cv::GScalar s; auto add_res = cv::gapi::add(in1, in2); auto super = GCompoundDoubleAddC::on(add_res, s); auto out = cv::gapi::addC(super, s); const auto custom_pkg = cv::gapi::kernels(); const auto full_pkg = cv::gapi::combine(custom_pkg, cv::gapi::core::cpu::kernels()); cv::GComputation comp(cv::GIn(in1, in2, s), cv::GOut(out)); cv::Mat in_mat1 = cv::Mat::eye(3, 3, CV_8UC1), in_mat2 = cv::Mat::eye(3, 3, CV_8UC1), out_mat(3, 3, CV_8UC1), ref_mat(3, 3, CV_8UC1); cv::Scalar scalar = 2; comp.apply(cv::gin(in_mat1, in_mat2, scalar), cv::gout(out_mat), cv::compile_args(full_pkg)); ref_mat = in_mat1 + in_mat2 + scalar + scalar + scalar; EXPECT_EQ(0, cvtest::norm(out_mat, ref_mat, NORM_INF)); } TEST(GCompoundKernel, AddC) { cv::GMat in1, in2; cv::GScalar s; auto add_res = cv::gapi::add(in1, in2); auto super = GCompoundAddC::on(add_res, s); auto out = cv::gapi::addC(super, s); const auto custom_pkg = cv::gapi::kernels(); const auto full_pkg = cv::gapi::combine(custom_pkg, cv::gapi::core::cpu::kernels()); cv::GComputation comp(cv::GIn(in1, in2, s), cv::GOut(out)); cv::Mat in_mat1 = cv::Mat::eye(3, 3, CV_8UC1), in_mat2 = cv::Mat::eye(3, 3, CV_8UC1), out_mat(3, 3, CV_8UC1), ref_mat(3, 3, CV_8UC1); cv::Scalar scalar = 2; comp.apply(cv::gin(in_mat1, in_mat2, scalar), cv::gout(out_mat), cv::compile_args(full_pkg)); ref_mat = in_mat1 + in_mat2 + scalar + scalar; EXPECT_EQ(0, cvtest::norm(out_mat, ref_mat, NORM_INF)); } TEST(GCompoundKernel, MergeWithSplit) { cv::GMat in, a1, b1, c1, a2, b2, c2; std::tie(a1, b1, c1) = cv::gapi::split3(in); std::tie(a2, b2, c2) = GCompoundMergeWithSplit::on(a1, b1, c1); auto out = cv::gapi::merge3(a2, b2, c2); const auto custom_pkg = cv::gapi::kernels(); const auto full_pkg = cv::gapi::combine(custom_pkg, cv::gapi::core::cpu::kernels()); cv::GComputation comp(cv::GIn(in), cv::GOut(out)); cv::Mat in_mat = cv::Mat::eye(3, 3, CV_8UC3), out_mat, ref_mat; comp.apply(cv::gin(in_mat), cv::gout(out_mat), cv::compile_args(full_pkg)); ref_mat = in_mat; EXPECT_EQ(0, cvtest::norm(out_mat, ref_mat, NORM_INF)); } TEST(GCompoundKernel, AddWithAddC) { cv::GMat in1, in2; cv::GScalar s; auto out = GCompoundAddWithAddC::on(in1, in2, s); const auto custom_pkg = cv::gapi::kernels(); const auto full_pkg = cv::gapi::combine(custom_pkg, cv::gapi::core::cpu::kernels()); cv::GComputation comp(cv::GIn(in1, in2, s), cv::GOut(out)); cv::Mat in_mat1 = cv::Mat::eye(3, 3, CV_8UC1), in_mat2 = cv::Mat::eye(3, 3, CV_8UC1), out_mat(3, 3, CV_8UC1), ref_mat(3, 3, CV_8UC1); cv::Scalar scalar = 2; comp.apply(cv::gin(in_mat1, in_mat2, scalar), cv::gout(out_mat), cv::compile_args(full_pkg)); ref_mat = in_mat1 + in_mat2 + scalar; EXPECT_EQ(0, cvtest::norm(out_mat, ref_mat, NORM_INF)); } TEST(GCompoundKernel, SplitWithAdd) { cv::GMat in, out1, out2; std::tie(out1, out2) = GCompoundSplitWithAdd::on(in); const auto custom_pkg = cv::gapi::kernels(); const auto full_pkg = cv::gapi::combine(custom_pkg, cv::gapi::core::cpu::kernels()); cv::GComputation comp(cv::GIn(in), cv::GOut(out1, out2)); cv::Mat in_mat = cv::Mat::eye(3, 3, CV_8UC3), out_mat1(3, 3, CV_8UC1), out_mat2(3, 3, CV_8UC1), ref_mat1(3, 3, CV_8UC1), ref_mat2(3, 3, CV_8UC1); comp.apply(cv::gin(in_mat), cv::gout(out_mat1, out_mat2), cv::compile_args(full_pkg)); std::vector channels(3); cv::split(in_mat, channels); ref_mat1 = channels[0] + channels[1]; ref_mat2 = channels[2]; EXPECT_EQ(0, cvtest::norm(out_mat1, ref_mat1, NORM_INF)); EXPECT_EQ(0, cvtest::norm(out_mat2, ref_mat2, NORM_INF)); } TEST(GCompoundKernel, ParallelAddC) { cv::GMat in1, out1, out2; cv::GScalar in2; std::tie(out1, out2) = GCompoundParallelAddC::on(in1, in2); const auto custom_pkg = cv::gapi::kernels(); const auto full_pkg = cv::gapi::combine(custom_pkg, cv::gapi::core::cpu::kernels()); cv::GComputation comp(cv::GIn(in1, in2), cv::GOut(out1, out2)); cv::Mat in_mat = cv::Mat::eye(3, 3, CV_8UC1), out_mat1(3, 3, CV_8UC1), out_mat2(3, 3, CV_8UC1), ref_mat1(3, 3, CV_8UC1), ref_mat2(3, 3, CV_8UC1); cv::Scalar scalar = 2; comp.apply(cv::gin(in_mat, scalar), cv::gout(out_mat1, out_mat2), cv::compile_args(full_pkg)); ref_mat1 = in_mat + scalar; ref_mat2 = in_mat + scalar; EXPECT_EQ(0, cvtest::norm(out_mat1, ref_mat1, NORM_INF)); EXPECT_EQ(0, cvtest::norm(out_mat2, ref_mat2, NORM_INF)); } TEST(GCompoundKernel, GCompundKernelAndDefaultUseOneData) { cv::GMat in1, in2; cv::GScalar s; auto out = cv::gapi::add(GCompoundAddWithAddC::on(in1, in2, s), cv::gapi::addC(in2, s)); const auto custom_pkg = cv::gapi::kernels(); const auto full_pkg = cv::gapi::combine(custom_pkg, cv::gapi::core::cpu::kernels()); cv::GComputation comp(cv::GIn(in1, in2, s), cv::GOut(out)); cv::Mat in_mat1 = cv::Mat::eye(3, 3, CV_8UC1), in_mat2 = cv::Mat::eye(3, 3, CV_8UC1), out_mat(3, 3, CV_8UC1), ref_mat(3, 3, CV_8UC1); cv::Scalar scalar = 2; comp.apply(cv::gin(in_mat1, in_mat2, scalar), cv::gout(out_mat), cv::compile_args(full_pkg)); ref_mat = in_mat1 + in_mat2 + scalar + in_mat2 + scalar; EXPECT_EQ(0, cvtest::norm(out_mat, ref_mat, NORM_INF)); } TEST(GCompoundKernel, CompoundExpandedToCompound) { cv::GMat in1, in2; cv::GScalar s; auto out = GCompoundAddWithAddCWithDoubleAddC::on(in1, in2, s); const auto custom_pkg = cv::gapi::kernels(); const auto full_pkg = cv::gapi::combine(custom_pkg, cv::gapi::core::cpu::kernels()); cv::GComputation comp(cv::GIn(in1, in2, s), cv::GOut(out)); cv::Mat in_mat1 = cv::Mat::eye(3, 3, CV_8UC1), in_mat2 = cv::Mat::eye(3, 3, CV_8UC1), out_mat(3, 3, CV_8UC1), ref_mat(3, 3, CV_8UC1); cv::Scalar scalar = 2; comp.apply(cv::gin(in_mat1, in_mat2, scalar), cv::gout(out_mat), cv::compile_args(full_pkg)); ref_mat = in_mat1 + in_mat2 + scalar + scalar + scalar; EXPECT_EQ(0, cvtest::norm(out_mat, ref_mat, NORM_INF)); } TEST(GCompoundKernel, MaxInArray) { GDoubleArray in; auto out = GCompoundMaxInArray::on(in); const auto custom_pkg = cv::gapi::kernels(); const auto full_pkg = cv::gapi::combine(custom_pkg, cv::gapi::core::cpu::kernels()); cv::GComputation comp(cv::GIn(in), cv::GOut(out)); std::vector v = { 1, 5, -2, 3, 10, 2}; cv::Scalar out_scl; cv::Scalar ref_scl(*std::max_element(v.begin(), v.end())); comp.apply(cv::gin(v), cv::gout(out_scl), cv::compile_args(full_pkg)); EXPECT_EQ(out_scl, ref_scl); } TEST(GCompoundKernel, NegateArray) { GDoubleArray in; GDoubleArray out = GCompoundNegateArray::on(in); const auto custom_pkg = cv::gapi::kernels(); const auto full_pkg = cv::gapi::combine(custom_pkg, cv::gapi::core::cpu::kernels()); cv::GComputation comp(cv::GIn(in), cv::GOut(out)); std::vector in_v = {1, 5, -2, -10, 3}; std::vector out_v; std::vector ref_v; ade::util::transform(in_v, std::back_inserter(ref_v), std::negate()); comp.apply(cv::gin(in_v), cv::gout(out_v), cv::compile_args(full_pkg)); EXPECT_EQ(out_v, ref_v); } TEST(GCompoundKernel, RightGArrayHandle) { cv::GMat in[2]; GDoubleArray a; cv::GMat out = GCompoundGMatGArrayGMat::on(in[0], a, in[1]); const auto custom_pkg = cv::gapi::kernels(); const auto full_pkg = cv::gapi::combine(custom_pkg, cv::gapi::core::cpu::kernels()); cv::GComputation comp(cv::GIn(in[0], a, in[1]), cv::GOut(out)); std::vector in_v(3, 1.0); cv::Mat in_mat1 = cv::Mat::eye(cv::Size(3, 3), CV_8UC1), in_mat2 = cv::Mat::eye(cv::Size(3, 3), CV_8UC1), out_mat; cv::Mat ref_mat= in_mat1 + in_mat2; setDiag(ref_mat, in_v); comp.apply(cv::gin(in_mat1, in_v, in_mat2), cv::gout(out_mat), cv::compile_args(full_pkg)); EXPECT_EQ(0, cvtest::norm(out_mat, ref_mat, NORM_INF)); } TEST(GCompoundKernel, ToInterleavedToPlanar) { cv::GMatP in; cv::GMatP out = GCompoundToInterleavedToPlanar::on(in); const auto pkg = cv::gapi::kernels(); cv::GComputation comp(cv::GIn(in), cv::GOut(out)); constexpr int numPlanes = 3; cv::Mat in_mat(cv::Size(15, 15), CV_8UC1), out_mat, ref_mat; cv::randu(in_mat, 0, 255); ref_mat = in_mat; comp.compile(cv::descr_of(in_mat).asPlanar(numPlanes), cv::compile_args(pkg)) (cv::gin(in_mat), cv::gout(out_mat)); EXPECT_EQ(0, cvtest::norm(out_mat, ref_mat, NORM_INF)); } } // opencv_test