diff --git a/modules/gapi/src/api/render_ocv.cpp b/modules/gapi/src/api/render_ocv.cpp index 6c035f6d70..d87581e773 100644 --- a/modules/gapi/src/api/render_ocv.cpp +++ b/modules/gapi/src/api/render_ocv.cpp @@ -16,13 +16,54 @@ namespace draw // FIXME Support `decim` mosaic parameter inline void mosaic(cv::Mat& mat, const cv::Rect &rect, int cellSz) { - cv::Mat msc_roi = mat(rect); - int crop_x = msc_roi.cols - msc_roi.cols % cellSz; - int crop_y = msc_roi.rows - msc_roi.rows % cellSz; + cv::Rect mat_rect(0, 0, mat.cols, mat.rows); + auto intersection = mat_rect & rect; - for(int i = 0; i < crop_y; i += cellSz ) { - for(int j = 0; j < crop_x; j += cellSz) { - auto cell_roi = msc_roi(cv::Rect(j, i, cellSz, cellSz)); + cv::Mat msc_roi = mat(intersection); + + bool has_crop_x = false; + bool has_crop_y = false; + + int cols = msc_roi.cols; + int rows = msc_roi.rows; + + if (msc_roi.cols % cellSz != 0) + { + has_crop_x = true; + cols -= msc_roi.cols % cellSz; + } + + if (msc_roi.rows % cellSz != 0) + { + has_crop_y = true; + rows -= msc_roi.rows % cellSz; + } + + cv::Mat cell_roi; + for(int i = 0; i < rows; i += cellSz ) + { + for(int j = 0; j < cols; j += cellSz) + { + cell_roi = msc_roi(cv::Rect(j, i, cellSz, cellSz)); + cell_roi = cv::mean(cell_roi); + } + if (has_crop_x) + { + cell_roi = msc_roi(cv::Rect(cols, i, msc_roi.cols - cols, cellSz)); + cell_roi = cv::mean(cell_roi); + } + } + + if (has_crop_y) + { + for(int j = 0; j < cols; j += cellSz) + { + cell_roi = msc_roi(cv::Rect(j, rows, cellSz, msc_roi.rows - rows)); + cell_roi = cv::mean(cell_roi); + } + if (has_crop_x) + { + cell_roi = msc_roi(cv::Rect(cols, rows, msc_roi.cols - cols, msc_roi.rows - rows)); cell_roi = cv::mean(cell_roi); } } diff --git a/modules/gapi/test/common/gapi_render_tests.cpp b/modules/gapi/test/common/gapi_render_tests.cpp index 81f7c5b86e..e29406d783 100644 --- a/modules/gapi/test/common/gapi_render_tests.cpp +++ b/modules/gapi/test/common/gapi_render_tests.cpp @@ -21,13 +21,54 @@ cv::Scalar cvtBGRToYUVC(const cv::Scalar& bgr) void drawMosaicRef(const cv::Mat& mat, const cv::Rect &rect, int cellSz) { - cv::Mat msc_roi = mat(rect); - int crop_x = msc_roi.cols - msc_roi.cols % cellSz; - int crop_y = msc_roi.rows - msc_roi.rows % cellSz; + cv::Rect mat_rect(0, 0, mat.cols, mat.rows); + auto intersection = mat_rect & rect; - for(int i = 0; i < crop_y; i += cellSz ) { - for(int j = 0; j < crop_x; j += cellSz) { - auto cell_roi = msc_roi(cv::Rect(j, i, cellSz, cellSz)); + cv::Mat msc_roi = mat(intersection); + + bool has_crop_x = false; + bool has_crop_y = false; + + int cols = msc_roi.cols; + int rows = msc_roi.rows; + + if (msc_roi.cols % cellSz != 0) + { + has_crop_x = true; + cols -= msc_roi.cols % cellSz; + } + + if (msc_roi.rows % cellSz != 0) + { + has_crop_y = true; + rows -= msc_roi.rows % cellSz; + } + + cv::Mat cell_roi; + for(int i = 0; i < rows; i += cellSz ) + { + for(int j = 0; j < cols; j += cellSz) + { + cell_roi = msc_roi(cv::Rect(j, i, cellSz, cellSz)); + cell_roi = cv::mean(cell_roi); + } + if (has_crop_x) + { + cell_roi = msc_roi(cv::Rect(cols, i, msc_roi.cols - cols, cellSz)); + cell_roi = cv::mean(cell_roi); + } + } + + if (has_crop_y) + { + for(int j = 0; j < cols; j += cellSz) + { + cell_roi = msc_roi(cv::Rect(j, rows, cellSz, msc_roi.rows - rows)); + cell_roi = cv::mean(cell_roi); + } + if (has_crop_x) + { + cell_roi = msc_roi(cv::Rect(cols, rows, msc_roi.cols - cols, msc_roi.rows - rows)); cell_roi = cv::mean(cell_roi); } } diff --git a/modules/gapi/test/render/gapi_render_tests_ocv.cpp b/modules/gapi/test/render/gapi_render_tests_ocv.cpp index 19701c8348..f727d977aa 100644 --- a/modules/gapi/test/render/gapi_render_tests_ocv.cpp +++ b/modules/gapi/test/render/gapi_render_tests_ocv.cpp @@ -493,15 +493,41 @@ INSTANTIATE_TEST_CASE_P(RenderNV12OCVTestFTextsImpl, RenderNV12OCVTestFTexts, 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 + INSTANTIATE_TEST_CASE_P(RenderBGROCVTestMosaicsImpl, RenderBGROCVTestMosaics, Combine(Values(cv::Size(1280, 720)), - Values(cv::Rect(100, 100, 200, 200)), + 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(RenderNV12OCVTestMosaicsImpl, RenderNV12OCVTestMosaics, Combine(Values(cv::Size(1280, 720)), - Values(cv::Rect(100, 100, 200, 200)), + 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)));