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
90c23067
Commit
90c23067
authored
Dec 03, 2013
by
Roman Donchenko
Committed by
OpenCV Buildbot
Dec 03, 2013
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1912 from KonstantinMatskevich:ocl_tapi_math
parents
35ea600c
eaf620dd
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
162 additions
and
14 deletions
+162
-14
mathfuncs.cpp
modules/core/src/mathfuncs.cpp
+79
-13
arithm.cl
modules/core/src/opencl/arithm.cl
+3
-1
test_arithm.cpp
modules/core/test/ocl/test_arithm.cpp
+80
-0
No files found.
modules/core/src/mathfuncs.cpp
View file @
90c23067
...
...
@@ -41,7 +41,7 @@
//M*/
#include "precomp.hpp"
#include "opencl_kernels.hpp"
namespace
cv
{
...
...
@@ -54,6 +54,50 @@ static const float atan2_p3 = -0.3258083974640975f*(float)(180/CV_PI);
static
const
float
atan2_p5
=
0.1555786518463281
f
*
(
float
)(
180
/
CV_PI
);
static
const
float
atan2_p7
=
-
0.04432655554792128
f
*
(
float
)(
180
/
CV_PI
);
enum
{
OCL_OP_LOG
=
0
,
OCL_OP_EXP
=
1
,
OCL_OP_MAG
=
2
,
OCL_OP_PHASE_DEGREES
=
3
,
OCL_OP_PHASE_RADIANS
=
4
};
static
const
char
*
oclop2str
[]
=
{
"OP_LOG"
,
"OP_EXP"
,
"OP_MAG"
,
"OP_PHASE_DEGREES"
,
"OP_PHASE_RADIANS"
,
0
};
static
bool
ocl_math_op
(
InputArray
_src1
,
InputArray
_src2
,
OutputArray
_dst
,
int
oclop
)
{
int
type1
=
_src1
.
type
(),
depth1
=
CV_MAT_DEPTH
(
type1
),
cn1
=
CV_MAT_CN
(
type1
);
int
type2
=
_src2
.
type
(),
cn2
=
CV_MAT_CN
(
type2
);
char
opts
[
1024
];
bool
double_support
=
false
;
if
(
ocl
::
Device
::
getDefault
().
doubleFPConfig
()
>
0
)
double_support
=
true
;
if
(
!
double_support
&&
depth1
==
CV_64F
)
return
false
;
sprintf
(
opts
,
"-D %s -D %s -D dstT=%s %s"
,
_src2
.
empty
()
?
"UNARY_OP"
:
"BINARY_OP"
,
oclop2str
[
oclop
],
ocl
::
typeToStr
(
CV_MAKETYPE
(
depth1
,
1
)
),
double_support
?
"-D DOUBLE_SUPPORT"
:
""
);
ocl
::
Kernel
k
(
"KF"
,
ocl
::
core
::
arithm_oclsrc
,
opts
);
if
(
k
.
empty
()
)
return
false
;
UMat
src1
=
_src1
.
getUMat
();
UMat
src2
=
_src2
.
getUMat
();
_dst
.
create
(
src1
.
size
(),
type1
);
UMat
dst
=
_dst
.
getUMat
();
ocl
::
KernelArg
src1arg
=
ocl
::
KernelArg
::
ReadOnlyNoSize
(
src1
,
cn1
);
ocl
::
KernelArg
src2arg
=
ocl
::
KernelArg
::
ReadOnlyNoSize
(
src2
,
cn2
);
ocl
::
KernelArg
dstarg
=
ocl
::
KernelArg
::
WriteOnly
(
dst
,
cn1
);
if
(
_src2
.
empty
())
k
.
args
(
src1arg
,
dstarg
);
else
k
.
args
(
src1arg
,
src2arg
,
dstarg
);
size_t
globalsize
[]
=
{
src1
.
cols
*
cn1
,
src1
.
rows
};
return
k
.
run
(
2
,
globalsize
,
0
,
false
);
}
float
fastAtan2
(
float
y
,
float
x
)
{
float
ax
=
std
::
abs
(
x
),
ay
=
std
::
abs
(
y
);
...
...
@@ -354,9 +398,16 @@ static void Sqrt_64f(const double* src, double* dst, int len)
void
magnitude
(
InputArray
src1
,
InputArray
src2
,
OutputArray
dst
)
{
int
type
=
src1
.
type
(),
depth
=
src1
.
depth
(),
cn
=
src1
.
channels
();
CV_Assert
(
src1
.
size
()
==
src2
.
size
()
&&
type
==
src2
.
type
()
&&
(
depth
==
CV_32F
||
depth
==
CV_64F
));
bool
use_opencl
=
dst
.
isUMat
()
&&
ocl
::
useOpenCL
()
&&
src1
.
dims
()
<=
2
&&
src2
.
dims
()
<=
2
;
if
(
use_opencl
&&
ocl_math_op
(
src1
,
src2
,
dst
,
OCL_OP_MAG
)
)
return
;
Mat
X
=
src1
.
getMat
(),
Y
=
src2
.
getMat
();
int
type
=
X
.
type
(),
depth
=
X
.
depth
(),
cn
=
X
.
channels
();
CV_Assert
(
X
.
size
==
Y
.
size
&&
type
==
Y
.
type
()
&&
(
depth
==
CV_32F
||
depth
==
CV_64F
));
dst
.
create
(
X
.
dims
,
X
.
size
,
X
.
type
());
Mat
Mag
=
dst
.
getMat
();
...
...
@@ -385,9 +436,16 @@ void magnitude( InputArray src1, InputArray src2, OutputArray dst )
void
phase
(
InputArray
src1
,
InputArray
src2
,
OutputArray
dst
,
bool
angleInDegrees
)
{
int
type
=
src1
.
type
(),
depth
=
src1
.
depth
(),
cn
=
src1
.
channels
();
CV_Assert
(
src1
.
size
()
==
src2
.
size
()
&&
type
==
src2
.
type
()
&&
(
depth
==
CV_32F
||
depth
==
CV_64F
));
bool
use_opencl
=
dst
.
isUMat
()
&&
ocl
::
useOpenCL
()
&&
src1
.
dims
()
<=
2
&&
src2
.
dims
()
<=
2
;
if
(
use_opencl
&&
ocl_math_op
(
src1
,
src2
,
dst
,
angleInDegrees
?
OCL_OP_PHASE_DEGREES
:
OCL_OP_PHASE_RADIANS
)
)
return
;
Mat
X
=
src1
.
getMat
(),
Y
=
src2
.
getMat
();
int
type
=
X
.
type
(),
depth
=
X
.
depth
(),
cn
=
X
.
channels
();
CV_Assert
(
X
.
size
==
Y
.
size
&&
type
==
Y
.
type
()
&&
(
depth
==
CV_32F
||
depth
==
CV_64F
));
dst
.
create
(
X
.
dims
,
X
.
size
,
type
);
Mat
Angle
=
dst
.
getMat
();
...
...
@@ -1151,14 +1209,18 @@ static void Exp_64f( const double *_x, double *y, int n )
void
exp
(
InputArray
_src
,
OutputArray
_dst
)
{
Mat
src
=
_src
.
getMat
();
int
type
=
src
.
type
(),
depth
=
src
.
depth
(),
cn
=
src
.
channels
();
int
type
=
_src
.
type
(),
depth
=
_src
.
depth
(),
cn
=
_src
.
channels
();
CV_Assert
(
depth
==
CV_32F
||
depth
==
CV_64F
);
bool
use_opencl
=
_dst
.
isUMat
()
&&
ocl
::
useOpenCL
()
&&
_src
.
dims
()
<=
2
;
if
(
use_opencl
&&
ocl_math_op
(
_src
,
noArray
(),
_dst
,
OCL_OP_EXP
)
)
return
;
Mat
src
=
_src
.
getMat
();
_dst
.
create
(
src
.
dims
,
src
.
size
,
type
);
Mat
dst
=
_dst
.
getMat
();
CV_Assert
(
depth
==
CV_32F
||
depth
==
CV_64F
);
const
Mat
*
arrays
[]
=
{
&
src
,
&
dst
,
0
};
uchar
*
ptrs
[
2
];
NAryMatIterator
it
(
arrays
,
ptrs
);
...
...
@@ -1796,14 +1858,18 @@ static void Log_64f( const double *x, double *y, int n )
void
log
(
InputArray
_src
,
OutputArray
_dst
)
{
Mat
src
=
_src
.
getMat
();
int
type
=
src
.
type
(),
depth
=
src
.
depth
(),
cn
=
src
.
channels
(
);
int
type
=
_src
.
type
(),
depth
=
_src
.
depth
(),
cn
=
_src
.
channels
();
CV_Assert
(
depth
==
CV_32F
||
depth
==
CV_64F
);
bool
use_opencl
=
_dst
.
isUMat
()
&&
ocl
::
useOpenCL
()
&&
_src
.
dims
()
<=
2
;
if
(
use_opencl
&&
ocl_math_op
(
_src
,
noArray
(),
_dst
,
OCL_OP_LOG
)
)
return
;
Mat
src
=
_src
.
getMat
();
_dst
.
create
(
src
.
dims
,
src
.
size
,
type
);
Mat
dst
=
_dst
.
getMat
();
CV_Assert
(
depth
==
CV_32F
||
depth
==
CV_64F
);
const
Mat
*
arrays
[]
=
{
&
src
,
&
dst
,
0
};
uchar
*
ptrs
[
2
];
NAryMatIterator
it
(
arrays
,
ptrs
);
...
...
modules/core/src/opencl/arithm.cl
View file @
90c23067
...
...
@@ -173,7 +173,9 @@
#define PROCESS_ELEM dstelem = sqrt(srcelem1)
#elif defined OP_LOG
#define PROCESS_ELEM dstelem = log(abs(srcelem1))
#define PROCESS_ELEM \
dstT v = (dstT)(srcelem1);\
dstelem = v > (dstT)(0) ? log(v) : log(-v)
#elif defined OP_CMP
#define PROCESS_ELEM dstelem = convert_uchar(srcelem1 CMP_OPERATOR srcelem2 ? 255 : 0)
...
...
modules/core/test/ocl/test_arithm.cpp
View file @
90c23067
...
...
@@ -281,11 +281,91 @@ OCL_TEST_P(Subtract, Scalar_Mask)
}
}
//////////////////////////////////////// Log /////////////////////////////////////////
typedef
ArithmTestBase
Log
;
OCL_TEST_P
(
Log
,
Mat
)
{
for
(
int
j
=
0
;
j
<
test_loop_times
;
j
++
)
{
generateTestData
();
OCL_OFF
(
cv
::
log
(
src1_roi
,
dst1_roi
));
OCL_ON
(
cv
::
log
(
usrc1_roi
,
udst1_roi
));
Near
(
1
);
}
}
//////////////////////////////////////// Exp /////////////////////////////////////////
typedef
ArithmTestBase
Exp
;
OCL_TEST_P
(
Exp
,
Mat
)
{
for
(
int
j
=
0
;
j
<
test_loop_times
;
j
++
)
{
generateTestData
();
OCL_OFF
(
cv
::
exp
(
src1_roi
,
dst1_roi
));
OCL_ON
(
cv
::
exp
(
usrc1_roi
,
udst1_roi
));
Near
(
2
);
}
}
//////////////////////////////////////// Phase /////////////////////////////////////////
typedef
ArithmTestBase
Phase
;
OCL_TEST_P
(
Phase
,
angleInDegree
)
{
for
(
int
j
=
0
;
j
<
test_loop_times
;
j
++
)
{
generateTestData
();
OCL_OFF
(
cv
::
phase
(
src1_roi
,
src2_roi
,
dst1_roi
,
true
));
OCL_ON
(
cv
::
phase
(
usrc1_roi
,
usrc2_roi
,
udst1_roi
,
true
));
Near
(
1e-2
);
}
}
OCL_TEST_P
(
Phase
,
angleInRadians
)
{
for
(
int
j
=
0
;
j
<
test_loop_times
;
j
++
)
{
generateTestData
();
OCL_OFF
(
cv
::
phase
(
src1_roi
,
src2_roi
,
dst1_roi
));
OCL_ON
(
cv
::
phase
(
usrc1_roi
,
usrc2_roi
,
udst1_roi
));
Near
(
1e-2
);
}
}
//////////////////////////////////////// Magnitude /////////////////////////////////////////
typedef
ArithmTestBase
Magnitude
;
OCL_TEST_P
(
Magnitude
,
Mat
)
{
for
(
int
j
=
0
;
j
<
test_loop_times
;
j
++
)
{
generateTestData
();
OCL_OFF
(
cv
::
magnitude
(
src1_roi
,
src2_roi
,
dst1_roi
));
OCL_ON
(
cv
::
magnitude
(
usrc1_roi
,
usrc2_roi
,
udst1_roi
));
Near
(
depth
==
CV_64F
?
1e-5
:
1e-2
);
}
}
//////////////////////////////////////// Instantiation /////////////////////////////////////////
OCL_INSTANTIATE_TEST_CASE_P
(
Arithm
,
Lut
,
Combine
(
::
testing
::
Values
(
CV_8U
,
CV_8S
),
OCL_ALL_DEPTHS
,
::
testing
::
Values
(
1
,
2
,
3
,
4
),
Bool
(),
Bool
()));
OCL_INSTANTIATE_TEST_CASE_P
(
Arithm
,
Add
,
Combine
(
OCL_ALL_DEPTHS
,
::
testing
::
Values
(
1
,
2
,
4
),
Bool
()));
OCL_INSTANTIATE_TEST_CASE_P
(
Arithm
,
Subtract
,
Combine
(
OCL_ALL_DEPTHS
,
::
testing
::
Values
(
1
,
2
,
4
),
Bool
()));
OCL_INSTANTIATE_TEST_CASE_P
(
Arithm
,
Log
,
Combine
(
::
testing
::
Values
(
CV_32F
,
CV_64F
),
::
testing
::
Values
(
1
,
2
,
3
,
4
),
Bool
()));
OCL_INSTANTIATE_TEST_CASE_P
(
Arithm
,
Exp
,
Combine
(
::
testing
::
Values
(
CV_32F
,
CV_64F
),
::
testing
::
Values
(
1
,
2
,
3
,
4
),
Bool
()));
OCL_INSTANTIATE_TEST_CASE_P
(
Arithm
,
Phase
,
Combine
(
::
testing
::
Values
(
CV_32F
,
CV_64F
),
::
testing
::
Values
(
1
,
2
,
3
,
4
),
Bool
()));
OCL_INSTANTIATE_TEST_CASE_P
(
Arithm
,
Magnitude
,
Combine
(
::
testing
::
Values
(
CV_32F
,
CV_64F
),
::
testing
::
Values
(
1
,
2
,
3
,
4
),
Bool
()));
}
}
// namespace cvtest::ocl
...
...
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