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
d2c2c07a
Commit
d2c2c07a
authored
Jan 11, 2011
by
Vadim Pisarevsky
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
updated the new arithmetic tests
parent
57f917d6
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
1168 additions
and
43 deletions
+1168
-43
test_arithm.cpp
modules/core/test/test_arithm.cpp
+51
-15
gtestcv.hpp
modules/gtest/include/opencv2/gtest/gtestcv.hpp
+19
-10
gtestcv.cpp
modules/gtest/src/gtestcv.cpp
+1098
-18
No files found.
modules/core/test/test_arithm.cpp
View file @
d2c2c07a
#include "precomp.hpp"
#include "precomp.hpp"
#include <iostream>
using
namespace
cv
;
using
namespace
cv
;
using
namespace
std
;
const
int
ARITHM_NTESTS
=
1000
;
const
int
ARITHM_RNG_SEED
=
-
1
;
const
int
ARITHM_MAX_NDIMS
=
4
;
const
int
ARITHM_MAX_SIZE_LOG
=
10
;
const
int
ARITHM_MAX_CHANNELS
=
4
;
static
void
getArithmValueRange
(
int
depth
,
double
&
minval
,
double
&
maxval
)
{
minval
=
depth
<
CV_32S
?
cvtest
::
getMinVal
(
depth
)
:
depth
==
CV_32S
?
-
1000000
:
-
1000.
;
maxval
=
depth
<
CV_32S
?
cvtest
::
getMinVal
(
depth
)
:
depth
==
CV_32S
?
1000000
:
1000.
;
}
static
double
getArithmMaxErr
(
int
depth
)
{
return
depth
<
CV_32F
?
0
:
4
;
}
TEST
(
ArithmTest
,
add
)
TEST
(
ArithmTest
,
add
)
{
{
typedef
uchar
_Tp
;
int
testIdx
=
0
;
RNG
rng
(
ARITHM_RNG_SEED
);
for
(
testIdx
=
0
;
testIdx
<
ARITHM_NTESTS
;
testIdx
++
)
{
double
minval
,
maxval
;
vector
<
int
>
size
;
cvtest
::
randomSize
(
rng
,
2
,
ARITHM_MAX_NDIMS
,
ARITHM_MAX_SIZE_LOG
,
size
);
int
type
=
cvtest
::
randomType
(
rng
,
cvtest
::
TYPE_MASK_ALL
,
1
,
ARITHM_MAX_CHANNELS
);
int
depth
=
CV_MAT_DEPTH
(
type
);
bool
haveMask
=
rng
.
uniform
(
0
,
4
)
==
0
;
Mat
A
(
30
,
30
,
DataType
<
_Tp
>::
type
),
B
(
A
.
size
(),
A
.
type
()),
C0
,
C
;
getArithmValueRange
(
depth
,
minval
,
maxval
);
RNG
rng
(
-
1
);
Mat
src1
=
cvtest
::
randomMat
(
rng
,
size
,
type
,
minval
,
maxval
,
true
);
rng
.
fill
(
A
,
RNG
::
UNIFORM
,
Scalar
::
all
(
0
),
Scalar
::
all
(
256
));
Mat
src2
=
cvtest
::
randomMat
(
rng
,
size
,
type
,
minval
,
maxval
,
true
);
rng
.
fill
(
B
,
RNG
::
UNIFORM
,
Scalar
::
all
(
0
),
Scalar
::
all
(
256
));
Mat
dst0
=
cvtest
::
randomMat
(
rng
,
size
,
type
,
minval
,
maxval
,
false
);
C0
.
create
(
A
.
size
(),
A
.
type
());
Mat
dst
=
cvtest
::
randomMat
(
rng
,
size
,
type
,
minval
,
maxval
,
true
);
int
i
,
j
,
cols
=
A
.
cols
*
A
.
channels
();
Mat
mask
;
for
(
i
=
0
;
i
<
A
.
rows
;
i
++
)
if
(
haveMask
)
{
mask
=
cvtest
::
randomMat
(
rng
,
size
,
CV_8U
,
0
,
2
,
true
);
cvtest
::
copy
(
dst0
,
dst
);
cvtest
::
add
(
src1
,
1
,
src2
,
1
,
Scalar
::
all
(
0
),
dst0
,
dst
.
type
());
cvtest
::
copy
(
dst
,
dst0
,
mask
,
true
);
add
(
src1
,
src2
,
dst
,
mask
);
}
else
{
{
const
_Tp
*
aptr
=
A
.
ptr
<
_Tp
>
(
i
);
cvtest
::
add
(
src1
,
1
,
src2
,
1
,
Scalar
::
all
(
0
),
dst0
,
dst
.
type
());
const
_Tp
*
bptr
=
B
.
ptr
<
_Tp
>
(
i
);
add
(
src1
,
src2
,
dst
);
_Tp
*
cptr
=
C0
.
ptr
<
_Tp
>
(
i
);
}
for
(
j
=
0
;
j
<
cols
;
j
++
)
cptr
[
j
]
=
saturate_cast
<
_Tp
>
(
aptr
[
j
]
+
bptr
[
j
]);
double
maxErr
=
getArithmMaxErr
(
depth
);
vector
<
int
>
pos
;
ASSERT_TRUE
(
cvtest
::
cmpEps
(
dst0
,
dst
,
maxErr
,
&
pos
))
<<
"position: "
<<
Mat
(
pos
);
}
}
add
(
A
,
B
,
C
);
EXPECT_EQ
(
norm
(
C
,
C0
,
NORM_INF
),
0
);
}
}
modules/gtest/include/opencv2/gtest/gtestcv.hpp
View file @
d2c2c07a
...
@@ -28,28 +28,37 @@ enum
...
@@ -28,28 +28,37 @@ enum
TYPE_MASK_ALL_BUT_8S
=
TYPE_MASK_ALL
&
~
TYPE_MASK_8S
TYPE_MASK_ALL_BUT_8S
=
TYPE_MASK_ALL
&
~
TYPE_MASK_8S
};
};
CV_EXPORTS
double
getMinVal
(
int
depth
);
CV_EXPORTS
double
getMaxVal
(
int
depth
);
CV_EXPORTS
Size
randomSize
(
RNG
&
rng
,
double
maxSizeLog
);
CV_EXPORTS
Size
randomSize
(
RNG
&
rng
,
double
maxSizeLog
);
CV_EXPORTS
void
randomSize
(
RNG
&
rng
,
int
minDims
,
int
maxDims
,
double
maxSizeLog
,
vector
<
int
>&
sz
);
CV_EXPORTS
void
randomSize
(
RNG
&
rng
,
int
minDims
,
int
maxDims
,
double
maxSizeLog
,
vector
<
int
>&
sz
);
CV_EXPORTS
int
randomType
(
RNG
&
rng
,
int
typeMask
,
int
minChannels
,
int
maxChannels
);
CV_EXPORTS
int
randomType
(
RNG
&
rng
,
int
typeMask
,
int
minChannels
,
int
maxChannels
);
CV_EXPORTS
Mat
randomMat
(
RNG
&
rng
,
Size
size
,
int
type
,
bool
useRoi
);
CV_EXPORTS
Mat
randomMat
(
RNG
&
rng
,
Size
size
,
int
type
,
double
minVal
,
double
maxVal
,
bool
useRoi
);
CV_EXPORTS
Mat
randomMat
(
RNG
&
rng
,
const
vector
<
int
>&
size
,
int
type
,
bool
useRoi
);
CV_EXPORTS
Mat
randomMat
(
RNG
&
rng
,
const
vector
<
int
>&
size
,
int
type
,
double
minVal
,
double
maxVal
,
bool
useRoi
);
CV_EXPORTS
void
add
(
const
Mat
&
a
,
double
alpha
,
const
Mat
&
b
,
double
beta
,
CV_EXPORTS
void
add
(
const
Mat
&
a
,
double
alpha
,
const
Mat
&
b
,
double
beta
,
Scalar
gamma
,
Mat
&
c
,
int
ctype
,
bool
calcAbs
);
Scalar
gamma
,
Mat
&
c
,
int
ctype
,
bool
calcAbs
=
false
);
CV_EXPORTS
void
convert
(
const
Mat
&
src
,
Mat
&
dst
,
int
dtype
,
double
alpha
,
double
beta
);
CV_EXPORTS
void
convert
(
const
Mat
&
src
,
Mat
&
dst
,
int
dtype
,
double
alpha
=
1
,
double
beta
=
0
);
CV_EXPORTS
void
copy
(
const
Mat
&
src
,
Mat
&
dst
,
const
Mat
&
mask
=
Mat
());
CV_EXPORTS
void
copy
(
const
Mat
&
src
,
Mat
&
dst
,
const
Mat
&
mask
=
Mat
()
,
bool
invertMask
=
false
);
CV_EXPORTS
void
set
(
Mat
&
dst
,
const
Scalar
&
gamma
,
const
Mat
&
mask
=
Mat
());
CV_EXPORTS
void
set
(
Mat
&
dst
,
const
Scalar
&
gamma
,
const
Mat
&
mask
=
Mat
());
CV_EXPORTS
void
minMaxFilter
(
const
Mat
&
a
,
Mat
&
maxresult
,
const
Mat
&
minresult
,
const
Mat
&
kernel
,
Point
anchor
);
CV_EXPORTS
void
erode
(
const
Mat
&
src
,
Mat
&
dst
,
const
Mat
&
_kernel
,
Point
anchor
=
Point
(
-
1
,
-
1
),
CV_EXPORTS
void
filter2D
(
const
Mat
&
src
,
Mat
&
dst
,
int
ddepth
,
const
Mat
&
kernel
,
Point
anchor
,
double
delta
,
int
borderType
);
int
borderType
=
IPL_BORDER_CONSTANT
,
const
Scalar
&
borderValue
=
Scalar
());
CV_EXPORTS
void
copyMakeBorder
(
const
Mat
&
src
,
Mat
&
dst
,
int
top
,
int
bottom
,
int
left
,
int
right
,
int
borderType
,
Scalar
borderValue
);
CV_EXPORTS
void
dilate
(
const
Mat
&
src
,
Mat
&
dst
,
const
Mat
&
_kernel
,
Point
anchor
=
Point
(
-
1
,
-
1
),
int
borderType
=
IPL_BORDER_CONSTANT
,
const
Scalar
&
borderValue
=
Scalar
());
CV_EXPORTS
void
filter2D
(
const
Mat
&
src
,
Mat
&
dst
,
int
ddepth
,
const
Mat
&
kernel
,
Point
anchor
,
double
delta
,
int
borderType
,
const
Scalar
&
borderValue
=
Scalar
());
CV_EXPORTS
void
copyMakeBorder
(
const
Mat
&
src
,
Mat
&
dst
,
int
top
,
int
bottom
,
int
left
,
int
right
,
int
borderType
,
const
Scalar
&
borderValue
=
Scalar
());
CV_EXPORTS
void
minMaxLoc
(
const
Mat
&
src
,
double
*
maxval
,
double
*
minval
,
CV_EXPORTS
void
minMaxLoc
(
const
Mat
&
src
,
double
*
maxval
,
double
*
minval
,
vector
<
int
>*
maxloc
,
vector
<
int
>*
minloc
,
const
Mat
&
mask
=
Mat
());
vector
<
int
>*
maxloc
,
vector
<
int
>*
minloc
,
const
Mat
&
mask
=
Mat
());
CV_EXPORTS
double
norm
(
const
Mat
&
src
,
int
normType
,
const
Mat
&
mask
=
Mat
());
CV_EXPORTS
double
norm
(
const
Mat
&
src
,
int
normType
,
const
Mat
&
mask
=
Mat
());
CV_EXPORTS
double
norm
(
const
Mat
&
src1
,
const
Mat
&
src2
,
int
normType
,
const
Mat
&
mask
=
Mat
());
CV_EXPORTS
double
norm
(
const
Mat
&
src1
,
const
Mat
&
src2
,
int
normType
,
const
Mat
&
mask
=
Mat
());
CV_EXPORTS
bool
cmpEps
(
const
Mat
&
src1
,
const
Mat
&
src2
,
double
maxDiff
,
vector
<
int
>*
loc
);
CV_EXPORTS
bool
cmpEps
(
const
Mat
&
src1
,
const
Mat
&
src2
,
int
maxDiff
,
vector
<
int
>*
loc
);
CV_EXPORTS
void
logicOp
(
const
Mat
&
src1
,
const
Mat
&
src2
,
Mat
&
dst
,
char
c
);
CV_EXPORTS
void
logicOp
(
const
Mat
&
src1
,
const
Mat
&
src2
,
Mat
&
dst
,
char
c
);
CV_EXPORTS
void
logicOp
(
const
Mat
&
src
,
const
Scalar
&
s
,
Mat
&
dst
,
char
c
);
CV_EXPORTS
void
logicOp
(
const
Mat
&
src
,
const
Scalar
&
s
,
Mat
&
dst
,
char
c
);
CV_EXPORTS
void
compare
(
const
Mat
&
src1
,
const
Mat
&
src2
,
Mat
&
dst
,
int
cmpop
);
CV_EXPORTS
void
compare
(
const
Mat
&
src1
,
const
Mat
&
src2
,
Mat
&
dst
,
int
cmpop
);
CV_EXPORTS
void
compare
(
const
Mat
&
src
,
const
Scalar
&
s
,
Mat
&
dst
,
int
cmpop
);
CV_EXPORTS
void
compare
(
const
Mat
&
src
,
double
s
,
Mat
&
dst
,
int
cmpop
);
CV_EXPORTS
void
gemm
(
const
Mat
&
src1
,
const
Mat
&
src2
,
double
alpha
,
CV_EXPORTS
void
gemm
(
const
Mat
&
src1
,
const
Mat
&
src2
,
double
alpha
,
const
Mat
&
src3
,
double
beta
,
Mat
&
dst
,
int
flags
);
const
Mat
&
src3
,
double
beta
,
Mat
&
dst
,
int
flags
);
CV_EXPORTS
void
crosscorr
(
const
Mat
&
src1
,
const
Mat
&
src2
,
Mat
&
dst
,
int
dtype
);
CV_EXPORTS
void
crosscorr
(
const
Mat
&
src1
,
const
Mat
&
src2
,
Mat
&
dst
,
int
dtype
);
...
...
modules/gtest/src/gtestcv.cpp
View file @
d2c2c07a
#include "precomp.hpp"
#include "precomp.hpp"
#include <float.h>
#include <limits.h>
using
namespace
cv
;
using
namespace
cv
;
...
@@ -49,14 +51,65 @@ int randomType(RNG& rng, int typeMask, int minChannels, int maxChannels)
...
@@ -49,14 +51,65 @@ int randomType(RNG& rng, int typeMask, int minChannels, int maxChannels)
return
CV_MAKETYPE
(
depth
,
channels
);
return
CV_MAKETYPE
(
depth
,
channels
);
}
}
Mat
randomMat
(
RNG
&
rng
,
Size
size
,
int
type
,
bool
useRoi
)
double
getMinVal
(
int
depth
)
{
{
return
Mat
();
double
val
=
depth
==
CV_8U
?
0
:
depth
==
CV_8S
?
SCHAR_MIN
:
depth
==
CV_16U
?
0
:
depth
==
CV_16S
?
SHRT_MIN
:
depth
==
CV_32S
?
INT_MIN
:
depth
==
CV_32F
?
-
FLT_MAX
:
depth
==
CV_64F
?
-
DBL_MAX
:
-
1
;
CV_Assert
(
val
!=
-
1
);
return
val
;
}
}
Mat
randomMat
(
RNG
&
rng
,
const
vector
<
int
>&
size
,
int
type
,
bool
useRoi
)
double
getMaxVal
(
int
depth
)
{
{
return
Mat
();
double
val
=
depth
==
CV_8U
?
UCHAR_MAX
:
depth
==
CV_8S
?
SCHAR_MAX
:
depth
==
CV_16U
?
USHRT_MAX
:
depth
==
CV_16S
?
SHRT_MAX
:
depth
==
CV_32S
?
INT_MAX
:
depth
==
CV_32F
?
FLT_MAX
:
depth
==
CV_64F
?
DBL_MAX
:
-
1
;
CV_Assert
(
val
!=
-
1
);
return
val
;
}
Mat
randomMat
(
RNG
&
rng
,
Size
size
,
int
type
,
double
minVal
,
double
maxVal
,
bool
useRoi
)
{
Size
size0
=
size
;
if
(
useRoi
)
{
size0
.
width
+=
std
::
max
(
rng
.
uniform
(
0
,
10
)
-
5
,
0
);
size0
.
height
+=
std
::
max
(
rng
.
uniform
(
0
,
10
)
-
5
,
0
);
}
Mat
m
(
size0
,
type
);
rng
.
fill
(
m
,
RNG
::
UNIFORM
,
Scalar
::
all
(
minVal
),
Scalar
::
all
(
maxVal
));
if
(
size0
==
size
)
return
m
;
return
m
(
Rect
((
size0
.
width
-
size
.
width
)
/
2
,
(
size0
.
height
-
size
.
height
)
/
2
,
size
.
width
,
size
.
height
));
}
Mat
randomMat
(
RNG
&
rng
,
const
vector
<
int
>&
size
,
int
type
,
double
minVal
,
double
maxVal
,
bool
useRoi
)
{
int
i
,
dims
=
(
int
)
size
.
size
();
vector
<
int
>
size0
(
dims
);
vector
<
Range
>
r
(
dims
);
bool
eqsize
=
true
;
for
(
i
=
0
;
i
<
dims
;
i
++
)
{
size0
[
i
]
=
size
[
i
];
r
[
i
]
=
Range
::
all
();
if
(
useRoi
)
{
size0
[
i
]
+=
std
::
max
(
rng
.
uniform
(
0
,
5
)
-
2
,
0
);
r
[
i
]
=
Range
((
size0
[
i
]
-
size
[
i
])
/
2
,
(
size0
[
i
]
-
size
[
i
])
/
2
+
size
[
i
]);
}
eqsize
=
eqsize
&&
size
[
i
]
==
size0
[
i
];
}
Mat
m
(
dims
,
&
size0
[
0
],
type
);
rng
.
fill
(
m
,
RNG
::
UNIFORM
,
Scalar
::
all
(
minVal
),
Scalar
::
all
(
maxVal
));
if
(
eqsize
)
return
m
;
return
m
(
&
r
[
0
]);
}
}
void
add
(
const
Mat
&
_a
,
double
alpha
,
const
Mat
&
_b
,
double
beta
,
void
add
(
const
Mat
&
_a
,
double
alpha
,
const
Mat
&
_b
,
double
beta
,
...
@@ -244,7 +297,7 @@ void convert(const Mat& src, Mat& dst, int dtype, double alpha, double beta)
...
@@ -244,7 +297,7 @@ void convert(const Mat& src, Mat& dst, int dtype, double alpha, double beta)
}
}
void
copy
(
const
Mat
&
src
,
Mat
&
dst
,
const
Mat
&
mask
)
void
copy
(
const
Mat
&
src
,
Mat
&
dst
,
const
Mat
&
mask
,
bool
invertMask
)
{
{
dst
.
create
(
src
.
dims
,
&
src
.
size
[
0
],
src
.
type
());
dst
.
create
(
src
.
dims
,
&
src
.
size
[
0
],
src
.
type
());
...
@@ -279,7 +332,7 @@ void copy(const Mat& src, Mat& dst, const Mat& mask)
...
@@ -279,7 +332,7 @@ void copy(const Mat& src, Mat& dst, const Mat& mask)
for
(
j
=
0
;
j
<
total
;
j
++
,
sptr
+=
elemSize
,
dptr
+=
elemSize
)
for
(
j
=
0
;
j
<
total
;
j
++
,
sptr
+=
elemSize
,
dptr
+=
elemSize
)
{
{
if
(
mptr
[
j
]
)
if
(
(
mptr
[
j
]
!=
0
)
^
invertMask
)
for
(
k
=
0
;
k
<
elemSize
;
k
++
)
for
(
k
=
0
;
k
<
elemSize
;
k
++
)
dptr
[
k
]
=
sptr
[
k
];
dptr
[
k
]
=
sptr
[
k
];
}
}
...
@@ -347,17 +400,1044 @@ void set(Mat& dst, const Scalar& gamma, const Mat& mask)
...
@@ -347,17 +400,1044 @@ void set(Mat& dst, const Scalar& gamma, const Mat& mask)
}
}
/*void minMaxFilter(const Mat& a, Mat& maxresult, const Mat& minresult, const Mat& kernel, Point anchor);
template
<
typename
_Tp
>
static
void
void filter2D(const Mat& src, Mat& dst, int ddepth, const Mat& kernel, Point anchor, double delta, int borderType);
erode_
(
const
Mat
&
src
,
Mat
&
dst
,
const
vector
<
int
>&
ofsvec
)
void copyMakeBorder(const Mat& src, Mat& dst, int top, int bottom, int left, int right, int borderType, Scalar borderValue);
{
void minMaxLoc(const Mat& src, double* maxval, double* minval,
int
width
=
src
.
cols
*
src
.
channels
(),
n
=
(
int
)
ofsvec
.
size
();
vector<int>* maxloc, vector<int>* minloc, const Mat& mask=Mat());
const
int
*
ofs
=
&
ofsvec
[
0
];
double norm(const Mat& src, int normType, const Mat& mask=Mat());
double norm(const Mat& src1, const Mat& src2, int normType, const Mat& mask=Mat());
for
(
int
y
=
0
;
y
<
dst
.
rows
;
y
++
)
bool cmpEps(const Mat& src1, const Mat& src2, int int_maxdiff, int flt_maxulp, vector<int>* loc);
{
void logicOp(const Mat& src1, const Mat& src2, Mat& dst, char c);
const
_Tp
*
sptr
=
src
.
ptr
<
_Tp
>
(
y
);
void logicOp(const Mat& src, const Scalar& s, Mat& dst, char c);
_Tp
*
dptr
=
dst
.
ptr
<
_Tp
>
(
y
);
void compare(const Mat& src1, const Mat& src2, Mat& dst, int cmpop);
void compare(const Mat& src, const Scalar& s, Mat& dst, int cmpop);*/
for
(
int
x
=
0
;
x
<
width
;
x
++
)
{
_Tp
result
=
sptr
[
x
+
ofs
[
0
]];
for
(
int
i
=
1
;
i
<
n
;
i
++
)
result
=
std
::
min
(
result
,
sptr
[
x
+
ofs
[
i
]]);
dptr
[
x
]
=
result
;
}
}
}
template
<
typename
_Tp
>
static
void
dilate_
(
const
Mat
&
src
,
Mat
&
dst
,
const
vector
<
int
>&
ofsvec
)
{
int
width
=
src
.
cols
*
src
.
channels
(),
n
=
(
int
)
ofsvec
.
size
();
const
int
*
ofs
=
&
ofsvec
[
0
];
for
(
int
y
=
0
;
y
<
dst
.
rows
;
y
++
)
{
const
_Tp
*
sptr
=
src
.
ptr
<
_Tp
>
(
y
);
_Tp
*
dptr
=
dst
.
ptr
<
_Tp
>
(
y
);
for
(
int
x
=
0
;
x
<
width
;
x
++
)
{
_Tp
result
=
sptr
[
x
+
ofs
[
0
]];
for
(
int
i
=
1
;
i
<
n
;
i
++
)
result
=
std
::
max
(
result
,
sptr
[
x
+
ofs
[
i
]]);
dptr
[
x
]
=
result
;
}
}
}
void
erode
(
const
Mat
&
_src
,
Mat
&
dst
,
const
Mat
&
_kernel
,
Point
anchor
,
int
borderType
,
const
Scalar
&
_borderValue
)
{
Mat
kernel
=
_kernel
,
src
;
Scalar
borderValue
=
_borderValue
;
if
(
kernel
.
empty
()
)
kernel
=
Mat
::
ones
(
3
,
3
,
CV_8U
);
else
{
CV_Assert
(
kernel
.
type
()
==
CV_8U
);
}
if
(
anchor
==
Point
(
-
1
,
-
1
)
)
anchor
=
Point
(
kernel
.
cols
/
2
,
kernel
.
rows
/
2
);
if
(
borderType
==
IPL_BORDER_CONSTANT
)
borderValue
=
getMaxVal
(
src
.
depth
());
copyMakeBorder
(
_src
,
src
,
anchor
.
y
,
kernel
.
rows
-
anchor
.
y
-
1
,
anchor
.
x
,
kernel
.
cols
-
anchor
.
y
-
1
,
borderType
,
borderValue
);
dst
.
create
(
_src
.
size
(),
src
.
type
()
);
vector
<
int
>
ofs
;
int
step
=
(
int
)(
src
.
step
/
src
.
elemSize1
()),
cn
=
src
.
channels
();
for
(
int
i
=
0
;
i
<
kernel
.
rows
;
i
++
)
for
(
int
j
=
0
;
j
<
kernel
.
cols
;
j
++
)
if
(
kernel
.
at
<
uchar
>
(
i
,
j
)
!=
0
)
ofs
.
push_back
(
i
*
step
+
j
*
cn
);
if
(
ofs
.
empty
()
)
ofs
.
push_back
(
anchor
.
y
*
step
+
anchor
.
x
*
cn
);
switch
(
src
.
depth
()
)
{
case
CV_8U
:
erode_
<
uchar
>
(
src
,
dst
,
ofs
);
break
;
case
CV_8S
:
erode_
<
schar
>
(
src
,
dst
,
ofs
);
break
;
case
CV_16U
:
erode_
<
ushort
>
(
src
,
dst
,
ofs
);
break
;
case
CV_16S
:
erode_
<
short
>
(
src
,
dst
,
ofs
);
break
;
case
CV_32S
:
erode_
<
int
>
(
src
,
dst
,
ofs
);
break
;
case
CV_32F
:
erode_
<
float
>
(
src
,
dst
,
ofs
);
break
;
case
CV_64F
:
erode_
<
double
>
(
src
,
dst
,
ofs
);
break
;
default
:
CV_Assert
(
0
);
}
}
void
dilate
(
const
Mat
&
_src
,
Mat
&
dst
,
const
Mat
&
_kernel
,
Point
anchor
,
int
borderType
,
const
Scalar
&
_borderValue
)
{
Mat
kernel
=
_kernel
,
src
;
Scalar
borderValue
=
_borderValue
;
if
(
kernel
.
empty
()
)
kernel
=
Mat
::
ones
(
3
,
3
,
CV_8U
);
else
{
CV_Assert
(
kernel
.
type
()
==
CV_8U
);
}
if
(
anchor
==
Point
(
-
1
,
-
1
)
)
anchor
=
Point
(
kernel
.
cols
/
2
,
kernel
.
rows
/
2
);
if
(
borderType
==
IPL_BORDER_CONSTANT
)
borderValue
=
getMinVal
(
src
.
depth
());
copyMakeBorder
(
_src
,
src
,
anchor
.
y
,
kernel
.
rows
-
anchor
.
y
-
1
,
anchor
.
x
,
kernel
.
cols
-
anchor
.
y
-
1
,
borderType
,
borderValue
);
dst
.
create
(
_src
.
size
(),
src
.
type
()
);
vector
<
int
>
ofs
;
int
step
=
(
int
)(
src
.
step
/
src
.
elemSize1
()),
cn
=
src
.
channels
();
for
(
int
i
=
0
;
i
<
kernel
.
rows
;
i
++
)
for
(
int
j
=
0
;
j
<
kernel
.
cols
;
j
++
)
if
(
kernel
.
at
<
uchar
>
(
i
,
j
)
!=
0
)
ofs
.
push_back
(
i
*
step
+
j
*
cn
);
if
(
ofs
.
empty
()
)
ofs
.
push_back
(
anchor
.
y
*
step
+
anchor
.
x
*
cn
);
switch
(
src
.
depth
()
)
{
case
CV_8U
:
dilate_
<
uchar
>
(
src
,
dst
,
ofs
);
break
;
case
CV_8S
:
dilate_
<
schar
>
(
src
,
dst
,
ofs
);
break
;
case
CV_16U
:
dilate_
<
ushort
>
(
src
,
dst
,
ofs
);
break
;
case
CV_16S
:
dilate_
<
short
>
(
src
,
dst
,
ofs
);
break
;
case
CV_32S
:
dilate_
<
int
>
(
src
,
dst
,
ofs
);
break
;
case
CV_32F
:
dilate_
<
float
>
(
src
,
dst
,
ofs
);
break
;
case
CV_64F
:
dilate_
<
double
>
(
src
,
dst
,
ofs
);
break
;
default
:
CV_Assert
(
0
);
}
}
template
<
typename
_Tp
>
static
void
filter2D_
(
const
Mat
&
src
,
Mat
&
dst
,
const
vector
<
int
>&
ofsvec
,
const
vector
<
double
>&
coeffvec
)
{
const
int
*
ofs
=
&
ofsvec
[
0
];
const
double
*
coeff
=
&
coeffvec
[
0
];
int
width
=
dst
.
cols
*
dst
.
channels
(),
ncoeffs
=
(
int
)
ofsvec
.
size
();
for
(
int
y
=
0
;
y
<
dst
.
rows
;
y
++
)
{
const
_Tp
*
sptr
=
src
.
ptr
<
_Tp
>
(
y
);
double
*
dptr
=
dst
.
ptr
<
double
>
(
y
);
for
(
int
x
=
0
;
x
<
width
;
x
++
)
{
double
s
=
0
;
for
(
int
i
=
0
;
i
<
ncoeffs
;
i
++
)
s
+=
sptr
[
ofs
[
i
]]
*
coeff
[
i
];
dptr
[
x
]
=
s
;
}
}
}
void
filter2D
(
const
Mat
&
_src
,
Mat
&
dst
,
int
ddepth
,
const
Mat
&
_kernel
,
Point
anchor
,
double
delta
,
int
borderType
,
const
Scalar
&
_borderValue
)
{
Mat
kernel
=
_kernel
,
src
,
_dst
;
Scalar
borderValue
=
_borderValue
;
CV_Assert
(
kernel
.
type
()
==
CV_32F
||
kernel
.
type
()
==
CV_64F
);
if
(
anchor
==
Point
(
-
1
,
-
1
)
)
anchor
=
Point
(
kernel
.
cols
/
2
,
kernel
.
rows
/
2
);
if
(
borderType
==
IPL_BORDER_CONSTANT
)
borderValue
=
getMinVal
(
src
.
depth
());
copyMakeBorder
(
_src
,
src
,
anchor
.
y
,
kernel
.
rows
-
anchor
.
y
-
1
,
anchor
.
x
,
kernel
.
cols
-
anchor
.
y
-
1
,
borderType
,
borderValue
);
_dst
.
create
(
_src
.
size
(),
CV_MAKETYPE
(
CV_64F
,
src
.
channels
())
);
vector
<
int
>
ofs
;
vector
<
double
>
coeff
(
kernel
.
rows
*
kernel
.
cols
);
Mat
cmat
(
kernel
.
rows
,
kernel
.
cols
,
CV_64F
,
&
coeff
[
0
]);
convert
(
kernel
,
cmat
,
cmat
.
type
());
int
step
=
(
int
)(
src
.
step
/
src
.
elemSize1
()),
cn
=
src
.
channels
();
for
(
int
i
=
0
;
i
<
kernel
.
rows
;
i
++
)
for
(
int
j
=
0
;
j
<
kernel
.
cols
;
j
++
)
ofs
.
push_back
(
i
*
step
+
j
*
cn
);
switch
(
src
.
depth
()
)
{
case
CV_8U
:
filter2D_
<
uchar
>
(
src
,
_dst
,
ofs
,
coeff
);
break
;
case
CV_8S
:
filter2D_
<
schar
>
(
src
,
_dst
,
ofs
,
coeff
);
break
;
case
CV_16U
:
filter2D_
<
ushort
>
(
src
,
_dst
,
ofs
,
coeff
);
break
;
case
CV_16S
:
filter2D_
<
short
>
(
src
,
_dst
,
ofs
,
coeff
);
break
;
case
CV_32S
:
filter2D_
<
int
>
(
src
,
_dst
,
ofs
,
coeff
);
break
;
case
CV_32F
:
filter2D_
<
float
>
(
src
,
_dst
,
ofs
,
coeff
);
break
;
case
CV_64F
:
filter2D_
<
double
>
(
src
,
_dst
,
ofs
,
coeff
);
break
;
default
:
CV_Assert
(
0
);
}
convert
(
_dst
,
dst
,
ddepth
,
1
,
delta
);
}
static
int
borderInterpolate
(
int
p
,
int
len
,
int
borderType
)
{
if
(
(
unsigned
)
p
<
(
unsigned
)
len
)
;
else
if
(
borderType
==
IPL_BORDER_REPLICATE
)
p
=
p
<
0
?
0
:
len
-
1
;
else
if
(
borderType
==
IPL_BORDER_REFLECT
||
borderType
==
IPL_BORDER_REFLECT_101
)
{
int
delta
=
borderType
==
IPL_BORDER_REFLECT_101
;
if
(
len
==
1
)
return
0
;
do
{
if
(
p
<
0
)
p
=
-
p
-
1
+
delta
;
else
p
=
len
-
1
-
(
p
-
len
)
-
delta
;
}
while
(
(
unsigned
)
p
>=
(
unsigned
)
len
);
}
else
if
(
borderType
==
IPL_BORDER_WRAP
)
{
if
(
p
<
0
)
p
-=
((
p
-
len
+
1
)
/
len
)
*
len
;
if
(
p
>=
len
)
p
%=
len
;
}
else
if
(
borderType
==
IPL_BORDER_CONSTANT
)
p
=
-
1
;
else
CV_Error
(
CV_StsBadArg
,
"Unknown/unsupported border type"
);
return
p
;
}
void
copyMakeBorder
(
const
Mat
&
src
,
Mat
&
dst
,
int
top
,
int
bottom
,
int
left
,
int
right
,
int
borderType
,
const
Scalar
&
borderValue
)
{
dst
.
create
(
src
.
rows
+
top
+
bottom
,
src
.
cols
+
left
+
right
,
src
.
type
());
int
i
,
j
,
k
,
esz
=
(
int
)
src
.
elemSize
();
int
width
=
src
.
cols
*
esz
,
width1
=
dst
.
cols
*
esz
;
if
(
borderType
==
IPL_BORDER_CONSTANT
)
{
vector
<
uchar
>
valvec
((
src
.
cols
+
left
+
right
)
*
esz
);
uchar
*
val
=
&
valvec
[
0
];
scalarToRawData
(
borderValue
,
val
,
src
.
type
(),
(
src
.
cols
+
left
+
right
)
*
src
.
channels
());
left
*=
esz
;
right
*=
esz
;
for
(
i
=
0
;
i
<
src
.
rows
;
i
++
)
{
const
uchar
*
sptr
=
src
.
ptr
(
i
);
uchar
*
dptr
=
dst
.
ptr
(
i
+
top
)
+
left
;
for
(
j
=
0
;
j
<
left
;
j
++
)
dptr
[
j
-
left
]
=
val
[
j
];
if
(
dptr
!=
sptr
)
for
(
j
=
0
;
j
<
width
;
j
++
)
dptr
[
j
]
=
sptr
[
j
];
for
(
j
=
0
;
j
<
right
;
j
++
)
dptr
[
j
+
width
]
=
val
[
j
];
}
for
(
i
=
0
;
i
<
top
;
i
++
)
{
uchar
*
dptr
=
dst
.
ptr
(
i
);
for
(
j
=
0
;
j
<
width1
;
j
++
)
dptr
[
j
]
=
val
[
j
];
}
for
(
i
=
0
;
i
<
bottom
;
i
++
)
{
uchar
*
dptr
=
dst
.
ptr
(
i
+
top
+
src
.
rows
);
for
(
j
=
0
;
j
<
width1
;
j
++
)
dptr
[
j
]
=
val
[
j
];
}
}
else
{
vector
<
int
>
tabvec
((
left
+
right
)
*
esz
);
int
*
ltab
=
&
tabvec
[
0
];
int
*
rtab
=
&
tabvec
[
left
*
esz
];
for
(
i
=
0
;
i
<
left
;
i
++
)
{
j
=
borderInterpolate
(
i
-
left
,
src
.
cols
,
borderType
)
*
esz
;
for
(
k
=
0
;
k
<
esz
;
k
++
)
ltab
[
i
*
esz
+
k
]
=
j
+
k
;
}
for
(
i
=
0
;
i
<
right
;
i
++
)
{
j
=
borderInterpolate
(
src
.
cols
+
i
,
src
.
cols
,
borderType
)
*
esz
;
for
(
k
=
0
;
k
<
esz
;
k
++
)
rtab
[
i
*
esz
+
k
]
=
j
+
k
;
}
left
*=
esz
;
right
*=
esz
;
for
(
i
=
0
;
i
<
src
.
rows
;
i
++
)
{
const
uchar
*
sptr
=
src
.
ptr
(
i
);
uchar
*
dptr
=
dst
.
ptr
(
i
+
top
);
for
(
j
=
0
;
j
<
left
;
j
++
)
dptr
[
j
]
=
sptr
[
ltab
[
j
]];
if
(
dptr
+
left
!=
sptr
)
{
for
(
j
=
0
;
j
<
width
;
j
++
)
dptr
[
j
+
left
]
=
sptr
[
j
];
}
for
(
j
=
0
;
j
<
right
;
j
++
)
dptr
[
j
+
left
+
width
]
=
sptr
[
rtab
[
j
]];
}
for
(
i
=
0
;
i
<
top
;
i
++
)
{
j
=
borderInterpolate
(
i
-
top
,
src
.
rows
,
borderType
);
const
uchar
*
sptr
=
dst
.
ptr
(
j
+
top
);
uchar
*
dptr
=
dst
.
ptr
(
i
);
for
(
k
=
0
;
k
<
width1
;
k
++
)
dptr
[
k
]
=
sptr
[
k
];
}
for
(
i
=
0
;
i
<
bottom
;
i
++
)
{
j
=
borderInterpolate
(
i
+
src
.
rows
,
src
.
rows
,
borderType
);
const
uchar
*
sptr
=
dst
.
ptr
(
j
+
top
);
uchar
*
dptr
=
dst
.
ptr
(
i
+
top
+
src
.
rows
);
for
(
k
=
0
;
k
<
width1
;
k
++
)
dptr
[
k
]
=
sptr
[
k
];
}
}
}
template
<
typename
_Tp
>
static
void
minMaxLoc_
(
const
_Tp
*
src
,
size_t
total
,
size_t
startidx
,
double
*
_maxval
,
double
*
_minval
,
size_t
*
_minpos
,
size_t
*
_maxpos
,
const
uchar
*
mask
)
{
_Tp
maxval
=
saturate_cast
<
_Tp
>
(
*
_maxval
),
minval
=
saturate_cast
<
_Tp
>
(
*
_minval
);
size_t
minpos
=
*
_minpos
,
maxpos
=
*
_maxpos
;
if
(
!
mask
)
{
for
(
size_t
i
=
0
;
i
<
total
;
i
++
)
{
_Tp
val
=
src
[
i
];
if
(
minval
>
val
)
{
minval
=
val
;
minpos
=
startidx
+
i
;
}
if
(
maxval
<
val
)
{
maxval
=
val
;
maxpos
=
startidx
+
i
;
}
}
}
else
{
for
(
size_t
i
=
0
;
i
<
total
;
i
++
)
{
_Tp
val
=
src
[
i
];
if
(
minval
>
val
&&
mask
[
i
]
)
{
minval
=
val
;
minpos
=
startidx
+
i
;
}
if
(
maxval
<
val
&&
mask
[
i
]
)
{
maxval
=
val
;
maxpos
=
startidx
+
i
;
}
}
}
*
_maxval
=
maxval
;
*
_minval
=
minval
;
*
_maxpos
=
maxpos
;
*
_minpos
=
minpos
;
}
static
void
setpos
(
const
Mat
&
mtx
,
vector
<
int
>&
pos
,
size_t
idx
)
{
pos
.
resize
(
mtx
.
dims
);
for
(
int
i
=
mtx
.
dims
-
1
;
i
>=
0
;
i
--
)
{
int
sz
=
mtx
.
size
[
i
]
*
(
i
==
mtx
.
dims
-
1
?
mtx
.
channels
()
:
1
);
pos
[
i
]
=
idx
%
sz
;
idx
/=
sz
;
}
}
void
minMaxLoc
(
const
Mat
&
src
,
double
*
_maxval
,
double
*
_minval
,
vector
<
int
>*
_maxloc
,
vector
<
int
>*
_minloc
,
const
Mat
&
mask
)
{
CV_Assert
(
src
.
channels
()
==
1
);
const
Mat
*
arrays
[
2
]
=
{
&
src
,
&
mask
};
Mat
planes
[
2
];
NAryMatIterator
it
(
arrays
,
planes
,
2
);
size_t
startidx
=
1
,
total
=
planes
[
0
].
total
();
int
i
,
nplanes
=
it
.
nplanes
,
depth
=
src
.
depth
();
double
maxval
=
depth
<
CV_32F
?
INT_MIN
:
depth
==
CV_32F
?
-
FLT_MAX
:
-
DBL_MAX
;
double
minval
=
depth
<
CV_32F
?
INT_MAX
:
depth
==
CV_32F
?
FLT_MAX
:
DBL_MAX
;
size_t
maxidx
=
0
,
minidx
=
0
;
for
(
i
=
0
;
i
<
nplanes
;
i
++
,
++
it
,
startidx
+=
total
)
{
const
uchar
*
sptr
=
planes
[
0
].
data
;
const
uchar
*
mptr
=
planes
[
1
].
data
;
switch
(
depth
)
{
case
CV_8U
:
minMaxLoc_
((
const
uchar
*
)
sptr
,
total
,
startidx
,
&
maxval
,
&
minval
,
&
maxidx
,
&
minidx
,
mptr
);
break
;
case
CV_8S
:
minMaxLoc_
((
const
schar
*
)
sptr
,
total
,
startidx
,
&
maxval
,
&
minval
,
&
maxidx
,
&
minidx
,
mptr
);
break
;
case
CV_16U
:
minMaxLoc_
((
const
ushort
*
)
sptr
,
total
,
startidx
,
&
maxval
,
&
minval
,
&
maxidx
,
&
minidx
,
mptr
);
break
;
case
CV_16S
:
minMaxLoc_
((
const
short
*
)
sptr
,
total
,
startidx
,
&
maxval
,
&
minval
,
&
maxidx
,
&
minidx
,
mptr
);
break
;
case
CV_32S
:
minMaxLoc_
((
const
int
*
)
sptr
,
total
,
startidx
,
&
maxval
,
&
minval
,
&
maxidx
,
&
minidx
,
mptr
);
break
;
case
CV_32F
:
minMaxLoc_
((
const
float
*
)
sptr
,
total
,
startidx
,
&
maxval
,
&
minval
,
&
maxidx
,
&
minidx
,
mptr
);
break
;
case
CV_64F
:
minMaxLoc_
((
const
double
*
)
sptr
,
total
,
startidx
,
&
maxval
,
&
minval
,
&
maxidx
,
&
minidx
,
mptr
);
break
;
default
:
CV_Assert
(
0
);
}
}
if
(
_maxval
)
*
_maxval
=
maxval
;
if
(
_minval
)
*
_minval
=
minval
;
if
(
_maxloc
)
setpos
(
src
,
*
_maxloc
,
maxidx
);
if
(
_minloc
)
setpos
(
src
,
*
_minloc
,
minidx
);
}
template
<
typename
_Tp
>
static
double
norm_
(
const
_Tp
*
src
,
size_t
total
,
int
normType
,
double
startval
,
const
uchar
*
mask
)
{
size_t
i
;
double
result
=
startval
;
if
(
normType
==
NORM_INF
)
{
if
(
!
mask
)
for
(
i
=
0
;
i
<
total
;
i
++
)
result
=
std
::
max
(
result
,
(
double
)
std
::
abs
(
src
[
i
]));
else
for
(
i
=
0
;
i
<
total
;
i
++
)
if
(
mask
[
i
]
)
result
=
std
::
max
(
result
,
(
double
)
std
::
abs
(
src
[
i
]));
}
else
if
(
normType
==
NORM_L1
)
{
if
(
!
mask
)
for
(
i
=
0
;
i
<
total
;
i
++
)
result
+=
std
::
abs
(
src
[
i
]);
else
for
(
i
=
0
;
i
<
total
;
i
++
)
if
(
mask
[
i
]
)
result
+=
std
::
abs
(
src
[
i
]);
}
else
{
if
(
!
mask
)
for
(
i
=
0
;
i
<
total
;
i
++
)
{
double
v
=
src
[
i
];
result
+=
v
*
v
;
}
else
for
(
i
=
0
;
i
<
total
;
i
++
)
if
(
mask
[
i
]
)
{
double
v
=
src
[
i
];
result
+=
v
*
v
;
}
}
return
result
;
}
template
<
typename
_Tp
>
static
double
norm_
(
const
_Tp
*
src1
,
const
_Tp
*
src2
,
size_t
total
,
int
normType
,
double
startval
,
const
uchar
*
mask
)
{
size_t
i
;
double
result
=
startval
;
if
(
normType
==
NORM_INF
)
{
if
(
!
mask
)
for
(
i
=
0
;
i
<
total
;
i
++
)
result
=
std
::
max
(
result
,
(
double
)
std
::
abs
(
src1
[
i
]
-
src2
[
i
]));
else
for
(
i
=
0
;
i
<
total
;
i
++
)
if
(
mask
[
i
]
)
result
=
std
::
max
(
result
,
(
double
)
std
::
abs
(
src1
[
i
]
-
src2
[
i
]));
}
else
if
(
normType
==
NORM_L1
)
{
if
(
!
mask
)
for
(
i
=
0
;
i
<
total
;
i
++
)
result
+=
std
::
abs
(
src1
[
i
]
-
src2
[
i
]);
else
for
(
i
=
0
;
i
<
total
;
i
++
)
if
(
mask
[
i
]
)
result
+=
std
::
abs
(
src1
[
i
]
-
src2
[
i
]);
}
else
{
if
(
!
mask
)
for
(
i
=
0
;
i
<
total
;
i
++
)
{
double
v
=
src1
[
i
]
-
src2
[
i
];
result
+=
v
*
v
;
}
else
for
(
i
=
0
;
i
<
total
;
i
++
)
if
(
mask
[
i
]
)
{
double
v
=
src1
[
i
]
-
src2
[
i
];
result
+=
v
*
v
;
}
}
return
result
;
}
double
norm
(
const
Mat
&
src
,
int
normType
,
const
Mat
&
mask
)
{
CV_Assert
(
mask
.
empty
()
||
(
src
.
size
==
mask
.
size
&&
mask
.
type
()
==
CV_8U
)
);
CV_Assert
(
normType
==
NORM_INF
||
normType
==
NORM_L1
||
normType
==
NORM_L2
);
const
Mat
*
arrays
[
2
]
=
{
&
src
,
&
mask
};
Mat
planes
[
2
];
NAryMatIterator
it
(
arrays
,
planes
,
2
);
size_t
total
=
planes
[
0
].
total
()
*
planes
[
0
].
channels
();
int
i
,
nplanes
=
it
.
nplanes
,
depth
=
src
.
depth
();
double
result
=
0
;
for
(
i
=
0
;
i
<
nplanes
;
i
++
,
++
it
)
{
const
uchar
*
sptr
=
planes
[
0
].
data
;
const
uchar
*
mptr
=
planes
[
1
].
data
;
switch
(
depth
)
{
case
CV_8U
:
result
=
norm_
((
const
uchar
*
)
sptr
,
total
,
normType
,
result
,
mptr
);
break
;
case
CV_8S
:
result
=
norm_
((
const
schar
*
)
sptr
,
total
,
normType
,
result
,
mptr
);
break
;
case
CV_16U
:
result
=
norm_
((
const
ushort
*
)
sptr
,
total
,
normType
,
result
,
mptr
);
break
;
case
CV_16S
:
result
=
norm_
((
const
short
*
)
sptr
,
total
,
normType
,
result
,
mptr
);
break
;
case
CV_32S
:
result
=
norm_
((
const
int
*
)
sptr
,
total
,
normType
,
result
,
mptr
);
break
;
case
CV_32F
:
result
=
norm_
((
const
float
*
)
sptr
,
total
,
normType
,
result
,
mptr
);
break
;
case
CV_64F
:
result
=
norm_
((
const
double
*
)
sptr
,
total
,
normType
,
result
,
mptr
);
break
;
default
:
CV_Error
(
CV_StsUnsupportedFormat
,
""
);
};
}
if
(
normType
==
NORM_L2
)
result
=
sqrt
(
result
);
return
result
;
}
double
norm
(
const
Mat
&
src1
,
const
Mat
&
src2
,
int
normType
,
const
Mat
&
mask
)
{
CV_Assert
(
src1
.
type
()
==
src2
.
type
()
&&
src1
.
size
==
src2
.
size
);
CV_Assert
(
mask
.
empty
()
||
(
src1
.
size
==
mask
.
size
&&
mask
.
type
()
==
CV_8U
)
);
CV_Assert
(
normType
==
NORM_INF
||
normType
==
NORM_L1
||
normType
==
NORM_L2
);
const
Mat
*
arrays
[
3
]
=
{
&
src1
,
&
src2
,
&
mask
};
Mat
planes
[
3
];
NAryMatIterator
it
(
arrays
,
planes
,
3
);
size_t
total
=
planes
[
0
].
total
()
*
planes
[
0
].
channels
();
int
i
,
nplanes
=
it
.
nplanes
,
depth
=
src1
.
depth
();
double
result
=
0
;
for
(
i
=
0
;
i
<
nplanes
;
i
++
,
++
it
)
{
const
uchar
*
sptr1
=
planes
[
0
].
data
;
const
uchar
*
sptr2
=
planes
[
1
].
data
;
const
uchar
*
mptr
=
planes
[
2
].
data
;
switch
(
depth
)
{
case
CV_8U
:
result
=
norm_
((
const
uchar
*
)
sptr1
,
(
const
uchar
*
)
sptr2
,
total
,
normType
,
result
,
mptr
);
break
;
case
CV_8S
:
result
=
norm_
((
const
schar
*
)
sptr1
,
(
const
schar
*
)
sptr2
,
total
,
normType
,
result
,
mptr
);
break
;
case
CV_16U
:
result
=
norm_
((
const
ushort
*
)
sptr1
,
(
const
ushort
*
)
sptr2
,
total
,
normType
,
result
,
mptr
);
break
;
case
CV_16S
:
result
=
norm_
((
const
short
*
)
sptr1
,
(
const
short
*
)
sptr2
,
total
,
normType
,
result
,
mptr
);
break
;
case
CV_32S
:
result
=
norm_
((
const
int
*
)
sptr1
,
(
const
int
*
)
sptr2
,
total
,
normType
,
result
,
mptr
);
break
;
case
CV_32F
:
result
=
norm_
((
const
float
*
)
sptr1
,
(
const
float
*
)
sptr2
,
total
,
normType
,
result
,
mptr
);
break
;
case
CV_64F
:
result
=
norm_
((
const
double
*
)
sptr1
,
(
const
double
*
)
sptr2
,
total
,
normType
,
result
,
mptr
);
break
;
default
:
CV_Error
(
CV_StsUnsupportedFormat
,
""
);
};
}
if
(
normType
==
NORM_L2
)
result
=
sqrt
(
result
);
return
result
;
}
bool
cmpEps
(
const
Mat
&
src1
,
const
Mat
&
src2
,
int
int_maxdiff
,
int
flt_maxulp
,
vector
<
int
>*
loc
);
static
void
logicOp_
(
const
uchar
*
src1
,
const
uchar
*
src2
,
uchar
*
dst
,
size_t
total
,
char
c
)
{
size_t
i
;
if
(
c
==
'&'
)
for
(
i
=
0
;
i
<
total
;
i
++
)
dst
[
i
]
=
src1
[
i
]
&
src2
[
i
];
else
if
(
c
==
'|'
)
for
(
i
=
0
;
i
<
total
;
i
++
)
dst
[
i
]
=
src1
[
i
]
|
src2
[
i
];
else
for
(
i
=
0
;
i
<
total
;
i
++
)
dst
[
i
]
=
src1
[
i
]
^
src2
[
i
];
}
static
void
logicOpS_
(
const
uchar
*
src
,
const
uchar
*
scalar
,
uchar
*
dst
,
size_t
total
,
char
c
)
{
const
size_t
blockSize
=
96
;
size_t
i
,
j
;
if
(
c
==
'&'
)
for
(
i
=
0
;
i
<
total
;
i
+=
blockSize
,
dst
+=
blockSize
,
src
+=
blockSize
)
{
size_t
sz
=
std
::
min
(
total
-
i
,
blockSize
);
for
(
j
=
0
;
j
<
sz
;
j
++
)
dst
[
j
]
=
src
[
j
]
&
scalar
[
j
];
}
else
if
(
c
==
'|'
)
for
(
i
=
0
;
i
<
total
;
i
+=
blockSize
,
dst
+=
blockSize
,
src
+=
blockSize
)
{
size_t
sz
=
std
::
min
(
total
-
i
,
blockSize
);
for
(
j
=
0
;
j
<
sz
;
j
++
)
dst
[
j
]
=
src
[
j
]
|
scalar
[
j
];
}
else
if
(
c
==
'^'
)
{
for
(
i
=
0
;
i
<
total
;
i
+=
blockSize
,
dst
+=
blockSize
,
src
+=
blockSize
)
{
size_t
sz
=
std
::
min
(
total
-
i
,
blockSize
);
for
(
j
=
0
;
j
<
sz
;
j
++
)
dst
[
j
]
=
src
[
j
]
^
scalar
[
j
];
}
}
else
for
(
i
=
0
;
i
<
total
;
i
++
)
dst
[
i
]
=
~
src
[
i
];
}
void
logicOp
(
const
Mat
&
src1
,
const
Mat
&
src2
,
Mat
&
dst
,
char
op
)
{
CV_Assert
(
op
==
'&'
||
op
==
'|'
||
op
==
'^'
);
CV_Assert
(
src1
.
type
()
==
src2
.
type
()
&&
src1
.
size
==
src2
.
size
);
dst
.
create
(
src1
.
dims
,
&
src1
.
size
[
0
],
src1
.
type
()
);
const
Mat
*
arrays
[
3
]
=
{
&
src1
,
&
src2
,
&
dst
};
Mat
planes
[
3
];
NAryMatIterator
it
(
arrays
,
planes
,
3
);
size_t
total
=
planes
[
0
].
total
()
*
planes
[
0
].
elemSize
();
int
i
,
nplanes
=
it
.
nplanes
;
for
(
i
=
0
;
i
<
nplanes
;
i
++
,
++
it
)
{
const
uchar
*
sptr1
=
planes
[
0
].
data
;
const
uchar
*
sptr2
=
planes
[
1
].
data
;
uchar
*
dptr
=
planes
[
2
].
data
;
logicOp_
(
sptr1
,
sptr2
,
dptr
,
total
,
op
);
}
}
void
logicOp
(
const
Mat
&
src
,
const
Scalar
&
s
,
Mat
&
dst
,
char
op
)
{
CV_Assert
(
op
==
'&'
||
op
==
'|'
||
op
==
'^'
);
dst
.
create
(
src
.
dims
,
&
src
.
size
[
0
],
src
.
type
()
);
const
Mat
*
arrays
[
2
]
=
{
&
src
,
&
dst
};
Mat
planes
[
2
];
NAryMatIterator
it
(
arrays
,
planes
,
2
);
size_t
total
=
planes
[
0
].
total
()
*
planes
[
0
].
elemSize
();
int
i
,
nplanes
=
it
.
nplanes
;
double
buf
[
12
];
scalarToRawData
(
s
,
buf
,
src
.
type
(),
12
);
for
(
i
=
0
;
i
<
nplanes
;
i
++
,
++
it
)
{
const
uchar
*
sptr
=
planes
[
0
].
data
;
uchar
*
dptr
=
planes
[
1
].
data
;
logicOpS_
(
sptr
,
(
uchar
*
)
&
buf
[
0
],
dptr
,
total
,
op
);
}
}
template
<
typename
_Tp
>
static
void
compare_
(
const
_Tp
*
src1
,
const
_Tp
*
src2
,
uchar
*
dst
,
size_t
total
,
int
cmpop
)
{
size_t
i
;
switch
(
cmpop
)
{
case
CMP_LT
:
for
(
i
=
0
;
i
<
total
;
i
++
)
dst
[
i
]
=
src1
[
i
]
<
src2
[
i
]
?
255
:
0
;
break
;
case
CMP_LE
:
for
(
i
=
0
;
i
<
total
;
i
++
)
dst
[
i
]
=
src1
[
i
]
<=
src2
[
i
]
?
255
:
0
;
break
;
case
CMP_EQ
:
for
(
i
=
0
;
i
<
total
;
i
++
)
dst
[
i
]
=
src1
[
i
]
==
src2
[
i
]
?
255
:
0
;
break
;
case
CMP_NE
:
for
(
i
=
0
;
i
<
total
;
i
++
)
dst
[
i
]
=
src1
[
i
]
!=
src2
[
i
]
?
255
:
0
;
break
;
case
CMP_GE
:
for
(
i
=
0
;
i
<
total
;
i
++
)
dst
[
i
]
=
src1
[
i
]
>=
src2
[
i
]
?
255
:
0
;
break
;
case
CMP_GT
:
for
(
i
=
0
;
i
<
total
;
i
++
)
dst
[
i
]
=
src1
[
i
]
>
src2
[
i
]
?
255
:
0
;
break
;
default
:
CV_Error
(
CV_StsBadArg
,
"Unknown comparison operation"
);
}
}
template
<
typename
_Tp
,
typename
_WTp
>
static
void
compareS_
(
const
_Tp
*
src1
,
_WTp
value
,
uchar
*
dst
,
size_t
total
,
int
cmpop
)
{
size_t
i
;
switch
(
cmpop
)
{
case
CMP_LT
:
for
(
i
=
0
;
i
<
total
;
i
++
)
dst
[
i
]
=
src1
[
i
]
<
value
?
255
:
0
;
break
;
case
CMP_LE
:
for
(
i
=
0
;
i
<
total
;
i
++
)
dst
[
i
]
=
src1
[
i
]
<=
value
?
255
:
0
;
break
;
case
CMP_EQ
:
for
(
i
=
0
;
i
<
total
;
i
++
)
dst
[
i
]
=
src1
[
i
]
==
value
?
255
:
0
;
break
;
case
CMP_NE
:
for
(
i
=
0
;
i
<
total
;
i
++
)
dst
[
i
]
=
src1
[
i
]
!=
value
?
255
:
0
;
break
;
case
CMP_GE
:
for
(
i
=
0
;
i
<
total
;
i
++
)
dst
[
i
]
=
src1
[
i
]
>=
value
?
255
:
0
;
break
;
case
CMP_GT
:
for
(
i
=
0
;
i
<
total
;
i
++
)
dst
[
i
]
=
src1
[
i
]
>
value
?
255
:
0
;
break
;
default
:
CV_Error
(
CV_StsBadArg
,
"Unknown comparison operation"
);
}
}
void
compare
(
const
Mat
&
src1
,
const
Mat
&
src2
,
Mat
&
dst
,
int
cmpop
)
{
CV_Assert
(
src1
.
type
()
==
src2
.
type
()
&&
src1
.
channels
()
==
1
&&
src1
.
size
==
src2
.
size
);
dst
.
create
(
src1
.
dims
,
&
src1
.
size
[
0
],
CV_8U
);
const
Mat
*
arrays
[
3
]
=
{
&
src1
,
&
src2
,
&
dst
};
Mat
planes
[
3
];
NAryMatIterator
it
(
arrays
,
planes
,
3
);
size_t
total
=
planes
[
0
].
total
()
*
planes
[
0
].
elemSize
();
int
i
,
nplanes
=
it
.
nplanes
,
depth
=
src1
.
depth
();
for
(
i
=
0
;
i
<
nplanes
;
i
++
,
++
it
)
{
const
uchar
*
sptr1
=
planes
[
0
].
data
;
const
uchar
*
sptr2
=
planes
[
1
].
data
;
uchar
*
dptr
=
planes
[
2
].
data
;
switch
(
depth
)
{
case
CV_8U
:
compare_
((
const
uchar
*
)
sptr1
,
(
const
uchar
*
)
sptr2
,
dptr
,
total
,
cmpop
);
break
;
case
CV_8S
:
compare_
((
const
schar
*
)
sptr1
,
(
const
schar
*
)
sptr2
,
dptr
,
total
,
cmpop
);
break
;
case
CV_16U
:
compare_
((
const
ushort
*
)
sptr1
,
(
const
ushort
*
)
sptr2
,
dptr
,
total
,
cmpop
);
break
;
case
CV_16S
:
compare_
((
const
short
*
)
sptr1
,
(
const
short
*
)
sptr2
,
dptr
,
total
,
cmpop
);
break
;
case
CV_32S
:
compare_
((
const
int
*
)
sptr1
,
(
const
int
*
)
sptr2
,
dptr
,
total
,
cmpop
);
break
;
case
CV_32F
:
compare_
((
const
float
*
)
sptr1
,
(
const
float
*
)
sptr2
,
dptr
,
total
,
cmpop
);
break
;
case
CV_64F
:
compare_
((
const
double
*
)
sptr1
,
(
const
double
*
)
sptr2
,
dptr
,
total
,
cmpop
);
break
;
default
:
CV_Error
(
CV_StsUnsupportedFormat
,
""
);
}
}
}
void
compare
(
const
Mat
&
src
,
double
value
,
Mat
&
dst
,
int
cmpop
)
{
CV_Assert
(
src
.
channels
()
==
1
);
dst
.
create
(
src
.
dims
,
&
src
.
size
[
0
],
CV_8U
);
const
Mat
*
arrays
[
2
]
=
{
&
src
,
&
dst
};
Mat
planes
[
2
];
NAryMatIterator
it
(
arrays
,
planes
,
2
);
size_t
total
=
planes
[
0
].
total
()
*
planes
[
0
].
elemSize
();
int
i
,
nplanes
=
it
.
nplanes
,
depth
=
src
.
depth
();
int
ivalue
=
saturate_cast
<
int
>
(
value
);
for
(
i
=
0
;
i
<
nplanes
;
i
++
,
++
it
)
{
const
uchar
*
sptr
=
planes
[
0
].
data
;
uchar
*
dptr
=
planes
[
1
].
data
;
switch
(
depth
)
{
case
CV_8U
:
compareS_
((
const
uchar
*
)
sptr
,
ivalue
,
dptr
,
total
,
cmpop
);
break
;
case
CV_8S
:
compareS_
((
const
schar
*
)
sptr
,
ivalue
,
dptr
,
total
,
cmpop
);
break
;
case
CV_16U
:
compareS_
((
const
ushort
*
)
sptr
,
ivalue
,
dptr
,
total
,
cmpop
);
break
;
case
CV_16S
:
compareS_
((
const
short
*
)
sptr
,
ivalue
,
dptr
,
total
,
cmpop
);
break
;
case
CV_32S
:
compareS_
((
const
int
*
)
sptr
,
ivalue
,
dptr
,
total
,
cmpop
);
break
;
case
CV_32F
:
compareS_
((
const
float
*
)
sptr
,
value
,
dptr
,
total
,
cmpop
);
break
;
case
CV_64F
:
compareS_
((
const
double
*
)
sptr
,
value
,
dptr
,
total
,
cmpop
);
break
;
default
:
CV_Error
(
CV_StsUnsupportedFormat
,
""
);
}
}
}
template
<
typename
_Tp
>
static
bool
cmpEpsInt_
(
const
_Tp
*
src1
,
const
_Tp
*
src2
,
int
imaxdiff
,
size_t
total
,
size_t
startidx
,
size_t
&
idx
)
{
size_t
i
;
for
(
i
=
0
;
i
<
total
;
i
++
)
if
(
std
::
abs
(
src1
[
i
]
-
src2
[
i
])
>
imaxdiff
)
{
idx
=
i
+
startidx
;
return
false
;
}
return
true
;
}
template
<
typename
_Tp
>
static
bool
cmpEpsFlt_
(
const
_Tp
*
src1
,
const
_Tp
*
src2
,
size_t
total
,
int
imaxdiff
,
size_t
startidx
,
size_t
&
idx
)
{
const
_Tp
C
=
((
_Tp
)
1
<<
(
sizeof
(
_Tp
)
*
8
-
1
))
-
1
;
size_t
i
;
for
(
i
=
0
;
i
<
total
;
i
++
)
{
_Tp
a
=
src1
[
i
],
b
=
src2
[
i
];
if
(
a
<
0
)
a
^=
C
;
if
(
b
<
0
)
b
^=
C
;
_Tp
d
=
std
::
abs
(
a
-
b
);
if
(
d
>
imaxdiff
)
{
idx
=
i
+
startidx
;
return
false
;
}
}
return
true
;
}
bool
cmpEps
(
const
Mat
&
src1
,
const
Mat
&
src2
,
int
imaxDiff
,
vector
<
int
>*
loc
)
{
CV_Assert
(
src1
.
type
()
==
src2
.
type
()
&&
src1
.
size
==
src2
.
size
);
const
Mat
*
arrays
[
2
]
=
{
&
src1
,
&
src2
};
Mat
planes
[
2
];
NAryMatIterator
it
(
arrays
,
planes
,
2
);
size_t
total
=
planes
[
0
].
total
()
*
planes
[
0
].
channels
();
int
i
,
nplanes
=
it
.
nplanes
,
depth
=
src1
.
depth
();
size_t
startidx
=
0
,
idx
=
-
1
;
bool
ok
=
true
;
for
(
i
=
0
;
i
<
nplanes
;
i
++
,
++
it
,
startidx
+=
total
)
{
const
uchar
*
sptr1
=
planes
[
0
].
data
;
const
uchar
*
sptr2
=
planes
[
1
].
data
;
switch
(
depth
)
{
case
CV_8U
:
ok
=
cmpEpsInt_
((
const
uchar
*
)
sptr1
,
(
const
uchar
*
)
sptr2
,
total
,
imaxDiff
,
startidx
,
idx
);
break
;
case
CV_8S
:
ok
=
cmpEpsInt_
((
const
schar
*
)
sptr1
,
(
const
schar
*
)
sptr2
,
total
,
imaxDiff
,
startidx
,
idx
);
break
;
case
CV_16U
:
ok
=
cmpEpsInt_
((
const
ushort
*
)
sptr1
,
(
const
ushort
*
)
sptr2
,
total
,
imaxDiff
,
startidx
,
idx
);
break
;
case
CV_16S
:
ok
=
cmpEpsInt_
((
const
short
*
)
sptr1
,
(
const
short
*
)
sptr2
,
total
,
imaxDiff
,
startidx
,
idx
);
break
;
case
CV_32S
:
ok
=
cmpEpsInt_
((
const
int
*
)
sptr1
,
(
const
int
*
)
sptr2
,
total
,
imaxDiff
,
startidx
,
idx
);
break
;
case
CV_32F
:
ok
=
cmpEpsFlt_
((
const
int
*
)
sptr1
,
(
const
int
*
)
sptr2
,
total
,
imaxDiff
,
startidx
,
idx
);
break
;
case
CV_64F
:
ok
=
cmpEpsFlt_
((
const
int64
*
)
sptr1
,
(
const
int64
*
)
sptr2
,
total
,
imaxDiff
,
startidx
,
idx
);
break
;
default
:
CV_Error
(
CV_StsUnsupportedFormat
,
""
);
}
if
(
!
ok
)
break
;
}
if
(
!
ok
&&
loc
)
setpos
(
src1
,
*
loc
,
idx
);
return
ok
;
}
}
}
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