added patches by Bram Bolder
authorVadim Pisarevsky <vadim.pisarevsky@itseez.com>
Tue, 18 Sep 2012 10:11:08 +0000 (14:11 +0400)
committerVadim Pisarevsky <vadim.pisarevsky@itseez.com>
Tue, 18 Sep 2012 10:11:08 +0000 (14:11 +0400)
modules/imgproc/src/cornersubpix.cpp
modules/imgproc/src/deriv.cpp

index 83a5bdb..3eab5f6 100644 (file)
@@ -48,8 +48,7 @@ cvFindCornerSubPix( const void* srcarr, CvPoint2D32f* corners,
     cv::AutoBuffer<float> buffer;
     
     const int MAX_ITERS = 100;
-    const float drv_x[] = { -1.f, 0.f, 1.f };
-    const float drv_y[] = { 0.f, 0.5f, 0.f };
+    const float drv[] = { -1.f, 0.f, 1.f };
     float *maskX;
     float *maskY;
     float *mask;
@@ -187,13 +186,12 @@ cvFindCornerSubPix( const void* srcarr, CvPoint2D32f* corners,
                                         cvSize( win_w + 2, win_h + 2 ), cI ));
 
             /* calc derivatives */
-            icvSepConvSmall3_32f( src_buffer, src_buf_size.width * sizeof(src_buffer[0]),
-                                  gx_buffer, win_w * sizeof(gx_buffer[0]),
-                                  src_buf_size, drv_x, drv_y, buffer );
-
-            icvSepConvSmall3_32f( src_buffer, src_buf_size.width * sizeof(src_buffer[0]),
-                                  gy_buffer, win_w * sizeof(gy_buffer[0]),
-                                  src_buf_size, drv_y, drv_x, buffer );
+            icvSepConvSmall3_32f( src_buffer+src_buf_size.width, src_buf_size.width * sizeof(src_buffer[0]),
+                                 gx_buffer, win_w * sizeof(gx_buffer[0]),
+                                 src_buf_size, drv, NULL, NULL );
+            icvSepConvSmall3_32f( src_buffer+1, src_buf_size.width * sizeof(src_buffer[0]),
+                                 gy_buffer, win_w * sizeof(gy_buffer[0]),
+                                 src_buf_size, NULL, drv, NULL );
 
             a = b = c = bb1 = bb2 = 0;
 
@@ -221,21 +219,17 @@ cvFindCornerSubPix( const void* srcarr, CvPoint2D32f* corners,
                 }
             }
 
+            double det=a*c-b*b;
+            if( fabs( det ) > DBL_EPSILON*DBL_EPSILON )
             {
-                double A[4];
-                double InvA[4];
-                CvMat matA, matInvA;
-
-                A[0] = a;
-                A[1] = A[2] = b;
-                A[3] = c;
-
-                cvInitMatHeader( &matA, 2, 2, CV_64F, A );
-                cvInitMatHeader( &matInvA, 2, 2, CV_64FC1, InvA );
-
-                cvInvert( &matA, &matInvA, CV_SVD );
-                cI2.x = (float)(cI.x + InvA[0]*bb1 + InvA[1]*bb2);
-                cI2.y = (float)(cI.y + InvA[2]*bb1 + InvA[3]*bb2);
+                // 2x2 matrix inversion
+                double scale=1.0/det;
+                cI2.x = (float)(cI.x + c*scale*bb1 - b*scale*bb2);
+                cI2.y = (float)(cI.y - b*scale*bb1 + a*scale*bb2);
+            }
+            else
+            {
+                cI2 = cI;
             }
 
             err = (cI2.x - cI.x) * (cI2.x - cI.x) + (cI2.y - cI.y) * (cI2.y - cI.y);
index 94f2e67..82395b2 100644 (file)
@@ -51,6 +51,7 @@ void icvSepConvSmall3_32f( float* src, int src_step, float* dst, int dst_step,
 {
     int  dst_width, buffer_step = 0;
     int  x, y;
+    bool fast_kx = true, fast_ky = true;
 
     assert( src && dst && src_size.width > 2 && src_size.height > 2 &&
             (src_step & 3) == 0 && (dst_step & 3) == 0 &&
@@ -71,35 +72,51 @@ void icvSepConvSmall3_32f( float* src, int src_step, float* dst, int dst_step,
         buffer = dst;
         dst_width = 0;
     }
+    else
+        fast_kx = kx[1] == 0.f && kx[0] == -kx[2] && kx[0] == -1.f;
 
     assert( src_step >= src_size.width && dst_step >= dst_width );
 
-    src_size.height -= 3;
+    src_size.height -= 2;
     if( !ky )
     {
         /* set vars, so that vertical convolution won't run and
            horizontal convolution will write results into destination ROI */
-        src_size.height += 3;
+        src_size.height += 2;
         buffer_step = src_step;
         buffer = src;
         src_size.width = 0;
     }
+    else
+        fast_ky = ky[1] == 0.f && ky[0] == -ky[2] && ky[0] == -1.f;
 
-    for( y = 0; y <= src_size.height; y++, src += src_step,
-                                           dst += dst_step,
-                                           buffer += buffer_step )
+    for( y = 0; y < src_size.height; y++, src += src_step,
+                                          dst += dst_step,
+                                          buffer += buffer_step )
     {
         float* src2 = src + src_step;
         float* src3 = src + src_step*2;
-        for( x = 0; x < src_size.width; x++ )
-        {
-            buffer[x] = (float)(ky[0]*src[x] + ky[1]*src2[x] + ky[2]*src3[x]);
-        }
+        if( fast_ky )
+            for( x = 0; x < src_size.width; x++ )
+            {
+                buffer[x] = (float)(src3[x] - src[x]);
+            }
+        else
+            for( x = 0; x < src_size.width; x++ )
+            {
+                buffer[x] = (float)(ky[0]*src[x] + ky[1]*src2[x] + ky[2]*src3[x]);
+            }
 
-        for( x = 0; x < dst_width; x++ )
-        {
-            dst[x] = (float)(kx[0]*buffer[x] + kx[1]*buffer[x+1] + kx[2]*buffer[x+2]);
-        }
+        if( fast_kx )
+            for( x = 0; x < dst_width; x++ )
+            {
+                dst[x] = (float)(buffer[x+2] - buffer[x]);
+            }
+        else
+            for( x = 0; x < dst_width; x++ )
+            {
+                dst[x] = (float)(kx[0]*buffer[x] + kx[1]*buffer[x+1] + kx[2]*buffer[x+2]);
+            }
     }
 }