Merge pull request #19828 from OrestChura:oc/fix_garray_garray_input
authorOrest Chura <orest.chura@intel.com>
Thu, 1 Apr 2021 20:39:31 +0000 (23:39 +0300)
committerGitHub <noreply@github.com>
Thu, 1 Apr 2021 20:39:31 +0000 (20:39 +0000)
[G-API] Fix bug of GArray<GArray> passing through a graph

* Add test to check GArray<GArray> passing through a graph (assertion failed)

* G-API: Flatten GArray<T> to std::vector<T> when capturing VCtr

- Also: Fix formatting in garray.hpp

* Refactored test, added valuable check

* Initialize size_t

Co-authored-by: Dmitry Matveev <dmitry.matveev@intel.com>
modules/gapi/include/opencv2/gapi/garray.hpp
modules/gapi/test/gapi_array_tests.cpp

index 36e61de2e13094a3969f354fa6897961f337a8d4..32799bc07e15fb0317b371e4f4f8af9b996e0c81 100644 (file)
@@ -246,12 +246,18 @@ namespace detail
 
     public:
         VectorRef() = default;
-        template<typename T> explicit VectorRef(const std::vector<T>& vec) :
-                                            m_ref(new VectorRefT<T>(vec)), m_kind(GOpaqueTraits<T>::kind) {}
-        template<typename T> explicit VectorRef(std::vector<T>& vec)       :
-                                            m_ref(new VectorRefT<T>(vec)), m_kind(GOpaqueTraits<T>::kind) {}
-        template<typename T> explicit VectorRef(std::vector<T>&& vec)      :
-                                            m_ref(new VectorRefT<T>(std::move(vec))), m_kind(GOpaqueTraits<T>::kind) {}
+        template<typename T> explicit VectorRef(const std::vector<T>& vec)
+            : m_ref(new VectorRefT<T>(vec))
+            , m_kind(GOpaqueTraits<T>::kind)
+        {}
+        template<typename T> explicit VectorRef(std::vector<T>& vec)
+            : m_ref(new VectorRefT<T>(vec))
+            , m_kind(GOpaqueTraits<T>::kind)
+        {}
+        template<typename T> explicit VectorRef(std::vector<T>&& vec)
+            : m_ref(new VectorRefT<T>(std::move(vec)))
+            , m_kind(GOpaqueTraits<T>::kind)
+        {}
 
         cv::detail::OpaqueKind getKind() const
         {
@@ -321,9 +327,10 @@ namespace detail
 #  define FLATTEN_NS cv
 #endif
     template<class T> struct flatten_g;
-    template<> struct flatten_g<cv::GMat>    { using type = FLATTEN_NS::Mat; };
-    template<> struct flatten_g<cv::GScalar> { using type = FLATTEN_NS::Scalar; };
-    template<class T> struct flatten_g       { using type = T; };
+    template<> struct flatten_g<cv::GMat>         { using type = FLATTEN_NS::Mat; };
+    template<> struct flatten_g<cv::GScalar>      { using type = FLATTEN_NS::Scalar; };
+    template<class T> struct flatten_g<GArray<T>> { using type = std::vector<T>; };
+    template<class T> struct flatten_g            { using type = T; };
 #undef FLATTEN_NS
     // FIXME: the above mainly duplicates "ProtoToParam" thing from gtyped.hpp
     // but I decided not to include gtyped here - probably worth moving that stuff
index 8bdc0854f007c3d428b13e79195a863c7c5397c7..1ae5261d994ce97dd775df3c991dd02a9e2587f9 100644 (file)
@@ -32,6 +32,10 @@ G_TYPED_KERNEL(PointIncrement, <GPointArray(GMat, GPointArray)>, "test.point_inc
 {
     static GArrayDesc outMeta(const GMatDesc&, const GArrayDesc&) { return empty_array_desc(); }
 };
+G_TYPED_KERNEL(CountContours, <GOpaque<size_t>(GArray<GPointArray>)>, "test.array.array.in")
+{
+    static GOpaqueDesc outMeta(const GArrayDesc&) { return empty_gopaque_desc(); }
+};
 } // namespace ThisTest
 
 namespace
@@ -70,6 +74,14 @@ GAPI_OCV_KERNEL(OCVPointIncrement, ThisTest::PointIncrement)
     }
 };
 
+GAPI_OCV_KERNEL(OCVCountContours, ThisTest::CountContours)
+{
+    static void run(const std::vector<std::vector<cv::Point>> &contours, size_t &out)
+    {
+        out = contours.size();
+    }
+};
+
 cv::Mat cross(int w, int h)
 {
     cv::Mat mat = cv::Mat::eye(h, w, CV_8UC1)*255;
@@ -177,6 +189,24 @@ TEST(GArray, TestIntermediateOutput)
     EXPECT_EQ(10,  out_count[0]);
 }
 
+TEST(GArray, TestGArrayGArrayKernelInput)
+{
+    cv::GMat in;
+    auto contours = cv::gapi::findContours(in, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
+    auto out = ThisTest::CountContours::on(contours);
+    cv::GComputation c(GIn(in), GOut(out));
+
+    // Create input - two filled rectangles
+    cv::Mat in_mat = cv::Mat::zeros(50, 50, CV_8UC1);
+    cv::rectangle(in_mat, cv::Point{5,5},   cv::Point{20,20}, 255, cv::FILLED);
+    cv::rectangle(in_mat, cv::Point{25,25}, cv::Point{40,40}, 255, cv::FILLED);
+
+    size_t out_count = 0u;
+    c.apply(gin(in_mat), gout(out_count), cv::compile_args(cv::gapi::kernels<OCVCountContours>()));
+
+    EXPECT_EQ(2u, out_count) << "Two contours must be found";
+}
+
 TEST(GArray, GArrayConstValInitialization)
 {
     std::vector<cv::Point> initial_vec {Point(0,0), Point(1,1), Point(2,2)};