Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv
Commits
6803d1ed
Commit
6803d1ed
authored
Jun 26, 2015
by
Seon-Wook Park
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Support non continuous, BORDER_REPLICATE
TODO: HAL-accelerated code
parent
2ff614df
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
81 additions
and
109 deletions
+81
-109
imgproc.hpp
modules/imgproc/include/opencv2/imgproc.hpp
+3
-1
perf_spatialgradient.cpp
modules/imgproc/perf/perf_spatialgradient.cpp
+7
-5
spatialgradient.cpp
modules/imgproc/src/spatialgradient.cpp
+63
-95
test_filter.cpp
modules/imgproc/test/test_filter.cpp
+8
-8
No files found.
modules/imgproc/include/opencv2/imgproc.hpp
View file @
6803d1ed
...
@@ -1382,12 +1382,14 @@ Sobel( src, dy, CV_16SC1, 0, 1, 3 );
...
@@ -1382,12 +1382,14 @@ Sobel( src, dy, CV_16SC1, 0, 1, 3 );
@param dx output image with first-order derivative in x.
@param dx output image with first-order derivative in x.
@param dy output image with first-order derivative in y.
@param dy output image with first-order derivative in y.
@param ksize size of Sobel kernel. It must be 3.
@param ksize size of Sobel kernel. It must be 3.
@param borderType pixel extrapolation method, see cv::BorderTypes
@sa Sobel
@sa Sobel
*/
*/
CV_EXPORTS_W
void
spatialGradient
(
InputArray
src
,
OutputArray
dx
,
CV_EXPORTS_W
void
spatialGradient
(
InputArray
src
,
OutputArray
dx
,
OutputArray
dy
,
int
ksize
=
3
);
OutputArray
dy
,
int
ksize
=
3
,
int
borderType
=
BORDER_DEFAULT
);
/** @brief Calculates the first x- or y- image derivative using Scharr operator.
/** @brief Calculates the first x- or y- image derivative using Scharr operator.
...
...
modules/imgproc/perf/perf_spatialgradient.cpp
View file @
6803d1ed
...
@@ -7,18 +7,20 @@ using namespace testing;
...
@@ -7,18 +7,20 @@ using namespace testing;
using
std
::
tr1
::
make_tuple
;
using
std
::
tr1
::
make_tuple
;
using
std
::
tr1
::
get
;
using
std
::
tr1
::
get
;
typedef
std
::
tr1
::
tuple
<
Size
,
int
>
Size_Ksiz
e_t
;
typedef
std
::
tr1
::
tuple
<
Size
,
int
,
int
>
Size_Ksize_BorderTyp
e_t
;
typedef
perf
::
TestBaseWithParam
<
Size_Ksize_
t
>
Size_Ksiz
e
;
typedef
perf
::
TestBaseWithParam
<
Size_Ksize_
BorderType_t
>
Size_Ksize_BorderTyp
e
;
PERF_TEST_P
(
Size_Ksize
,
spatialGradient
,
PERF_TEST_P
(
Size_Ksize
_BorderType
,
spatialGradient
,
Combine
(
Combine
(
SZ_ALL_HD
,
SZ_ALL_HD
,
Values
(
3
)
Values
(
3
),
Values
(
BORDER_DEFAULT
)
)
)
)
)
{
{
Size
size
=
std
::
tr1
::
get
<
0
>
(
GetParam
());
Size
size
=
std
::
tr1
::
get
<
0
>
(
GetParam
());
int
ksize
=
std
::
tr1
::
get
<
1
>
(
GetParam
());
int
ksize
=
std
::
tr1
::
get
<
1
>
(
GetParam
());
int
borderType
=
std
::
tr1
::
get
<
2
>
(
GetParam
());
Mat
src
(
size
,
CV_8UC1
);
Mat
src
(
size
,
CV_8UC1
);
Mat
dx
(
size
,
CV_16SC1
);
Mat
dx
(
size
,
CV_16SC1
);
...
@@ -26,7 +28,7 @@ PERF_TEST_P( Size_Ksize, spatialGradient,
...
@@ -26,7 +28,7 @@ PERF_TEST_P( Size_Ksize, spatialGradient,
declare
.
in
(
src
,
WARMUP_RNG
).
out
(
dx
,
dy
);
declare
.
in
(
src
,
WARMUP_RNG
).
out
(
dx
,
dy
);
TEST_CYCLE
()
spatialGradient
(
src
,
dx
,
dy
,
ksize
);
TEST_CYCLE
()
spatialGradient
(
src
,
dx
,
dy
,
ksize
,
borderType
);
SANITY_CHECK
(
dx
);
SANITY_CHECK
(
dx
);
SANITY_CHECK
(
dy
);
SANITY_CHECK
(
dy
);
...
...
modules/imgproc/src/spatialgradient.cpp
View file @
6803d1ed
...
@@ -46,128 +46,73 @@
...
@@ -46,128 +46,73 @@
namespace
cv
namespace
cv
{
{
void
spatialGradient
(
InputArray
_src
,
OutputArray
_dx
,
OutputArray
_dy
,
int
ksize
)
void
spatialGradient
(
InputArray
_src
,
OutputArray
_dx
,
OutputArray
_dy
,
int
ksize
,
int
borderType
)
{
{
// Prepare InputArray src
// Prepare InputArray src
Mat
src
=
_src
.
getMat
();
Mat
src
=
_src
.
getMat
();
CV_Assert
(
!
src
.
empty
()
);
CV_Assert
(
!
src
.
empty
()
);
CV_Assert
(
src
.
isContinuous
()
);
CV_Assert
(
src
.
type
()
==
CV_8UC1
);
CV_Assert
(
src
.
type
()
==
CV_8UC1
);
CV_Assert
(
borderType
==
BORDER_DEFAULT
||
borderType
==
BORDER_REPLICATE
);
// Prepare OutputArrays dx, dy
// Prepare OutputArrays dx, dy
_dx
.
create
(
src
.
size
(),
CV_16SC1
);
_dx
.
create
(
src
.
size
(),
CV_16SC1
);
_dy
.
create
(
src
.
size
(),
CV_16SC1
);
_dy
.
create
(
src
.
size
(),
CV_16SC1
);
Mat
dx
=
_dx
.
getMat
(),
Mat
dx
=
_dx
.
getMat
(),
dy
=
_dy
.
getMat
();
dy
=
_dy
.
getMat
();
CV_Assert
(
dx
.
isContinuous
()
);
CV_Assert
(
dy
.
isContinuous
()
);
// TODO: Allow for other kernel sizes
// TODO: Allow for other kernel sizes
CV_Assert
(
ksize
==
3
);
CV_Assert
(
ksize
==
3
);
// Reference
//Sobel( src, dx, CV_16SC1, 1, 0, ksize );
//Sobel( src, dy, CV_16SC1, 0, 1, ksize );
// Get dimensions
// Get dimensions
int
H
=
src
.
rows
,
const
int
H
=
src
.
rows
,
W
=
src
.
cols
,
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
// Row, column indices
int
i
,
j
;
int
i
,
j
;
/* NOTE:
// Store pointers to rows of input/output data
*
// Padded by two rows for border handling
* Sobel-x: -1 0 1
uchar
*
P_src
[
H
+
2
];
* -2 0 2
short
*
P_dx
[
H
+
2
];
* -1 0 1
short
*
P_dy
[
H
+
2
];
*
* Sobel-y: -1 -2 -1
* 0 0 0
* 1 2 1
*/
// No-SSE
int
idx
;
p_dx
[
0
]
=
0
;
// Top-left corner
int
i_top
=
0
,
// Case for H == 1 && W == 1 && BORDER_REPLICATE
p_dy
[
0
]
=
0
;
i_bottom
=
H
-
1
,
p_dx
[
W
-
1
]
=
0
;
// Top-right corner
j_offl
=
0
,
// j offset from 0th pixel to reach -1st pixel
p_dy
[
W
-
1
]
=
0
;
j_offr
=
0
;
// j offset from W-1th pixel to reach Wth pixel
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
(
borderType
==
BORDER_DEFAULT
)
// Equiv. to BORDER_REFLECT_101
if
(
W
==
1
)
{
{
for
(
i
=
1
;
i
<
H
-
1
;
i
++
)
if
(
H
>
1
)
{
{
p_dx
[
i
]
=
0
;
i_top
=
1
;
p_dy
[
i
]
=
4
*
(
p_src
[
i
+
1
]
-
p_src
[
i
-
1
]);
// Should be 2?! 4 makes tests pass
i_bottom
=
H
-
2
;
}
}
return
;
if
(
W
>
1
)
}
// 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
j_offl
=
1
;
p_dy
[
j
]
=
0
;
j_offr
=
-
1
;
}
}
return
;
}
}
// Do top row
P_src
[
0
]
=
src
.
ptr
<
uchar
>
(
i_top
);
// Mirrored top border
for
(
j
=
1
;
j
<
W
-
1
;
j
++
)
P_src
[
H
+
1
]
=
src
.
ptr
<
uchar
>
(
i_bottom
);
// Mirrored bottom border
{
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
for
(
i
=
0
;
i
<
H
;
i
++
)
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
[
i
+
1
]
=
src
.
ptr
<
uchar
>
(
i
);
(
p_src
[
idx
-
W
+
1
]
+
2
*
p_src
[
idx
+
1
]
+
p_src
[
idx
-
W
+
1
]);
P_dx
[
i
]
=
dx
.
ptr
<
short
>
(
i
);
p_dy
[
idx
]
=
0
;
P_dy
[
i
]
=
dy
.
ptr
<
short
>
(
i
);
idx
++
;
}
}
// Do left column
// Pointer to row vectors
idx
=
W
;
uchar
*
p_src
,
*
c_src
,
*
n_src
;
// previous, current, next row
for
(
i
=
1
;
i
<
H
-
1
;
i
++
)
short
*
c_dx
,
*
c_dy
;
{
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
int
j_start
=
0
;
/*
#if CV_SIMD128
#if CV_SIMD128
// Characters in variable names have the following meanings:
// Characters in variable names have the following meanings:
// u: unsigned char
// u: unsigned char
...
@@ -260,16 +205,39 @@ void spatialGradient( InputArray _src, OutputArray _dx, OutputArray _dy, int ksi
...
@@ -260,16 +205,39 @@ void spatialGradient( InputArray _src, OutputArray _dx, OutputArray _dy, int ksi
}
}
}
}
#else
#else
for
(
i
=
1
;
i
<
H
-
1
;
i
++
)
*/
for
(
j
=
1
;
j
<
W
-
1
;
j
++
)
/* NOTE:
*
* Sobel-x: -1 0 1
* -2 0 2
* -1 0 1
*
* Sobel-y: -1 -2 -1
* 0 0 0
* 1 2 1
*/
int
j_p
,
j_n
;
for
(
i
=
0
;
i
<
H
;
i
++
)
{
{
idx
=
i
*
W
+
j
;
p_src
=
P_src
[
i
];
c_src
=
P_src
[
i
+
1
];
n_src
=
P_src
[
i
+
2
];
p_dx
[
idx
]
=
-
(
p_src
[
idx
-
W
-
1
]
+
2
*
p_src
[
idx
-
1
]
+
p_src
[
idx
+
W
-
1
])
+
c_dx
=
P_dx
[
i
];
(
p_src
[
idx
-
W
+
1
]
+
2
*
p_src
[
idx
+
1
]
+
p_src
[
idx
+
W
+
1
]);
c_dy
=
P_dy
[
i
];
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
]);
for
(
j
=
j_start
;
j
<
W
;
j
++
)
{
j_p
=
j
-
1
;
j_n
=
j
+
1
;
if
(
j_p
<
0
)
j_p
=
j
+
j_offl
;
if
(
j_n
>=
W
)
j_n
=
j
+
j_offr
;
c_dx
[
j
]
=
-
(
p_src
[
j_p
]
+
c_src
[
j_p
]
+
c_src
[
j_p
]
+
n_src
[
j_p
])
+
(
p_src
[
j_n
]
+
c_src
[
j_n
]
+
c_src
[
j_n
]
+
n_src
[
j_n
]);
c_dy
[
j
]
=
-
(
p_src
[
j_p
]
+
p_src
[
j
]
+
p_src
[
j
]
+
p_src
[
j_n
])
+
(
n_src
[
j_p
]
+
n_src
[
j
]
+
n_src
[
j
]
+
n_src
[
j_n
]);
}
}
}
#endif
//
#endif
}
}
...
...
modules/imgproc/test/test_filter.cpp
View file @
6803d1ed
...
@@ -587,19 +587,17 @@ void CV_SpatialGradientTest::get_test_array_types_and_sizes( int test_case_idx,
...
@@ -587,19 +587,17 @@ void CV_SpatialGradientTest::get_test_array_types_and_sizes( int test_case_idx,
// Outputs are only CV_16SC1 for now
// Outputs are only CV_16SC1 for now
types
[
OUTPUT
][
0
]
=
types
[
OUTPUT
][
1
]
=
types
[
REF_OUTPUT
][
0
]
types
[
OUTPUT
][
0
]
=
types
[
OUTPUT
][
1
]
=
types
[
REF_OUTPUT
][
0
]
=
types
[
REF_OUTPUT
][
1
]
=
CV_16SC1
;
=
types
[
REF_OUTPUT
][
1
]
=
CV_16SC1
;
ksize
=
3
;
ksize
=
3
;
border
=
BORDER_DEFAULT
;
// TODO: Add BORDER_REPLICATE
}
}
void
CV_SpatialGradientTest
::
run_func
()
void
CV_SpatialGradientTest
::
run_func
()
{
{
Mat
dx
,
dy
;
spatialGradient
(
test_mat
[
INPUT
][
0
],
test_mat
[
OUTPUT
][
0
],
spatialGradient
(
test_mat
[
INPUT
][
0
].
clone
(),
dx
,
dy
,
ksize
);
test_mat
[
OUTPUT
][
1
],
ksize
,
border
);
test_mat
[
OUTPUT
][
0
]
=
dx
;
test_mat
[
OUTPUT
][
1
]
=
dy
;
}
}
void
CV_SpatialGradientTest
::
prepare_to_validation
(
int
/*test_case_idx*/
)
void
CV_SpatialGradientTest
::
prepare_to_validation
(
int
/*test_case_idx*/
)
...
@@ -607,10 +605,12 @@ void CV_SpatialGradientTest::prepare_to_validation( int /*test_case_idx*/ )
...
@@ -607,10 +605,12 @@ void CV_SpatialGradientTest::prepare_to_validation( int /*test_case_idx*/ )
int
dx
,
dy
;
int
dx
,
dy
;
dx
=
1
;
dy
=
0
;
dx
=
1
;
dy
=
0
;
Sobel
(
test_mat
[
INPUT
][
0
],
test_mat
[
REF_OUTPUT
][
0
],
CV_16SC1
,
dx
,
dy
,
ksize
);
Sobel
(
test_mat
[
INPUT
][
0
],
test_mat
[
REF_OUTPUT
][
0
],
CV_16SC1
,
dx
,
dy
,
ksize
,
1
,
0
,
border
);
dx
=
0
;
dy
=
1
;
dx
=
0
;
dy
=
1
;
Sobel
(
test_mat
[
INPUT
][
0
],
test_mat
[
REF_OUTPUT
][
1
],
CV_16SC1
,
dx
,
dy
,
ksize
);
Sobel
(
test_mat
[
INPUT
][
0
],
test_mat
[
REF_OUTPUT
][
1
],
CV_16SC1
,
dx
,
dy
,
ksize
,
1
,
0
,
border
);
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment