Merge pull request #18292 from smirnov-alexey:as/osd_serialization
authorAlexey Smirnov <alexey.smirnov@intel.com>
Mon, 21 Sep 2020 19:08:58 +0000 (22:08 +0300)
committerGitHub <noreply@github.com>
Mon, 21 Sep 2020 19:08:58 +0000 (19:08 +0000)
[G-API]: Support render primitives serialization

* Add GOpaque and GArray serialization support

* Address review comments

* Remove holds() method

* Add serialization mechanism for render primitives

* Fix standalone mode

* Fix wchar_t error on win64

* Fix assert on windows

* Address review comments

* Fix GArray and GOpaque reset() method to store proper kind

* Reset wchar before deserializing it

* Fix wchar_t cross-platform issue

* Address review comments

* Fix wchar_t serialization and tests

* Remove FText serialization

modules/gapi/include/opencv2/gapi/garray.hpp
modules/gapi/include/opencv2/gapi/gcommon.hpp
modules/gapi/include/opencv2/gapi/gopaque.hpp
modules/gapi/include/opencv2/gapi/render/render.hpp
modules/gapi/include/opencv2/gapi/render/render_types.hpp [new file with mode: 0644]
modules/gapi/src/backends/common/serialization.cpp
modules/gapi/src/backends/common/serialization.hpp
modules/gapi/test/gapi_array_tests.cpp
modules/gapi/test/gapi_opaque_tests.cpp
modules/gapi/test/s11n/gapi_s11n_tests.cpp
modules/gapi/test/s11n/gapi_sample_pipelines_s11n.cpp

index d87ec8c..9118f4d 100644 (file)
@@ -261,8 +261,8 @@ namespace detail
         template<typename T> void reset()
         {
             if (!m_ref) m_ref.reset(new VectorRefT<T>());
-
             check<T>();
+            storeKind<T>();
             static_cast<VectorRefT<T>&>(*m_ref).reset();
         }
 
index 06499c1..27b154b 100644 (file)
@@ -18,6 +18,7 @@
 #include <opencv2/gapi/util/optional.hpp>
 #include <opencv2/gapi/own/exports.hpp>
 #include <opencv2/gapi/own/assert.hpp>
+#include <opencv2/gapi/render/render_types.hpp>
 
 namespace cv {
 
@@ -48,6 +49,7 @@ namespace detail
         CV_RECT,       // cv::Rect user G-API data
         CV_SCALAR,     // cv::Scalar user G-API data
         CV_MAT,        // cv::Mat user G-API data
+        CV_PRIM,       // cv::gapi::wip::draw::Prim user G-API data
     };
 
     // Type traits helper which simplifies the extraction of kind from type
@@ -62,10 +64,12 @@ namespace detail
     template<> struct GOpaqueTraits<cv::Mat>     { static constexpr const OpaqueKind kind = OpaqueKind::CV_MAT; };
     template<> struct GOpaqueTraits<cv::Rect>    { static constexpr const OpaqueKind kind = OpaqueKind::CV_RECT; };
     template<> struct GOpaqueTraits<cv::GMat>    { static constexpr const OpaqueKind kind = OpaqueKind::CV_MAT; };
+    template<> struct GOpaqueTraits<cv::gapi::wip::draw::Prim>
+                                                 { static constexpr const OpaqueKind kind = OpaqueKind::CV_PRIM; };
     // GArray is not supporting bool type for now due to difference in std::vector<bool> implementation
-    using GOpaqueTraitsArrayTypes = std::tuple<int, double, cv::Size, cv::Scalar, cv::Point, cv::Mat, cv::Rect>;
+    using GOpaqueTraitsArrayTypes = std::tuple<int, double, cv::Size, cv::Scalar, cv::Point, cv::Mat, cv::Rect, cv::gapi::wip::draw::Prim>;
     // GOpaque is not supporting cv::Mat and cv::Scalar since there are GScalar and GMat types
-    using GOpaqueTraitsOpaqueTypes = std::tuple<bool, int, double, cv::Size, cv::Point, cv::Rect>;
+    using GOpaqueTraitsOpaqueTypes = std::tuple<bool, int, double, cv::Size, cv::Point, cv::Rect, cv::gapi::wip::draw::Prim>;
 } // namespace detail
 
 // This definition is here because it is reused by both public(?) and internal
index 9cfd588..1c45d46 100644 (file)
@@ -250,8 +250,8 @@ namespace detail
         template<typename T> void reset()
         {
             if (!m_ref) m_ref.reset(new OpaqueRefT<T>());
-
             check<T>();
+            storeKind<T>();
             static_cast<OpaqueRefT<T>&>(*m_ref).reset();
         }
 
index fcb69cb..a4df304 100644 (file)
@@ -2,23 +2,16 @@
 // 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_RENDER_HPP
 #define OPENCV_GAPI_RENDER_HPP
 
-#include <string>
-#include <vector>
+#include <opencv2/gapi/render/render_types.hpp>
 
-#include <opencv2/imgproc.hpp>
 #include <opencv2/gapi.hpp>
 
-#include <opencv2/gapi/opencv_includes.hpp>
-#include <opencv2/gapi/util/variant.hpp>
-#include <opencv2/gapi/own/exports.hpp>
-
-
 /** \defgroup gapi_draw G-API Drawing and composition functionality
  *  @{
  *
@@ -77,309 +70,9 @@ namespace wip
 namespace draw
 {
 
-/**
- * @brief This structure specifies which FreeType font to use by FText primitives.
- */
-struct freetype_font
-{
-    /*@{*/
-    std::string path; //!< The path to the font file (.ttf)
-    /*@{*/
-};
-
-//! @addtogroup gapi_draw_prims
-//! @{
-/**
- * @brief This structure represents a text string to draw.
- *
- * Parameters match cv::putText().
- */
-struct Text
-{
-    /**
-     * @brief Text constructor
-     *
-     * @param text_               The text string to be drawn
-     * @param org_                The bottom-left corner of the text string in the image
-     * @param ff_                 The font type, see #HersheyFonts
-     * @param fs_                 The font scale factor that is multiplied by the font-specific base size
-     * @param color_              The text color
-     * @param thick_              The thickness of the lines used to draw a text
-     * @param lt_                 The line type. See #LineTypes
-     * @param bottom_left_origin_ When true, the image data origin is at the bottom-left corner. Otherwise, it is at the top-left corner
-     */
-    Text(const std::string& text_,
-         const cv::Point& org_,
-         int ff_,
-         double fs_,
-         const cv::Scalar& color_,
-         int thick_ = 1,
-         int lt_ = cv::LINE_8,
-         bool bottom_left_origin_ = false) :
-        text(text_), org(org_), ff(ff_), fs(fs_),
-        color(color_), thick(thick_), lt(lt_), bottom_left_origin(bottom_left_origin_)
-    {
-    }
-
-    /*@{*/
-    std::string text;               //!< The text string to be drawn
-    cv::Point   org;                //!< The bottom-left corner of the text string in the image
-    int         ff;                 //!< The font type, see #HersheyFonts
-    double      fs;                 //!< The font scale factor that is multiplied by the font-specific base size
-    cv::Scalar  color;              //!< The text color
-    int         thick;              //!< The thickness of the lines used to draw a text
-    int         lt;                 //!< The line type. See #LineTypes
-    bool        bottom_left_origin; //!< When true, the image data origin is at the bottom-left corner. Otherwise, it is at the top-left corner
-    /*@{*/
-};
-
-/**
- * @brief This structure represents a text string to draw using
- * FreeType renderer.
- *
- * If OpenCV is built without FreeType support, this primitive will
- * fail at the execution stage.
- */
-struct FText
-{
-    /**
-     * @brief FText constructor
-     *
-     * @param text_ The text string to be drawn
-     * @param org_  The bottom-left corner of the text string in the image
-     * @param fh_   The height of text
-     * @param color_ The text color
-     */
-    FText(const std::wstring& text_,
-          const cv::Point& org_,
-          int fh_,
-          const cv::Scalar& color_) :
-        text(text_), org(org_), fh(fh_), color(color_)
-    {
-    }
-
-    /*@{*/
-    std::wstring text;              //!< The text string to be drawn
-    cv::Point    org;               //!< The bottom-left corner of the text string in the image
-    int          fh;                //!< The height of text
-    cv::Scalar   color;             //!< The text color
-    /*@{*/
-};
-
-/**
- * @brief This structure represents a rectangle to draw.
- *
- * Parameters match cv::rectangle().
- */
-struct Rect
-{
-    /**
-     * @brief Rect constructor
-     *
-     * @param rect_   Coordinates of the rectangle
-     * @param color_  The bottom-left corner of the text string in the image
-     * @param thick_  The thickness of lines that make up the rectangle. Negative values, like #FILLED, mean that the function has to draw a filled rectangle
-     * @param lt_     The type of the line. See #LineTypes
-     * @param shift_  The number of fractional bits in the point coordinates
-     */
-    Rect(const cv::Rect& rect_,
-         const cv::Scalar& color_,
-         int thick_ = 1,
-         int lt_ = cv::LINE_8,
-         int shift_ = 0) :
-        rect(rect_), color(color_), thick(thick_), lt(lt_), shift(shift_)
-    {
-    }
-
-    /*@{*/
-    cv::Rect   rect;  //!< Coordinates of the rectangle
-    cv::Scalar color; //!< The rectangle color or brightness (grayscale image)
-    int        thick; //!< The thickness of lines that make up the rectangle. Negative values, like #FILLED, mean that the function has to draw a filled rectangle
-    int        lt;    //!< The type of the line. See #LineTypes
-    int        shift; //!< The number of fractional bits in the point coordinates
-    /*@{*/
-};
-
-/**
- * @brief This structure represents a circle to draw.
- *
- * Parameters match cv::circle().
- */
-struct Circle
-{
-    /**
-     * @brief Circle constructor
-     *
-     * @param  center_ The center of the circle
-     * @param  radius_ The radius of the circle
-     * @param  color_  The color of the  circle
-     * @param  thick_  The thickness of the circle outline, if positive. Negative values, like #FILLED, mean that a filled circle is to be drawn
-     * @param  lt_     The Type of the circle boundary. See #LineTypes
-     * @param  shift_  The Number of fractional bits in the coordinates of the center and in the radius value
-     */
-    Circle(const cv::Point& center_,
-           int radius_,
-           const cv::Scalar& color_,
-           int thick_ = 1,
-           int lt_ = cv::LINE_8,
-           int shift_ = 0) :
-        center(center_), radius(radius_), color(color_), thick(thick_), lt(lt_), shift(shift_)
-    {
-    }
-
-    /*@{*/
-    cv::Point  center; //!< The center of the circle
-    int        radius; //!< The radius of the circle
-    cv::Scalar color;  //!< The color of the  circle
-    int        thick;  //!< The thickness of the circle outline, if positive. Negative values, like #FILLED, mean that a filled circle is to be drawn
-    int        lt;     //!< The Type of the circle boundary. See #LineTypes
-    int        shift;  //!< The Number of fractional bits in the coordinates of the center and in the radius value
-    /*@{*/
-};
-
-/**
- * @brief This structure represents a line to draw.
- *
- * Parameters match cv::line().
- */
-struct Line
-{
-    /**
-     * @brief Line constructor
-     *
-     * @param  pt1_    The first point of the line segment
-     * @param  pt2_    The second point of the line segment
-     * @param  color_  The line color
-     * @param  thick_  The thickness of line
-     * @param  lt_     The Type of the line. See #LineTypes
-     * @param  shift_  The number of fractional bits in the point coordinates
-    */
-    Line(const cv::Point& pt1_,
-         const cv::Point& pt2_,
-         const cv::Scalar& color_,
-         int thick_ = 1,
-         int lt_ = cv::LINE_8,
-         int shift_ = 0) :
-        pt1(pt1_), pt2(pt2_), color(color_), thick(thick_), lt(lt_), shift(shift_)
-    {
-    }
-
-    /*@{*/
-    cv::Point  pt1;    //!< The first point of the line segment
-    cv::Point  pt2;    //!< The second point of the line segment
-    cv::Scalar color;  //!< The line color
-    int        thick;  //!< The thickness of line
-    int        lt;     //!< The Type of the line. See #LineTypes
-    int        shift;  //!< The number of fractional bits in the point coordinates
-    /*@{*/
-};
-
-/**
- * @brief This structure represents a mosaicing operation.
- *
- * Mosaicing is a very basic method to obfuscate regions in the image.
- */
-struct Mosaic
-{
-    /**
-     * @brief Mosaic constructor
-     *
-     * @param mos_    Coordinates of the mosaic
-     * @param cellSz_ Cell size (same for X, Y)
-     * @param decim_  Decimation (0 stands for no decimation)
-    */
-    Mosaic(const cv::Rect& mos_,
-           int cellSz_,
-           int decim_) :
-        mos(mos_), cellSz(cellSz_), decim(decim_)
-    {
-    }
-
-    /*@{*/
-    cv::Rect   mos;    //!< Coordinates of the mosaic
-    int        cellSz; //!< Cell size (same for X, Y)
-    int        decim;  //!< Decimation (0 stands for no decimation)
-    /*@{*/
-};
-
-/**
- * @brief This structure represents an image to draw.
- *
- * Image is blended on a frame using the specified mask.
- */
-struct Image
-{
-    /**
-     * @brief Mosaic constructor
-     *
-     * @param  org_   The bottom-left corner of the image
-     * @param  img_   Image to draw
-     * @param  alpha_ Alpha channel for image to draw (same size and number of channels)
-    */
-    Image(const cv::Point& org_,
-          const cv::Mat& img_,
-          const cv::Mat& alpha_) :
-        org(org_), img(img_), alpha(alpha_)
-    {
-    }
-
-    /*@{*/
-    cv::Point org;   //!< The bottom-left corner of the image
-    cv::Mat   img;   //!< Image to draw
-    cv::Mat   alpha; //!< Alpha channel for image to draw (same size and number of channels)
-    /*@{*/
-};
-
-/**
- * @brief This structure represents a polygon to draw.
- */
-struct Poly
-{
-    /**
-     * @brief Mosaic constructor
-     *
-     * @param points_ Points to connect
-     * @param color_  The line color
-     * @param thick_  The thickness of line
-     * @param lt_     The Type of the line. See #LineTypes
-     * @param shift_  The number of fractional bits in the point coordinate
-    */
-    Poly(const std::vector<cv::Point>& points_,
-         const cv::Scalar& color_,
-         int thick_ = 1,
-         int lt_ = cv::LINE_8,
-         int shift_ = 0) :
-        points(points_), color(color_), thick(thick_), lt(lt_), shift(shift_)
-    {
-    }
-
-    /*@{*/
-    std::vector<cv::Point> points;  //!< Points to connect
-    cv::Scalar             color;   //!< The line color
-    int                    thick;   //!< The thickness of line
-    int                    lt;      //!< The Type of the line. See #LineTypes
-    int                    shift;   //!< The number of fractional bits in the point coordinate
-    /*@{*/
-};
-
-using Prim  = util::variant
-    < Text
-    , FText
-    , Rect
-    , Circle
-    , Line
-    , Mosaic
-    , Image
-    , Poly
-    >;
-
-using Prims     = std::vector<Prim>;
-//! @} gapi_draw_prims
-
 using GMat2     = std::tuple<cv::GMat,cv::GMat>;
 using GMatDesc2 = std::tuple<cv::GMatDesc,cv::GMatDesc>;
 
-
 //! @addtogroup gapi_draw_api
 //! @{
 /** @brief The function renders on the input image passed drawing primitivies
diff --git a/modules/gapi/include/opencv2/gapi/render/render_types.hpp b/modules/gapi/include/opencv2/gapi/render/render_types.hpp
new file mode 100644 (file)
index 0000000..08b14d1
--- /dev/null
@@ -0,0 +1,347 @@
+// This file is part of OpenCV project.
+// 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) 2020 Intel Corporation
+
+
+#ifndef OPENCV_GAPI_RENDER_TYPES_HPP
+#define OPENCV_GAPI_RENDER_TYPES_HPP
+
+#include <string>
+#include <vector>
+
+#include <opencv2/gapi/opencv_includes.hpp>
+#include <opencv2/gapi/util/variant.hpp>
+#include <opencv2/gapi/own/exports.hpp>
+
+namespace cv
+{
+namespace gapi
+{
+namespace wip
+{
+namespace draw
+{
+
+/**
+ * @brief This structure specifies which FreeType font to use by FText primitives.
+ */
+struct freetype_font
+{
+    /*@{*/
+    std::string path; //!< The path to the font file (.ttf)
+    /*@{*/
+};
+
+//! @addtogroup gapi_draw_prims
+//! @{
+/**
+ * @brief This structure represents a text string to draw.
+ *
+ * Parameters match cv::putText().
+ */
+struct Text
+{
+    /**
+     * @brief Text constructor
+     *
+     * @param text_               The text string to be drawn
+     * @param org_                The bottom-left corner of the text string in the image
+     * @param ff_                 The font type, see #HersheyFonts
+     * @param fs_                 The font scale factor that is multiplied by the font-specific base size
+     * @param color_              The text color
+     * @param thick_              The thickness of the lines used to draw a text
+     * @param lt_                 The line type. See #LineTypes
+     * @param bottom_left_origin_ When true, the image data origin is at the bottom-left corner. Otherwise, it is at the top-left corner
+     */
+    Text(const std::string& text_,
+         const cv::Point& org_,
+         int ff_,
+         double fs_,
+         const cv::Scalar& color_,
+         int thick_ = 1,
+         int lt_ = 8,
+         bool bottom_left_origin_ = false) :
+        text(text_), org(org_), ff(ff_), fs(fs_),
+        color(color_), thick(thick_), lt(lt_), bottom_left_origin(bottom_left_origin_)
+    {
+    }
+
+    Text() = default;
+
+    /*@{*/
+    std::string text;               //!< The text string to be drawn
+    cv::Point   org;                //!< The bottom-left corner of the text string in the image
+    int         ff;                 //!< The font type, see #HersheyFonts
+    double      fs;                 //!< The font scale factor that is multiplied by the font-specific base size
+    cv::Scalar  color;              //!< The text color
+    int         thick;              //!< The thickness of the lines used to draw a text
+    int         lt;                 //!< The line type. See #LineTypes
+    bool        bottom_left_origin; //!< When true, the image data origin is at the bottom-left corner. Otherwise, it is at the top-left corner
+    /*@{*/
+};
+
+/**
+ * @brief This structure represents a text string to draw using
+ * FreeType renderer.
+ *
+ * If OpenCV is built without FreeType support, this primitive will
+ * fail at the execution stage.
+ */
+struct FText
+{
+    /**
+     * @brief FText constructor
+     *
+     * @param text_ The text string to be drawn
+     * @param org_  The bottom-left corner of the text string in the image
+     * @param fh_   The height of text
+     * @param color_ The text color
+     */
+    FText(const std::wstring& text_,
+          const cv::Point& org_,
+          int fh_,
+          const cv::Scalar& color_) :
+        text(text_), org(org_), fh(fh_), color(color_)
+    {
+    }
+
+    FText() = default;
+
+    /*@{*/
+    std::wstring text;              //!< The text string to be drawn
+    cv::Point    org;               //!< The bottom-left corner of the text string in the image
+    int          fh;                //!< The height of text
+    cv::Scalar   color;             //!< The text color
+    /*@{*/
+};
+
+/**
+ * @brief This structure represents a rectangle to draw.
+ *
+ * Parameters match cv::rectangle().
+ */
+struct Rect
+{
+    /**
+     * @brief Rect constructor
+     *
+     * @param rect_   Coordinates of the rectangle
+     * @param color_  The bottom-left corner of the text string in the image
+     * @param thick_  The thickness of lines that make up the rectangle. Negative values, like #FILLED, mean that the function has to draw a filled rectangle
+     * @param lt_     The type of the line. See #LineTypes
+     * @param shift_  The number of fractional bits in the point coordinates
+     */
+    Rect(const cv::Rect& rect_,
+         const cv::Scalar& color_,
+         int thick_ = 1,
+         int lt_ = 8,
+         int shift_ = 0) :
+        rect(rect_), color(color_), thick(thick_), lt(lt_), shift(shift_)
+    {
+    }
+
+    Rect() = default;
+
+    /*@{*/
+    cv::Rect   rect;  //!< Coordinates of the rectangle
+    cv::Scalar color; //!< The rectangle color or brightness (grayscale image)
+    int        thick; //!< The thickness of lines that make up the rectangle. Negative values, like #FILLED, mean that the function has to draw a filled rectangle
+    int        lt;    //!< The type of the line. See #LineTypes
+    int        shift; //!< The number of fractional bits in the point coordinates
+    /*@{*/
+};
+
+/**
+ * @brief This structure represents a circle to draw.
+ *
+ * Parameters match cv::circle().
+ */
+struct Circle
+{
+    /**
+     * @brief Circle constructor
+     *
+     * @param  center_ The center of the circle
+     * @param  radius_ The radius of the circle
+     * @param  color_  The color of the  circle
+     * @param  thick_  The thickness of the circle outline, if positive. Negative values, like #FILLED, mean that a filled circle is to be drawn
+     * @param  lt_     The Type of the circle boundary. See #LineTypes
+     * @param  shift_  The Number of fractional bits in the coordinates of the center and in the radius value
+     */
+    Circle(const cv::Point& center_,
+           int radius_,
+           const cv::Scalar& color_,
+           int thick_ = 1,
+           int lt_ = 8,
+           int shift_ = 0) :
+        center(center_), radius(radius_), color(color_), thick(thick_), lt(lt_), shift(shift_)
+    {
+    }
+
+    Circle() = default;
+
+    /*@{*/
+    cv::Point  center; //!< The center of the circle
+    int        radius; //!< The radius of the circle
+    cv::Scalar color;  //!< The color of the  circle
+    int        thick;  //!< The thickness of the circle outline, if positive. Negative values, like #FILLED, mean that a filled circle is to be drawn
+    int        lt;     //!< The Type of the circle boundary. See #LineTypes
+    int        shift;  //!< The Number of fractional bits in the coordinates of the center and in the radius value
+    /*@{*/
+};
+
+/**
+ * @brief This structure represents a line to draw.
+ *
+ * Parameters match cv::line().
+ */
+struct Line
+{
+    /**
+     * @brief Line constructor
+     *
+     * @param  pt1_    The first point of the line segment
+     * @param  pt2_    The second point of the line segment
+     * @param  color_  The line color
+     * @param  thick_  The thickness of line
+     * @param  lt_     The Type of the line. See #LineTypes
+     * @param  shift_  The number of fractional bits in the point coordinates
+    */
+    Line(const cv::Point& pt1_,
+         const cv::Point& pt2_,
+         const cv::Scalar& color_,
+         int thick_ = 1,
+         int lt_ = 8,
+         int shift_ = 0) :
+        pt1(pt1_), pt2(pt2_), color(color_), thick(thick_), lt(lt_), shift(shift_)
+    {
+    }
+
+    Line() = default;
+
+    /*@{*/
+    cv::Point  pt1;    //!< The first point of the line segment
+    cv::Point  pt2;    //!< The second point of the line segment
+    cv::Scalar color;  //!< The line color
+    int        thick;  //!< The thickness of line
+    int        lt;     //!< The Type of the line. See #LineTypes
+    int        shift;  //!< The number of fractional bits in the point coordinates
+    /*@{*/
+};
+
+/**
+ * @brief This structure represents a mosaicing operation.
+ *
+ * Mosaicing is a very basic method to obfuscate regions in the image.
+ */
+struct Mosaic
+{
+    /**
+     * @brief Mosaic constructor
+     *
+     * @param mos_    Coordinates of the mosaic
+     * @param cellSz_ Cell size (same for X, Y)
+     * @param decim_  Decimation (0 stands for no decimation)
+    */
+    Mosaic(const cv::Rect& mos_,
+           int cellSz_,
+           int decim_) :
+        mos(mos_), cellSz(cellSz_), decim(decim_)
+    {
+    }
+
+    Mosaic() = default;
+
+    /*@{*/
+    cv::Rect   mos;    //!< Coordinates of the mosaic
+    int        cellSz; //!< Cell size (same for X, Y)
+    int        decim;  //!< Decimation (0 stands for no decimation)
+    /*@{*/
+};
+
+/**
+ * @brief This structure represents an image to draw.
+ *
+ * Image is blended on a frame using the specified mask.
+ */
+struct Image
+{
+    /**
+     * @brief Mosaic constructor
+     *
+     * @param  org_   The bottom-left corner of the image
+     * @param  img_   Image to draw
+     * @param  alpha_ Alpha channel for image to draw (same size and number of channels)
+    */
+    Image(const cv::Point& org_,
+          const cv::Mat& img_,
+          const cv::Mat& alpha_) :
+        org(org_), img(img_), alpha(alpha_)
+    {
+    }
+
+    Image() = default;
+
+    /*@{*/
+    cv::Point org;   //!< The bottom-left corner of the image
+    cv::Mat   img;   //!< Image to draw
+    cv::Mat   alpha; //!< Alpha channel for image to draw (same size and number of channels)
+    /*@{*/
+};
+
+/**
+ * @brief This structure represents a polygon to draw.
+ */
+struct Poly
+{
+    /**
+     * @brief Mosaic constructor
+     *
+     * @param points_ Points to connect
+     * @param color_  The line color
+     * @param thick_  The thickness of line
+     * @param lt_     The Type of the line. See #LineTypes
+     * @param shift_  The number of fractional bits in the point coordinate
+    */
+    Poly(const std::vector<cv::Point>& points_,
+         const cv::Scalar& color_,
+         int thick_ = 1,
+         int lt_ = 8,
+         int shift_ = 0) :
+        points(points_), color(color_), thick(thick_), lt(lt_), shift(shift_)
+    {
+    }
+
+    Poly() = default;
+
+    /*@{*/
+    std::vector<cv::Point> points;  //!< Points to connect
+    cv::Scalar             color;   //!< The line color
+    int                    thick;   //!< The thickness of line
+    int                    lt;      //!< The Type of the line. See #LineTypes
+    int                    shift;   //!< The number of fractional bits in the point coordinate
+    /*@{*/
+};
+
+using Prim  = util::variant
+    < Text
+    , FText
+    , Rect
+    , Circle
+    , Line
+    , Mosaic
+    , Image
+    , Poly
+    >;
+
+using Prims     = std::vector<Prim>;
+//! @} gapi_draw_prims
+
+} // namespace draw
+} // namespace wip
+} // namespace gapi
+} // namespace cv
+
+#endif // OPENCV_GAPI_RENDER_TYPES_HPP
index ea97f17..ab7626d 100644 (file)
@@ -252,6 +252,62 @@ I::IStream& operator>> (I::IStream& is, cv::Mat& m) {
     return is;
 }
 
+I::OStream& operator<< (I::OStream& os, const cv::gapi::wip::draw::Text &t) {
+    return os << t.bottom_left_origin << t.color << t.ff << t.fs << t.lt << t.org << t.text << t.thick;
+}
+I::IStream& operator>> (I::IStream& is,       cv::gapi::wip::draw::Text &t) {
+    return is >> t.bottom_left_origin >> t.color >> t.ff >> t.fs >> t.lt >> t.org >> t.text >> t.thick;
+}
+
+I::OStream& operator<< (I::OStream&, const cv::gapi::wip::draw::FText &) {
+    GAPI_Assert(false && "Serialization: Unsupported << for FText");
+}
+I::IStream& operator>> (I::IStream&,       cv::gapi::wip::draw::FText &) {
+    GAPI_Assert(false && "Serialization: Unsupported >> for FText");
+}
+
+I::OStream& operator<< (I::OStream& os, const cv::gapi::wip::draw::Circle &c) {
+    return os << c.center << c.color << c.lt << c.radius << c.shift << c.thick;
+}
+I::IStream& operator>> (I::IStream& is,       cv::gapi::wip::draw::Circle &c) {
+    return is >> c.center >> c.color >> c.lt >> c.radius >> c.shift >> c.thick;
+}
+
+I::OStream& operator<< (I::OStream& os, const cv::gapi::wip::draw::Rect &r) {
+    return os << r.color << r.lt << r.rect << r.shift << r.thick;
+}
+I::IStream& operator>> (I::IStream& is,       cv::gapi::wip::draw::Rect &r) {
+    return is >> r.color >> r.lt >> r.rect >> r.shift >> r.thick;
+}
+
+I::OStream& operator<< (I::OStream& os, const cv::gapi::wip::draw::Image &i) {
+    return os << i.org << i.alpha << i.img;
+}
+I::IStream& operator>> (I::IStream& is,       cv::gapi::wip::draw::Image &i) {
+    return is >> i.org >> i.alpha >> i.img;
+}
+
+I::OStream& operator<< (I::OStream& os, const cv::gapi::wip::draw::Mosaic &m) {
+    return os << m.cellSz << m.decim << m.mos;
+}
+I::IStream& operator>> (I::IStream& is,       cv::gapi::wip::draw::Mosaic &m) {
+    return is >> m.cellSz >> m.decim >> m.mos;
+}
+
+I::OStream& operator<< (I::OStream& os, const cv::gapi::wip::draw::Poly &p) {
+    return os << p.color << p.lt << p.points << p.shift << p.thick;
+}
+I::IStream& operator>> (I::IStream& is,       cv::gapi::wip::draw::Poly &p) {
+    return is >> p.color >> p.lt >> p.points >> p.shift >> p.thick;
+}
+
+I::OStream& operator<< (I::OStream& os, const cv::gapi::wip::draw::Line &l) {
+    return os << l.color << l.lt << l.pt1 << l.pt2 << l.shift << l.thick;
+}
+I::IStream& operator>> (I::IStream& is,       cv::gapi::wip::draw::Line &l) {
+    return is >> l.color >> l.lt >> l.pt1 >> l.pt2 >> l.shift >> l.thick;
+}
+
 // G-API types /////////////////////////////////////////////////////////////////
 
 // Stubs (empty types)
index 90169f6..9286bc4 100644 (file)
@@ -14,6 +14,7 @@
 #include <ade/util/iota_range.hpp> // used in the vector<</>>
 
 #include "compiler/gmodel.hpp"
+#include "opencv2/gapi/render/render_types.hpp"
 
 #if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
 #pragma warning(disable: 4702)
@@ -89,7 +90,29 @@ GAPI_EXPORTS I::IStream& operator>> (I::IStream& is,       cv::Scalar &s);
 GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, const cv::Mat &m);
 GAPI_EXPORTS I::IStream& operator>> (I::IStream& is,       cv::Mat &m);
 
+GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, const cv::gapi::wip::draw::Text &t);
+GAPI_EXPORTS I::IStream& operator>> (I::IStream& is,       cv::gapi::wip::draw::Text &t);
 
+GAPI_EXPORTS I::OStream& operator<< (I::OStream&, const cv::gapi::wip::draw::FText &);
+GAPI_EXPORTS I::IStream& operator>> (I::IStream&,       cv::gapi::wip::draw::FText &);
+
+GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, const cv::gapi::wip::draw::Circle &c);
+GAPI_EXPORTS I::IStream& operator>> (I::IStream& is,       cv::gapi::wip::draw::Circle &c);
+
+GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, const cv::gapi::wip::draw::Rect &r);
+GAPI_EXPORTS I::IStream& operator>> (I::IStream& is,       cv::gapi::wip::draw::Rect &r);
+
+GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, const cv::gapi::wip::draw::Image &i);
+GAPI_EXPORTS I::IStream& operator>> (I::IStream& is,       cv::gapi::wip::draw::Image &i);
+
+GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, const cv::gapi::wip::draw::Mosaic &m);
+GAPI_EXPORTS I::IStream& operator>> (I::IStream& is,       cv::gapi::wip::draw::Mosaic &m);
+
+GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, const cv::gapi::wip::draw::Poly &p);
+GAPI_EXPORTS I::IStream& operator>> (I::IStream& is,       cv::gapi::wip::draw::Poly &p);
+
+GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, const cv::gapi::wip::draw::Line &l);
+GAPI_EXPORTS I::IStream& operator>> (I::IStream& is,       cv::gapi::wip::draw::Line &l);
 
 // G-API types /////////////////////////////////////////////////////////////////
 
index 74a531c..2faf538 100644 (file)
@@ -274,4 +274,13 @@ TEST(GArray_VectorRef, TestRvalue)
     auto v = std::vector<int>{3, 5, -4};
     EXPECT_EQ(vref.rref<int>(), v);
 }
+
+TEST(GArray_VectorRef, TestReset)
+{
+    // Warning: this test is testing some not-very-public APIs
+    cv::detail::VectorRef vref(std::vector<int>{3, 5, -4});
+    EXPECT_EQ(cv::detail::OpaqueKind::CV_INT, vref.getKind());
+    vref.reset<int>();
+    EXPECT_EQ(cv::detail::OpaqueKind::CV_INT, vref.getKind());
+}
 } // namespace opencv_test
index 6a5cb1a..c76c97a 100644 (file)
@@ -235,4 +235,13 @@ TEST(GOpaque_OpaqueRef, Kind)
     cv::detail::OpaqueRef v8(std::string{});
     EXPECT_EQ(cv::detail::OpaqueKind::CV_UNKNOWN, v8.getKind());
 }
+
+TEST(GOpaque_OpaqueRef, TestReset)
+{
+    // Warning: this test is testing some not-very-public APIs
+    cv::detail::OpaqueRef opref(int{42});
+    EXPECT_EQ(cv::detail::OpaqueKind::CV_INT, opref.getKind());
+    opref.reset<int>();
+    EXPECT_EQ(cv::detail::OpaqueKind::CV_INT, opref.getKind());
+}
 } // namespace opencv_test
index 561fcb2..5b5be99 100644 (file)
@@ -348,5 +348,4 @@ TEST_F(S11N_Basic, Test_Bind_RunArgs_MatScalar) {
         i++;
     }
 }
-
 } // namespace opencv_test
index 930d996..1d8f751 100644 (file)
@@ -8,8 +8,9 @@
 #include "../test_precomp.hpp"
 
 #include <ade/util/iota_range.hpp>
-
 #include <opencv2/gapi/s11n.hpp>
+#include "api/render_priv.hpp"
+#include "../common/gapi_render_tests.hpp"
 
 namespace opencv_test
 {
@@ -484,4 +485,226 @@ TEST(S11N, Pipeline_GArray_GOpaque_Multinode)
     }
 }
 
+TEST(S11N, Pipeline_Render_NV12)
+{
+    cv::Size sz (100, 200);
+    int rects_num = 10;
+    int text_num  = 10;
+    int image_num = 10;
+
+    int thick = 2;
+    int lt = LINE_8;
+    cv::Scalar color(111, 222, 77);
+
+    // G-API code //////////////////////////////////////////////////////////////
+    cv::gapi::wip::draw::Prims prims;
+
+    // Rects
+    int shift = 0;
+    for (int i = 0; i < rects_num; ++i) {
+        cv::Rect rect(200 + i, 200 + i, 200, 200);
+        prims.emplace_back(cv::gapi::wip::draw::Rect(rect, color, thick, lt, shift));
+    }
+
+    // Mosaic
+    int cellsz = 50;
+    int decim = 0;
+    for (int i = 0; i < rects_num; ++i) {
+        cv::Rect mos(200 + i, 200 + i, 200, 200);
+        prims.emplace_back(cv::gapi::wip::draw::Mosaic(mos, cellsz, decim));
+    }
+
+    // Text
+    std::string text = "Some text";
+    int ff = FONT_HERSHEY_SIMPLEX;
+    double fs = 2.0;
+    bool blo = false;
+    for (int i = 0; i < text_num; ++i) {
+        cv::Point org(200 + i, 200 + i);
+        prims.emplace_back(cv::gapi::wip::draw::Text(text, org, ff, fs, color, thick, lt, blo));
+    }
+
+    // Image
+    double transparency = 1.0;
+    cv::Rect rect_img(0 ,0 , 50, 50);
+    cv::Mat img(rect_img.size(), CV_8UC3, color);
+    cv::Mat alpha(rect_img.size(), CV_32FC1, transparency);
+    auto tl = rect_img.tl();
+    for (int i = 0; i < image_num; ++i) {
+        cv::Point org_img = {tl.x + i, tl.y + rect_img.size().height + i};
+
+        prims.emplace_back(cv::gapi::wip::draw::Image({org_img, img, alpha}));
+    }
+
+    // Circle
+    cv::Point center(300, 400);
+    int rad = 25;
+    prims.emplace_back(cv::gapi::wip::draw::Circle({center, rad, color, thick, lt, shift}));
+
+    // Line
+    cv::Point point_next(300, 425);
+    prims.emplace_back(cv::gapi::wip::draw::Line({center, point_next, color, thick, lt, shift}));
+
+    // Poly
+    std::vector<cv::Point> points = {{300, 400}, {290, 450}, {348, 410}, {300, 400}};
+    prims.emplace_back(cv::gapi::wip::draw::Poly({points, color, thick, lt, shift}));
+
+    cv::GMat y_in, uv_in, y_out, uv_out;
+    cv::GArray<cv::gapi::wip::draw::Prim> arr;
+    std::tie(y_out, uv_out) = cv::gapi::wip::draw::renderNV12(y_in, uv_in, arr);
+    cv::GComputation comp(cv::GIn(y_in, uv_in, arr), cv::GOut(y_out, uv_out));
+
+    auto serialized = cv::gapi::serialize(comp);
+    auto dc = cv::gapi::deserialize<cv::GComputation>(serialized);
+
+    cv::Mat y(1920, 1080, CV_8UC1);
+    cv::Mat uv(960, 540, CV_8UC2);
+    cv::randu(y, cv::Scalar(0), cv::Scalar(255));
+    cv::randu(uv, cv::Scalar::all(0), cv::Scalar::all(255));
+    cv::Mat y_ref_mat = y.clone(), uv_ref_mat = uv.clone();
+    dc.apply(cv::gin(y, uv, prims), cv::gout(y, uv));
+
+    // OpenCV code //////////////////////////////////////////////////////////////
+    cv::Mat yuv;
+    cv::gapi::wip::draw::cvtNV12ToYUV(y_ref_mat, uv_ref_mat, yuv);
+
+    for (int i = 0; i < rects_num; ++i) {
+        cv::Rect rect(200 + i, 200 + i, 200, 200);
+        cv::rectangle(yuv, rect, cvtBGRToYUVC(color), thick, lt, shift);
+    }
+
+    for (int i = 0; i < rects_num; ++i) {
+        cv::Rect mos(200 + i, 200 + i, 200, 200);
+         drawMosaicRef(yuv, mos, cellsz);
+    }
+
+    for (int i = 0; i < text_num; ++i) {
+        cv::Point org(200 + i, 200 + i);
+        cv::putText(yuv, text, org, ff, fs, cvtBGRToYUVC(color), thick, lt, blo);
+    }
+
+    for (int i = 0; i < image_num; ++i) {
+        cv::Point org_img = {tl.x + i, tl.y + rect_img.size().height + i};
+        cv::Mat yuv_img;
+        cv::cvtColor(img, yuv_img, cv::COLOR_BGR2YUV);
+        blendImageRef(yuv, org_img, yuv_img, alpha);
+    }
+
+    cv::circle(yuv, center, rad, cvtBGRToYUVC(color), thick, lt, shift);
+    cv::line(yuv, center, point_next, cvtBGRToYUVC(color), thick, lt, shift);
+    std::vector<std::vector<cv::Point>> pp{points};
+    cv::fillPoly(yuv, pp, cvtBGRToYUVC(color), lt, shift);
+
+    // YUV -> NV12
+    cv::gapi::wip::draw::cvtYUVToNV12(yuv, y_ref_mat, uv_ref_mat);
+
+    EXPECT_EQ(cv::norm( y,  y_ref_mat), 0);
+    EXPECT_EQ(cv::norm(uv, uv_ref_mat), 0);
+}
+
+TEST(S11N, Pipeline_Render_RGB)
+{
+    cv::Size sz (100, 200);
+    int rects_num = 10;
+    int text_num  = 10;
+    int image_num = 10;
+
+    int thick = 2;
+    int lt = LINE_8;
+    cv::Scalar color(111, 222, 77);
+
+    // G-API code //////////////////////////////////////////////////////////////
+    cv::gapi::wip::draw::Prims prims;
+
+    // Rects
+    int shift = 0;
+    for (int i = 0; i < rects_num; ++i) {
+        cv::Rect rect(200 + i, 200 + i, 200, 200);
+        prims.emplace_back(cv::gapi::wip::draw::Rect(rect, color, thick, lt, shift));
+    }
+
+    // Mosaic
+    int cellsz = 50;
+    int decim = 0;
+    for (int i = 0; i < rects_num; ++i) {
+        cv::Rect mos(200 + i, 200 + i, 200, 200);
+        prims.emplace_back(cv::gapi::wip::draw::Mosaic(mos, cellsz, decim));
+    }
+
+    // Text
+    std::string text = "Some text";
+    int ff = FONT_HERSHEY_SIMPLEX;
+    double fs = 2.0;
+    bool blo = false;
+    for (int i = 0; i < text_num; ++i) {
+        cv::Point org(200 + i, 200 + i);
+        prims.emplace_back(cv::gapi::wip::draw::Text(text, org, ff, fs, color, thick, lt, blo));
+    }
+
+    // Image
+    double transparency = 1.0;
+    cv::Rect rect_img(0 ,0 , 50, 50);
+    cv::Mat img(rect_img.size(), CV_8UC3, color);
+    cv::Mat alpha(rect_img.size(), CV_32FC1, transparency);
+    auto tl = rect_img.tl();
+    for (int i = 0; i < image_num; ++i) {
+        cv::Point org_img = {tl.x + i, tl.y + rect_img.size().height + i};
+
+        prims.emplace_back(cv::gapi::wip::draw::Image({org_img, img, alpha}));
+    }
+
+    // Circle
+    cv::Point center(300, 400);
+    int rad = 25;
+    prims.emplace_back(cv::gapi::wip::draw::Circle({center, rad, color, thick, lt, shift}));
+
+    // Line
+    cv::Point point_next(300, 425);
+    prims.emplace_back(cv::gapi::wip::draw::Line({center, point_next, color, thick, lt, shift}));
+
+    // Poly
+    std::vector<cv::Point> points = {{300, 400}, {290, 450}, {348, 410}, {300, 400}};
+    prims.emplace_back(cv::gapi::wip::draw::Poly({points, color, thick, lt, shift}));
+
+    cv::GMat in, out;
+    cv::GArray<cv::gapi::wip::draw::Prim> arr;
+    out = cv::gapi::wip::draw::render3ch(in, arr);
+    cv::GComputation comp(cv::GIn(in, arr), cv::GOut(out));
+
+    auto serialized = cv::gapi::serialize(comp);
+    auto dc = cv::gapi::deserialize<cv::GComputation>(serialized);
+
+    cv::Mat input(1920, 1080, CV_8UC3);
+    cv::randu(input, cv::Scalar::all(0), cv::Scalar::all(255));
+    cv::Mat ref_mat = input.clone();
+    dc.apply(cv::gin(input, prims), cv::gout(input));
+
+    // OpenCV code //////////////////////////////////////////////////////////////
+    for (int i = 0; i < rects_num; ++i) {
+        cv::Rect rect(200 + i, 200 + i, 200, 200);
+        cv::rectangle(ref_mat, rect, color, thick, lt, shift);
+    }
+
+    for (int i = 0; i < rects_num; ++i) {
+        cv::Rect mos(200 + i, 200 + i, 200, 200);
+         drawMosaicRef(ref_mat, mos, cellsz);
+    }
+
+    for (int i = 0; i < text_num; ++i) {
+        cv::Point org(200 + i, 200 + i);
+        cv::putText(ref_mat, text, org, ff, fs, color, thick, lt, blo);
+    }
+
+    for (int i = 0; i < image_num; ++i) {
+        cv::Point org_img = {tl.x + i, tl.y + rect_img.size().height + i};
+        blendImageRef(ref_mat, org_img, img, alpha);
+    }
+
+    cv::circle(ref_mat, center, rad, color, thick, lt, shift);
+    cv::line(ref_mat, center, point_next, color, thick, lt, shift);
+    std::vector<std::vector<cv::Point>> pp{points};
+    cv::fillPoly(ref_mat, pp, color, lt, shift);
+
+    EXPECT_EQ(cv::norm(input,  ref_mat), 0);
+}
 } // namespace opencv_test