Merge pull request #17871 from OrestChura:oc/typed_GArray_GMat
authorOrest Chura <orest.chura@intel.com>
Tue, 28 Jul 2020 11:20:36 +0000 (14:20 +0300)
committerGitHub <noreply@github.com>
Tue, 28 Jul 2020 11:20:36 +0000 (14:20 +0300)
* Added overload for `GArray<GMat>` ProtoParam in `gtyped.hpp`

* Tests+compile_args
 - added tests for GArray<GMat> as an input and an output of GComputationT
 - added possibility to give the compile_args to GComputationT.apply()

* Fix win errors

modules/gapi/include/opencv2/gapi/gtyped.hpp
modules/gapi/test/gapi_typed_tests.cpp

index 1ce6201..6fe52a6 100644 (file)
@@ -26,6 +26,7 @@ namespace detail
     template<> struct ProtoToParam<cv::GMat>    { using type = cv::Mat; };
     template<> struct ProtoToParam<cv::GScalar> { using type = cv::Scalar; };
     template<typename U> struct ProtoToParam<cv::GArray<U> >  { using type = std::vector<U>; };
+    template<> struct ProtoToParam<cv::GArray<cv::GMat>>      { using type = std::vector<cv::Mat>; };
     template<typename U> struct ProtoToParam<cv::GOpaque<U> > { using type = U; };
     template<typename T> using ProtoToParamT = typename ProtoToParam<T>::type;
 
@@ -133,11 +134,19 @@ public:
     }
 
     void apply(detail::ProtoToParamT<Args>... inArgs,
+               detail::ProtoToParamT<R> &outArg,
+               GCompileArgs &&args)
+    {
+        m_comp.apply(cv::gin(inArgs...), cv::gout(outArg), std::move(args));
+    }
+
+    void apply(detail::ProtoToParamT<Args>... inArgs,
                detail::ProtoToParamT<R> &outArg)
     {
-        m_comp.apply(cv::gin(inArgs...), cv::gout(outArg));
+        apply(inArgs..., outArg, GCompileArgs());
     }
 
+
     GCompiledT compile(detail::ProtoToMetaT<Args>... inDescs)
     {
         GMetaArgs inMetas = { GMetaArg(inDescs)... };
@@ -206,11 +215,19 @@ public:
     }
 
     void apply(detail::ProtoToParamT<Args>... inArgs,
+               detail::ProtoToParamT<R>&... outArgs,
+               GCompileArgs &&args)
+    {
+        m_comp.apply(cv::gin(inArgs...), cv::gout(outArgs...), std::move(args));
+    }
+
+    void apply(detail::ProtoToParamT<Args>... inArgs,
                detail::ProtoToParamT<R>&... outArgs)
     {
-        m_comp.apply(cv::gin(inArgs...), cv::gout(outArgs...));
+        apply(inArgs..., outArgs..., GCompileArgs());
     }
 
+
     GCompiledT compile(detail::ProtoToMetaT<Args>... inDescs)
     {
         GMetaArgs inMetas = { GMetaArg(inDescs)... };
index c811cef..97de39f 100644 (file)
@@ -7,6 +7,45 @@
 
 #include "test_precomp.hpp"
 
+#include "common/gapi_tests_common.hpp"
+
+namespace custom
+{
+G_TYPED_KERNEL(GKernelForGArrayGMatOut, <cv::GArray<cv::GMat>(cv::GMat)>,
+               "custom.test.kernelForGArrayGMatOut")
+{
+    static cv::GArrayDesc outMeta(const cv::GMatDesc&)
+    {
+        return cv::empty_array_desc();
+    }
+};
+
+GAPI_OCV_KERNEL(GCPUKernelForGArrayGMatOut, custom::GKernelForGArrayGMatOut)
+{
+    static void run(const cv::Mat &src, std::vector<cv::Mat> &out)
+    {
+        out[0] = src.clone();
+    }
+};
+
+G_TYPED_KERNEL(GSizeOfVectorGMat, <cv::GOpaque<size_t>(cv::GArray<cv::GMat>)>,
+               "custom.test.sizeOfVectorGMat")
+{
+    static cv::GOpaqueDesc outMeta(const cv::GArrayDesc&)
+    {
+        return cv::empty_gopaque_desc();
+    }
+};
+
+GAPI_OCV_KERNEL(GCPUSizeOfVectorGMat, custom::GSizeOfVectorGMat)
+{
+    static void run(const std::vector<cv::Mat> &src, size_t &out)
+    {
+        out = src.size();
+    }
+};
+}
+
 namespace opencv_test
 {
 
@@ -94,7 +133,6 @@ TEST(GAPI_Typed, BinaryOp)
     EXPECT_EQ(0, cvtest::norm(out_mat_cv, out_mat_typed2, NORM_INF));
 }
 
-
 TEST(GAPI_Typed, MultipleOuts)
 {
     // Initialization //////////////////////////////////////////////////////////
@@ -147,4 +185,84 @@ TEST(GAPI_Typed, MultipleOuts)
     EXPECT_EQ(0, cvtest::norm(out_mat_cv2, out_mat_comp2, NORM_INF));
 }
 
+TEST(GAPI_Typed, GArrayGMatOut)
+{
+    // Initialization //////////////////////////////////////////////////////////
+    const cv::Size sz(32, 32);
+    cv::Mat in_mat(sz, CV_8UC3);
+    std::vector<cv::Mat> out_vec_mat_untyped(1),
+                         out_vec_mat_typed1 (1),
+                         out_vec_mat_typed2 (1),
+                         out_vec_mat_cv     (1);
+    cv::randu(in_mat, cv::Scalar::all(0), cv::Scalar::all(255));
+
+    auto customKernel = cv::gapi::kernels<custom::GCPUKernelForGArrayGMatOut>();
+    auto absExactCompare = AbsExact().to_compare_f();
+
+    // Untyped G-API ///////////////////////////////////////////////////////////
+    cv::GComputation cptU([]()
+    {
+        cv::GMat in;
+        cv::GArray<cv::GMat> out = custom::GKernelForGArrayGMatOut::on(in);
+        return cv::GComputation(cv::GIn(in), cv::GOut(out));
+    });
+    cptU.apply(cv::gin(in_mat), cv::gout(out_vec_mat_untyped), cv::compile_args(customKernel));
+
+    // Typed G-API /////////////////////////////////////////////////////////////
+    cv::GComputationT<cv::GArray<cv::GMat> (cv::GMat)> cptT(custom::GKernelForGArrayGMatOut::on);
+    auto cplT = cptT.compile(cv::descr_of(in_mat), cv::compile_args(customKernel));
+
+    cptT.apply(in_mat, out_vec_mat_typed1, cv::compile_args(customKernel));
+    cplT(in_mat, out_vec_mat_typed2);
+
+    // Plain OpenCV ////////////////////////////////////////////////////////////
+    out_vec_mat_cv[0] = in_mat.clone();
+
+    // Comparison //////////////////////////////////////////////////////////////
+    EXPECT_TRUE(absExactCompare(out_vec_mat_cv[0], out_vec_mat_untyped[0]));
+    EXPECT_TRUE(absExactCompare(out_vec_mat_cv[0], out_vec_mat_typed1 [0]));
+    EXPECT_TRUE(absExactCompare(out_vec_mat_cv[0], out_vec_mat_typed2 [0]));
+}
+
+TEST(GAPI_Typed, GArrayGMatIn)
+{
+    // Initialization //////////////////////////////////////////////////////////
+    const cv::Size sz(32, 32);
+    size_t vectorSize = 5;
+
+    cv::Mat in_mat (sz, CV_8UC3);
+    size_t out_size_t_untyped, out_size_t_typed1, out_size_t_typed2, out_size_t_cv;
+
+    cv::randu(in_mat, cv::Scalar::all(0), cv::Scalar::all(255));
+    std::vector<cv::Mat> in_vec(vectorSize);
+    for (size_t i = 0; i < vectorSize; i++)
+        in_vec[i] = in_mat.clone();
+
+    auto customKernel = cv::gapi::kernels<custom::GCPUSizeOfVectorGMat>();
+
+    // Untyped G-API ///////////////////////////////////////////////////////////
+    cv::GComputation cptU([]()
+    {
+        cv::GArray<cv::GMat> in;
+        cv::GOpaque<size_t> out = custom::GSizeOfVectorGMat::on(in);
+        return cv::GComputation(cv::GIn(in), cv::GOut(out));
+    });
+    cptU.apply(cv::gin(in_vec), cv::gout(out_size_t_untyped), cv::compile_args(customKernel));
+
+    // Typed G-API /////////////////////////////////////////////////////////////
+    cv::GComputationT<cv::GOpaque<size_t> (cv::GArray<cv::GMat>)> cptT(custom::GSizeOfVectorGMat::on);
+    auto cplT = cptT.compile(cv::descr_of(in_vec), cv::compile_args(customKernel));
+
+    cptT.apply(in_vec, out_size_t_typed1, cv::compile_args(customKernel));
+    cplT(in_vec, out_size_t_typed2);
+
+    // Plain OpenCV ////////////////////////////////////////////////////////////
+    out_size_t_cv = in_vec.size();
+
+    // Comparison //////////////////////////////////////////////////////////////
+    EXPECT_TRUE(out_size_t_cv      == vectorSize);
+    EXPECT_TRUE(out_size_t_untyped == vectorSize);
+    EXPECT_TRUE(out_size_t_typed1  == vectorSize);
+    EXPECT_TRUE(out_size_t_typed2  == vectorSize);
+}
 } // opencv_test