Bug fixes for filter2D and associated tests.
authorAaron Kunze <aaron.kunze@intel.com>
Wed, 21 May 2014 05:30:09 +0000 (22:30 -0700)
committerAaron Kunze <aaron.kunze@intel.com>
Wed, 21 May 2014 05:30:09 +0000 (22:30 -0700)
modules/imgproc/perf/opencl/perf_filters.cpp
modules/imgproc/src/filter.cpp
modules/imgproc/test/ocl/test_filter2d.cpp

index 27dc09f..9667b8f 100644 (file)
@@ -272,7 +272,8 @@ OCL_PERF_TEST_P(Filter2DFixture, Filter2D,
 
     checkDeviceMaxMemoryAllocSize(srcSize, type);
 
-    UMat src(srcSize, type), dst(srcSize, type), kernel(ksize, ksize, CV_32SC1);
+    UMat src(srcSize, type), dst(srcSize, type);
+    Mat kernel(ksize, ksize, CV_32SC1);
     declare.in(src, WARMUP_RNG).in(kernel).out(dst);
     randu(kernel, -3.0, 3.0);
 
index d1af406..9c76128 100644 (file)
@@ -3238,12 +3238,12 @@ static bool ocl_filter2D( InputArray _src, OutputArray _dst, int ddepth,
         if (cn <= 2 && ksize.width <= 4 && ksize.height <= 4)
         {
             pxPerWorkItemX = sz.width % 8 ? sz.width % 4 ? sz.width % 2 ? 1 : 2 : 4 : 8;
-            pxPerWorkItemY = sz.width % 2 ? 1 : 2;
+            pxPerWorkItemY = sz.height % 2 ? 1 : 2;
         }
         else if (cn < 4 || (ksize.width <= 4 && ksize.height <= 4))
         {
             pxPerWorkItemX = sz.width % 2 ? 1 : 2;
-            pxPerWorkItemY = sz.width % 2 ? 1 : 2;
+            pxPerWorkItemY = sz.height % 2 ? 1 : 2;
         }
         globalsize[0] = sz.width / pxPerWorkItemX;
         globalsize[1] = sz.height / pxPerWorkItemY;
@@ -3823,26 +3823,45 @@ void cv::filter2D( InputArray _src, OutputArray _dst, int ddepth,
     if( kernel.cols*kernel.rows >= dft_filter_size )
     {
         Mat temp;
-        if( src.data != dst.data )
-            temp = dst;
-        else
-            temp.create(dst.size(), dst.type());
         // crossCorr doesn't accept non-zero delta with multiple channels
         if( src.channels() != 1 && delta != 0 )
         {
+            // The semantics of filter2D require that the delta be applied
+            // as floating-point math.  So wee need an intermediate Mat
+            // with a float datatype.  If the dest is already floats,
+            // we just use that.
+            int corrDepth = dst.depth();
+            if( (dst.depth() == CV_32F || dst.depth() == CV_64F) &&
+                src.data != dst.data )
+            {
+                temp = dst;
+            }
+            else
+            {
+                corrDepth = dst.depth() == CV_64F ? CV_64F : CV_32F;
+                temp.create( dst.size(), CV_MAKETYPE(corrDepth, dst.channels()) );
+            }
             crossCorr( src, kernel, temp, src.size(),
-                       CV_MAKETYPE(ddepth, src.channels()),
+                       CV_MAKETYPE(corrDepth, src.channels()),
                        anchor, 0, borderType );
             add( temp, delta, temp );
+            if ( temp.data != dst.data )
+            {
+                temp.convertTo( dst, dst.type() );
+            }
         }
         else
         {
+            if( src.data != dst.data )
+                temp = dst;
+            else
+                temp.create(dst.size(), dst.type());
             crossCorr( src, kernel, temp, src.size(),
                        CV_MAKETYPE(ddepth, src.channels()),
                        anchor, delta, borderType );
+            if( temp.data != dst.data )
+                temp.copyTo(dst);
         }
-        if( temp.data != dst.data )
-            temp.copyTo(dst);
         return;
     }
 
index 7da2718..18ba4cc 100644 (file)
@@ -57,7 +57,7 @@ PARAM_TEST_CASE(Filter2D, MatDepth, Channels, int, int, BorderType, bool, bool)
     static const int kernelMaxSize = 10;
 
     int type;
-    Size dsize;
+    Size size;
     Point anchor;
     int borderType;
     int widthMultiple;
@@ -81,17 +81,16 @@ PARAM_TEST_CASE(Filter2D, MatDepth, Channels, int, int, BorderType, bool, bool)
 
     void random_roi()
     {
-        dsize = randomSize(1, MAX_VALUE);
+        size = randomSize(1, MAX_VALUE);
         // Make sure the width is a multiple of the requested value, and no more.
-        dsize.width &= ~((widthMultiple * 2) - 1);
-        dsize.width += widthMultiple;
+        size.width &= ~((widthMultiple * 2) - 1);
+        size.width += widthMultiple;
 
-        Size roiSize = randomSize(kernel.size[0], MAX_VALUE, kernel.size[1], MAX_VALUE);
         Border srcBorder = randomBorder(0, useRoi ? MAX_VALUE : 0);
-        randomSubMat(src, src_roi, roiSize, srcBorder, type, -MAX_VALUE, MAX_VALUE);
+        randomSubMat(src, src_roi, size, srcBorder, type, -MAX_VALUE, MAX_VALUE);
 
         Border dstBorder = randomBorder(0, useRoi ? MAX_VALUE : 0);
-        randomSubMat(dst, dst_roi, dsize, dstBorder, type, -MAX_VALUE, MAX_VALUE);
+        randomSubMat(dst, dst_roi, size, dstBorder, type, -MAX_VALUE, MAX_VALUE);
 
         anchor.x = randomInt(-1, kernel.size[0]);
         anchor.y = randomInt(-1, kernel.size[1]);