From: Alexey Smirnov Date: Mon, 21 Sep 2020 19:08:58 +0000 (+0300) Subject: Merge pull request #18292 from smirnov-alexey:as/osd_serialization X-Git-Tag: submit/tizen/20210224.033012~2^2~42 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f6aa9ac304e418af0f2556609f3a467bc50b6e0f;p=platform%2Fupstream%2Fopencv.git Merge pull request #18292 from smirnov-alexey:as/osd_serialization [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 --- diff --git a/modules/gapi/include/opencv2/gapi/garray.hpp b/modules/gapi/include/opencv2/gapi/garray.hpp index d87ec8c2df..9118f4de98 100644 --- a/modules/gapi/include/opencv2/gapi/garray.hpp +++ b/modules/gapi/include/opencv2/gapi/garray.hpp @@ -261,8 +261,8 @@ namespace detail template void reset() { if (!m_ref) m_ref.reset(new VectorRefT()); - check(); + storeKind(); static_cast&>(*m_ref).reset(); } diff --git a/modules/gapi/include/opencv2/gapi/gcommon.hpp b/modules/gapi/include/opencv2/gapi/gcommon.hpp index 06499c1756..27b154b4b2 100644 --- a/modules/gapi/include/opencv2/gapi/gcommon.hpp +++ b/modules/gapi/include/opencv2/gapi/gcommon.hpp @@ -18,6 +18,7 @@ #include #include #include +#include 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 { static constexpr const OpaqueKind kind = OpaqueKind::CV_MAT; }; template<> struct GOpaqueTraits { static constexpr const OpaqueKind kind = OpaqueKind::CV_RECT; }; template<> struct GOpaqueTraits { static constexpr const OpaqueKind kind = OpaqueKind::CV_MAT; }; + template<> struct GOpaqueTraits + { static constexpr const OpaqueKind kind = OpaqueKind::CV_PRIM; }; // GArray is not supporting bool type for now due to difference in std::vector implementation - using GOpaqueTraitsArrayTypes = std::tuple; + using GOpaqueTraitsArrayTypes = std::tuple; // GOpaque is not supporting cv::Mat and cv::Scalar since there are GScalar and GMat types - using GOpaqueTraitsOpaqueTypes = std::tuple; + using GOpaqueTraitsOpaqueTypes = std::tuple; } // namespace detail // This definition is here because it is reused by both public(?) and internal diff --git a/modules/gapi/include/opencv2/gapi/gopaque.hpp b/modules/gapi/include/opencv2/gapi/gopaque.hpp index 9cfd588a7e..1c45d4683e 100644 --- a/modules/gapi/include/opencv2/gapi/gopaque.hpp +++ b/modules/gapi/include/opencv2/gapi/gopaque.hpp @@ -250,8 +250,8 @@ namespace detail template void reset() { if (!m_ref) m_ref.reset(new OpaqueRefT()); - check(); + storeKind(); static_cast&>(*m_ref).reset(); } diff --git a/modules/gapi/include/opencv2/gapi/render/render.hpp b/modules/gapi/include/opencv2/gapi/render/render.hpp index fcb69cb4f0..a4df304289 100644 --- a/modules/gapi/include/opencv2/gapi/render/render.hpp +++ b/modules/gapi/include/opencv2/gapi/render/render.hpp @@ -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 -#include +#include -#include #include -#include -#include -#include - - /** \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& 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 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; -//! @} gapi_draw_prims - using GMat2 = std::tuple; using GMatDesc2 = std::tuple; - //! @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 index 0000000000..08b14d1ddd --- /dev/null +++ b/modules/gapi/include/opencv2/gapi/render/render_types.hpp @@ -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 +#include + +#include +#include +#include + +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& 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 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; +//! @} gapi_draw_prims + +} // namespace draw +} // namespace wip +} // namespace gapi +} // namespace cv + +#endif // OPENCV_GAPI_RENDER_TYPES_HPP diff --git a/modules/gapi/src/backends/common/serialization.cpp b/modules/gapi/src/backends/common/serialization.cpp index ea97f175d9..ab7626d43d 100644 --- a/modules/gapi/src/backends/common/serialization.cpp +++ b/modules/gapi/src/backends/common/serialization.cpp @@ -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) diff --git a/modules/gapi/src/backends/common/serialization.hpp b/modules/gapi/src/backends/common/serialization.hpp index 90169f6c38..9286bc4391 100644 --- a/modules/gapi/src/backends/common/serialization.hpp +++ b/modules/gapi/src/backends/common/serialization.hpp @@ -14,6 +14,7 @@ #include // 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 ///////////////////////////////////////////////////////////////// diff --git a/modules/gapi/test/gapi_array_tests.cpp b/modules/gapi/test/gapi_array_tests.cpp index 74a531cad4..2faf538ae9 100644 --- a/modules/gapi/test/gapi_array_tests.cpp +++ b/modules/gapi/test/gapi_array_tests.cpp @@ -274,4 +274,13 @@ TEST(GArray_VectorRef, TestRvalue) auto v = std::vector{3, 5, -4}; EXPECT_EQ(vref.rref(), v); } + +TEST(GArray_VectorRef, TestReset) +{ + // Warning: this test is testing some not-very-public APIs + cv::detail::VectorRef vref(std::vector{3, 5, -4}); + EXPECT_EQ(cv::detail::OpaqueKind::CV_INT, vref.getKind()); + vref.reset(); + EXPECT_EQ(cv::detail::OpaqueKind::CV_INT, vref.getKind()); +} } // namespace opencv_test diff --git a/modules/gapi/test/gapi_opaque_tests.cpp b/modules/gapi/test/gapi_opaque_tests.cpp index 6a5cb1a041..c76c97ad01 100644 --- a/modules/gapi/test/gapi_opaque_tests.cpp +++ b/modules/gapi/test/gapi_opaque_tests.cpp @@ -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(); + EXPECT_EQ(cv::detail::OpaqueKind::CV_INT, opref.getKind()); +} } // namespace opencv_test diff --git a/modules/gapi/test/s11n/gapi_s11n_tests.cpp b/modules/gapi/test/s11n/gapi_s11n_tests.cpp index 561fcb2eb0..5b5be997b9 100644 --- a/modules/gapi/test/s11n/gapi_s11n_tests.cpp +++ b/modules/gapi/test/s11n/gapi_s11n_tests.cpp @@ -348,5 +348,4 @@ TEST_F(S11N_Basic, Test_Bind_RunArgs_MatScalar) { i++; } } - } // namespace opencv_test diff --git a/modules/gapi/test/s11n/gapi_sample_pipelines_s11n.cpp b/modules/gapi/test/s11n/gapi_sample_pipelines_s11n.cpp index 930d9961c0..1d8f7514ea 100644 --- a/modules/gapi/test/s11n/gapi_sample_pipelines_s11n.cpp +++ b/modules/gapi/test/s11n/gapi_sample_pipelines_s11n.cpp @@ -8,8 +8,9 @@ #include "../test_precomp.hpp" #include - #include +#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 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 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(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> 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 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 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(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> pp{points}; + cv::fillPoly(ref_mat, pp, color, lt, shift); + + EXPECT_EQ(cv::norm(input, ref_mat), 0); +} } // namespace opencv_test