From 0cdbdfdf9fe654f6645615429aa5338555251580 Mon Sep 17 00:00:00 2001 From: Dmitry Budnikov Date: Mon, 15 Feb 2021 22:57:22 +0300 Subject: [PATCH] Merge pull request #19516 from dbudniko:dbudniko/gapi_render_frame_cpu Render Frame NV12 on CPU * render frame on CPU * doxygen fix * address review from Alexey * comment fixes * Address comments from Ruslan * remove NV12 specific * mat clone and more renaming * misprint fix --- .../gapi/include/opencv2/gapi/render/render.hpp | 30 ++ modules/gapi/src/api/render.cpp | 20 ++ modules/gapi/src/backends/render/grenderocv.cpp | 77 ++++- modules/gapi/test/common/gapi_render_tests.hpp | 2 + modules/gapi/test/render/gapi_render_tests_ocv.cpp | 314 +++++++++++++++++++++ 5 files changed, 442 insertions(+), 1 deletion(-) diff --git a/modules/gapi/include/opencv2/gapi/render/render.hpp b/modules/gapi/include/opencv2/gapi/render/render.hpp index a4df304..a84c26c 100644 --- a/modules/gapi/include/opencv2/gapi/render/render.hpp +++ b/modules/gapi/include/opencv2/gapi/render/render.hpp @@ -97,6 +97,17 @@ void GAPI_EXPORTS render(cv::Mat& y_plane, const Prims& prims, cv::GCompileArgs&& args = {}); +/** @brief The function renders on the input media frame passed drawing primitivies + +@param frame input Media Frame : @ref cv::MediaFrame. +@param prims vector of drawing primitivies +@param args graph compile time parameters +*/ +void GAPI_EXPORTS render(cv::MediaFrame& frame, + const Prims& prims, + cv::GCompileArgs&& args = {}); + + G_TYPED_KERNEL_M(GRenderNV12, )>, "org.opencv.render.nv12") { static GMatDesc2 outMeta(GMatDesc y_plane, GMatDesc uv_plane, GArrayDesc) @@ -113,6 +124,14 @@ G_TYPED_KERNEL(GRenderBGR, )>, "or } }; +G_TYPED_KERNEL(GRenderFrame, )>, "org.opencv.render.frame") +{ + static GFrameDesc outMeta(GFrameDesc desc, GArrayDesc) + { + return desc; + } +}; + /** @brief Renders on 3 channels input Output image must be 8-bit unsigned planar 3-channel image @@ -134,6 +153,17 @@ uv image must be 8-bit unsigned planar 2-channel image @ref CV_8UC2 GAPI_EXPORTS GMat2 renderNV12(const GMat& y, const GMat& uv, const GArray& prims); + +/** @brief Renders Media Frame + +Output media frame frame cv::MediaFrame + +@param m_frame input image: cv::MediaFrame @ref cv::MediaFrame +@param prims draw primitives +*/ +GAPI_EXPORTS GFrame renderFrame(const GFrame& m_frame, + const GArray& prims); + //! @} gapi_draw_api } // namespace draw diff --git a/modules/gapi/src/api/render.cpp b/modules/gapi/src/api/render.cpp index 428ebda..cf0dac0 100644 --- a/modules/gapi/src/api/render.cpp +++ b/modules/gapi/src/api/render.cpp @@ -33,6 +33,20 @@ void cv::gapi::wip::draw::render(cv::Mat& y_plane, cv::gout(y_plane, uv_plane), std::move(args)); } +void cv::gapi::wip::draw::render(cv::MediaFrame& frame, + const Prims& prims, + cv::GCompileArgs&& args) +{ + cv::GFrame in, out; + cv::GArray arr; + out = cv::gapi::wip::draw::renderFrame(in, arr); + + cv::GComputation comp(cv::GIn(in, arr), cv::GOut(out)); + comp.apply(cv::gin(frame, prims), + cv::gout(frame), std::move(args)); +} + + void cv::gapi::wip::draw::cvtYUVToNV12(const cv::Mat& yuv, cv::Mat& y, cv::Mat& uv) @@ -69,3 +83,9 @@ cv::gapi::wip::draw::renderNV12(const cv::GMat& y, { return cv::gapi::wip::draw::GRenderNV12::on(y, uv, prims); } + +cv::GFrame cv::gapi::wip::draw::renderFrame(const cv::GFrame& frame, + const cv::GArray& prims) +{ + return cv::gapi::wip::draw::GRenderFrame::on(frame, prims); +} diff --git a/modules/gapi/src/backends/render/grenderocv.cpp b/modules/gapi/src/backends/render/grenderocv.cpp index 71be889..2652284 100644 --- a/modules/gapi/src/backends/render/grenderocv.cpp +++ b/modules/gapi/src/backends/render/grenderocv.cpp @@ -114,8 +114,83 @@ GAPI_OCV_KERNEL_ST(RenderNV12OCVImpl, cv::gapi::wip::draw::GRenderNV12, RenderOC } }; +GAPI_OCV_KERNEL_ST(RenderFrameOCVImpl, cv::gapi::wip::draw::GRenderFrame, RenderOCVState) +{ + static void run(const cv::MediaFrame & in, + const cv::gapi::wip::draw::Prims & prims, + cv::MediaFrame & out, + RenderOCVState & state) + { + GAPI_Assert(in.desc().fmt == cv::MediaFormat::NV12); + + // FIXME: consider a better approach (aka native inplace operation) + // Non-intuitive logic with shared_ptr Priv class + out = in; + + auto desc = out.desc(); + auto w_out = out.access(cv::MediaFrame::Access::W); + + auto out_y = cv::Mat(desc.size, CV_8UC1, w_out.ptr[0], w_out.stride[0]); + auto out_uv = cv::Mat(desc.size / 2, CV_8UC2, w_out.ptr[1], w_out.stride[1]); + + auto r_in = in.access(cv::MediaFrame::Access::R); + + auto in_y = cv::Mat(desc.size, CV_8UC1, r_in.ptr[0], r_in.stride[0]); + auto in_uv = cv::Mat(desc.size / 2, CV_8UC2, r_in.ptr[1], r_in.stride[1]); + + /* FIXME How to render correctly on NV12 format ? + * + * Rendering on NV12 via OpenCV looks like this: + * + * y --------> 1)(NV12 -> YUV) -> yuv -> 2)draw -> yuv -> 3)split -------> out_y + * ^ | + * | | + * uv -------------- `----------> out_uv + * + * + * 1) Collect yuv mat from two planes, uv plain in two times less than y plane + * so, upsample uv in two times, with bilinear interpolation + * + * 2) Render primitives on YUV + * + * 3) Convert yuv to NV12 (using bilinear interpolation) + * + */ + + // NV12 -> YUV + cv::Mat upsample_uv, yuv; + cv::resize(in_uv, upsample_uv, in_uv.size() * 2, cv::INTER_LINEAR); + cv::merge(std::vector{in_y, upsample_uv}, yuv); + + cv::gapi::wip::draw::drawPrimitivesOCVYUV(yuv, prims, state.ftpr); + + // YUV -> NV12 + cv::Mat out_u, out_v, uv_plane; + std::vector chs = { out_y, out_u, out_v }; + cv::split(yuv, chs); + cv::merge(std::vector{chs[1], chs[2]}, uv_plane); + cv::resize(uv_plane, out_uv, uv_plane.size() / 2, cv::INTER_LINEAR); + } + + static void setup(const cv::GFrameDesc& /* in_nv12 */, + const cv::GArrayDesc& /* prims */, + std::shared_ptr&state, + const cv::GCompileArgs & args) + { + using namespace cv::gapi::wip::draw; + auto has_freetype_font = cv::gapi::getCompileArg(args); + state = std::make_shared(); + + if (has_freetype_font) + { + state->ftpr = std::make_shared(has_freetype_font->path); + } + } +}; + + cv::gapi::GKernelPackage cv::gapi::render::ocv::kernels() { - const static auto pkg = cv::gapi::kernels(); + const static auto pkg = cv::gapi::kernels(); return pkg; } diff --git a/modules/gapi/test/common/gapi_render_tests.hpp b/modules/gapi/test/common/gapi_render_tests.hpp index 1f28e92..30caca9 100644 --- a/modules/gapi/test/common/gapi_render_tests.hpp +++ b/modules/gapi/test/common/gapi_render_tests.hpp @@ -130,6 +130,8 @@ struct Fixture : public RenderBGRTestBase API { \ #define GAPI_RENDER_TEST_FIXTURES(Fixture, API, Number, ...) \ GAPI_RENDER_TEST_FIXTURE_BGR(RenderBGR##Fixture, GET_VA_ARGS(API), Number, __VA_ARGS__) \ GAPI_RENDER_TEST_FIXTURE_NV12(RenderNV12##Fixture, GET_VA_ARGS(API), Number, __VA_ARGS__) \ + GAPI_RENDER_TEST_FIXTURE_NV12(RenderMFrame##Fixture, GET_VA_ARGS(API), Number, __VA_ARGS__) \ + using Points = std::vector; GAPI_RENDER_TEST_FIXTURES(TestTexts, FIXTURE_API(std::string, cv::Point, double, cv::Scalar), 4, text, org, fs, color) diff --git a/modules/gapi/test/render/gapi_render_tests_ocv.cpp b/modules/gapi/test/render/gapi_render_tests_ocv.cpp index 88b5d88..010df5d 100644 --- a/modules/gapi/test/render/gapi_render_tests_ocv.cpp +++ b/modules/gapi/test/render/gapi_render_tests_ocv.cpp @@ -73,6 +73,54 @@ TEST_P(RenderNV12OCVTestTexts, AccuracyTest) } } +class TestMediaNV12 final : public cv::MediaFrame::IAdapter { + cv::Mat m_y; + cv::Mat m_uv; +public: + TestMediaNV12(cv::Mat y, cv::Mat uv) : m_y(y), m_uv(uv) { + } + cv::GFrameDesc meta() const override { + return cv::GFrameDesc{ cv::MediaFormat::NV12, cv::Size(m_y.cols, m_y.rows) }; + } + cv::MediaFrame::View access(cv::MediaFrame::Access) override { + cv::MediaFrame::View::Ptrs pp = { + m_y.ptr(), m_uv.ptr(), nullptr, nullptr + }; + cv::MediaFrame::View::Strides ss = { + m_y.step, m_uv.step, 0u, 0u + }; + return cv::MediaFrame::View(std::move(pp), std::move(ss)); + } +}; + +TEST_P(RenderMFrameOCVTestTexts, AccuracyTest) +{ + // G-API code ////////////////////////////////////////////////////////////// + cv::gapi::wip::draw::Prims prims; + prims.emplace_back(cv::gapi::wip::draw::Text{ text, org, ff, fs, color, thick, lt, blo }); + cv::MediaFrame nv12 = cv::MediaFrame::Create(y_gapi_mat, uv_gapi_mat); + cv::gapi::wip::draw::render(nv12, prims); + + // OpenCV code ////////////////////////////////////////////////////////////// + { + // NV12 -> YUV + cv::Mat yuv; + cv::gapi::wip::draw::cvtNV12ToYUV(y_ref_mat, uv_ref_mat, yuv); + + cv::putText(yuv, text, org, ff, fs, cvtBGRToYUVC(color), thick, lt, blo); + + // YUV -> NV12 + cv::gapi::wip::draw::cvtYUVToNV12(yuv, y_ref_mat, uv_ref_mat); + } + + // Comparison ////////////////////////////////////////////////////////////// + { + EXPECT_EQ(0, cv::norm(y_gapi_mat, y_ref_mat)); + EXPECT_EQ(0, cv::norm(uv_gapi_mat, uv_ref_mat)); + } +} + + # ifdef HAVE_FREETYPE TEST_P(RenderBGROCVTestFTexts, AccuracyTest) @@ -97,6 +145,23 @@ TEST_P(RenderNV12OCVTestFTexts, AccuracyTest) }))); } +TEST_P(RenderMFrameOCVTestFTexts, AccuracyTest) +{ + // G-API code ////////////////////////////////////////////////////////////// + cv::Mat y_copy_mat = y_gapi_mat.clone(); + cv::Mat uv_copy_mat = uv_gapi_mat.clone(); + cv::gapi::wip::draw::Prims prims; + prims.emplace_back(cv::gapi::wip::draw::FText{ text, org, fh, color }); + cv::MediaFrame nv12 = cv::MediaFrame::Create(y_gapi_mat, uv_gapi_mat); + EXPECT_NO_THROW(cv::gapi::wip::draw::render(nv12, prims, + cv::compile_args(cv::gapi::wip::draw::freetype_font{ + "/usr/share/fonts/truetype/wqy/wqy-microhei.ttc" + }))); + EXPECT_NE(0, cv::norm(y_gapi_mat, y_copy_mat)); + EXPECT_NE(0, cv::norm(uv_gapi_mat, uv_copy_mat)); +} + + static std::wstring to_wstring(const char* bytes) { std::wstring_convert, wchar_t> converter; @@ -164,6 +229,33 @@ TEST_P(RenderNV12OCVTestRects, AccuracyTest) } } +TEST_P(RenderMFrameOCVTestRects, AccuracyTest) +{ + // G-API code ////////////////////////////////////////////////////////////// + cv::gapi::wip::draw::Prims prims; + prims.emplace_back(cv::gapi::wip::draw::Rect{ rect, color, thick, lt, shift }); + cv::MediaFrame nv12 = cv::MediaFrame::Create(y_gapi_mat, uv_gapi_mat); + cv::gapi::wip::draw::render(nv12, prims); + + // OpenCV code ////////////////////////////////////////////////////////////// + { + // NV12 -> YUV + cv::Mat yuv; + cv::gapi::wip::draw::cvtNV12ToYUV(y_ref_mat, uv_ref_mat, yuv); + + cv::rectangle(yuv, rect, cvtBGRToYUVC(color), thick, lt, shift); + + // YUV -> NV12 + cv::gapi::wip::draw::cvtYUVToNV12(yuv, y_ref_mat, uv_ref_mat); + } + + // Comparison ////////////////////////////////////////////////////////////// + { + EXPECT_EQ(0, cv::norm(y_gapi_mat, y_ref_mat)); + EXPECT_EQ(0, cv::norm(uv_gapi_mat, uv_ref_mat)); + } +} + TEST_P(RenderBGROCVTestCircles, AccuracyTest) { // G-API code ////////////////////////////////////////////////////////////// @@ -208,6 +300,33 @@ TEST_P(RenderNV12OCVTestCircles, AccuracyTest) } } +TEST_P(RenderMFrameOCVTestCircles, AccuracyTest) +{ + // G-API code ////////////////////////////////////////////////////////////// + cv::gapi::wip::draw::Prims prims; + prims.emplace_back(cv::gapi::wip::draw::Circle{ center, radius, color, thick, lt, shift }); + cv::MediaFrame nv12 = cv::MediaFrame::Create(y_gapi_mat, uv_gapi_mat); + cv::gapi::wip::draw::render(nv12, prims); + + // OpenCV code ////////////////////////////////////////////////////////////// + { + // NV12 -> YUV + cv::Mat yuv; + cv::gapi::wip::draw::cvtNV12ToYUV(y_ref_mat, uv_ref_mat, yuv); + + cv::circle(yuv, center, radius, cvtBGRToYUVC(color), thick, lt, shift); + + // YUV -> NV12 + cv::gapi::wip::draw::cvtYUVToNV12(yuv, y_ref_mat, uv_ref_mat); + } + + // Comparison ////////////////////////////////////////////////////////////// + { + EXPECT_EQ(0, cv::norm(y_gapi_mat, y_ref_mat)); + EXPECT_EQ(0, cv::norm(uv_gapi_mat, uv_ref_mat)); + } +} + TEST_P(RenderBGROCVTestLines, AccuracyTest) { // G-API code ////////////////////////////////////////////////////////////// @@ -252,6 +371,33 @@ TEST_P(RenderNV12OCVTestLines, AccuracyTest) } } +TEST_P(RenderMFrameOCVTestLines, AccuracyTest) +{ + // G-API code ////////////////////////////////////////////////////////////// + cv::gapi::wip::draw::Prims prims; + prims.emplace_back(cv::gapi::wip::draw::Line{ pt1, pt2, color, thick, lt, shift }); + cv::MediaFrame nv12 = cv::MediaFrame::Create(y_gapi_mat, uv_gapi_mat); + cv::gapi::wip::draw::render(nv12, prims); + + // OpenCV code ////////////////////////////////////////////////////////////// + { + // NV12 -> YUV + cv::Mat yuv; + cv::gapi::wip::draw::cvtNV12ToYUV(y_ref_mat, uv_ref_mat, yuv); + + cv::line(yuv, pt1, pt2, cvtBGRToYUVC(color), thick, lt, shift); + + // YUV -> NV12 + cv::gapi::wip::draw::cvtYUVToNV12(yuv, y_ref_mat, uv_ref_mat); + } + + // Comparison ////////////////////////////////////////////////////////////// + { + EXPECT_EQ(0, cv::norm(y_gapi_mat, y_ref_mat)); + EXPECT_EQ(0, cv::norm(uv_gapi_mat, uv_ref_mat)); + } +} + TEST_P(RenderBGROCVTestMosaics, AccuracyTest) { // G-API code ////////////////////////////////////////////////////////////// @@ -296,6 +442,33 @@ TEST_P(RenderNV12OCVTestMosaics, AccuracyTest) } } +TEST_P(RenderMFrameOCVTestMosaics, AccuracyTest) +{ + // G-API code ////////////////////////////////////////////////////////////// + cv::gapi::wip::draw::Prims prims; + prims.emplace_back(cv::gapi::wip::draw::Mosaic{ mos, cellsz, decim }); + cv::MediaFrame nv12 = cv::MediaFrame::Create(y_gapi_mat, uv_gapi_mat); + cv::gapi::wip::draw::render(nv12, prims); + + // OpenCV code ////////////////////////////////////////////////////////////// + { + // NV12 -> YUV + cv::Mat yuv; + cv::gapi::wip::draw::cvtNV12ToYUV(y_ref_mat, uv_ref_mat, yuv); + + drawMosaicRef(yuv, mos, cellsz); + + // YUV -> NV12 + cv::gapi::wip::draw::cvtYUVToNV12(yuv, y_ref_mat, uv_ref_mat); + } + + // Comparison ////////////////////////////////////////////////////////////// + { + EXPECT_EQ(0, cv::norm(y_gapi_mat, y_ref_mat)); + EXPECT_EQ(0, cv::norm(uv_gapi_mat, uv_ref_mat)); + } +} + TEST_P(RenderBGROCVTestImages, AccuracyTest) { cv::Mat img(rect.size(), CV_8UC3, color); @@ -352,6 +525,40 @@ TEST_P(RenderNV12OCVTestImages, AccuracyTest) } } +TEST_P(RenderMFrameOCVTestImages, AccuracyTest) +{ + cv::Mat img(rect.size(), CV_8UC3, color); + cv::Mat alpha(rect.size(), CV_32FC1, transparency); + auto tl = rect.tl(); + cv::Point org = { tl.x, tl.y + rect.size().height }; + + // G-API code ////////////////////////////////////////////////////////////// + cv::gapi::wip::draw::Prims prims; + prims.emplace_back(cv::gapi::wip::draw::Image{ org, img, alpha }); + cv::MediaFrame nv12 = cv::MediaFrame::Create(y_gapi_mat, uv_gapi_mat); + cv::gapi::wip::draw::render(nv12, prims); + + // OpenCV code ////////////////////////////////////////////////////////////// + { + // NV12 -> YUV + cv::Mat yuv; + cv::gapi::wip::draw::cvtNV12ToYUV(y_ref_mat, uv_ref_mat, yuv); + + cv::Mat yuv_img; + cv::cvtColor(img, yuv_img, cv::COLOR_BGR2YUV); + blendImageRef(yuv, org, yuv_img, alpha); + + // YUV -> NV12 + cv::gapi::wip::draw::cvtYUVToNV12(yuv, y_ref_mat, uv_ref_mat); + } + + // Comparison ////////////////////////////////////////////////////////////// + { + EXPECT_EQ(0, cv::norm(y_gapi_mat, y_ref_mat)); + EXPECT_EQ(0, cv::norm(uv_gapi_mat, uv_ref_mat)); + } +} + TEST_P(RenderBGROCVTestPolylines, AccuracyTest) { // G-API code ////////////////////////////////////////////////////////////// @@ -398,6 +605,34 @@ TEST_P(RenderNV12OCVTestPolylines, AccuracyTest) } } +TEST_P(RenderMFrameOCVTestPolylines, AccuracyTest) +{ + // G-API code ////////////////////////////////////////////////////////////// + cv::gapi::wip::draw::Prims prims; + prims.emplace_back(cv::gapi::wip::draw::Poly{ points, color, thick, lt, shift }); + cv::MediaFrame nv12 = cv::MediaFrame::Create(y_gapi_mat, uv_gapi_mat); + cv::gapi::wip::draw::render(nv12, prims); + + // OpenCV code ////////////////////////////////////////////////////////////// + { + // NV12 -> YUV + cv::Mat yuv; + cv::gapi::wip::draw::cvtNV12ToYUV(y_ref_mat, uv_ref_mat, yuv); + + 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); + } + + // Comparison ////////////////////////////////////////////////////////////// + { + EXPECT_EQ(0, cv::norm(y_gapi_mat, y_ref_mat)); + EXPECT_EQ(0, cv::norm(uv_gapi_mat, uv_ref_mat)); + } +} + // FIXME avoid code duplicate for NV12 and BGR cases INSTANTIATE_TEST_CASE_P(RenderBGROCVTestRectsImpl, RenderBGROCVTestRects, Combine(Values(cv::Size(1280, 720)), @@ -415,6 +650,14 @@ INSTANTIATE_TEST_CASE_P(RenderNV12OCVTestRectsImpl, RenderNV12OCVTestRects, Values(LINE_8), Values(0))); +INSTANTIATE_TEST_CASE_P(RenderMFrameOCVTestRectsImpl, RenderMFrameOCVTestRects, + Combine(Values(cv::Size(1280, 720)), + Values(cv::Rect(100, 100, 200, 200)), + Values(cv::Scalar(100, 50, 150)), + Values(2), + Values(LINE_8), + Values(0))); + INSTANTIATE_TEST_CASE_P(RenderBGROCVTestCirclesImpl, RenderBGROCVTestCircles, Combine(Values(cv::Size(1280, 720)), Values(cv::Point(100, 100)), @@ -433,6 +676,15 @@ INSTANTIATE_TEST_CASE_P(RenderNV12OCVTestCirclesImpl, RenderNV12OCVTestCircles, Values(LINE_8), Values(0))); +INSTANTIATE_TEST_CASE_P(RenderMFrameOCVTestCirclesImpl, RenderMFrameOCVTestCircles, + Combine(Values(cv::Size(1280, 720)), + Values(cv::Point(100, 100)), + Values(10), + Values(cv::Scalar(100, 50, 150)), + Values(2), + Values(LINE_8), + Values(0))); + INSTANTIATE_TEST_CASE_P(RenderBGROCVTestLinesImpl, RenderBGROCVTestLines, Combine(Values(cv::Size(1280, 720)), Values(cv::Point(100, 100)), @@ -451,6 +703,15 @@ INSTANTIATE_TEST_CASE_P(RenderNV12OCVTestLinesImpl, RenderNV12OCVTestLines, Values(LINE_8), Values(0))); +INSTANTIATE_TEST_CASE_P(RenderMFrameOCVTestLinesImpl, RenderMFrameOCVTestLines, + Combine(Values(cv::Size(1280, 720)), + Values(cv::Point(100, 100)), + Values(cv::Point(200, 200)), + Values(cv::Scalar(100, 50, 150)), + Values(2), + Values(LINE_8), + Values(0))); + INSTANTIATE_TEST_CASE_P(RenderBGROCVTestTextsImpl, RenderBGROCVTestTexts, Combine(Values(cv::Size(1280, 720)), Values("SomeText"), @@ -473,6 +734,18 @@ INSTANTIATE_TEST_CASE_P(RenderNV12OCVTestTextsImpl, RenderNV12OCVTestTexts, Values(LINE_8), Values(false))); +INSTANTIATE_TEST_CASE_P(RenderMFrameOCVTestTextsImpl, RenderMFrameOCVTestTexts, + Combine(Values(cv::Size(1280, 720)), + Values("SomeText"), + Values(cv::Point(200, 200)), + Values(FONT_HERSHEY_SIMPLEX), + Values(2.0), + Values(cv::Scalar(0, 255, 0)), + Values(2), + Values(LINE_8), + Values(false))); + + #ifdef HAVE_FREETYPE INSTANTIATE_TEST_CASE_P(RenderBGROCVTestFTextsImpl, RenderBGROCVTestFTexts, @@ -490,6 +763,15 @@ INSTANTIATE_TEST_CASE_P(RenderNV12OCVTestFTextsImpl, RenderNV12OCVTestFTexts, Values(cv::Point(200, 200)), Values(64), Values(cv::Scalar(0, 255, 0)))); + +INSTANTIATE_TEST_CASE_P(RenderMFrameOCVTestFTextsImpl, RenderMFrameOCVTestFTexts, + Combine(Values(cv::Size(1280, 720)), + Values(to_wstring("\xe4\xbd\xa0\xe5\xa5\xbd\xef\xbc\x8c\xe4\xb8\x96\xe7\x95\x8c"), + to_wstring("\xe3\x80\xa4\xe3\x80\xa5\xe3\x80\xa6\xe3\x80\xa7\xe3\x80\xa8\xe3\x80\x85\xe3\x80\x86")), + Values(cv::Point(200, 200)), + Values(64), + Values(cv::Scalar(0, 255, 0)))); + #endif // HAVE_FREETYPE // FIXME Implement a macros to instantiate the tests because BGR and NV12 have the same parameters @@ -530,6 +812,24 @@ INSTANTIATE_TEST_CASE_P(RenderNV12OCVTestMosaicsImpl, RenderNV12OCVTestMosaics, Values(25), Values(0))); +INSTANTIATE_TEST_CASE_P(RenderMFrameOCVTestMosaicsImpl, RenderMFrameOCVTestMosaics, + Combine(Values(cv::Size(1280, 720)), + Values(cv::Rect(100, 100, 200, 200), // Normal case + cv::Rect(-50, -50, 200, 200), // Intersection with left-top corner + cv::Rect(-50, 100, 200, 200), // Intersection with left side + cv::Rect(-50, 600, 200, 200), // Intersection with left-bottom corner + cv::Rect(100, 600, 200, 200), // Intersection with bottom side + cv::Rect(1200, 700, 200, 200), // Intersection with right-bottom corner + cv::Rect(1200, 400, 200, 200), // Intersection with right side + cv::Rect(1200, -50, 200, 200), // Intersection with right-top corner + cv::Rect(500, -50, 200, 200), // Intersection with top side + cv::Rect(-100, 300, 1480, 300), // From left to right side with intersection + cv::Rect(5000, 2000, 100, 100), // Outside image + cv::Rect(-300, -300, 3000, 3000), // Cover all image + cv::Rect(100, 100, -500, -500)), // Negative width and height + Values(25), + Values(0))); + INSTANTIATE_TEST_CASE_P(RenderBGROCVTestImagesImpl, RenderBGROCVTestImages, Combine(Values(cv::Size(1280, 720)), Values(cv::Rect(100, 100, 200, 200)), @@ -542,6 +842,12 @@ INSTANTIATE_TEST_CASE_P(RenderNV12OCVTestImagesImpl, RenderNV12OCVTestImages, Values(cv::Scalar(100, 150, 60)), Values(1.0))); +INSTANTIATE_TEST_CASE_P(RenderMFrameOCVTestImagesImpl, RenderMFrameOCVTestImages, + Combine(Values(cv::Size(1280, 720)), + Values(cv::Rect(100, 100, 200, 200)), + Values(cv::Scalar(100, 150, 60)), + Values(1.0))); + INSTANTIATE_TEST_CASE_P(RenderBGROCVTestPolylinesImpl, RenderBGROCVTestPolylines, Combine(Values(cv::Size(1280, 720)), Values(std::vector{{100, 100}, {200, 200}, {150, 300}, {400, 150}}), @@ -557,4 +863,12 @@ INSTANTIATE_TEST_CASE_P(RenderNV12OCVTestPolylinesImpl, RenderNV12OCVTestPolylin Values(2), Values(LINE_8), Values(0))); + +INSTANTIATE_TEST_CASE_P(RenderMFrameOCVTestPolylinesImpl, RenderMFrameOCVTestPolylines, + Combine(Values(cv::Size(1280, 720)), + Values(std::vector{ {100, 100}, { 200, 200 }, { 150, 300 }, { 400, 150 }}), + Values(cv::Scalar(100, 150, 60)), + Values(2), + Values(LINE_8), + Values(0))); } -- 2.7.4