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
bb4b4acc
Commit
bb4b4acc
authored
Dec 10, 2015
by
Vadim Pisarevsky
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #5776 from alalek:checkRange_fixes
parents
bfe5ed23
b26580cc
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
112 additions
and
50 deletions
+112
-50
core.hpp
modules/core/include/opencv2/core.hpp
+16
-1
mathfuncs.cpp
modules/core/src/mathfuncs.cpp
+25
-22
test_math.cpp
modules/core/test/test_math.cpp
+70
-26
defs.h
modules/hal/include/opencv2/hal/defs.h
+1
-1
No files found.
modules/core/include/opencv2/core.hpp
View file @
bb4b4acc
...
...
@@ -1509,7 +1509,7 @@ CV_EXPORTS_W void magnitude(InputArray x, InputArray y, OutputArray magnitude);
/** @brief Checks every element of an input array for invalid values.
The functions checkRange check that every array element is neither NaN nor infinite. When minVal \
<
The functions checkRange check that every array element is neither NaN nor infinite. When minVal \
>
-DBL_MAX and maxVal \< DBL_MAX, the functions also check that each value is between minVal and
maxVal. In case of multi-channel arrays, each channel is processed independently. If some values
are out of range, position of the first outlier is stored in pos (when pos != NULL). Then, the
...
...
@@ -2906,6 +2906,21 @@ public:
};
static
inline
String
&
operator
<<
(
String
&
out
,
Ptr
<
Formatted
>
fmtd
)
{
fmtd
->
reset
();
for
(
const
char
*
str
=
fmtd
->
next
();
str
;
str
=
fmtd
->
next
())
out
+=
cv
::
String
(
str
);
return
out
;
}
static
inline
String
&
operator
<<
(
String
&
out
,
const
Mat
&
mtx
)
{
return
out
<<
Formatter
::
get
()
->
format
(
mtx
);
}
//////////////////////////////////////// Algorithm ////////////////////////////////////
class
CV_EXPORTS
Algorithm
;
...
...
modules/core/src/mathfuncs.cpp
View file @
bb4b4acc
...
...
@@ -1571,9 +1571,8 @@ template<> struct mat_type_assotiations<CV_32S>
static
const
type
max_allowable
=
INT_MAX
;
};
// inclusive maxVal !!!
template
<
int
depth
>
bool
checkIntegerRange
(
cv
::
Mat
src
,
Point
&
bad_pt
,
int
minVal
,
int
maxVal
,
double
&
bad_value
)
static
bool
checkIntegerRange
(
cv
::
Mat
src
,
Point
&
bad_pt
,
int
minVal
,
int
maxVal
)
{
typedef
mat_type_assotiations
<
depth
>
type_ass
;
...
...
@@ -1591,20 +1590,19 @@ bool checkIntegerRange(cv::Mat src, Point& bad_pt, int minVal, int maxVal, doubl
for
(
int
j
=
0
;
j
<
as_one_channel
.
rows
;
++
j
)
for
(
int
i
=
0
;
i
<
as_one_channel
.
cols
;
++
i
)
{
if
(
as_one_channel
.
at
<
typename
type_ass
::
type
>
(
j
,
i
)
<
minVal
||
as_one_channel
.
at
<
typename
type_ass
::
type
>
(
j
,
i
)
>
maxVal
)
typename
type_ass
::
type
v
=
as_one_channel
.
at
<
typename
type_ass
::
type
>
(
j
,
i
);
if
(
v
<
minVal
||
v
>
maxVal
)
{
bad_pt
.
y
=
j
;
bad_pt
.
x
=
i
%
src
.
channels
();
bad_value
=
as_one_channel
.
at
<
typename
type_ass
::
type
>
(
j
,
i
);
bad_pt
.
y
=
j
;
bad_pt
.
x
=
i
/
src
.
channels
();
return
false
;
}
}
bad_value
=
0.0
;
return
true
;
}
typedef
bool
(
*
check_range_function
)(
cv
::
Mat
src
,
Point
&
bad_pt
,
int
minVal
,
int
maxVal
,
double
&
bad_value
);
typedef
bool
(
*
check_range_function
)(
cv
::
Mat
src
,
Point
&
bad_pt
,
int
minVal
,
int
maxVal
);
check_range_function
check_range_functions
[]
=
{
...
...
@@ -1621,15 +1619,16 @@ bool checkRange(InputArray _src, bool quiet, Point* pt, double minVal, double ma
if
(
src
.
dims
>
2
)
{
CV_Assert
(
pt
==
NULL
);
// no way to provide location info
const
Mat
*
arrays
[]
=
{
&
src
,
0
};
Mat
planes
[
1
];
NAryMatIterator
it
(
arrays
,
planes
);
for
(
size_t
i
=
0
;
i
<
it
.
nplanes
;
i
++
,
++
it
)
{
if
(
!
checkRange
(
it
.
planes
[
0
],
quiet
,
pt
,
minVal
,
maxVal
))
if
(
!
checkRange
(
it
.
planes
[
0
],
quiet
,
NULL
,
minVal
,
maxVal
))
{
// todo: set index properly
return
false
;
}
}
...
...
@@ -1638,20 +1637,19 @@ bool checkRange(InputArray _src, bool quiet, Point* pt, double minVal, double ma
int
depth
=
src
.
depth
();
Point
badPt
(
-
1
,
-
1
);
double
badValue
=
0
;
if
(
depth
<
CV_32F
)
{
// see "Bug #1784"
int
minVali
=
minVal
<
(
-
INT_MAX
-
1
)
?
(
-
INT_MAX
-
1
)
:
cvFloor
(
minVal
);
int
maxVali
=
maxVal
>
INT_MAX
?
INT_MAX
:
cvCeil
(
maxVal
)
-
1
;
// checkIntegerRang() use inclusive maxVal
int
minVali
=
minVal
<=
INT_MIN
?
INT_MIN
:
cvFloor
(
minVal
);
int
maxVali
=
maxVal
>
INT_MAX
?
INT_MAX
:
cvCeil
(
maxVal
)
-
1
;
(
check_range_functions
[
depth
])(
src
,
badPt
,
minVali
,
maxVali
,
badValue
);
(
check_range_functions
[
depth
])(
src
,
badPt
,
minVali
,
maxVali
);
}
else
{
int
i
,
loc
=
0
;
Size
size
=
getContinuousSize
(
src
,
src
.
channels
()
);
int
cn
=
src
.
channels
();
Size
size
=
getContinuousSize
(
src
,
cn
);
if
(
depth
==
CV_32F
)
{
...
...
@@ -1675,8 +1673,8 @@ bool checkRange(InputArray _src, bool quiet, Point* pt, double minVal, double ma
if
(
val
<
ia
||
val
>=
ib
)
{
badPt
=
Point
((
loc
+
i
)
%
src
.
cols
,
(
loc
+
i
)
/
src
.
cols
)
;
bad
Value
=
((
const
float
*
)
isrc
)[
i
]
;
int
pixelId
=
(
loc
+
i
)
/
cn
;
bad
Pt
=
Point
(
pixelId
%
src
.
cols
,
pixelId
/
src
.
cols
)
;
break
;
}
}
...
...
@@ -1704,8 +1702,8 @@ bool checkRange(InputArray _src, bool quiet, Point* pt, double minVal, double ma
if
(
val
<
ia
||
val
>=
ib
)
{
badPt
=
Point
((
loc
+
i
)
%
src
.
cols
,
(
loc
+
i
)
/
src
.
cols
)
;
bad
Value
=
((
const
double
*
)
isrc
)[
i
]
;
int
pixelId
=
(
loc
+
i
)
/
cn
;
bad
Pt
=
Point
(
pixelId
%
src
.
cols
,
pixelId
/
src
.
cols
)
;
break
;
}
}
...
...
@@ -1718,10 +1716,15 @@ bool checkRange(InputArray _src, bool quiet, Point* pt, double minVal, double ma
if
(
pt
)
*
pt
=
badPt
;
if
(
!
quiet
)
{
cv
::
String
value_str
;
value_str
<<
src
(
cv
::
Range
(
badPt
.
y
,
badPt
.
y
+
1
),
cv
::
Range
(
badPt
.
x
,
badPt
.
x
+
1
));
CV_Error_
(
CV_StsOutOfRange
,
(
"the value at (%d, %d)=%g is out of range"
,
badPt
.
x
,
badPt
.
y
,
badValue
));
(
"the value at (%d, %d)=%s is out of range [%f, %f)"
,
badPt
.
x
,
badPt
.
y
,
value_str
.
c_str
(),
minVal
,
maxVal
));
}
return
false
;
}
return
badPt
.
x
<
0
;
return
true
;
}
#ifdef HAVE_OPENCL
...
...
modules/core/test/test_math.cpp
View file @
bb4b4acc
...
...
@@ -2502,40 +2502,25 @@ protected:
}
};
class
Core_CheckRange_Empty
:
public
cvtest
::
BaseTest
{
public
:
Core_CheckRange_Empty
(){}
~
Core_CheckRange_Empty
(){}
protected
:
virtual
void
run
(
int
start_from
);
};
void
Core_CheckRange_Empty
::
run
(
int
)
TEST
(
Core_CheckRange_Empty
,
accuracy
)
{
cv
::
Mat
m
;
ASSERT_TRUE
(
cv
::
checkRange
(
m
)
);
}
TEST
(
Core_CheckRange_Empty
,
accuracy
)
{
Core_CheckRange_Empty
test
;
test
.
safe_run
();
}
class
Core_CheckRange_INT_MAX
:
public
cvtest
::
BaseTest
{
public
:
Core_CheckRange_INT_MAX
(){}
~
Core_CheckRange_INT_MAX
(){}
protected
:
virtual
void
run
(
int
start_from
);
};
void
Core_CheckRange_INT_MAX
::
run
(
int
)
TEST
(
Core_CheckRange_INT_MAX
,
accuracy
)
{
cv
::
Mat
m
(
3
,
3
,
CV_32SC1
,
cv
::
Scalar
(
INT_MAX
));
ASSERT_FALSE
(
cv
::
checkRange
(
m
,
true
,
0
,
0
,
INT_MAX
)
);
ASSERT_TRUE
(
cv
::
checkRange
(
m
)
);
}
TEST
(
Core_CheckRange_INT_MAX
,
accuracy
)
{
Core_CheckRange_INT_MAX
test
;
test
.
safe_run
();
}
TEST
(
Core_CheckRange_INT_MAX1
,
accuracy
)
{
cv
::
Mat
m
(
3
,
3
,
CV_32SC1
,
cv
::
Scalar
(
INT_MAX
));
ASSERT_TRUE
(
cv
::
checkRange
(
m
,
true
,
0
,
0
,
INT_MAX
+
1.0
f
)
);
ASSERT_TRUE
(
cv
::
checkRange
(
m
)
);
}
template
<
typename
T
>
class
Core_CheckRange
:
public
testing
::
Test
{};
...
...
@@ -2546,13 +2531,30 @@ TYPED_TEST_P(Core_CheckRange, Negative)
double
min_bound
=
4.5
;
double
max_bound
=
16.0
;
TypeParam
data
[]
=
{
5
,
10
,
15
,
4
,
10
,
2
,
8
,
12
,
14
};
TypeParam
data
[]
=
{
5
,
10
,
15
,
10
,
10
,
2
,
8
,
12
,
14
};
cv
::
Mat
src
=
cv
::
Mat
(
3
,
3
,
cv
::
DataDepth
<
TypeParam
>::
value
,
data
);
cv
::
Point
bad_pt
(
0
,
0
);
ASSERT_FALSE
(
checkRange
(
src
,
true
,
&
bad_pt
,
min_bound
,
max_bound
));
ASSERT_EQ
(
bad_pt
.
x
,
0
);
ASSERT_EQ
(
bad_pt
.
x
,
2
);
ASSERT_EQ
(
bad_pt
.
y
,
1
);
}
TYPED_TEST_P
(
Core_CheckRange
,
Negative3CN
)
{
double
min_bound
=
4.5
;
double
max_bound
=
16.0
;
TypeParam
data
[]
=
{
5
,
6
,
7
,
10
,
11
,
12
,
13
,
14
,
15
,
10
,
11
,
12
,
10
,
11
,
12
,
2
,
5
,
6
,
8
,
8
,
8
,
12
,
12
,
12
,
14
,
14
,
14
};
cv
::
Mat
src
=
cv
::
Mat
(
3
,
3
,
CV_MAKETYPE
(
cv
::
DataDepth
<
TypeParam
>::
value
,
3
),
data
);
cv
::
Point
bad_pt
(
0
,
0
);
ASSERT_FALSE
(
checkRange
(
src
,
true
,
&
bad_pt
,
min_bound
,
max_bound
));
ASSERT_EQ
(
bad_pt
.
x
,
2
);
ASSERT_EQ
(
bad_pt
.
y
,
1
);
}
...
...
@@ -2614,7 +2616,49 @@ TYPED_TEST_P(Core_CheckRange, One)
ASSERT_TRUE
(
checkRange
(
src2
,
true
,
NULL
,
min_bound
,
max_bound
)
);
}
REGISTER_TYPED_TEST_CASE_P
(
Core_CheckRange
,
Negative
,
Positive
,
Bounds
,
Zero
,
One
);
TEST
(
Core_CheckRange
,
NaN
)
{
float
data
[]
=
{
5
,
6
,
7
,
10
,
11
,
12
,
13
,
14
,
15
,
10
,
11
,
12
,
10
,
11
,
12
,
5
,
5
,
std
::
numeric_limits
<
float
>::
quiet_NaN
(),
8
,
8
,
8
,
12
,
12
,
12
,
14
,
14
,
14
};
cv
::
Mat
src
=
cv
::
Mat
(
3
,
3
,
CV_32FC3
,
data
);
cv
::
Point
bad_pt
(
0
,
0
);
ASSERT_FALSE
(
checkRange
(
src
,
true
,
&
bad_pt
));
ASSERT_EQ
(
bad_pt
.
x
,
2
);
ASSERT_EQ
(
bad_pt
.
y
,
1
);
}
TEST
(
Core_CheckRange
,
Inf
)
{
float
data
[]
=
{
5
,
6
,
7
,
10
,
11
,
12
,
13
,
14
,
15
,
10
,
11
,
12
,
10
,
11
,
12
,
5
,
5
,
std
::
numeric_limits
<
float
>::
infinity
(),
8
,
8
,
8
,
12
,
12
,
12
,
14
,
14
,
14
};
cv
::
Mat
src
=
cv
::
Mat
(
3
,
3
,
CV_32FC3
,
data
);
cv
::
Point
bad_pt
(
0
,
0
);
ASSERT_FALSE
(
checkRange
(
src
,
true
,
&
bad_pt
));
ASSERT_EQ
(
bad_pt
.
x
,
2
);
ASSERT_EQ
(
bad_pt
.
y
,
1
);
}
TEST
(
Core_CheckRange
,
Inf_Minus
)
{
float
data
[]
=
{
5
,
6
,
7
,
10
,
11
,
12
,
13
,
14
,
15
,
10
,
11
,
12
,
10
,
11
,
12
,
5
,
5
,
-
std
::
numeric_limits
<
float
>::
infinity
(),
8
,
8
,
8
,
12
,
12
,
12
,
14
,
14
,
14
};
cv
::
Mat
src
=
cv
::
Mat
(
3
,
3
,
CV_32FC3
,
data
);
cv
::
Point
bad_pt
(
0
,
0
);
ASSERT_FALSE
(
checkRange
(
src
,
true
,
&
bad_pt
));
ASSERT_EQ
(
bad_pt
.
x
,
2
);
ASSERT_EQ
(
bad_pt
.
y
,
1
);
}
REGISTER_TYPED_TEST_CASE_P
(
Core_CheckRange
,
Negative
,
Negative3CN
,
Positive
,
Bounds
,
Zero
,
One
);
typedef
::
testing
::
Types
<
signed
char
,
unsigned
char
,
signed
short
,
unsigned
short
,
signed
int
>
mat_data_types
;
INSTANTIATE_TYPED_TEST_CASE_P
(
Negative_Test
,
Core_CheckRange
,
mat_data_types
);
...
...
modules/hal/include/opencv2/hal/defs.h
View file @
bb4b4acc
...
...
@@ -415,7 +415,7 @@ CV_INLINE int cvFloor( double value )
#endif
}
/** @brief Rounds floating-point number to the nearest integer not
larg
er than the original.
/** @brief Rounds floating-point number to the nearest integer not
small
er than the original.
The function computes an integer i such that:
\f[i \le \texttt{value} < i+1\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