diff --git a/modules/gapi/src/backends/fluid/gfluidbackend.cpp b/modules/gapi/src/backends/fluid/gfluidbackend.cpp index d9c91e476d..eecfa6546d 100644 --- a/modules/gapi/src/backends/fluid/gfluidbackend.cpp +++ b/modules/gapi/src/backends/fluid/gfluidbackend.cpp @@ -648,6 +648,7 @@ void cv::gimpl::GFluidExecutable::initBufferRois(std::vector& readStarts, cv::gapi::own::Rect produced = rois[m_id_map.at(data.rc)]; + // Apply resize-specific roi transformations cv::gapi::own::Rect resized; switch (fg.metadata(oh).get().k.m_kind) { @@ -657,8 +658,28 @@ void cv::gimpl::GFluidExecutable::initBufferRois(std::vector& readStarts, default: GAPI_Assert(false); } + // All below transformations affect roi of the writer, preserve read start position here int readStart = resized.y; - cv::gapi::own::Rect roi = adjFilterRoi(resized, fd.border_size, in_meta.size.height); + + // Extend required input roi (both y and height) to be even if it's produced by NV12toRGB + if (!in_node->inNodes().empty()) { + auto in_data_producer = in_node->inNodes().front(); + if (fg.metadata(in_data_producer).get().k.m_kind == GFluidKernel::Kind::NV12toRGB) { + if (resized.y % 2 != 0) { + resized.y--; + resized.height++; + } + + if (resized.height % 2 != 0) { + resized.height++; + } + } + } + + // Apply filter-specific roi transformations, clip to image size + // Note: done even for non-filter kernels as applies border-related transformations + // (required in the case when there are multiple readers with different border requirements) + auto roi = adjFilterRoi(resized, fd.border_size, in_meta.size.height); auto in_id = m_id_map.at(in_data.rc); if (rois[in_id] == cv::gapi::own::Rect{}) diff --git a/modules/gapi/test/gapi_fluid_resize_test.cpp b/modules/gapi/test/gapi_fluid_resize_test.cpp index 7dcf0d0b6e..cbe3237d33 100644 --- a/modules/gapi/test/gapi_fluid_resize_test.cpp +++ b/modules/gapi/test/gapi_fluid_resize_test.cpp @@ -794,18 +794,24 @@ struct Preproc4lpiTest : public TestWithParam (splitted), out_sz, 0, 0, interp) , cv::gapi::resize(std::get<1>(splitted), out_sz, 0, 0, interp) @@ -813,16 +819,18 @@ TEST_P(Preproc4lpiTest, Test) auto out = merge3_4lpi(resized[0], resized[1], resized[2]); - cv::GComputation c(cv::GIn(in), cv::GOut(out)); + cv::GComputation c(cv::GIn(y, uv), cv::GOut(out)); auto pkg = cv::gapi::combine(cv::gapi::core::fluid::kernels(), fluidResizeTestPackage(interp, in_sz, out_sz, 4), cv::unite_policy::REPLACE); - c.apply(cv::gin(in_mat), cv::gout(out_mat) + c.apply(cv::gin(y_mat, uv_mat), cv::gout(out_mat) ,cv::compile_args(pkg, cv::GFluidOutputRois{{to_own(roi)}})); - cv::resize(in_mat, out_mat_ocv, out_sz, 0, 0, interp); + cv::Mat rgb_mat; + cv::cvtColor(in_mat, rgb_mat, cv::COLOR_YUV2RGB_NV12); + cv::resize(rgb_mat, out_mat_ocv, out_sz, 0, 0, interp); EXPECT_EQ(0, cv::countNonZero(out_mat(roi) != out_mat_ocv(roi))); } @@ -848,7 +856,15 @@ INSTANTIATE_TEST_CASE_P(Fluid, Preproc4lpiTest, cv::Size{49, 49}, cv::Rect{0, 11, 49, 15}) ,std::make_tuple(cv::Size{64, 64}, cv::Size{49, 49}, cv::Rect{0, 39, 49, 10}) - )); + ,std::make_tuple(cv::Size{640, 480}, + cv::Size{300, 199}, cv::Rect{0, 0, 300, 50}) + ,std::make_tuple(cv::Size{640, 480}, + cv::Size{300, 199}, cv::Rect{0, 50, 300, 50}) + ,std::make_tuple(cv::Size{640, 480}, + cv::Size{300, 199}, cv::Rect{0, 100, 300, 50}) + ,std::make_tuple(cv::Size{640, 480}, + cv::Size{300, 199}, cv::Rect{0, 150, 300, 49}) + )); } // namespace opencv_test