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
437ac1a2
Commit
437ac1a2
authored
Nov 29, 2010
by
Alexey Spizhevoy
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
added mask support into gpu::minMax
parent
bb532239
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
120 additions
and
65 deletions
+120
-65
gpu.hpp
modules/gpu/include/opencv2/gpu/gpu.hpp
+2
-2
arithm.cpp
modules/gpu/src/arithm.cpp
+57
-51
mathfunc.cu
modules/gpu/src/cuda/mathfunc.cu
+0
-0
arithm.cpp
tests/gpu/src/arithm.cpp
+61
-12
No files found.
modules/gpu/include/opencv2/gpu/gpu.hpp
View file @
437ac1a2
...
...
@@ -425,10 +425,10 @@ namespace cv
CV_EXPORTS
Scalar
sum
(
const
GpuMat
&
m
);
//! finds global minimum and maximum array elements and returns their values
CV_EXPORTS
void
minMax
(
const
GpuMat
&
src
,
double
*
minVal
,
double
*
maxVal
=
0
);
CV_EXPORTS
void
minMax
(
const
GpuMat
&
src
,
double
*
minVal
,
double
*
maxVal
=
0
,
const
GpuMat
&
mask
=
GpuMat
()
);
//! finds global minimum and maximum array elements and returns their values
CV_EXPORTS
void
minMax
(
const
GpuMat
&
src
,
double
*
minVal
,
double
*
maxVal
,
GpuMat
&
buf
);
CV_EXPORTS
void
minMax
(
const
GpuMat
&
src
,
double
*
minVal
,
double
*
maxVal
,
const
GpuMat
&
mask
,
GpuMat
&
buf
);
//! finds global minimum and maximum array elements and returns their values with locations
CV_EXPORTS
void
minMaxLoc
(
const
GpuMat
&
src
,
double
*
minVal
,
double
*
maxVal
=
0
,
Point
*
minLoc
=
0
,
Point
*
maxLoc
=
0
);
...
...
modules/gpu/src/arithm.cpp
View file @
437ac1a2
...
...
@@ -65,8 +65,8 @@ double cv::gpu::norm(const GpuMat&, int) { throw_nogpu(); return 0.0; }
double
cv
::
gpu
::
norm
(
const
GpuMat
&
,
const
GpuMat
&
,
int
)
{
throw_nogpu
();
return
0.0
;
}
void
cv
::
gpu
::
flip
(
const
GpuMat
&
,
GpuMat
&
,
int
)
{
throw_nogpu
();
}
Scalar
cv
::
gpu
::
sum
(
const
GpuMat
&
)
{
throw_nogpu
();
return
Scalar
();
}
void
cv
::
gpu
::
minMax
(
const
GpuMat
&
,
double
*
,
double
*
)
{
throw_nogpu
();
}
void
cv
::
gpu
::
minMax
(
const
GpuMat
&
,
double
*
,
double
*
,
GpuMat
&
)
{
throw_nogpu
();
}
void
cv
::
gpu
::
minMax
(
const
GpuMat
&
,
double
*
,
double
*
,
const
GpuMat
&
)
{
throw_nogpu
();
}
void
cv
::
gpu
::
minMax
(
const
GpuMat
&
,
double
*
,
double
*
,
const
GpuMat
&
,
GpuMat
&
)
{
throw_nogpu
();
}
void
cv
::
gpu
::
minMaxLoc
(
const
GpuMat
&
,
double
*
,
double
*
,
Point
*
,
Point
*
)
{
throw_nogpu
();
}
void
cv
::
gpu
::
minMaxLoc
(
const
GpuMat
&
,
double
*
,
double
*
,
Point
*
,
Point
*
,
GpuMat
&
,
GpuMat
&
)
{
throw_nogpu
();
}
int
cv
::
gpu
::
countNonZero
(
const
GpuMat
&
)
{
throw_nogpu
();
return
0
;
}
...
...
@@ -502,62 +502,68 @@ namespace cv { namespace gpu { namespace mathfunc { namespace minmax {
void
min_max_caller
(
const
DevMem2D
src
,
double
*
minval
,
double
*
maxval
,
PtrStep
buf
);
template
<
typename
T
>
void
min_max_caller_2steps
(
const
DevMem2D
src
,
double
*
minval
,
double
*
maxval
,
PtrStep
buf
);
void
min_max_mask_caller
(
const
DevMem2D
src
,
const
PtrStep
mask
,
double
*
minval
,
double
*
maxval
,
PtrStep
buf
);
template
<
typename
T
>
void
min_max_multipass_caller
(
const
DevMem2D
src
,
double
*
minval
,
double
*
maxval
,
PtrStep
buf
);
template
<
typename
T
>
void
min_max_mask_multipass_caller
(
const
DevMem2D
src
,
const
PtrStep
mask
,
double
*
minval
,
double
*
maxval
,
PtrStep
buf
);
}}}}
void
cv
::
gpu
::
minMax
(
const
GpuMat
&
src
,
double
*
minVal
,
double
*
maxVal
)
void
cv
::
gpu
::
minMax
(
const
GpuMat
&
src
,
double
*
minVal
,
double
*
maxVal
,
const
GpuMat
&
mask
)
{
GpuMat
buf
;
minMax
(
src
,
minVal
,
maxVal
,
buf
);
minMax
(
src
,
minVal
,
maxVal
,
mask
,
buf
);
}
void
cv
::
gpu
::
minMax
(
const
GpuMat
&
src
,
double
*
minVal
,
double
*
maxVal
,
GpuMat
&
buf
)
void
cv
::
gpu
::
minMax
(
const
GpuMat
&
src
,
double
*
minVal
,
double
*
maxVal
,
const
GpuMat
&
mask
,
GpuMat
&
buf
)
{
using
namespace
mathfunc
::
minmax
;
typedef
void
(
*
Caller
)(
const
DevMem2D
,
double
*
,
double
*
,
PtrStep
);
static
const
Caller
callers
[
2
][
7
]
=
{
{
min_max_multipass_caller
<
unsigned
char
>
,
min_max_multipass_caller
<
signed
char
>
,
min_max_multipass_caller
<
unsigned
short
>
,
min_max_multipass_caller
<
signed
short
>
,
min_max_multipass_caller
<
int
>
,
min_max_multipass_caller
<
float
>
,
0
},
{
min_max_caller
<
unsigned
char
>
,
min_max_caller
<
signed
char
>
,
min_max_caller
<
unsigned
short
>
,
min_max_caller
<
signed
short
>
,
min_max_caller
<
int
>
,
min_max_caller
<
float
>
,
min_max_caller
<
double
>
}
};
typedef
void
(
*
MaskedCaller
)(
const
DevMem2D
,
const
PtrStep
,
double
*
,
double
*
,
PtrStep
);
static
const
MaskedCaller
masked_callers
[
2
][
7
]
=
{
{
min_max_mask_multipass_caller
<
unsigned
char
>
,
min_max_mask_multipass_caller
<
signed
char
>
,
min_max_mask_multipass_caller
<
unsigned
short
>
,
min_max_mask_multipass_caller
<
signed
short
>
,
min_max_mask_multipass_caller
<
int
>
,
min_max_mask_multipass_caller
<
float
>
,
0
},
{
min_max_mask_caller
<
unsigned
char
>
,
min_max_mask_caller
<
signed
char
>
,
min_max_mask_caller
<
unsigned
short
>
,
min_max_mask_caller
<
signed
short
>
,
min_max_mask_caller
<
int
>
,
min_max_mask_caller
<
float
>
,
min_max_mask_caller
<
double
>
}
};
CV_Assert
(
src
.
channels
()
==
1
);
CV_Assert
(
mask
.
empty
()
||
(
mask
.
type
()
==
CV_8U
&&
src
.
size
()
==
mask
.
size
()));
CV_Assert
(
src
.
type
()
!=
CV_64F
||
hasNativeDoubleSupport
(
getDevice
()));
double
minVal_
;
if
(
!
minVal
)
minVal
=
&
minVal_
;
double
maxVal_
;
if
(
!
maxVal
)
maxVal
=
&
maxVal_
;
GpuMat
src_
=
src
.
reshape
(
1
);
Size
bufSize
;
get_buf_size_required
(
src
.
elemSize
(),
bufSize
.
width
,
bufSize
.
height
);
buf
.
create
(
bufSize
,
CV_8U
);
int
device
=
getDevice
();
if
(
hasAtomicsSupport
(
device
))
if
(
mask
.
empty
())
{
switch
(
src_
.
type
())
{
case
CV_8U
:
min_max_caller
<
unsigned
char
>
(
src_
,
minVal
,
maxVal
,
buf
);
break
;
case
CV_8S
:
min_max_caller
<
signed
char
>
(
src_
,
minVal
,
maxVal
,
buf
);
break
;
case
CV_16U
:
min_max_caller
<
unsigned
short
>
(
src_
,
minVal
,
maxVal
,
buf
);
break
;
case
CV_16S
:
min_max_caller
<
signed
short
>
(
src_
,
minVal
,
maxVal
,
buf
);
break
;
case
CV_32S
:
min_max_caller
<
int
>
(
src_
,
minVal
,
maxVal
,
buf
);
break
;
case
CV_32F
:
min_max_caller
<
float
>
(
src_
,
minVal
,
maxVal
,
buf
);
break
;
case
CV_64F
:
if
(
hasNativeDoubleSupport
(
device
))
{
min_max_caller
<
double
>
(
src_
,
minVal
,
maxVal
,
buf
);
break
;
}
default
:
CV_Error
(
CV_StsBadArg
,
"minMax: unsupported type"
);
}
Caller
caller
=
callers
[
hasAtomicsSupport
(
getDevice
())][
src
.
type
()];
if
(
!
caller
)
CV_Error
(
CV_StsBadArg
,
"minMax: unsupported type"
);
caller
(
src
,
minVal
,
maxVal
,
buf
);
}
else
{
switch
(
src_
.
type
())
{
case
CV_8U
:
min_max_caller_2steps
<
unsigned
char
>
(
src_
,
minVal
,
maxVal
,
buf
);
break
;
case
CV_8S
:
min_max_caller_2steps
<
signed
char
>
(
src_
,
minVal
,
maxVal
,
buf
);
break
;
case
CV_16U
:
min_max_caller_2steps
<
unsigned
short
>
(
src_
,
minVal
,
maxVal
,
buf
);
break
;
case
CV_16S
:
min_max_caller_2steps
<
signed
short
>
(
src_
,
minVal
,
maxVal
,
buf
);
break
;
case
CV_32S
:
min_max_caller_2steps
<
int
>
(
src_
,
minVal
,
maxVal
,
buf
);
break
;
case
CV_32F
:
min_max_caller_2steps
<
float
>
(
src_
,
minVal
,
maxVal
,
buf
);
break
;
default
:
CV_Error
(
CV_StsBadArg
,
"minMax: unsupported type"
);
}
MaskedCaller
caller
=
masked_callers
[
hasAtomicsSupport
(
getDevice
())][
src
.
type
()];
if
(
!
caller
)
CV_Error
(
CV_StsBadArg
,
"minMax: unsupported type"
);
caller
(
src
,
mask
,
minVal
,
maxVal
,
buf
);
}
}
...
...
@@ -575,7 +581,7 @@ namespace cv { namespace gpu { namespace mathfunc { namespace minmaxloc {
int
minloc
[
2
],
int
maxloc
[
2
],
PtrStep
valbuf
,
PtrStep
locbuf
);
template
<
typename
T
>
void
min_max_loc_
caller_2steps
(
const
DevMem2D
src
,
double
*
minval
,
double
*
maxval
,
void
min_max_loc_
multipass_caller
(
const
DevMem2D
src
,
double
*
minval
,
double
*
maxval
,
int
minloc
[
2
],
int
maxloc
[
2
],
PtrStep
valbuf
,
PtrStep
locbuf
);
}}}}
...
...
@@ -627,12 +633,12 @@ void cv::gpu::minMaxLoc(const GpuMat& src, double* minVal, double* maxVal, Point
{
switch
(
src
.
type
())
{
case
CV_8U
:
min_max_loc_
caller_2steps
<
unsigned
char
>
(
src
,
minVal
,
maxVal
,
minLoc_
,
maxLoc_
,
valbuf
,
locbuf
);
break
;
case
CV_8S
:
min_max_loc_
caller_2steps
<
signed
char
>
(
src
,
minVal
,
maxVal
,
minLoc_
,
maxLoc_
,
valbuf
,
locbuf
);
break
;
case
CV_16U
:
min_max_loc_
caller_2steps
<
unsigned
short
>
(
src
,
minVal
,
maxVal
,
minLoc_
,
maxLoc_
,
valbuf
,
locbuf
);
break
;
case
CV_16S
:
min_max_loc_
caller_2steps
<
signed
short
>
(
src
,
minVal
,
maxVal
,
minLoc_
,
maxLoc_
,
valbuf
,
locbuf
);
break
;
case
CV_32S
:
min_max_loc_
caller_2steps
<
int
>
(
src
,
minVal
,
maxVal
,
minLoc_
,
maxLoc_
,
valbuf
,
locbuf
);
break
;
case
CV_32F
:
min_max_loc_
caller_2steps
<
float
>
(
src
,
minVal
,
maxVal
,
minLoc_
,
maxLoc_
,
valbuf
,
locbuf
);
break
;
case
CV_8U
:
min_max_loc_
multipass_caller
<
unsigned
char
>
(
src
,
minVal
,
maxVal
,
minLoc_
,
maxLoc_
,
valbuf
,
locbuf
);
break
;
case
CV_8S
:
min_max_loc_
multipass_caller
<
signed
char
>
(
src
,
minVal
,
maxVal
,
minLoc_
,
maxLoc_
,
valbuf
,
locbuf
);
break
;
case
CV_16U
:
min_max_loc_
multipass_caller
<
unsigned
short
>
(
src
,
minVal
,
maxVal
,
minLoc_
,
maxLoc_
,
valbuf
,
locbuf
);
break
;
case
CV_16S
:
min_max_loc_
multipass_caller
<
signed
short
>
(
src
,
minVal
,
maxVal
,
minLoc_
,
maxLoc_
,
valbuf
,
locbuf
);
break
;
case
CV_32S
:
min_max_loc_
multipass_caller
<
int
>
(
src
,
minVal
,
maxVal
,
minLoc_
,
maxLoc_
,
valbuf
,
locbuf
);
break
;
case
CV_32F
:
min_max_loc_
multipass_caller
<
float
>
(
src
,
minVal
,
maxVal
,
minLoc_
,
maxLoc_
,
valbuf
,
locbuf
);
break
;
default
:
CV_Error
(
CV_StsBadArg
,
"minMaxLoc: unsupported type"
);
}
}
...
...
@@ -652,7 +658,7 @@ namespace cv { namespace gpu { namespace mathfunc { namespace countnonzero {
int
count_non_zero_caller
(
const
DevMem2D
src
,
PtrStep
buf
);
template
<
typename
T
>
int
count_non_zero_
caller_2steps
(
const
DevMem2D
src
,
PtrStep
buf
);
int
count_non_zero_
multipass_caller
(
const
DevMem2D
src
,
PtrStep
buf
);
}}}}
...
...
@@ -691,12 +697,12 @@ int cv::gpu::countNonZero(const GpuMat& src, GpuMat& buf)
{
switch
(
src
.
type
())
{
case
CV_8U
:
return
count_non_zero_
caller_2steps
<
unsigned
char
>
(
src
,
buf
);
case
CV_8S
:
return
count_non_zero_
caller_2steps
<
signed
char
>
(
src
,
buf
);
case
CV_16U
:
return
count_non_zero_
caller_2steps
<
unsigned
short
>
(
src
,
buf
);
case
CV_16S
:
return
count_non_zero_
caller_2steps
<
signed
short
>
(
src
,
buf
);
case
CV_32S
:
return
count_non_zero_
caller_2steps
<
int
>
(
src
,
buf
);
case
CV_32F
:
return
count_non_zero_
caller_2steps
<
float
>
(
src
,
buf
);
case
CV_8U
:
return
count_non_zero_
multipass_caller
<
unsigned
char
>
(
src
,
buf
);
case
CV_8S
:
return
count_non_zero_
multipass_caller
<
signed
char
>
(
src
,
buf
);
case
CV_16U
:
return
count_non_zero_
multipass_caller
<
unsigned
short
>
(
src
,
buf
);
case
CV_16S
:
return
count_non_zero_
multipass_caller
<
signed
short
>
(
src
,
buf
);
case
CV_32S
:
return
count_non_zero_
multipass_caller
<
int
>
(
src
,
buf
);
case
CV_32F
:
return
count_non_zero_
multipass_caller
<
float
>
(
src
,
buf
);
}
}
...
...
modules/gpu/src/cuda/mathfunc.cu
View file @
437ac1a2
This diff is collapsed.
Click to expand it.
tests/gpu/src/arithm.cpp
View file @
437ac1a2
...
...
@@ -682,16 +682,16 @@ struct CV_GpuMinMaxTest: public CvTest
{
int
depth_end
;
if
(
cv
::
gpu
::
hasNativeDoubleSupport
(
cv
::
gpu
::
getDevice
()))
depth_end
=
CV_64F
;
else
depth_end
=
CV_32F
;
for
(
int
cn
=
1
;
cn
<=
4
;
++
cn
)
for
(
int
depth
=
CV_8U
;
depth
<=
depth_end
;
++
depth
)
for
(
int
depth
=
CV_8U
;
depth
<=
depth_end
;
++
depth
)
{
for
(
int
i
=
0
;
i
<
1
;
++
i
)
{
for
(
int
i
=
0
;
i
<
1
;
++
i
)
{
int
rows
=
1
+
rand
()
%
1000
;
int
cols
=
1
+
rand
()
%
1000
;
test
(
rows
,
cols
,
cn
,
depth
);
}
int
rows
=
1
+
rand
()
%
1000
;
int
cols
=
1
+
rand
()
%
1000
;
test
(
rows
,
cols
,
1
,
depth
);
test_masked
(
rows
,
cols
,
1
,
depth
);
}
}
}
void
test
(
int
rows
,
int
cols
,
int
cn
,
int
depth
)
...
...
@@ -707,10 +707,59 @@ struct CV_GpuMinMaxTest: public CvTest
double
minVal
,
maxVal
;
cv
::
Point
minLoc
,
maxLoc
;
if
(
depth
!=
CV_8S
)
{
cv
::
minMaxLoc
(
src
,
&
minVal
,
&
maxVal
,
&
minLoc
,
&
maxLoc
);
}
else
{
minVal
=
std
::
numeric_limits
<
double
>::
max
();
maxVal
=
std
::
numeric_limits
<
double
>::
min
();
for
(
int
i
=
0
;
i
<
src
.
rows
;
++
i
)
for
(
int
j
=
0
;
j
<
src
.
cols
;
++
j
)
{
signed
char
val
=
src
.
at
<
signed
char
>
(
i
,
j
);
if
(
val
<
minVal
)
minVal
=
val
;
if
(
val
>
maxVal
)
maxVal
=
val
;
}
}
double
minVal_
,
maxVal_
;
cv
::
Point
minLoc_
,
maxLoc_
;
cv
::
gpu
::
minMax
(
cv
::
gpu
::
GpuMat
(
src
),
&
minVal_
,
&
maxVal_
,
cv
::
gpu
::
GpuMat
(),
buf
);
if
(
abs
(
minVal
-
minVal_
)
>
1e-3
f
)
{
ts
->
printf
(
CvTS
::
CONSOLE
,
"
\n
fail: minVal=%f minVal_=%f rows=%d cols=%d depth=%d cn=%d
\n
"
,
minVal
,
minVal_
,
rows
,
cols
,
depth
,
cn
);
ts
->
set_failed_test_info
(
CvTS
::
FAIL_INVALID_OUTPUT
);
}
if
(
abs
(
maxVal
-
maxVal_
)
>
1e-3
f
)
{
ts
->
printf
(
CvTS
::
CONSOLE
,
"
\n
fail: maxVal=%f maxVal_=%f rows=%d cols=%d depth=%d cn=%d
\n
"
,
maxVal
,
maxVal_
,
rows
,
cols
,
depth
,
cn
);
ts
->
set_failed_test_info
(
CvTS
::
FAIL_INVALID_OUTPUT
);
}
}
void
test_masked
(
int
rows
,
int
cols
,
int
cn
,
int
depth
)
{
cv
::
Mat
src
(
rows
,
cols
,
CV_MAKE_TYPE
(
depth
,
cn
));
cv
::
RNG
rng
;
for
(
int
i
=
0
;
i
<
src
.
rows
;
++
i
)
{
Mat
row
(
1
,
src
.
cols
*
src
.
elemSize
(),
CV_8U
,
src
.
ptr
(
i
));
rng
.
fill
(
row
,
RNG
::
UNIFORM
,
Scalar
(
0
),
Scalar
(
255
));
}
cv
::
Mat
mask
(
src
.
size
(),
CV_8U
);
rng
.
fill
(
mask
,
RNG
::
UNIFORM
,
Scalar
(
0
),
Scalar
(
2
));
double
minVal
,
maxVal
;
cv
::
Point
minLoc
,
maxLoc
;
Mat
src_
=
src
.
reshape
(
1
);
if
(
depth
!=
CV_8S
)
{
cv
::
minMaxLoc
(
src_
,
&
minVal
,
&
maxVal
,
&
minLoc
,
&
maxLoc
);
cv
::
minMaxLoc
(
src_
,
&
minVal
,
&
maxVal
,
&
minLoc
,
&
maxLoc
,
mask
);
}
else
{
...
...
@@ -721,14 +770,14 @@ struct CV_GpuMinMaxTest: public CvTest
for
(
int
j
=
0
;
j
<
src_
.
cols
;
++
j
)
{
char
val
=
src_
.
at
<
char
>
(
i
,
j
);
if
(
val
<
minVal
)
minVal
=
val
;
if
(
val
>
maxVal
)
maxVal
=
val
;
if
(
mask
.
at
<
unsigned
char
>
(
i
,
j
))
{
if
(
val
<
minVal
)
minVal
=
val
;
}
if
(
mask
.
at
<
unsigned
char
>
(
i
,
j
))
{
if
(
val
>
maxVal
)
maxVal
=
val
;
}
}
}
double
minVal_
,
maxVal_
;
cv
::
Point
minLoc_
,
maxLoc_
;
cv
::
gpu
::
minMax
(
cv
::
gpu
::
GpuMat
(
src
),
&
minVal_
,
&
maxVal_
,
buf
);
cv
::
gpu
::
minMax
(
cv
::
gpu
::
GpuMat
(
src
),
&
minVal_
,
&
maxVal_
,
cv
::
gpu
::
GpuMat
(
mask
),
buf
);
if
(
abs
(
minVal
-
minVal_
)
>
1e-3
f
)
{
...
...
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