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
acedb4a5
Commit
acedb4a5
authored
Oct 16, 2017
by
Vladislav Sovrasov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dnn: make NMS function public
parent
21c8e6d0
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
161 additions
and
62 deletions
+161
-62
dnn.hpp
modules/dnn/include/opencv2/dnn/dnn.hpp
+13
-0
nms.inl.hpp
modules/dnn/include/opencv2/dnn/nms.inl.hpp
+114
-0
detection_output_layer.cpp
modules/dnn/src/layers/detection_output_layer.cpp
+10
-62
nms.cpp
modules/dnn/src/nms.cpp
+24
-0
No files found.
modules/dnn/include/opencv2/dnn/dnn.hpp
View file @
acedb4a5
...
...
@@ -734,6 +734,19 @@ 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
*/
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__DNN_EXPERIMENTAL_NS_END
...
...
modules/dnn/include/opencv2/dnn/nms.inl.hpp
0 → 100644
View file @
acedb4a5
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
//
// Copyright (C) 2017, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
#ifndef OPENCV_DNN_NMS_INL_HPP
#define OPENCV_DNN_NMS_INL_HPP
#include <opencv2/dnn.hpp>
namespace
cv
{
namespace
dnn
{
namespace
{
template
<
typename
T
>
static
inline
bool
SortScorePairDescend
(
const
std
::
pair
<
float
,
T
>&
pair1
,
const
std
::
pair
<
float
,
T
>&
pair2
)
{
return
pair1
.
first
>
pair2
.
first
;
}
}
// namespace
// Get max scores with corresponding indices.
// scores: a set of scores.
// threshold: only consider scores higher than the threshold.
// top_k: if -1, keep all; otherwise, keep at most top_k.
// score_index_vec: store the sorted (score, index) pair.
inline
void
GetMaxScoreIndex
(
const
std
::
vector
<
float
>&
scores
,
const
float
threshold
,
const
int
top_k
,
std
::
vector
<
std
::
pair
<
float
,
int
>
>&
score_index_vec
)
{
CV_DbgAssert
(
score_index_vec
.
empty
());
// Generate index score pairs.
for
(
size_t
i
=
0
;
i
<
scores
.
size
();
++
i
)
{
if
(
scores
[
i
]
>
threshold
)
{
score_index_vec
.
push_back
(
std
::
make_pair
(
scores
[
i
],
i
));
}
}
// Sort the score pair according to the scores in descending order
std
::
stable_sort
(
score_index_vec
.
begin
(),
score_index_vec
.
end
(),
SortScorePairDescend
<
int
>
);
// Keep top_k scores if needed.
if
(
top_k
>
-
1
&&
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
// bboxes: a set of bounding boxes.
// 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.
// 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
)
{
CV_Assert
(
bboxes
.
size
()
==
scores
.
size
());
// Get top_k scores (with corresponding indices).
std
::
vector
<
std
::
pair
<
float
,
int
>
>
score_index_vec
;
GetMaxScoreIndex
(
scores
,
score_threshold
,
top_k
,
score_index_vec
);
// Do nms.
float
adaptive_threshold
=
nms_threshold
;
indices
.
clear
();
while
(
score_index_vec
.
size
()
!=
0
)
{
const
int
idx
=
score_index_vec
.
front
().
second
;
bool
keep
=
true
;
for
(
int
k
=
0
;
k
<
(
int
)
indices
.
size
()
&&
keep
;
++
k
)
{
const
int
kept_idx
=
indices
[
k
];
float
overlap
=
computeOverlap
(
bboxes
[
idx
],
bboxes
[
kept_idx
]);
keep
=
overlap
<=
adaptive_threshold
;
}
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
;
}
}
}
}
// dnn
}
// cv
#endif
modules/dnn/src/layers/detection_output_layer.cpp
View file @
acedb4a5
...
...
@@ -45,6 +45,7 @@
#include <float.h>
#include <string>
#include <caffe.pb.h>
#include <opencv2/dnn/nms.inl.hpp>
namespace
cv
{
...
...
@@ -619,73 +620,14 @@ public:
}
}
// Do non maximum suppression given bboxes and scores.
// Inspired by Piotr Dollar's NMS implementation in EdgeBox.
// https://goo.gl/jV3JYS
// bboxes: a set of bounding boxes.
// 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.
// indices: the kept indices of bboxes after nms.
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
)
{
CV_Assert
(
bboxes
.
size
()
==
scores
.
size
());
// Get top_k scores (with corresponding indices).
std
::
vector
<
std
::
pair
<
float
,
int
>
>
score_index_vec
;
GetMaxScoreIndex
(
scores
,
score_threshold
,
top_k
,
score_index_vec
);
// Do nms.
float
adaptive_threshold
=
nms_threshold
;
indices
.
clear
();
while
(
score_index_vec
.
size
()
!=
0
)
{
const
int
idx
=
score_index_vec
.
front
().
second
;
bool
keep
=
true
;
for
(
int
k
=
0
;
k
<
(
int
)
indices
.
size
()
&&
keep
;
++
k
)
{
const
int
kept_idx
=
indices
[
k
];
float
overlap
=
JaccardOverlap
<
true
>
(
bboxes
[
idx
],
bboxes
[
kept_idx
]);
keep
=
overlap
<=
adaptive_threshold
;
}
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
;
}
}
}
// Get max scores with corresponding indices.
// scores: a set of scores.
// threshold: only consider scores higher than the threshold.
// top_k: if -1, keep all; otherwise, keep at most top_k.
// score_index_vec: store the sorted (score, index) pair.
static
void
GetMaxScoreIndex
(
const
std
::
vector
<
float
>&
scores
,
const
float
threshold
,
const
int
top_k
,
std
::
vector
<
std
::
pair
<
float
,
int
>
>&
score_index_vec
)
{
CV_DbgAssert
(
score_index_vec
.
empty
());
// Generate index score pairs.
for
(
size_t
i
=
0
;
i
<
scores
.
size
();
++
i
)
{
if
(
scores
[
i
]
>
threshold
)
{
score_index_vec
.
push_back
(
std
::
make_pair
(
scores
[
i
],
i
));
}
}
// Sort the score pair according to the scores in descending order
std
::
stable_sort
(
score_index_vec
.
begin
(),
score_index_vec
.
end
(),
util
::
SortScorePairDescend
<
int
>
);
// Keep top_k scores if needed.
if
(
top_k
>
-
1
&&
top_k
<
(
int
)
score_index_vec
.
size
())
{
score_index_vec
.
resize
(
top_k
);
}
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.
...
...
@@ -733,6 +675,12 @@ public:
}
};
template
<>
float
NMSOverlap
<
caffe
::
NormalizedBBox
>::
operator
()
(
const
caffe
::
NormalizedBBox
&
a
,
const
caffe
::
NormalizedBBox
&
b
)
{
return
DetectionOutputLayerImpl
::
JaccardOverlap
<
true
>
(
a
,
b
);
}
const
std
::
string
DetectionOutputLayerImpl
::
_layerName
=
std
::
string
(
"DetectionOutput"
);
Ptr
<
DetectionOutputLayer
>
DetectionOutputLayer
::
create
(
const
LayerParams
&
params
)
...
...
modules/dnn/src/nms.cpp
0 → 100644
View file @
acedb4a5
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
//
// Copyright (C) 2017, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
#include "precomp.hpp"
#include <opencv2/dnn/nms.inl.hpp>
namespace
cv
{
namespace
dnn
{
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
)
{
NMSFast_
(
bboxes
,
scores
,
score_threshold
,
nms_threshold
,
eta
,
top_k
,
indices
,
NMSOverlap
<
Rect
>
());
}
}
// 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