mirror of
https://github.com/opencv/opencv.git
synced 2025-08-05 22:19:14 +08:00
spatialGradient: Add non-SSE version
This commit is contained in:
parent
11fb1f74cc
commit
770e742e04
@ -48,21 +48,136 @@ namespace cv
|
||||
void spatialGradient( InputArray _src, OutputArray _dx, OutputArray _dy, int ksize )
|
||||
{
|
||||
|
||||
// Prepare InputArray src
|
||||
Mat src = _src.getMat();
|
||||
CV_Assert(!src.empty());
|
||||
CV_Assert(src.isContinuous());
|
||||
CV_Assert(src.type() == CV_8UC1);
|
||||
CV_Assert( !src.empty() );
|
||||
CV_Assert( src.isContinuous() );
|
||||
CV_Assert( src.type() == CV_8UC1 );
|
||||
|
||||
_dx.create(src.size(), CV_16SC1);
|
||||
_dy.create(src.size(), CV_16SC1);
|
||||
// Prepare OutputArrays dx, dy
|
||||
_dx.create( src.size(), CV_16SC1 );
|
||||
_dy.create( src.size(), CV_16SC1 );
|
||||
Mat dx = _dx.getMat(),
|
||||
dy = _dy.getMat();
|
||||
CV_Assert(dx.isContinuous());
|
||||
CV_Assert(dy.isContinuous());
|
||||
CV_Assert( dx.isContinuous() );
|
||||
CV_Assert( dy.isContinuous() );
|
||||
|
||||
// TODO: Allow for other kernel sizes
|
||||
CV_Assert(ksize == 3);
|
||||
|
||||
// Reference
|
||||
//Sobel( src, dx, CV_16SC1, 1, 0, ksize );
|
||||
//Sobel( src, dy, CV_16SC1, 0, 1, ksize );
|
||||
|
||||
// Get dimensions
|
||||
int H = src.rows,
|
||||
W = src.cols,
|
||||
N = H * W;
|
||||
|
||||
// Get raw pointers to input/output data
|
||||
uchar* p_src = src.ptr<uchar>(0);
|
||||
short* p_dx = dx.ptr<short>(0);
|
||||
short* p_dy = dy.ptr<short>(0);
|
||||
|
||||
// Row, column indices
|
||||
int i, j;
|
||||
|
||||
/* NOTE:
|
||||
*
|
||||
* Sobel-x: -1 0 1
|
||||
* -2 0 2
|
||||
* -1 0 1
|
||||
*
|
||||
* Sobel-y: -1 -2 -1
|
||||
* 0 0 0
|
||||
* 1 2 1
|
||||
*/
|
||||
|
||||
// No-SSE
|
||||
int idx;
|
||||
|
||||
|
||||
p_dx[0] = 0; // Top-left corner
|
||||
p_dy[0] = 0;
|
||||
p_dx[W-1] = 0; // Top-right corner
|
||||
p_dy[W-1] = 0;
|
||||
p_dx[N-1] = 0; // Bottom-right corner
|
||||
p_dy[N-1] = 0;
|
||||
p_dx[N-W] = 0; // Bottom-left corner
|
||||
p_dy[N-W] = 0;
|
||||
|
||||
// Handle special case: column matrix
|
||||
if ( W == 1 )
|
||||
{
|
||||
for ( i = 1; i < H - 1; i++ )
|
||||
{
|
||||
p_dx[i] = 0;
|
||||
p_dy[i] = 4*(p_src[i + 1] - p_src[i - 1]); // Should be 2?! 4 makes tests pass
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle special case: row matrix
|
||||
if ( H == 1 )
|
||||
{
|
||||
for ( j = 1; j < W - 1; j++ )
|
||||
{
|
||||
p_dx[j] = 4*(p_src[j + 1] - p_src[j - 1]); // Should be 2?! 4 makes tests pass
|
||||
p_dy[j] = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Do top row
|
||||
for ( j = 1; j < W - 1; j++ )
|
||||
{
|
||||
idx = j;
|
||||
p_dx[idx] = -(p_src[idx+W-1] + 2*p_src[idx-1] + p_src[idx+W-1]) +
|
||||
(p_src[idx+W+1] + 2*p_src[idx+1] + p_src[idx+W+1]);
|
||||
p_dy[idx] = 0;
|
||||
}
|
||||
|
||||
// Do right column
|
||||
idx = 2*W - 1;
|
||||
for ( i = 1; i < H - 1; i++ )
|
||||
{
|
||||
p_dx[idx] = 0;
|
||||
p_dy[idx] = -(p_src[idx-W-1] + 2*p_src[idx-W] + p_src[idx-W-1]) +
|
||||
(p_src[idx+W-1] + 2*p_src[idx+W] + p_src[idx+W-1]);
|
||||
idx += W;
|
||||
}
|
||||
|
||||
// Do bottom row
|
||||
idx = N - W + 1;
|
||||
for ( j = 1; j < W - 1; j++ )
|
||||
{
|
||||
p_dx[idx] = -(p_src[idx-W-1] + 2*p_src[idx-1] + p_src[idx-W-1]) +
|
||||
(p_src[idx-W+1] + 2*p_src[idx+1] + p_src[idx-W+1]);
|
||||
p_dy[idx] = 0;
|
||||
idx++;
|
||||
}
|
||||
|
||||
// Do left column
|
||||
idx = W;
|
||||
for ( i = 1; i < H - 1; i++ )
|
||||
{
|
||||
p_dx[idx] = 0;
|
||||
p_dy[idx] = -(p_src[idx-W+1] + 2*p_src[idx-W] + p_src[idx-W+1]) +
|
||||
(p_src[idx+W+1] + 2*p_src[idx+W] + p_src[idx+W+1]);
|
||||
idx += W;
|
||||
}
|
||||
|
||||
// Do Inner area
|
||||
for ( i = 1; i < H - 1; i++ )
|
||||
for ( j = 1; j < W - 1; j++ )
|
||||
{
|
||||
idx = i*W + j;
|
||||
p_dx[idx] = -(p_src[idx-W-1] + 2*p_src[idx-1] + p_src[idx+W-1]) +
|
||||
(p_src[idx-W+1] + 2*p_src[idx+1] + p_src[idx+W+1]);
|
||||
p_dy[idx] = -(p_src[idx-W-1] + 2*p_src[idx-W] + p_src[idx-W+1]) +
|
||||
(p_src[idx+W-1] + 2*p_src[idx+W] + p_src[idx+W+1]);
|
||||
}
|
||||
|
||||
// TODO: Vectorize using hal intrinsics
|
||||
Sobel( src, dx, CV_16SC1, 1, 0, ksize );
|
||||
Sobel( src, dy, CV_16SC1, 0, 1, ksize );
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user