Merge pull request #18451 from OrestChura:oc/count_non_zero
authorOrest Chura <orest.chura@intel.com>
Wed, 30 Sep 2020 16:07:35 +0000 (19:07 +0300)
committerGitHub <noreply@github.com>
Wed, 30 Sep 2020 16:07:35 +0000 (16:07 +0000)
[G-API]: countNonZero() Standard Kernel Implementation

* Add countNonZero() standard kernel
 - API and documentation provided
 - OCV backend supported
 - accuracy and performance tests provided
 - some refactoring of related documentation done

* Fix GOpaque functionality for OCL Backend
 - test for OCL Opaque usage providied

* countNonZero for GPU
 - OCL Backend implementation for countNonZero() added
 - tests provided

* Addressing comments

15 files changed:
modules/gapi/include/opencv2/gapi/core.hpp
modules/gapi/include/opencv2/gapi/ocl/goclkernel.hpp
modules/gapi/perf/common/gapi_core_perf_tests.hpp
modules/gapi/perf/common/gapi_core_perf_tests_inl.hpp
modules/gapi/perf/cpu/gapi_core_perf_tests_cpu.cpp
modules/gapi/perf/gpu/gapi_core_perf_tests_gpu.cpp
modules/gapi/src/api/kernels_core.cpp
modules/gapi/src/backends/cpu/gcpucore.cpp
modules/gapi/src/backends/ocl/goclcore.cpp
modules/gapi/src/backends/ocl/goclkernel.cpp
modules/gapi/test/common/gapi_core_tests.hpp
modules/gapi/test/common/gapi_core_tests_inl.hpp
modules/gapi/test/cpu/gapi_core_tests_cpu.cpp
modules/gapi/test/gapi_opaque_tests.cpp
modules/gapi/test/gpu/gapi_core_tests_gpu.cpp

index 0313aad..c4ddaf6 100644 (file)
@@ -2,7 +2,7 @@
 // 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
+// Copyright (C) 2018-2020 Intel Corporation
 
 
 #ifndef OPENCV_GAPI_CORE_HPP
@@ -308,6 +308,13 @@ namespace core {
         }
     };
 
+    G_TYPED_KERNEL(GCountNonZero, <GOpaque<int>(GMat)>, "org.opencv.core.matrixop.countNonZero") {
+        static GOpaqueDesc outMeta(GMatDesc in) {
+            GAPI_Assert(in.chan == 1);
+            return empty_gopaque_desc();
+        }
+    };
+
     G_TYPED_KERNEL(GAddW, <GMat(GMat, double, GMat, double, double, int)>, "org.opencv.core.matrixop.addweighted") {
         static GMatDesc outMeta(GMatDesc a, double, GMatDesc b, double, double, int ddepth) {
             if (ddepth == -1)
@@ -755,6 +762,7 @@ Supported matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref
 
 @note Function textual ID is "org.opencv.core.math.mean"
 @param src input matrix.
+@sa  countNonZero, min, max
 */
 GAPI_EXPORTS_W GScalar mean(const GMat& src);
 
@@ -856,7 +864,7 @@ Supported input matrix data types are @ref CV_8UC1, @ref CV_16UC1, @ref CV_16SC1
 @note Function textual ID is "org.opencv.core.pixelwise.compare.cmpGT"
 @param src1 first input matrix.
 @param src2 second input matrix/scalar of the same depth as first input matrix.
-@sa min, max, threshold, cmpLE, cmpGE, cmpLS
+@sa min, max, threshold, cmpLE, cmpGE, cmpLT
 */
 GAPI_EXPORTS GMat cmpGT(const GMat& src1, const GMat& src2);
 /** @overload
@@ -908,7 +916,7 @@ Supported input matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1,
 @note Function textual ID is "org.opencv.core.pixelwise.compare.cmpGE"
 @param src1 first input matrix.
 @param src2 second input matrix/scalar of the same depth as first input matrix.
-@sa min, max, threshold, cmpLE, cmpGT, cmpLS
+@sa min, max, threshold, cmpLE, cmpGT, cmpLT
 */
 GAPI_EXPORTS GMat cmpGE(const GMat& src1, const GMat& src2);
 /** @overload
@@ -934,7 +942,7 @@ Supported input matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1,
 @note Function textual ID is "org.opencv.core.pixelwise.compare.cmpLE"
 @param src1 first input matrix.
 @param src2 second input matrix/scalar of the same depth as first input matrix.
-@sa min, max, threshold, cmpGT, cmpGE, cmpLS
+@sa min, max, threshold, cmpGT, cmpGE, cmpLT
 */
 GAPI_EXPORTS GMat cmpLE(const GMat& src1, const GMat& src2);
 /** @overload
@@ -1012,7 +1020,7 @@ Supported matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref
 */
 GAPI_EXPORTS GMat bitwise_and(const GMat& src1, const GMat& src2);
 /** @overload
-@note Function textual ID is "org.opencv.core.pixelwise.compare.bitwise_andS"
+@note Function textual ID is "org.opencv.core.pixelwise.bitwise_andS"
 @param src1 first input matrix.
 @param src2 scalar, which will be per-lemenetly conjuncted with elements of src1.
 */
@@ -1036,7 +1044,7 @@ Supported matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref
 */
 GAPI_EXPORTS GMat bitwise_or(const GMat& src1, const GMat& src2);
 /** @overload
-@note Function textual ID is "org.opencv.core.pixelwise.compare.bitwise_orS"
+@note Function textual ID is "org.opencv.core.pixelwise.bitwise_orS"
 @param src1 first input matrix.
 @param src2 scalar, which will be per-lemenetly disjuncted with elements of src1.
 */
@@ -1061,7 +1069,7 @@ Supported matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref
 */
 GAPI_EXPORTS GMat bitwise_xor(const GMat& src1, const GMat& src2);
 /** @overload
-@note Function textual ID is "org.opencv.core.pixelwise.compare.bitwise_xorS"
+@note Function textual ID is "org.opencv.core.pixelwise.bitwise_xorS"
 @param src1 first input matrix.
 @param src2 scalar, for which per-lemenet "logical or" operation on elements of src1 will be performed.
 */
@@ -1121,7 +1129,7 @@ Supported input matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1,
 @note Function textual ID is "org.opencv.core.matrixop.min"
 @param src1 first input matrix.
 @param src2 second input matrix of the same size and depth as src1.
-@sa max, compareEqual, compareLess, compareLessEqual
+@sa max, cmpEQ, cmpLT, cmpLE
 */
 GAPI_EXPORTS GMat min(const GMat& src1, const GMat& src2);
 
@@ -1138,7 +1146,7 @@ Supported matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref
 @note Function textual ID is "org.opencv.core.matrixop.max"
 @param src1 first input matrix.
 @param src2 second input matrix of the same size and depth as src1.
-@sa min, compare, compareEqual, compareGreater, compareGreaterEqual
+@sa min, compare, cmpEQ, cmpGT, cmpGE
 */
 GAPI_EXPORTS GMat max(const GMat& src1, const GMat& src2);
 
@@ -1184,10 +1192,23 @@ Supported matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref
 
 @note Function textual ID is "org.opencv.core.matrixop.sum"
 @param src input matrix.
-@sa min, max
+@sa countNonZero, mean, min, max
 */
 GAPI_EXPORTS GScalar sum(const GMat& src);
 
+/** @brief Counts non-zero array elements.
+
+The function returns the number of non-zero elements in src :
+\f[\sum _{I: \; \texttt{src} (I) \ne0 } 1\f]
+
+Supported matrix data types are @ref CV_8UC1, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1.
+
+@note Function textual ID is "org.opencv.core.matrixop.countNonZero"
+@param src input single-channel matrix.
+@sa  mean, min, max
+*/
+GAPI_EXPORTS GOpaque<int> countNonZero(const GMat& src);
+
 /** @brief Calculates the weighted sum of two matrices.
 
 The function addWeighted calculates the weighted sum of two matrices as follows:
@@ -1324,7 +1345,7 @@ Output matrix must be of the same size and depth as src.
 types.
 @param type thresholding type (see the cv::ThresholdTypes).
 
-@sa min, max, cmpGT, cmpLE, cmpGE, cmpLS
+@sa min, max, cmpGT, cmpLE, cmpGE, cmpLT
  */
 GAPI_EXPORTS GMat threshold(const GMat& src, const GScalar& thresh, const GScalar& maxval, int type);
 /** @overload
index ee363c0..8ec388d 100644 (file)
@@ -2,7 +2,7 @@
 // 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-2019 Intel Corporation
+// Copyright (C) 2018-2020 Intel Corporation
 
 
 #ifndef OPENCV_GAPI_GOCLKERNEL_HPP
@@ -75,7 +75,7 @@ public:
 
 protected:
     detail::VectorRef& outVecRef(int output);
-    detail::VectorRef& outOpaqueRef(int output);
+    detail::OpaqueRef& outOpaqueRef(int output);
 
     std::vector<GArg> m_args;
     std::unordered_map<std::size_t, GRunArgP> m_results;
index ac7182c..4a88b4f 100644 (file)
@@ -2,7 +2,7 @@
 // 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
+// Copyright (C) 2018-2020 Intel Corporation
 
 
 #ifndef OPENCV_GAPI_CORE_PERF_TESTS_HPP
@@ -52,6 +52,7 @@ namespace opencv_test
     class AbsDiffPerfTest : public TestPerfParams<tuple<cv::Size, MatType, cv::GCompileArgs>> {};
     class AbsDiffCPerfTest : public TestPerfParams<tuple<cv::Size, MatType, cv::GCompileArgs>> {};
     class SumPerfTest : public TestPerfParams<tuple<compare_scalar_f, cv::Size, MatType, cv::GCompileArgs>> {};
+    class CountNonZeroPerfTest : public TestPerfParams<tuple<compare_scalar_f, cv::Size, MatType, cv::GCompileArgs>> {};
     class AddWeightedPerfTest : public TestPerfParams<tuple<compare_f, cv::Size, MatType, int, cv::GCompileArgs>> {};
     class NormPerfTest : public TestPerfParams<tuple<compare_scalar_f, NormTypes, cv::Size, MatType, cv::GCompileArgs>> {};
     class IntegralPerfTest : public TestPerfParams<tuple<cv::Size, MatType, cv::GCompileArgs>> {};
index 9ad1d04..91d08bb 100644 (file)
@@ -2,7 +2,7 @@
 // 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
+// Copyright (C) 2018-2020 Intel Corporation
 
 
 #ifndef OPENCV_GAPI_CORE_PERF_TESTS_INL_HPP
@@ -1012,6 +1012,44 @@ PERF_TEST_P_(SumPerfTest, TestPerformance)
 }
 
 //------------------------------------------------------------------------------
+#pragma push_macro("countNonZero")
+#undef countNonZero
+PERF_TEST_P_(CountNonZeroPerfTest, TestPerformance)
+{
+    compare_scalar_f cmpF;
+    cv::Size sz_in;
+    MatType type = -1;
+    cv::GCompileArgs compile_args;
+    std::tie(cmpF, sz_in, type, compile_args) = GetParam();
+
+    initMatrixRandU(type, sz_in, type, false);
+    int out_cnz_gapi, out_cnz_ocv;
+
+    // OpenCV code ///////////////////////////////////////////////////////////
+    out_cnz_ocv = cv::countNonZero(in_mat1);
+
+    // G-API code ////////////////////////////////////////////////////////////
+    cv::GMat in;
+    auto out = cv::gapi::countNonZero(in);
+    cv::GComputation c(cv::GIn(in), cv::GOut(out));
+
+    // Warm-up graph engine:
+    c.apply(cv::gin(in_mat1), cv::gout(out_cnz_gapi), std::move(compile_args));
+
+    TEST_CYCLE()
+    {
+        c.apply(cv::gin(in_mat1), cv::gout(out_cnz_gapi));
+    }
+
+    // Comparison ////////////////////////////////////////////////////////////
+    {
+        EXPECT_TRUE(cmpF(out_cnz_gapi, out_cnz_ocv));
+    }
+
+    SANITY_CHECK_NOTHING();
+}
+#pragma pop_macro("countNonZero")
+//------------------------------------------------------------------------------
 
 PERF_TEST_P_(AddWeightedPerfTest, TestPerformance)
 {
index d4319f2..ffc4b1a 100644 (file)
@@ -2,7 +2,7 @@
 // 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
+// Copyright (C) 2018-2020 Intel Corporation
 
 
 #include "../perf_precomp.hpp"
@@ -160,6 +160,12 @@ INSTANTIATE_TEST_CASE_P(SumPerfTestCPU, SumPerfTest,
         //Values(0.0),
         Values(cv::compile_args(CORE_CPU))));
 
+INSTANTIATE_TEST_CASE_P(CountNonZeroPerfTestCPU, CountNonZeroPerfTest,
+                        Combine(Values(AbsToleranceScalar(0.0).to_compare_f()),
+                                Values(szSmall128, szVGA, sz720p, sz1080p),
+                                Values(CV_8UC1, CV_16UC1, CV_16SC1, CV_32FC1),
+                                Values(cv::compile_args(CORE_CPU))));
+
 INSTANTIATE_TEST_CASE_P(AddWeightedPerfTestCPU, AddWeightedPerfTest,
     Combine(Values(Tolerance_FloatRel_IntAbs(1e-6, 1).to_compare_f()),
         Values(szSmall128, szVGA, sz720p, sz1080p),
index 0c5ff9e..2d8c254 100644 (file)
@@ -2,7 +2,7 @@
 // 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
+// Copyright (C) 2018-2020 Intel Corporation
 
 
 #include "../perf_precomp.hpp"
@@ -157,6 +157,12 @@ INSTANTIATE_TEST_CASE_P(SumPerfTestGPU, SumPerfTest,
                                 Values( CV_8UC1, CV_8UC3, CV_16UC1, CV_16SC1, CV_32FC1 ),
                                 Values(cv::compile_args(CORE_GPU))));
 
+INSTANTIATE_TEST_CASE_P(CountNonZeroPerfTestGPU, CountNonZeroPerfTest,
+                        Combine(Values(AbsToleranceScalar(0.0).to_compare_f()),
+                                Values(szSmall128, szVGA, sz720p, sz1080p),
+                                Values(CV_8UC1, CV_16UC1, CV_16SC1, CV_32FC1),
+                                Values(cv::compile_args(CORE_GPU))));
+
 INSTANTIATE_TEST_CASE_P(AddWeightedPerfTestGPU, AddWeightedPerfTest,
                         Combine(Values(Tolerance_FloatRel_IntAbs(1e-6, 1).to_compare_f()),
                                 Values( szSmall128, szVGA, sz720p, sz1080p ),
index 961d19c..55c4359 100644 (file)
@@ -2,7 +2,7 @@
 // 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
+// Copyright (C) 2018-2020 Intel Corporation
 
 
 #include "precomp.hpp"
@@ -234,6 +234,11 @@ GScalar sum(const GMat& src)
     return core::GSum::on(src);
 }
 
+GOpaque<int> countNonZero(const GMat& src)
+{
+    return core::GCountNonZero::on(src);
+}
+
 GMat addWeighted(const GMat& src1, double alpha, const GMat& src2, double beta, double gamma, int dtype)
 {
     return core::GAddW::on(src1, alpha, src2, beta, gamma, dtype);
index d9c3c3a..f2b8f70 100644 (file)
@@ -2,7 +2,7 @@
 // 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
+// Copyright (C) 2018-2020 Intel Corporation
 
 
 #include "precomp.hpp"
@@ -342,6 +342,14 @@ GAPI_OCV_KERNEL(GCPUSum, cv::gapi::core::GSum)
     }
 };
 
+GAPI_OCV_KERNEL(GCPUCountNonZero, cv::gapi::core::GCountNonZero)
+{
+    static void run(const cv::Mat& in, int& out)
+    {
+        out = cv::countNonZero(in);
+    }
+};
+
 GAPI_OCV_KERNEL(GCPUAddW, cv::gapi::core::GAddW)
 {
     static void run(const cv::Mat& in1, double alpha, const cv::Mat& in2, double beta, double gamma, int dtype, cv::Mat& out)
@@ -679,6 +687,7 @@ cv::gapi::GKernelPackage cv::gapi::core::cpu::kernels()
          , GCPUAbsDiff
          , GCPUAbsDiffC
          , GCPUSum
+         , GCPUCountNonZero
          , GCPUAddW
          , GCPUNormL1
          , GCPUNormL2
index ec6ab18..61e0334 100644 (file)
@@ -2,7 +2,7 @@
 // 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
+// Copyright (C) 2018-2020 Intel Corporation
 
 
 #include "precomp.hpp"
@@ -337,6 +337,14 @@ GAPI_OCL_KERNEL(GOCLSum, cv::gapi::core::GSum)
     }
 };
 
+GAPI_OCL_KERNEL(GOCLCountNonZero, cv::gapi::core::GCountNonZero)
+{
+    static void run(const cv::UMat& in, int& out)
+    {
+        out = cv::countNonZero(in);
+    }
+};
+
 GAPI_OCL_KERNEL(GOCLAddW, cv::gapi::core::GAddW)
 {
     static void run(const cv::UMat& in1, double alpha, const cv::UMat& in2, double beta, double gamma, int dtype, cv::UMat& out)
@@ -565,6 +573,7 @@ cv::gapi::GKernelPackage cv::gapi::core::ocl::kernels()
          , GOCLAbsDiff
          , GOCLAbsDiffC
          , GOCLSum
+         , GOCLCountNonZero
          , GOCLAddW
          , GOCLNormL1
          , GOCLNormL2
index 585e017..9ea8502 100644 (file)
@@ -34,6 +34,11 @@ cv::detail::VectorRef& cv::GOCLContext::outVecRef(int output)
     return util::get<cv::detail::VectorRef>(m_results.at(output));
 }
 
+cv::detail::OpaqueRef& cv::GOCLContext::outOpaqueRef(int output)
+{
+    return util::get<cv::detail::OpaqueRef>(m_results.at(output));
+}
+
 cv::GOCLKernel::GOCLKernel()
 {
 }
index 308f886..4a0a764 100644 (file)
@@ -97,6 +97,7 @@ GAPI_TEST_FIXTURE(MaxTest, initMatsRandU, <>, 0)
 GAPI_TEST_FIXTURE(AbsDiffTest, initMatsRandU, <>, 0)
 GAPI_TEST_FIXTURE(AbsDiffCTest, initMatsRandU, <>, 0)
 GAPI_TEST_FIXTURE(SumTest, initMatrixRandU, FIXTURE_API(CompareScalars), 1, cmpF)
+GAPI_TEST_FIXTURE(CountNonZeroTest, initMatrixRandU, FIXTURE_API(CompareScalars), 1, cmpF)
 GAPI_TEST_FIXTURE(AddWeightedTest, initMatsRandU, FIXTURE_API(CompareMats), 1, cmpF)
 GAPI_TEST_FIXTURE(NormTest, initMatrixRandU, FIXTURE_API(CompareScalars,NormTypes), 2,
     cmpF, opType)
index 331ef70..e350a14 100644 (file)
@@ -2,7 +2,7 @@
 // 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-2019 Intel Corporation
+// Copyright (C) 2018-2020 Intel Corporation
 
 
 #ifndef OPENCV_GAPI_CORE_TESTS_INL_HPP
@@ -614,6 +614,29 @@ TEST_P(SumTest, AccuracyTest)
     }
 }
 
+#pragma push_macro("countNonZero")
+#undef countNonZero
+TEST_P(CountNonZeroTest, AccuracyTest)
+{
+    int out_cnz_gapi, out_cnz_ocv;
+
+    // G-API code //////////////////////////////////////////////////////////////
+    cv::GMat in;
+    auto out = cv::gapi::countNonZero(in);
+
+    cv::GComputation c(cv::GIn(in), cv::GOut(out));
+    c.apply(cv::gin(in_mat1), cv::gout(out_cnz_gapi), getCompileArgs());
+    // OpenCV code /////////////////////////////////////////////////////////////
+    {
+        out_cnz_ocv = cv::countNonZero(in_mat1);
+    }
+    // Comparison //////////////////////////////////////////////////////////////
+    {
+        EXPECT_TRUE(cmpF(out_cnz_gapi, out_cnz_ocv));
+    }
+}
+#pragma pop_macro("countNonZero")
+
 TEST_P(AddWeightedTest, AccuracyTest)
 {
     auto& rng = cv::theRNG();
index ff98130..53faa28 100644 (file)
@@ -2,7 +2,7 @@
 // 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-2019 Intel Corporation
+// Copyright (C) 2018-2020 Intel Corporation
 
 
 #include "../test_precomp.hpp"
@@ -202,6 +202,15 @@ INSTANTIATE_TEST_CASE_P(SumTestCPU, SumTest,
                                 Values(CORE_CPU),
                                 Values(AbsToleranceScalar(1e-5).to_compare_obj())));
 
+INSTANTIATE_TEST_CASE_P(CountNonZeroTestCPU, CountNonZeroTest,
+                        Combine(Values( CV_8UC1, CV_16UC1, CV_16SC1, CV_32FC1 ),
+                                Values(cv::Size(1280, 720),
+                                       cv::Size(640, 480),
+                                       cv::Size(128, 128)),
+                                Values(-1),
+                                Values(CORE_CPU),
+                                Values(AbsToleranceScalar(1e-5).to_compare_obj())));
+
 INSTANTIATE_TEST_CASE_P(AbsDiffTestCPU, AbsDiffTest,
                         Combine(Values( CV_8UC1, CV_8UC3, CV_16UC1, CV_16SC1, CV_32FC1 ),
                                 Values(cv::Size(1280, 720),
index 9bbb431..4cadb91 100644 (file)
@@ -63,6 +63,14 @@ GAPI_OCV_KERNEL(OCVGeneratePoint, ThisTest::GeneratePoint)
     }
 };
 
+GAPI_OCL_KERNEL(OCLGeneratePoint, ThisTest::GeneratePoint)
+{
+    static void run(const cv::UMat&, cv::Point& out)
+    {
+        out = cv::Point(42, 42);
+    }
+};
+
 GAPI_OCV_KERNEL(OCVFillMat, ThisTest::FillMat)
 {
     static void run(int a, int, int, cv::Size, cv::Mat& out)
@@ -79,6 +87,16 @@ GAPI_OCV_KERNEL(OCVPaintPoint, ThisTest::PaintPoint)
     }
 };
 
+GAPI_OCL_KERNEL(OCLPaintPoint, ThisTest::PaintPoint)
+{
+    static void run(cv::Point a, int depth, int chan, cv::Size size, cv::UMat& out)
+    {
+        GAPI_Assert(chan == 1);
+        out.create(size, CV_MAKETYPE(depth, chan));
+        cv::drawMarker(out, a, cv::Scalar(77));
+    }
+};
+
 GAPI_OCV_KERNEL(OCVGenerateOpaque, ThisTest::GenerateOpaque)
 {
     static void run(const cv::Mat& a, const cv::Mat& b, const std::string& s,
@@ -189,6 +207,57 @@ TEST(GOpaque, TestOpaqueCustomOut2)
     EXPECT_EQ(out2.s, str2);
 }
 
+TEST(GOpaque, TestOpaqueOCLBackendIn)
+{
+    cv::Point p_in = {42, 42};
+    cv::Mat mat_out;
+
+    ThisTest::GPointOpaque in;
+    cv::GMat out = ThisTest::PaintPoint::on(in, CV_8U, 1, {50, 50});
+
+    cv::GComputation c(cv::GIn(in), cv::GOut(out));
+    c.apply(cv::gin(p_in), cv::gout(mat_out),
+            cv::compile_args(cv::gapi::kernels<OCLPaintPoint>()));
+
+    int painted = mat_out.at<uint8_t>(42, 42);
+    EXPECT_EQ(painted, 77);
+}
+
+TEST(GOpaque, TestOpaqueOCLBackendBetween)
+{
+    cv::Size sz = {50, 50};
+    int depth   = CV_8U;
+    int chan    = 1;
+    cv::Mat mat_in = cv::Mat::zeros(sz, CV_MAKETYPE(depth, chan));
+    cv::Mat mat_out;
+
+    cv::GMat in;
+    auto     betw = ThisTest::GeneratePoint::on(in);
+    cv::GMat out  = ThisTest::PaintPoint::on(betw, depth, chan, sz);
+
+    cv::GComputation c(cv::GIn(in), cv::GOut(out));
+    c.apply(cv::gin(mat_in), cv::gout(mat_out),
+            cv::compile_args(cv::gapi::kernels<OCLGeneratePoint, OCLPaintPoint>()));
+
+    int painted = mat_out.at<uint8_t>(42, 42);
+    EXPECT_EQ(painted, 77);
+}
+
+TEST(GOpaque, TestOpaqueOCLBackendOut)
+{
+    cv::Mat input = cv::Mat(52, 52, CV_8U);
+    cv::Point p_out;
+
+    cv::GMat in;
+    ThisTest::GPointOpaque out = ThisTest::GeneratePoint::on(in);
+
+    cv::GComputation c(cv::GIn(in), cv::GOut(out));
+    c.apply(cv::gin(input), cv::gout(p_out),
+            cv::compile_args(cv::gapi::kernels<OCLGeneratePoint>()));
+
+    EXPECT_TRUE(p_out == cv::Point(42, 42));
+}
+
 TEST(GOpaque_OpaqueRef, TestMov)
 {
     // Warning: this test is testing some not-very-public APIs
index 35daed7..1bd076a 100644 (file)
@@ -2,7 +2,7 @@
 // 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-2019 Intel Corporation
+// Copyright (C) 2018-2020 Intel Corporation
 
 
 #include "../test_precomp.hpp"
@@ -192,7 +192,16 @@ INSTANTIATE_TEST_CASE_P(SumTestGPU, SumTest,
                                        cv::Size(128, 128)),
                                 Values(-1),
                                 Values(CORE_GPU),
-                                Values(AbsToleranceScalar(1e-3).to_compare_obj())));//TODO: too relaxed?
+                                Values(AbsToleranceScalar(1e-5).to_compare_obj())));
+
+INSTANTIATE_TEST_CASE_P(CountNonZeroTestGPU, CountNonZeroTest,
+                        Combine(Values( CV_8UC1, CV_16UC1, CV_16SC1, CV_32FC1 ),
+                                Values(cv::Size(1280, 720),
+                                       cv::Size(640, 480),
+                                       cv::Size(128, 128)),
+                                Values(-1),
+                                Values(CORE_GPU),
+                                Values(AbsToleranceScalar(1e-5).to_compare_obj())));
 
 INSTANTIATE_TEST_CASE_P(AbsDiffTestGPU, AbsDiffTest,
                         Combine(Values( CV_8UC1, CV_8UC3, CV_16UC1, CV_16SC1, CV_32FC1 ),