diff --git a/modules/imgproc/src/filter.dispatch.cpp b/modules/imgproc/src/filter.dispatch.cpp index b6f5331028..24e1a74e88 100644 --- a/modules/imgproc/src/filter.dispatch.cpp +++ b/modules/imgproc/src/filter.dispatch.cpp @@ -1112,6 +1112,7 @@ static bool ippFilter2D(int stype, int dtype, int kernel_type, static bool dftFilter2D(int stype, int dtype, int kernel_type, uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step, + int width, int height, int full_width, int full_height, int offset_x, int offset_y, uchar * kernel_data, size_t kernel_step, @@ -1125,13 +1126,23 @@ static bool dftFilter2D(int stype, int dtype, int kernel_type, int dft_filter_size = checkHardwareSupport(CV_CPU_SSE3) && ((sdepth == CV_8U && (ddepth == CV_8U || ddepth == CV_16S)) || (sdepth == CV_32F && ddepth == CV_32F)) ? 130 : 50; if (kernel_width * kernel_height < dft_filter_size) return false; + + // detect roi case + if( (offset_x != 0) || (offset_y != 0) ) + { + return false; + } + if( (width != full_width) || (height != full_height) ) + { + return false; + } } Point anchor = Point(anchor_x, anchor_y); Mat kernel = Mat(Size(kernel_width, kernel_height), kernel_type, kernel_data, kernel_step); - Mat src(Size(full_width-offset_x, full_height-offset_y), stype, src_data, src_step); - Mat dst(Size(full_width, full_height), dtype, dst_data, dst_step); + Mat src(Size(width, height), stype, src_data, src_step); + Mat dst(Size(width, height), dtype, dst_data, dst_step); Mat temp; int src_channels = CV_MAT_CN(stype); int dst_channels = CV_MAT_CN(dtype); @@ -1144,10 +1155,10 @@ static bool dftFilter2D(int stype, int dtype, int kernel_type, // we just use that. int corrDepth = ddepth; if ((ddepth == CV_32F || ddepth == CV_64F) && src_data != dst_data) { - temp = Mat(Size(full_width, full_height), dtype, dst_data, dst_step); + temp = Mat(Size(width, height), dtype, dst_data, dst_step); } else { corrDepth = ddepth == CV_64F ? CV_64F : CV_32F; - temp.create(Size(full_width, full_height), CV_MAKETYPE(corrDepth, dst_channels)); + temp.create(Size(width, height), CV_MAKETYPE(corrDepth, dst_channels)); } crossCorr(src, kernel, temp, src.size(), CV_MAKETYPE(corrDepth, src_channels), @@ -1158,9 +1169,9 @@ static bool dftFilter2D(int stype, int dtype, int kernel_type, } } else { if (src_data != dst_data) - temp = Mat(Size(full_width, full_height), dtype, dst_data, dst_step); + temp = Mat(Size(width, height), dtype, dst_data, dst_step); else - temp.create(Size(full_width, full_height), dtype); + temp.create(Size(width, height), dtype); crossCorr(src, kernel, temp, src.size(), CV_MAKETYPE(ddepth, src_channels), anchor, delta, borderType); @@ -1293,6 +1304,7 @@ void filter2D(int stype, int dtype, int kernel_type, res = dftFilter2D(stype, dtype, kernel_type, src_data, src_step, dst_data, dst_step, + width, height, full_width, full_height, offset_x, offset_y, kernel_data, kernel_step, diff --git a/modules/imgproc/test/test_filter.cpp b/modules/imgproc/test/test_filter.cpp index 5b73e3bf8e..55efae23f9 100644 --- a/modules/imgproc/test/test_filter.cpp +++ b/modules/imgproc/test/test_filter.cpp @@ -2201,6 +2201,67 @@ TEST(Imgproc_Filter2D, dftFilter2d_regression_10683) EXPECT_LE(cvtest::norm(dst, expected, NORM_INF), 2); } +TEST(Imgproc_Filter2D, dftFilter2d_regression_13179) +{ + uchar src_[24*24] = { + 0, 40, 0, 0, 255, 0, 0, 78, 131, 0, 196, 0, 255, 0, 0, 0, 0, 255, 70, 0, 255, 0, 0, 0, + 0, 0, 255, 204, 0, 0, 255, 93, 255, 0, 0, 255, 12, 0, 0, 0, 255, 121, 0, 255, 0, 0, 0, 255, + 0, 178, 0, 25, 67, 0, 165, 0, 255, 0, 0, 181, 151, 175, 0, 0, 32, 0, 0, 255, 165, 93, 0, 255, + 255, 255, 0, 0, 255, 126, 0, 0, 0, 0, 133, 29, 9, 0, 220, 255, 0, 142, 255, 255, 255, 0, 255, 0, + 255, 32, 255, 0, 13, 237, 0, 0, 0, 0, 0, 19, 90, 0, 0, 85, 122, 62, 95, 29, 255, 20, 0, 0, + 0, 0, 166, 41, 0, 48, 70, 0, 68, 0, 255, 0, 139, 7, 63, 144, 0, 204, 0, 0, 0, 98, 114, 255, + 105, 0, 0, 0, 0, 255, 91, 0, 73, 0, 255, 0, 0, 0, 255, 198, 21, 0, 0, 0, 255, 43, 153, 128, + 0, 98, 26, 0, 101, 0, 0, 0, 255, 0, 0, 0, 255, 77, 56, 0, 241, 0, 169, 132, 0, 255, 186, 255, + 255, 87, 0, 1, 0, 0, 10, 39, 120, 0, 23, 69, 207, 0, 0, 0, 0, 84, 0, 0, 0, 0, 255, 0, + 255, 0, 0, 136, 255, 77, 247, 0, 67, 0, 15, 255, 0, 143, 0, 243, 255, 0, 0, 238, 255, 0, 255, 8, + 42, 0, 0, 255, 29, 0, 0, 0, 255, 255, 255, 75, 0, 0, 0, 255, 0, 0, 255, 38, 197, 0, 255, 87, + 0, 123, 17, 0, 234, 0, 0, 149, 0, 0, 255, 16, 0, 0, 0, 255, 0, 255, 0, 38, 0, 114, 255, 76, + 0, 0, 8, 0, 255, 0, 0, 0, 220, 0, 11, 255, 0, 0, 55, 98, 0, 0, 0, 255, 0, 175, 255, 110, + 235, 0, 175, 0, 255, 227, 38, 206, 0, 0, 255, 246, 0, 0, 123, 183, 255, 0, 0, 255, 0, 156, 0, 54, + 0, 255, 0, 202, 0, 0, 0, 0, 157, 0, 255, 63, 0, 0, 0, 0, 0, 255, 132, 0, 255, 0, 0, 0, + 0, 0, 0, 255, 0, 0, 128, 126, 0, 243, 46, 7, 0, 211, 108, 166, 0, 0, 162, 227, 0, 204, 0, 51, + 255, 216, 0, 0, 43, 0, 255, 40, 188, 188, 255, 0, 0, 255, 34, 0, 0, 168, 0, 0, 0, 35, 0, 0, + 0, 80, 131, 255, 0, 255, 10, 0, 0, 0, 180, 255, 209, 255, 173, 34, 0, 66, 0, 49, 0, 255, 83, 0, + 0, 204, 0, 91, 0, 0, 0, 205, 84, 0, 0, 0, 92, 255, 91, 0, 126, 0, 185, 145, 0, 0, 9, 0, + 255, 0, 0, 255, 255, 0, 0, 255, 0, 0, 216, 0, 187, 221, 0, 0, 141, 0, 0, 209, 0, 0, 255, 0, + 255, 0, 0, 154, 150, 0, 0, 0, 148, 0, 201, 255, 0, 255, 16, 0, 0, 160, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 198, 255, 147, 131, 0, 255, 202, 0, 0, 0, 0, 255, 0, + 0, 0, 0, 164, 181, 0, 0, 0, 69, 255, 31, 0, 255, 195, 0, 0, 255, 164, 109, 0, 0, 202, 0, 206, + 0, 0, 61, 235, 33, 255, 77, 0, 0, 0, 0, 85, 0, 228, 0, 0, 0, 0, 255, 0, 0, 5, 255, 255 + }; + cv::Mat_ src(24, 24, src_); + + uchar expected_[16*16] = { + 0,255, 0, 0,255, 0, 0,255, 0, 0,255,255, 0,255, 0, 0, + 0,255, 0, 0,255, 0, 0,255, 0, 0,255,255, 0,255, 0, 0, + 0,255, 0, 0,255, 0, 0,255, 70, 0,255,255, 0,255, 0, 0, + 0,234,138, 0,255, 0, 0,255, 8, 0,255,255, 0,255, 0, 0, + 0, 0,255, 0,255,228, 0,255,255, 0,255,255, 0,255, 0, 5, + 0, 0,255, 0,255, 0, 0,255, 0, 0,255,255, 0,255, 0, 0, + 0,253, 0, 0,255, 0, 0,255, 0, 0,255,255, 0,255, 0, 0, + 0,255, 0, 0,255, 0, 0,255, 0, 0,255, 93, 0,255, 0,255, + 0,255, 0, 0,255, 0,182,255, 0, 0,255, 0, 0,255, 0, 0, + 0, 0,253, 0,228, 0,255,255, 0, 0,255, 0, 0, 0, 0, 75, + 0, 0,255, 0, 0, 0,255,255, 0,255,206, 0, 1,162, 0,255, + 0, 0,255, 0, 0, 0,255,255, 0,255,255, 0, 0,255, 0,255, + 0, 0,255, 0, 0, 0,255,255, 0,255,255, 0,255,255, 0,255, + 0, 0,255,255, 0, 0,255, 0, 0,255,255, 0,255,168, 0,255, + 0, 0,255,255, 0, 0,255, 26, 0,255,255, 0,255,255, 0,255, + 0, 0,255,255, 0, 0,255, 0, 0,255,255, 0,255,255, 0,255, + }; + cv::Mat_ expected(16, 16, expected_); + + cv::Mat kernel = cv::getGaborKernel(cv::Size(13, 13), 8, 0, 3, 0.25); + + cv::Mat roi(src, cv::Rect(0, 0, 16, 16)); + + cv::Mat filtered(16, 16, roi.type()); + + cv::filter2D(roi, filtered, -1, kernel); + + EXPECT_LE(cvtest::norm(filtered, expected, cv::NORM_INF), 2); +} + TEST(Imgproc_MedianBlur, hires_regression_13409) { Mat src(2048, 2048, CV_8UC1), dst_hires, dst_ref;