fix dftFilter2D
authortake1014 <y.takehara1014@gmail.com>
Tue, 12 Mar 2019 15:27:56 +0000 (00:27 +0900)
committertake1014 <y.takehara1014@gmail.com>
Tue, 12 Mar 2019 15:27:56 +0000 (00:27 +0900)
modules/imgproc/src/filter.dispatch.cpp
modules/imgproc/test/test_filter.cpp

index b6f5331..24e1a74 100644 (file)
@@ -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,
index 5b73e3b..55efae2 100644 (file)
@@ -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_<uchar> 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_<uchar> 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;