Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
s920243400
PaddleDetection
提交
2580dc01
P
PaddleDetection
项目概览
s920243400
/
PaddleDetection
与 Fork 源项目一致
Fork自
PaddlePaddle / PaddleDetection
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
PaddleDetection
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
2580dc01
编写于
1月 05, 2022
作者:
G
Guanghua Yu
提交者:
GitHub
1月 05, 2022
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix picodet cpp infer (#5065)
上级
b367361e
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
863 addition
and
977 deletion
+863
-977
deploy/cpp/include/picodet_postprocess.h
deploy/cpp/include/picodet_postprocess.h
+13
-14
deploy/cpp/src/picodet_postprocess.cc
deploy/cpp/src/picodet_postprocess.cc
+62
-64
deploy/lite/src/picodet_postprocess.cc
deploy/lite/src/picodet_postprocess.cc
+62
-64
deploy/third_engine/demo_mnn/picodet_mnn.cpp
deploy/third_engine/demo_mnn/picodet_mnn.cpp
+175
-195
deploy/third_engine/demo_ncnn/picodet.cpp
deploy/third_engine/demo_ncnn/picodet.cpp
+136
-153
deploy/third_engine/demo_openvino/main.cpp
deploy/third_engine/demo_openvino/main.cpp
+247
-296
deploy/third_engine/demo_openvino/picodet_openvino.cpp
deploy/third_engine/demo_openvino/picodet_openvino.cpp
+168
-191
未找到文件。
deploy/cpp/include/picodet_postprocess.h
浏览文件 @
2580dc01
...
...
@@ -14,25 +14,24 @@
#pragma once
#include <string>
#include <vector>
#include <memory>
#include <utility>
#include <cmath>
#include <ctime>
#include <memory>
#include <numeric>
#include <string>
#include <utility>
#include <vector>
#include "include/utils.h"
namespace
PaddleDetection
{
void
PicoDetPostProcess
(
std
::
vector
<
PaddleDetection
::
ObjectResult
>*
results
,
std
::
vector
<
const
float
*>
outs
,
std
::
vector
<
int
>
fpn_stride
,
std
::
vector
<
float
>
im_shape
,
std
::
vector
<
float
>
scale_factor
,
float
score_threshold
=
0.3
,
float
nms_threshold
=
0.5
,
int
num_class
=
80
,
int
reg_max
=
7
);
void
PicoDetPostProcess
(
std
::
vector
<
PaddleDetection
::
ObjectResult
>
*
results
,
std
::
vector
<
const
float
*>
outs
,
std
::
vector
<
int
>
fpn_stride
,
std
::
vector
<
float
>
im_shape
,
std
::
vector
<
float
>
scale_factor
,
float
score_threshold
=
0.3
,
float
nms_threshold
=
0.5
,
int
num_class
=
80
,
int
reg_max
=
7
);
}
// namespace PaddleDetection
\ No newline at end of file
}
// namespace PaddleDetection
deploy/cpp/src/picodet_postprocess.cc
浏览文件 @
2580dc01
...
...
@@ -20,79 +20,76 @@
namespace
PaddleDetection
{
float
fast_exp
(
float
x
)
{
union
{
uint32_t
i
;
float
f
;
}
v
{};
v
.
i
=
(
1
<<
23
)
*
(
1.4426950409
*
x
+
126.93490512
f
);
return
v
.
f
;
union
{
uint32_t
i
;
float
f
;
}
v
{};
v
.
i
=
(
1
<<
23
)
*
(
1.4426950409
*
x
+
126.93490512
f
);
return
v
.
f
;
}
template
<
typename
_Tp
>
int
activation_function_softmax
(
const
_Tp
*
src
,
_Tp
*
dst
,
int
length
)
{
const
_Tp
alpha
=
*
std
::
max_element
(
src
,
src
+
length
);
_Tp
denominator
{
0
};
const
_Tp
alpha
=
*
std
::
max_element
(
src
,
src
+
length
);
_Tp
denominator
{
0
};
for
(
int
i
=
0
;
i
<
length
;
++
i
)
{
dst
[
i
]
=
fast_exp
(
src
[
i
]
-
alpha
);
denominator
+=
dst
[
i
];
}
for
(
int
i
=
0
;
i
<
length
;
++
i
)
{
dst
[
i
]
=
fast_exp
(
src
[
i
]
-
alpha
);
denominator
+=
dst
[
i
];
}
for
(
int
i
=
0
;
i
<
length
;
++
i
)
{
dst
[
i
]
/=
denominator
;
}
for
(
int
i
=
0
;
i
<
length
;
++
i
)
{
dst
[
i
]
/=
denominator
;
}
return
0
;
return
0
;
}
// PicoDet decode
PaddleDetection
::
ObjectResult
disPred2Bbox
(
const
float
*&
dfl_det
,
int
label
,
float
score
,
int
x
,
int
y
,
int
stride
,
std
::
vector
<
float
>
im_shape
,
int
reg_max
)
{
float
ct_x
=
(
x
+
0.5
)
*
stride
;
float
ct_y
=
(
y
+
0.5
)
*
stride
;
std
::
vector
<
float
>
dis_pred
;
dis_pred
.
resize
(
4
);
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
float
dis
=
0
;
float
*
dis_after_sm
=
new
float
[
reg_max
+
1
];
activation_function_softmax
(
dfl_det
+
i
*
(
reg_max
+
1
),
dis_after_sm
,
reg_max
+
1
);
for
(
int
j
=
0
;
j
<
reg_max
+
1
;
j
++
)
{
dis
+=
j
*
dis_after_sm
[
j
];
}
dis
*=
stride
;
dis_pred
[
i
]
=
dis
;
delete
[]
dis_after_sm
;
PaddleDetection
::
ObjectResult
disPred2Bbox
(
const
float
*&
dfl_det
,
int
label
,
float
score
,
int
x
,
int
y
,
int
stride
,
std
::
vector
<
float
>
im_shape
,
int
reg_max
)
{
float
ct_x
=
(
x
+
0.5
)
*
stride
;
float
ct_y
=
(
y
+
0.5
)
*
stride
;
std
::
vector
<
float
>
dis_pred
;
dis_pred
.
resize
(
4
);
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
float
dis
=
0
;
float
*
dis_after_sm
=
new
float
[
reg_max
+
1
];
activation_function_softmax
(
dfl_det
+
i
*
(
reg_max
+
1
),
dis_after_sm
,
reg_max
+
1
);
for
(
int
j
=
0
;
j
<
reg_max
+
1
;
j
++
)
{
dis
+=
j
*
dis_after_sm
[
j
];
}
int
xmin
=
(
int
)(
std
::
max
)(
ct_x
-
dis_pred
[
0
],
.0
f
);
int
ymin
=
(
int
)(
std
::
max
)(
ct_y
-
dis_pred
[
1
],
.0
f
);
int
xmax
=
(
int
)(
std
::
min
)(
ct_x
+
dis_pred
[
2
],
(
float
)
im_shape
[
0
]);
int
ymax
=
(
int
)(
std
::
min
)(
ct_y
+
dis_pred
[
3
],
(
float
)
im_shape
[
1
]);
dis
*=
stride
;
dis_pred
[
i
]
=
dis
;
delete
[]
dis_after_sm
;
}
int
xmin
=
(
int
)(
std
::
max
)(
ct_x
-
dis_pred
[
0
],
.0
f
);
int
ymin
=
(
int
)(
std
::
max
)(
ct_y
-
dis_pred
[
1
],
.0
f
);
int
xmax
=
(
int
)(
std
::
min
)(
ct_x
+
dis_pred
[
2
],
(
float
)
im_shape
[
0
]);
int
ymax
=
(
int
)(
std
::
min
)(
ct_y
+
dis_pred
[
3
],
(
float
)
im_shape
[
1
]);
PaddleDetection
::
ObjectResult
result_item
;
result_item
.
rect
=
{
xmin
,
ymin
,
xmax
,
ymax
};
result_item
.
class_id
=
label
;
result_item
.
confidence
=
score
;
PaddleDetection
::
ObjectResult
result_item
;
result_item
.
rect
=
{
xmin
,
ymin
,
xmax
,
ymax
};
result_item
.
class_id
=
label
;
result_item
.
confidence
=
score
;
return
result_item
;
return
result_item
;
}
void
PicoDetPostProcess
(
std
::
vector
<
PaddleDetection
::
ObjectResult
>*
results
,
std
::
vector
<
const
float
*>
outs
,
std
::
vector
<
int
>
fpn_stride
,
std
::
vector
<
float
>
im_shape
,
std
::
vector
<
float
>
scale_factor
,
float
score_threshold
,
float
nms_threshold
,
int
num_class
,
int
reg_max
)
{
void
PicoDetPostProcess
(
std
::
vector
<
PaddleDetection
::
ObjectResult
>
*
results
,
std
::
vector
<
const
float
*>
outs
,
std
::
vector
<
int
>
fpn_stride
,
std
::
vector
<
float
>
im_shape
,
std
::
vector
<
float
>
scale_factor
,
float
score_threshold
,
float
nms_threshold
,
int
num_class
,
int
reg_max
)
{
std
::
vector
<
std
::
vector
<
PaddleDetection
::
ObjectResult
>>
bbox_results
;
bbox_results
.
resize
(
num_class
);
int
in_h
=
im_shape
[
0
],
in_w
=
im_shape
[
1
];
for
(
int
i
=
0
;
i
<
fpn_stride
.
size
();
++
i
)
{
int
feature_h
=
in_h
/
fpn_stride
[
i
]
;
int
feature_w
=
in_w
/
fpn_stride
[
i
]
;
int
feature_h
=
std
::
ceil
((
float
)
in_h
/
fpn_stride
[
i
])
;
int
feature_w
=
std
::
ceil
((
float
)
in_w
/
fpn_stride
[
i
])
;
for
(
int
idx
=
0
;
idx
<
feature_h
*
feature_w
;
idx
++
)
{
const
float
*
scores
=
outs
[
i
]
+
(
idx
*
num_class
);
...
...
@@ -107,10 +104,11 @@ void PicoDetPostProcess(std::vector<PaddleDetection::ObjectResult>* results,
}
}
if
(
score
>
score_threshold
)
{
const
float
*
bbox_pred
=
outs
[
i
+
fpn_stride
.
size
()]
+
(
idx
*
4
*
(
reg_max
+
1
));
bbox_results
[
cur_label
].
push_back
(
disPred2Bbox
(
bbox_pred
,
cur_label
,
score
,
col
,
row
,
fpn_stride
[
i
],
im_shape
,
reg_max
));
const
float
*
bbox_pred
=
outs
[
i
+
fpn_stride
.
size
()]
+
(
idx
*
4
*
(
reg_max
+
1
));
bbox_results
[
cur_label
].
push_back
(
disPred2Bbox
(
bbox_pred
,
cur_label
,
score
,
col
,
row
,
fpn_stride
[
i
],
im_shape
,
reg_max
));
}
}
}
...
...
@@ -118,13 +116,13 @@ void PicoDetPostProcess(std::vector<PaddleDetection::ObjectResult>* results,
PaddleDetection
::
nms
(
bbox_results
[
i
],
nms_threshold
);
for
(
auto
box
:
bbox_results
[
i
])
{
box
.
rect
[
0
]
=
box
.
rect
[
0
]
/
scale_factor
[
1
];
box
.
rect
[
2
]
=
box
.
rect
[
2
]
/
scale_factor
[
1
];
box
.
rect
[
1
]
=
box
.
rect
[
1
]
/
scale_factor
[
0
];
box
.
rect
[
3
]
=
box
.
rect
[
3
]
/
scale_factor
[
0
];
results
->
push_back
(
box
);
box
.
rect
[
0
]
=
box
.
rect
[
0
]
/
scale_factor
[
1
];
box
.
rect
[
2
]
=
box
.
rect
[
2
]
/
scale_factor
[
1
];
box
.
rect
[
1
]
=
box
.
rect
[
1
]
/
scale_factor
[
0
];
box
.
rect
[
3
]
=
box
.
rect
[
3
]
/
scale_factor
[
0
];
results
->
push_back
(
box
);
}
}
}
}
// namespace PaddleDetection
}
// namespace PaddleDetection
deploy/lite/src/picodet_postprocess.cc
浏览文件 @
2580dc01
...
...
@@ -20,79 +20,76 @@
namespace
PaddleDetection
{
float
fast_exp
(
float
x
)
{
union
{
uint32_t
i
;
float
f
;
}
v
{};
v
.
i
=
(
1
<<
23
)
*
(
1.4426950409
*
x
+
126.93490512
f
);
return
v
.
f
;
union
{
uint32_t
i
;
float
f
;
}
v
{};
v
.
i
=
(
1
<<
23
)
*
(
1.4426950409
*
x
+
126.93490512
f
);
return
v
.
f
;
}
template
<
typename
_Tp
>
int
activation_function_softmax
(
const
_Tp
*
src
,
_Tp
*
dst
,
int
length
)
{
const
_Tp
alpha
=
*
std
::
max_element
(
src
,
src
+
length
);
_Tp
denominator
{
0
};
const
_Tp
alpha
=
*
std
::
max_element
(
src
,
src
+
length
);
_Tp
denominator
{
0
};
for
(
int
i
=
0
;
i
<
length
;
++
i
)
{
dst
[
i
]
=
fast_exp
(
src
[
i
]
-
alpha
);
denominator
+=
dst
[
i
];
}
for
(
int
i
=
0
;
i
<
length
;
++
i
)
{
dst
[
i
]
=
fast_exp
(
src
[
i
]
-
alpha
);
denominator
+=
dst
[
i
];
}
for
(
int
i
=
0
;
i
<
length
;
++
i
)
{
dst
[
i
]
/=
denominator
;
}
for
(
int
i
=
0
;
i
<
length
;
++
i
)
{
dst
[
i
]
/=
denominator
;
}
return
0
;
return
0
;
}
// PicoDet decode
PaddleDetection
::
ObjectResult
disPred2Bbox
(
const
float
*&
dfl_det
,
int
label
,
float
score
,
int
x
,
int
y
,
int
stride
,
std
::
vector
<
float
>
im_shape
,
int
reg_max
)
{
float
ct_x
=
(
x
+
0.5
)
*
stride
;
float
ct_y
=
(
y
+
0.5
)
*
stride
;
std
::
vector
<
float
>
dis_pred
;
dis_pred
.
resize
(
4
);
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
float
dis
=
0
;
float
*
dis_after_sm
=
new
float
[
reg_max
+
1
];
activation_function_softmax
(
dfl_det
+
i
*
(
reg_max
+
1
),
dis_after_sm
,
reg_max
+
1
);
for
(
int
j
=
0
;
j
<
reg_max
+
1
;
j
++
)
{
dis
+=
j
*
dis_after_sm
[
j
];
}
dis
*=
stride
;
dis_pred
[
i
]
=
dis
;
delete
[]
dis_after_sm
;
PaddleDetection
::
ObjectResult
disPred2Bbox
(
const
float
*&
dfl_det
,
int
label
,
float
score
,
int
x
,
int
y
,
int
stride
,
std
::
vector
<
float
>
im_shape
,
int
reg_max
)
{
float
ct_x
=
(
x
+
0.5
)
*
stride
;
float
ct_y
=
(
y
+
0.5
)
*
stride
;
std
::
vector
<
float
>
dis_pred
;
dis_pred
.
resize
(
4
);
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
float
dis
=
0
;
float
*
dis_after_sm
=
new
float
[
reg_max
+
1
];
activation_function_softmax
(
dfl_det
+
i
*
(
reg_max
+
1
),
dis_after_sm
,
reg_max
+
1
);
for
(
int
j
=
0
;
j
<
reg_max
+
1
;
j
++
)
{
dis
+=
j
*
dis_after_sm
[
j
];
}
int
xmin
=
(
int
)(
std
::
max
)(
ct_x
-
dis_pred
[
0
],
.0
f
);
int
ymin
=
(
int
)(
std
::
max
)(
ct_y
-
dis_pred
[
1
],
.0
f
);
int
xmax
=
(
int
)(
std
::
min
)(
ct_x
+
dis_pred
[
2
],
(
float
)
im_shape
[
0
]);
int
ymax
=
(
int
)(
std
::
min
)(
ct_y
+
dis_pred
[
3
],
(
float
)
im_shape
[
1
]);
dis
*=
stride
;
dis_pred
[
i
]
=
dis
;
delete
[]
dis_after_sm
;
}
int
xmin
=
(
int
)(
std
::
max
)(
ct_x
-
dis_pred
[
0
],
.0
f
);
int
ymin
=
(
int
)(
std
::
max
)(
ct_y
-
dis_pred
[
1
],
.0
f
);
int
xmax
=
(
int
)(
std
::
min
)(
ct_x
+
dis_pred
[
2
],
(
float
)
im_shape
[
0
]);
int
ymax
=
(
int
)(
std
::
min
)(
ct_y
+
dis_pred
[
3
],
(
float
)
im_shape
[
1
]);
PaddleDetection
::
ObjectResult
result_item
;
result_item
.
rect
=
{
xmin
,
ymin
,
xmax
,
ymax
};
result_item
.
class_id
=
label
;
result_item
.
confidence
=
score
;
PaddleDetection
::
ObjectResult
result_item
;
result_item
.
rect
=
{
xmin
,
ymin
,
xmax
,
ymax
};
result_item
.
class_id
=
label
;
result_item
.
confidence
=
score
;
return
result_item
;
return
result_item
;
}
void
PicoDetPostProcess
(
std
::
vector
<
PaddleDetection
::
ObjectResult
>*
results
,
std
::
vector
<
const
float
*>
outs
,
std
::
vector
<
int
>
fpn_stride
,
std
::
vector
<
float
>
im_shape
,
std
::
vector
<
float
>
scale_factor
,
float
score_threshold
,
float
nms_threshold
,
int
num_class
,
int
reg_max
)
{
void
PicoDetPostProcess
(
std
::
vector
<
PaddleDetection
::
ObjectResult
>
*
results
,
std
::
vector
<
const
float
*>
outs
,
std
::
vector
<
int
>
fpn_stride
,
std
::
vector
<
float
>
im_shape
,
std
::
vector
<
float
>
scale_factor
,
float
score_threshold
,
float
nms_threshold
,
int
num_class
,
int
reg_max
)
{
std
::
vector
<
std
::
vector
<
PaddleDetection
::
ObjectResult
>>
bbox_results
;
bbox_results
.
resize
(
num_class
);
int
in_h
=
im_shape
[
0
],
in_w
=
im_shape
[
1
];
for
(
int
i
=
0
;
i
<
fpn_stride
.
size
();
++
i
)
{
int
feature_h
=
in_h
/
fpn_stride
[
i
]
;
int
feature_w
=
in_w
/
fpn_stride
[
i
]
;
int
feature_h
=
ceil
((
float
)
in_h
/
fpn_stride
[
i
])
;
int
feature_w
=
ceil
((
float
)
in_w
/
fpn_stride
[
i
])
;
for
(
int
idx
=
0
;
idx
<
feature_h
*
feature_w
;
idx
++
)
{
const
float
*
scores
=
outs
[
i
]
+
(
idx
*
num_class
);
...
...
@@ -107,10 +104,11 @@ void PicoDetPostProcess(std::vector<PaddleDetection::ObjectResult>* results,
}
}
if
(
score
>
score_threshold
)
{
const
float
*
bbox_pred
=
outs
[
i
+
fpn_stride
.
size
()]
+
(
idx
*
4
*
(
reg_max
+
1
));
bbox_results
[
cur_label
].
push_back
(
disPred2Bbox
(
bbox_pred
,
cur_label
,
score
,
col
,
row
,
fpn_stride
[
i
],
im_shape
,
reg_max
));
const
float
*
bbox_pred
=
outs
[
i
+
fpn_stride
.
size
()]
+
(
idx
*
4
*
(
reg_max
+
1
));
bbox_results
[
cur_label
].
push_back
(
disPred2Bbox
(
bbox_pred
,
cur_label
,
score
,
col
,
row
,
fpn_stride
[
i
],
im_shape
,
reg_max
));
}
}
}
...
...
@@ -118,13 +116,13 @@ void PicoDetPostProcess(std::vector<PaddleDetection::ObjectResult>* results,
PaddleDetection
::
nms
(
bbox_results
[
i
],
nms_threshold
);
for
(
auto
box
:
bbox_results
[
i
])
{
box
.
rect
[
0
]
=
box
.
rect
[
0
]
/
scale_factor
[
1
];
box
.
rect
[
2
]
=
box
.
rect
[
2
]
/
scale_factor
[
1
];
box
.
rect
[
1
]
=
box
.
rect
[
1
]
/
scale_factor
[
0
];
box
.
rect
[
3
]
=
box
.
rect
[
3
]
/
scale_factor
[
0
];
results
->
push_back
(
box
);
box
.
rect
[
0
]
=
box
.
rect
[
0
]
/
scale_factor
[
1
];
box
.
rect
[
2
]
=
box
.
rect
[
2
]
/
scale_factor
[
1
];
box
.
rect
[
1
]
=
box
.
rect
[
1
]
/
scale_factor
[
0
];
box
.
rect
[
3
]
=
box
.
rect
[
3
]
/
scale_factor
[
0
];
results
->
push_back
(
box
);
}
}
}
}
// namespace PaddleDetection
}
// namespace PaddleDetection
deploy/third_engine/demo_mnn/picodet_mnn.cpp
浏览文件 @
2580dc01
...
...
@@ -17,223 +17,203 @@
using
namespace
std
;
PicoDet
::
PicoDet
(
const
std
::
string
&
mnn_path
,
int
input_width
,
int
input_length
,
int
num_thread_
,
float
score_threshold_
,
float
nms_threshold_
)
{
num_thread
=
num_thread_
;
in_w
=
input_width
;
in_h
=
input_length
;
score_threshold
=
score_threshold_
;
nms_threshold
=
nms_threshold_
;
PicoDet_interpreter
=
std
::
shared_ptr
<
MNN
::
Interpreter
>
(
MNN
::
Interpreter
::
createFromFile
(
mnn_path
.
c_str
()));
MNN
::
ScheduleConfig
config
;
config
.
numThread
=
num_thread
;
MNN
::
BackendConfig
backendConfig
;
backendConfig
.
precision
=
(
MNN
::
BackendConfig
::
PrecisionMode
)
2
;
config
.
backendConfig
=
&
backendConfig
;
PicoDet_session
=
PicoDet_interpreter
->
createSession
(
config
);
input_tensor
=
PicoDet_interpreter
->
getSessionInput
(
PicoDet_session
,
nullptr
);
PicoDet
::
PicoDet
(
const
std
::
string
&
mnn_path
,
int
input_width
,
int
input_length
,
int
num_thread_
,
float
score_threshold_
,
float
nms_threshold_
)
{
num_thread
=
num_thread_
;
in_w
=
input_width
;
in_h
=
input_length
;
score_threshold
=
score_threshold_
;
nms_threshold
=
nms_threshold_
;
PicoDet_interpreter
=
std
::
shared_ptr
<
MNN
::
Interpreter
>
(
MNN
::
Interpreter
::
createFromFile
(
mnn_path
.
c_str
()));
MNN
::
ScheduleConfig
config
;
config
.
numThread
=
num_thread
;
MNN
::
BackendConfig
backendConfig
;
backendConfig
.
precision
=
(
MNN
::
BackendConfig
::
PrecisionMode
)
2
;
config
.
backendConfig
=
&
backendConfig
;
PicoDet_session
=
PicoDet_interpreter
->
createSession
(
config
);
input_tensor
=
PicoDet_interpreter
->
getSessionInput
(
PicoDet_session
,
nullptr
);
}
PicoDet
::~
PicoDet
()
{
PicoDet_interpreter
->
releaseModel
();
PicoDet_interpreter
->
releaseSession
(
PicoDet_session
);
PicoDet
::~
PicoDet
()
{
PicoDet_interpreter
->
releaseModel
();
PicoDet_interpreter
->
releaseSession
(
PicoDet_session
);
}
int
PicoDet
::
detect
(
cv
::
Mat
&
raw_image
,
std
::
vector
<
BoxInfo
>
&
result_list
)
{
if
(
raw_image
.
empty
())
{
std
::
cout
<<
"image is empty ,please check!"
<<
std
::
endl
;
return
-
1
;
}
image_h
=
raw_image
.
rows
;
image_w
=
raw_image
.
cols
;
cv
::
Mat
image
;
cv
::
resize
(
raw_image
,
image
,
cv
::
Size
(
in_w
,
in_h
));
PicoDet_interpreter
->
resizeTensor
(
input_tensor
,
{
1
,
3
,
in_h
,
in_w
});
PicoDet_interpreter
->
resizeSession
(
PicoDet_session
);
std
::
shared_ptr
<
MNN
::
CV
::
ImageProcess
>
pretreat
(
MNN
::
CV
::
ImageProcess
::
create
(
MNN
::
CV
::
BGR
,
MNN
::
CV
::
BGR
,
mean_vals
,
3
,
norm_vals
,
3
));
pretreat
->
convert
(
image
.
data
,
in_w
,
in_h
,
image
.
step
[
0
],
input_tensor
);
auto
start
=
chrono
::
steady_clock
::
now
();
// run network
PicoDet_interpreter
->
runSession
(
PicoDet_session
);
// get output data
std
::
vector
<
std
::
vector
<
BoxInfo
>>
results
;
results
.
resize
(
num_class
);
for
(
const
auto
&
head_info
:
heads_info
)
{
MNN
::
Tensor
*
tensor_scores
=
PicoDet_interpreter
->
getSessionOutput
(
PicoDet_session
,
head_info
.
cls_layer
.
c_str
());
MNN
::
Tensor
*
tensor_boxes
=
PicoDet_interpreter
->
getSessionOutput
(
PicoDet_session
,
head_info
.
dis_layer
.
c_str
());
MNN
::
Tensor
tensor_scores_host
(
tensor_scores
,
tensor_scores
->
getDimensionType
());
tensor_scores
->
copyToHostTensor
(
&
tensor_scores_host
);
MNN
::
Tensor
tensor_boxes_host
(
tensor_boxes
,
tensor_boxes
->
getDimensionType
());
tensor_boxes
->
copyToHostTensor
(
&
tensor_boxes_host
);
decode_infer
(
&
tensor_scores_host
,
&
tensor_boxes_host
,
head_info
.
stride
,
score_threshold
,
results
);
}
auto
end
=
chrono
::
steady_clock
::
now
();
chrono
::
duration
<
double
>
elapsed
=
end
-
start
;
cout
<<
"inference time:"
<<
elapsed
.
count
()
<<
" s, "
;
for
(
int
i
=
0
;
i
<
(
int
)
results
.
size
();
i
++
)
{
nms
(
results
[
i
],
nms_threshold
);
for
(
auto
box
:
results
[
i
])
{
box
.
x1
=
box
.
x1
/
in_w
*
image_w
;
box
.
x2
=
box
.
x2
/
in_w
*
image_w
;
box
.
y1
=
box
.
y1
/
in_h
*
image_h
;
box
.
y2
=
box
.
y2
/
in_h
*
image_h
;
result_list
.
push_back
(
box
);
}
int
PicoDet
::
detect
(
cv
::
Mat
&
raw_image
,
std
::
vector
<
BoxInfo
>
&
result_list
)
{
if
(
raw_image
.
empty
())
{
std
::
cout
<<
"image is empty ,please check!"
<<
std
::
endl
;
return
-
1
;
}
image_h
=
raw_image
.
rows
;
image_w
=
raw_image
.
cols
;
cv
::
Mat
image
;
cv
::
resize
(
raw_image
,
image
,
cv
::
Size
(
in_w
,
in_h
));
PicoDet_interpreter
->
resizeTensor
(
input_tensor
,
{
1
,
3
,
in_h
,
in_w
});
PicoDet_interpreter
->
resizeSession
(
PicoDet_session
);
std
::
shared_ptr
<
MNN
::
CV
::
ImageProcess
>
pretreat
(
MNN
::
CV
::
ImageProcess
::
create
(
MNN
::
CV
::
BGR
,
MNN
::
CV
::
BGR
,
mean_vals
,
3
,
norm_vals
,
3
));
pretreat
->
convert
(
image
.
data
,
in_w
,
in_h
,
image
.
step
[
0
],
input_tensor
);
auto
start
=
chrono
::
steady_clock
::
now
();
// run network
PicoDet_interpreter
->
runSession
(
PicoDet_session
);
// get output data
std
::
vector
<
std
::
vector
<
BoxInfo
>>
results
;
results
.
resize
(
num_class
);
for
(
const
auto
&
head_info
:
heads_info
)
{
MNN
::
Tensor
*
tensor_scores
=
PicoDet_interpreter
->
getSessionOutput
(
PicoDet_session
,
head_info
.
cls_layer
.
c_str
());
MNN
::
Tensor
*
tensor_boxes
=
PicoDet_interpreter
->
getSessionOutput
(
PicoDet_session
,
head_info
.
dis_layer
.
c_str
());
MNN
::
Tensor
tensor_scores_host
(
tensor_scores
,
tensor_scores
->
getDimensionType
());
tensor_scores
->
copyToHostTensor
(
&
tensor_scores_host
);
MNN
::
Tensor
tensor_boxes_host
(
tensor_boxes
,
tensor_boxes
->
getDimensionType
());
tensor_boxes
->
copyToHostTensor
(
&
tensor_boxes_host
);
decode_infer
(
&
tensor_scores_host
,
&
tensor_boxes_host
,
head_info
.
stride
,
score_threshold
,
results
);
}
auto
end
=
chrono
::
steady_clock
::
now
();
chrono
::
duration
<
double
>
elapsed
=
end
-
start
;
cout
<<
"inference time:"
<<
elapsed
.
count
()
<<
" s, "
;
for
(
int
i
=
0
;
i
<
(
int
)
results
.
size
();
i
++
)
{
nms
(
results
[
i
],
nms_threshold
);
for
(
auto
box
:
results
[
i
])
{
box
.
x1
=
box
.
x1
/
in_w
*
image_w
;
box
.
x2
=
box
.
x2
/
in_w
*
image_w
;
box
.
y1
=
box
.
y1
/
in_h
*
image_h
;
box
.
y2
=
box
.
y2
/
in_h
*
image_h
;
result_list
.
push_back
(
box
);
}
cout
<<
"detect "
<<
result_list
.
size
()
<<
" objects"
<<
endl
;
}
cout
<<
"detect "
<<
result_list
.
size
()
<<
" objects"
<<
endl
;
return
0
;
return
0
;
}
void
PicoDet
::
decode_infer
(
MNN
::
Tensor
*
cls_pred
,
MNN
::
Tensor
*
dis_pred
,
int
stride
,
float
threshold
,
std
::
vector
<
std
::
vector
<
BoxInfo
>>
&
results
)
{
int
feature_h
=
in_h
/
stride
;
int
feature_w
=
in_w
/
stride
;
for
(
int
idx
=
0
;
idx
<
feature_h
*
feature_w
;
idx
++
)
{
const
float
*
scores
=
cls_pred
->
host
<
float
>
()
+
(
idx
*
num_class
);
int
row
=
idx
/
feature_w
;
int
col
=
idx
%
feature_w
;
float
score
=
0
;
int
cur_label
=
0
;
for
(
int
label
=
0
;
label
<
num_class
;
label
++
)
{
if
(
scores
[
label
]
>
score
)
{
score
=
scores
[
label
];
cur_label
=
label
;
}
}
if
(
score
>
threshold
)
{
const
float
*
bbox_pred
=
dis_pred
->
host
<
float
>
()
+
(
idx
*
4
*
(
reg_max
+
1
));
results
[
cur_label
].
push_back
(
disPred2Bbox
(
bbox_pred
,
cur_label
,
score
,
col
,
row
,
stride
));
}
void
PicoDet
::
decode_infer
(
MNN
::
Tensor
*
cls_pred
,
MNN
::
Tensor
*
dis_pred
,
int
stride
,
float
threshold
,
std
::
vector
<
std
::
vector
<
BoxInfo
>>
&
results
)
{
int
feature_h
=
ceil
((
float
)
in_h
/
stride
);
int
feature_w
=
ceil
((
float
)
in_w
/
stride
);
for
(
int
idx
=
0
;
idx
<
feature_h
*
feature_w
;
idx
++
)
{
const
float
*
scores
=
cls_pred
->
host
<
float
>
()
+
(
idx
*
num_class
);
int
row
=
idx
/
feature_w
;
int
col
=
idx
%
feature_w
;
float
score
=
0
;
int
cur_label
=
0
;
for
(
int
label
=
0
;
label
<
num_class
;
label
++
)
{
if
(
scores
[
label
]
>
score
)
{
score
=
scores
[
label
];
cur_label
=
label
;
}
}
if
(
score
>
threshold
)
{
const
float
*
bbox_pred
=
dis_pred
->
host
<
float
>
()
+
(
idx
*
4
*
(
reg_max
+
1
));
results
[
cur_label
].
push_back
(
disPred2Bbox
(
bbox_pred
,
cur_label
,
score
,
col
,
row
,
stride
));
}
}
}
BoxInfo
PicoDet
::
disPred2Bbox
(
const
float
*&
dfl_det
,
int
label
,
float
score
,
int
x
,
int
y
,
int
stride
)
{
float
ct_x
=
(
x
+
0.5
)
*
stride
;
float
ct_y
=
(
y
+
0.5
)
*
stride
;
std
::
vector
<
float
>
dis_pred
;
dis_pred
.
resize
(
4
);
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
float
dis
=
0
;
float
*
dis_after_sm
=
new
float
[
reg_max
+
1
];
activation_function_softmax
(
dfl_det
+
i
*
(
reg_max
+
1
),
dis_after_sm
,
reg_max
+
1
);
for
(
int
j
=
0
;
j
<
reg_max
+
1
;
j
++
)
{
dis
+=
j
*
dis_after_sm
[
j
];
}
dis
*=
stride
;
dis_pred
[
i
]
=
dis
;
delete
[]
dis_after_sm
;
BoxInfo
PicoDet
::
disPred2Bbox
(
const
float
*&
dfl_det
,
int
label
,
float
score
,
int
x
,
int
y
,
int
stride
)
{
float
ct_x
=
(
x
+
0.5
)
*
stride
;
float
ct_y
=
(
y
+
0.5
)
*
stride
;
std
::
vector
<
float
>
dis_pred
;
dis_pred
.
resize
(
4
);
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
float
dis
=
0
;
float
*
dis_after_sm
=
new
float
[
reg_max
+
1
];
activation_function_softmax
(
dfl_det
+
i
*
(
reg_max
+
1
),
dis_after_sm
,
reg_max
+
1
);
for
(
int
j
=
0
;
j
<
reg_max
+
1
;
j
++
)
{
dis
+=
j
*
dis_after_sm
[
j
];
}
float
xmin
=
(
std
::
max
)(
ct_x
-
dis_pred
[
0
],
.0
f
);
float
ymin
=
(
std
::
max
)(
ct_y
-
dis_pred
[
1
],
.0
f
);
float
xmax
=
(
std
::
min
)(
ct_x
+
dis_pred
[
2
],
(
float
)
in_w
);
float
ymax
=
(
std
::
min
)(
ct_y
+
dis_pred
[
3
],
(
float
)
in_h
);
return
BoxInfo
{
xmin
,
ymin
,
xmax
,
ymax
,
score
,
label
};
dis
*=
stride
;
dis_pred
[
i
]
=
dis
;
delete
[]
dis_after_sm
;
}
float
xmin
=
(
std
::
max
)(
ct_x
-
dis_pred
[
0
],
.0
f
);
float
ymin
=
(
std
::
max
)(
ct_y
-
dis_pred
[
1
],
.0
f
);
float
xmax
=
(
std
::
min
)(
ct_x
+
dis_pred
[
2
],
(
float
)
in_w
);
float
ymax
=
(
std
::
min
)(
ct_y
+
dis_pred
[
3
],
(
float
)
in_h
);
return
BoxInfo
{
xmin
,
ymin
,
xmax
,
ymax
,
score
,
label
};
}
void
PicoDet
::
nms
(
std
::
vector
<
BoxInfo
>
&
input_boxes
,
float
NMS_THRESH
)
{
std
::
sort
(
input_boxes
.
begin
(),
input_boxes
.
end
(),
[](
BoxInfo
a
,
BoxInfo
b
)
{
return
a
.
score
>
b
.
score
;
});
std
::
vector
<
float
>
vArea
(
input_boxes
.
size
());
for
(
int
i
=
0
;
i
<
int
(
input_boxes
.
size
());
++
i
)
{
vArea
[
i
]
=
(
input_boxes
.
at
(
i
).
x2
-
input_boxes
.
at
(
i
).
x1
+
1
)
*
(
input_boxes
.
at
(
i
).
y2
-
input_boxes
.
at
(
i
).
y1
+
1
);
}
for
(
int
i
=
0
;
i
<
int
(
input_boxes
.
size
());
++
i
)
{
for
(
int
j
=
i
+
1
;
j
<
int
(
input_boxes
.
size
());)
{
float
xx1
=
(
std
::
max
)(
input_boxes
[
i
].
x1
,
input_boxes
[
j
].
x1
);
float
yy1
=
(
std
::
max
)(
input_boxes
[
i
].
y1
,
input_boxes
[
j
].
y1
);
float
xx2
=
(
std
::
min
)(
input_boxes
[
i
].
x2
,
input_boxes
[
j
].
x2
);
float
yy2
=
(
std
::
min
)(
input_boxes
[
i
].
y2
,
input_boxes
[
j
].
y2
);
float
w
=
(
std
::
max
)(
float
(
0
),
xx2
-
xx1
+
1
);
float
h
=
(
std
::
max
)(
float
(
0
),
yy2
-
yy1
+
1
);
float
inter
=
w
*
h
;
float
ovr
=
inter
/
(
vArea
[
i
]
+
vArea
[
j
]
-
inter
);
if
(
ovr
>=
NMS_THRESH
)
{
input_boxes
.
erase
(
input_boxes
.
begin
()
+
j
);
vArea
.
erase
(
vArea
.
begin
()
+
j
);
}
else
{
j
++
;
}
}
void
PicoDet
::
nms
(
std
::
vector
<
BoxInfo
>
&
input_boxes
,
float
NMS_THRESH
)
{
std
::
sort
(
input_boxes
.
begin
(),
input_boxes
.
end
(),
[](
BoxInfo
a
,
BoxInfo
b
)
{
return
a
.
score
>
b
.
score
;
});
std
::
vector
<
float
>
vArea
(
input_boxes
.
size
());
for
(
int
i
=
0
;
i
<
int
(
input_boxes
.
size
());
++
i
)
{
vArea
[
i
]
=
(
input_boxes
.
at
(
i
).
x2
-
input_boxes
.
at
(
i
).
x1
+
1
)
*
(
input_boxes
.
at
(
i
).
y2
-
input_boxes
.
at
(
i
).
y1
+
1
);
}
for
(
int
i
=
0
;
i
<
int
(
input_boxes
.
size
());
++
i
)
{
for
(
int
j
=
i
+
1
;
j
<
int
(
input_boxes
.
size
());)
{
float
xx1
=
(
std
::
max
)(
input_boxes
[
i
].
x1
,
input_boxes
[
j
].
x1
);
float
yy1
=
(
std
::
max
)(
input_boxes
[
i
].
y1
,
input_boxes
[
j
].
y1
);
float
xx2
=
(
std
::
min
)(
input_boxes
[
i
].
x2
,
input_boxes
[
j
].
x2
);
float
yy2
=
(
std
::
min
)(
input_boxes
[
i
].
y2
,
input_boxes
[
j
].
y2
);
float
w
=
(
std
::
max
)(
float
(
0
),
xx2
-
xx1
+
1
);
float
h
=
(
std
::
max
)(
float
(
0
),
yy2
-
yy1
+
1
);
float
inter
=
w
*
h
;
float
ovr
=
inter
/
(
vArea
[
i
]
+
vArea
[
j
]
-
inter
);
if
(
ovr
>=
NMS_THRESH
)
{
input_boxes
.
erase
(
input_boxes
.
begin
()
+
j
);
vArea
.
erase
(
vArea
.
begin
()
+
j
);
}
else
{
j
++
;
}
}
}
}
string
PicoDet
::
get_label_str
(
int
label
)
{
return
labels
[
label
];
}
string
PicoDet
::
get_label_str
(
int
label
)
{
return
labels
[
label
];
}
inline
float
fast_exp
(
float
x
)
{
union
{
uint32_t
i
;
float
f
;
}
v
{};
v
.
i
=
(
1
<<
23
)
*
(
1.4426950409
*
x
+
126.93490512
f
);
return
v
.
f
;
inline
float
fast_exp
(
float
x
)
{
union
{
uint32_t
i
;
float
f
;
}
v
{};
v
.
i
=
(
1
<<
23
)
*
(
1.4426950409
*
x
+
126.93490512
f
);
return
v
.
f
;
}
inline
float
sigmoid
(
float
x
)
{
return
1.0
f
/
(
1.0
f
+
fast_exp
(
-
x
));
}
inline
float
sigmoid
(
float
x
)
{
return
1.0
f
/
(
1.0
f
+
fast_exp
(
-
x
));
}
template
<
typename
_Tp
>
int
activation_function_softmax
(
const
_Tp
*
src
,
_Tp
*
dst
,
int
length
)
{
const
_Tp
alpha
=
*
std
::
max_element
(
src
,
src
+
length
);
_Tp
denominator
{
0
};
for
(
int
i
=
0
;
i
<
length
;
++
i
)
{
dst
[
i
]
=
fast_exp
(
src
[
i
]
-
alpha
);
denominator
+=
dst
[
i
];
}
int
activation_function_softmax
(
const
_Tp
*
src
,
_Tp
*
dst
,
int
length
)
{
const
_Tp
alpha
=
*
std
::
max_element
(
src
,
src
+
length
);
_Tp
denominator
{
0
};
for
(
int
i
=
0
;
i
<
length
;
++
i
)
{
dst
[
i
]
/=
denominator
;
}
for
(
int
i
=
0
;
i
<
length
;
++
i
)
{
dst
[
i
]
=
fast_exp
(
src
[
i
]
-
alpha
);
denominator
+=
dst
[
i
];
}
for
(
int
i
=
0
;
i
<
length
;
++
i
)
{
dst
[
i
]
/=
denominator
;
}
return
0
;
return
0
;
}
deploy/third_engine/demo_ncnn/picodet.cpp
浏览文件 @
2580dc01
...
...
@@ -17,186 +17,169 @@
#include <benchmark.h>
#include <iostream>
inline
float
fast_exp
(
float
x
)
{
union
{
uint32_t
i
;
float
f
;
}
v
{};
v
.
i
=
(
1
<<
23
)
*
(
1.4426950409
*
x
+
126.93490512
f
);
return
v
.
f
;
inline
float
fast_exp
(
float
x
)
{
union
{
uint32_t
i
;
float
f
;
}
v
{};
v
.
i
=
(
1
<<
23
)
*
(
1.4426950409
*
x
+
126.93490512
f
);
return
v
.
f
;
}
inline
float
sigmoid
(
float
x
)
{
return
1.0
f
/
(
1.0
f
+
fast_exp
(
-
x
));
}
inline
float
sigmoid
(
float
x
)
{
return
1.0
f
/
(
1.0
f
+
fast_exp
(
-
x
));
}
template
<
typename
_Tp
>
int
activation_function_softmax
(
const
_Tp
*
src
,
_Tp
*
dst
,
int
length
)
{
const
_Tp
alpha
=
*
std
::
max_element
(
src
,
src
+
length
);
_Tp
denominator
{
0
};
template
<
typename
_Tp
>
int
activation_function_softmax
(
const
_Tp
*
src
,
_Tp
*
dst
,
int
length
)
{
const
_Tp
alpha
=
*
std
::
max_element
(
src
,
src
+
length
);
_Tp
denominator
{
0
};
for
(
int
i
=
0
;
i
<
length
;
++
i
)
{
dst
[
i
]
=
fast_exp
(
src
[
i
]
-
alpha
);
denominator
+=
dst
[
i
];
}
for
(
int
i
=
0
;
i
<
length
;
++
i
)
{
dst
[
i
]
=
fast_exp
(
src
[
i
]
-
alpha
);
denominator
+=
dst
[
i
];
}
for
(
int
i
=
0
;
i
<
length
;
++
i
)
{
dst
[
i
]
/=
denominator
;
}
for
(
int
i
=
0
;
i
<
length
;
++
i
)
{
dst
[
i
]
/=
denominator
;
}
return
0
;
return
0
;
}
bool
PicoDet
::
hasGPU
=
false
;
PicoDet
*
PicoDet
::
detector
=
nullptr
;
PicoDet
*
PicoDet
::
detector
=
nullptr
;
PicoDet
::
PicoDet
(
const
char
*
param
,
const
char
*
bin
,
bool
useGPU
)
{
this
->
Net
=
new
ncnn
::
Net
();
PicoDet
::
PicoDet
(
const
char
*
param
,
const
char
*
bin
,
bool
useGPU
)
{
this
->
Net
=
new
ncnn
::
Net
();
#if NCNN_VULKAN
this
->
hasGPU
=
ncnn
::
get_gpu_count
()
>
0
;
this
->
hasGPU
=
ncnn
::
get_gpu_count
()
>
0
;
#endif
this
->
Net
->
opt
.
use_vulkan_compute
=
this
->
hasGPU
&&
useGPU
;
this
->
Net
->
opt
.
use_fp16_arithmetic
=
true
;
this
->
Net
->
load_param
(
param
);
this
->
Net
->
load_model
(
bin
);
this
->
Net
->
opt
.
use_vulkan_compute
=
this
->
hasGPU
&&
useGPU
;
this
->
Net
->
opt
.
use_fp16_arithmetic
=
true
;
this
->
Net
->
load_param
(
param
);
this
->
Net
->
load_model
(
bin
);
}
PicoDet
::~
PicoDet
()
{
delete
this
->
Net
;
}
PicoDet
::~
PicoDet
()
{
delete
this
->
Net
;
}
void
PicoDet
::
preprocess
(
cv
::
Mat
&
image
,
ncnn
::
Mat
&
in
)
{
int
img_w
=
image
.
cols
;
int
img_h
=
image
.
rows
;
in
=
ncnn
::
Mat
::
from_pixels
(
image
.
data
,
ncnn
::
Mat
::
PIXEL_BGR
,
img_w
,
img_h
);
const
float
mean_vals
[
3
]
=
{
103.53
f
,
116.28
f
,
123.675
f
};
const
float
norm_vals
[
3
]
=
{
0.017429
f
,
0.017507
f
,
0.017125
f
};
in
.
substract_mean_normalize
(
mean_vals
,
norm_vals
);
void
PicoDet
::
preprocess
(
cv
::
Mat
&
image
,
ncnn
::
Mat
&
in
)
{
int
img_w
=
image
.
cols
;
int
img_h
=
image
.
rows
;
in
=
ncnn
::
Mat
::
from_pixels
(
image
.
data
,
ncnn
::
Mat
::
PIXEL_BGR
,
img_w
,
img_h
);
const
float
mean_vals
[
3
]
=
{
103.53
f
,
116.28
f
,
123.675
f
};
const
float
norm_vals
[
3
]
=
{
0.017429
f
,
0.017507
f
,
0.017125
f
};
in
.
substract_mean_normalize
(
mean_vals
,
norm_vals
);
}
std
::
vector
<
BoxInfo
>
PicoDet
::
detect
(
cv
::
Mat
image
,
float
score_threshold
,
float
nms_threshold
)
{
ncnn
::
Mat
input
;
preprocess
(
image
,
input
);
auto
ex
=
this
->
Net
->
create_extractor
();
ex
.
set_light_mode
(
false
);
ex
.
set_num_threads
(
4
);
std
::
vector
<
BoxInfo
>
PicoDet
::
detect
(
cv
::
Mat
image
,
float
score_threshold
,
float
nms_threshold
)
{
ncnn
::
Mat
input
;
preprocess
(
image
,
input
);
auto
ex
=
this
->
Net
->
create_extractor
();
ex
.
set_light_mode
(
false
);
ex
.
set_num_threads
(
4
);
#if NCNN_VULKAN
ex
.
set_vulkan_compute
(
this
->
hasGPU
);
ex
.
set_vulkan_compute
(
this
->
hasGPU
);
#endif
ex
.
input
(
"image"
,
input
);
//picodet
std
::
vector
<
std
::
vector
<
BoxInfo
>>
results
;
results
.
resize
(
this
->
num_class
);
for
(
const
auto
&
head_info
:
this
->
heads_info
)
{
ncnn
::
Mat
dis_pred
;
ncnn
::
Mat
cls_pred
;
ex
.
extract
(
head_info
.
dis_layer
.
c_str
(),
dis_pred
);
ex
.
extract
(
head_info
.
cls_layer
.
c_str
(),
cls_pred
);
this
->
decode_infer
(
cls_pred
,
dis_pred
,
head_info
.
stride
,
score_threshold
,
results
);
}
std
::
vector
<
BoxInfo
>
dets
;
for
(
int
i
=
0
;
i
<
(
int
)
results
.
size
();
i
++
)
{
this
->
nms
(
results
[
i
],
nms_threshold
);
for
(
auto
box
:
results
[
i
])
{
dets
.
push_back
(
box
);
}
ex
.
input
(
"image"
,
input
);
// picodet
std
::
vector
<
std
::
vector
<
BoxInfo
>>
results
;
results
.
resize
(
this
->
num_class
);
for
(
const
auto
&
head_info
:
this
->
heads_info
)
{
ncnn
::
Mat
dis_pred
;
ncnn
::
Mat
cls_pred
;
ex
.
extract
(
head_info
.
dis_layer
.
c_str
(),
dis_pred
);
ex
.
extract
(
head_info
.
cls_layer
.
c_str
(),
cls_pred
);
this
->
decode_infer
(
cls_pred
,
dis_pred
,
head_info
.
stride
,
score_threshold
,
results
);
}
std
::
vector
<
BoxInfo
>
dets
;
for
(
int
i
=
0
;
i
<
(
int
)
results
.
size
();
i
++
)
{
this
->
nms
(
results
[
i
],
nms_threshold
);
for
(
auto
box
:
results
[
i
])
{
dets
.
push_back
(
box
);
}
return
dets
;
}
return
dets
;
}
void
PicoDet
::
decode_infer
(
ncnn
::
Mat
&
cls_pred
,
ncnn
::
Mat
&
dis_pred
,
int
stride
,
float
threshold
,
std
::
vector
<
std
::
vector
<
BoxInfo
>>&
results
)
{
int
feature_h
=
this
->
input_size
[
1
]
/
stride
;
int
feature_w
=
this
->
input_size
[
0
]
/
stride
;
for
(
int
idx
=
0
;
idx
<
feature_h
*
feature_w
;
idx
++
)
{
const
float
*
scores
=
cls_pred
.
row
(
idx
);
int
row
=
idx
/
feature_w
;
int
col
=
idx
%
feature_w
;
float
score
=
0
;
int
cur_label
=
0
;
for
(
int
label
=
0
;
label
<
this
->
num_class
;
label
++
)
{
if
(
scores
[
label
]
>
score
)
{
score
=
scores
[
label
];
cur_label
=
label
;
}
}
if
(
score
>
threshold
)
{
const
float
*
bbox_pred
=
dis_pred
.
row
(
idx
);
results
[
cur_label
].
push_back
(
this
->
disPred2Bbox
(
bbox_pred
,
cur_label
,
score
,
col
,
row
,
stride
));
}
void
PicoDet
::
decode_infer
(
ncnn
::
Mat
&
cls_pred
,
ncnn
::
Mat
&
dis_pred
,
int
stride
,
float
threshold
,
std
::
vector
<
std
::
vector
<
BoxInfo
>>
&
results
)
{
int
feature_h
=
ceil
((
float
)
this
->
input_size
[
1
]
/
stride
);
int
feature_w
=
ceil
((
float
)
this
->
input_size
[
0
]
/
stride
);
for
(
int
idx
=
0
;
idx
<
feature_h
*
feature_w
;
idx
++
)
{
const
float
*
scores
=
cls_pred
.
row
(
idx
);
int
row
=
idx
/
feature_w
;
int
col
=
idx
%
feature_w
;
float
score
=
0
;
int
cur_label
=
0
;
for
(
int
label
=
0
;
label
<
this
->
num_class
;
label
++
)
{
if
(
scores
[
label
]
>
score
)
{
score
=
scores
[
label
];
cur_label
=
label
;
}
}
if
(
score
>
threshold
)
{
const
float
*
bbox_pred
=
dis_pred
.
row
(
idx
);
results
[
cur_label
].
push_back
(
this
->
disPred2Bbox
(
bbox_pred
,
cur_label
,
score
,
col
,
row
,
stride
));
}
}
}
BoxInfo
PicoDet
::
disPred2Bbox
(
const
float
*&
dfl_det
,
int
label
,
float
score
,
int
x
,
int
y
,
int
stride
)
{
float
ct_x
=
(
x
+
0.5
)
*
stride
;
float
ct_y
=
(
y
+
0.5
)
*
stride
;
std
::
vector
<
float
>
dis_pred
;
dis_pred
.
resize
(
4
);
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
float
dis
=
0
;
float
*
dis_after_sm
=
new
float
[
this
->
reg_max
+
1
];
activation_function_softmax
(
dfl_det
+
i
*
(
this
->
reg_max
+
1
),
dis_after_sm
,
this
->
reg_max
+
1
);
for
(
int
j
=
0
;
j
<
this
->
reg_max
+
1
;
j
++
)
{
dis
+=
j
*
dis_after_sm
[
j
];
}
dis
*=
stride
;
dis_pred
[
i
]
=
dis
;
delete
[]
dis_after_sm
;
BoxInfo
PicoDet
::
disPred2Bbox
(
const
float
*&
dfl_det
,
int
label
,
float
score
,
int
x
,
int
y
,
int
stride
)
{
float
ct_x
=
(
x
+
0.5
)
*
stride
;
float
ct_y
=
(
y
+
0.5
)
*
stride
;
std
::
vector
<
float
>
dis_pred
;
dis_pred
.
resize
(
4
);
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
float
dis
=
0
;
float
*
dis_after_sm
=
new
float
[
this
->
reg_max
+
1
];
activation_function_softmax
(
dfl_det
+
i
*
(
this
->
reg_max
+
1
),
dis_after_sm
,
this
->
reg_max
+
1
);
for
(
int
j
=
0
;
j
<
this
->
reg_max
+
1
;
j
++
)
{
dis
+=
j
*
dis_after_sm
[
j
];
}
float
xmin
=
(
std
::
max
)(
ct_x
-
dis_pred
[
0
],
.0
f
);
float
ymin
=
(
std
::
max
)(
ct_y
-
dis_pred
[
1
],
.0
f
);
float
xmax
=
(
std
::
min
)(
ct_x
+
dis_pred
[
2
],
(
float
)
this
->
input_size
[
0
]);
float
ymax
=
(
std
::
min
)(
ct_y
+
dis_pred
[
3
],
(
float
)
this
->
input_size
[
1
]);
return
BoxInfo
{
xmin
,
ymin
,
xmax
,
ymax
,
score
,
label
};
dis
*=
stride
;
dis_pred
[
i
]
=
dis
;
delete
[]
dis_after_sm
;
}
float
xmin
=
(
std
::
max
)(
ct_x
-
dis_pred
[
0
],
.0
f
);
float
ymin
=
(
std
::
max
)(
ct_y
-
dis_pred
[
1
],
.0
f
);
float
xmax
=
(
std
::
min
)(
ct_x
+
dis_pred
[
2
],
(
float
)
this
->
input_size
[
0
]);
float
ymax
=
(
std
::
min
)(
ct_y
+
dis_pred
[
3
],
(
float
)
this
->
input_size
[
1
]);
return
BoxInfo
{
xmin
,
ymin
,
xmax
,
ymax
,
score
,
label
};
}
void
PicoDet
::
nms
(
std
::
vector
<
BoxInfo
>&
input_boxes
,
float
NMS_THRESH
)
{
std
::
sort
(
input_boxes
.
begin
(),
input_boxes
.
end
(),
[](
BoxInfo
a
,
BoxInfo
b
)
{
return
a
.
score
>
b
.
score
;
});
std
::
vector
<
float
>
vArea
(
input_boxes
.
size
());
for
(
int
i
=
0
;
i
<
int
(
input_boxes
.
size
());
++
i
)
{
vArea
[
i
]
=
(
input_boxes
.
at
(
i
).
x2
-
input_boxes
.
at
(
i
).
x1
+
1
)
*
(
input_boxes
.
at
(
i
).
y2
-
input_boxes
.
at
(
i
).
y1
+
1
);
}
for
(
int
i
=
0
;
i
<
int
(
input_boxes
.
size
());
++
i
)
{
for
(
int
j
=
i
+
1
;
j
<
int
(
input_boxes
.
size
());)
{
float
xx1
=
(
std
::
max
)(
input_boxes
[
i
].
x1
,
input_boxes
[
j
].
x1
);
float
yy1
=
(
std
::
max
)(
input_boxes
[
i
].
y1
,
input_boxes
[
j
].
y1
);
float
xx2
=
(
std
::
min
)(
input_boxes
[
i
].
x2
,
input_boxes
[
j
].
x2
);
float
yy2
=
(
std
::
min
)(
input_boxes
[
i
].
y2
,
input_boxes
[
j
].
y2
);
float
w
=
(
std
::
max
)(
float
(
0
),
xx2
-
xx1
+
1
);
float
h
=
(
std
::
max
)(
float
(
0
),
yy2
-
yy1
+
1
);
float
inter
=
w
*
h
;
float
ovr
=
inter
/
(
vArea
[
i
]
+
vArea
[
j
]
-
inter
);
if
(
ovr
>=
NMS_THRESH
)
{
input_boxes
.
erase
(
input_boxes
.
begin
()
+
j
);
vArea
.
erase
(
vArea
.
begin
()
+
j
);
}
else
{
j
++
;
}
}
void
PicoDet
::
nms
(
std
::
vector
<
BoxInfo
>
&
input_boxes
,
float
NMS_THRESH
)
{
std
::
sort
(
input_boxes
.
begin
(),
input_boxes
.
end
(),
[](
BoxInfo
a
,
BoxInfo
b
)
{
return
a
.
score
>
b
.
score
;
});
std
::
vector
<
float
>
vArea
(
input_boxes
.
size
());
for
(
int
i
=
0
;
i
<
int
(
input_boxes
.
size
());
++
i
)
{
vArea
[
i
]
=
(
input_boxes
.
at
(
i
).
x2
-
input_boxes
.
at
(
i
).
x1
+
1
)
*
(
input_boxes
.
at
(
i
).
y2
-
input_boxes
.
at
(
i
).
y1
+
1
);
}
for
(
int
i
=
0
;
i
<
int
(
input_boxes
.
size
());
++
i
)
{
for
(
int
j
=
i
+
1
;
j
<
int
(
input_boxes
.
size
());)
{
float
xx1
=
(
std
::
max
)(
input_boxes
[
i
].
x1
,
input_boxes
[
j
].
x1
);
float
yy1
=
(
std
::
max
)(
input_boxes
[
i
].
y1
,
input_boxes
[
j
].
y1
);
float
xx2
=
(
std
::
min
)(
input_boxes
[
i
].
x2
,
input_boxes
[
j
].
x2
);
float
yy2
=
(
std
::
min
)(
input_boxes
[
i
].
y2
,
input_boxes
[
j
].
y2
);
float
w
=
(
std
::
max
)(
float
(
0
),
xx2
-
xx1
+
1
);
float
h
=
(
std
::
max
)(
float
(
0
),
yy2
-
yy1
+
1
);
float
inter
=
w
*
h
;
float
ovr
=
inter
/
(
vArea
[
i
]
+
vArea
[
j
]
-
inter
);
if
(
ovr
>=
NMS_THRESH
)
{
input_boxes
.
erase
(
input_boxes
.
begin
()
+
j
);
vArea
.
erase
(
vArea
.
begin
()
+
j
);
}
else
{
j
++
;
}
}
}
}
deploy/third_engine/demo_openvino/main.cpp
浏览文件 @
2580dc01
...
...
@@ -14,338 +14,289 @@
// reference from https://github.com/RangiLyu/nanodet
#include "picodet_openvino.h"
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#define image_size 416
struct
object_rect
{
int
x
;
int
y
;
int
width
;
int
height
;
int
x
;
int
y
;
int
width
;
int
height
;
};
int
resize_uniform
(
cv
::
Mat
&
src
,
cv
::
Mat
&
dst
,
cv
::
Size
dst_size
,
object_rect
&
effect_area
)
{
int
w
=
src
.
cols
;
int
h
=
src
.
rows
;
int
dst_w
=
dst_size
.
width
;
int
dst_h
=
dst_size
.
height
;
dst
=
cv
::
Mat
(
cv
::
Size
(
dst_w
,
dst_h
),
CV_8UC3
,
cv
::
Scalar
(
0
));
int
resize_uniform
(
cv
::
Mat
&
src
,
cv
::
Mat
&
dst
,
cv
::
Size
dst_size
,
object_rect
&
effect_area
)
{
int
w
=
src
.
cols
;
int
h
=
src
.
rows
;
int
dst_w
=
dst_size
.
width
;
int
dst_h
=
dst_size
.
height
;
dst
=
cv
::
Mat
(
cv
::
Size
(
dst_w
,
dst_h
),
CV_8UC3
,
cv
::
Scalar
(
0
));
float
ratio_src
=
w
*
1.0
/
h
;
float
ratio_dst
=
dst_w
*
1.0
/
dst_h
;
float
ratio_src
=
w
*
1.0
/
h
;
float
ratio_dst
=
dst_w
*
1.0
/
dst_h
;
int
tmp_w
=
0
;
int
tmp_h
=
0
;
if
(
ratio_src
>
ratio_dst
)
{
tmp_w
=
dst_w
;
tmp_h
=
floor
((
dst_w
*
1.0
/
w
)
*
h
);
}
else
if
(
ratio_src
<
ratio_dst
)
{
tmp_h
=
dst_h
;
tmp_w
=
floor
((
dst_h
*
1.0
/
h
)
*
w
);
}
else
{
cv
::
resize
(
src
,
dst
,
dst_size
);
effect_area
.
x
=
0
;
effect_area
.
y
=
0
;
effect_area
.
width
=
dst_w
;
effect_area
.
height
=
dst_h
;
return
0
;
}
cv
::
Mat
tmp
;
cv
::
resize
(
src
,
tmp
,
cv
::
Size
(
tmp_w
,
tmp_h
));
int
tmp_w
=
0
;
int
tmp_h
=
0
;
if
(
ratio_src
>
ratio_dst
)
{
tmp_w
=
dst_w
;
tmp_h
=
floor
((
dst_w
*
1.0
/
w
)
*
h
);
}
else
if
(
ratio_src
<
ratio_dst
)
{
tmp_h
=
dst_h
;
tmp_w
=
floor
((
dst_h
*
1.0
/
h
)
*
w
);
}
else
{
cv
::
resize
(
src
,
dst
,
dst_size
);
effect_area
.
x
=
0
;
effect_area
.
y
=
0
;
effect_area
.
width
=
dst_w
;
effect_area
.
height
=
dst_h
;
return
0
;
}
cv
::
Mat
tmp
;
cv
::
resize
(
src
,
tmp
,
cv
::
Size
(
tmp_w
,
tmp_h
));
if
(
tmp_w
!=
dst_w
)
{
int
index_w
=
floor
((
dst_w
-
tmp_w
)
/
2.0
);
for
(
int
i
=
0
;
i
<
dst_h
;
i
++
)
{
memcpy
(
dst
.
data
+
i
*
dst_w
*
3
+
index_w
*
3
,
tmp
.
data
+
i
*
tmp_w
*
3
,
tmp_w
*
3
);
}
effect_area
.
x
=
index_w
;
effect_area
.
y
=
0
;
effect_area
.
width
=
tmp_w
;
effect_area
.
height
=
tmp_h
;
if
(
tmp_w
!=
dst_w
)
{
int
index_w
=
floor
((
dst_w
-
tmp_w
)
/
2.0
);
for
(
int
i
=
0
;
i
<
dst_h
;
i
++
)
{
memcpy
(
dst
.
data
+
i
*
dst_w
*
3
+
index_w
*
3
,
tmp
.
data
+
i
*
tmp_w
*
3
,
tmp_w
*
3
);
}
else
if
(
tmp_h
!=
dst_h
)
{
int
index_h
=
floor
((
dst_h
-
tmp_h
)
/
2.0
);
memcpy
(
dst
.
data
+
index_h
*
dst_w
*
3
,
tmp
.
data
,
tmp_w
*
tmp_h
*
3
);
effect_area
.
x
=
0
;
effect_area
.
y
=
index_h
;
effect_area
.
width
=
tmp_w
;
effect_area
.
height
=
tmp_h
;
}
else
{
printf
(
"error
\n
"
);
}
return
0
;
effect_area
.
x
=
index_w
;
effect_area
.
y
=
0
;
effect_area
.
width
=
tmp_w
;
effect_area
.
height
=
tmp_h
;
}
else
if
(
tmp_h
!=
dst_h
)
{
int
index_h
=
floor
((
dst_h
-
tmp_h
)
/
2.0
);
memcpy
(
dst
.
data
+
index_h
*
dst_w
*
3
,
tmp
.
data
,
tmp_w
*
tmp_h
*
3
);
effect_area
.
x
=
0
;
effect_area
.
y
=
index_h
;
effect_area
.
width
=
tmp_w
;
effect_area
.
height
=
tmp_h
;
}
else
{
printf
(
"error
\n
"
);
}
return
0
;
}
const
int
color_list
[
80
][
3
]
=
{
{
216
,
82
,
24
},
{
236
,
176
,
31
},
{
125
,
46
,
141
},
{
118
,
171
,
47
},
{
76
,
189
,
237
},
{
238
,
19
,
46
},
{
76
,
76
,
76
},
{
153
,
153
,
153
},
{
255
,
0
,
0
},
{
255
,
127
,
0
},
{
190
,
190
,
0
},
{
0
,
255
,
0
},
{
0
,
0
,
255
},
{
170
,
0
,
255
},
{
84
,
84
,
0
},
{
84
,
170
,
0
},
{
84
,
255
,
0
},
{
170
,
84
,
0
},
{
170
,
170
,
0
},
{
170
,
255
,
0
},
{
255
,
84
,
0
},
{
255
,
170
,
0
},
{
255
,
255
,
0
},
{
0
,
84
,
127
},
{
0
,
170
,
127
},
{
0
,
255
,
127
},
{
84
,
0
,
127
},
{
84
,
84
,
127
},
{
84
,
170
,
127
},
{
84
,
255
,
127
},
{
170
,
0
,
127
},
{
170
,
84
,
127
},
{
170
,
170
,
127
},
{
170
,
255
,
127
},
{
255
,
0
,
127
},
{
255
,
84
,
127
},
{
255
,
170
,
127
},
{
255
,
255
,
127
},
{
0
,
84
,
255
},
{
0
,
170
,
255
},
{
0
,
255
,
255
},
{
84
,
0
,
255
},
{
84
,
84
,
255
},
{
84
,
170
,
255
},
{
84
,
255
,
255
},
{
170
,
0
,
255
},
{
170
,
84
,
255
},
{
170
,
170
,
255
},
{
170
,
255
,
255
},
{
255
,
0
,
255
},
{
255
,
84
,
255
},
{
255
,
170
,
255
},
{
42
,
0
,
0
},
{
84
,
0
,
0
},
{
127
,
0
,
0
},
{
170
,
0
,
0
},
{
212
,
0
,
0
},
{
255
,
0
,
0
},
{
0
,
42
,
0
},
{
0
,
84
,
0
},
{
0
,
127
,
0
},
{
0
,
170
,
0
},
{
0
,
212
,
0
},
{
0
,
255
,
0
},
{
0
,
0
,
42
},
{
0
,
0
,
84
},
{
0
,
0
,
127
},
{
0
,
0
,
170
},
{
0
,
0
,
212
},
{
0
,
0
,
255
},
{
0
,
0
,
0
},
{
36
,
36
,
36
},
{
72
,
72
,
72
},
{
109
,
109
,
109
},
{
145
,
145
,
145
},
{
182
,
182
,
182
},
{
218
,
218
,
218
},
{
0
,
113
,
188
},
{
80
,
182
,
188
},
{
127
,
127
,
0
},
const
int
color_list
[
80
][
3
]
=
{
{
216
,
82
,
24
},
{
236
,
176
,
31
},
{
125
,
46
,
141
},
{
118
,
171
,
47
},
{
76
,
189
,
237
},
{
238
,
19
,
46
},
{
76
,
76
,
76
},
{
153
,
153
,
153
},
{
255
,
0
,
0
},
{
255
,
127
,
0
},
{
190
,
190
,
0
},
{
0
,
255
,
0
},
{
0
,
0
,
255
},
{
170
,
0
,
255
},
{
84
,
84
,
0
},
{
84
,
170
,
0
},
{
84
,
255
,
0
},
{
170
,
84
,
0
},
{
170
,
170
,
0
},
{
170
,
255
,
0
},
{
255
,
84
,
0
},
{
255
,
170
,
0
},
{
255
,
255
,
0
},
{
0
,
84
,
127
},
{
0
,
170
,
127
},
{
0
,
255
,
127
},
{
84
,
0
,
127
},
{
84
,
84
,
127
},
{
84
,
170
,
127
},
{
84
,
255
,
127
},
{
170
,
0
,
127
},
{
170
,
84
,
127
},
{
170
,
170
,
127
},
{
170
,
255
,
127
},
{
255
,
0
,
127
},
{
255
,
84
,
127
},
{
255
,
170
,
127
},
{
255
,
255
,
127
},
{
0
,
84
,
255
},
{
0
,
170
,
255
},
{
0
,
255
,
255
},
{
84
,
0
,
255
},
{
84
,
84
,
255
},
{
84
,
170
,
255
},
{
84
,
255
,
255
},
{
170
,
0
,
255
},
{
170
,
84
,
255
},
{
170
,
170
,
255
},
{
170
,
255
,
255
},
{
255
,
0
,
255
},
{
255
,
84
,
255
},
{
255
,
170
,
255
},
{
42
,
0
,
0
},
{
84
,
0
,
0
},
{
127
,
0
,
0
},
{
170
,
0
,
0
},
{
212
,
0
,
0
},
{
255
,
0
,
0
},
{
0
,
42
,
0
},
{
0
,
84
,
0
},
{
0
,
127
,
0
},
{
0
,
170
,
0
},
{
0
,
212
,
0
},
{
0
,
255
,
0
},
{
0
,
0
,
42
},
{
0
,
0
,
84
},
{
0
,
0
,
127
},
{
0
,
0
,
170
},
{
0
,
0
,
212
},
{
0
,
0
,
255
},
{
0
,
0
,
0
},
{
36
,
36
,
36
},
{
72
,
72
,
72
},
{
109
,
109
,
109
},
{
145
,
145
,
145
},
{
182
,
182
,
182
},
{
218
,
218
,
218
},
{
0
,
113
,
188
},
{
80
,
182
,
188
},
{
127
,
127
,
0
},
};
void
draw_bboxes
(
const
cv
::
Mat
&
bgr
,
const
std
::
vector
<
BoxInfo
>&
bboxes
,
object_rect
effect_roi
)
{
static
const
char
*
class_names
[]
=
{
"person"
,
"bicycle"
,
"car"
,
"motorcycle"
,
"airplane"
,
"bus"
,
"train"
,
"truck"
,
"boat"
,
"traffic light"
,
"fire hydrant"
,
"stop sign"
,
"parking meter"
,
"bench"
,
"bird"
,
"cat"
,
"dog"
,
"horse"
,
"sheep"
,
"cow"
,
"elephant"
,
"bear"
,
"zebra"
,
"giraffe"
,
"backpack"
,
"umbrella"
,
"handbag"
,
"tie"
,
"suitcase"
,
"frisbee"
,
"skis"
,
"snowboard"
,
"sports ball"
,
"kite"
,
"baseball bat"
,
"baseball glove"
,
"skateboard"
,
"surfboard"
,
"tennis racket"
,
"bottle"
,
"wine glass"
,
"cup"
,
"fork"
,
"knife"
,
"spoon"
,
"bowl"
,
"banana"
,
"apple"
,
"sandwich"
,
"orange"
,
"broccoli"
,
"carrot"
,
"hot dog"
,
"pizza"
,
"donut"
,
"cake"
,
"chair"
,
"couch"
,
"potted plant"
,
"bed"
,
"dining table"
,
"toilet"
,
"tv"
,
"laptop"
,
"mouse"
,
"remote"
,
"keyboard"
,
"cell phone"
,
"microwave"
,
"oven"
,
"toaster"
,
"sink"
,
"refrigerator"
,
"book"
,
"clock"
,
"vase"
,
"scissors"
,
"teddy bear"
,
"hair drier"
,
"toothbrush"
};
void
draw_bboxes
(
const
cv
::
Mat
&
bgr
,
const
std
::
vector
<
BoxInfo
>
&
bboxes
,
object_rect
effect_roi
)
{
static
const
char
*
class_names
[]
=
{
"person"
,
"bicycle"
,
"car"
,
"motorcycle"
,
"airplane"
,
"bus"
,
"train"
,
"truck"
,
"boat"
,
"traffic light"
,
"fire hydrant"
,
"stop sign"
,
"parking meter"
,
"bench"
,
"bird"
,
"cat"
,
"dog"
,
"horse"
,
"sheep"
,
"cow"
,
"elephant"
,
"bear"
,
"zebra"
,
"giraffe"
,
"backpack"
,
"umbrella"
,
"handbag"
,
"tie"
,
"suitcase"
,
"frisbee"
,
"skis"
,
"snowboard"
,
"sports ball"
,
"kite"
,
"baseball bat"
,
"baseball glove"
,
"skateboard"
,
"surfboard"
,
"tennis racket"
,
"bottle"
,
"wine glass"
,
"cup"
,
"fork"
,
"knife"
,
"spoon"
,
"bowl"
,
"banana"
,
"apple"
,
"sandwich"
,
"orange"
,
"broccoli"
,
"carrot"
,
"hot dog"
,
"pizza"
,
"donut"
,
"cake"
,
"chair"
,
"couch"
,
"potted plant"
,
"bed"
,
"dining table"
,
"toilet"
,
"tv"
,
"laptop"
,
"mouse"
,
"remote"
,
"keyboard"
,
"cell phone"
,
"microwave"
,
"oven"
,
"toaster"
,
"sink"
,
"refrigerator"
,
"book"
,
"clock"
,
"vase"
,
"scissors"
,
"teddy bear"
,
"hair drier"
,
"toothbrush"
};
cv
::
Mat
image
=
bgr
.
clone
();
int
src_w
=
image
.
cols
;
int
src_h
=
image
.
rows
;
int
dst_w
=
effect_roi
.
width
;
int
dst_h
=
effect_roi
.
height
;
float
width_ratio
=
(
float
)
src_w
/
(
float
)
dst_w
;
float
height_ratio
=
(
float
)
src_h
/
(
float
)
dst_h
;
cv
::
Mat
image
=
bgr
.
clone
();
int
src_w
=
image
.
cols
;
int
src_h
=
image
.
rows
;
int
dst_w
=
effect_roi
.
width
;
int
dst_h
=
effect_roi
.
height
;
float
width_ratio
=
(
float
)
src_w
/
(
float
)
dst_w
;
float
height_ratio
=
(
float
)
src_h
/
(
float
)
dst_h
;
for
(
size_t
i
=
0
;
i
<
bboxes
.
size
();
i
++
)
{
const
BoxInfo
&
bbox
=
bboxes
[
i
];
cv
::
Scalar
color
=
cv
::
Scalar
(
color_list
[
bbox
.
label
][
0
],
color_list
[
bbox
.
label
][
1
],
color_list
[
bbox
.
label
][
2
]);
cv
::
rectangle
(
image
,
cv
::
Rect
(
cv
::
Point
((
bbox
.
x1
-
effect_roi
.
x
)
*
width_ratio
,
(
bbox
.
y1
-
effect_roi
.
y
)
*
height_ratio
),
cv
::
Point
((
bbox
.
x2
-
effect_roi
.
x
)
*
width_ratio
,
(
bbox
.
y2
-
effect_roi
.
y
)
*
height_ratio
)),
color
);
for
(
size_t
i
=
0
;
i
<
bboxes
.
size
();
i
++
)
{
const
BoxInfo
&
bbox
=
bboxes
[
i
];
cv
::
Scalar
color
=
cv
::
Scalar
(
color_list
[
bbox
.
label
][
0
],
color_list
[
bbox
.
label
][
1
],
color_list
[
bbox
.
label
][
2
]);
cv
::
rectangle
(
image
,
cv
::
Rect
(
cv
::
Point
((
bbox
.
x1
-
effect_roi
.
x
)
*
width_ratio
,
(
bbox
.
y1
-
effect_roi
.
y
)
*
height_ratio
),
cv
::
Point
((
bbox
.
x2
-
effect_roi
.
x
)
*
width_ratio
,
(
bbox
.
y2
-
effect_roi
.
y
)
*
height_ratio
)),
color
);
char
text
[
256
];
sprintf
(
text
,
"%s %.1f%%"
,
class_names
[
bbox
.
label
],
bbox
.
score
*
100
);
int
baseLine
=
0
;
cv
::
Size
label_size
=
cv
::
getTextSize
(
text
,
cv
::
FONT_HERSHEY_SIMPLEX
,
0.4
,
1
,
&
baseLine
);
int
x
=
(
bbox
.
x1
-
effect_roi
.
x
)
*
width_ratio
;
int
y
=
(
bbox
.
y1
-
effect_roi
.
y
)
*
height_ratio
-
label_size
.
height
-
baseLine
;
if
(
y
<
0
)
y
=
0
;
if
(
x
+
label_size
.
width
>
image
.
cols
)
x
=
image
.
cols
-
label_size
.
width
;
char
text
[
256
];
sprintf
(
text
,
"%s %.1f%%"
,
class_names
[
bbox
.
label
],
bbox
.
score
*
100
);
int
baseLine
=
0
;
cv
::
Size
label_size
=
cv
::
getTextSize
(
text
,
cv
::
FONT_HERSHEY_SIMPLEX
,
0.4
,
1
,
&
baseLine
);
int
x
=
(
bbox
.
x1
-
effect_roi
.
x
)
*
width_ratio
;
int
y
=
(
bbox
.
y1
-
effect_roi
.
y
)
*
height_ratio
-
label_size
.
height
-
baseLine
;
if
(
y
<
0
)
y
=
0
;
if
(
x
+
label_size
.
width
>
image
.
cols
)
x
=
image
.
cols
-
label_size
.
width
;
cv
::
rectangle
(
image
,
cv
::
Rect
(
cv
::
Point
(
x
,
y
),
cv
::
Size
(
label_size
.
width
,
label_size
.
height
+
baseLine
)),
color
,
-
1
);
cv
::
putText
(
image
,
text
,
cv
::
Point
(
x
,
y
+
label_size
.
height
),
cv
::
FONT_HERSHEY_SIMPLEX
,
0.4
,
cv
::
Scalar
(
255
,
255
,
255
));
}
cv
::
rectangle
(
image
,
cv
::
Rect
(
cv
::
Point
(
x
,
y
),
cv
::
Size
(
label_size
.
width
,
label_size
.
height
+
baseLine
)),
color
,
-
1
);
cv
::
putText
(
image
,
text
,
cv
::
Point
(
x
,
y
+
label_size
.
height
),
cv
::
FONT_HERSHEY_SIMPLEX
,
0.4
,
cv
::
Scalar
(
255
,
255
,
255
));
}
cv
::
imwrite
(
"../predict.jpg"
,
image
);
cv
::
imwrite
(
"../predict.jpg"
,
image
);
}
int
image_demo
(
PicoDet
&
detector
,
const
char
*
imagepath
)
{
std
::
vector
<
std
::
string
>
filenames
;
cv
::
glob
(
imagepath
,
filenames
,
false
);
int
image_demo
(
PicoDet
&
detector
,
const
char
*
imagepath
)
{
std
::
vector
<
std
::
string
>
filenames
;
cv
::
glob
(
imagepath
,
filenames
,
false
);
for
(
auto
img_name
:
filenames
)
{
cv
::
Mat
image
=
cv
::
imread
(
img_name
);
if
(
image
.
empty
())
{
return
-
1
;
}
object_rect
effect_roi
;
cv
::
Mat
resized_img
;
resize_uniform
(
image
,
resized_img
,
cv
::
Size
(
image_size
,
image_size
),
effect_roi
);
auto
results
=
detector
.
detect
(
resized_img
,
0.4
,
0.5
);
draw_bboxes
(
image
,
results
,
effect_roi
);
for
(
auto
img_name
:
filenames
)
{
cv
::
Mat
image
=
cv
::
imread
(
img_name
);
if
(
image
.
empty
())
{
return
-
1
;
}
return
0
;
object_rect
effect_roi
;
cv
::
Mat
resized_img
;
resize_uniform
(
image
,
resized_img
,
cv
::
Size
(
image_size
,
image_size
),
effect_roi
);
auto
results
=
detector
.
detect
(
resized_img
,
0.4
,
0.5
);
draw_bboxes
(
image
,
results
,
effect_roi
);
}
return
0
;
}
int
webcam_demo
(
PicoDet
&
detector
,
int
cam_id
)
{
cv
::
Mat
image
;
cv
::
VideoCapture
cap
(
cam_id
);
while
(
true
)
{
cap
>>
image
;
object_rect
effect_roi
;
cv
::
Mat
resized_img
;
resize_uniform
(
image
,
resized_img
,
cv
::
Size
(
image_size
,
image_size
),
effect_roi
);
auto
results
=
detector
.
detect
(
resized_img
,
0.4
,
0.5
);
draw_bboxes
(
image
,
results
,
effect_roi
);
cv
::
waitKey
(
1
);
}
return
0
;
int
webcam_demo
(
PicoDet
&
detector
,
int
cam_id
)
{
cv
::
Mat
image
;
cv
::
VideoCapture
cap
(
cam_id
);
while
(
true
)
{
cap
>>
image
;
object_rect
effect_roi
;
cv
::
Mat
resized_img
;
resize_uniform
(
image
,
resized_img
,
cv
::
Size
(
image_size
,
image_size
),
effect_roi
);
auto
results
=
detector
.
detect
(
resized_img
,
0.4
,
0.5
);
draw_bboxes
(
image
,
results
,
effect_roi
);
cv
::
waitKey
(
1
);
}
return
0
;
}
int
video_demo
(
PicoDet
&
detector
,
const
char
*
path
)
{
cv
::
Mat
image
;
cv
::
VideoCapture
cap
(
path
);
int
video_demo
(
PicoDet
&
detector
,
const
char
*
path
)
{
cv
::
Mat
image
;
cv
::
VideoCapture
cap
(
path
);
while
(
true
)
{
cap
>>
image
;
object_rect
effect_roi
;
cv
::
Mat
resized_img
;
resize_uniform
(
image
,
resized_img
,
cv
::
Size
(
image_size
,
image_size
),
effect_roi
);
auto
results
=
detector
.
detect
(
resized_img
,
0.4
,
0.5
);
draw_bboxes
(
image
,
results
,
effect_roi
);
cv
::
waitKey
(
1
);
}
return
0
;
while
(
true
)
{
cap
>>
image
;
object_rect
effect_roi
;
cv
::
Mat
resized_img
;
resize_uniform
(
image
,
resized_img
,
cv
::
Size
(
image_size
,
image_size
),
effect_roi
);
auto
results
=
detector
.
detect
(
resized_img
,
0.4
,
0.5
);
draw_bboxes
(
image
,
results
,
effect_roi
);
cv
::
waitKey
(
1
);
}
return
0
;
}
int
benchmark
(
PicoDet
&
detector
)
{
int
loop_num
=
100
;
int
warm_up
=
8
;
int
benchmark
(
PicoDet
&
detector
)
{
int
loop_num
=
100
;
int
warm_up
=
8
;
double
time_min
=
DBL_MAX
;
double
time_max
=
-
DBL_MAX
;
double
time_avg
=
0
;
cv
::
Mat
image
(
image_size
,
image_size
,
CV_8UC3
,
cv
::
Scalar
(
1
,
1
,
1
));
double
time_min
=
DBL_MAX
;
double
time_max
=
-
DBL_MAX
;
double
time_avg
=
0
;
cv
::
Mat
image
(
image_size
,
image_size
,
CV_8UC3
,
cv
::
Scalar
(
1
,
1
,
1
));
for
(
int
i
=
0
;
i
<
warm_up
+
loop_num
;
i
++
)
{
auto
start
=
std
::
chrono
::
steady_clock
::
now
();
std
::
vector
<
BoxInfo
>
results
;
results
=
detector
.
detect
(
image
,
0.4
,
0.5
);
auto
end
=
std
::
chrono
::
steady_clock
::
now
();
double
time
=
std
::
chrono
::
duration
<
double
,
std
::
milli
>
(
end
-
start
).
count
();
if
(
i
>=
warm_up
)
{
time_min
=
(
std
::
min
)(
time_min
,
time
);
time_max
=
(
std
::
max
)(
time_max
,
time
);
time_avg
+=
time
;
}
for
(
int
i
=
0
;
i
<
warm_up
+
loop_num
;
i
++
)
{
auto
start
=
std
::
chrono
::
steady_clock
::
now
();
std
::
vector
<
BoxInfo
>
results
;
results
=
detector
.
detect
(
image
,
0.4
,
0.5
);
auto
end
=
std
::
chrono
::
steady_clock
::
now
();
double
time
=
std
::
chrono
::
duration
<
double
,
std
::
milli
>
(
end
-
start
).
count
();
if
(
i
>=
warm_up
)
{
time_min
=
(
std
::
min
)(
time_min
,
time
);
time_max
=
(
std
::
max
)(
time_max
,
time
);
time_avg
+=
time
;
}
time_avg
/=
loop_num
;
fprintf
(
stderr
,
"%20s min = %7.2f max = %7.2f avg = %7.2f
\n
"
,
"picodet"
,
time_min
,
time_max
,
time_avg
);
return
0
;
}
time_avg
/=
loop_num
;
fprintf
(
stderr
,
"%20s min = %7.2f max = %7.2f avg = %7.2f
\n
"
,
"picodet"
,
time_min
,
time_max
,
time_avg
);
return
0
;
}
int
main
(
int
argc
,
char
**
argv
)
{
if
(
argc
!=
3
)
{
fprintf
(
stderr
,
"usage: %s [mode] [path].
\n
For webcam mode=0, path is "
"cam id;
\n
For image demo, mode=1, path=xxx/xxx/*.jpg;
\n
"
"For video, mode=2;
\n
For benchmark, mode=3 path=0.
\n
"
,
argv
[
0
]);
return
-
1
;
}
std
::
cout
<<
"start init model"
<<
std
::
endl
;
auto
detector
=
PicoDet
(
"../weight/picodet_m_416.xml"
);
std
::
cout
<<
"success"
<<
std
::
endl
;
int
main
(
int
argc
,
char
**
argv
)
{
if
(
argc
!=
3
)
{
fprintf
(
stderr
,
"usage: %s [mode] [path].
\n
For webcam mode=0, path is cam id;
\n
For image demo, mode=1, path=xxx/xxx/*.jpg;
\n
For video, mode=2;
\n
For benchmark, mode=3 path=0.
\n
"
,
argv
[
0
]);
return
-
1
;
}
std
::
cout
<<
"start init model"
<<
std
::
endl
;
auto
detector
=
PicoDet
(
"../weight/picodet_m_416.xml"
);
std
::
cout
<<
"success"
<<
std
::
endl
;
int
mode
=
atoi
(
argv
[
1
]);
switch
(
mode
)
{
case
0
:{
int
cam_id
=
atoi
(
argv
[
2
]);
webcam_demo
(
detector
,
cam_id
);
break
;
}
case
1
:{
const
char
*
images
=
argv
[
2
];
image_demo
(
detector
,
images
);
break
;
}
case
2
:{
const
char
*
path
=
argv
[
2
];
video_demo
(
detector
,
path
);
break
;
}
case
3
:{
benchmark
(
detector
);
break
;
}
default:
{
fprintf
(
stderr
,
"usage: %s [mode] [path].
\n
For webcam mode=0, path is cam id;
\n
For image demo, mode=1, path=xxx/xxx/*.jpg;
\n
For video, mode=2;
\n
For benchmark, mode=3 path=0.
\n
"
,
argv
[
0
]);
break
;
}
}
int
mode
=
atoi
(
argv
[
1
]);
switch
(
mode
)
{
case
0
:
{
int
cam_id
=
atoi
(
argv
[
2
]);
webcam_demo
(
detector
,
cam_id
);
break
;
}
case
1
:
{
const
char
*
images
=
argv
[
2
];
image_demo
(
detector
,
images
);
break
;
}
case
2
:
{
const
char
*
path
=
argv
[
2
];
video_demo
(
detector
,
path
);
break
;
}
case
3
:
{
benchmark
(
detector
);
break
;
}
default:
{
fprintf
(
stderr
,
"usage: %s [mode] [path].
\n
For webcam mode=0, path is "
"cam id;
\n
For image demo, mode=1, path=xxx/xxx/*.jpg;
\n
"
"For video, mode=2;
\n
For benchmark, mode=3 path=0.
\n
"
,
argv
[
0
]);
break
;
}
}
}
deploy/third_engine/demo_openvino/picodet_openvino.cpp
浏览文件 @
2580dc01
...
...
@@ -15,218 +15,195 @@
#include "picodet_openvino.h"
inline
float
fast_exp
(
float
x
)
{
union
{
uint32_t
i
;
float
f
;
}
v
{};
v
.
i
=
(
1
<<
23
)
*
(
1.4426950409
*
x
+
126.93490512
f
);
return
v
.
f
;
inline
float
fast_exp
(
float
x
)
{
union
{
uint32_t
i
;
float
f
;
}
v
{};
v
.
i
=
(
1
<<
23
)
*
(
1.4426950409
*
x
+
126.93490512
f
);
return
v
.
f
;
}
inline
float
sigmoid
(
float
x
)
{
return
1.0
f
/
(
1.0
f
+
fast_exp
(
-
x
));
}
template
<
typename
_Tp
>
int
activation_function_softmax
(
const
_Tp
*
src
,
_Tp
*
dst
,
int
length
)
{
const
_Tp
alpha
=
*
std
::
max_element
(
src
,
src
+
length
);
_Tp
denominator
{
0
};
for
(
int
i
=
0
;
i
<
length
;
++
i
)
{
dst
[
i
]
=
fast_exp
(
src
[
i
]
-
alpha
);
denominator
+=
dst
[
i
];
}
for
(
int
i
=
0
;
i
<
length
;
++
i
)
{
dst
[
i
]
/=
denominator
;
}
inline
float
sigmoid
(
float
x
)
{
return
1.0
f
/
(
1.0
f
+
fast_exp
(
-
x
));
}
return
0
;
}
template
<
typename
_Tp
>
int
activation_function_softmax
(
const
_Tp
*
src
,
_Tp
*
dst
,
int
length
)
{
const
_Tp
alpha
=
*
std
::
max_element
(
src
,
src
+
length
);
_Tp
denominator
{
0
};
PicoDet
::
PicoDet
(
const
char
*
model_path
)
{
InferenceEngine
::
Core
ie
;
InferenceEngine
::
CNNNetwork
model
=
ie
.
ReadNetwork
(
model_path
);
// prepare input settings
InferenceEngine
::
InputsDataMap
inputs_map
(
model
.
getInputsInfo
());
input_name_
=
inputs_map
.
begin
()
->
first
;
InferenceEngine
::
InputInfo
::
Ptr
input_info
=
inputs_map
.
begin
()
->
second
;
//prepare output settings
InferenceEngine
::
OutputsDataMap
outputs_map
(
model
.
getOutputsInfo
());
for
(
auto
&
output_info
:
outputs_map
)
{
output_info
.
second
->
setPrecision
(
InferenceEngine
::
Precision
::
FP32
);
}
for
(
int
i
=
0
;
i
<
length
;
++
i
)
{
dst
[
i
]
=
fast_exp
(
src
[
i
]
-
alpha
);
denominator
+=
dst
[
i
];
}
//get network
network_
=
ie
.
LoadNetwork
(
model
,
"CPU"
)
;
infer_request_
=
network_
.
CreateInferRequest
();
for
(
int
i
=
0
;
i
<
length
;
++
i
)
{
dst
[
i
]
/=
denominator
;
}
return
0
;
}
PicoDet
::~
PicoDet
()
{
PicoDet
::
PicoDet
(
const
char
*
model_path
)
{
InferenceEngine
::
Core
ie
;
InferenceEngine
::
CNNNetwork
model
=
ie
.
ReadNetwork
(
model_path
);
// prepare input settings
InferenceEngine
::
InputsDataMap
inputs_map
(
model
.
getInputsInfo
());
input_name_
=
inputs_map
.
begin
()
->
first
;
InferenceEngine
::
InputInfo
::
Ptr
input_info
=
inputs_map
.
begin
()
->
second
;
// prepare output settings
InferenceEngine
::
OutputsDataMap
outputs_map
(
model
.
getOutputsInfo
());
for
(
auto
&
output_info
:
outputs_map
)
{
output_info
.
second
->
setPrecision
(
InferenceEngine
::
Precision
::
FP32
);
}
// get network
network_
=
ie
.
LoadNetwork
(
model
,
"CPU"
);
infer_request_
=
network_
.
CreateInferRequest
();
}
void
PicoDet
::
preprocess
(
cv
::
Mat
&
image
,
InferenceEngine
::
Blob
::
Ptr
&
blob
)
{
int
img_w
=
image
.
cols
;
int
img_h
=
image
.
rows
;
int
channels
=
3
;
InferenceEngine
::
MemoryBlob
::
Ptr
mblob
=
InferenceEngine
::
as
<
InferenceEngine
::
MemoryBlob
>
(
blob
);
if
(
!
mblob
)
{
THROW_IE_EXCEPTION
<<
"We expect blob to be inherited from MemoryBlob in matU8ToBlob, "
<<
"but by fact we were not able to cast inputBlob to MemoryBlob"
;
}
auto
mblobHolder
=
mblob
->
wmap
();
float
*
blob_data
=
mblobHolder
.
as
<
float
*>
();
for
(
size_t
c
=
0
;
c
<
channels
;
c
++
)
{
for
(
size_t
h
=
0
;
h
<
img_h
;
h
++
)
{
for
(
size_t
w
=
0
;
w
<
img_w
;
w
++
)
{
blob_data
[
c
*
img_w
*
img_h
+
h
*
img_w
+
w
]
=
(
float
)
image
.
at
<
cv
::
Vec3b
>
(
h
,
w
)[
c
];
}
}
PicoDet
::~
PicoDet
()
{}
void
PicoDet
::
preprocess
(
cv
::
Mat
&
image
,
InferenceEngine
::
Blob
::
Ptr
&
blob
)
{
int
img_w
=
image
.
cols
;
int
img_h
=
image
.
rows
;
int
channels
=
3
;
InferenceEngine
::
MemoryBlob
::
Ptr
mblob
=
InferenceEngine
::
as
<
InferenceEngine
::
MemoryBlob
>
(
blob
);
if
(
!
mblob
)
{
THROW_IE_EXCEPTION
<<
"We expect blob to be inherited from MemoryBlob in matU8ToBlob, "
<<
"but by fact we were not able to cast inputBlob to MemoryBlob"
;
}
auto
mblobHolder
=
mblob
->
wmap
();
float
*
blob_data
=
mblobHolder
.
as
<
float
*>
();
for
(
size_t
c
=
0
;
c
<
channels
;
c
++
)
{
for
(
size_t
h
=
0
;
h
<
img_h
;
h
++
)
{
for
(
size_t
w
=
0
;
w
<
img_w
;
w
++
)
{
blob_data
[
c
*
img_w
*
img_h
+
h
*
img_w
+
w
]
=
(
float
)
image
.
at
<
cv
::
Vec3b
>
(
h
,
w
)[
c
];
}
}
}
}
std
::
vector
<
BoxInfo
>
PicoDet
::
detect
(
cv
::
Mat
image
,
float
score_threshold
,
float
nms_threshold
)
{
InferenceEngine
::
Blob
::
Ptr
input_blob
=
infer_request_
.
GetBlob
(
input_name_
);
preprocess
(
image
,
input_blob
);
// do inference
infer_request_
.
Infer
();
// get output
std
::
vector
<
std
::
vector
<
BoxInfo
>>
results
;
results
.
resize
(
this
->
num_class_
);
for
(
const
auto
&
head_info
:
this
->
heads_info_
)
{
const
InferenceEngine
::
Blob
::
Ptr
dis_pred_blob
=
infer_request_
.
GetBlob
(
head_info
.
dis_layer
);
const
InferenceEngine
::
Blob
::
Ptr
cls_pred_blob
=
infer_request_
.
GetBlob
(
head_info
.
cls_layer
);
auto
mdis_pred
=
InferenceEngine
::
as
<
InferenceEngine
::
MemoryBlob
>
(
dis_pred_blob
);
auto
mdis_pred_holder
=
mdis_pred
->
rmap
();
const
float
*
dis_pred
=
mdis_pred_holder
.
as
<
const
float
*>
();
auto
mcls_pred
=
InferenceEngine
::
as
<
InferenceEngine
::
MemoryBlob
>
(
cls_pred_blob
);
auto
mcls_pred_holder
=
mcls_pred
->
rmap
();
const
float
*
cls_pred
=
mcls_pred_holder
.
as
<
const
float
*>
();
this
->
decode_infer
(
cls_pred
,
dis_pred
,
head_info
.
stride
,
score_threshold
,
results
);
}
std
::
vector
<
BoxInfo
>
dets
;
for
(
int
i
=
0
;
i
<
(
int
)
results
.
size
();
i
++
)
{
this
->
nms
(
results
[
i
],
nms_threshold
);
for
(
auto
&
box
:
results
[
i
])
{
dets
.
push_back
(
box
);
}
std
::
vector
<
BoxInfo
>
PicoDet
::
detect
(
cv
::
Mat
image
,
float
score_threshold
,
float
nms_threshold
)
{
InferenceEngine
::
Blob
::
Ptr
input_blob
=
infer_request_
.
GetBlob
(
input_name_
);
preprocess
(
image
,
input_blob
);
// do inference
infer_request_
.
Infer
();
// get output
std
::
vector
<
std
::
vector
<
BoxInfo
>>
results
;
results
.
resize
(
this
->
num_class_
);
for
(
const
auto
&
head_info
:
this
->
heads_info_
)
{
const
InferenceEngine
::
Blob
::
Ptr
dis_pred_blob
=
infer_request_
.
GetBlob
(
head_info
.
dis_layer
);
const
InferenceEngine
::
Blob
::
Ptr
cls_pred_blob
=
infer_request_
.
GetBlob
(
head_info
.
cls_layer
);
auto
mdis_pred
=
InferenceEngine
::
as
<
InferenceEngine
::
MemoryBlob
>
(
dis_pred_blob
);
auto
mdis_pred_holder
=
mdis_pred
->
rmap
();
const
float
*
dis_pred
=
mdis_pred_holder
.
as
<
const
float
*>
();
auto
mcls_pred
=
InferenceEngine
::
as
<
InferenceEngine
::
MemoryBlob
>
(
cls_pred_blob
);
auto
mcls_pred_holder
=
mcls_pred
->
rmap
();
const
float
*
cls_pred
=
mcls_pred_holder
.
as
<
const
float
*>
();
this
->
decode_infer
(
cls_pred
,
dis_pred
,
head_info
.
stride
,
score_threshold
,
results
);
}
std
::
vector
<
BoxInfo
>
dets
;
for
(
int
i
=
0
;
i
<
(
int
)
results
.
size
();
i
++
)
{
this
->
nms
(
results
[
i
],
nms_threshold
);
for
(
auto
&
box
:
results
[
i
])
{
dets
.
push_back
(
box
);
}
return
dets
;
}
return
dets
;
}
void
PicoDet
::
decode_infer
(
const
float
*&
cls_pred
,
const
float
*&
dis_pred
,
int
stride
,
float
threshold
,
std
::
vector
<
std
::
vector
<
BoxInfo
>>&
results
)
{
int
feature_h
=
input_size_
/
stride
;
int
feature_w
=
input_size_
/
stride
;
for
(
int
idx
=
0
;
idx
<
feature_h
*
feature_w
;
idx
++
)
{
int
row
=
idx
/
feature_w
;
int
col
=
idx
%
feature_w
;
float
score
=
0
;
int
cur_label
=
0
;
for
(
int
label
=
0
;
label
<
num_class_
;
label
++
)
{
if
(
cls_pred
[
idx
*
num_class_
+
label
]
>
score
)
{
score
=
cls_pred
[
idx
*
num_class_
+
label
];
cur_label
=
label
;
}
}
if
(
score
>
threshold
)
{
const
float
*
bbox_pred
=
dis_pred
+
idx
*
(
reg_max_
+
1
)
*
4
;
results
[
cur_label
].
push_back
(
this
->
disPred2Bbox
(
bbox_pred
,
cur_label
,
score
,
col
,
row
,
stride
));
}
void
PicoDet
::
decode_infer
(
const
float
*&
cls_pred
,
const
float
*&
dis_pred
,
int
stride
,
float
threshold
,
std
::
vector
<
std
::
vector
<
BoxInfo
>>
&
results
)
{
int
feature_h
=
ceil
((
float
)
input_size_
/
stride
);
int
feature_w
=
ceil
((
float
)
input_size_
/
stride
);
for
(
int
idx
=
0
;
idx
<
feature_h
*
feature_w
;
idx
++
)
{
int
row
=
idx
/
feature_w
;
int
col
=
idx
%
feature_w
;
float
score
=
0
;
int
cur_label
=
0
;
for
(
int
label
=
0
;
label
<
num_class_
;
label
++
)
{
if
(
cls_pred
[
idx
*
num_class_
+
label
]
>
score
)
{
score
=
cls_pred
[
idx
*
num_class_
+
label
];
cur_label
=
label
;
}
}
if
(
score
>
threshold
)
{
const
float
*
bbox_pred
=
dis_pred
+
idx
*
(
reg_max_
+
1
)
*
4
;
results
[
cur_label
].
push_back
(
this
->
disPred2Bbox
(
bbox_pred
,
cur_label
,
score
,
col
,
row
,
stride
));
}
}
}
BoxInfo
PicoDet
::
disPred2Bbox
(
const
float
*&
dfl_det
,
int
label
,
float
score
,
int
x
,
int
y
,
int
stride
)
{
float
ct_x
=
(
x
+
0.5
)
*
stride
;
float
ct_y
=
(
y
+
0.5
)
*
stride
;
std
::
vector
<
float
>
dis_pred
;
dis_pred
.
resize
(
4
);
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
float
dis
=
0
;
float
*
dis_after_sm
=
new
float
[
reg_max_
+
1
];
activation_function_softmax
(
dfl_det
+
i
*
(
reg_max_
+
1
),
dis_after_sm
,
reg_max_
+
1
);
for
(
int
j
=
0
;
j
<
reg_max_
+
1
;
j
++
)
{
dis
+=
j
*
dis_after_sm
[
j
];
}
dis
*=
stride
;
dis_pred
[
i
]
=
dis
;
delete
[]
dis_after_sm
;
BoxInfo
PicoDet
::
disPred2Bbox
(
const
float
*&
dfl_det
,
int
label
,
float
score
,
int
x
,
int
y
,
int
stride
)
{
float
ct_x
=
(
x
+
0.5
)
*
stride
;
float
ct_y
=
(
y
+
0.5
)
*
stride
;
std
::
vector
<
float
>
dis_pred
;
dis_pred
.
resize
(
4
);
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
float
dis
=
0
;
float
*
dis_after_sm
=
new
float
[
reg_max_
+
1
];
activation_function_softmax
(
dfl_det
+
i
*
(
reg_max_
+
1
),
dis_after_sm
,
reg_max_
+
1
);
for
(
int
j
=
0
;
j
<
reg_max_
+
1
;
j
++
)
{
dis
+=
j
*
dis_after_sm
[
j
];
}
float
xmin
=
(
std
::
max
)(
ct_x
-
dis_pred
[
0
],
.0
f
);
float
ymin
=
(
std
::
max
)(
ct_y
-
dis_pred
[
1
],
.0
f
);
float
xmax
=
(
std
::
min
)(
ct_x
+
dis_pred
[
2
],
(
float
)
this
->
input_size_
);
float
ymax
=
(
std
::
min
)(
ct_y
+
dis_pred
[
3
],
(
float
)
this
->
input_size_
);
return
BoxInfo
{
xmin
,
ymin
,
xmax
,
ymax
,
score
,
label
};
dis
*=
stride
;
dis_pred
[
i
]
=
dis
;
delete
[]
dis_after_sm
;
}
float
xmin
=
(
std
::
max
)(
ct_x
-
dis_pred
[
0
],
.0
f
);
float
ymin
=
(
std
::
max
)(
ct_y
-
dis_pred
[
1
],
.0
f
);
float
xmax
=
(
std
::
min
)(
ct_x
+
dis_pred
[
2
],
(
float
)
this
->
input_size_
);
float
ymax
=
(
std
::
min
)(
ct_y
+
dis_pred
[
3
],
(
float
)
this
->
input_size_
);
return
BoxInfo
{
xmin
,
ymin
,
xmax
,
ymax
,
score
,
label
};
}
void
PicoDet
::
nms
(
std
::
vector
<
BoxInfo
>&
input_boxes
,
float
NMS_THRESH
)
{
std
::
sort
(
input_boxes
.
begin
(),
input_boxes
.
end
(),
[](
BoxInfo
a
,
BoxInfo
b
)
{
return
a
.
score
>
b
.
score
;
});
std
::
vector
<
float
>
vArea
(
input_boxes
.
size
());
for
(
int
i
=
0
;
i
<
int
(
input_boxes
.
size
());
++
i
)
{
vArea
[
i
]
=
(
input_boxes
.
at
(
i
).
x2
-
input_boxes
.
at
(
i
).
x1
+
1
)
*
(
input_boxes
.
at
(
i
).
y2
-
input_boxes
.
at
(
i
).
y1
+
1
);
}
for
(
int
i
=
0
;
i
<
int
(
input_boxes
.
size
());
++
i
)
{
for
(
int
j
=
i
+
1
;
j
<
int
(
input_boxes
.
size
());)
{
float
xx1
=
(
std
::
max
)(
input_boxes
[
i
].
x1
,
input_boxes
[
j
].
x1
);
float
yy1
=
(
std
::
max
)(
input_boxes
[
i
].
y1
,
input_boxes
[
j
].
y1
);
float
xx2
=
(
std
::
min
)(
input_boxes
[
i
].
x2
,
input_boxes
[
j
].
x2
);
float
yy2
=
(
std
::
min
)(
input_boxes
[
i
].
y2
,
input_boxes
[
j
].
y2
);
float
w
=
(
std
::
max
)(
float
(
0
),
xx2
-
xx1
+
1
);
float
h
=
(
std
::
max
)(
float
(
0
),
yy2
-
yy1
+
1
);
float
inter
=
w
*
h
;
float
ovr
=
inter
/
(
vArea
[
i
]
+
vArea
[
j
]
-
inter
);
if
(
ovr
>=
NMS_THRESH
)
{
input_boxes
.
erase
(
input_boxes
.
begin
()
+
j
);
vArea
.
erase
(
vArea
.
begin
()
+
j
);
}
else
{
j
++
;
}
}
void
PicoDet
::
nms
(
std
::
vector
<
BoxInfo
>
&
input_boxes
,
float
NMS_THRESH
)
{
std
::
sort
(
input_boxes
.
begin
(),
input_boxes
.
end
(),
[](
BoxInfo
a
,
BoxInfo
b
)
{
return
a
.
score
>
b
.
score
;
});
std
::
vector
<
float
>
vArea
(
input_boxes
.
size
());
for
(
int
i
=
0
;
i
<
int
(
input_boxes
.
size
());
++
i
)
{
vArea
[
i
]
=
(
input_boxes
.
at
(
i
).
x2
-
input_boxes
.
at
(
i
).
x1
+
1
)
*
(
input_boxes
.
at
(
i
).
y2
-
input_boxes
.
at
(
i
).
y1
+
1
);
}
for
(
int
i
=
0
;
i
<
int
(
input_boxes
.
size
());
++
i
)
{
for
(
int
j
=
i
+
1
;
j
<
int
(
input_boxes
.
size
());)
{
float
xx1
=
(
std
::
max
)(
input_boxes
[
i
].
x1
,
input_boxes
[
j
].
x1
);
float
yy1
=
(
std
::
max
)(
input_boxes
[
i
].
y1
,
input_boxes
[
j
].
y1
);
float
xx2
=
(
std
::
min
)(
input_boxes
[
i
].
x2
,
input_boxes
[
j
].
x2
);
float
yy2
=
(
std
::
min
)(
input_boxes
[
i
].
y2
,
input_boxes
[
j
].
y2
);
float
w
=
(
std
::
max
)(
float
(
0
),
xx2
-
xx1
+
1
);
float
h
=
(
std
::
max
)(
float
(
0
),
yy2
-
yy1
+
1
);
float
inter
=
w
*
h
;
float
ovr
=
inter
/
(
vArea
[
i
]
+
vArea
[
j
]
-
inter
);
if
(
ovr
>=
NMS_THRESH
)
{
input_boxes
.
erase
(
input_boxes
.
begin
()
+
j
);
vArea
.
erase
(
vArea
.
begin
()
+
j
);
}
else
{
j
++
;
}
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录