Skip to content

Commit

Permalink
Merge pull request opencv#18451 from OrestChura:oc/count_non_zero
Browse files Browse the repository at this point in the history
[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
  • Loading branch information
OrestChura authored Sep 30, 2020
1 parent fc1a156 commit 40b8b58
Show file tree
Hide file tree
Showing 15 changed files with 235 additions and 24 deletions.
43 changes: 32 additions & 11 deletions modules/gapi/include/opencv2/gapi/core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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.
*/
Expand All @@ -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.
*/
Expand All @@ -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.
*/
Expand Down Expand Up @@ -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);

Expand All @@ -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);

Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions modules/gapi/include/opencv2/gapi/ocl/goclkernel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -75,7 +75,7 @@ class GAPI_EXPORTS GOCLContext

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;
Expand Down
3 changes: 2 additions & 1 deletion modules/gapi/perf/common/gapi_core_perf_tests.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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>> {};
Expand Down
40 changes: 39 additions & 1 deletion modules/gapi/perf/common/gapi_core_perf_tests_inl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -1011,6 +1011,44 @@ PERF_TEST_P_(SumPerfTest, TestPerformance)
SANITY_CHECK_NOTHING();
}

//------------------------------------------------------------------------------
#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)
Expand Down
8 changes: 7 additions & 1 deletion modules/gapi/perf/cpu/gapi_core_perf_tests_cpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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),
Expand Down
8 changes: 7 additions & 1 deletion modules/gapi/perf/gpu/gapi_core_perf_tests_gpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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 ),
Expand Down
7 changes: 6 additions & 1 deletion modules/gapi/src/api/kernels_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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);
Expand Down
11 changes: 10 additions & 1 deletion modules/gapi/src/backends/cpu/gcpucore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -679,6 +687,7 @@ cv::gapi::GKernelPackage cv::gapi::core::cpu::kernels()
, GCPUAbsDiff
, GCPUAbsDiffC
, GCPUSum
, GCPUCountNonZero
, GCPUAddW
, GCPUNormL1
, GCPUNormL2
Expand Down
11 changes: 10 additions & 1 deletion modules/gapi/src/backends/ocl/goclcore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -565,6 +573,7 @@ cv::gapi::GKernelPackage cv::gapi::core::ocl::kernels()
, GOCLAbsDiff
, GOCLAbsDiffC
, GOCLSum
, GOCLCountNonZero
, GOCLAddW
, GOCLNormL1
, GOCLNormL2
Expand Down
5 changes: 5 additions & 0 deletions modules/gapi/src/backends/ocl/goclkernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()
{
}
Expand Down
1 change: 1 addition & 0 deletions modules/gapi/test/common/gapi_core_tests.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Loading

0 comments on commit 40b8b58

Please sign in to comment.