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;
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;
}
}
+ 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);
{
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 &&
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]);
+ }
}
}