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
66df8ef0
Commit
66df8ef0
authored
Oct 06, 2010
by
Vladislav Vinogradov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
added Filter Engine to gpu module.
disabled gpu::sum, gpu::minMax, gpu:Canny until fix crash.
parent
7a3b0785
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
1127 additions
and
620 deletions
+1127
-620
gpu.hpp
modules/gpu/include/opencv2/gpu/gpu.hpp
+151
-12
arithm.cpp
modules/gpu/src/arithm.cpp
+2
-0
filtering_npp.cpp
modules/gpu/src/filtering_npp.cpp
+576
-212
imgproc_gpu.cpp
modules/gpu/src/imgproc_gpu.cpp
+1
-0
filters.cpp
tests/gpu/src/filters.cpp
+383
-218
gputest_main.cpp
tests/gpu/src/gputest_main.cpp
+14
-12
imgproc_gpu.cpp
tests/gpu/src/imgproc_gpu.cpp
+0
-166
No files found.
modules/gpu/include/opencv2/gpu/gpu.hpp
View file @
66df8ef0
...
...
@@ -407,10 +407,12 @@ namespace cv
//! computes sum of array elements
//! supports CV_8UC1, CV_8UC4 types
//! disabled until fix crash
CV_EXPORTS
Scalar
sum
(
const
GpuMat
&
m
);
//! finds global minimum and maximum array elements and returns their values
//! supports only CV_8UC1 type
//! disabled until fix npp bug
CV_EXPORTS
void
minMax
(
const
GpuMat
&
src
,
double
*
minVal
,
double
*
maxVal
=
0
);
//! transforms 8-bit unsigned integers using lookup table: dst(i)=lut(src(i))
...
...
@@ -451,8 +453,10 @@ namespace cv
CV_EXPORTS
void
log
(
const
GpuMat
&
a
,
GpuMat
&
b
);
//! computes magnitude (magnitude(i)) of each (x(i), y(i)) vector
//! supports only CV_32FC1 type
CV_EXPORTS
void
magnitude
(
const
GpuMat
&
x
,
const
GpuMat
&
y
,
GpuMat
&
magnitude
);
//! computes magnitude (magnitude(i)) of complex (x(i).re, x(i).im) vector
//! supports only CV_32FC2 type
CV_EXPORTS
void
magnitude
(
const
GpuMat
&
x
,
GpuMat
&
magnitude
);
////////////////////////////// Image processing //////////////////////////////
...
...
@@ -517,34 +521,169 @@ namespace cv
//! supports only CV_32FC1 source type
CV_EXPORTS
void
integral
(
GpuMat
&
src
,
GpuMat
&
sum
,
GpuMat
&
sqsum
);
//! applies Canny edge detector and produces the edge map
//! supprots only CV_8UC1 source type
//! disabled until fix crash
CV_EXPORTS
void
Canny
(
const
GpuMat
&
image
,
GpuMat
&
edges
,
double
threshold1
,
double
threshold2
,
int
apertureSize
=
3
);
//////////////////////////////// Filter Engine ////////////////////////////////
/*!
The Base Class for 1D or Row-wise Filters
This is the base class for linear or non-linear filters that process 1D data.
In particular, such filters are used for the "horizontal" filtering parts in separable filters.
*/
class
CV_EXPORTS
BaseRowFilter_GPU
{
public
:
BaseRowFilter_GPU
(
int
ksize_
,
int
anchor_
)
:
ksize
(
ksize_
),
anchor
(
anchor_
)
{}
virtual
~
BaseRowFilter_GPU
()
{}
virtual
void
operator
()(
const
GpuMat
&
src
,
GpuMat
&
dst
)
=
0
;
int
ksize
,
anchor
;
};
/*!
The Base Class for Column-wise Filters
This is the base class for linear or non-linear filters that process columns of 2D arrays.
Such filters are used for the "vertical" filtering parts in separable filters.
*/
class
CV_EXPORTS
BaseColumnFilter_GPU
{
public
:
BaseColumnFilter_GPU
(
int
ksize_
,
int
anchor_
)
:
ksize
(
ksize_
),
anchor
(
anchor_
)
{}
virtual
~
BaseColumnFilter_GPU
()
{}
virtual
void
operator
()(
const
GpuMat
&
src
,
GpuMat
&
dst
)
=
0
;
int
ksize
,
anchor
;
};
/*!
The Base Class for Non-Separable 2D Filters.
This is the base class for linear or non-linear 2D filters.
*/
class
CV_EXPORTS
BaseFilter_GPU
{
public
:
BaseFilter_GPU
(
const
Size
&
ksize_
,
const
Point
&
anchor_
)
:
ksize
(
ksize_
),
anchor
(
anchor_
)
{}
virtual
~
BaseFilter_GPU
()
{}
virtual
void
operator
()(
const
GpuMat
&
src
,
GpuMat
&
dst
)
=
0
;
Size
ksize
;
Point
anchor
;
};
/*!
The Base Class for Filter Engine.
The class can be used to apply an arbitrary filtering operation to an image.
It contains all the necessary intermediate buffers.
*/
class
CV_EXPORTS
FilterEngine_GPU
{
public
:
virtual
~
FilterEngine_GPU
()
{}
virtual
void
apply
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
Rect
roi
=
Rect
(
0
,
0
,
-
1
,
-
1
))
=
0
;
};
//! returns the non-separable filter engine with the specified filter
CV_EXPORTS
Ptr
<
FilterEngine_GPU
>
createFilter2D_GPU
(
const
Ptr
<
BaseFilter_GPU
>
filter2D
);
//! returns the separable filter engine with the specified filters
CV_EXPORTS
Ptr
<
FilterEngine_GPU
>
createSeparableFilter_GPU
(
const
Ptr
<
BaseRowFilter_GPU
>&
rowFilter
,
const
Ptr
<
BaseColumnFilter_GPU
>&
columnFilter
);
//! returns horizontal 1D box filter
//! supports only CV_8UC1 source type and CV_32FC1 sum type
CV_EXPORTS
Ptr
<
BaseRowFilter_GPU
>
getRowSumFilter_GPU
(
int
srcType
,
int
sumType
,
int
ksize
,
int
anchor
=
-
1
);
//! returns vertical 1D box filter
//! supports only CV_8UC1 sum type and CV_32FC1 dst type
CV_EXPORTS
Ptr
<
BaseColumnFilter_GPU
>
getColumnSumFilter_GPU
(
int
sumType
,
int
dstType
,
int
ksize
,
int
anchor
=
-
1
);
//! returns 2D box filter
//! supports CV_8UC1 and CV_8UC4 source type, dst type must be the same as source type
CV_EXPORTS
Ptr
<
BaseFilter_GPU
>
getBoxFilter_GPU
(
int
srcType
,
int
dstType
,
const
Size
&
ksize
,
Point
anchor
=
Point
(
-
1
,
-
1
));
//! returns box filter engine
CV_EXPORTS
Ptr
<
FilterEngine_GPU
>
createBoxFilter_GPU
(
int
srcType
,
int
dstType
,
const
Size
&
ksize
,
const
Point
&
anchor
=
Point
(
-
1
,
-
1
));
//! returns 2D morphological filter
//! only MORPH_ERODE and MORPH_DILATE are supported
//! supports CV_8UC1 and CV_8UC4 types
//! kernel must have CV_8UC1 type, one rows and cols == ksize.width * ksize.height
CV_EXPORTS
Ptr
<
BaseFilter_GPU
>
getMorphologyFilter_GPU
(
int
op
,
int
type
,
const
GpuMat
&
kernel
,
const
Size
&
ksize
,
Point
anchor
=
Point
(
-
1
,
-
1
));
//! returns morphological filter engine. Only MORPH_ERODE and MORPH_DILATE are supported.
CV_EXPORTS
Ptr
<
FilterEngine_GPU
>
createMorphologyFilter_GPU
(
int
op
,
int
type
,
const
Mat
&
kernel
,
const
Point
&
anchor
=
Point
(
-
1
,
-
1
),
int
iterations
=
1
);
//! returns 2D filter with the specified kernel
//! supports CV_8UC1 and CV_8UC4 types
//! kernel must have CV_8UC1 type, one rows and cols == ksize.width * ksize.height
CV_EXPORTS
Ptr
<
BaseFilter_GPU
>
getLinearFilter_GPU
(
int
srcType
,
int
dstType
,
const
GpuMat
&
kernel
,
const
Size
&
ksize
,
Point
anchor
=
Point
(
-
1
,
-
1
),
int
nDivisor
=
1
);
//! returns the non-separable linear filter engine
CV_EXPORTS
Ptr
<
FilterEngine_GPU
>
createLinearFilter_GPU
(
int
srcType
,
int
dstType
,
const
Mat
&
kernel
,
const
Point
&
anchor
=
Point
(
-
1
,
-
1
));
//! returns the primitive row filter with the specified kernel
CV_EXPORTS
Ptr
<
BaseRowFilter_GPU
>
getLinearRowFilter_GPU
(
int
srcType
,
int
bufType
,
const
GpuMat
&
rowKernel
,
int
anchor
=
-
1
,
int
nDivisor
=
1
);
//! returns the primitive column filter with the specified kernel
CV_EXPORTS
Ptr
<
BaseColumnFilter_GPU
>
getLinearColumnFilter_GPU
(
int
bufType
,
int
dstType
,
const
GpuMat
&
columnKernel
,
int
anchor
=
-
1
,
int
nDivisor
=
1
);
//! returns the separable linear filter engine
CV_EXPORTS
Ptr
<
FilterEngine_GPU
>
createSeparableLinearFilter_GPU
(
int
srcType
,
int
dstType
,
const
Mat
&
rowKernel
,
const
Mat
&
columnKernel
,
const
Point
&
anchor
=
Point
(
-
1
,
-
1
));
//! returns filter engine for the generalized Sobel operator
CV_EXPORTS
Ptr
<
FilterEngine_GPU
>
createDerivFilter_GPU
(
int
srcType
,
int
dstType
,
int
dx
,
int
dy
,
int
ksize
);
//! returns the Gaussian filter engine
CV_EXPORTS
Ptr
<
FilterEngine_GPU
>
createGaussianFilter_GPU
(
int
type
,
Size
ksize
,
double
sigma1
,
double
sigma2
=
0
);
//! smooths the image using the normalized box filter
//! supports CV_8UC1, CV_8UC4 types
and kernel size 3, 5, 7
CV_EXPORTS
void
boxFilter
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
Size
ksize
,
Point
anchor
=
Point
(
-
1
,
-
1
));
//! supports CV_8UC1, CV_8UC4 types
CV_EXPORTS
void
boxFilter
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
int
ddepth
,
Size
ksize
,
Point
anchor
=
Point
(
-
1
,
-
1
));
//! a synonym for normalized box filter
static
inline
void
blur
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
Size
ksize
,
Point
anchor
=
Point
(
-
1
,
-
1
))
{
boxFilter
(
src
,
dst
,
ksize
,
anchor
);
}
static
inline
void
blur
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
Size
ksize
,
Point
anchor
=
Point
(
-
1
,
-
1
))
{
boxFilter
(
src
,
dst
,
-
1
,
ksize
,
anchor
);
}
//! erodes the image (applies the local minimum operator)
CV_EXPORTS
void
erode
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
const
Mat
&
kernel
,
Point
anchor
,
int
iterations
);
CV_EXPORTS
void
erode
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
const
Mat
&
kernel
,
Point
anchor
=
Point
(
-
1
,
-
1
),
int
iterations
=
1
);
//! dilates the image (applies the local maximum operator)
CV_EXPORTS
void
dilate
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
const
Mat
&
kernel
,
Point
anchor
,
int
iterations
);
CV_EXPORTS
void
dilate
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
const
Mat
&
kernel
,
Point
anchor
=
Point
(
-
1
,
-
1
),
int
iterations
=
1
);
//! applies an advanced morphological operation to the image
CV_EXPORTS
void
morphologyEx
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
int
op
,
const
Mat
&
kernel
,
Point
anchor
,
int
iterations
);
CV_EXPORTS
void
morphologyEx
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
int
op
,
const
Mat
&
kernel
,
Point
anchor
=
Point
(
-
1
,
-
1
),
int
iterations
=
1
);
//! applies non-separable 2D linear filter to the image
CV_EXPORTS
void
filter2D
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
int
ddepth
,
const
Mat
&
kernel
,
Point
anchor
=
Point
(
-
1
,
-
1
));
//!
1D mask Window Sum for 8 bit images
CV_EXPORTS
void
s
umWindowColumn
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
int
ksize
,
int
anchor
=
-
1
);
CV_EXPORTS
void
sumWindowRow
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
int
ksize
,
int
anchor
=
-
1
);
//!
applies separable 2D linear filter to the image
CV_EXPORTS
void
s
epFilter2D
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
int
ddepth
,
const
Mat
&
kernelX
,
const
Mat
&
kernelY
,
Point
anchor
=
Point
(
-
1
,
-
1
)
);
//! applies generalized Sobel operator to the image
CV_EXPORTS
void
Sobel
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
int
ddepth
,
int
dx
,
int
dy
,
int
ksize
=
3
,
double
scale
=
1
);
//! applies the vertical or horizontal Scharr operator to the image
CV_EXPORTS
void
Scharr
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
int
ddepth
,
int
dx
,
int
dy
,
double
scale
=
1
);
//! smooths the image using Gaussian filter.
CV_EXPORTS
void
GaussianBlur
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
Size
ksize
,
double
sigma1
,
double
sigma2
=
0
);
//! applies Canny edge detector and produces the edge map.
CV_EXPORTS
void
Canny
(
const
GpuMat
&
image
,
GpuMat
&
edges
,
double
threshold1
,
double
threshold2
,
int
apertureSize
=
3
);
//! applies Laplacian operator to the image
//! supports only ksize = 1 and ksize = 3
CV_EXPORTS
void
Laplacian
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
int
ddepth
,
int
ksize
=
1
,
double
scale
=
1
);
//////////////////////////////// Image Labeling ////////////////////////////////
...
...
modules/gpu/src/arithm.cpp
View file @
66df8ef0
...
...
@@ -387,6 +387,7 @@ void cv::gpu::flip(const GpuMat& src, GpuMat& dst, int flipCode)
Scalar
cv
::
gpu
::
sum
(
const
GpuMat
&
src
)
{
CV_Assert
(
!
"disabled until fix crash"
);
CV_Assert
(
src
.
type
()
==
CV_8UC1
||
src
.
type
()
==
CV_8UC4
);
NppiSize
sz
;
...
...
@@ -420,6 +421,7 @@ Scalar cv::gpu::sum(const GpuMat& src)
void
cv
::
gpu
::
minMax
(
const
GpuMat
&
src
,
double
*
minVal
,
double
*
maxVal
)
{
CV_Assert
(
!
"disabled until fix npp bug"
);
CV_Assert
(
src
.
type
()
==
CV_8UC1
);
NppiSize
sz
;
...
...
modules/gpu/src/filtering_npp.cpp
View file @
66df8ef0
...
...
@@ -48,82 +48,413 @@ using namespace cv::gpu;
#if !defined (HAVE_CUDA)
Ptr
<
FilterEngine_GPU
>
cv
::
gpu
::
createFilter2D_GPU
(
const
Ptr
<
BaseFilter_GPU
>
)
{
throw_nogpu
();
return
Ptr
<
FilterEngine_GPU
>
(
0
);
}
Ptr
<
FilterEngine_GPU
>
cv
::
gpu
::
createSeparableFilter_GPU
(
const
Ptr
<
BaseRowFilter_GPU
>&
,
const
Ptr
<
BaseColumnFilter_GPU
>&
)
{
throw_nogpu
();
return
Ptr
<
FilterEngine_GPU
>
(
0
);
}
Ptr
<
BaseRowFilter_GPU
>
cv
::
gpu
::
getRowSumFilter_GPU
(
int
,
int
,
int
,
int
)
{
throw_nogpu
();
return
Ptr
<
BaseRowFilter_GPU
>
(
0
);
}
Ptr
<
BaseColumnFilter_GPU
>
cv
::
gpu
::
getColumnSumFilter_GPU
(
int
,
int
,
int
,
int
)
{
throw_nogpu
();
return
Ptr
<
BaseColumnFilter_GPU
>
(
0
);
}
Ptr
<
BaseFilter_GPU
>
cv
::
gpu
::
getBoxFilter_GPU
(
int
,
int
,
const
Size
&
,
Point
)
{
throw_nogpu
();
return
Ptr
<
BaseFilter_GPU
>
(
0
);
}
Ptr
<
FilterEngine_GPU
>
cv
::
gpu
::
createBoxFilter_GPU
(
int
,
int
,
const
Size
&
,
const
Point
&
)
{
throw_nogpu
();
return
Ptr
<
FilterEngine_GPU
>
(
0
);
}
Ptr
<
BaseFilter_GPU
>
cv
::
gpu
::
getMorphologyFilter_GPU
(
int
,
int
,
const
GpuMat
&
,
const
Size
&
,
Point
)
{
throw_nogpu
();
return
Ptr
<
BaseFilter_GPU
>
(
0
);
}
Ptr
<
FilterEngine_GPU
>
cv
::
gpu
::
createMorphologyFilter_GPU
(
int
,
int
,
const
Mat
&
,
const
Point
&
,
int
)
{
throw_nogpu
();
return
Ptr
<
FilterEngine_GPU
>
(
0
);
}
Ptr
<
BaseFilter_GPU
>
cv
::
gpu
::
getLinearFilter_GPU
(
int
,
int
,
const
GpuMat
&
,
const
Size
&
,
Point
,
int
)
{
throw_nogpu
();
return
Ptr
<
BaseFilter_GPU
>
(
0
);
}
Ptr
<
FilterEngine_GPU
>
cv
::
gpu
::
createLinearFilter_GPU
(
int
,
int
,
const
Mat
&
,
const
Point
&
)
{
throw_nogpu
();
return
Ptr
<
FilterEngine_GPU
>
(
0
);
}
Ptr
<
BaseRowFilter_GPU
>
cv
::
gpu
::
getLinearRowFilter_GPU
(
int
,
int
,
const
GpuMat
&
,
int
,
int
)
{
throw_nogpu
();
return
Ptr
<
BaseRowFilter_GPU
>
(
0
);
}
Ptr
<
BaseColumnFilter_GPU
>
cv
::
gpu
::
getLinearColumnFilter_GPU
(
int
,
int
,
const
GpuMat
&
,
int
,
int
)
{
throw_nogpu
();
return
Ptr
<
BaseColumnFilter_GPU
>
(
0
);
}
Ptr
<
FilterEngine_GPU
>
cv
::
gpu
::
createSeparableLinearFilter_GPU
(
int
,
int
,
const
Mat
&
,
const
Mat
&
,
const
Point
&
)
{
throw_nogpu
();
return
Ptr
<
FilterEngine_GPU
>
(
0
);
}
Ptr
<
FilterEngine_GPU
>
cv
::
gpu
::
createDerivFilter_GPU
(
int
,
int
,
int
,
int
,
int
)
{
throw_nogpu
();
return
Ptr
<
FilterEngine_GPU
>
(
0
);
}
Ptr
<
FilterEngine_GPU
>
cv
::
gpu
::
createGaussianFilter_GPU
(
int
,
Size
,
double
,
double
)
{
throw_nogpu
();
return
Ptr
<
FilterEngine_GPU
>
(
0
);
}
void
cv
::
gpu
::
boxFilter
(
const
GpuMat
&
,
GpuMat
&
,
int
,
Size
,
Point
)
{
throw_nogpu
();
}
void
cv
::
gpu
::
erode
(
const
GpuMat
&
,
GpuMat
&
,
const
Mat
&
,
Point
,
int
)
{
throw_nogpu
();
}
void
cv
::
gpu
::
dilate
(
const
GpuMat
&
,
GpuMat
&
,
const
Mat
&
,
Point
,
int
)
{
throw_nogpu
();
}
void
cv
::
gpu
::
morphologyEx
(
const
GpuMat
&
,
GpuMat
&
,
int
,
const
Mat
&
,
Point
,
int
)
{
throw_nogpu
();
}
void
cv
::
gpu
::
boxFilter
(
const
GpuMat
&
,
GpuMat
&
,
Size
,
Point
)
{
throw_nogpu
();
}
void
cv
::
gpu
::
sumWindowColumn
(
const
GpuMat
&
,
GpuMat
&
,
int
,
int
)
{
throw_nogpu
();
}
void
cv
::
gpu
::
sumWindowRow
(
const
GpuMat
&
,
GpuMat
&
,
int
,
int
)
{
throw_nogpu
();
}
void
cv
::
gpu
::
filter2D
(
const
GpuMat
&
,
GpuMat
&
,
int
,
const
Mat
&
,
Point
)
{
throw_nogpu
();
}
void
cv
::
gpu
::
sepFilter2D
(
const
GpuMat
&
,
GpuMat
&
,
int
,
const
Mat
&
,
const
Mat
&
,
Point
)
{
throw_nogpu
();
}
void
cv
::
gpu
::
Sobel
(
const
GpuMat
&
,
GpuMat
&
,
int
,
int
,
int
,
int
,
double
)
{
throw_nogpu
();
}
void
cv
::
gpu
::
Scharr
(
const
GpuMat
&
,
GpuMat
&
,
int
,
int
,
int
,
double
)
{
throw_nogpu
();
}
void
cv
::
gpu
::
GaussianBlur
(
const
GpuMat
&
,
GpuMat
&
,
Size
,
double
,
double
)
{
throw_nogpu
();
}
void
cv
::
gpu
::
Laplacian
(
const
GpuMat
&
,
GpuMat
&
,
int
,
int
,
double
)
{
throw_nogpu
();
}
#else
namespace
namespace
{
typedef
NppStatus
(
*
npp_morf_func
)(
const
Npp8u
*
,
Npp32s
,
Npp8u
*
,
Npp32s
,
NppiSize
,
const
Npp8u
*
,
NppiSize
,
NppiPoint
);
inline
void
normalizeAnchor
(
int
&
anchor
,
int
ksize
)
{
if
(
anchor
<
0
)
anchor
=
ksize
>>
1
;
CV_Assert
(
0
<=
anchor
&&
anchor
<
ksize
);
}
void
morphoogy_caller
(
npp_morf_func
func
,
const
GpuMat
&
src
,
GpuMat
&
dst
,
const
Mat
&
kernel
,
Point
anchor
,
int
iterations
)
inline
void
normalizeAnchor
(
Point
&
anchor
,
const
Size
&
ksize
)
{
CV_Assert
(
src
.
type
()
==
CV_8U
||
src
.
type
()
==
CV_8UC4
);
CV_Assert
(
kernel
.
type
()
==
CV_8U
&&
(
kernel
.
cols
&
1
)
!=
0
&&
(
kernel
.
rows
&
1
)
!=
0
);
normalizeAnchor
(
anchor
.
x
,
ksize
.
width
);
normalizeAnchor
(
anchor
.
y
,
ksize
.
height
);
}
if
(
anchor
.
x
==
-
1
)
anchor
.
x
=
kernel
.
cols
/
2
;
if
(
anchor
.
y
==
-
1
)
anchor
.
y
=
kernel
.
rows
/
2
;
inline
void
normalizeROI
(
Rect
&
roi
,
const
Size
&
ksize
,
const
Size
&
src_size
)
{
if
(
roi
==
Rect
(
0
,
0
,
-
1
,
-
1
)
)
roi
=
Rect
(
ksize
.
width
,
ksize
.
height
,
src_size
.
width
-
2
*
ksize
.
width
,
src_size
.
height
-
2
*
ksize
.
height
)
;
// in NPP for Cuda 3.1 only such anchor is supported.
CV_Assert
(
anchor
.
x
==
0
&&
anchor
.
y
==
0
);
CV_Assert
(
roi
.
x
>=
0
&&
roi
.
y
>=
0
&&
roi
.
width
<=
src_size
.
width
&&
roi
.
height
<=
src_size
.
height
);
}
if
(
iterations
==
0
)
inline
void
normalizeKernel
(
const
Mat
&
kernel
,
GpuMat
&
gpu_krnl
,
int
type
=
CV_8U
,
int
*
nDivisor
=
0
,
bool
reverse
=
false
)
{
int
scale
=
nDivisor
&&
(
kernel
.
depth
()
==
CV_32F
||
kernel
.
depth
()
==
CV_64F
)
?
256
:
1
;
if
(
nDivisor
)
*
nDivisor
=
scale
;
Mat
cont_krnl
=
(
kernel
.
isContinuous
()
?
kernel
:
kernel
.
clone
()).
reshape
(
1
,
1
);
Mat
temp
;
cont_krnl
.
convertTo
(
temp
,
type
,
scale
);
if
(
reverse
)
{
src
.
copyTo
(
dst
);
return
;
int
count
=
temp
.
cols
>>
1
;
for
(
int
i
=
0
;
i
<
count
;
++
i
)
{
std
::
swap
(
temp
.
at
<
int
>
(
0
,
i
),
temp
.
at
<
int
>
(
0
,
temp
.
cols
-
1
-
i
));
}
}
const
Mat
&
cont_krnl
=
(
kernel
.
isContinuous
()
?
kernel
:
kernel
.
clone
()).
reshape
(
1
,
1
);
GpuMat
gpu_krnl
(
cont_krnl
);
NppiSize
sz
;
sz
.
width
=
src
.
cols
;
sz
.
height
=
src
.
rows
;
gpu_krnl
.
upload
(
temp
);
}
}
NppiSize
mask_sz
;
mask_sz
.
width
=
kernel
.
cols
;
mask_sz
.
height
=
kernel
.
rows
;
////////////////////////////////////////////////////////////////////////////////////////////////////
// Filter2D
NppiPoint
anc
;
anc
.
x
=
anchor
.
x
;
anc
.
y
=
anchor
.
y
;
dst
.
create
(
src
.
size
(),
src
.
type
());
namespace
{
class
Filter2DEngine_GPU
:
public
FilterEngine_GPU
{
public
:
Filter2DEngine_GPU
(
const
Ptr
<
BaseFilter_GPU
>&
filter2D_
)
:
filter2D
(
filter2D_
)
{}
virtual
void
apply
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
Rect
roi
=
Rect
(
0
,
0
,
-
1
,
-
1
))
{
Size
src_size
=
src
.
size
();
dst
.
create
(
src_size
,
src
.
type
());
normalizeROI
(
roi
,
filter2D
->
ksize
,
src_size
);
GpuMat
srcROI
=
src
(
roi
);
GpuMat
dstROI
=
dst
(
roi
);
(
*
filter2D
)(
srcROI
,
dstROI
);
}
Ptr
<
BaseFilter_GPU
>
filter2D
;
};
}
Ptr
<
FilterEngine_GPU
>
cv
::
gpu
::
createFilter2D_GPU
(
const
Ptr
<
BaseFilter_GPU
>
filter2D
)
{
return
Ptr
<
FilterEngine_GPU
>
(
new
Filter2DEngine_GPU
(
filter2D
));
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// SeparableFilter
namespace
{
class
SeparableFilterEngine_GPU
:
public
FilterEngine_GPU
{
public
:
SeparableFilterEngine_GPU
(
const
Ptr
<
BaseRowFilter_GPU
>&
rowFilter_
,
const
Ptr
<
BaseColumnFilter_GPU
>&
columnFilter_
)
:
rowFilter
(
rowFilter_
),
columnFilter
(
columnFilter_
)
{
ksize
=
Size
(
rowFilter
->
ksize
,
columnFilter
->
ksize
);
}
virtual
void
apply
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
Rect
roi
=
Rect
(
0
,
0
,
-
1
,
-
1
))
{
Size
src_size
=
src
.
size
();
int
src_type
=
src
.
type
();
dst
.
create
(
src_size
,
src_type
);
dstBuf
.
create
(
src_size
,
src_type
);
normalizeROI
(
roi
,
ksize
,
src_size
);
GpuMat
srcROI
=
src
(
roi
);
GpuMat
dstROI
=
dst
(
roi
);
GpuMat
dstBufROI
=
dstBuf
(
roi
);
(
*
rowFilter
)(
srcROI
,
dstBufROI
);
(
*
columnFilter
)(
dstBufROI
,
dstROI
);
}
Ptr
<
BaseRowFilter_GPU
>
rowFilter
;
Ptr
<
BaseColumnFilter_GPU
>
columnFilter
;
Size
ksize
;
GpuMat
dstBuf
;
if
(
iterations
>
1
)
dstBuf
.
create
(
src
.
size
(),
src
.
type
());
};
}
Ptr
<
FilterEngine_GPU
>
cv
::
gpu
::
createSeparableFilter_GPU
(
const
Ptr
<
BaseRowFilter_GPU
>&
rowFilter
,
const
Ptr
<
BaseColumnFilter_GPU
>&
columnFilter
)
{
return
Ptr
<
FilterEngine_GPU
>
(
new
SeparableFilterEngine_GPU
(
rowFilter
,
columnFilter
));
}
nppSafeCall
(
func
(
src
.
ptr
<
Npp8u
>
(),
src
.
step
,
dst
.
ptr
<
Npp8u
>
(),
dst
.
step
,
sz
,
gpu_krnl
.
ptr
<
Npp8u
>
(),
mask_sz
,
anc
)
);
for
(
int
i
=
1
;
i
<
iterations
;
++
i
)
////////////////////////////////////////////////////////////////////////////////////////////////////
// 1D Sum Filter
namespace
{
class
NppRowSumFilter
:
public
BaseRowFilter_GPU
{
public
:
NppRowSumFilter
(
int
ksize_
,
int
anchor_
)
:
BaseRowFilter_GPU
(
ksize_
,
anchor_
)
{}
virtual
void
operator
()(
const
GpuMat
&
src
,
GpuMat
&
dst
)
{
dst
.
swap
(
dstBuf
);
nppSafeCall
(
func
(
dstBuf
.
ptr
<
Npp8u
>
(),
dstBuf
.
step
,
dst
.
ptr
<
Npp8u
>
(),
dst
.
step
,
sz
,
gpu_krnl
.
ptr
<
Npp8u
>
(),
mask_sz
,
anc
)
);
NppiSize
sz
;
sz
.
width
=
src
.
cols
;
sz
.
height
=
src
.
rows
;
nppSafeCall
(
nppiSumWindowRow_8u32f_C1R
(
src
.
ptr
<
Npp8u
>
(),
src
.
step
,
dst
.
ptr
<
Npp32f
>
(),
dst
.
step
,
sz
,
ksize
,
anchor
)
);
}
}
};
}
Ptr
<
BaseRowFilter_GPU
>
cv
::
gpu
::
getRowSumFilter_GPU
(
int
srcType
,
int
sumType
,
int
ksize
,
int
anchor
)
{
CV_Assert
(
srcType
==
CV_8UC1
&&
sumType
==
CV_32FC1
);
normalizeAnchor
(
anchor
,
ksize
);
return
Ptr
<
BaseRowFilter_GPU
>
(
new
NppRowSumFilter
(
ksize
,
anchor
));
}
namespace
{
class
NppColumnSumFilter
:
public
BaseColumnFilter_GPU
{
public
:
NppColumnSumFilter
(
int
ksize_
,
int
anchor_
)
:
BaseColumnFilter_GPU
(
ksize_
,
anchor_
)
{}
void
cv
::
gpu
::
erode
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
const
Mat
&
kernel
,
Point
anchor
,
int
iterations
)
virtual
void
operator
()(
const
GpuMat
&
src
,
GpuMat
&
dst
)
{
NppiSize
sz
;
sz
.
width
=
src
.
cols
;
sz
.
height
=
src
.
rows
;
nppSafeCall
(
nppiSumWindowColumn_8u32f_C1R
(
src
.
ptr
<
Npp8u
>
(),
src
.
step
,
dst
.
ptr
<
Npp32f
>
(),
dst
.
step
,
sz
,
ksize
,
anchor
)
);
}
};
}
Ptr
<
BaseColumnFilter_GPU
>
cv
::
gpu
::
getColumnSumFilter_GPU
(
int
sumType
,
int
dstType
,
int
ksize
,
int
anchor
)
{
CV_Assert
(
sumType
==
CV_8UC1
&&
dstType
==
CV_32FC1
);
normalizeAnchor
(
anchor
,
ksize
);
return
Ptr
<
BaseColumnFilter_GPU
>
(
new
NppColumnSumFilter
(
ksize
,
anchor
));
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Box Filter
namespace
{
typedef
NppStatus
(
*
nppFilterBox_t
)(
const
Npp8u
*
pSrc
,
Npp32s
nSrcStep
,
Npp8u
*
pDst
,
Npp32s
nDstStep
,
NppiSize
oSizeROI
,
NppiSize
oMaskSize
,
NppiPoint
oAnchor
);
class
NPPBoxFilter
:
public
BaseFilter_GPU
{
public
:
NPPBoxFilter
(
const
Size
&
ksize_
,
const
Point
&
anchor_
,
nppFilterBox_t
func_
)
:
BaseFilter_GPU
(
ksize_
,
anchor_
),
func
(
func_
)
{}
virtual
void
operator
()(
const
GpuMat
&
src
,
GpuMat
&
dst
)
{
NppiSize
sz
;
sz
.
width
=
src
.
cols
;
sz
.
height
=
src
.
rows
;
NppiSize
oKernelSize
;
oKernelSize
.
height
=
ksize
.
height
;
oKernelSize
.
width
=
ksize
.
width
;
NppiPoint
oAnchor
;
oAnchor
.
x
=
anchor
.
x
;
oAnchor
.
y
=
anchor
.
y
;
nppSafeCall
(
func
(
src
.
ptr
<
Npp8u
>
(),
src
.
step
,
dst
.
ptr
<
Npp8u
>
(),
dst
.
step
,
sz
,
oKernelSize
,
oAnchor
)
);
}
nppFilterBox_t
func
;
};
}
Ptr
<
BaseFilter_GPU
>
cv
::
gpu
::
getBoxFilter_GPU
(
int
srcType
,
int
dstType
,
const
Size
&
ksize
,
Point
anchor
)
{
static
const
nppFilterBox_t
nppFilterBox_callers
[]
=
{
0
,
nppiFilterBox_8u_C1R
,
0
,
0
,
nppiFilterBox_8u_C4R
};
CV_Assert
((
srcType
==
CV_8UC1
||
srcType
==
CV_8UC4
)
&&
dstType
==
srcType
);
normalizeAnchor
(
anchor
,
ksize
);
return
Ptr
<
BaseFilter_GPU
>
(
new
NPPBoxFilter
(
ksize
,
anchor
,
nppFilterBox_callers
[
CV_MAT_CN
(
srcType
)]));
}
Ptr
<
FilterEngine_GPU
>
cv
::
gpu
::
createBoxFilter_GPU
(
int
srcType
,
int
dstType
,
const
Size
&
ksize
,
const
Point
&
anchor
)
{
Ptr
<
BaseFilter_GPU
>
boxFilter
=
getBoxFilter_GPU
(
srcType
,
dstType
,
ksize
,
anchor
);
return
createFilter2D_GPU
(
boxFilter
);
}
void
cv
::
gpu
::
boxFilter
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
int
ddepth
,
Size
ksize
,
Point
anchor
)
{
int
sdepth
=
src
.
depth
(),
cn
=
src
.
channels
();
if
(
ddepth
<
0
)
ddepth
=
sdepth
;
dst
.
create
(
src
.
size
(),
CV_MAKETYPE
(
ddepth
,
cn
));
Ptr
<
FilterEngine_GPU
>
f
=
createBoxFilter_GPU
(
src
.
type
(),
dst
.
type
(),
ksize
,
anchor
);
f
->
apply
(
src
,
dst
);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Morphology Filter
namespace
{
typedef
NppStatus
(
*
nppMorfFilter_t
)(
const
Npp8u
*
,
Npp32s
,
Npp8u
*
,
Npp32s
,
NppiSize
,
const
Npp8u
*
,
NppiSize
,
NppiPoint
);
class
NPPMorphFilter
:
public
BaseFilter_GPU
{
public
:
NPPMorphFilter
(
const
Size
&
ksize_
,
const
Point
&
anchor_
,
const
GpuMat
&
kernel_
,
nppMorfFilter_t
func_
)
:
BaseFilter_GPU
(
ksize_
,
anchor_
),
kernel
(
kernel_
),
func
(
func_
)
{}
virtual
void
operator
()(
const
GpuMat
&
src
,
GpuMat
&
dst
)
{
NppiSize
sz
;
sz
.
width
=
src
.
cols
;
sz
.
height
=
src
.
rows
;
NppiSize
oKernelSize
;
oKernelSize
.
height
=
ksize
.
height
;
oKernelSize
.
width
=
ksize
.
width
;
NppiPoint
oAnchor
;
oAnchor
.
x
=
anchor
.
x
;
oAnchor
.
y
=
anchor
.
y
;
nppSafeCall
(
func
(
src
.
ptr
<
Npp8u
>
(),
src
.
step
,
dst
.
ptr
<
Npp8u
>
(),
dst
.
step
,
sz
,
kernel
.
ptr
<
Npp8u
>
(),
oKernelSize
,
oAnchor
)
);
}
GpuMat
kernel
;
nppMorfFilter_t
func
;
};
}
Ptr
<
BaseFilter_GPU
>
cv
::
gpu
::
getMorphologyFilter_GPU
(
int
op
,
int
type
,
const
GpuMat
&
kernel
,
const
Size
&
ksize
,
Point
anchor
)
{
static
const
nppMorfFilter_t
nppMorfFilter_callers
[
2
][
5
]
=
{
{
0
,
nppiErode_8u_C1R
,
0
,
0
,
nppiErode_8u_C4R
},
{
0
,
nppiDilate_8u_C1R
,
0
,
0
,
nppiDilate_8u_C4R
}
};
CV_Assert
(
op
==
MORPH_ERODE
||
op
==
MORPH_DILATE
);
CV_Assert
(
type
==
CV_8UC1
||
type
==
CV_8UC4
);
CV_Assert
(
kernel
.
type
()
==
CV_8UC1
&&
kernel
.
rows
==
1
&&
kernel
.
cols
==
ksize
.
area
());
normalizeAnchor
(
anchor
,
ksize
);
return
Ptr
<
BaseFilter_GPU
>
(
new
NPPMorphFilter
(
ksize
,
anchor
,
kernel
,
nppMorfFilter_callers
[
op
][
CV_MAT_CN
(
type
)]));
}
namespace
{
class
MorphologyFilterEngine_GPU
:
public
Filter2DEngine_GPU
{
public
:
MorphologyFilterEngine_GPU
(
const
Ptr
<
BaseFilter_GPU
>&
filter2D_
,
int
iters_
)
:
Filter2DEngine_GPU
(
filter2D_
),
iters
(
iters_
)
{}
virtual
void
apply
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
Rect
roi
=
Rect
(
0
,
0
,
-
1
,
-
1
))
{
if
(
iters
>
1
)
dstBuf
.
create
(
src
.
size
(),
src
.
type
());
Filter2DEngine_GPU
::
apply
(
src
,
dst
);
for
(
int
i
=
1
;
i
<
iters
;
++
i
)
{
dst
.
swap
(
dstBuf
);
Filter2DEngine_GPU
::
apply
(
dst
,
dst
);
}
}
int
iters
;
GpuMat
dstBuf
;
};
}
Ptr
<
FilterEngine_GPU
>
cv
::
gpu
::
createMorphologyFilter_GPU
(
int
op
,
int
type
,
const
Mat
&
kernel
,
const
Point
&
anchor
,
int
iterations
)
{
CV_Assert
(
iterations
>
0
);
Size
ksize
=
kernel
.
size
();
GpuMat
gpu_krnl
;
normalizeKernel
(
kernel
,
gpu_krnl
);
Ptr
<
BaseFilter_GPU
>
filter2D
=
getMorphologyFilter_GPU
(
op
,
type
,
gpu_krnl
,
ksize
,
anchor
);
return
Ptr
<
FilterEngine_GPU
>
(
new
MorphologyFilterEngine_GPU
(
filter2D
,
iterations
));
}
namespace
{
static
npp_morf_func
funcs
[]
=
{
0
,
nppiErode_8u_C1R
,
0
,
0
,
nppiErode_8u_C4R
};
void
morphOp
(
int
op
,
const
GpuMat
&
src
,
GpuMat
&
dst
,
const
Mat
&
_kernel
,
Point
anchor
,
int
iterations
)
{
Mat
kernel
;
Size
ksize
=
_kernel
.
data
?
_kernel
.
size
()
:
Size
(
3
,
3
);
normalizeAnchor
(
anchor
,
ksize
);
morphoogy_caller
(
funcs
[
src
.
channels
()],
src
,
dst
,
kernel
,
anchor
,
iterations
);
if
(
iterations
==
0
||
_kernel
.
rows
*
_kernel
.
cols
==
1
)
{
src
.
copyTo
(
dst
);
return
;
}
dst
.
create
(
src
.
size
(),
src
.
type
());
if
(
!
_kernel
.
data
)
{
kernel
=
getStructuringElement
(
MORPH_RECT
,
Size
(
1
+
iterations
*
2
,
1
+
iterations
*
2
));
anchor
=
Point
(
iterations
,
iterations
);
iterations
=
1
;
}
else
if
(
iterations
>
1
&&
countNonZero
(
_kernel
)
==
_kernel
.
rows
*
_kernel
.
cols
)
{
anchor
=
Point
(
anchor
.
x
*
iterations
,
anchor
.
y
*
iterations
);
kernel
=
getStructuringElement
(
MORPH_RECT
,
Size
(
ksize
.
width
+
iterations
*
(
ksize
.
width
-
1
),
ksize
.
height
+
iterations
*
(
ksize
.
height
-
1
)),
anchor
);
iterations
=
1
;
}
else
kernel
=
_kernel
;
Ptr
<
FilterEngine_GPU
>
f
=
createMorphologyFilter_GPU
(
op
,
src
.
type
(),
kernel
,
anchor
,
iterations
);
f
->
apply
(
src
,
dst
);
}
}
void
cv
::
gpu
::
erode
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
const
Mat
&
kernel
,
Point
anchor
,
int
iterations
)
{
morphOp
(
MORPH_ERODE
,
src
,
dst
,
kernel
,
anchor
,
iterations
);
}
void
cv
::
gpu
::
dilate
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
const
Mat
&
kernel
,
Point
anchor
,
int
iterations
)
{
static
npp_morf_func
funcs
[]
=
{
0
,
nppiDilate_8u_C1R
,
0
,
0
,
nppiDilate_8u_C4R
};
morphoogy_caller
(
funcs
[
src
.
channels
()],
src
,
dst
,
kernel
,
anchor
,
iterations
);
morphOp
(
MORPH_DILATE
,
src
,
dst
,
kernel
,
anchor
,
iterations
);
}
void
cv
::
gpu
::
morphologyEx
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
int
op
,
const
Mat
&
kernel
,
Point
anchor
,
int
iterations
)
...
...
@@ -165,195 +496,197 @@ void cv::gpu::morphologyEx( const GpuMat& src, GpuMat& dst, int op, const Mat& k
}
}
////////////////////////////////////////////////////////////////////////
//
box
Filter
////////////////////////////////////////////////////////////////////////
////////////////////////////
//
Linear
Filter
void
cv
::
gpu
::
boxFilter
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
Size
ksize
,
Point
anchor
)
namespace
{
CV_Assert
(
src
.
type
()
==
CV_8UC1
||
src
.
type
()
==
CV_8UC4
);
CV_Assert
(
ksize
.
height
==
3
||
ksize
.
height
==
5
||
ksize
.
height
==
7
);
CV_Assert
(
ksize
.
height
==
ksize
.
width
);
if
(
anchor
.
x
==
-
1
)
anchor
.
x
=
0
;
if
(
anchor
.
y
==
-
1
)
anchor
.
y
=
0
;
typedef
NppStatus
(
*
nppFilter2D_t
)(
const
Npp8u
*
pSrc
,
Npp32s
nSrcStep
,
Npp8u
*
pDst
,
Npp32s
nDstStep
,
NppiSize
oSizeROI
,
const
Npp32s
*
pKernel
,
NppiSize
oKernelSize
,
NppiPoint
oAnchor
,
Npp32s
nDivisor
);
CV_Assert
(
anchor
.
x
==
0
&&
anchor
.
y
==
0
);
class
NPPLinearFilter
:
public
BaseFilter_GPU
{
public
:
NPPLinearFilter
(
const
Size
&
ksize_
,
const
Point
&
anchor_
,
const
GpuMat
&
kernel_
,
Npp32s
nDivisor_
,
nppFilter2D_t
func_
)
:
BaseFilter_GPU
(
ksize_
,
anchor_
),
kernel
(
kernel_
),
nDivisor
(
nDivisor_
),
func
(
func_
)
{}
dst
.
create
(
src
.
size
(),
src
.
type
());
virtual
void
operator
()(
const
GpuMat
&
src
,
GpuMat
&
dst
)
{
NppiSize
sz
;
sz
.
width
=
src
.
cols
;
sz
.
height
=
src
.
rows
;
NppiSize
oKernelSize
;
oKernelSize
.
height
=
ksize
.
height
;
oKernelSize
.
width
=
ksize
.
width
;
NppiPoint
oAnchor
;
oAnchor
.
x
=
anchor
.
x
;
oAnchor
.
y
=
anchor
.
y
;
nppSafeCall
(
func
(
src
.
ptr
<
Npp8u
>
(),
src
.
step
,
dst
.
ptr
<
Npp8u
>
(),
dst
.
step
,
sz
,
kernel
.
ptr
<
Npp32s
>
(),
oKernelSize
,
oAnchor
,
nDivisor
)
);
}
NppiSize
srcsz
;
srcsz
.
height
=
src
.
rows
;
srcsz
.
width
=
src
.
cols
;
NppiSize
masksz
;
masksz
.
height
=
ksize
.
height
;
masksz
.
width
=
ksize
.
width
;
NppiPoint
anc
;
anc
.
x
=
anchor
.
x
;
anc
.
y
=
anchor
.
y
;
if
(
src
.
type
()
==
CV_8UC1
)
{
nppSafeCall
(
nppiFilterBox_8u_C1R
(
src
.
ptr
<
Npp8u
>
(),
src
.
step
,
dst
.
ptr
<
Npp8u
>
(),
dst
.
step
,
srcsz
,
masksz
,
anc
)
);
}
else
{
nppSafeCall
(
nppiFilterBox_8u_C4R
(
src
.
ptr
<
Npp8u
>
(),
src
.
step
,
dst
.
ptr
<
Npp8u
>
(),
dst
.
step
,
srcsz
,
masksz
,
anc
)
);
}
GpuMat
kernel
;
Npp32s
nDivisor
;
nppFilter2D_t
func
;
};
}
////////////////////////////////////////////////////////////////////////
// sumWindow Filter
namespace
Ptr
<
BaseFilter_GPU
>
cv
::
gpu
::
getLinearFilter_GPU
(
int
srcType
,
int
dstType
,
const
GpuMat
&
kernel
,
const
Size
&
ksize
,
Point
anchor
,
int
nDivisor
)
{
typedef
NppStatus
(
*
nppSumWindow_t
)(
const
Npp8u
*
pSrc
,
Npp32s
nSrcStep
,
Npp32f
*
pDst
,
Npp32s
nDstStep
,
NppiSize
oROI
,
Npp32s
nMaskSize
,
Npp32s
nAnchor
);
inline
void
sumWindowCaller
(
nppSumWindow_t
func
,
const
GpuMat
&
src
,
GpuMat
&
dst
,
int
ksize
,
int
anchor
)
{
CV_Assert
(
src
.
type
()
==
CV_8UC1
);
if
(
anchor
==
-
1
)
anchor
=
ksize
/
2
;
static
const
nppFilter2D_t
cppFilter2D_callers
[]
=
{
0
,
nppiFilter_8u_C1R
,
0
,
0
,
nppiFilter_8u_C4R
};
NppiSize
sz
;
sz
.
width
=
src
.
cols
;
sz
.
height
=
src
.
rows
;
CV_Assert
((
srcType
==
CV_8UC1
||
srcType
==
CV_8UC4
)
&&
dstType
==
srcType
);
CV_Assert
(
kernel
.
type
()
==
CV_32SC1
&&
kernel
.
rows
==
1
&&
kernel
.
cols
==
ksize
.
area
());
dst
.
create
(
src
.
size
(),
CV_32FC1
);
normalizeAnchor
(
anchor
,
ksize
);
nppSafeCall
(
func
(
src
.
ptr
<
Npp8u
>
(),
src
.
step
,
dst
.
ptr
<
Npp32f
>
(),
dst
.
step
,
sz
,
ksize
,
anchor
)
);
}
}
return
Ptr
<
BaseFilter_GPU
>
(
new
NPPLinearFilter
(
ksize
,
anchor
,
kernel
,
nDivisor
,
cppFilter2D_callers
[
CV_MAT_CN
(
srcType
)]));
}
void
cv
::
gpu
::
sumWindowColumn
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
int
ksize
,
int
anchor
)
Ptr
<
FilterEngine_GPU
>
cv
::
gpu
::
createLinearFilter_GPU
(
int
srcType
,
int
dstType
,
const
Mat
&
kernel
,
const
Point
&
anchor
)
{
sumWindowCaller
(
nppiSumWindowColumn_8u32f_C1R
,
src
,
dst
,
ksize
,
anchor
);
Size
ksize
=
kernel
.
size
();
GpuMat
gpu_krnl
;
int
nDivisor
;
normalizeKernel
(
kernel
,
gpu_krnl
,
CV_32S
,
&
nDivisor
,
true
);
Ptr
<
BaseFilter_GPU
>
linearFilter
=
getLinearFilter_GPU
(
srcType
,
dstType
,
gpu_krnl
,
ksize
,
anchor
,
nDivisor
);
return
createFilter2D_GPU
(
linearFilter
);
}
void
cv
::
gpu
::
sumWindowRow
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
int
ksize
,
int
anchor
)
void
cv
::
gpu
::
filter2D
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
int
ddepth
,
const
Mat
&
kernel
,
Po
int
anchor
)
{
sumWindowCaller
(
nppiSumWindowRow_8u32f_C1R
,
src
,
dst
,
ksize
,
anchor
);
if
(
ddepth
<
0
)
ddepth
=
src
.
depth
();
dst
.
create
(
src
.
size
(),
CV_MAKETYPE
(
ddepth
,
src
.
channels
()));
Ptr
<
FilterEngine_GPU
>
f
=
createLinearFilter_GPU
(
src
.
type
(),
dst
.
type
(),
kernel
,
anchor
);
f
->
apply
(
src
,
dst
);
}
////////////////////////////////////////////////////////////////////////
//
Filter Engine
////////////////////////////////////////////////////////////////////////
////////////////////////////
//
Separable Linear Filter
namespace
{
typedef
NppStatus
(
*
nppFilter1D_t
)(
const
Npp8u
*
pSrc
,
Npp32s
nSrcStep
,
Npp8u
*
pDst
,
Npp32s
nDstStep
,
NppiSize
oROI
,
const
Npp32s
*
pKernel
,
Npp32s
nMaskSize
,
Npp32s
nAnchor
,
Npp32s
nDivisor
);
typedef
NppStatus
(
*
nppFilter2D_t
)(
const
Npp8u
*
pSrc
,
Npp32s
nSrcStep
,
Npp8u
*
pDst
,
Npp32s
nDstStep
,
NppiSize
oSizeROI
,
const
Npp32s
*
pKernel
,
NppiSize
oKernelSize
,
NppiPoint
oAnchor
,
Npp32s
nDivisor
);
const
Npp32s
*
pKernel
,
Npp32s
nMaskSize
,
Npp32s
nAnchor
,
Npp32s
nDivisor
);
void
applyRowFilter
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
const
GpuMat
&
rowKernel
,
Npp32s
anchor
=
-
1
,
Npp32s
nDivisor
=
1
)
class
NppLinearRowFilter
:
public
BaseRowFilter_GPU
{
static
const
nppFilter1D_t
nppFilter1D_callers
[]
=
{
nppiFilterRow_8u_C1R
,
nppiFilterRow_8u_C4R
};
public
:
NppLinearRowFilter
(
int
ksize_
,
int
anchor_
,
const
GpuMat
&
kernel_
,
Npp32s
nDivisor_
,
nppFilter1D_t
func_
)
:
BaseRowFilter_GPU
(
ksize_
,
anchor_
),
kernel
(
kernel_
),
nDivisor
(
nDivisor_
),
func
(
func_
)
{}
CV_Assert
(
src
.
type
()
==
CV_8UC1
||
src
.
type
()
==
CV_8UC4
);
virtual
void
operator
()(
const
GpuMat
&
src
,
GpuMat
&
dst
)
{
NppiSize
sz
;
sz
.
width
=
src
.
cols
;
sz
.
height
=
src
.
rows
;
int
kRowSize
=
rowKernel
.
cols
;
nppSafeCall
(
func
(
src
.
ptr
<
Npp8u
>
(),
src
.
step
,
dst
.
ptr
<
Npp8u
>
(),
dst
.
step
,
sz
,
kernel
.
ptr
<
Npp32s
>
(),
ksize
,
anchor
,
nDivisor
)
);
}
dst
.
create
(
src
.
size
(),
src
.
type
());
dst
=
Scalar
();
GpuMat
kernel
;
Npp32s
nDivisor
;
nppFilter1D_t
func
;
};
}
NppiSize
oROI
;
oROI
.
width
=
src
.
cols
-
kRowSize
+
1
;
oROI
.
height
=
src
.
rows
;
Ptr
<
BaseRowFilter_GPU
>
cv
::
gpu
::
getLinearRowFilter_GPU
(
int
srcType
,
int
bufType
,
const
GpuMat
&
rowKernel
,
int
anchor
,
int
nDivisor
)
{
static
const
nppFilter1D_t
nppFilter1D_callers
[]
=
{
0
,
nppiFilterRow_8u_C1R
,
0
,
0
,
nppiFilterRow_8u_C4R
}
;
if
(
anchor
<
0
)
anchor
=
kRowSize
>>
1
;
CV_Assert
((
srcType
==
CV_8UC1
||
srcType
==
CV_8UC4
)
&&
bufType
==
srcType
);
CV_Assert
(
rowKernel
.
type
()
==
CV_32SC1
&&
rowKernel
.
rows
==
1
)
;
GpuMat
srcROI
=
src
.
colRange
(
kRowSize
-
1
,
oROI
.
width
);
GpuMat
dstROI
=
dst
.
colRange
(
kRowSize
-
1
,
oROI
.
width
);
int
ksize
=
rowKernel
.
cols
;
nppFilter1D_callers
[
src
.
channels
()
>>
2
](
srcROI
.
ptr
<
Npp8u
>
(),
srcROI
.
step
,
dstROI
.
ptr
<
Npp8u
>
(),
dstROI
.
step
,
oROI
,
rowKernel
.
ptr
<
Npp32s
>
(),
kRowSize
,
anchor
,
nDivisor
);
}
normalizeAnchor
(
anchor
,
ksize
);
return
Ptr
<
BaseRowFilter_GPU
>
(
new
NppLinearRowFilter
(
ksize
,
anchor
,
rowKernel
,
nDivisor
,
nppFilter1D_callers
[
CV_MAT_CN
(
srcType
)]));
}
void
applyColumnFilter
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
const
GpuMat
&
columnKernel
,
Npp32s
anchor
=
-
1
,
Npp32s
nDivisor
=
1
)
namespace
{
class
NppLinearColumnFilter
:
public
BaseColumnFilter_GPU
{
static
const
nppFilter1D_t
nppFilter1D_callers
[]
=
{
nppiFilterColumn_8u_C1R
,
nppiFilterColumn_8u_C4R
};
public
:
NppLinearColumnFilter
(
int
ksize_
,
int
anchor_
,
const
GpuMat
&
kernel_
,
Npp32s
nDivisor_
,
nppFilter1D_t
func_
)
:
BaseColumnFilter_GPU
(
ksize_
,
anchor_
),
kernel
(
kernel_
),
nDivisor
(
nDivisor_
),
func
(
func_
)
{}
CV_Assert
(
src
.
type
()
==
CV_8UC1
||
src
.
type
()
==
CV_8UC4
);
virtual
void
operator
()(
const
GpuMat
&
src
,
GpuMat
&
dst
)
{
NppiSize
sz
;
sz
.
width
=
src
.
cols
;
sz
.
height
=
src
.
rows
;
int
kColSize
=
columnKernel
.
cols
;
nppSafeCall
(
func
(
src
.
ptr
<
Npp8u
>
(),
src
.
step
,
dst
.
ptr
<
Npp8u
>
(),
dst
.
step
,
sz
,
kernel
.
ptr
<
Npp32s
>
(),
ksize
,
anchor
,
nDivisor
)
);
}
dst
.
create
(
src
.
size
(),
src
.
type
());
dst
=
Scalar
();
GpuMat
kernel
;
Npp32s
nDivisor
;
nppFilter1D_t
func
;
};
}
NppiSize
oROI
;
oROI
.
width
=
src
.
cols
;
oROI
.
height
=
src
.
rows
-
kColSize
+
1
;
Ptr
<
BaseColumnFilter_GPU
>
cv
::
gpu
::
getLinearColumnFilter_GPU
(
int
bufType
,
int
dstType
,
const
GpuMat
&
columnKernel
,
int
anchor
,
int
nDivisor
)
{
static
const
nppFilter1D_t
nppFilter1D_callers
[]
=
{
0
,
nppiFilterColumn_8u_C1R
,
0
,
0
,
nppiFilterColumn_8u_C4R
}
;
if
(
anchor
<
0
)
anchor
=
kColSize
>>
1
;
CV_Assert
((
bufType
==
CV_8UC1
||
bufType
==
CV_8UC4
)
&&
dstType
==
bufType
);
CV_Assert
(
columnKernel
.
type
()
==
CV_32SC1
&&
columnKernel
.
rows
==
1
)
;
GpuMat
srcROI
=
src
.
rowRange
(
kColSize
-
1
,
oROI
.
height
);
GpuMat
dstROI
=
dst
.
rowRange
(
kColSize
-
1
,
oROI
.
height
);
nppFilter1D_callers
[
src
.
channels
()
>>
2
](
srcROI
.
ptr
<
Npp8u
>
(),
srcROI
.
step
,
dstROI
.
ptr
<
Npp8u
>
(),
dstROI
.
step
,
oROI
,
columnKernel
.
ptr
<
Npp32s
>
(),
kColSize
,
anchor
,
nDivisor
);
}
int
ksize
=
columnKernel
.
cols
;
inline
void
applySeparableFilter
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
const
GpuMat
&
rowKernel
,
const
GpuMat
&
columnKernel
,
const
cv
::
Point
&
anchor
=
cv
::
Point
(
-
1
,
-
1
),
Npp32s
nDivisor
=
1
)
{
GpuMat
dstBuf
;
applyRowFilter
(
src
,
dstBuf
,
rowKernel
,
anchor
.
x
,
nDivisor
);
applyColumnFilter
(
dstBuf
,
dst
,
columnKernel
,
anchor
.
y
,
nDivisor
);
}
normalizeAnchor
(
anchor
,
ksize
);
void
makeNppKernel
(
Mat
kernel
,
GpuMat
&
dst
)
{
kernel
.
convertTo
(
kernel
,
CV_32S
);
kernel
=
kernel
.
t
();
int
ksize
=
kernel
.
cols
;
for
(
int
i
=
0
;
i
<
ksize
/
2
;
++
i
)
{
std
::
swap
(
kernel
.
at
<
int
>
(
0
,
i
),
kernel
.
at
<
int
>
(
0
,
ksize
-
1
-
i
));
}
dst
.
upload
(
kernel
);
}
return
Ptr
<
BaseColumnFilter_GPU
>
(
new
NppLinearColumnFilter
(
ksize
,
anchor
,
columnKernel
,
nDivisor
,
nppFilter1D_callers
[
CV_MAT_CN
(
bufType
)]));
}
void
applyFilter2D
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
const
GpuMat
&
kernel
,
cv
::
Point
anchor
=
cv
::
Point
(
-
1
,
-
1
),
Npp32s
nDivisor
=
1
)
{
static
const
nppFilter2D_t
nppFilter2D_callers
[]
=
{
nppiFilter_8u_C1R
,
nppiFilter_8u_C4R
};
Ptr
<
FilterEngine_GPU
>
cv
::
gpu
::
createSeparableLinearFilter_GPU
(
int
srcType
,
int
dstType
,
const
Mat
&
rowKernel
,
const
Mat
&
columnKernel
,
const
Point
&
anchor
)
{
int
sdepth
=
CV_MAT_DEPTH
(
srcType
),
ddepth
=
CV_MAT_DEPTH
(
dstType
);
int
cn
=
CV_MAT_CN
(
srcType
);
int
bdepth
=
std
::
max
(
sdepth
,
ddepth
);
int
bufType
=
CV_MAKETYPE
(
bdepth
,
cn
);
CV_Assert
(
src
.
type
()
==
CV_8UC1
||
src
.
type
()
==
CV_8UC4
);
GpuMat
gpu_row_krnl
,
gpu_col_krnl
;
int
nRowDivisor
,
nColDivisor
;
normalizeKernel
(
rowKernel
,
gpu_row_krnl
,
CV_32S
,
&
nRowDivisor
,
true
);
normalizeKernel
(
columnKernel
,
gpu_col_krnl
,
CV_32S
,
&
nColDivisor
,
true
);
dst
.
create
(
src
.
size
(),
src
.
type
());
dst
=
Scalar
();
NppiSize
oROI
;
oROI
.
width
=
src
.
cols
-
kernel
.
cols
+
1
;
oROI
.
height
=
src
.
rows
-
kernel
.
rows
+
1
;
if
(
anchor
.
x
<
0
)
anchor
.
x
=
kernel
.
cols
>>
1
;
if
(
anchor
.
y
<
0
)
anchor
.
y
=
kernel
.
rows
>>
1
;
GpuMat
srcROI
=
src
(
Range
(
kernel
.
rows
-
1
,
oROI
.
height
),
Range
(
kernel
.
cols
-
1
,
oROI
.
width
));
GpuMat
dstROI
=
dst
(
Range
(
kernel
.
rows
-
1
,
oROI
.
height
),
Range
(
kernel
.
cols
-
1
,
oROI
.
width
));
NppiSize
oKernelSize
;
oKernelSize
.
height
=
kernel
.
rows
;
oKernelSize
.
width
=
kernel
.
cols
;
NppiPoint
oAnchor
;
oAnchor
.
x
=
anchor
.
x
;
oAnchor
.
y
=
anchor
.
y
;
nppFilter2D_callers
[
src
.
channels
()
>>
2
](
srcROI
.
ptr
<
Npp8u
>
(),
srcROI
.
step
,
dstROI
.
ptr
<
Npp8u
>
(),
dstROI
.
step
,
oROI
,
kernel
.
ptr
<
Npp32s
>
(),
oKernelSize
,
oAnchor
,
nDivisor
);
}
Ptr
<
BaseRowFilter_GPU
>
rowFilter
=
getLinearRowFilter_GPU
(
srcType
,
bufType
,
gpu_row_krnl
,
anchor
.
x
,
nRowDivisor
);
Ptr
<
BaseColumnFilter_GPU
>
columnFilter
=
getLinearColumnFilter_GPU
(
bufType
,
dstType
,
gpu_col_krnl
,
anchor
.
y
,
nColDivisor
);
return
createSeparableFilter_GPU
(
rowFilter
,
columnFilter
);
}
void
cv
::
gpu
::
sepFilter2D
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
int
ddepth
,
const
Mat
&
kernelX
,
const
Mat
&
kernelY
,
Point
anchor
)
{
if
(
ddepth
<
0
)
ddepth
=
src
.
depth
();
dst
.
create
(
src
.
size
(),
CV_MAKETYPE
(
ddepth
,
src
.
channels
()));
Ptr
<
FilterEngine_GPU
>
f
=
createSeparableLinearFilter_GPU
(
src
.
type
(),
dst
.
type
(),
kernelX
,
kernelY
,
anchor
);
f
->
apply
(
src
,
dst
);
}
////////////////////////////////////////////////////////////////////////
// Sobel
////////////////////////////////////////////////////////////////////////////////////////////////////
// Deriv Filter
Ptr
<
FilterEngine_GPU
>
cv
::
gpu
::
createDerivFilter_GPU
(
int
srcType
,
int
dstType
,
int
dx
,
int
dy
,
int
ksize
)
{
Mat
kx
,
ky
;
getDerivKernels
(
kx
,
ky
,
dx
,
dy
,
ksize
,
false
,
CV_32F
);
return
createSeparableLinearFilter_GPU
(
srcType
,
dstType
,
kx
,
ky
);
}
void
cv
::
gpu
::
Sobel
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
int
ddepth
,
int
dx
,
int
dy
,
int
ksize
,
double
scale
)
{
...
...
@@ -370,55 +703,86 @@ void cv::gpu::Sobel(const GpuMat& src, GpuMat& dst, int ddepth, int dx, int dy,
ky
*=
scale
;
}
GpuMat
rowKernel
;
makeNppKernel
(
kx
,
rowKernel
);
GpuMat
columnKernel
;
makeNppKernel
(
ky
,
columnKernel
);
applySeparableFilter
(
src
,
dst
,
rowKernel
,
columnKernel
);
sepFilter2D
(
src
,
dst
,
ddepth
,
kx
,
ky
,
Point
(
-
1
,
-
1
));
}
////////////////////////////////////////////////////////////////////////
// GaussianBlur
void
cv
::
gpu
::
GaussianBlur
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
Size
ksize
,
double
sigma1
,
double
sigma2
)
void
cv
::
gpu
::
Scharr
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
int
ddepth
,
int
dx
,
int
dy
,
double
scale
)
{
if
(
ksize
.
width
==
1
&&
ksize
.
height
==
1
)
Mat
kx
,
ky
;
getDerivKernels
(
kx
,
ky
,
dx
,
dy
,
-
1
,
false
,
CV_32F
);
if
(
scale
!=
1
)
{
src
.
copyTo
(
dst
);
return
;
// usually the smoothing part is the slowest to compute,
// so try to scale it instead of the faster differenciating part
if
(
dx
==
0
)
kx
*=
scale
;
else
ky
*=
scale
;
}
int
depth
=
src
.
depth
();
sepFilter2D
(
src
,
dst
,
ddepth
,
kx
,
ky
,
Point
(
-
1
,
-
1
));
}
void
cv
::
gpu
::
Laplacian
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
int
ddepth
,
int
ksize
,
double
scale
)
{
CV_Assert
(
ksize
==
1
||
ksize
==
3
);
static
const
int
K
[
2
][
9
]
=
{
{
0
,
1
,
0
,
1
,
-
4
,
1
,
0
,
1
,
0
},
{
2
,
0
,
2
,
0
,
-
8
,
0
,
2
,
0
,
2
}
};
Mat
kernel
(
3
,
3
,
CV_32S
,
(
void
*
)
K
[
ksize
==
3
]);
if
(
scale
!=
1
)
kernel
*=
scale
;
filter2D
(
src
,
dst
,
ddepth
,
kernel
,
Point
(
-
1
,
-
1
));
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Gaussian Filter
Ptr
<
FilterEngine_GPU
>
cv
::
gpu
::
createGaussianFilter_GPU
(
int
type
,
Size
ksize
,
double
sigma1
,
double
sigma2
)
{
int
depth
=
CV_MAT_DEPTH
(
type
);
if
(
sigma2
<=
0
)
sigma2
=
sigma1
;
// automatic detection of kernel size from sigma
if
(
ksize
.
width
<=
0
&&
sigma1
>
0
)
ksize
.
width
=
cvRound
(
sigma1
*
(
depth
==
CV_8U
?
3
:
4
)
*
2
+
1
)
|
1
;
ksize
.
width
=
cvRound
(
sigma1
*
(
depth
==
CV_8U
?
3
:
4
)
*
2
+
1
)
|
1
;
if
(
ksize
.
height
<=
0
&&
sigma2
>
0
)
ksize
.
height
=
cvRound
(
sigma2
*
(
depth
==
CV_8U
?
3
:
4
)
*
2
+
1
)
|
1
;
ksize
.
height
=
cvRound
(
sigma2
*
(
depth
==
CV_8U
?
3
:
4
)
*
2
+
1
)
|
1
;
CV_Assert
(
ksize
.
width
>
0
&&
ksize
.
width
%
2
==
1
&&
ksize
.
height
>
0
&&
ksize
.
height
%
2
==
1
);
CV_Assert
(
ksize
.
width
>
0
&&
ksize
.
width
%
2
==
1
&&
ksize
.
height
>
0
&&
ksize
.
height
%
2
==
1
);
sigma1
=
std
::
max
(
sigma1
,
0.0
);
sigma2
=
std
::
max
(
sigma2
,
0.0
);
const
int
scaleFactor
=
256
;
Mat
kx
=
getGaussianKernel
(
ksize
.
width
,
sigma1
,
std
::
max
(
depth
,
CV_32F
));
kx
.
convertTo
(
kx
,
kx
.
depth
(),
scaleFactor
);
Mat
kx
=
getGaussianKernel
(
ksize
.
width
,
sigma1
,
std
::
max
(
depth
,
CV_32F
)
);
Mat
ky
;
if
(
ksize
.
height
==
ksize
.
width
&&
std
::
abs
(
sigma1
-
sigma2
)
<
DBL_EPSILON
)
if
(
ksize
.
height
==
ksize
.
width
&&
std
::
abs
(
sigma1
-
sigma2
)
<
DBL_EPSILON
)
ky
=
kx
;
else
ky
=
getGaussianKernel
(
ksize
.
height
,
sigma2
,
std
::
max
(
depth
,
CV_32F
)
);
return
createSeparableLinearFilter_GPU
(
type
,
type
,
kx
,
ky
);
}
void
cv
::
gpu
::
GaussianBlur
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
Size
ksize
,
double
sigma1
,
double
sigma2
)
{
if
(
ksize
.
width
==
1
&&
ksize
.
height
==
1
)
{
ky
=
getGaussianKernel
(
ksize
.
height
,
sigma2
,
std
::
max
(
depth
,
CV_32F
));
ky
.
convertTo
(
ky
,
ky
.
depth
(),
scaleFactor
)
;
src
.
copyTo
(
dst
);
return
;
}
GpuMat
rowKernel
;
makeNppKernel
(
kx
,
rowKernel
);
GpuMat
columnKernel
;
makeNppKernel
(
ky
,
columnKernel
);
applySeparableFilter
(
src
,
dst
,
rowKernel
,
columnKernel
,
cv
::
Point
(
-
1
,
-
1
),
scaleFactor
);
dst
.
create
(
src
.
size
(),
src
.
type
()
);
Ptr
<
FilterEngine_GPU
>
f
=
createGaussianFilter_GPU
(
src
.
type
(),
ksize
,
sigma1
,
sigma2
);
f
->
apply
(
src
,
dst
);
}
#endif
modules/gpu/src/imgproc_gpu.cpp
View file @
66df8ef0
...
...
@@ -992,6 +992,7 @@ void cv::gpu::integral(GpuMat& src, GpuMat& sum, GpuMat& sqsum)
void
cv
::
gpu
::
Canny
(
const
GpuMat
&
image
,
GpuMat
&
edges
,
double
threshold1
,
double
threshold2
,
int
apertureSize
)
{
CV_Assert
(
!
"disabled until fix crash"
);
CV_Assert
(
image
.
type
()
==
CV_8UC1
);
GpuMat
srcDx
,
srcDy
;
...
...
tests/gpu/src/
morf_
filters.cpp
→
tests/gpu/src/filters.cpp
View file @
66df8ef0
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include <iostream>
#include <cmath>
#include <limits>
#include "gputest.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
using
namespace
cv
;
using
namespace
std
;
using
namespace
gpu
;
class
CV_GpuNppMorphogyTest
:
public
CvTest
{
public
:
CV_GpuNppMorphogyTest
(
const
char
*
test_name
,
const
char
*
test_funcs
)
:
CvTest
(
test_name
,
test_funcs
)
{}
virtual
~
CV_GpuNppMorphogyTest
()
{}
protected
:
void
run
(
int
);
virtual
int
test
(
const
Mat
&
img
)
=
0
;
int
test8UC1
(
const
Mat
&
img
)
{
cv
::
Mat
img_C1
;
cvtColor
(
img
,
img_C1
,
CV_BGR2GRAY
);
return
test
(
img_C1
);
}
int
test8UC4
(
const
Mat
&
img
)
{
cv
::
Mat
img_C4
;
cvtColor
(
img
,
img_C4
,
CV_BGR2BGRA
);
return
test
(
img_C4
);
}
int
CheckNorm
(
const
Mat
&
m1
,
const
Mat
&
m2
)
{
double
res
=
norm
(
m1
,
m2
,
NORM_INF
);
if
(
res
<
std
::
numeric_limits
<
double
>::
epsilon
())
return
CvTS
::
OK
;
ts
->
printf
(
CvTS
::
LOG
,
"
\n
Norm: %f
\n
"
,
res
);
return
CvTS
::
FAIL_GENERIC
;
}
};
void
CV_GpuNppMorphogyTest
::
run
(
int
)
{
cv
::
Mat
img
=
cv
::
imread
(
std
::
string
(
ts
->
get_data_path
())
+
"stereobp/aloe-L.png"
);
if
(
img
.
empty
())
{
ts
->
set_failed_test_info
(
CvTS
::
FAIL_MISSING_TEST_DATA
);
return
;
}
try
{
//run tests
int
testResult
=
test8UC1
(
img
);
if
(
testResult
!=
CvTS
::
OK
)
{
ts
->
set_failed_test_info
(
testResult
);
return
;
}
testResult
=
test8UC4
(
img
);
if
(
testResult
!=
CvTS
::
OK
)
{
ts
->
set_failed_test_info
(
testResult
);
return
;
}
}
catch
(
const
cv
::
Exception
&
e
)
{
if
(
!
check_and_treat_gpu_exception
(
e
,
ts
))
throw
;
return
;
}
ts
->
set_failed_test_info
(
CvTS
::
OK
);
}
////////////////////////////////////////////////////////////////////////////////
// Erode
class
CV_GpuErodeTest
:
public
CV_GpuNppMorphogyTest
{
public
:
CV_GpuErodeTest
()
:
CV_GpuNppMorphogyTest
(
"GPU-NppErode"
,
"erode"
)
{}
protected
:
virtual
int
test
(
const
Mat
&
img
)
{
GpuMat
kernel
(
Mat
::
ones
(
3
,
3
,
CV_8U
));
Point
anchor
(
0
,
0
);
int
iters
=
1
;
cv
::
Mat
cpuRes
,
cpuRes1
;
cv
::
erode
(
img
,
cpuRes
,
kernel
,
anchor
,
iters
);
GpuMat
gpuRes
;
cv
::
gpu
::
erode
(
GpuMat
(
img
),
gpuRes
,
kernel
,
anchor
,
iters
);
return
CheckNorm
(
cpuRes
,
gpuRes
);
}
};
////////////////////////////////////////////////////////////////////////////////
// Dilate
class
CV_GpuDilateTest
:
public
CV_GpuNppMorphogyTest
{
public
:
CV_GpuDilateTest
()
:
CV_GpuNppMorphogyTest
(
"GPU-NppDilate"
,
"dilate"
)
{}
protected
:
virtual
int
test
(
const
Mat
&
img
)
{
GpuMat
kernel
(
Mat
::
ones
(
3
,
3
,
CV_8U
));
Point
anchor
(
0
,
0
);
int
iters
=
1
;
cv
::
Mat
cpuRes
,
cpuRes1
;
cv
::
dilate
(
img
,
cpuRes
,
kernel
,
anchor
,
iters
);
GpuMat
gpuRes
,
gpuRes1
;
cv
::
gpu
::
dilate
(
GpuMat
(
img
),
gpuRes
,
kernel
,
anchor
,
iters
);
return
CheckNorm
(
cpuRes
,
gpuRes
);
}
};
////////////////////////////////////////////////////////////////////////////////
// Dilate
class
CV_GpuMorphExTest
:
public
CV_GpuNppMorphogyTest
{
public
:
CV_GpuMorphExTest
()
:
CV_GpuNppMorphogyTest
(
"GPU-NppMorphologyEx"
,
"dmorphologyExilate"
)
{}
protected
:
virtual
int
test
(
const
Mat
&
img
)
{
static
int
ops
[]
=
{
MORPH_OPEN
,
CV_MOP_CLOSE
,
CV_MOP_GRADIENT
,
CV_MOP_TOPHAT
,
CV_MOP_BLACKHAT
};
const
char
*
names
[]
=
{
"MORPH_OPEN"
,
"CV_MOP_CLOSE"
,
"CV_MOP_GRADIENT"
,
"CV_MOP_TOPHAT"
,
"CV_MOP_BLACKHAT"
};
int
num
=
sizeof
(
ops
)
/
sizeof
(
ops
[
0
]);
GpuMat
kernel
(
Mat
::
ones
(
3
,
3
,
CV_8U
));
Point
anchor
(
0
,
0
);
int
iters
=
1
;
for
(
int
i
=
0
;
i
<
num
;
++
i
)
{
ts
->
printf
(
CvTS
::
LOG
,
"Tesing %s
\n
"
,
names
[
i
]);
cv
::
Mat
cpuRes
;
cv
::
morphologyEx
(
img
,
cpuRes
,
ops
[
i
],
kernel
,
anchor
,
iters
);
GpuMat
gpuRes
;
cv
::
gpu
::
morphologyEx
(
GpuMat
(
img
),
gpuRes
,
ops
[
i
],
kernel
,
anchor
,
iters
);
int
res
=
CheckNorm
(
cpuRes
,
gpuRes
);
if
(
CvTS
::
OK
!=
res
)
return
res
;
}
return
CvTS
::
OK
;
}
};
/////////////////////////////////////////////////////////////////////////////
/////////////////// tests registration /////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
CV_GpuErodeTest
CV_GpuErode_test
;
CV_GpuDilateTest
CV_GpuDilate_test
;
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include <iostream>
#include <cmath>
#include <limits>
#include "gputest.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
using
namespace
cv
;
using
namespace
std
;
using
namespace
gpu
;
class
CV_GpuNppFilterTest
:
public
CvTest
{
public
:
CV_GpuNppFilterTest
(
const
char
*
test_name
,
const
char
*
test_funcs
)
:
CvTest
(
test_name
,
test_funcs
)
{}
virtual
~
CV_GpuNppFilterTest
()
{}
protected
:
void
run
(
int
);
virtual
int
test
(
const
Mat
&
img
)
=
0
;
int
test8UC1
(
const
Mat
&
img
)
{
cv
::
Mat
img_C1
;
cvtColor
(
img
,
img_C1
,
CV_BGR2GRAY
);
return
test
(
img_C1
);
}
int
test8UC4
(
const
Mat
&
img
)
{
cv
::
Mat
img_C4
;
cvtColor
(
img
,
img_C4
,
CV_BGR2BGRA
);
return
test
(
img_C4
);
}
int
CheckNorm
(
const
Mat
&
m1
,
const
Mat
&
m2
,
const
Size
&
ksize
)
{
Rect
roi
=
Rect
(
ksize
.
width
,
ksize
.
height
,
m1
.
cols
-
2
*
ksize
.
width
,
m1
.
rows
-
2
*
ksize
.
height
);
Mat
m1ROI
=
m1
(
roi
);
Mat
m2ROI
=
m2
(
roi
);
double
res
=
norm
(
m1ROI
,
m2ROI
,
NORM_INF
);
if
(
res
<=
1
)
return
CvTS
::
OK
;
ts
->
printf
(
CvTS
::
LOG
,
"
\n
Norm: %f
\n
"
,
res
);
return
CvTS
::
FAIL_GENERIC
;
}
};
void
CV_GpuNppFilterTest
::
run
(
int
)
{
cv
::
Mat
img
=
cv
::
imread
(
std
::
string
(
ts
->
get_data_path
())
+
"stereobp/aloe-L.png"
);
if
(
img
.
empty
())
{
ts
->
set_failed_test_info
(
CvTS
::
FAIL_MISSING_TEST_DATA
);
return
;
}
try
{
//run tests
int
testResult
=
CvTS
::
OK
;
if
(
test8UC1
(
img
)
!=
CvTS
::
OK
)
testResult
=
CvTS
::
FAIL_GENERIC
;
if
(
test8UC4
(
img
)
!=
CvTS
::
OK
)
testResult
=
CvTS
::
FAIL_GENERIC
;
ts
->
set_failed_test_info
(
testResult
);
}
catch
(
const
cv
::
Exception
&
e
)
{
if
(
!
check_and_treat_gpu_exception
(
e
,
ts
))
throw
;
return
;
}
ts
->
set_failed_test_info
(
CvTS
::
OK
);
}
////////////////////////////////////////////////////////////////////////////////
// blur
struct
CV_GpuNppImageBlurTest
:
public
CV_GpuNppFilterTest
{
CV_GpuNppImageBlurTest
()
:
CV_GpuNppFilterTest
(
"GPU-NppImageBlur"
,
"blur"
)
{}
int
test
(
const
Mat
&
img
)
{
int
ksizes
[]
=
{
3
,
5
,
7
};
int
ksizes_num
=
sizeof
(
ksizes
)
/
sizeof
(
int
);
int
test_res
=
CvTS
::
OK
;
for
(
int
i
=
0
;
i
<
ksizes_num
;
++
i
)
{
for
(
int
j
=
0
;
j
<
ksizes_num
;
++
j
)
{
Size
ksize
(
ksizes
[
i
],
ksizes
[
j
]);
ts
->
printf
(
CvTS
::
LOG
,
"
\n
ksize = (%dx%d)
\n
"
,
ksizes
[
i
],
ksizes
[
j
]);
Mat
cpudst
;
cv
::
blur
(
img
,
cpudst
,
ksize
);
GpuMat
gpu1
(
img
);
GpuMat
gpudst
;
cv
::
gpu
::
blur
(
gpu1
,
gpudst
,
ksize
);
if
(
CheckNorm
(
cpudst
,
gpudst
,
ksize
)
!=
CvTS
::
OK
)
test_res
=
CvTS
::
FAIL_GENERIC
;
}
}
return
test_res
;
}
};
////////////////////////////////////////////////////////////////////////////////
// Sobel
struct
CV_GpuNppImageSobelTest
:
public
CV_GpuNppFilterTest
{
CV_GpuNppImageSobelTest
()
:
CV_GpuNppFilterTest
(
"GPU-NppImageSobel"
,
"Sobel"
)
{}
int
test
(
const
Mat
&
img
)
{
int
ksizes
[]
=
{
3
,
5
,
7
};
int
ksizes_num
=
sizeof
(
ksizes
)
/
sizeof
(
int
);
int
dx
=
1
,
dy
=
0
;
int
test_res
=
CvTS
::
OK
;
for
(
int
i
=
0
;
i
<
ksizes_num
;
++
i
)
{
ts
->
printf
(
CvTS
::
LOG
,
"
\n
ksize = %d
\n
"
,
ksizes
[
i
]);
Mat
cpudst
;
cv
::
Sobel
(
img
,
cpudst
,
-
1
,
dx
,
dy
,
ksizes
[
i
]);
GpuMat
gpu1
(
img
);
GpuMat
gpudst
;
cv
::
gpu
::
Sobel
(
gpu1
,
gpudst
,
-
1
,
dx
,
dy
,
ksizes
[
i
]);
if
(
CheckNorm
(
cpudst
,
gpudst
,
Size
(
ksizes
[
i
],
ksizes
[
i
]))
!=
CvTS
::
OK
)
test_res
=
CvTS
::
FAIL_GENERIC
;
}
return
test_res
;
}
};
////////////////////////////////////////////////////////////////////////////////
// Scharr
struct
CV_GpuNppImageScharrTest
:
public
CV_GpuNppFilterTest
{
CV_GpuNppImageScharrTest
()
:
CV_GpuNppFilterTest
(
"GPU-NppImageScharr"
,
"Scharr"
)
{}
int
test
(
const
Mat
&
img
)
{
int
dx
=
1
,
dy
=
0
;
Mat
cpudst
;
cv
::
Scharr
(
img
,
cpudst
,
-
1
,
dx
,
dy
);
GpuMat
gpu1
(
img
);
GpuMat
gpudst
;
cv
::
gpu
::
Scharr
(
gpu1
,
gpudst
,
-
1
,
dx
,
dy
);
return
CheckNorm
(
cpudst
,
gpudst
,
Size
(
3
,
3
));
}
};
////////////////////////////////////////////////////////////////////////////////
// GaussianBlur
struct
CV_GpuNppImageGaussianBlurTest
:
public
CV_GpuNppFilterTest
{
CV_GpuNppImageGaussianBlurTest
()
:
CV_GpuNppFilterTest
(
"GPU-NppImageGaussianBlur"
,
"GaussianBlur"
)
{}
int
test
(
const
Mat
&
img
)
{
int
ksizes
[]
=
{
3
,
5
,
7
};
int
ksizes_num
=
sizeof
(
ksizes
)
/
sizeof
(
int
);
int
test_res
=
CvTS
::
OK
;
const
double
sigma1
=
3.0
;
for
(
int
i
=
0
;
i
<
ksizes_num
;
++
i
)
{
for
(
int
j
=
0
;
j
<
ksizes_num
;
++
j
)
{
cv
::
Size
ksize
(
ksizes
[
i
],
ksizes
[
j
]);
ts
->
printf
(
CvTS
::
LOG
,
"
\n
ksize = (%dx%d)
\n
"
,
ksizes
[
i
],
ksizes
[
j
]);
Mat
cpudst
;
cv
::
GaussianBlur
(
img
,
cpudst
,
ksize
,
sigma1
);
GpuMat
gpu1
(
img
);
GpuMat
gpudst
;
cv
::
gpu
::
GaussianBlur
(
gpu1
,
gpudst
,
ksize
,
sigma1
);
if
(
CheckNorm
(
cpudst
,
gpudst
,
ksize
)
!=
CvTS
::
OK
)
test_res
=
CvTS
::
FAIL_GENERIC
;
}
}
return
test_res
;
}
};
////////////////////////////////////////////////////////////////////////////////
// Laplacian
struct
CV_GpuNppImageLaplacianTest
:
public
CV_GpuNppFilterTest
{
CV_GpuNppImageLaplacianTest
()
:
CV_GpuNppFilterTest
(
"GPU-NppImageLaplacian"
,
"Laplacian"
)
{}
int
test
(
const
Mat
&
img
)
{
int
ksizes
[]
=
{
1
,
3
};
int
ksizes_num
=
sizeof
(
ksizes
)
/
sizeof
(
int
);
int
test_res
=
CvTS
::
OK
;
for
(
int
i
=
0
;
i
<
ksizes_num
;
++
i
)
{
ts
->
printf
(
CvTS
::
LOG
,
"
\n
ksize = %d
\n
"
,
ksizes
[
i
]);
Mat
cpudst
;
cv
::
Laplacian
(
img
,
cpudst
,
-
1
,
ksizes
[
i
]);
GpuMat
gpu1
(
img
);
GpuMat
gpudst
;
cv
::
gpu
::
Laplacian
(
gpu1
,
gpudst
,
-
1
,
ksizes
[
i
]);
if
(
CheckNorm
(
cpudst
,
gpudst
,
Size
(
3
,
3
))
!=
CvTS
::
OK
)
test_res
=
CvTS
::
FAIL_GENERIC
;
}
return
test_res
;
}
};
////////////////////////////////////////////////////////////////////////////////
// Erode
class
CV_GpuErodeTest
:
public
CV_GpuNppFilterTest
{
public
:
CV_GpuErodeTest
()
:
CV_GpuNppFilterTest
(
"GPU-NppErode"
,
"erode"
)
{}
protected
:
virtual
int
test
(
const
Mat
&
img
)
{
Mat
kernel
(
Mat
::
ones
(
3
,
3
,
CV_8U
));
cv
::
Mat
cpuRes
;
cv
::
erode
(
img
,
cpuRes
,
kernel
);
GpuMat
gpuRes
;
cv
::
gpu
::
erode
(
GpuMat
(
img
),
gpuRes
,
kernel
);
return
CheckNorm
(
cpuRes
,
gpuRes
,
Size
(
3
,
3
));
}
};
////////////////////////////////////////////////////////////////////////////////
// Dilate
class
CV_GpuDilateTest
:
public
CV_GpuNppFilterTest
{
public
:
CV_GpuDilateTest
()
:
CV_GpuNppFilterTest
(
"GPU-NppDilate"
,
"dilate"
)
{}
protected
:
virtual
int
test
(
const
Mat
&
img
)
{
Mat
kernel
(
Mat
::
ones
(
3
,
3
,
CV_8U
));
cv
::
Mat
cpuRes
;
cv
::
dilate
(
img
,
cpuRes
,
kernel
);
GpuMat
gpuRes
;
cv
::
gpu
::
dilate
(
GpuMat
(
img
),
gpuRes
,
kernel
);
return
CheckNorm
(
cpuRes
,
gpuRes
,
Size
(
3
,
3
));
}
};
////////////////////////////////////////////////////////////////////////////////
// MorphologyEx
class
CV_GpuMorphExTest
:
public
CV_GpuNppFilterTest
{
public
:
CV_GpuMorphExTest
()
:
CV_GpuNppFilterTest
(
"GPU-NppMorphologyEx"
,
"morphologyEx"
)
{}
protected
:
virtual
int
test
(
const
Mat
&
img
)
{
static
int
ops
[]
=
{
MORPH_OPEN
,
CV_MOP_CLOSE
,
CV_MOP_GRADIENT
,
CV_MOP_TOPHAT
,
CV_MOP_BLACKHAT
};
const
char
*
names
[]
=
{
"MORPH_OPEN"
,
"CV_MOP_CLOSE"
,
"CV_MOP_GRADIENT"
,
"CV_MOP_TOPHAT"
,
"CV_MOP_BLACKHAT"
};
int
num
=
sizeof
(
ops
)
/
sizeof
(
ops
[
0
]);
GpuMat
kernel
(
Mat
::
ones
(
3
,
3
,
CV_8U
));
int
res
=
CvTS
::
OK
;
for
(
int
i
=
0
;
i
<
num
;
++
i
)
{
ts
->
printf
(
CvTS
::
LOG
,
"Tesing %s
\n
"
,
names
[
i
]);
cv
::
Mat
cpuRes
;
cv
::
morphologyEx
(
img
,
cpuRes
,
ops
[
i
],
kernel
);
GpuMat
gpuRes
;
cv
::
gpu
::
morphologyEx
(
GpuMat
(
img
),
gpuRes
,
ops
[
i
],
kernel
);
if
(
CvTS
::
OK
!=
CheckNorm
(
cpuRes
,
gpuRes
,
Size
(
3
,
3
)))
res
=
CvTS
::
FAIL_GENERIC
;
}
return
res
;
}
};
/////////////////////////////////////////////////////////////////////////////
/////////////////// tests registration /////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
CV_GpuNppImageBlurTest
CV_GpuNppImageBlur_test
;
CV_GpuNppImageSobelTest
CV_GpuNppImageSobel_test
;
CV_GpuNppImageScharrTest
CV_GpuNppImageScharr_test
;
CV_GpuNppImageGaussianBlurTest
CV_GpuNppImageGaussianBlur_test
;
CV_GpuNppImageLaplacianTest
CV_GpuNppImageLaplacian_test
;
CV_GpuErodeTest
CV_GpuErode_test
;
CV_GpuDilateTest
CV_GpuDilate_test
;
CV_GpuMorphExTest
CV_GpuMorphEx_test
;
\ No newline at end of file
tests/gpu/src/gputest_main.cpp
View file @
66df8ef0
...
...
@@ -45,25 +45,27 @@ CvTS test_system;
const
char
*
blacklist
[]
=
{
"GPU-NppImageSum"
,
// crash
"GPU-MatOperatorAsyncCall"
,
// crash
//"GPU-NppErode", // different border interpolation
//"GPU-NppMorphologyEx", // different border interpolation
"GPU-NppImageSum"
,
// crash, probably npp bug
"GPU-NppImageMinNax"
,
// npp bug - don't find min/max near right border
//"GPU-NppImageDivide", // different round mode
//"GPU-NppImageMeanStdDev", // different precision
//"GPU-NppImageMinNax", // npp bug - don't find min/max near right border
//"GPU-NppImageResize", // different precision in interpolation
//"GPU-NppImageWarpAffine", // different precision in interpolation
//"GPU-NppImageWarpPerspective", // different precision in interpolation
//"GPU-NppImageIntegral", // different precision
//"GPU-NppImageBlur", // different precision
//"GPU-NppImageExp", // different precision
//"GPU-NppImageLog", // different precision
//"GPU-NppImageMagnitude", // different precision
//"GPU-NppImageSumWindow", // different border interpolation
//"GPU-NppImageSobel", // ???
//"GPU-NppImageGaussianBlur", // different border interpolation
"GPU-NppImageCanny"
,
// NPP_TEXTURE_BIND_ERROR
//"GPU-NppImageResize", // different precision
//"GPU-NppImageWarpAffine", // different precision
//"GPU-NppImageWarpPerspective", // different precision
//"GPU-NppImageIntegral", // different precision
//"GPU-NppImageSobel", // ???
//"GPU-NppImageScharr", // ???
//"GPU-NppImageGaussianBlur", // different precision
//"GPU-NppMorphologyEx", // different precision?
0
};
...
...
tests/gpu/src/imgproc_gpu.cpp
View file @
66df8ef0
...
...
@@ -413,167 +413,6 @@ struct CV_GpuNppImageIntegralTest : public CV_GpuImageProcTest
}
};
////////////////////////////////////////////////////////////////////////////////
// blur
struct
CV_GpuNppImageBlurTest
:
public
CV_GpuImageProcTest
{
CV_GpuNppImageBlurTest
()
:
CV_GpuImageProcTest
(
"GPU-NppImageBlur"
,
"blur"
)
{}
int
test
(
const
Mat
&
img
)
{
if
(
img
.
type
()
!=
CV_8UC1
&&
img
.
type
()
!=
CV_8UC4
)
{
ts
->
printf
(
CvTS
::
LOG
,
"
\n
Unsupported type
\n
"
);
return
CvTS
::
OK
;
}
int
ksizes
[]
=
{
3
,
5
,
7
};
int
ksizes_num
=
sizeof
(
ksizes
)
/
sizeof
(
int
);
int
test_res
=
CvTS
::
OK
;
for
(
int
i
=
0
;
i
<
ksizes_num
;
++
i
)
{
ts
->
printf
(
CvTS
::
LOG
,
"
\n
ksize = %d
\n
"
,
ksizes
[
i
]);
Mat
cpudst
;
cv
::
blur
(
img
,
cpudst
,
Size
(
ksizes
[
i
],
ksizes
[
i
]));
GpuMat
gpu1
(
img
);
GpuMat
gpudst
;
cv
::
gpu
::
blur
(
gpu1
,
gpudst
,
Size
(
ksizes
[
i
],
ksizes
[
i
]));
if
(
CheckNorm
(
cpudst
,
gpudst
)
!=
CvTS
::
OK
)
test_res
=
CvTS
::
FAIL_GENERIC
;
}
return
test_res
;
}
};
////////////////////////////////////////////////////////////////////////////////
// sumWindow
struct
CV_GpuNppImageSumWindowTest
:
public
CV_GpuImageProcTest
{
CV_GpuNppImageSumWindowTest
()
:
CV_GpuImageProcTest
(
"GPU-NppImageSumWindow"
,
"sumWindow"
)
{}
int
test
(
const
Mat
&
img
)
{
if
(
img
.
type
()
!=
CV_8UC1
)
{
ts
->
printf
(
CvTS
::
LOG
,
"
\n
Unsupported type
\n
"
);
return
CvTS
::
OK
;
}
int
ksizes
[]
=
{
3
,
5
,
7
};
int
ksizes_num
=
sizeof
(
ksizes
)
/
sizeof
(
int
);
int
test_res
=
CvTS
::
OK
;
for
(
int
i
=
0
;
i
<
ksizes_num
;
++
i
)
{
ts
->
printf
(
CvTS
::
LOG
,
"
\n
ksize = %d
\n
"
,
ksizes
[
i
]);
Mat
cpudst
(
img
.
size
(),
CV_64FC1
,
Scalar
());
cv
::
Ptr
<
cv
::
BaseRowFilter
>
ft
=
cv
::
getRowSumFilter
(
CV_8UC1
,
CV_64FC1
,
ksizes
[
i
],
0
);
for
(
int
y
=
0
;
y
<
img
.
rows
;
++
y
)
(
*
ft
)(
img
.
ptr
(
y
),
cpudst
.
ptr
(
y
),
img
.
cols
,
1
);
cpudst
.
convertTo
(
cpudst
,
CV_32F
);
GpuMat
gpu1
(
img
);
GpuMat
gpudst
;
cv
::
gpu
::
sumWindowRow
(
gpu1
,
gpudst
,
ksizes
[
i
],
0
);
if
(
CheckNorm
(
cpudst
,
gpudst
)
!=
CvTS
::
OK
)
test_res
=
CvTS
::
FAIL_GENERIC
;
}
return
test_res
;
}
};
////////////////////////////////////////////////////////////////////////////////
// Sobel
struct
CV_GpuNppImageSobelTest
:
public
CV_GpuImageProcTest
{
CV_GpuNppImageSobelTest
()
:
CV_GpuImageProcTest
(
"GPU-NppImageSobel"
,
"Sobel"
)
{}
int
test
(
const
Mat
&
img
)
{
if
(
img
.
type
()
!=
CV_8UC1
&&
img
.
type
()
!=
CV_8UC4
)
{
ts
->
printf
(
CvTS
::
LOG
,
"
\n
Unsupported type
\n
"
);
return
CvTS
::
OK
;
}
int
ksizes
[]
=
{
3
,
5
,
7
};
int
ksizes_num
=
sizeof
(
ksizes
)
/
sizeof
(
int
);
int
dx
=
1
,
dy
=
0
;
int
test_res
=
CvTS
::
OK
;
for
(
int
i
=
0
;
i
<
ksizes_num
;
++
i
)
{
ts
->
printf
(
CvTS
::
LOG
,
"
\n
ksize = %d
\n
"
,
ksizes
[
i
]);
Mat
cpudst
;
cv
::
Sobel
(
img
,
cpudst
,
-
1
,
dx
,
dy
,
ksizes
[
i
]);
GpuMat
gpu1
(
img
);
GpuMat
gpudst
;
cv
::
gpu
::
Sobel
(
gpu1
,
gpudst
,
-
1
,
dx
,
dy
,
ksizes
[
i
]);
if
(
CheckNorm
(
cpudst
,
gpudst
)
!=
CvTS
::
OK
)
test_res
=
CvTS
::
FAIL_GENERIC
;
}
return
test_res
;
}
};
////////////////////////////////////////////////////////////////////////////////
// GaussianBlur
struct
CV_GpuNppImageGaussianBlurTest
:
public
CV_GpuImageProcTest
{
CV_GpuNppImageGaussianBlurTest
()
:
CV_GpuImageProcTest
(
"GPU-NppImageGaussianBlur"
,
"GaussianBlur"
)
{}
int
test
(
const
Mat
&
img
)
{
if
(
img
.
type
()
!=
CV_8UC1
&&
img
.
type
()
!=
CV_8UC4
)
{
ts
->
printf
(
CvTS
::
LOG
,
"
\n
Unsupported type
\n
"
);
return
CvTS
::
OK
;
}
int
ksizes
[]
=
{
3
,
5
,
7
};
int
ksizes_num
=
sizeof
(
ksizes
)
/
sizeof
(
int
);
int
test_res
=
CvTS
::
OK
;
const
double
sigma1
=
3.0
;
for
(
int
i
=
0
;
i
<
ksizes_num
;
++
i
)
{
for
(
int
j
=
0
;
j
<
ksizes_num
;
++
j
)
{
ts
->
printf
(
CvTS
::
LOG
,
"
\n
ksize = (%dx%d)
\n
"
,
ksizes
[
i
],
ksizes
[
j
]);
Mat
cpudst
;
cv
::
GaussianBlur
(
img
,
cpudst
,
cv
::
Size
(
ksizes
[
i
],
ksizes
[
j
]),
sigma1
);
GpuMat
gpu1
(
img
);
GpuMat
gpudst
;
cv
::
gpu
::
GaussianBlur
(
gpu1
,
gpudst
,
cv
::
Size
(
ksizes
[
i
],
ksizes
[
j
]),
sigma1
);
if
(
CheckNorm
(
cpudst
,
gpudst
)
!=
CvTS
::
OK
)
test_res
=
CvTS
::
FAIL_GENERIC
;
}
}
return
test_res
;
}
};
////////////////////////////////////////////////////////////////////////////////
// Canny
struct
CV_GpuNppImageCannyTest
:
public
CV_GpuImageProcTest
...
...
@@ -705,9 +544,5 @@ CV_GpuNppImageCopyMakeBorderTest CV_GpuNppImageCopyMakeBorder_test;
CV_GpuNppImageWarpAffineTest
CV_GpuNppImageWarpAffine_test
;
CV_GpuNppImageWarpPerspectiveTest
CV_GpuNppImageWarpPerspective_test
;
CV_GpuNppImageIntegralTest
CV_GpuNppImageIntegral_test
;
CV_GpuNppImageBlurTest
CV_GpuNppImageBlur_test
;
CV_GpuNppImageSumWindowTest
CV_GpuNppImageSumWindow_test
;
CV_GpuNppImageSobelTest
CV_GpuNppImageSobel_test
;
CV_GpuNppImageGaussianBlurTest
CV_GpuNppImageGaussianBlur_test
;
CV_GpuNppImageCannyTest
CV_GpuNppImageCanny_test
;
CV_GpuCvtColorTest
CV_GpuCvtColor_test
;
\ No newline at end of file
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