Merge pull request #20284 from TolyaTalamanov:at/wrap-render
authorAnatoliy Talamanov <anatoliy.talamanov@intel.com>
Thu, 1 Jul 2021 09:36:19 +0000 (12:36 +0300)
committerGitHub <noreply@github.com>
Thu, 1 Jul 2021 09:36:19 +0000 (09:36 +0000)
G-API: Wrap render functionality to python

* Wrap render Rect prim

* Add all primitives and tests

* Cover mosaic and image

* Handle error in pyopencv_to(Prim)

* Move Mosaic and Rect ctors wrappers to shadow file

* Use GAPI_PROP_RW

* Fix indent

modules/gapi/include/opencv2/gapi/own/exports.hpp
modules/gapi/include/opencv2/gapi/render/render.hpp
modules/gapi/include/opencv2/gapi/render/render_types.hpp
modules/gapi/misc/python/package/gapi/__init__.py
modules/gapi/misc/python/pyopencv_gapi.hpp
modules/gapi/misc/python/python_bridge.hpp
modules/gapi/misc/python/shadow_gapi.hpp
modules/gapi/misc/python/test/test_gapi_render.py [new file with mode: 0644]
modules/gapi/src/api/render_ocv.cpp
modules/gapi/test/render/gapi_render_tests_ocv.cpp
modules/python/src2/hdr_parser.py

index 1978991..c36f400 100644 (file)
 #       define GAPI_EXPORTS CV_EXPORTS
         /* special informative macros for wrapper generators */
 #       define GAPI_PROP CV_PROP
+#       define GAPI_PROP_RW CV_PROP_RW
 #       define GAPI_WRAP CV_WRAP
 #       define GAPI_EXPORTS_W_SIMPLE CV_EXPORTS_W_SIMPLE
 #       define GAPI_EXPORTS_W CV_EXPORTS_W
 #   else
 #       define GAPI_PROP
+#       define GAPI_PROP_RW
 #       define GAPI_WRAP
 #       define GAPI_EXPORTS
 #       define GAPI_EXPORTS_W_SIMPLE
index 6bfe923..5375412 100644 (file)
@@ -81,9 +81,9 @@ using GMatDesc2 = std::tuple<cv::GMatDesc,cv::GMatDesc>;
 @param prims vector of drawing primitivies
 @param args graph compile time parameters
 */
-void GAPI_EXPORTS render(cv::Mat& bgr,
-                         const Prims& prims,
-                         cv::GCompileArgs&& args = {});
+void GAPI_EXPORTS_W render(cv::Mat& bgr,
+                           const Prims& prims,
+                           cv::GCompileArgs&& args = {});
 
 /** @brief The function renders on two NV12 planes passed drawing primitivies
 
@@ -92,10 +92,10 @@ void GAPI_EXPORTS render(cv::Mat& bgr,
 @param prims vector of drawing primitivies
 @param args graph compile time parameters
 */
-void GAPI_EXPORTS render(cv::Mat& y_plane,
-                         cv::Mat& uv_plane,
-                         const Prims& prims,
-                         cv::GCompileArgs&& args = {});
+void GAPI_EXPORTS_W render(cv::Mat& y_plane,
+                           cv::Mat& uv_plane,
+                           const Prims& prims,
+                           cv::GCompileArgs&& args = {});
 
 /** @brief The function renders on the input media frame passed drawing primitivies
 
@@ -139,7 +139,7 @@ Output image must be 8-bit unsigned planar 3-channel image
 @param src input image: 8-bit unsigned 3-channel image @ref CV_8UC3
 @param prims draw primitives
 */
-GAPI_EXPORTS GMat render3ch(const GMat& src, const GArray<Prim>& prims);
+GAPI_EXPORTS_W GMat render3ch(const GMat& src, const GArray<Prim>& prims);
 
 /** @brief Renders on two planes
 
@@ -150,9 +150,9 @@ uv image must be 8-bit unsigned planar 2-channel image @ref CV_8UC2
 @param uv input image: 8-bit unsigned 2-channel image @ref CV_8UC2
 @param prims draw primitives
 */
-GAPI_EXPORTS GMat2 renderNV12(const GMat& y,
-                              const GMat& uv,
-                              const GArray<Prim>& prims);
+GAPI_EXPORTS_W GMat2 renderNV12(const GMat& y,
+                                const GMat& uv,
+                                const GArray<Prim>& prims);
 
 /** @brief Renders Media Frame
 
@@ -177,7 +177,7 @@ namespace render
 {
 namespace ocv
 {
-    GAPI_EXPORTS cv::gapi::GKernelPackage kernels();
+    GAPI_EXPORTS_W cv::gapi::GKernelPackage kernels();
 
 } // namespace ocv
 } // namespace render
index ca403be..6d70e3a 100644 (file)
@@ -41,7 +41,7 @@ struct freetype_font
  *
  * Parameters match cv::putText().
  */
-struct Text
+struct GAPI_EXPORTS_W_SIMPLE Text
 {
     /**
      * @brief Text constructor
@@ -55,6 +55,7 @@ struct 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
      */
+    GAPI_WRAP
     Text(const std::string& text_,
          const cv::Point& org_,
          int ff_,
@@ -68,17 +69,18 @@ struct Text
     {
     }
 
+    GAPI_WRAP
     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
+    GAPI_PROP_RW std::string text;               //!< The text string to be drawn
+    GAPI_PROP_RW cv::Point   org;                //!< The bottom-left corner of the text string in the image
+    GAPI_PROP_RW int         ff;                 //!< The font type, see #HersheyFonts
+    GAPI_PROP_RW double      fs;                 //!< The font scale factor that is multiplied by the font-specific base size
+    GAPI_PROP_RW cv::Scalar  color;              //!< The text color
+    GAPI_PROP_RW int         thick;              //!< The thickness of the lines used to draw a text
+    GAPI_PROP_RW int         lt;                 //!< The line type. See #LineTypes
+    GAPI_PROP_RW bool        bottom_left_origin; //!< When true, the image data origin is at the bottom-left corner. Otherwise, it is at the top-left corner
     /*@{*/
 };
 
@@ -122,7 +124,7 @@ struct FText
  *
  * Parameters match cv::rectangle().
  */
-struct Rect
+struct GAPI_EXPORTS_W_SIMPLE Rect
 {
     /**
      * @brief Rect constructor
@@ -142,14 +144,15 @@ struct Rect
     {
     }
 
+    GAPI_WRAP
     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
+    GAPI_PROP_RW cv::Rect   rect;  //!< Coordinates of the rectangle
+    GAPI_PROP_RW cv::Scalar color; //!< The rectangle color or brightness (grayscale image)
+    GAPI_PROP_RW 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
+    GAPI_PROP_RW int        lt;    //!< The type of the line. See #LineTypes
+    GAPI_PROP_RW int        shift; //!< The number of fractional bits in the point coordinates
     /*@{*/
 };
 
@@ -158,7 +161,7 @@ struct Rect
  *
  * Parameters match cv::circle().
  */
-struct Circle
+struct GAPI_EXPORTS_W_SIMPLE Circle
 {
     /**
      * @brief Circle constructor
@@ -170,6 +173,7 @@ struct Circle
      * @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
      */
+    GAPI_WRAP
     Circle(const cv::Point& center_,
            int radius_,
            const cv::Scalar& color_,
@@ -180,15 +184,16 @@ struct Circle
     {
     }
 
+    GAPI_WRAP
     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
+    GAPI_PROP_RW cv::Point  center; //!< The center of the circle
+    GAPI_PROP_RW int        radius; //!< The radius of the circle
+    GAPI_PROP_RW cv::Scalar color;  //!< The color of the  circle
+    GAPI_PROP_RW int        thick;  //!< The thickness of the circle outline, if positive. Negative values, like #FILLED, mean that a filled circle is to be drawn
+    GAPI_PROP_RW int        lt;     //!< The Type of the circle boundary. See #LineTypes
+    GAPI_PROP_RW int        shift;  //!< The Number of fractional bits in the coordinates of the center and in the radius value
     /*@{*/
 };
 
@@ -197,7 +202,7 @@ struct Circle
  *
  * Parameters match cv::line().
  */
-struct Line
+struct GAPI_EXPORTS_W_SIMPLE Line
 {
     /**
      * @brief Line constructor
@@ -209,6 +214,7 @@ struct Line
      * @param  lt_     The Type of the line. See #LineTypes
      * @param  shift_  The number of fractional bits in the point coordinates
     */
+    GAPI_WRAP
     Line(const cv::Point& pt1_,
          const cv::Point& pt2_,
          const cv::Scalar& color_,
@@ -219,15 +225,16 @@ struct Line
     {
     }
 
+    GAPI_WRAP
     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
+    GAPI_PROP_RW cv::Point  pt1;    //!< The first point of the line segment
+    GAPI_PROP_RW cv::Point  pt2;    //!< The second point of the line segment
+    GAPI_PROP_RW cv::Scalar color;  //!< The line color
+    GAPI_PROP_RW int        thick;  //!< The thickness of line
+    GAPI_PROP_RW int        lt;     //!< The Type of the line. See #LineTypes
+    GAPI_PROP_RW int        shift;  //!< The number of fractional bits in the point coordinates
     /*@{*/
 };
 
@@ -236,7 +243,7 @@ struct Line
  *
  * Mosaicing is a very basic method to obfuscate regions in the image.
  */
-struct Mosaic
+struct GAPI_EXPORTS_W_SIMPLE Mosaic
 {
     /**
      * @brief Mosaic constructor
@@ -252,12 +259,13 @@ struct Mosaic
     {
     }
 
+    GAPI_WRAP
     Mosaic() : cellSz(0), decim(0) {}
 
     /*@{*/
-    cv::Rect   mos;    //!< Coordinates of the mosaic
-    int        cellSz; //!< Cell size (same for X, Y)
-    int        decim;  //!< Decimation (0 stands for no decimation)
+    GAPI_PROP_RW cv::Rect mos;    //!< Coordinates of the mosaic
+    GAPI_PROP_RW int      cellSz; //!< Cell size (same for X, Y)
+    GAPI_PROP_RW int      decim;  //!< Decimation (0 stands for no decimation)
     /*@{*/
 };
 
@@ -266,7 +274,7 @@ struct Mosaic
  *
  * Image is blended on a frame using the specified mask.
  */
-struct Image
+struct GAPI_EXPORTS_W_SIMPLE Image
 {
     /**
      * @brief Mosaic constructor
@@ -275,6 +283,7 @@ struct Image
      * @param  img_   Image to draw
      * @param  alpha_ Alpha channel for image to draw (same size and number of channels)
     */
+    GAPI_WRAP
     Image(const cv::Point& org_,
           const cv::Mat& img_,
           const cv::Mat& alpha_) :
@@ -282,19 +291,20 @@ struct Image
     {
     }
 
+    GAPI_WRAP
     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)
+    GAPI_PROP_RW cv::Point org;   //!< The bottom-left corner of the image
+    GAPI_PROP_RW cv::Mat   img;   //!< Image to draw
+    GAPI_PROP_RW 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
+struct GAPI_EXPORTS_W_SIMPLE Poly
 {
     /**
      * @brief Mosaic constructor
@@ -305,6 +315,7 @@ struct Poly
      * @param lt_     The Type of the line. See #LineTypes
      * @param shift_  The number of fractional bits in the point coordinate
     */
+    GAPI_WRAP
     Poly(const std::vector<cv::Point>& points_,
          const cv::Scalar& color_,
          int thick_ = 1,
@@ -314,14 +325,15 @@ struct Poly
     {
     }
 
+    GAPI_WRAP
     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
+    GAPI_PROP_RW std::vector<cv::Point> points;  //!< Points to connect
+    GAPI_PROP_RW cv::Scalar             color;   //!< The line color
+    GAPI_PROP_RW int                    thick;   //!< The thickness of line
+    GAPI_PROP_RW int                    lt;      //!< The Type of the line. See #LineTypes
+    GAPI_PROP_RW int                    shift;   //!< The number of fractional bits in the point coordinate
     /*@{*/
 };
 
@@ -336,7 +348,7 @@ using Prim  = util::variant
     , Poly
     >;
 
-using Prims     = std::vector<Prim>;
+using Prims = std::vector<Prim>;
 //! @} gapi_draw_prims
 
 } // namespace draw
index 587f641..dc874f0 100644 (file)
@@ -84,6 +84,10 @@ class GOpaque():
         def __new__(self):
             return cv.GOpaqueT(cv.gapi.CV_RECT)
 
+    class Prim():
+        def __new__(self):
+            return cv.GOpaqueT(cv.gapi.CV_DRAW_PRIM)
+
     class Any():
         def __new__(self):
             return cv.GOpaqueT(cv.gapi.CV_ANY)
@@ -143,6 +147,10 @@ class GArray():
         def __new__(self):
             return cv.GArrayT(cv.gapi.CV_GMAT)
 
+    class Prim():
+        def __new__(self):
+            return cv.GArray(cv.gapi.CV_DRAW_PRIM)
+
     class Any():
         def __new__(self):
             return cv.GArray(cv.gapi.CV_ANY)
@@ -164,6 +172,7 @@ def op(op_id, in_types, out_types):
             cv.GArray.Scalar:  cv.gapi.CV_SCALAR,
             cv.GArray.Mat:     cv.gapi.CV_MAT,
             cv.GArray.GMat:    cv.gapi.CV_GMAT,
+            cv.GArray.Prim:    cv.gapi.CV_DRAW_PRIM,
             cv.GArray.Any:     cv.gapi.CV_ANY
     }
 
@@ -179,22 +188,24 @@ def op(op_id, in_types, out_types):
             cv.GOpaque.Point2f: cv.gapi.CV_POINT2F,
             cv.GOpaque.Size:    cv.gapi.CV_SIZE,
             cv.GOpaque.Rect:    cv.gapi.CV_RECT,
+            cv.GOpaque.Prim:    cv.gapi.CV_DRAW_PRIM,
             cv.GOpaque.Any:     cv.gapi.CV_ANY
     }
 
     type2str = {
-        cv.gapi.CV_BOOL:    'cv.gapi.CV_BOOL' ,
-        cv.gapi.CV_INT:     'cv.gapi.CV_INT' ,
-        cv.gapi.CV_DOUBLE:  'cv.gapi.CV_DOUBLE' ,
-        cv.gapi.CV_FLOAT:   'cv.gapi.CV_FLOAT' ,
-        cv.gapi.CV_STRING:  'cv.gapi.CV_STRING' ,
-        cv.gapi.CV_POINT:   'cv.gapi.CV_POINT' ,
-        cv.gapi.CV_POINT2F: 'cv.gapi.CV_POINT2F' ,
-        cv.gapi.CV_SIZE:    'cv.gapi.CV_SIZE',
-        cv.gapi.CV_RECT:    'cv.gapi.CV_RECT',
-        cv.gapi.CV_SCALAR:  'cv.gapi.CV_SCALAR',
-        cv.gapi.CV_MAT:     'cv.gapi.CV_MAT',
-        cv.gapi.CV_GMAT:    'cv.gapi.CV_GMAT'
+        cv.gapi.CV_BOOL:      'cv.gapi.CV_BOOL' ,
+        cv.gapi.CV_INT:       'cv.gapi.CV_INT' ,
+        cv.gapi.CV_DOUBLE:    'cv.gapi.CV_DOUBLE' ,
+        cv.gapi.CV_FLOAT:     'cv.gapi.CV_FLOAT' ,
+        cv.gapi.CV_STRING:    'cv.gapi.CV_STRING' ,
+        cv.gapi.CV_POINT:     'cv.gapi.CV_POINT' ,
+        cv.gapi.CV_POINT2F:   'cv.gapi.CV_POINT2F' ,
+        cv.gapi.CV_SIZE:      'cv.gapi.CV_SIZE',
+        cv.gapi.CV_RECT:      'cv.gapi.CV_RECT',
+        cv.gapi.CV_SCALAR:    'cv.gapi.CV_SCALAR',
+        cv.gapi.CV_MAT:       'cv.gapi.CV_MAT',
+        cv.gapi.CV_GMAT:      'cv.gapi.CV_GMAT',
+        cv.gapi.CV_DRAW_PRIM: 'cv.gapi.CV_DRAW_PRIM'
     }
 
     # NB: Second lvl decorator takes class to decorate
@@ -274,3 +285,13 @@ def kernel(op_cls):
         return cls
 
     return kernel_with_params
+
+
+# FIXME: On the c++ side every class is placed in cv2 module.
+cv.gapi.wip.draw.Rect = cv.gapi_wip_draw_Rect
+cv.gapi.wip.draw.Text = cv.gapi_wip_draw_Text
+cv.gapi.wip.draw.Circle = cv.gapi_wip_draw_Circle
+cv.gapi.wip.draw.Line = cv.gapi_wip_draw_Line
+cv.gapi.wip.draw.Mosaic = cv.gapi_wip_draw_Mosaic
+cv.gapi.wip.draw.Image = cv.gapi_wip_draw_Image
+cv.gapi.wip.draw.Poly = cv.gapi_wip_draw_Poly
index 6cd79e4..3c428dd 100644 (file)
@@ -43,6 +43,7 @@ using GArray_Rect    = cv::GArray<cv::Rect>;
 using GArray_Scalar  = cv::GArray<cv::Scalar>;
 using GArray_Mat     = cv::GArray<cv::Mat>;
 using GArray_GMat    = cv::GArray<cv::GMat>;
+using GArray_Prim    = cv::GArray<cv::gapi::wip::draw::Prim>;
 
 // FIXME: Python wrapper generate code without namespace std,
 // so it cause error: "string wasn't declared"
@@ -125,6 +126,65 @@ PyObject* pyopencv_from(const cv::detail::PyObjectHolder& v)
     return o;
 }
 
+// #FIXME: Is it possible to implement pyopencv_from/pyopencv_to for generic
+// cv::variant<Types...> ?
+template <>
+PyObject* pyopencv_from(const cv::gapi::wip::draw::Prim& prim)
+{
+    switch (prim.index()) {
+        case cv::gapi::wip::draw::Prim::index_of<cv::gapi::wip::draw::Rect>():
+            return pyopencv_from(cv::util::get<cv::gapi::wip::draw::Rect>(prim));
+        case cv::gapi::wip::draw::Prim::index_of<cv::gapi::wip::draw::Text>():
+            return pyopencv_from(cv::util::get<cv::gapi::wip::draw::Text>(prim));
+        case cv::gapi::wip::draw::Prim::index_of<cv::gapi::wip::draw::Circle>():
+            return pyopencv_from(cv::util::get<cv::gapi::wip::draw::Circle>(prim));
+        case cv::gapi::wip::draw::Prim::index_of<cv::gapi::wip::draw::Line>():
+            return pyopencv_from(cv::util::get<cv::gapi::wip::draw::Line>(prim));
+        case cv::gapi::wip::draw::Prim::index_of<cv::gapi::wip::draw::Poly>():
+            return pyopencv_from(cv::util::get<cv::gapi::wip::draw::Poly>(prim));
+        case cv::gapi::wip::draw::Prim::index_of<cv::gapi::wip::draw::Mosaic>():
+            return pyopencv_from(cv::util::get<cv::gapi::wip::draw::Mosaic>(prim));
+        case cv::gapi::wip::draw::Prim::index_of<cv::gapi::wip::draw::Image>():
+            return pyopencv_from(cv::util::get<cv::gapi::wip::draw::Image>(prim));
+    }
+
+    util::throw_error(std::logic_error("Unsupported draw primitive type"));
+}
+
+template <>
+PyObject* pyopencv_from(const cv::gapi::wip::draw::Prims& value)
+{
+    return pyopencv_from_generic_vec(value);
+}
+
+template<>
+bool pyopencv_to(PyObject* obj, cv::gapi::wip::draw::Prim& value, const ArgInfo& info)
+{
+#define TRY_EXTRACT(Prim)                                                                                  \
+    if (PyObject_TypeCheck(obj, reinterpret_cast<PyTypeObject*>(pyopencv_gapi_wip_draw_##Prim##_TypePtr))) \
+    {                                                                                                      \
+        value = reinterpret_cast<pyopencv_gapi_wip_draw_##Prim##_t*>(obj)->v;                              \
+        return true;                                                                                       \
+    }                                                                                                      \
+
+    TRY_EXTRACT(Rect)
+    TRY_EXTRACT(Text)
+    TRY_EXTRACT(Circle)
+    TRY_EXTRACT(Line)
+    TRY_EXTRACT(Mosaic)
+    TRY_EXTRACT(Image)
+    TRY_EXTRACT(Poly)
+
+    failmsg("Unsupported primitive type");
+    return false;
+}
+
+template <>
+bool pyopencv_to(PyObject* obj, cv::gapi::wip::draw::Prims& value, const ArgInfo& info)
+{
+    return pyopencv_to_generic_vec(obj, value, info);
+}
+
 template<>
 PyObject* pyopencv_from(const cv::GArg& value)
 {
@@ -137,21 +197,21 @@ PyObject* pyopencv_from(const cv::GArg& value)
 #define UNSUPPORTED(T) case cv::detail::OpaqueKind::CV_##T: break
     switch (value.opaque_kind)
     {
-        HANDLE_CASE(BOOL,    bool);
-        HANDLE_CASE(INT,     int);
+        HANDLE_CASE(BOOL,      bool);
+        HANDLE_CASE(INT,       int);
         HANDLE_CASE(INT64,   int64_t);
-        HANDLE_CASE(DOUBLE,  double);
-        HANDLE_CASE(FLOAT,   float);
-        HANDLE_CASE(STRING,  std::string);
-        HANDLE_CASE(POINT,   cv::Point);
-        HANDLE_CASE(POINT2F, cv::Point2f);
-        HANDLE_CASE(SIZE,    cv::Size);
-        HANDLE_CASE(RECT,    cv::Rect);
-        HANDLE_CASE(SCALAR,  cv::Scalar);
-        HANDLE_CASE(MAT,     cv::Mat);
-        HANDLE_CASE(UNKNOWN, cv::detail::PyObjectHolder);
+        HANDLE_CASE(DOUBLE,    double);
+        HANDLE_CASE(FLOAT,     float);
+        HANDLE_CASE(STRING,    std::string);
+        HANDLE_CASE(POINT,     cv::Point);
+        HANDLE_CASE(POINT2F,   cv::Point2f);
+        HANDLE_CASE(SIZE,      cv::Size);
+        HANDLE_CASE(RECT,      cv::Rect);
+        HANDLE_CASE(SCALAR,    cv::Scalar);
+        HANDLE_CASE(MAT,       cv::Mat);
+        HANDLE_CASE(UNKNOWN,   cv::detail::PyObjectHolder);
+        HANDLE_CASE(DRAW_PRIM, cv::gapi::wip::draw::Prim);
         UNSUPPORTED(UINT64);
-        UNSUPPORTED(DRAW_PRIM);
 #undef HANDLE_CASE
 #undef UNSUPPORTED
     }
@@ -205,10 +265,10 @@ PyObject* pyopencv_from(const cv::detail::OpaqueRef& o)
         case cv::detail::OpaqueKind::CV_SIZE      : return pyopencv_from(o.rref<cv::Size>());
         case cv::detail::OpaqueKind::CV_RECT      : return pyopencv_from(o.rref<cv::Rect>());
         case cv::detail::OpaqueKind::CV_UNKNOWN   : return pyopencv_from(o.rref<cv::GArg>());
+        case cv::detail::OpaqueKind::CV_DRAW_PRIM : return pyopencv_from(o.rref<cv::gapi::wip::draw::Prim>());
         case cv::detail::OpaqueKind::CV_UINT64    : break;
         case cv::detail::OpaqueKind::CV_SCALAR    : break;
         case cv::detail::OpaqueKind::CV_MAT       : break;
-        case cv::detail::OpaqueKind::CV_DRAW_PRIM : break;
     }
 
     PyErr_SetString(PyExc_TypeError, "Unsupported GOpaque type");
@@ -233,8 +293,8 @@ PyObject* pyopencv_from(const cv::detail::VectorRef& v)
         case cv::detail::OpaqueKind::CV_SCALAR    : return pyopencv_from_generic_vec(v.rref<cv::Scalar>());
         case cv::detail::OpaqueKind::CV_MAT       : return pyopencv_from_generic_vec(v.rref<cv::Mat>());
         case cv::detail::OpaqueKind::CV_UNKNOWN   : return pyopencv_from_generic_vec(v.rref<cv::GArg>());
+        case cv::detail::OpaqueKind::CV_DRAW_PRIM : return pyopencv_from_generic_vec(v.rref<cv::gapi::wip::draw::Prim>());
         case cv::detail::OpaqueKind::CV_UINT64    : break;
-        case cv::detail::OpaqueKind::CV_DRAW_PRIM : break;
     }
 
     PyErr_SetString(PyExc_TypeError, "Unsupported GArray type");
@@ -394,21 +454,21 @@ static cv::detail::VectorRef extract_vector_ref(PyObject* from, cv::detail::Opaq
 #define UNSUPPORTED(T) case cv::detail::OpaqueKind::CV_##T: break
     switch (kind)
     {
-        HANDLE_CASE(BOOL,    bool);
-        HANDLE_CASE(INT,     int);
-        HANDLE_CASE(DOUBLE,  double);
-        HANDLE_CASE(FLOAT,   float);
-        HANDLE_CASE(STRING,  std::string);
-        HANDLE_CASE(POINT,   cv::Point);
-        HANDLE_CASE(POINT2F, cv::Point2f);
-        HANDLE_CASE(SIZE,    cv::Size);
-        HANDLE_CASE(RECT,    cv::Rect);
-        HANDLE_CASE(SCALAR,  cv::Scalar);
-        HANDLE_CASE(MAT,     cv::Mat);
-        HANDLE_CASE(UNKNOWN, cv::GArg);
+        HANDLE_CASE(BOOL,      bool);
+        HANDLE_CASE(INT,       int);
+        HANDLE_CASE(DOUBLE,    double);
+        HANDLE_CASE(FLOAT,     float);
+        HANDLE_CASE(STRING,    std::string);
+        HANDLE_CASE(POINT,     cv::Point);
+        HANDLE_CASE(POINT2F,   cv::Point2f);
+        HANDLE_CASE(SIZE,      cv::Size);
+        HANDLE_CASE(RECT,      cv::Rect);
+        HANDLE_CASE(SCALAR,    cv::Scalar);
+        HANDLE_CASE(MAT,       cv::Mat);
+        HANDLE_CASE(UNKNOWN,   cv::GArg);
+        HANDLE_CASE(DRAW_PRIM, cv::gapi::wip::draw::Prim);
         UNSUPPORTED(UINT64);
         UNSUPPORTED(INT64);
-        UNSUPPORTED(DRAW_PRIM);
 #undef HANDLE_CASE
 #undef UNSUPPORTED
     }
index b212bab..11d1728 100644 (file)
@@ -10,6 +10,7 @@
 #include <opencv2/gapi.hpp>
 #include <opencv2/gapi/garg.hpp>
 #include <opencv2/gapi/gopaque.hpp>
+#include <opencv2/gapi/render/render_types.hpp> // Prim
 
 #define ID(T, E)  T
 #define ID_(T, E) ID(T, E),
             GAPI_Assert(false && "Unsupported type"); \
     }
 
+using cv::gapi::wip::draw::Prim;
+
 #define GARRAY_TYPE_LIST_G(G, G2) \
-WRAP_ARGS(bool        , cv::gapi::ArgType::CV_BOOL,    G)  \
-WRAP_ARGS(int         , cv::gapi::ArgType::CV_INT,     G)  \
-WRAP_ARGS(int64_t     , cv::gapi::ArgType::CV_INT64,   G)  \
-WRAP_ARGS(double      , cv::gapi::ArgType::CV_DOUBLE,  G)  \
-WRAP_ARGS(float       , cv::gapi::ArgType::CV_FLOAT,   G)  \
-WRAP_ARGS(std::string , cv::gapi::ArgType::CV_STRING,  G)  \
-WRAP_ARGS(cv::Point   , cv::gapi::ArgType::CV_POINT,   G)  \
-WRAP_ARGS(cv::Point2f , cv::gapi::ArgType::CV_POINT2F, G)  \
-WRAP_ARGS(cv::Size    , cv::gapi::ArgType::CV_SIZE,    G)  \
-WRAP_ARGS(cv::Rect    , cv::gapi::ArgType::CV_RECT,    G)  \
-WRAP_ARGS(cv::Scalar  , cv::gapi::ArgType::CV_SCALAR,  G)  \
-WRAP_ARGS(cv::Mat     , cv::gapi::ArgType::CV_MAT,     G)  \
-WRAP_ARGS(cv::GArg    , cv::gapi::ArgType::CV_ANY,     G)  \
-WRAP_ARGS(cv::GMat    , cv::gapi::ArgType::CV_GMAT,    G2) \
+WRAP_ARGS(bool        , cv::gapi::ArgType::CV_BOOL,      G)  \
+WRAP_ARGS(int         , cv::gapi::ArgType::CV_INT,       G)  \
+WRAP_ARGS(int64_t     , cv::gapi::ArgType::CV_INT64,     G)  \
+WRAP_ARGS(double      , cv::gapi::ArgType::CV_DOUBLE,    G)  \
+WRAP_ARGS(float       , cv::gapi::ArgType::CV_FLOAT,     G)  \
+WRAP_ARGS(std::string , cv::gapi::ArgType::CV_STRING,    G)  \
+WRAP_ARGS(cv::Point   , cv::gapi::ArgType::CV_POINT,     G)  \
+WRAP_ARGS(cv::Point2f , cv::gapi::ArgType::CV_POINT2F,   G)  \
+WRAP_ARGS(cv::Size    , cv::gapi::ArgType::CV_SIZE,      G)  \
+WRAP_ARGS(cv::Rect    , cv::gapi::ArgType::CV_RECT,      G)  \
+WRAP_ARGS(cv::Scalar  , cv::gapi::ArgType::CV_SCALAR,    G)  \
+WRAP_ARGS(cv::Mat     , cv::gapi::ArgType::CV_MAT,       G)  \
+WRAP_ARGS(Prim        , cv::gapi::ArgType::CV_DRAW_PRIM, G)  \
+WRAP_ARGS(cv::GArg    , cv::gapi::ArgType::CV_ANY,       G)  \
+WRAP_ARGS(cv::GMat    , cv::gapi::ArgType::CV_GMAT,      G2) \
 
 #define GOPAQUE_TYPE_LIST_G(G, G2) \
 WRAP_ARGS(bool        , cv::gapi::ArgType::CV_BOOL,    G)  \
@@ -71,6 +75,7 @@ enum ArgType {
     CV_SCALAR,
     CV_MAT,
     CV_GMAT,
+    CV_DRAW_PRIM,
     CV_ANY,
 };
 
index e777aa5..41d0f19 100644 (file)
@@ -3,58 +3,77 @@
 
 namespace cv
 {
-   struct GAPI_EXPORTS_W_SIMPLE GCompileArg {
-       GAPI_WRAP GCompileArg(gapi::GKernelPackage pkg);
-       GAPI_WRAP GCompileArg(gapi::GNetPackage pkg);
-   };
-
-   class GAPI_EXPORTS_W_SIMPLE GInferInputs
-   {
-   public:
-       GAPI_WRAP GInferInputs();
-       GAPI_WRAP GInferInputs& setInput(const std::string& name, const cv::GMat&   value);
-       GAPI_WRAP GInferInputs& setInput(const std::string& name, const cv::GFrame& value);
-   };
-
-   class GAPI_EXPORTS_W_SIMPLE GInferListInputs
-   {
-   public:
-       GAPI_WRAP GInferListInputs();
-       GAPI_WRAP GInferListInputs setInput(const std::string& name, const cv::GArray<cv::GMat>& value);
-       GAPI_WRAP GInferListInputs setInput(const std::string& name, const cv::GArray<cv::Rect>& value);
-   };
-
-   class GAPI_EXPORTS_W_SIMPLE GInferOutputs
-   {
-   public:
-       GAPI_WRAP GInferOutputs();
-       GAPI_WRAP cv::GMat at(const std::string& name);
-   };
-
-   class GAPI_EXPORTS_W_SIMPLE GInferListOutputs
-   {
-   public:
-       GAPI_WRAP GInferListOutputs();
-       GAPI_WRAP cv::GArray<cv::GMat> at(const std::string& name);
-   };
-
-   namespace detail
-   {
-       gapi::GNetParam GAPI_EXPORTS_W strip(gapi::ie::PyParams params);
-   } // namespace detail
-
-   namespace gapi
-   {
-       namespace streaming
-       {
-           // FIXME: Extend to work with an arbitrary G-type.
-           cv::GOpaque<int64_t> GAPI_EXPORTS_W timestamp(cv::GMat);
-           cv::GOpaque<int64_t> GAPI_EXPORTS_W seqNo(cv::GMat);
-           cv::GOpaque<int64_t> GAPI_EXPORTS_W seq_id(cv::GMat);
-       } // namespace streaming
-       namespace wip
-       {
-           class GAPI_EXPORTS_W IStreamSource { };
-       } // namespace wip
-   } // namespace gapi
+struct GAPI_EXPORTS_W_SIMPLE GCompileArg {
+   GAPI_WRAP GCompileArg(gapi::GKernelPackage pkg);
+   GAPI_WRAP GCompileArg(gapi::GNetPackage pkg);
+};
+
+class GAPI_EXPORTS_W_SIMPLE GInferInputs
+{
+public:
+   GAPI_WRAP GInferInputs();
+   GAPI_WRAP GInferInputs& setInput(const std::string& name, const cv::GMat&   value);
+   GAPI_WRAP GInferInputs& setInput(const std::string& name, const cv::GFrame& value);
+};
+
+class GAPI_EXPORTS_W_SIMPLE GInferListInputs
+{
+public:
+   GAPI_WRAP GInferListInputs();
+   GAPI_WRAP GInferListInputs setInput(const std::string& name, const cv::GArray<cv::GMat>& value);
+   GAPI_WRAP GInferListInputs setInput(const std::string& name, const cv::GArray<cv::Rect>& value);
+};
+
+class GAPI_EXPORTS_W_SIMPLE GInferOutputs
+{
+public:
+   GAPI_WRAP GInferOutputs();
+   GAPI_WRAP cv::GMat at(const std::string& name);
+};
+
+class GAPI_EXPORTS_W_SIMPLE GInferListOutputs
+{
+public:
+   GAPI_WRAP GInferListOutputs();
+   GAPI_WRAP cv::GArray<cv::GMat> at(const std::string& name);
+};
+
+namespace gapi
+{
+namespace wip
+{
+class GAPI_EXPORTS_W IStreamSource { };
+namespace draw
+{
+    // NB: These render primitives are partially wrapped in shadow file
+    // because cv::Rect conflicts with cv::gapi::wip::draw::Rect in python generator
+    // and cv::Rect2i breaks standalone mode.
+    struct Rect
+    {
+        GAPI_WRAP Rect(const cv::Rect2i& rect_,
+                       const cv::Scalar& color_,
+                       int thick_ = 1,
+                       int lt_ = 8,
+                       int shift_ = 0);
+    };
+
+    struct Mosaic
+    {
+        GAPI_WRAP Mosaic(const cv::Rect2i& mos_, int cellSz_, int decim_);
+    };
+} // namespace draw
+} // namespace wip
+namespace streaming
+{
+    // FIXME: Extend to work with an arbitrary G-type.
+    cv::GOpaque<int64_t> GAPI_EXPORTS_W timestamp(cv::GMat);
+    cv::GOpaque<int64_t> GAPI_EXPORTS_W seqNo(cv::GMat);
+    cv::GOpaque<int64_t> GAPI_EXPORTS_W seq_id(cv::GMat);
+} // namespace streaming
+} // namespace gapi
+
+namespace detail
+{
+   gapi::GNetParam GAPI_EXPORTS_W strip(gapi::ie::PyParams params);
+} // namespace detail
 } // namespace cv
diff --git a/modules/gapi/misc/python/test/test_gapi_render.py b/modules/gapi/misc/python/test/test_gapi_render.py
new file mode 100644 (file)
index 0000000..70601a7
--- /dev/null
@@ -0,0 +1,227 @@
+#!/usr/bin/env python
+
+import numpy as np
+import cv2 as cv
+import os
+import sys
+import unittest
+
+from tests_common import NewOpenCVTests
+
+try:
+
+    if sys.version_info[:2] < (3, 0):
+        raise unittest.SkipTest('Python 2.x is not supported')
+
+    # FIXME: FText isn't supported yet.
+    class gapi_render_test(NewOpenCVTests):
+        def __init__(self, *args):
+            super().__init__(*args)
+
+            self.size = (300, 300, 3)
+
+            # Rect
+            self.rect = (30, 30, 50, 50)
+            self.rcolor = (0, 255, 0)
+            self.rlt = cv.LINE_4
+            self.rthick = 2
+            self.rshift = 3
+
+            # Text
+            self.text = 'Hello, world!'
+            self.org = (100, 100)
+            self.ff = cv.FONT_HERSHEY_SIMPLEX
+            self.fs = 1.0
+            self.tthick = 2
+            self.tlt = cv.LINE_8
+            self.tcolor = (255, 255, 255)
+            self.blo = False
+
+            # Circle
+            self.center = (200, 200)
+            self.radius = 200
+            self.ccolor = (255, 255, 0)
+            self.cthick = 2
+            self.clt = cv.LINE_4
+            self.cshift = 1
+
+            # Line
+            self.pt1 = (50, 50)
+            self.pt2 = (200, 200)
+            self.lcolor = (0, 255, 128)
+            self.lthick = 5
+            self.llt = cv.LINE_8
+            self.lshift = 2
+
+            # Poly
+            self.pts = [(50, 100), (100, 200), (25, 250)]
+            self.pcolor = (0, 0, 255)
+            self.pthick = 3
+            self.plt = cv.LINE_4
+            self.pshift = 1
+
+            # Image
+            self.iorg = (150, 150)
+            img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
+            self.img = cv.resize(cv.imread(img_path), (50, 50))
+            self.alpha = np.full(self.img.shape[:2], 0.8, dtype=np.float32)
+
+            # Mosaic
+            self.mos = (100, 100, 100, 100)
+            self.cell_sz = 25
+            self.decim = 0
+
+            # Render primitives
+            self.prims = [cv.gapi.wip.draw.Rect(self.rect, self.rcolor, self.rthick, self.rlt, self.rshift),
+                          cv.gapi.wip.draw.Text(self.text, self.org, self.ff, self.fs, self.tcolor, self.tthick, self.tlt, self.blo),
+                          cv.gapi.wip.draw.Circle(self.center, self.radius, self.ccolor, self.cthick, self.clt, self.cshift),
+                          cv.gapi.wip.draw.Line(self.pt1, self.pt2, self.lcolor, self.lthick, self.llt, self.lshift),
+                          cv.gapi.wip.draw.Mosaic(self.mos, self.cell_sz, self.decim),
+                          cv.gapi.wip.draw.Image(self.iorg, self.img, self.alpha),
+                          cv.gapi.wip.draw.Poly(self.pts, self.pcolor, self.pthick, self.plt, self.pshift)]
+
+        def cvt_nv12_to_yuv(self, y, uv):
+            h,w,_ = uv.shape
+            upsample_uv = cv.resize(uv, (h * 2, w * 2))
+            return cv.merge([y, upsample_uv])
+
+        def cvt_yuv_to_nv12(self, yuv, y_out, uv_out):
+            chs = cv.split(yuv, [y_out, None, None])
+            uv = cv.merge([chs[1], chs[2]])
+            uv_out = cv.resize(uv, (uv.shape[0] // 2, uv.shape[1] // 2), dst=uv_out)
+            return y_out, uv_out
+
+        def cvt_bgr_to_yuv_color(self, bgr):
+            y = bgr[2] *  0.299000 + bgr[1] *  0.587000 + bgr[0] *  0.114000;
+            u = bgr[2] * -0.168736 + bgr[1] * -0.331264 + bgr[0] *  0.500000 + 128;
+            v = bgr[2] *  0.500000 + bgr[1] * -0.418688 + bgr[0] * -0.081312 + 128;
+            return (y, u, v)
+
+        def blend_img(self, background, org, img, alpha):
+            x, y = org
+            h, w, _ = img.shape
+            roi_img = background[x:x+w, y:y+h, :]
+            img32f_w = cv.merge([alpha] * 3).astype(np.float32)
+            roi32f_w = np.full(roi_img.shape, 1.0, dtype=np.float32)
+            roi32f_w -= img32f_w
+            img32f = (img / 255).astype(np.float32)
+            roi32f = (roi_img / 255).astype(np.float32)
+            cv.multiply(img32f, img32f_w, dst=img32f)
+            cv.multiply(roi32f, roi32f_w, dst=roi32f)
+            roi32f += img32f
+            roi_img[...] = np.round(roi32f * 255)
+
+        # This is quite naive implementations used as a simple reference
+        # doesn't consider corner cases.
+        def draw_mosaic(self, img, mos, cell_sz, decim):
+            x,y,w,h = mos
+            mosaic_area = img[x:x+w, y:y+h, :]
+            for i in range(0, mosaic_area.shape[0], cell_sz):
+                for j in range(0, mosaic_area.shape[1], cell_sz):
+                    cell_roi = mosaic_area[j:j+cell_sz, i:i+cell_sz, :]
+                    s0, s1, s2 = cv.mean(cell_roi)[:3]
+                    mosaic_area[j:j+cell_sz, i:i+cell_sz] = (round(s0), round(s1), round(s2))
+
+        def render_primitives_bgr_ref(self, img):
+            cv.rectangle(img, self.rect, self.rcolor, self.rthick, self.rlt, self.rshift)
+            cv.putText(img, self.text, self.org, self.ff, self.fs, self.tcolor, self.tthick, self.tlt, self.blo)
+            cv.circle(img, self.center, self.radius, self.ccolor, self.cthick, self.clt, self.cshift)
+            cv.line(img, self.pt1, self.pt2, self.lcolor, self.lthick, self.llt, self.lshift)
+            cv.fillPoly(img, np.expand_dims(np.array([self.pts]), axis=0), self.pcolor, self.plt, self.pshift)
+            self.draw_mosaic(img, self.mos, self.cell_sz, self.decim)
+            self.blend_img(img, self.iorg, self.img, self.alpha)
+
+        def render_primitives_nv12_ref(self, y_plane, uv_plane):
+            yuv = self.cvt_nv12_to_yuv(y_plane, uv_plane)
+            cv.rectangle(yuv, self.rect, self.cvt_bgr_to_yuv_color(self.rcolor), self.rthick, self.rlt, self.rshift)
+            cv.putText(yuv, self.text, self.org, self.ff, self.fs, self.cvt_bgr_to_yuv_color(self.tcolor), self.tthick, self.tlt, self.blo)
+            cv.circle(yuv, self.center, self.radius, self.cvt_bgr_to_yuv_color(self.ccolor), self.cthick, self.clt, self.cshift)
+            cv.line(yuv, self.pt1, self.pt2, self.cvt_bgr_to_yuv_color(self.lcolor), self.lthick, self.llt, self.lshift)
+            cv.fillPoly(yuv, np.expand_dims(np.array([self.pts]), axis=0), self.cvt_bgr_to_yuv_color(self.pcolor), self.plt, self.pshift)
+            self.draw_mosaic(yuv, self.mos, self.cell_sz, self.decim)
+            self.blend_img(yuv, self.iorg, cv.cvtColor(self.img, cv.COLOR_BGR2YUV), self.alpha)
+            self.cvt_yuv_to_nv12(yuv, y_plane, uv_plane)
+
+        def test_render_primitives_on_bgr_graph(self):
+            expected = np.zeros(self.size, dtype=np.uint8)
+            actual = np.array(expected, copy=True)
+
+            # OpenCV
+            self.render_primitives_bgr_ref(expected)
+
+            # G-API
+            g_in = cv.GMat()
+            g_prims = cv.GArray.Prim()
+            g_out = cv.gapi.wip.draw.render3ch(g_in, g_prims)
+
+
+            comp = cv.GComputation(cv.GIn(g_in, g_prims), cv.GOut(g_out))
+            actual = comp.apply(cv.gin(actual, self.prims))
+
+            self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF))
+
+        def test_render_primitives_on_bgr_function(self):
+            expected = np.zeros(self.size, dtype=np.uint8)
+            actual = np.array(expected, copy=True)
+
+            # OpenCV
+            self.render_primitives_bgr_ref(expected)
+
+            # G-API
+            cv.gapi.wip.draw.render(actual, self.prims)
+            self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF))
+
+        def test_render_primitives_on_nv12_graph(self):
+            y_expected = np.zeros((self.size[0], self.size[1], 1), dtype=np.uint8)
+            uv_expected = np.zeros((self.size[0] // 2, self.size[1] // 2, 2), dtype=np.uint8)
+
+            y_actual = np.array(y_expected, copy=True)
+            uv_actual = np.array(uv_expected, copy=True)
+
+            # OpenCV
+            self.render_primitives_nv12_ref(y_expected, uv_expected)
+
+            # G-API
+            g_y = cv.GMat()
+            g_uv = cv.GMat()
+            g_prims = cv.GArray.Prim()
+            g_out_y, g_out_uv = cv.gapi.wip.draw.renderNV12(g_y, g_uv, g_prims)
+
+            comp = cv.GComputation(cv.GIn(g_y, g_uv, g_prims), cv.GOut(g_out_y, g_out_uv))
+            y_actual, uv_actual = comp.apply(cv.gin(y_actual, uv_actual, self.prims))
+
+            self.assertEqual(0.0, cv.norm(y_expected, y_actual, cv.NORM_INF))
+            self.assertEqual(0.0, cv.norm(uv_expected, uv_actual, cv.NORM_INF))
+
+        def test_render_primitives_on_nv12_function(self):
+            y_expected = np.zeros((self.size[0], self.size[1], 1), dtype=np.uint8)
+            uv_expected = np.zeros((self.size[0] // 2, self.size[1] // 2, 2), dtype=np.uint8)
+
+            y_actual = np.array(y_expected, copy=True)
+            uv_actual = np.array(uv_expected, copy=True)
+
+            # OpenCV
+            self.render_primitives_nv12_ref(y_expected, uv_expected)
+
+            # G-API
+            cv.gapi.wip.draw.render(y_actual, uv_actual, self.prims)
+
+            self.assertEqual(0.0, cv.norm(y_expected, y_actual, cv.NORM_INF))
+            self.assertEqual(0.0, cv.norm(uv_expected, uv_actual, cv.NORM_INF))
+
+
+except unittest.SkipTest as e:
+
+    message = str(e)
+
+    class TestSkip(unittest.TestCase):
+        def setUp(self):
+            self.skipTest('Skip tests: ' + message)
+
+        def test_skip():
+            pass
+
+    pass
+
+if __name__ == '__main__':
+    NewOpenCVTests.bootstrap()
index 5ab2e1d..f1e9be4 100644 (file)
@@ -159,7 +159,7 @@ void drawPrimitivesOCV(cv::Mat& in,
             {
                 const auto& rp = cv::util::get<Rect>(p);
                 const auto color = converter.cvtColor(rp.color);
-                cv::rectangle(in, rp.rect, color , rp.thick);
+                cv::rectangle(in, rp.rect, color, rp.thick, rp.lt, rp.shift);
                 break;
             }
 
@@ -198,7 +198,7 @@ void drawPrimitivesOCV(cv::Mat& in,
             {
                 const auto& cp = cv::util::get<Circle>(p);
                 const auto color = converter.cvtColor(cp.color);
-                cv::circle(in, cp.center, cp.radius, color, cp.thick);
+                cv::circle(in, cp.center, cp.radius, color, cp.thick, cp.lt, cp.shift);
                 break;
             }
 
@@ -206,7 +206,7 @@ void drawPrimitivesOCV(cv::Mat& in,
             {
                 const auto& lp = cv::util::get<Line>(p);
                 const auto color = converter.cvtColor(lp.color);
-                cv::line(in, lp.pt1, lp.pt2, color, lp.thick);
+                cv::line(in, lp.pt1, lp.pt2, color, lp.thick, lp.lt, lp.shift);
                 break;
             }
 
index 010df5d..95f6954 100644 (file)
@@ -639,8 +639,8 @@ INSTANTIATE_TEST_CASE_P(RenderBGROCVTestRectsImpl, RenderBGROCVTestRects,
                                 Values(cv::Rect(100, 100, 200, 200)),
                                 Values(cv::Scalar(100, 50, 150)),
                                 Values(2),
-                                Values(LINE_8),
-                                Values(0)));
+                                Values(LINE_8, LINE_4),
+                                Values(0, 1)));
 
 INSTANTIATE_TEST_CASE_P(RenderNV12OCVTestRectsImpl, RenderNV12OCVTestRects,
                         Combine(Values(cv::Size(1280, 720)),
@@ -673,8 +673,8 @@ INSTANTIATE_TEST_CASE_P(RenderNV12OCVTestCirclesImpl, RenderNV12OCVTestCircles,
                                 Values(10),
                                 Values(cv::Scalar(100, 50, 150)),
                                 Values(2),
-                                Values(LINE_8),
-                                Values(0)));
+                                Values(LINE_8, LINE_4),
+                                Values(0, 1)));
 
 INSTANTIATE_TEST_CASE_P(RenderMFrameOCVTestCirclesImpl, RenderMFrameOCVTestCircles,
                         Combine(Values(cv::Size(1280, 720)),
index 412d41a..1e0f9b3 100755 (executable)
@@ -832,6 +832,7 @@ class CppHeaderParser(object):
                     ("GAPI_EXPORTS_W_SIMPLE","CV_EXPORTS_W_SIMPLE"),
                     ("GAPI_WRAP", "CV_WRAP"),
                     ("GAPI_PROP", "CV_PROP"),
+                    ("GAPI_PROP_RW", "CV_PROP_RW"),
                     ('defined(GAPI_STANDALONE)', '0'),
                 ])