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
c704942b
Commit
c704942b
authored
Oct 17, 2017
by
Vladislav Sovrasov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dnn: add a documentation for NMS, fix missing experimantal namespace
parent
acedb4a5
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
32 additions
and
43 deletions
+32
-43
dnn.hpp
modules/dnn/include/opencv2/dnn/dnn.hpp
+11
-9
nms.inl.hpp
modules/dnn/include/opencv2/dnn/nms.inl.hpp
+5
-19
detection_output_layer.cpp
modules/dnn/src/layers/detection_output_layer.cpp
+5
-13
nms.cpp
modules/dnn/src/nms.cpp
+11
-2
No files found.
modules/dnn/include/opencv2/dnn/dnn.hpp
View file @
c704942b
...
...
@@ -734,18 +734,20 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN
*/
CV_EXPORTS_W
void
shrinkCaffeModel
(
const
String
&
src
,
const
String
&
dst
);
/** @brief
* @param bboxes
* @param scores
* @param score_threshold
* @param nms_threshold
* @param eta
* @param top_k
* @param indices
/** @brief Performs non maximum suppression given boxes and corresponding scores.
* @param bboxes a set of bounding boxes to apply NMS.
* @param scores a set of corresponding confidences.
* @param score_threshold a threshold used to filter boxes by score.
* @param nms_threshold a threshold used in non maximum suppression.
* @param indices the kept indices of bboxes after NMS.
* @param eta a coefficient in adaptive threshold formula: \f$nms\_threshold_{i+1}=eta\cdot nms\_threshold_i\f$.
* @param top_k if `>0`, keep at most @p top_k picked indices.
*/
CV_EXPORTS_W
void
NMSBoxes
(
const
std
::
vector
<
Rect
>&
bboxes
,
const
std
::
vector
<
float
>&
scores
,
const
float
score_threshold
,
const
float
nms_threshold
,
const
float
eta
,
const
int
top_k
,
CV_OUT
std
::
vector
<
int
>&
indices
);
CV_OUT
std
::
vector
<
int
>&
indices
,
const
float
eta
=
1.
f
,
const
int
top_k
=
0
);
//! @}
...
...
modules/dnn/include/opencv2/dnn/nms.inl.hpp
View file @
c704942b
...
...
@@ -48,25 +48,12 @@ inline void GetMaxScoreIndex(const std::vector<float>& scores, const float thres
SortScorePairDescend
<
int
>
);
// Keep top_k scores if needed.
if
(
top_k
>
-
1
&&
top_k
<
(
int
)
score_index_vec
.
size
())
if
(
top_k
>
0
&&
top_k
<
(
int
)
score_index_vec
.
size
())
{
score_index_vec
.
resize
(
top_k
);
}
}
template
<
typename
BoxType
>
struct
NMSOverlap
{
float
operator
()
(
const
BoxType
&
a
,
const
BoxType
&
b
);
};
template
<>
inline
float
NMSOverlap
<
Rect
>::
operator
()
(
const
Rect
&
a
,
const
Rect
&
b
)
{
float
rectIntersectionArea
=
(
float
)(
a
&
b
).
area
();
return
rectIntersectionArea
/
(
a
.
area
()
+
b
.
area
()
-
rectIntersectionArea
);
}
// Do non maximum suppression given bboxes and scores.
// Inspired by Piotr Dollar's NMS implementation in EdgeBox.
// https://goo.gl/jV3JYS
...
...
@@ -74,13 +61,13 @@ inline float NMSOverlap<Rect>::operator() (const Rect& a, const Rect& b)
// scores: a set of corresponding confidences.
// score_threshold: a threshold used to filter detection results.
// nms_threshold: a threshold used in non maximum suppression.
// top_k: if not
-1
, keep at most top_k picked indices.
// top_k: if not
> 0
, keep at most top_k picked indices.
// indices: the kept indices of bboxes after nms.
template
<
typename
BoxType
>
inline
void
NMSFast_
(
const
std
::
vector
<
BoxType
>&
bboxes
,
const
std
::
vector
<
float
>&
scores
,
const
float
score_threshold
,
const
float
nms_threshold
,
const
float
eta
,
const
int
top_k
,
std
::
vector
<
int
>&
indices
,
NMSOverlap
<
BoxType
>
computeOverlap
)
std
::
vector
<
int
>&
indices
,
float
(
*
computeOverlap
)(
const
BoxType
&
,
const
BoxType
&
)
)
{
CV_Assert
(
bboxes
.
size
()
==
scores
.
size
());
...
...
@@ -91,8 +78,8 @@ inline void NMSFast_(const std::vector<BoxType>& bboxes,
// Do nms.
float
adaptive_threshold
=
nms_threshold
;
indices
.
clear
();
while
(
score_index_vec
.
size
()
!=
0
)
{
const
int
idx
=
score_index_vec
.
front
()
.
second
;
for
(
size_t
i
=
0
;
i
<
score_index_vec
.
size
();
++
i
)
{
const
int
idx
=
score_index_vec
[
i
]
.
second
;
bool
keep
=
true
;
for
(
int
k
=
0
;
k
<
(
int
)
indices
.
size
()
&&
keep
;
++
k
)
{
const
int
kept_idx
=
indices
[
k
];
...
...
@@ -101,7 +88,6 @@ inline void NMSFast_(const std::vector<BoxType>& bboxes,
}
if
(
keep
)
indices
.
push_back
(
idx
);
score_index_vec
.
erase
(
score_index_vec
.
begin
());
if
(
keep
&&
eta
<
1
&&
adaptive_threshold
>
0.5
)
{
adaptive_threshold
*=
eta
;
}
...
...
modules/dnn/src/layers/detection_output_layer.cpp
View file @
c704942b
...
...
@@ -62,6 +62,8 @@ static inline bool SortScorePairDescend(const std::pair<float, T>& pair1,
return
pair1
.
first
>
pair2
.
first
;
}
static
inline
float
caffe_box_overlap
(
const
caffe
::
NormalizedBBox
&
a
,
const
caffe
::
NormalizedBBox
&
b
);
}
// namespace
class
DetectionOutputLayerImpl
:
public
DetectionOutputLayer
...
...
@@ -309,7 +311,8 @@ public:
LabelBBox
::
const_iterator
label_bboxes
=
decodeBBoxes
.
find
(
label
);
if
(
label_bboxes
==
decodeBBoxes
.
end
())
CV_ErrorNoReturn_
(
cv
::
Error
::
StsError
,
(
"Could not find location predictions for label %d"
,
label
));
ApplyNMSFast
(
label_bboxes
->
second
,
scores
,
_confidenceThreshold
,
_nmsThreshold
,
1.0
,
_topK
,
indices
[
c
]);
NMSFast_
(
label_bboxes
->
second
,
scores
,
_confidenceThreshold
,
_nmsThreshold
,
1.0
,
_topK
,
indices
[
c
],
util
::
caffe_box_overlap
);
numDetections
+=
indices
[
c
].
size
();
}
if
(
_keepTopK
>
-
1
&&
numDetections
>
(
size_t
)
_keepTopK
)
...
...
@@ -620,16 +623,6 @@ public:
}
}
static
void
ApplyNMSFast
(
const
std
::
vector
<
caffe
::
NormalizedBBox
>&
bboxes
,
const
std
::
vector
<
float
>&
scores
,
const
float
score_threshold
,
const
float
nms_threshold
,
const
float
eta
,
const
int
top_k
,
std
::
vector
<
int
>&
indices
)
{
NMSFast_
(
bboxes
,
scores
,
score_threshold
,
nms_threshold
,
eta
,
top_k
,
indices
,
NMSOverlap
<
caffe
::
NormalizedBBox
>
());
}
// Compute the jaccard (intersection over union IoU) overlap between two bboxes.
template
<
bool
normalized
>
static
float
JaccardOverlap
(
const
caffe
::
NormalizedBBox
&
bbox1
,
...
...
@@ -675,8 +668,7 @@ public:
}
};
template
<>
float
NMSOverlap
<
caffe
::
NormalizedBBox
>::
operator
()
(
const
caffe
::
NormalizedBBox
&
a
,
const
caffe
::
NormalizedBBox
&
b
)
float
util
::
caffe_box_overlap
(
const
caffe
::
NormalizedBBox
&
a
,
const
caffe
::
NormalizedBBox
&
b
)
{
return
DetectionOutputLayerImpl
::
JaccardOverlap
<
true
>
(
a
,
b
);
}
...
...
modules/dnn/src/nms.cpp
View file @
c704942b
...
...
@@ -12,13 +12,22 @@ namespace cv
{
namespace
dnn
{
CV__DNN_EXPERIMENTAL_NS_BEGIN
static
inline
float
rectOverlap
(
const
Rect
&
a
,
const
Rect
&
b
)
{
return
1.
f
-
static_cast
<
float
>
(
jaccardDistance
(
a
,
b
));
}
void
NMSBoxes
(
const
std
::
vector
<
Rect
>&
bboxes
,
const
std
::
vector
<
float
>&
scores
,
const
float
score_threshold
,
const
float
nms_threshold
,
const
float
eta
,
const
int
top_k
,
std
::
vector
<
int
>&
indices
)
std
::
vector
<
int
>&
indices
,
const
float
eta
,
const
int
top_k
)
{
NMSFast_
(
bboxes
,
scores
,
score_threshold
,
nms_threshold
,
eta
,
top_k
,
indices
,
NMSOverlap
<
Rect
>
());
CV_Assert
(
bboxes
.
size
()
==
scores
.
size
(),
score_threshold
>=
0
,
nms_threshold
>=
0
,
eta
>
0
);
NMSFast_
(
bboxes
,
scores
,
score_threshold
,
nms_threshold
,
eta
,
top_k
,
indices
,
rectOverlap
);
}
CV__DNN_EXPERIMENTAL_NS_END
}
// dnn
}
// cv
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