Merge pull request #17163 from AsyaPronina:gcompound_kernel_gmatp_coop
authorAnastasiya(Asya) Pronina <anastasiya.pronina@intel.com>
Tue, 25 Aug 2020 13:51:43 +0000 (16:51 +0300)
committerGitHub <noreply@github.com>
Tue, 25 Aug 2020 13:51:43 +0000 (13:51 +0000)
* Fixed cooperation of Compound kernel and GMatP type

* Added test for GCompound kernel + GMatP type cooperation

modules/gapi/include/opencv2/gapi/gcompoundkernel.hpp
modules/gapi/src/backends/common/gcompoundkernel.cpp
modules/gapi/test/common/gapi_compoundkernel_tests.cpp

index 2f17064..df0ce34 100644 (file)
@@ -75,6 +75,16 @@ template<typename U> struct get_compound_in<cv::GOpaque<U>>
     }
 };
 
+template<> struct get_compound_in<cv::GMatP>
+{
+    static cv::GMatP get(GCompoundContext &ctx, int idx)
+    {
+        auto mat = cv::GMatP();
+        ctx.m_args[idx] = GArg(mat);
+        return mat;
+    }
+};
+
 template<typename, typename, typename>
 struct GCompoundCallHelper;
 
index 05ed51d..8983a3a 100644 (file)
@@ -32,7 +32,11 @@ cv::detail::GCompoundContext::GCompoundContext(const cv::GArgs& in_args)
             {
                 case GShape::GMAT   : m_args[i] = GArg(GMat());    break;
                 case GShape::GSCALAR: m_args[i] = GArg(GScalar()); break;
-                case GShape::GARRAY :/* do nothing - as handled in a special way, see gcompoundkernel.hpp for details */; break;
+                case GShape::GARRAY :
+                case GShape::GOPAQUE:
+                    // do nothing - as handled in a special way, see gcompoundkernel.hpp for details
+                    // same applies to GMatP
+                    break;
                 default: GAPI_Assert(false);
             }
         }
index f1364e9..523ecb0 100644 (file)
@@ -227,6 +227,73 @@ namespace
         }
     };
 
+    G_TYPED_KERNEL(GToInterleaved, <GMat(GMatP)>, "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, <GMatP(GMat)>, "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<cv::Mat> 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<cv::Mat> inPlanes;
+            cv::split(in, inPlanes);
+            cv::vconcat(inPlanes, out);
+        }
+    };
+
+    G_TYPED_KERNEL(GCompoundToInterleavedToPlanar, <GMatP(GMatP)>,
+                   "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
@@ -497,4 +564,29 @@ TEST(GCompoundKernel, RightGArrayHandle)
     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<GCompoundToInterleavedToPlanarImpl,
+                                       GToInterleavedImpl,
+                                       GToPlanarImpl>();
+
+    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