Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
PaddleClas
提交
29f8fb83
P
PaddleClas
项目概览
PaddlePaddle
/
PaddleClas
大约 2 年 前同步成功
通知
118
Star
4999
Fork
1114
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
19
列表
看板
标记
里程碑
合并请求
6
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
PaddleClas
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
19
Issue
19
列表
看板
标记
里程碑
合并请求
6
合并请求
6
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
29f8fb83
编写于
11月 15, 2021
作者:
D
dongshuilong
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
cpp shitu code format
上级
a96305c2
变更
19
隐藏空白更改
内联
并排
Showing
19 changed file
with
1324 addition
and
1301 deletion
+1324
-1301
deploy/cpp_shitu/include/feature_extracter.h
deploy/cpp_shitu/include/feature_extracter.h
+71
-72
deploy/cpp_shitu/include/nms.h
deploy/cpp_shitu/include/nms.h
+40
-40
deploy/cpp_shitu/include/object_detector.h
deploy/cpp_shitu/include/object_detector.h
+97
-94
deploy/cpp_shitu/include/preprocess_op.h
deploy/cpp_shitu/include/preprocess_op.h
+20
-20
deploy/cpp_shitu/include/preprocess_op_det.h
deploy/cpp_shitu/include/preprocess_op_det.h
+119
-116
deploy/cpp_shitu/include/vector_search.h
deploy/cpp_shitu/include/vector_search.h
+35
-30
deploy/cpp_shitu/include/yaml_config.h
deploy/cpp_shitu/include/yaml_config.h
+13
-8
deploy/cpp_shitu/readme.md
deploy/cpp_shitu/readme.md
+78
-54
deploy/cpp_shitu/src/feature_extracter.cpp
deploy/cpp_shitu/src/feature_extracter.cpp
+96
-96
deploy/cpp_shitu/src/main.cpp
deploy/cpp_shitu/src/main.cpp
+222
-220
deploy/cpp_shitu/src/object_detector.cpp
deploy/cpp_shitu/src/object_detector.cpp
+310
-310
deploy/cpp_shitu/src/preprocess_op.cpp
deploy/cpp_shitu/src/preprocess_op.cpp
+49
-49
deploy/cpp_shitu/src/preprocess_op_det.cpp
deploy/cpp_shitu/src/preprocess_op_det.cpp
+96
-96
deploy/cpp_shitu/src/vector_search.cpp
deploy/cpp_shitu/src/vector_search.cpp
+29
-29
deploy/cpp_shitu/src/yaml_config.cpp
deploy/cpp_shitu/src/yaml_config.cpp
+45
-45
deploy/cpp_shitu/tools/build.sh
deploy/cpp_shitu/tools/build.sh
+4
-4
deploy/cpp_shitu/tools/config.txt
deploy/cpp_shitu/tools/config.txt
+0
-17
deploy/cpp_shitu/tools/run.sh
deploy/cpp_shitu/tools/run.sh
+0
-1
docs/images/quick_start/shitu_c++_result.png
docs/images/quick_start/shitu_c++_result.png
+0
-0
未找到文件。
deploy/cpp_shitu/include/feature_extracter.h
浏览文件 @
29f8fb83
...
@@ -35,77 +35,76 @@ using namespace paddle_infer;
...
@@ -35,77 +35,76 @@ using namespace paddle_infer;
namespace
Feature
{
namespace
Feature
{
class
FeatureExtracter
{
class
FeatureExtracter
{
public:
public:
explicit
FeatureExtracter
(
const
YAML
::
Node
&
config_file
)
{
explicit
FeatureExtracter
(
const
YAML
::
Node
&
config_file
)
{
this
->
use_gpu_
=
config_file
[
"Global"
][
"use_gpu"
].
as
<
bool
>
();
this
->
use_gpu_
=
config_file
[
"Global"
][
"use_gpu"
].
as
<
bool
>
();
if
(
config_file
[
"Global"
][
"gpu_id"
].
IsDefined
())
if
(
config_file
[
"Global"
][
"gpu_id"
].
IsDefined
())
this
->
gpu_id_
=
config_file
[
"Global"
][
"gpu_id"
].
as
<
int
>
();
this
->
gpu_id_
=
config_file
[
"Global"
][
"gpu_id"
].
as
<
int
>
();
else
else
this
->
gpu_id_
=
0
;
this
->
gpu_id_
=
0
;
this
->
gpu_mem_
=
config_file
[
"Global"
][
"gpu_mem"
].
as
<
int
>
();
this
->
gpu_mem_
=
config_file
[
"Global"
][
"gpu_mem"
].
as
<
int
>
();
this
->
cpu_math_library_num_threads_
=
this
->
cpu_math_library_num_threads_
=
config_file
[
"Global"
][
"cpu_num_threads"
].
as
<
int
>
();
config_file
[
"Global"
][
"cpu_num_threads"
].
as
<
int
>
();
this
->
use_mkldnn_
=
config_file
[
"Global"
][
"enable_mkldnn"
].
as
<
bool
>
();
this
->
use_mkldnn_
=
config_file
[
"Global"
][
"enable_mkldnn"
].
as
<
bool
>
();
this
->
use_tensorrt_
=
config_file
[
"Global"
][
"use_tensorrt"
].
as
<
bool
>
();
this
->
use_tensorrt_
=
config_file
[
"Global"
][
"use_tensorrt"
].
as
<
bool
>
();
this
->
use_fp16_
=
config_file
[
"Global"
][
"use_fp16"
].
as
<
bool
>
();
this
->
use_fp16_
=
config_file
[
"Global"
][
"use_fp16"
].
as
<
bool
>
();
this
->
cls_model_path_
=
this
->
cls_model_path_
=
config_file
[
"Global"
][
"rec_inference_model_dir"
].
as
<
std
::
string
>
()
+
config_file
[
"Global"
][
"rec_inference_model_dir"
].
as
<
std
::
string
>
()
+
OS_PATH_SEP
+
"inference.pdmodel"
;
OS_PATH_SEP
+
"inference.pdmodel"
;
this
->
cls_params_path_
=
this
->
cls_params_path_
=
config_file
[
"Global"
][
"rec_inference_model_dir"
].
as
<
std
::
string
>
()
+
config_file
[
"Global"
][
"rec_inference_model_dir"
].
as
<
std
::
string
>
()
+
OS_PATH_SEP
+
"inference.pdiparams"
;
OS_PATH_SEP
+
"inference.pdiparams"
;
this
->
resize_size_
=
this
->
resize_size_
=
config_file
[
"RecPreProcess"
][
"transform_ops"
][
0
][
"ResizeImage"
][
"size"
]
config_file
[
"RecPreProcess"
][
"transform_ops"
][
0
][
"ResizeImage"
][
"size"
]
.
as
<
int
>
();
.
as
<
int
>
();
this
->
scale_
=
config_file
[
"RecPreProcess"
][
"transform_ops"
][
1
]
this
->
scale_
=
config_file
[
"RecPreProcess"
][
"transform_ops"
][
1
][
"NormalizeImage"
][
"scale"
].
as
<
float
>
();
[
"NormalizeImage"
][
"scale"
]
this
->
mean_
=
config_file
[
"RecPreProcess"
][
"transform_ops"
][
1
]
.
as
<
float
>
();
[
"NormalizeImage"
][
"mean"
]
this
->
mean_
=
config_file
[
"RecPreProcess"
][
"transform_ops"
][
1
]
.
as
<
std
::
vector
<
float
>>
();
[
"NormalizeImage"
][
"mean"
]
this
->
std_
=
config_file
[
"RecPreProcess"
][
"transform_ops"
][
1
]
.
as
<
std
::
vector
<
float
>>
();
[
"NormalizeImage"
][
"std"
]
this
->
std_
=
config_file
[
"RecPreProcess"
][
"transform_ops"
][
1
]
.
as
<
std
::
vector
<
float
>>
();
[
"NormalizeImage"
][
"std"
]
if
(
config_file
[
"Global"
][
"rec_feature_normlize"
].
IsDefined
())
.
as
<
std
::
vector
<
float
>>
();
this
->
feature_norm
=
if
(
config_file
[
"Global"
][
"rec_feature_normlize"
].
IsDefined
())
config_file
[
"Global"
][
"rec_feature_normlize"
].
as
<
bool
>
();
this
->
feature_norm
=
config_file
[
"Global"
][
"rec_feature_normlize"
].
as
<
bool
>
();
LoadModel
(
cls_model_path_
,
cls_params_path_
);
}
LoadModel
(
cls_model_path_
,
cls_params_path_
);
}
// Load Paddle inference model
void
LoadModel
(
const
std
::
string
&
model_path
,
const
std
::
string
&
params_path
);
// Load Paddle inference model
void
LoadModel
(
const
std
::
string
&
model_path
,
const
std
::
string
&
params_path
);
// Run predictor
void
Run
(
cv
::
Mat
&
img
,
std
::
vector
<
float
>
&
out_data
,
// Run predictor
std
::
vector
<
double
>
&
times
);
void
Run
(
cv
::
Mat
&
img
,
std
::
vector
<
float
>
&
out_data
,
std
::
vector
<
double
>
&
times
);
void
FeatureNorm
(
std
::
vector
<
float
>
&
feature
);
void
FeatureNorm
(
std
::
vector
<
float
>
&
feature
);
std
::
shared_ptr
<
Predictor
>
predictor_
;
std
::
shared_ptr
<
Predictor
>
predictor_
;
private:
private:
bool
use_gpu_
=
false
;
bool
use_gpu_
=
false
;
int
gpu_id_
=
0
;
int
gpu_id_
=
0
;
int
gpu_mem_
=
4000
;
int
gpu_mem_
=
4000
;
int
cpu_math_library_num_threads_
=
4
;
int
cpu_math_library_num_threads_
=
4
;
bool
use_mkldnn_
=
false
;
bool
use_mkldnn_
=
false
;
bool
use_tensorrt_
=
false
;
bool
use_tensorrt_
=
false
;
bool
feature_norm
=
true
;
bool
feature_norm
=
true
;
bool
use_fp16_
=
false
;
bool
use_fp16_
=
false
;
std
::
vector
<
float
>
mean_
=
{
0.485
f
,
0.456
f
,
0.406
f
};
std
::
vector
<
float
>
mean_
=
{
0.485
f
,
0.456
f
,
0.406
f
};
std
::
vector
<
float
>
std_
=
{
0.229
f
,
0.224
f
,
0.225
f
};
std
::
vector
<
float
>
std_
=
{
0.229
f
,
0.224
f
,
0.225
f
};
float
scale_
=
0.00392157
;
float
scale_
=
0.00392157
;
int
resize_size_
=
224
;
int
resize_size_
=
224
;
int
resize_short_
=
224
;
int
resize_short_
=
224
;
std
::
string
cls_model_path_
;
std
::
string
cls_model_path_
;
std
::
string
cls_params_path_
;
std
::
string
cls_params_path_
;
// pre-process
// pre-process
ResizeImg
resize_op_
;
ResizeImg
resize_op_
;
Normalize
normalize_op_
;
Normalize
normalize_op_
;
Permute
permute_op_
;
Permute
permute_op_
;
};
};
}
// namespace Feature
}
// namespace Feature
deploy/cpp_shitu/include/nms.h
浏览文件 @
29f8fb83
...
@@ -17,21 +17,21 @@
...
@@ -17,21 +17,21 @@
#include <algorithm>
#include <algorithm>
#include <include/object_detector.h>
#include <include/object_detector.h>
template
<
typename
T
>
template
<
typename
T
>
static
inline
bool
SortScorePairDescend
(
const
std
::
pair
<
float
,
T
>
&
pair1
,
static
inline
bool
SortScorePairDescend
(
const
std
::
pair
<
float
,
T
>
&
pair1
,
const
std
::
pair
<
float
,
T
>
&
pair2
)
{
const
std
::
pair
<
float
,
T
>
&
pair2
)
{
return
pair1
.
first
>
pair2
.
first
;
return
pair1
.
first
>
pair2
.
first
;
}
}
float
RectOverlap
(
const
Detection
::
ObjectResult
&
a
,
float
RectOverlap
(
const
Detection
::
ObjectResult
&
a
,
const
Detection
::
ObjectResult
&
b
)
{
const
Detection
::
ObjectResult
&
b
)
{
float
Aa
=
(
a
.
rect
[
2
]
-
a
.
rect
[
0
]
+
1
)
*
(
a
.
rect
[
3
]
-
a
.
rect
[
1
]
+
1
);
float
Aa
=
(
a
.
rect
[
2
]
-
a
.
rect
[
0
]
+
1
)
*
(
a
.
rect
[
3
]
-
a
.
rect
[
1
]
+
1
);
float
Ab
=
(
b
.
rect
[
2
]
-
b
.
rect
[
0
]
+
1
)
*
(
b
.
rect
[
3
]
-
b
.
rect
[
1
]
+
1
);
float
Ab
=
(
b
.
rect
[
2
]
-
b
.
rect
[
0
]
+
1
)
*
(
b
.
rect
[
3
]
-
b
.
rect
[
1
]
+
1
);
int
iou_w
=
max
(
min
(
a
.
rect
[
2
],
b
.
rect
[
2
])
-
max
(
a
.
rect
[
0
],
b
.
rect
[
0
])
+
1
,
0
);
int
iou_w
=
max
(
min
(
a
.
rect
[
2
],
b
.
rect
[
2
])
-
max
(
a
.
rect
[
0
],
b
.
rect
[
0
])
+
1
,
0
);
int
iou_h
=
max
(
min
(
a
.
rect
[
3
],
b
.
rect
[
3
])
-
max
(
a
.
rect
[
1
],
b
.
rect
[
1
])
+
1
,
0
);
int
iou_h
=
max
(
min
(
a
.
rect
[
3
],
b
.
rect
[
3
])
-
max
(
a
.
rect
[
1
],
b
.
rect
[
1
])
+
1
,
0
);
float
Aab
=
iou_w
*
iou_h
;
float
Aab
=
iou_w
*
iou_h
;
return
Aab
/
(
Aa
+
Ab
-
Aab
);
return
Aab
/
(
Aa
+
Ab
-
Aab
);
}
}
// Get max scores with corresponding indices.
// Get max scores with corresponding indices.
...
@@ -40,46 +40,46 @@ float RectOverlap(const Detection::ObjectResult &a,
...
@@ -40,46 +40,46 @@ float RectOverlap(const Detection::ObjectResult &a,
// top_k: if -1, keep all; otherwise, keep at most top_k.
// top_k: if -1, keep all; otherwise, keep at most top_k.
// score_index_vec: store the sorted (score, index) pair.
// score_index_vec: store the sorted (score, index) pair.
inline
void
inline
void
GetMaxScoreIndex
(
const
std
::
vector
<
Detection
::
ObjectResult
>
&
det_result
,
GetMaxScoreIndex
(
const
std
::
vector
<
Detection
::
ObjectResult
>
&
det_result
,
const
float
threshold
,
const
float
threshold
,
std
::
vector
<
std
::
pair
<
float
,
int
>>
&
score_index_vec
)
{
std
::
vector
<
std
::
pair
<
float
,
int
>>
&
score_index_vec
)
{
// Generate index score pairs.
// Generate index score pairs.
for
(
size_t
i
=
0
;
i
<
det_result
.
size
();
++
i
)
{
for
(
size_t
i
=
0
;
i
<
det_result
.
size
();
++
i
)
{
if
(
det_result
[
i
].
confidence
>
threshold
)
{
if
(
det_result
[
i
].
confidence
>
threshold
)
{
score_index_vec
.
push_back
(
std
::
make_pair
(
det_result
[
i
].
confidence
,
i
));
score_index_vec
.
push_back
(
std
::
make_pair
(
det_result
[
i
].
confidence
,
i
));
}
}
}
}
// Sort the score pair according to the scores in descending order
// Sort the score pair according to the scores in descending order
std
::
stable_sort
(
score_index_vec
.
begin
(),
score_index_vec
.
end
(),
std
::
stable_sort
(
score_index_vec
.
begin
(),
score_index_vec
.
end
(),
SortScorePairDescend
<
int
>
);
SortScorePairDescend
<
int
>
);
// // Keep top_k scores if needed.
// // Keep top_k scores if needed.
// if (top_k > 0 && top_k < (int)score_index_vec.size())
// if (top_k > 0 && top_k < (int)score_index_vec.size())
// {
// {
// score_index_vec.resize(top_k);
// score_index_vec.resize(top_k);
// }
// }
}
}
void
NMSBoxes
(
const
std
::
vector
<
Detection
::
ObjectResult
>
det_result
,
void
NMSBoxes
(
const
std
::
vector
<
Detection
::
ObjectResult
>
det_result
,
const
float
score_threshold
,
const
float
nms_threshold
,
const
float
score_threshold
,
const
float
nms_threshold
,
std
::
vector
<
int
>
&
indices
)
{
std
::
vector
<
int
>
&
indices
)
{
int
a
=
1
;
int
a
=
1
;
// Get top_k scores (with corresponding indices).
// Get top_k scores (with corresponding indices).
std
::
vector
<
std
::
pair
<
float
,
int
>>
score_index_vec
;
std
::
vector
<
std
::
pair
<
float
,
int
>>
score_index_vec
;
GetMaxScoreIndex
(
det_result
,
score_threshold
,
score_index_vec
);
GetMaxScoreIndex
(
det_result
,
score_threshold
,
score_index_vec
);
// Do nms
// Do nms
indices
.
clear
();
indices
.
clear
();
for
(
size_t
i
=
0
;
i
<
score_index_vec
.
size
();
++
i
)
{
for
(
size_t
i
=
0
;
i
<
score_index_vec
.
size
();
++
i
)
{
const
int
idx
=
score_index_vec
[
i
].
second
;
const
int
idx
=
score_index_vec
[
i
].
second
;
bool
keep
=
true
;
bool
keep
=
true
;
for
(
int
k
=
0
;
k
<
(
int
)
indices
.
size
()
&&
keep
;
++
k
)
{
for
(
int
k
=
0
;
k
<
(
int
)
indices
.
size
()
&&
keep
;
++
k
)
{
const
int
kept_idx
=
indices
[
k
];
const
int
kept_idx
=
indices
[
k
];
float
overlap
=
RectOverlap
(
det_result
[
idx
],
det_result
[
kept_idx
]);
float
overlap
=
RectOverlap
(
det_result
[
idx
],
det_result
[
kept_idx
]);
keep
=
overlap
<=
nms_threshold
;
keep
=
overlap
<=
nms_threshold
;
}
if
(
keep
)
indices
.
push_back
(
idx
);
}
}
if
(
keep
)
indices
.
push_back
(
idx
);
}
}
}
deploy/cpp_shitu/include/object_detector.h
浏览文件 @
29f8fb83
...
@@ -33,103 +33,106 @@ using namespace paddle_infer;
...
@@ -33,103 +33,106 @@ using namespace paddle_infer;
namespace
Detection
{
namespace
Detection
{
// Object Detection Result
// Object Detection Result
struct
ObjectResult
{
struct
ObjectResult
{
// Rectangle coordinates of detected object: left, right, top, down
// Rectangle coordinates of detected object: left, right, top, down
std
::
vector
<
int
>
rect
;
std
::
vector
<
int
>
rect
;
// Class id of detected object
// Class id of detected object
int
class_id
;
int
class_id
;
// Confidence of detected object
// Confidence of detected object
float
confidence
;
float
confidence
;
};
};
// Generate visualization colormap for each class
// Generate visualization colormap for each class
std
::
vector
<
int
>
GenerateColorMap
(
int
num_class
);
std
::
vector
<
int
>
GenerateColorMap
(
int
num_class
);
// Visualiztion Detection Result
// Visualiztion Detection Result
cv
::
Mat
VisualizeResult
(
const
cv
::
Mat
&
img
,
cv
::
Mat
VisualizeResult
(
const
cv
::
Mat
&
img
,
const
std
::
vector
<
ObjectResult
>
&
results
,
const
std
::
vector
<
ObjectResult
>
&
results
,
const
std
::
vector
<
std
::
string
>
&
lables
,
const
std
::
vector
<
std
::
string
>
&
lables
,
const
std
::
vector
<
int
>
&
colormap
,
const
bool
is_rbox
);
const
std
::
vector
<
int
>
&
colormap
,
const
bool
is_rbox
);
class
ObjectDetector
{
class
ObjectDetector
{
public:
public:
explicit
ObjectDetector
(
const
YAML
::
Node
&
config_file
)
{
explicit
ObjectDetector
(
const
YAML
::
Node
&
config_file
)
{
this
->
use_gpu_
=
config_file
[
"Global"
][
"use_gpu"
].
as
<
bool
>
();
this
->
use_gpu_
=
config_file
[
"Global"
][
"use_gpu"
].
as
<
bool
>
();
if
(
config_file
[
"Global"
][
"gpu_id"
].
IsDefined
())
if
(
config_file
[
"Global"
][
"gpu_id"
].
IsDefined
())
this
->
gpu_id_
=
config_file
[
"Global"
][
"gpu_id"
].
as
<
int
>
();
this
->
gpu_id_
=
config_file
[
"Global"
][
"gpu_id"
].
as
<
int
>
();
this
->
gpu_mem_
=
config_file
[
"Global"
][
"gpu_mem"
].
as
<
int
>
();
this
->
gpu_mem_
=
config_file
[
"Global"
][
"gpu_mem"
].
as
<
int
>
();
this
->
cpu_math_library_num_threads_
=
this
->
cpu_math_library_num_threads_
=
config_file
[
"Global"
][
"cpu_num_threads"
].
as
<
int
>
();
config_file
[
"Global"
][
"cpu_num_threads"
].
as
<
int
>
();
this
->
use_mkldnn_
=
config_file
[
"Global"
][
"enable_mkldnn"
].
as
<
bool
>
();
this
->
use_mkldnn_
=
config_file
[
"Global"
][
"enable_mkldnn"
].
as
<
bool
>
();
this
->
use_tensorrt_
=
config_file
[
"Global"
][
"use_tensorrt"
].
as
<
bool
>
();
this
->
use_tensorrt_
=
config_file
[
"Global"
][
"use_tensorrt"
].
as
<
bool
>
();
this
->
use_fp16_
=
config_file
[
"Global"
][
"use_fp16"
].
as
<
bool
>
();
this
->
use_fp16_
=
config_file
[
"Global"
][
"use_fp16"
].
as
<
bool
>
();
this
->
model_dir_
=
this
->
model_dir_
=
config_file
[
"Global"
][
"det_inference_model_dir"
].
as
<
std
::
string
>
();
config_file
[
"Global"
][
"det_inference_model_dir"
].
as
<
std
::
string
>
();
this
->
threshold_
=
config_file
[
"Global"
][
"threshold"
].
as
<
float
>
();
this
->
threshold_
=
config_file
[
"Global"
][
"threshold"
].
as
<
float
>
();
this
->
max_det_results_
=
config_file
[
"Global"
][
"max_det_results"
].
as
<
int
>
();
this
->
max_det_results_
=
config_file
[
"Global"
][
"max_det_results"
].
as
<
int
>
();
this
->
image_shape_
=
this
->
image_shape_
=
config_file
[
"Global"
][
"image_shape"
].
as
<
std
::
vector
<
int
>>
();
config_file
[
"Global"
][
"image_shape"
].
as
<
std
::
vector
<
int
>>
();
this
->
label_list_
=
this
->
label_list_
=
config_file
[
"Global"
][
"labe_list"
].
as
<
std
::
vector
<
std
::
string
>>
();
config_file
[
"Global"
][
"labe_list"
].
as
<
std
::
vector
<
std
::
string
>>
();
this
->
ir_optim_
=
config_file
[
"Global"
][
"ir_optim"
].
as
<
bool
>
();
this
->
ir_optim_
=
config_file
[
"Global"
][
"ir_optim"
].
as
<
bool
>
();
this
->
batch_size_
=
config_file
[
"Global"
][
"batch_size"
].
as
<
int
>
();
this
->
batch_size_
=
config_file
[
"Global"
][
"batch_size"
].
as
<
int
>
();
preprocessor_
.
Init
(
config_file
[
"DetPreProcess"
][
"transform_ops"
]);
preprocessor_
.
Init
(
config_file
[
"DetPreProcess"
][
"transform_ops"
]);
LoadModel
(
model_dir_
,
batch_size_
,
run_mode
);
LoadModel
(
model_dir_
,
batch_size_
,
run_mode
);
}
}
// Load Paddle inference model
// Load Paddle inference model
void
LoadModel
(
const
std
::
string
&
model_dir
,
const
int
batch_size
=
1
,
void
LoadModel
(
const
std
::
string
&
model_dir
,
const
int
batch_size
=
1
,
const
std
::
string
&
run_mode
=
"fluid"
);
const
std
::
string
&
run_mode
=
"fluid"
);
// Run predictor
// Run predictor
void
Predict
(
const
std
::
vector
<
cv
::
Mat
>
imgs
,
const
int
warmup
=
0
,
void
Predict
(
const
std
::
vector
<
cv
::
Mat
>
imgs
,
const
int
warmup
=
0
,
const
int
repeats
=
1
,
const
int
repeats
=
1
,
std
::
vector
<
ObjectResult
>
*
result
=
nullptr
,
std
::
vector
<
ObjectResult
>
*
result
=
nullptr
,
std
::
vector
<
int
>
*
bbox_num
=
nullptr
,
std
::
vector
<
int
>
*
bbox_num
=
nullptr
,
std
::
vector
<
double
>
*
times
=
nullptr
);
std
::
vector
<
double
>
*
times
=
nullptr
);
const
std
::
vector
<
std
::
string
>
&
GetLabelList
()
const
{
return
this
->
label_list_
;
const
std
::
vector
<
std
::
string
>
&
GetLabelList
()
const
{
}
return
this
->
label_list_
;
const
float
&
GetThreshold
()
const
{
return
this
->
threshold_
;
}
}
private:
const
float
&
GetThreshold
()
const
{
return
this
->
threshold_
;
}
bool
use_gpu_
=
true
;
int
gpu_id_
=
0
;
private:
int
gpu_mem_
=
800
;
bool
use_gpu_
=
true
;
int
cpu_math_library_num_threads_
=
6
;
int
gpu_id_
=
0
;
std
::
string
run_mode
=
"fluid"
;
int
gpu_mem_
=
800
;
bool
use_mkldnn_
=
false
;
int
cpu_math_library_num_threads_
=
6
;
bool
use_tensorrt_
=
false
;
std
::
string
run_mode
=
"fluid"
;
bool
batch_size_
=
1
;
bool
use_mkldnn_
=
false
;
bool
use_fp16_
=
false
;
bool
use_tensorrt_
=
false
;
std
::
string
model_dir_
;
bool
batch_size_
=
1
;
float
threshold_
=
0.5
;
bool
use_fp16_
=
false
;
float
max_det_results_
=
5
;
std
::
string
model_dir_
;
std
::
vector
<
int
>
image_shape_
=
{
3
,
640
,
640
};
float
threshold_
=
0.5
;
std
::
vector
<
std
::
string
>
label_list_
;
float
max_det_results_
=
5
;
bool
ir_optim_
=
true
;
std
::
vector
<
int
>
image_shape_
=
{
3
,
640
,
640
};
bool
det_permute_
=
true
;
std
::
vector
<
std
::
string
>
label_list_
;
bool
det_postprocess_
=
true
;
bool
ir_optim_
=
true
;
int
min_subgraph_size_
=
30
;
bool
det_permute_
=
true
;
bool
use_dynamic_shape_
=
false
;
bool
det_postprocess_
=
true
;
int
trt_min_shape_
=
1
;
int
min_subgraph_size_
=
30
;
int
trt_max_shape_
=
1280
;
bool
use_dynamic_shape_
=
false
;
int
trt_opt_shape_
=
640
;
int
trt_min_shape_
=
1
;
bool
trt_calib_mode_
=
false
;
int
trt_max_shape_
=
1280
;
int
trt_opt_shape_
=
640
;
// Preprocess image and copy data to input buffer
bool
trt_calib_mode_
=
false
;
void
Preprocess
(
const
cv
::
Mat
&
image_mat
);
// Postprocess result
// Preprocess image and copy data to input buffer
void
Postprocess
(
const
std
::
vector
<
cv
::
Mat
>
mats
,
void
Preprocess
(
const
cv
::
Mat
&
image_mat
);
std
::
vector
<
ObjectResult
>
*
result
,
std
::
vector
<
int
>
bbox_num
,
bool
is_rbox
);
// Postprocess result
void
Postprocess
(
const
std
::
vector
<
cv
::
Mat
>
mats
,
std
::
shared_ptr
<
Predictor
>
predictor_
;
std
::
vector
<
ObjectResult
>
*
result
,
std
::
vector
<
int
>
bbox_num
,
Preprocessor
preprocessor_
;
bool
is_rbox
);
ImageBlob
inputs_
;
std
::
vector
<
float
>
output_data_
;
std
::
shared_ptr
<
Predictor
>
predictor_
;
std
::
vector
<
int
>
out_bbox_num_data_
;
Preprocessor
preprocessor_
;
};
ImageBlob
inputs_
;
std
::
vector
<
float
>
output_data_
;
std
::
vector
<
int
>
out_bbox_num_data_
;
};
}
// namespace Detection
}
// namespace Detection
deploy/cpp_shitu/include/preprocess_op.h
浏览文件 @
29f8fb83
...
@@ -31,27 +31,27 @@ using namespace std;
...
@@ -31,27 +31,27 @@ using namespace std;
namespace
Feature
{
namespace
Feature
{
class
Normalize
{
class
Normalize
{
public:
public:
virtual
void
Run
(
cv
::
Mat
*
im
,
const
std
::
vector
<
float
>
&
mean
,
virtual
void
Run
(
cv
::
Mat
*
im
,
const
std
::
vector
<
float
>
&
mean
,
const
std
::
vector
<
float
>
&
std
,
float
scale
);
const
std
::
vector
<
float
>
&
std
,
float
scale
);
};
};
// RGB -> CHW
// RGB -> CHW
class
Permute
{
class
Permute
{
public:
public:
virtual
void
Run
(
const
cv
::
Mat
*
im
,
float
*
data
);
virtual
void
Run
(
const
cv
::
Mat
*
im
,
float
*
data
);
};
};
class
CenterCropImg
{
class
CenterCropImg
{
public:
public:
virtual
void
Run
(
cv
::
Mat
&
im
,
const
int
crop_size
=
224
);
virtual
void
Run
(
cv
::
Mat
&
im
,
const
int
crop_size
=
224
);
};
};
class
ResizeImg
{
class
ResizeImg
{
public:
public:
virtual
void
Run
(
const
cv
::
Mat
&
img
,
cv
::
Mat
&
resize_img
,
int
max_size_len
,
virtual
void
Run
(
const
cv
::
Mat
&
img
,
cv
::
Mat
&
resize_img
,
int
max_size_len
,
int
size
=
0
);
int
size
=
0
);
};
};
}
// namespace Feature
}
// namespace Feature
deploy/cpp_shitu/include/preprocess_op_det.h
浏览文件 @
29f8fb83
...
@@ -31,125 +31,128 @@
...
@@ -31,125 +31,128 @@
namespace
Detection
{
namespace
Detection
{
// Object for storing all preprocessed data
// Object for storing all preprocessed data
class
ImageBlob
{
class
ImageBlob
{
public:
public:
// image width and height
// image width and height
std
::
vector
<
float
>
im_shape_
;
std
::
vector
<
float
>
im_shape_
;
// Buffer for image data after preprocessing
// Buffer for image data after preprocessing
std
::
vector
<
float
>
im_data_
;
std
::
vector
<
float
>
im_data_
;
// in net data shape(after pad)
// in net data shape(after pad)
std
::
vector
<
float
>
in_net_shape_
;
std
::
vector
<
float
>
in_net_shape_
;
// Evaluation image width and height
// Evaluation image width and height
// std::vector<float> eval_im_size_f_;
// std::vector<float> eval_im_size_f_;
// Scale factor for image size to origin image size
// Scale factor for image size to origin image size
std
::
vector
<
float
>
scale_factor_
;
std
::
vector
<
float
>
scale_factor_
;
};
};
// Abstraction of preprocessing opration class
// Abstraction of preprocessing opration class
class
PreprocessOp
{
class
PreprocessOp
{
public:
public:
virtual
void
Init
(
const
YAML
::
Node
&
item
)
=
0
;
virtual
void
Init
(
const
YAML
::
Node
&
item
)
=
0
;
virtual
void
Run
(
cv
::
Mat
*
im
,
ImageBlob
*
data
)
=
0
;
};
virtual
void
Run
(
cv
::
Mat
*
im
,
ImageBlob
*
data
)
=
0
;
};
class
InitInfo
:
public
PreprocessOp
{
public:
class
InitInfo
:
public
PreprocessOp
{
virtual
void
Init
(
const
YAML
::
Node
&
item
)
{}
public:
virtual
void
Run
(
cv
::
Mat
*
im
,
ImageBlob
*
data
);
virtual
void
Init
(
const
YAML
::
Node
&
item
)
{}
};
virtual
void
Run
(
cv
::
Mat
*
im
,
ImageBlob
*
data
);
class
NormalizeImage
:
public
PreprocessOp
{
};
public:
virtual
void
Init
(
const
YAML
::
Node
&
item
)
{
class
NormalizeImage
:
public
PreprocessOp
{
mean_
=
item
[
"mean"
].
as
<
std
::
vector
<
float
>>
();
public:
scale_
=
item
[
"std"
].
as
<
std
::
vector
<
float
>>
();
virtual
void
Init
(
const
YAML
::
Node
&
item
)
{
is_scale_
=
item
[
"is_scale"
].
as
<
bool
>
();
mean_
=
item
[
"mean"
].
as
<
std
::
vector
<
float
>>
();
}
scale_
=
item
[
"std"
].
as
<
std
::
vector
<
float
>>
();
is_scale_
=
item
[
"is_scale"
].
as
<
bool
>
();
virtual
void
Run
(
cv
::
Mat
*
im
,
ImageBlob
*
data
);
}
private:
virtual
void
Run
(
cv
::
Mat
*
im
,
ImageBlob
*
data
);
// CHW or HWC
std
::
vector
<
float
>
mean_
;
private:
std
::
vector
<
float
>
scale_
;
// CHW or HWC
bool
is_scale_
;
std
::
vector
<
float
>
mean_
;
};
std
::
vector
<
float
>
scale_
;
bool
is_scale_
;
class
Permute
:
public
PreprocessOp
{
};
public:
virtual
void
Init
(
const
YAML
::
Node
&
item
)
{}
class
Permute
:
public
PreprocessOp
{
virtual
void
Run
(
cv
::
Mat
*
im
,
ImageBlob
*
data
);
public:
};
virtual
void
Init
(
const
YAML
::
Node
&
item
)
{}
class
Resize
:
public
PreprocessOp
{
virtual
void
Run
(
cv
::
Mat
*
im
,
ImageBlob
*
data
);
public:
};
virtual
void
Init
(
const
YAML
::
Node
&
item
)
{
interp_
=
item
[
"interp"
].
as
<
int
>
();
class
Resize
:
public
PreprocessOp
{
// max_size_ = item["target_size"].as<int>();
public:
keep_ratio_
=
item
[
"keep_ratio"
].
as
<
bool
>
();
virtual
void
Init
(
const
YAML
::
Node
&
item
)
{
target_size_
=
item
[
"target_size"
].
as
<
std
::
vector
<
int
>>
();
interp_
=
item
[
"interp"
].
as
<
int
>
();
}
// max_size_ = item["target_size"].as<int>();
keep_ratio_
=
item
[
"keep_ratio"
].
as
<
bool
>
();
// Compute best resize scale for x-dimension, y-dimension
target_size_
=
item
[
"target_size"
].
as
<
std
::
vector
<
int
>>
();
std
::
pair
<
double
,
double
>
GenerateScale
(
const
cv
::
Mat
&
im
);
}
virtual
void
Run
(
cv
::
Mat
*
im
,
ImageBlob
*
data
);
// Compute best resize scale for x-dimension, y-dimension
std
::
pair
<
double
,
double
>
GenerateScale
(
const
cv
::
Mat
&
im
);
private:
int
interp_
=
2
;
virtual
void
Run
(
cv
::
Mat
*
im
,
ImageBlob
*
data
);
bool
keep_ratio_
;
std
::
vector
<
int
>
target_size_
;
private:
std
::
vector
<
int
>
in_net_shape_
;
int
interp_
=
2
;
};
bool
keep_ratio_
;
std
::
vector
<
int
>
target_size_
;
std
::
vector
<
int
>
in_net_shape_
;
};
// Models with FPN need input shape % stride == 0
// Models with FPN need input shape % stride == 0
class
PadStride
:
public
PreprocessOp
{
class
PadStride
:
public
PreprocessOp
{
public:
public:
virtual
void
Init
(
const
YAML
::
Node
&
item
)
{
virtual
void
Init
(
const
YAML
::
Node
&
item
)
{
stride_
=
item
[
"stride"
].
as
<
int
>
();
stride_
=
item
[
"stride"
].
as
<
int
>
();
}
}
virtual
void
Run
(
cv
::
Mat
*
im
,
ImageBlob
*
data
);
virtual
void
Run
(
cv
::
Mat
*
im
,
ImageBlob
*
data
);
private:
private:
int
stride_
;
int
stride_
;
};
};
class
Preprocessor
{
class
Preprocessor
{
public:
public:
void
Init
(
const
YAML
::
Node
&
config_node
)
{
void
Init
(
const
YAML
::
Node
&
config_node
)
{
// initialize image info at first
// initialize image info at first
ops_
[
"InitInfo"
]
=
std
::
make_shared
<
InitInfo
>
();
ops_
[
"InitInfo"
]
=
std
::
make_shared
<
InitInfo
>
();
for
(
int
i
=
0
;
i
<
config_node
.
size
();
++
i
)
{
for
(
int
i
=
0
;
i
<
config_node
.
size
();
++
i
)
{
if
(
config_node
[
i
][
"DetResize"
].
IsDefined
())
{
if
(
config_node
[
i
][
"DetResize"
].
IsDefined
())
{
ops_
[
"Resize"
]
=
std
::
make_shared
<
Resize
>
();
ops_
[
"Resize"
]
=
std
::
make_shared
<
Resize
>
();
ops_
[
"Resize"
]
->
Init
(
config_node
[
i
][
"DetResize"
]);
ops_
[
"Resize"
]
->
Init
(
config_node
[
i
][
"DetResize"
]);
}
}
if
(
config_node
[
i
][
"DetNormalizeImage"
].
IsDefined
())
{
if
(
config_node
[
i
][
"DetNormalizeImage"
].
IsDefined
())
{
ops_
[
"NormalizeImage"
]
=
std
::
make_shared
<
NormalizeImage
>
();
ops_
[
"NormalizeImage"
]
=
std
::
make_shared
<
NormalizeImage
>
();
ops_
[
"NormalizeImage"
]
->
Init
(
config_node
[
i
][
"DetNormalizeImage"
]);
ops_
[
"NormalizeImage"
]
->
Init
(
config_node
[
i
][
"DetNormalizeImage"
]);
}
}
if
(
config_node
[
i
][
"DetPermute"
].
IsDefined
())
{
if
(
config_node
[
i
][
"DetPermute"
].
IsDefined
())
{
ops_
[
"Permute"
]
=
std
::
make_shared
<
Permute
>
();
ops_
[
"Permute"
]
=
std
::
make_shared
<
Permute
>
();
ops_
[
"Permute"
]
->
Init
(
config_node
[
i
][
"DetPermute"
]);
ops_
[
"Permute"
]
->
Init
(
config_node
[
i
][
"DetPermute"
]);
}
}
if
(
config_node
[
i
][
"DetPadStrid"
].
IsDefined
())
{
if
(
config_node
[
i
][
"DetPadStrid"
].
IsDefined
())
{
ops_
[
"PadStride"
]
=
std
::
make_shared
<
PadStride
>
();
ops_
[
"PadStride"
]
=
std
::
make_shared
<
PadStride
>
();
ops_
[
"PadStride"
]
->
Init
(
config_node
[
i
][
"DetPadStrid"
]);
ops_
[
"PadStride"
]
->
Init
(
config_node
[
i
][
"DetPadStrid"
]);
}
}
}
}
}
}
void
Run
(
cv
::
Mat
*
im
,
ImageBlob
*
data
);
void
Run
(
cv
::
Mat
*
im
,
ImageBlob
*
data
);
public:
public:
static
const
std
::
vector
<
std
::
string
>
RUN_ORDER
;
static
const
std
::
vector
<
std
::
string
>
RUN_ORDER
;
private:
private:
std
::
unordered_map
<
std
::
string
,
std
::
shared_ptr
<
PreprocessOp
>>
ops_
;
std
::
unordered_map
<
std
::
string
,
std
::
shared_ptr
<
PreprocessOp
>>
ops_
;
};
};
}
// namespace Detection
}
// namespace Detection
deploy/cpp_shitu/include/vector_search.h
浏览文件 @
29f8fb83
...
@@ -26,40 +26,45 @@
...
@@ -26,40 +26,45 @@
#include <map>
#include <map>
struct
SearchResult
{
struct
SearchResult
{
std
::
vector
<
faiss
::
Index
::
idx_t
>
I
;
std
::
vector
<
faiss
::
Index
::
idx_t
>
I
;
std
::
vector
<
float
>
D
;
std
::
vector
<
float
>
D
;
int
return_k
;
int
return_k
;
};
};
class
VectorSearch
{
class
VectorSearch
{
public:
public:
explicit
VectorSearch
(
const
YAML
::
Node
&
config_file
)
{
explicit
VectorSearch
(
const
YAML
::
Node
&
config_file
)
{
// IndexProcess
// IndexProcess
this
->
index_dir
=
this
->
index_dir
=
config_file
[
"IndexProcess"
][
"index_dir"
].
as
<
std
::
string
>
();
config_file
[
"IndexProcess"
][
"index_dir"
].
as
<
std
::
string
>
();
this
->
return_k
=
config_file
[
"IndexProcess"
][
"return_k"
].
as
<
int
>
();
this
->
return_k
=
config_file
[
"IndexProcess"
][
"return_k"
].
as
<
int
>
();
this
->
score_thres
=
config_file
[
"IndexProcess"
][
"score_thres"
].
as
<
float
>
();
this
->
score_thres
=
config_file
[
"IndexProcess"
][
"score_thres"
].
as
<
float
>
();
this
->
max_query_number
=
this
->
max_query_number
=
config_file
[
"Global"
][
"max_det_results"
].
as
<
int
>
()
+
1
;
config_file
[
"Global"
][
"max_det_results"
].
as
<
int
>
()
+
1
;
LoadIdMap
();
LoadIdMap
();
LoadIndexFile
();
LoadIndexFile
();
this
->
I
.
resize
(
this
->
return_k
*
this
->
max_query_number
);
this
->
I
.
resize
(
this
->
return_k
*
this
->
max_query_number
);
this
->
D
.
resize
(
this
->
return_k
*
this
->
max_query_number
);
this
->
D
.
resize
(
this
->
return_k
*
this
->
max_query_number
);
};
};
void
LoadIdMap
();
void
LoadIndexFile
();
void
LoadIdMap
();
const
SearchResult
&
Search
(
float
*
feature
,
int
query_number
);
const
std
::
string
&
GetLabel
(
faiss
::
Index
::
idx_t
ind
);
void
LoadIndexFile
();
const
float
&
GetThreshold
()
{
return
this
->
score_thres
;
}
const
SearchResult
&
Search
(
float
*
feature
,
int
query_number
);
const
std
::
string
&
GetLabel
(
faiss
::
Index
::
idx_t
ind
);
const
float
&
GetThreshold
()
{
return
this
->
score_thres
;
}
private:
private:
std
::
string
index_dir
;
std
::
string
index_dir
;
int
return_k
=
5
;
int
return_k
=
5
;
float
score_thres
=
0.5
;
float
score_thres
=
0.5
;
std
::
map
<
long
int
,
std
::
string
>
id_map
;
std
::
map
<
long
int
,
std
::
string
>
id_map
;
faiss
::
Index
*
index
;
faiss
::
Index
*
index
;
int
max_query_number
=
6
;
int
max_query_number
=
6
;
std
::
vector
<
float
>
D
;
std
::
vector
<
float
>
D
;
std
::
vector
<
faiss
::
Index
::
idx_t
>
I
;
std
::
vector
<
faiss
::
Index
::
idx_t
>
I
;
SearchResult
sr
;
SearchResult
sr
;
};
};
deploy/cpp_shitu/include/yaml_config.h
浏览文件 @
29f8fb83
...
@@ -42,12 +42,17 @@
...
@@ -42,12 +42,17 @@
class
YamlConfig
{
class
YamlConfig
{
public:
public:
explicit
YamlConfig
(
const
std
::
string
&
path
)
{
explicit
YamlConfig
(
const
std
::
string
&
path
)
{
config_file
=
ReadYamlConfig
(
path
);
config_file
=
ReadYamlConfig
(
path
);
}
}
static
std
::
vector
<
std
::
string
>
ReadDict
(
const
std
::
string
&
path
);
static
std
::
map
<
int
,
std
::
string
>
ReadIndexId
(
const
std
::
string
&
path
);
static
std
::
vector
<
std
::
string
>
ReadDict
(
const
std
::
string
&
path
);
static
YAML
::
Node
ReadYamlConfig
(
const
std
::
string
&
path
);
void
PrintConfigInfo
();
static
std
::
map
<
int
,
std
::
string
>
ReadIndexId
(
const
std
::
string
&
path
);
YAML
::
Node
config_file
;
static
YAML
::
Node
ReadYamlConfig
(
const
std
::
string
&
path
);
void
PrintConfigInfo
();
YAML
::
Node
config_file
;
};
};
deploy/cpp_shitu/readme.md
浏览文件 @
29f8fb83
...
@@ -6,10 +6,7 @@
...
@@ -6,10 +6,7 @@
## 1. 准备环境
## 1. 准备环境
### 运行准备
### 运行准备
-
Linux环境,推荐使用docker。
-
Linux环境,推荐使用ubuntu docker。
-
Windows环境,目前支持基于
`Visual Studio 2019 Community`
进行编译;此外,如果您希望通过生成
`sln解决方案`
的方式进行编译,可以参考该文档:
[
https://zhuanlan.zhihu.com/p/145446681
](
https://zhuanlan.zhihu.com/p/145446681
)
*
该文档主要介绍基于Linux环境下的PaddleClas C++预测流程,如果需要在Windows环境下使用预测库进行C++预测,具体编译方法请参考
[
Windows下编译教程
](
./docs/windows_vs2019_build.md
)
。
### 1.1 编译opencv库
### 1.1 编译opencv库
...
@@ -103,7 +100,7 @@ make -j
...
@@ -103,7 +100,7 @@ make -j
make inference_lib_dist
make inference_lib_dist
```
```
更多编译参数选项可以参考
Paddle C++预测库官网:
[
https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/guides/05_inference_deployment/inference/build_and_install_lib_cn.html#id16
](
https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/guides/05_inference_deployment/inference/build_and_install_lib_cn.html#id16
)
。
更多编译参数选项可以参考
[
Paddle C++预测库官网
](
https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/guides/05_inference_deployment/inference/build_and_install_lib_cn.html#id16
)
。
*
编译完成之后,可以在
`build/paddle_inference_install_dir/`
文件下看到生成了以下文件及文件夹。
*
编译完成之后,可以在
`build/paddle_inference_install_dir/`
文件下看到生成了以下文件及文件夹。
...
@@ -137,29 +134,27 @@ tar -xvf paddle_inference.tgz
...
@@ -137,29 +134,27 @@ tar -xvf paddle_inference.tgz
### 1.3 安装faiss库
### 1.3 安装faiss库
```
shell
```
shell
# 下载 faiss
git clone https://github.com/facebookresearch/faiss.git
git clone https://github.com/facebookresearch/faiss.git
cd
faiss
cd
faiss
cmake
-B
build
.
-DFAISS_ENABLE_PYTHON
=
OFF
-DCMAKE_INSTALL_PREFIX
=
${
faiss_install_path
}
cmake
-B
build
.
-DFAISS_ENABLE_PYTHON
=
OFF
-DCMAKE_INSTALL_PREFIX
=
${
faiss_install_path
}
make
-C
build
-j
faiss
make
-C
build
-j
faiss
make
-C
build
install
make
-C
build
install
```
```
## 2 开始运行
在安装
`faiss`
前,请安装
`openblas`
,
`ubuntu`
系统中安装命令如下:
### 2.1 将模型导出为inference model
```
shell
apt-get
install
libopenblas-dev
```
*
可以参考
[
模型导出
](
../../tools/export_model.py
)
,导出
`inference model`
,用于模型预测。得到预测模型后,假设模型文件放在
`inference`
目录下,则目录结构如下
。
注意本教程以安装faiss cpu版本为例,安装时请参考
[
faiss
](
https://github.com/facebookresearch/faiss
)
官网文档,根据需求自行安装
。
```
## 2 代码编译
inference/
|--cls_infer.pdmodel
|--cls_infer.pdiparams
```
**注意**
:上述文件中,
`cls_infer.pdmodel`
文件存储了模型结构信息,
`cls_infer.pdiparams`
文件存储了模型参数信息。注意两个文件的路径需要与配置文件
`tools/config.txt`
中的
`cls_model_path`
和
`cls_params_path`
参数对应一致。
### 2.2 编译PaddleClas C++预测demo
### 2.2 编译PaddleClas C++预测demo
*
编译命令如下,其中Paddle C++预测库、opencv等其他依赖库的地址需要换成自己机器上的实际地址
。
编译命令如下,其中Paddle C++预测库、opencv等其他依赖库的地址需要换成自己机器上的实际地址。同时,编译过程中需要下载编译
`yaml-cpp`
等C++库,请保持联网环境
。
```
shell
```
shell
...
@@ -169,11 +164,12 @@ sh tools/build.sh
...
@@ -169,11 +164,12 @@ sh tools/build.sh
具体地,
`tools/build.sh`
中内容如下。
具体地,
`tools/build.sh`
中内容如下。
```
shell
```
shell
OPENCV_DIR
=
your_opencv_dir
OPENCV_DIR
=
${
opencv_install_dir
}
LIB_DIR
=
your_paddle_inference_dir
LIB_DIR
=
${
paddle_inference_dir
}
CUDA_LIB_DIR
=
your_cuda_lib_dir
CUDA_LIB_DIR
=
/usr/local/cuda/lib64
CUDNN_LIB_DIR
=
your_cudnn_lib_dir
CUDNN_LIB_DIR
=
/usr/lib/x86_64-linux-gnu/
TENSORRT_DIR
=
your_tensorrt_lib_dir
FAISS_DIR
=
${
faiss_install_dir
}
FAISS_WITH_MKL
=
OFF
BUILD_DIR
=
build
BUILD_DIR
=
build
rm
-rf
${
BUILD_DIR
}
rm
-rf
${
BUILD_DIR
}
...
@@ -182,14 +178,14 @@ cd ${BUILD_DIR}
...
@@ -182,14 +178,14 @@ cd ${BUILD_DIR}
cmake ..
\
cmake ..
\
-DPADDLE_LIB
=
${
LIB_DIR
}
\
-DPADDLE_LIB
=
${
LIB_DIR
}
\
-DWITH_MKL
=
ON
\
-DWITH_MKL
=
ON
\
-DDEMO_NAME
=
clas_system
\
-DWITH_GPU
=
OFF
\
-DWITH_GPU
=
OFF
\
-DWITH_STATIC_LIB
=
OFF
\
-DWITH_STATIC_LIB
=
OFF
\
-DWITH_TENSORRT
=
OFF
\
-DUSE_TENSORRT
=
OFF
\
-DTENSORRT_DIR
=
${
TENSORRT_DIR
}
\
-DOPENCV_DIR
=
${
OPENCV_DIR
}
\
-DOPENCV_DIR
=
${
OPENCV_DIR
}
\
-DCUDNN_LIB
=
${
CUDNN_LIB_DIR
}
\
-DCUDNN_LIB
=
${
CUDNN_LIB_DIR
}
\
-DCUDA_LIB
=
${
CUDA_LIB_DIR
}
\
-DCUDA_LIB
=
${
CUDA_LIB_DIR
}
\
-DFAISS_DIR
=
${
FAISS_DIR
}
\
-DFAISS_WITH_MKL
=
${
FAISS_WITH_MKL
}
make
-j
make
-j
```
```
...
@@ -197,47 +193,75 @@ make -j
...
@@ -197,47 +193,75 @@ make -j
上述命令中,
上述命令中,
*
`OPENCV_DIR`
为opencv编译安装的地址(本例中为
`opencv-3.4.7/opencv3`
文件夹的路径);
*
`OPENCV_DIR`
为opencv编译安装的地址(本例中为
`opencv-3.4.7/opencv3`
文件夹的路径);
*
`LIB_DIR`
为下载的Paddle预测库(
`paddle_inference`
文件夹),或编译生成的Paddle预测库(
`build/paddle_inference_install_dir`
文件夹)的路径;
*
`LIB_DIR`
为下载的Paddle预测库(
`paddle_inference`
文件夹),或编译生成的Paddle预测库(
`build/paddle_inference_install_dir`
文件夹)的路径;
*
`CUDA_LIB_DIR`
为cuda库文件地址,在docker中为
`/usr/local/cuda/lib64`
;
*
`CUDA_LIB_DIR`
为cuda库文件地址,在docker中为
`/usr/local/cuda/lib64`
;
*
`CUDNN_LIB_DIR`
为cudnn库文件地址,在docker中为
`/usr/lib/x86_64-linux-gnu/`
。
*
`CUDNN_LIB_DIR`
为cudnn库文件地址,在docker中为
`/usr/lib/x86_64-linux-gnu/`
。
*
`TENSORRT_DIR`
是tensorrt库文件地址,在dokcer中为
`/usr/local/TensorRT6-cuda10.0-cudnn7/`
,TensorRT需要结合GPU使用。
*
`TENSORRT_DIR`
是tensorrt库文件地址,在dokcer中为
`/usr/local/TensorRT6-cuda10.0-cudnn7/`
,TensorRT需要结合GPU使用。
*
`FAISS_DIR`
是faiss的安装地址
*
`FAISS_WITH_MKL`
是指在编译faiss的过程中,是否使用了mkldnn,本文档中编译faiss,没有使用,而使用了openblas,故设置为
`OFF`
,若使用了mkldnn,则为
`ON`
.
在执行上述命令,编译完成之后,会在当前路径下生成
`build`
文件夹,其中生成一个名为
`clas_system`
的可执行文件。
在执行上述命令,编译完成之后,会在当前路径下生成
`build`
文件夹,其中生成一个名为
`pp_shitu`
的可执行文件。
### 运行demo
## 3 运行demo
*
首先修改
`tools/config.txt`
中对应字段:
*
use_gpu:是否使用GPU;
*
gpu_id:使用的GPU卡号;
*
gpu_mem:显存;
*
cpu_math_library_num_threads:底层科学计算库所用线程的数量;
*
use_mkldnn:是否使用MKLDNN加速;
*
use_tensorrt: 是否使用tensorRT进行加速;
*
use_fp16:是否使用半精度浮点数进行计算,该选项仅在use_tensorrt为true时有效;
*
cls_model_path:预测模型结构文件路径;
*
cls_params_path:预测模型参数文件路径;
*
resize_short_size:预处理时图像缩放大小;
*
crop_size:预处理时图像裁剪后的大小。
*
然后修改
`tools/run.sh`
:
-
请参考
[
识别快速开始文档
](
../../docs/zh_CN/quick_start/quick_start_recognition.md
)
,下载好相应的 轻量级通用主体检测模型、轻量级通用识别模型及瓶装饮料测试数据并解压。
*
`./build/clas_system ./tools/config.txt ./docs/imgs/ILSVRC2012_val_00000666.JPEG`
*
上述命令中分别为:编译得到的可执行文件
`clas_system`
;运行时的配置文件
`config.txt`
;待预测的图像。
*
最后执行以下命令,完成对一幅图像的分类。
```
shell
mkdir
models
cd
models
wget https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/picodet_PPLCNet_x2_5_mainbody_lite_v1.0_infer.tar
tar
-xf
picodet_PPLCNet_x2_5_mainbody_lite_v1.0_infer.tar
wget https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/general_PPLCNet_x2_5_lite_v1.0_infer.tar
tar
-xf
general_PPLCNet_x2_5_lite_v1.0_infer.tar
cd
..
mkdir
data
cd
data
wget https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/data/drink_dataset_v1.0.tar
tar
-xf
drink_dataset_v1.0.tar
cd
..
```
```
shell
-
将相应的yaml文件拷到
`test`
文件夹下
sh tools/run.sh
```
```
shell
cp
../configs/inference_drink.yaml .
```
-
将
`inference_drink.yaml`
中的相对路径,改成基于本目录的路径或者绝对路径。涉及到的参数有
-
Global.infer_imgs :此参数可以是具体的图像地址,也可以是图像集所在的目录
-
Global.det_inference_model_dir : 检测模型存储目录
-
Global.rec_inference_model_dir : 识别模型存储目录
-
IndexProcess.index_dir : 检索库的存储目录,在示例中,检索库在下载的demo数据中。
-
字典转换
由于python的检索库的字典,使用
`pickle`
进行的序列化存储,导致C++不方便读取,因此进行转换
```
shell
python tools/transform_id_map.py
-c
inference_drink.yaml
```
转换成功后,在
`IndexProcess.index_dir`
目录下生成
`id_map.txt`
,方便c++ 读取。
-
执行程序
```
shell
./build/pp_shitu
-c
inference_drink.yaml
# or
./build/pp_shitu
-config
inference_drink.yaml
```
若对图像集进行检索,则可能得到,如下结果。注意,此结果只做展示,具体以实际运行结果为准。
同时,需注意的是,由于opencv 版本问题,会导致图像在预处理的过程中,resize产生细微差别,导致python 和c++结果,轻微不同,如bbox相差几个像素,检索结果小数点后3位diff等。但不会改变最终检索label。
*
最终屏幕上会输出结果,如下图所示。
!
[](
../../docs/images/quick_start/shitu_c++_result.png
)
<div
align=
"center"
>
## 4 使用自己模型
<img
src=
"./docs/imgs/cpp_infer_result.png"
width=
"600"
>
</div>
使用自己训练的模型,可以参考
[
模型导出
](
../../docs/zh_CN/inference_deployment/export_model.md
)
,导出
`inference model`
,用于模型预测。
其中
`class id`
表示置信度最高的类别对应的id,score表示图片属于该类别的概率
。
同时注意修改
`yaml`
文件中具体参数
。
deploy/cpp_shitu/src/feature_extracter.cpp
浏览文件 @
29f8fb83
...
@@ -18,102 +18,102 @@
...
@@ -18,102 +18,102 @@
namespace
Feature
{
namespace
Feature
{
void
FeatureExtracter
::
LoadModel
(
const
std
::
string
&
model_path
,
void
FeatureExtracter
::
LoadModel
(
const
std
::
string
&
model_path
,
const
std
::
string
&
params_path
)
{
const
std
::
string
&
params_path
)
{
paddle_infer
::
Config
config
;
paddle_infer
::
Config
config
;
config
.
SetModel
(
model_path
,
params_path
);
config
.
SetModel
(
model_path
,
params_path
);
if
(
this
->
use_gpu_
)
{
if
(
this
->
use_gpu_
)
{
config
.
EnableUseGpu
(
this
->
gpu_mem_
,
this
->
gpu_id_
);
config
.
EnableUseGpu
(
this
->
gpu_mem_
,
this
->
gpu_id_
);
if
(
this
->
use_tensorrt_
)
{
if
(
this
->
use_tensorrt_
)
{
config
.
EnableTensorRtEngine
(
config
.
EnableTensorRtEngine
(
1
<<
20
,
1
,
3
,
1
<<
20
,
1
,
3
,
this
->
use_fp16_
?
paddle_infer
::
Config
::
Precision
::
kHalf
this
->
use_fp16_
?
paddle_infer
::
Config
::
Precision
::
kHalf
:
paddle_infer
::
Config
::
Precision
::
kFloat32
,
:
paddle_infer
::
Config
::
Precision
::
kFloat32
,
false
,
false
);
false
,
false
);
}
}
else
{
config
.
DisableGpu
();
if
(
this
->
use_mkldnn_
)
{
config
.
EnableMKLDNN
();
// cache 10 different shapes for mkldnn to avoid memory leak
config
.
SetMkldnnCacheCapacity
(
10
);
}
config
.
SetCpuMathLibraryNumThreads
(
this
->
cpu_math_library_num_threads_
);
}
config
.
SwitchUseFeedFetchOps
(
false
);
// true for multiple input
config
.
SwitchSpecifyInputNames
(
true
);
config
.
SwitchIrOptim
(
true
);
config
.
EnableMemoryOptim
();
config
.
DisableGlogInfo
();
this
->
predictor_
=
CreatePredictor
(
config
);
}
}
}
else
{
config
.
DisableGpu
();
void
FeatureExtracter
::
Run
(
cv
::
Mat
&
img
,
std
::
vector
<
float
>
&
out_data
,
if
(
this
->
use_mkldnn_
)
{
std
::
vector
<
double
>
&
times
)
{
config
.
EnableMKLDNN
();
cv
::
Mat
resize_img
;
// cache 10 different shapes for mkldnn to avoid memory leak
std
::
vector
<
double
>
time
;
config
.
SetMkldnnCacheCapacity
(
10
);
auto
preprocess_start
=
std
::
chrono
::
system_clock
::
now
();
this
->
resize_op_
.
Run
(
img
,
resize_img
,
this
->
resize_short_
,
this
->
resize_size_
);
this
->
normalize_op_
.
Run
(
&
resize_img
,
this
->
mean_
,
this
->
std_
,
this
->
scale_
);
std
::
vector
<
float
>
input
(
1
*
3
*
resize_img
.
rows
*
resize_img
.
cols
,
0.0
f
);
this
->
permute_op_
.
Run
(
&
resize_img
,
input
.
data
());
auto
input_names
=
this
->
predictor_
->
GetInputNames
();
auto
input_t
=
this
->
predictor_
->
GetInputHandle
(
input_names
[
0
]);
input_t
->
Reshape
({
1
,
3
,
resize_img
.
rows
,
resize_img
.
cols
});
auto
preprocess_end
=
std
::
chrono
::
system_clock
::
now
();
auto
infer_start
=
std
::
chrono
::
system_clock
::
now
();
input_t
->
CopyFromCpu
(
input
.
data
());
this
->
predictor_
->
Run
();
auto
output_names
=
this
->
predictor_
->
GetOutputNames
();
auto
output_t
=
this
->
predictor_
->
GetOutputHandle
(
output_names
[
0
]);
std
::
vector
<
int
>
output_shape
=
output_t
->
shape
();
int
out_num
=
std
::
accumulate
(
output_shape
.
begin
(),
output_shape
.
end
(),
1
,
std
::
multiplies
<
int
>
());
out_data
.
resize
(
out_num
);
output_t
->
CopyToCpu
(
out_data
.
data
());
auto
infer_end
=
std
::
chrono
::
system_clock
::
now
();
auto
postprocess_start
=
std
::
chrono
::
system_clock
::
now
();
if
(
this
->
feature_norm
)
FeatureNorm
(
out_data
);
auto
postprocess_end
=
std
::
chrono
::
system_clock
::
now
();
std
::
chrono
::
duration
<
float
>
preprocess_diff
=
preprocess_end
-
preprocess_start
;
time
.
push_back
(
double
(
preprocess_diff
.
count
()));
std
::
chrono
::
duration
<
float
>
inference_diff
=
infer_end
-
infer_start
;
double
inference_cost_time
=
double
(
inference_diff
.
count
());
time
.
push_back
(
inference_cost_time
);
// std::chrono::duration<float> postprocess_diff =
// postprocess_end - postprocess_start;
time
.
push_back
(
0
);
// std::cout << "result: " << std::endl;
// std::cout << "\tclass id: " << maxPosition << std::endl;
// std::cout << std::fixed << std::setprecision(10)
// << "\tscore: " << double(out_data[maxPosition]) << std::endl;
times
[
0
]
+=
time
[
0
];
times
[
1
]
+=
time
[
1
];
times
[
2
]
+=
time
[
2
];
}
void
FeatureExtracter
::
FeatureNorm
(
std
::
vector
<
float
>
&
featuer
)
{
float
featuer_sqrt
=
std
::
sqrt
(
std
::
inner_product
(
featuer
.
begin
(),
featuer
.
end
(),
featuer
.
begin
(),
0.0
f
));
for
(
int
i
=
0
;
i
<
featuer
.
size
();
++
i
)
featuer
[
i
]
/=
featuer_sqrt
;
}
}
config
.
SetCpuMathLibraryNumThreads
(
this
->
cpu_math_library_num_threads_
);
}
config
.
SwitchUseFeedFetchOps
(
false
);
// true for multiple input
config
.
SwitchSpecifyInputNames
(
true
);
config
.
SwitchIrOptim
(
true
);
config
.
EnableMemoryOptim
();
config
.
DisableGlogInfo
();
this
->
predictor_
=
CreatePredictor
(
config
);
}
void
FeatureExtracter
::
Run
(
cv
::
Mat
&
img
,
std
::
vector
<
float
>
&
out_data
,
std
::
vector
<
double
>
&
times
)
{
cv
::
Mat
resize_img
;
std
::
vector
<
double
>
time
;
auto
preprocess_start
=
std
::
chrono
::
system_clock
::
now
();
this
->
resize_op_
.
Run
(
img
,
resize_img
,
this
->
resize_short_
,
this
->
resize_size_
);
this
->
normalize_op_
.
Run
(
&
resize_img
,
this
->
mean_
,
this
->
std_
,
this
->
scale_
);
std
::
vector
<
float
>
input
(
1
*
3
*
resize_img
.
rows
*
resize_img
.
cols
,
0.0
f
);
this
->
permute_op_
.
Run
(
&
resize_img
,
input
.
data
());
auto
input_names
=
this
->
predictor_
->
GetInputNames
();
auto
input_t
=
this
->
predictor_
->
GetInputHandle
(
input_names
[
0
]);
input_t
->
Reshape
({
1
,
3
,
resize_img
.
rows
,
resize_img
.
cols
});
auto
preprocess_end
=
std
::
chrono
::
system_clock
::
now
();
auto
infer_start
=
std
::
chrono
::
system_clock
::
now
();
input_t
->
CopyFromCpu
(
input
.
data
());
this
->
predictor_
->
Run
();
auto
output_names
=
this
->
predictor_
->
GetOutputNames
();
auto
output_t
=
this
->
predictor_
->
GetOutputHandle
(
output_names
[
0
]);
std
::
vector
<
int
>
output_shape
=
output_t
->
shape
();
int
out_num
=
std
::
accumulate
(
output_shape
.
begin
(),
output_shape
.
end
(),
1
,
std
::
multiplies
<
int
>
());
out_data
.
resize
(
out_num
);
output_t
->
CopyToCpu
(
out_data
.
data
());
auto
infer_end
=
std
::
chrono
::
system_clock
::
now
();
auto
postprocess_start
=
std
::
chrono
::
system_clock
::
now
();
if
(
this
->
feature_norm
)
FeatureNorm
(
out_data
);
auto
postprocess_end
=
std
::
chrono
::
system_clock
::
now
();
std
::
chrono
::
duration
<
float
>
preprocess_diff
=
preprocess_end
-
preprocess_start
;
time
.
push_back
(
double
(
preprocess_diff
.
count
()));
std
::
chrono
::
duration
<
float
>
inference_diff
=
infer_end
-
infer_start
;
double
inference_cost_time
=
double
(
inference_diff
.
count
());
time
.
push_back
(
inference_cost_time
);
// std::chrono::duration<float> postprocess_diff =
// postprocess_end - postprocess_start;
time
.
push_back
(
0
);
// std::cout << "result: " << std::endl;
// std::cout << "\tclass id: " << maxPosition << std::endl;
// std::cout << std::fixed << std::setprecision(10)
// << "\tscore: " << double(out_data[maxPosition]) << std::endl;
times
[
0
]
+=
time
[
0
];
times
[
1
]
+=
time
[
1
];
times
[
2
]
+=
time
[
2
];
}
void
FeatureExtracter
::
FeatureNorm
(
std
::
vector
<
float
>
&
featuer
)
{
float
featuer_sqrt
=
std
::
sqrt
(
std
::
inner_product
(
featuer
.
begin
(),
featuer
.
end
(),
featuer
.
begin
(),
0.0
f
));
for
(
int
i
=
0
;
i
<
featuer
.
size
();
++
i
)
featuer
[
i
]
/=
featuer_sqrt
;
}
}
// namespace Feature
}
// namespace Feature
deploy/cpp_shitu/src/main.cpp
浏览文件 @
29f8fb83
...
@@ -37,260 +37,262 @@
...
@@ -37,260 +37,262 @@
using
namespace
std
;
using
namespace
std
;
using
namespace
cv
;
using
namespace
cv
;
DEFINE_string
(
config
,
""
,
"Path of yaml file"
);
DEFINE_string
(
config
,
DEFINE_string
(
c
,
""
,
"Path of yaml file"
);
""
,
"Path of yaml file"
);
DEFINE_string
(
c
,
""
,
"Path of yaml file"
);
void
DetPredictImage
(
const
std
::
vector
<
cv
::
Mat
>
&
batch_imgs
,
void
DetPredictImage
(
const
std
::
vector
<
cv
::
Mat
>
&
batch_imgs
,
const
std
::
vector
<
std
::
string
>
&
all_img_paths
,
const
std
::
vector
<
std
::
string
>
&
all_img_paths
,
const
int
batch_size
,
Detection
::
ObjectDetector
*
det
,
const
int
batch_size
,
Detection
::
ObjectDetector
*
det
,
std
::
vector
<
Detection
::
ObjectResult
>
&
im_result
,
std
::
vector
<
Detection
::
ObjectResult
>
&
im_result
,
std
::
vector
<
int
>
&
im_bbox_num
,
std
::
vector
<
double
>
&
det_t
,
std
::
vector
<
int
>
&
im_bbox_num
,
std
::
vector
<
double
>
&
det_t
,
const
bool
visual_det
=
false
,
const
bool
visual_det
=
false
,
const
bool
run_benchmark
=
false
,
const
bool
run_benchmark
=
false
,
const
std
::
string
&
output_dir
=
"output"
)
{
const
std
::
string
&
output_dir
=
"output"
)
{
int
steps
=
ceil
(
float
(
all_img_paths
.
size
())
/
batch_size
);
int
steps
=
ceil
(
float
(
all_img_paths
.
size
())
/
batch_size
);
// printf("total images = %d, batch_size = %d, total steps = %d\n",
// printf("total images = %d, batch_size = %d, total steps = %d\n",
// all_img_paths.size(), batch_size, steps);
// all_img_paths.size(), batch_size, steps);
for
(
int
idx
=
0
;
idx
<
steps
;
idx
++
)
{
for
(
int
idx
=
0
;
idx
<
steps
;
idx
++
)
{
int
left_image_cnt
=
all_img_paths
.
size
()
-
idx
*
batch_size
;
int
left_image_cnt
=
all_img_paths
.
size
()
-
idx
*
batch_size
;
if
(
left_image_cnt
>
batch_size
)
{
if
(
left_image_cnt
>
batch_size
)
{
left_image_cnt
=
batch_size
;
left_image_cnt
=
batch_size
;
}
}
// for (int bs = 0; bs < left_image_cnt; bs++) {
// for (int bs = 0; bs < left_image_cnt; bs++) {
// std::string image_file_path = all_img_paths.at(idx * batch_size+bs);
// std::string image_file_path = all_img_paths.at(idx * batch_size+bs);
// cv::Mat im = cv::imread(image_file_path, 1);
// cv::Mat im = cv::imread(image_file_path, 1);
// batch_imgs.insert(batch_imgs.end(), im);
// batch_imgs.insert(batch_imgs.end(), im);
// }
// }
// Store all detected result
// Store all detected result
std
::
vector
<
Detection
::
ObjectResult
>
result
;
std
::
vector
<
Detection
::
ObjectResult
>
result
;
std
::
vector
<
int
>
bbox_num
;
std
::
vector
<
int
>
bbox_num
;
std
::
vector
<
double
>
det_times
;
std
::
vector
<
double
>
det_times
;
bool
is_rbox
=
false
;
bool
is_rbox
=
false
;
if
(
run_benchmark
)
{
if
(
run_benchmark
)
{
det
->
Predict
(
batch_imgs
,
10
,
10
,
&
result
,
&
bbox_num
,
&
det_times
);
det
->
Predict
(
batch_imgs
,
10
,
10
,
&
result
,
&
bbox_num
,
&
det_times
);
}
else
{
}
else
{
det
->
Predict
(
batch_imgs
,
0
,
1
,
&
result
,
&
bbox_num
,
&
det_times
);
det
->
Predict
(
batch_imgs
,
0
,
1
,
&
result
,
&
bbox_num
,
&
det_times
);
// get labels and colormap
// get labels and colormap
auto
labels
=
det
->
GetLabelList
();
auto
labels
=
det
->
GetLabelList
();
auto
colormap
=
Detection
::
GenerateColorMap
(
labels
.
size
());
auto
colormap
=
Detection
::
GenerateColorMap
(
labels
.
size
());
int
item_start_idx
=
0
;
int
item_start_idx
=
0
;
for
(
int
i
=
0
;
i
<
left_image_cnt
;
i
++
)
{
for
(
int
i
=
0
;
i
<
left_image_cnt
;
i
++
)
{
cv
::
Mat
im
=
batch_imgs
[
i
];
cv
::
Mat
im
=
batch_imgs
[
i
];
int
detect_num
=
0
;
int
detect_num
=
0
;
for
(
int
j
=
0
;
j
<
bbox_num
[
i
];
j
++
)
{
for
(
int
j
=
0
;
j
<
bbox_num
[
i
];
j
++
)
{
Detection
::
ObjectResult
item
=
result
[
item_start_idx
+
j
];
Detection
::
ObjectResult
item
=
result
[
item_start_idx
+
j
];
if
(
item
.
confidence
<
det
->
GetThreshold
()
||
item
.
class_id
==
-
1
)
{
if
(
item
.
confidence
<
det
->
GetThreshold
()
||
item
.
class_id
==
-
1
)
{
continue
;
continue
;
}
}
detect_num
+=
1
;
detect_num
+=
1
;
im_result
.
push_back
(
item
);
im_result
.
push_back
(
item
);
if
(
visual_det
)
{
if
(
visual_det
)
{
if
(
item
.
rect
.
size
()
>
6
)
{
if
(
item
.
rect
.
size
()
>
6
)
{
is_rbox
=
true
;
is_rbox
=
true
;
printf
(
printf
(
"class=%d confidence=%.4f rect=[%d %d %d %d %d %d %d %d]
\n
"
,
"class=%d confidence=%.4f rect=[%d %d %d %d %d %d %d %d]
\n
"
,
item
.
class_id
,
item
.
confidence
,
item
.
rect
[
0
],
item
.
rect
[
1
],
item
.
class_id
,
item
.
confidence
,
item
.
rect
[
0
],
item
.
rect
[
1
],
item
.
rect
[
2
],
item
.
rect
[
3
],
item
.
rect
[
4
],
item
.
rect
[
5
],
item
.
rect
[
2
],
item
.
rect
[
3
],
item
.
rect
[
4
],
item
.
rect
[
5
],
item
.
rect
[
6
],
item
.
rect
[
7
]);
item
.
rect
[
6
],
item
.
rect
[
7
]);
}
else
{
}
else
{
printf
(
"class=%d confidence=%.4f rect=[%d %d %d %d]
\n
"
,
printf
(
"class=%d confidence=%.4f rect=[%d %d %d %d]
\n
"
,
item
.
class_id
,
item
.
confidence
,
item
.
rect
[
0
],
item
.
rect
[
1
],
item
.
class_id
,
item
.
confidence
,
item
.
rect
[
0
],
item
.
rect
[
1
],
item
.
rect
[
2
],
item
.
rect
[
3
]);
item
.
rect
[
2
],
item
.
rect
[
3
]);
}
}
}
}
}
}
im_bbox_num
.
push_back
(
detect_num
);
im_bbox_num
.
push_back
(
detect_num
);
item_start_idx
=
item_start_idx
+
bbox_num
[
i
];
item_start_idx
=
item_start_idx
+
bbox_num
[
i
];
// Visualization result
// Visualization result
if
(
visual_det
)
{
if
(
visual_det
)
{
std
::
cout
<<
all_img_paths
.
at
(
idx
*
batch_size
+
i
)
std
::
cout
<<
all_img_paths
.
at
(
idx
*
batch_size
+
i
)
<<
" The number of detected box: "
<<
detect_num
<<
" The number of detected box: "
<<
detect_num
<<
std
::
endl
;
<<
std
::
endl
;
cv
::
Mat
vis_img
=
Detection
::
VisualizeResult
(
im
,
im_result
,
labels
,
cv
::
Mat
vis_img
=
Detection
::
VisualizeResult
(
im
,
im_result
,
labels
,
colormap
,
is_rbox
);
colormap
,
is_rbox
);
std
::
vector
<
int
>
compression_params
;
std
::
vector
<
int
>
compression_params
;
compression_params
.
push_back
(
CV_IMWRITE_JPEG_QUALITY
);
compression_params
.
push_back
(
CV_IMWRITE_JPEG_QUALITY
);
compression_params
.
push_back
(
95
);
compression_params
.
push_back
(
95
);
std
::
string
output_path
(
output_dir
);
std
::
string
output_path
(
output_dir
);
if
(
output_dir
.
rfind
(
OS_PATH_SEP
)
!=
output_dir
.
size
()
-
1
)
{
if
(
output_dir
.
rfind
(
OS_PATH_SEP
)
!=
output_dir
.
size
()
-
1
)
{
output_path
+=
OS_PATH_SEP
;
output_path
+=
OS_PATH_SEP
;
}
}
std
::
string
image_file_path
=
all_img_paths
.
at
(
idx
*
batch_size
+
i
);
std
::
string
image_file_path
=
all_img_paths
.
at
(
idx
*
batch_size
+
i
);
output_path
+=
output_path
+=
image_file_path
.
substr
(
image_file_path
.
find_last_of
(
'/'
)
+
1
);
image_file_path
.
substr
(
image_file_path
.
find_last_of
(
'/'
)
+
1
);
cv
::
imwrite
(
output_path
,
vis_img
,
compression_params
);
cv
::
imwrite
(
output_path
,
vis_img
,
compression_params
);
printf
(
"Visualized output saved as %s
\n
"
,
output_path
.
c_str
());
printf
(
"Visualized output saved as %s
\n
"
,
output_path
.
c_str
());
}
}
}
}
}
det_t
[
0
]
+=
det_times
[
0
];
det_t
[
1
]
+=
det_times
[
1
];
det_t
[
2
]
+=
det_times
[
2
];
}
}
det_t
[
0
]
+=
det_times
[
0
];
det_t
[
1
]
+=
det_times
[
1
];
det_t
[
2
]
+=
det_times
[
2
];
}
}
}
void
PrintResult
(
std
::
string
&
img_path
,
void
PrintResult
(
std
::
string
&
img_path
,
std
::
vector
<
Detection
::
ObjectResult
>
&
det_result
,
std
::
vector
<
Detection
::
ObjectResult
>
&
det_result
,
std
::
vector
<
int
>
&
indeices
,
VectorSearch
&
vector_search
,
std
::
vector
<
int
>
&
indeices
,
VectorSearch
&
vector_search
,
SearchResult
&
search_result
)
{
SearchResult
&
search_result
)
{
printf
(
"%s:
\n
"
,
img_path
.
c_str
());
printf
(
"%s:
\n
"
,
img_path
.
c_str
());
for
(
int
i
=
0
;
i
<
indeices
.
size
();
++
i
)
{
for
(
int
i
=
0
;
i
<
indeices
.
size
();
++
i
)
{
int
t
=
indeices
[
i
];
int
t
=
indeices
[
i
];
printf
(
"
\t
result%d: bbox[%d, %d, %d, %d], score: %f, label: %s
\n
"
,
i
,
printf
(
"
\t
result%d: bbox[%d, %d, %d, %d], score: %f, label: %s
\n
"
,
i
,
det_result
[
t
].
rect
[
0
],
det_result
[
t
].
rect
[
1
],
det_result
[
t
].
rect
[
2
],
det_result
[
t
].
rect
[
0
],
det_result
[
t
].
rect
[
1
],
det_result
[
t
].
rect
[
2
],
det_result
[
t
].
rect
[
3
],
det_result
[
t
].
confidence
,
det_result
[
t
].
rect
[
3
],
det_result
[
t
].
confidence
,
vector_search
.
GetLabel
(
search_result
.
I
[
search_result
.
return_k
*
t
])
vector_search
.
GetLabel
(
search_result
.
I
[
search_result
.
return_k
*
t
])
.
c_str
());
.
c_str
());
}
}
}
}
int
main
(
int
argc
,
char
**
argv
)
{
int
main
(
int
argc
,
char
**
argv
)
{
google
::
ParseCommandLineFlags
(
&
argc
,
&
argv
,
true
);
google
::
ParseCommandLineFlags
(
&
argc
,
&
argv
,
true
);
std
::
string
yaml_path
=
""
;
std
::
string
yaml_path
=
""
;
if
(
FLAGS_config
==
""
&&
FLAGS_c
==
""
)
{
if
(
FLAGS_config
==
""
&&
FLAGS_c
==
""
)
{
std
::
cerr
<<
"[ERROR] usage: "
<<
std
::
endl
std
::
cerr
<<
"[ERROR] usage: "
<<
std
::
endl
<<
argv
[
0
]
<<
" -c $yaml_path"
<<
std
::
endl
<<
argv
[
0
]
<<
" -c $yaml_path"
<<
std
::
endl
<<
"or:"
<<
std
::
endl
<<
"or:"
<<
std
::
endl
<<
argv
[
0
]
<<
" -config $yaml_path"
<<
std
::
endl
;
<<
argv
[
0
]
<<
" -config $yaml_path"
<<
std
::
endl
;
exit
(
1
);
exit
(
1
);
}
else
if
(
FLAGS_config
!=
""
)
{
}
else
if
(
FLAGS_config
!=
""
)
{
yaml_path
=
FLAGS_config
;
yaml_path
=
FLAGS_config
;
}
else
{
}
else
{
yaml_path
=
FLAGS_c
;
yaml_path
=
FLAGS_c
;
}
}
YamlConfig
config
(
yaml_path
);
config
.
PrintConfigInfo
();
// initialize detector, rec_Model, vector_search
YamlConfig
config
(
yaml_path
);
Feature
::
FeatureExtracter
feature_extracter
(
config
.
config_file
);
config
.
PrintConfigInfo
();
Detection
::
ObjectDetector
detector
(
config
.
config_file
);
VectorSearch
searcher
(
config
.
config_file
);
// config
// initialize detector, rec_Model, vector_search
const
int
batch_size
=
config
.
config_file
[
"Global"
][
"batch_size"
].
as
<
int
>
();
Feature
::
FeatureExtracter
feature_extracter
(
config
.
config_file
);
bool
visual_det
=
false
;
Detection
::
ObjectDetector
detector
(
config
.
config_file
);
if
(
config
.
config_file
[
"Global"
][
"visual_det"
].
IsDefined
())
{
VectorSearch
searcher
(
config
.
config_file
);
visual_det
=
config
.
config_file
[
"Global"
][
"visual_det"
].
as
<
bool
>
();
}
bool
run_benchmark
=
false
;
if
(
config
.
config_file
[
"Global"
][
"benchmark"
].
IsDefined
())
{
run_benchmark
=
config
.
config_file
[
"Global"
][
"benchmark"
].
as
<
bool
>
();
}
int
max_det_results
=
5
;
if
(
config
.
config_file
[
"Global"
][
"max_det_results"
].
IsDefined
())
{
max_det_results
=
config
.
config_file
[
"Global"
][
"max_det_results"
].
as
<
int
>
();
}
float
rec_nms_thresold
=
0.05
;
if
(
config
.
config_file
[
"Global"
][
"rec_nms_thresold"
].
IsDefined
())
{
rec_nms_thresold
=
config
.
config_file
[
"Global"
][
"rec_nms_thresold"
].
as
<
float
>
();
}
// load image_file_path
// config
std
::
string
path
=
const
int
batch_size
=
config
.
config_file
[
"Global"
][
"batch_size"
].
as
<
int
>
();
config
.
config_file
[
"Global"
][
"infer_imgs"
].
as
<
std
::
string
>
();
bool
visual_det
=
false
;
std
::
vector
<
std
::
string
>
img_files_list
;
if
(
config
.
config_file
[
"Global"
][
"visual_det"
].
IsDefined
())
{
if
(
cv
::
utils
::
fs
::
isDirectory
(
path
))
{
visual_det
=
config
.
config_file
[
"Global"
][
"visual_det"
].
as
<
bool
>
();
std
::
vector
<
cv
::
String
>
filenames
;
}
cv
::
glob
(
path
,
filenames
);
bool
run_benchmark
=
false
;
for
(
auto
f
:
filenames
)
{
if
(
config
.
config_file
[
"Global"
][
"benchmark"
].
IsDefined
())
{
img_files_list
.
push_back
(
f
);
run_benchmark
=
config
.
config_file
[
"Global"
][
"benchmark"
].
as
<
bool
>
();
}
int
max_det_results
=
5
;
if
(
config
.
config_file
[
"Global"
][
"max_det_results"
].
IsDefined
())
{
max_det_results
=
config
.
config_file
[
"Global"
][
"max_det_results"
].
as
<
int
>
();
}
float
rec_nms_thresold
=
0.05
;
if
(
config
.
config_file
[
"Global"
][
"rec_nms_thresold"
].
IsDefined
())
{
rec_nms_thresold
=
config
.
config_file
[
"Global"
][
"rec_nms_thresold"
].
as
<
float
>
();
}
}
}
else
{
img_files_list
.
push_back
(
path
);
}
std
::
cout
<<
"img_file_list length: "
<<
img_files_list
.
size
()
<<
std
::
endl
;
// for time log
std
::
vector
<
double
>
cls_times
=
{
0
,
0
,
0
};
std
::
vector
<
double
>
det_times
=
{
0
,
0
,
0
};
// for read images
std
::
vector
<
cv
::
Mat
>
batch_imgs
;
std
::
vector
<
std
::
string
>
img_paths
;
// for detection
std
::
vector
<
Detection
::
ObjectResult
>
det_result
;
std
::
vector
<
int
>
det_bbox_num
;
// for vector search
std
::
vector
<
float
>
features
;
std
::
vector
<
float
>
feature
;
// for nms
std
::
vector
<
int
>
indeices
;
int
warmup_iter
=
img_files_list
.
size
()
>
5
?
5
:
0
;
// load image_file_path
for
(
int
idx
=
0
;
idx
<
img_files_list
.
size
();
++
idx
)
{
std
::
string
path
=
std
::
string
img_path
=
img_files_list
[
idx
];
config
.
config_file
[
"Global"
][
"infer_imgs"
].
as
<
std
::
string
>
();
cv
::
Mat
srcimg
=
cv
::
imread
(
img_path
,
cv
::
IMREAD_COLOR
);
std
::
vector
<
std
::
string
>
img_files_list
;
if
(
!
srcimg
.
data
)
{
if
(
cv
::
utils
::
fs
::
isDirectory
(
path
))
{
std
::
cerr
<<
"[ERROR] image read failed! image path: "
<<
img_path
std
::
vector
<
cv
::
String
>
filenames
;
<<
"
\n
"
;
cv
::
glob
(
path
,
filenames
);
exit
(
-
1
);
for
(
auto
f
:
filenames
)
{
img_files_list
.
push_back
(
f
);
}
}
else
{
img_files_list
.
push_back
(
path
);
}
}
cv
::
cvtColor
(
srcimg
,
srcimg
,
cv
::
COLOR_BGR2RGB
);
std
::
cout
<<
"img_file_list length: "
<<
img_files_list
.
size
()
<<
std
::
endl
;
// for time log
std
::
vector
<
double
>
cls_times
=
{
0
,
0
,
0
};
std
::
vector
<
double
>
det_times
=
{
0
,
0
,
0
};
// for read images
std
::
vector
<
cv
::
Mat
>
batch_imgs
;
std
::
vector
<
std
::
string
>
img_paths
;
// for detection
std
::
vector
<
Detection
::
ObjectResult
>
det_result
;
std
::
vector
<
int
>
det_bbox_num
;
// for vector search
std
::
vector
<
float
>
features
;
std
::
vector
<
float
>
feature
;
// for nms
std
::
vector
<
int
>
indeices
;
batch_imgs
.
push_back
(
srcimg
);
int
warmup_iter
=
img_files_list
.
size
()
>
5
?
5
:
0
;
img_paths
.
push_back
(
img_path
);
for
(
int
idx
=
0
;
idx
<
img_files_list
.
size
();
++
idx
)
{
std
::
string
img_path
=
img_files_list
[
idx
];
cv
::
Mat
srcimg
=
cv
::
imread
(
img_path
,
cv
::
IMREAD_COLOR
);
if
(
!
srcimg
.
data
)
{
std
::
cerr
<<
"[ERROR] image read failed! image path: "
<<
img_path
<<
"
\n
"
;
exit
(
-
1
);
}
cv
::
cvtColor
(
srcimg
,
srcimg
,
cv
::
COLOR_BGR2RGB
);
// step1: get all detection results
batch_imgs
.
push_back
(
srcimg
);
DetPredictImage
(
batch_imgs
,
img_paths
,
batch_size
,
&
detector
,
det_result
,
img_paths
.
push_back
(
img_path
);
det_bbox_num
,
det_times
,
visual_det
,
run_benchmark
);
// select max_det_results bbox
// step1: get all detection results
if
(
det_result
.
size
()
>
max_det_results
)
{
DetPredictImage
(
batch_imgs
,
img_paths
,
batch_size
,
&
detector
,
det_result
,
det_result
.
resize
(
max_det_results
);
det_bbox_num
,
det_times
,
visual_det
,
run_benchmark
);
}
// step2: add the whole image for recognition to improve recall
Detection
::
ObjectResult
result_whole_img
=
{
{
0
,
0
,
srcimg
.
cols
-
1
,
srcimg
.
rows
-
1
},
0
,
1.0
};
det_result
.
push_back
(
result_whole_img
);
det_bbox_num
[
0
]
=
det_result
.
size
()
+
1
;
// step3: extract feature for all boxes in an inmage
// select max_det_results bbox
SearchResult
search_result
;
if
(
det_result
.
size
()
>
max_det_results
)
{
for
(
int
j
=
0
;
j
<
det_result
.
size
();
++
j
)
{
det_result
.
resize
(
max_det_results
);
int
w
=
det_result
[
j
].
rect
[
2
]
-
det_result
[
j
].
rect
[
0
];
}
int
h
=
det_result
[
j
].
rect
[
3
]
-
det_result
[
j
].
rect
[
1
];
// step2: add the whole image for recognition to improve recall
cv
::
Rect
rect
(
det_result
[
j
].
rect
[
0
],
det_result
[
j
].
rect
[
1
],
w
,
h
);
Detection
::
ObjectResult
result_whole_img
=
{
cv
::
Mat
crop_img
=
srcimg
(
rect
);
{
0
,
0
,
srcimg
.
cols
-
1
,
srcimg
.
rows
-
1
},
0
,
1.0
};
feature_extracter
.
Run
(
crop_img
,
feature
,
cls_times
);
det_result
.
push_back
(
result_whole_img
);
features
.
insert
(
features
.
end
(),
feature
.
begin
(),
feature
.
end
());
det_bbox_num
[
0
]
=
det_result
.
size
()
+
1
;
}
// step4: get search result
// step3: extract feature for all boxes in an inmage
search_result
=
searcher
.
Search
(
features
.
data
(),
det_result
.
size
());
SearchResult
search_result
;
for
(
int
j
=
0
;
j
<
det_result
.
size
();
++
j
)
{
int
w
=
det_result
[
j
].
rect
[
2
]
-
det_result
[
j
].
rect
[
0
];
int
h
=
det_result
[
j
].
rect
[
3
]
-
det_result
[
j
].
rect
[
1
];
cv
::
Rect
rect
(
det_result
[
j
].
rect
[
0
],
det_result
[
j
].
rect
[
1
],
w
,
h
);
cv
::
Mat
crop_img
=
srcimg
(
rect
);
feature_extracter
.
Run
(
crop_img
,
feature
,
cls_times
);
features
.
insert
(
features
.
end
(),
feature
.
begin
(),
feature
.
end
());
}
// nms for search result
// step4: get search result
for
(
int
i
=
0
;
i
<
det_result
.
size
();
++
i
)
{
search_result
=
searcher
.
Search
(
features
.
data
(),
det_result
.
size
());
det_result
[
i
].
confidence
=
search_result
.
D
[
search_result
.
return_k
*
i
];
}
// nms for search result
NMSBoxes
(
det_result
,
searcher
.
GetThreshold
(),
rec_nms_thresold
,
indeices
);
for
(
int
i
=
0
;
i
<
det_result
.
size
();
++
i
)
{
det_result
[
i
].
confidence
=
search_result
.
D
[
search_result
.
return_k
*
i
];
}
NMSBoxes
(
det_result
,
searcher
.
GetThreshold
(),
rec_nms_thresold
,
indeices
);
// print result
// print result
PrintResult
(
img_path
,
det_result
,
indeices
,
searcher
,
search_result
);
PrintResult
(
img_path
,
det_result
,
indeices
,
searcher
,
search_result
);
// for postprocess
// for postprocess
batch_imgs
.
clear
();
batch_imgs
.
clear
();
img_paths
.
clear
();
img_paths
.
clear
();
det_bbox_num
.
clear
();
det_bbox_num
.
clear
();
det_result
.
clear
();
det_result
.
clear
();
feature
.
clear
();
feature
.
clear
();
features
.
clear
();
features
.
clear
();
indeices
.
clear
();
indeices
.
clear
();
}
}
std
::
string
presion
=
"fp32"
;
std
::
string
presion
=
"fp32"
;
// if (config.use_fp16)
// if (config.use_fp16)
// presion = "fp16";
// presion = "fp16";
// if (config.benchmark) {
// if (config.benchmark) {
// AutoLogger autolog("Classification", config.use_gpu, config.use_tensorrt,
// AutoLogger autolog("Classification", config.use_gpu, config.use_tensorrt,
// config.use_mkldnn, config.cpu_threads, 1,
// config.use_mkldnn, config.cpu_threads, 1,
// "1, 3, 224, 224", presion, cls_times,
// "1, 3, 224, 224", presion, cls_times,
// img_files_list.size());
// img_files_list.size());
// autolog.report();
// autolog.report();
// }
// }
return
0
;
return
0
;
}
}
deploy/cpp_shitu/src/object_detector.cpp
浏览文件 @
29f8fb83
...
@@ -22,344 +22,344 @@ using namespace paddle_infer;
...
@@ -22,344 +22,344 @@ using namespace paddle_infer;
namespace
Detection
{
namespace
Detection
{
// Load Model and create model predictor
// Load Model and create model predictor
void
ObjectDetector
::
LoadModel
(
const
std
::
string
&
model_dir
,
void
ObjectDetector
::
LoadModel
(
const
std
::
string
&
model_dir
,
const
int
batch_size
,
const
int
batch_size
,
const
std
::
string
&
run_mode
)
{
const
std
::
string
&
run_mode
)
{
paddle_infer
::
Config
config
;
paddle_infer
::
Config
config
;
std
::
string
prog_file
=
model_dir
+
OS_PATH_SEP
+
"inference.pdmodel"
;
std
::
string
prog_file
=
model_dir
+
OS_PATH_SEP
+
"inference.pdmodel"
;
std
::
string
params_file
=
model_dir
+
OS_PATH_SEP
+
"inference.pdiparams"
;
std
::
string
params_file
=
model_dir
+
OS_PATH_SEP
+
"inference.pdiparams"
;
config
.
SetModel
(
prog_file
,
params_file
);
config
.
SetModel
(
prog_file
,
params_file
);
if
(
this
->
use_gpu_
)
{
if
(
this
->
use_gpu_
)
{
config
.
EnableUseGpu
(
this
->
gpu_mem_
,
this
->
gpu_id_
);
config
.
EnableUseGpu
(
this
->
gpu_mem_
,
this
->
gpu_id_
);
config
.
SwitchIrOptim
(
this
->
ir_optim_
);
config
.
SwitchIrOptim
(
this
->
ir_optim_
);
// // use tensorrt
// // use tensorrt
// if (run_mode != "fluid") {
// if (run_mode != "fluid") {
// auto precision = paddle_infer::Config::Precision::kFloat32;
// auto precision = paddle_infer::Config::Precision::kFloat32;
// if (run_mode == "trt_fp32") {
// if (run_mode == "trt_fp32") {
// precision = paddle_infer::Config::Precision::kFloat32;
// precision = paddle_infer::Config::Precision::kFloat32;
// }
// }
// else if (run_mode == "trt_fp16") {
// else if (run_mode == "trt_fp16") {
// precision = paddle_infer::Config::Precision::kHalf;
// precision = paddle_infer::Config::Precision::kHalf;
// }
// }
// else if (run_mode == "trt_int8") {
// else if (run_mode == "trt_int8") {
// precision = paddle_infer::Config::Precision::kInt8;
// precision = paddle_infer::Config::Precision::kInt8;
// } else {
// } else {
// printf("run_mode should be 'fluid', 'trt_fp32', 'trt_fp16' or
// printf("run_mode should be 'fluid', 'trt_fp32', 'trt_fp16' or
// 'trt_int8'");
// 'trt_int8'");
// }
// }
// set tensorrt
// set tensorrt
if
(
this
->
use_tensorrt_
)
{
if
(
this
->
use_tensorrt_
)
{
config
.
EnableTensorRtEngine
(
config
.
EnableTensorRtEngine
(
1
<<
30
,
batch_size
,
this
->
min_subgraph_size_
,
1
<<
30
,
batch_size
,
this
->
min_subgraph_size_
,
this
->
use_fp16_
?
paddle_infer
::
Config
::
Precision
::
kHalf
this
->
use_fp16_
?
paddle_infer
::
Config
::
Precision
::
kHalf
:
paddle_infer
::
Config
::
Precision
::
kFloat32
,
:
paddle_infer
::
Config
::
Precision
::
kFloat32
,
false
,
this
->
trt_calib_mode_
);
false
,
this
->
trt_calib_mode_
);
// set use dynamic shape
// set use dynamic shape
if
(
this
->
use_dynamic_shape_
)
{
if
(
this
->
use_dynamic_shape_
)
{
// set DynamicShsape for image tensor
// set DynamicShsape for image tensor
const
std
::
vector
<
int
>
min_input_shape
=
{
1
,
3
,
this
->
trt_min_shape_
,
const
std
::
vector
<
int
>
min_input_shape
=
{
1
,
3
,
this
->
trt_min_shape_
,
this
->
trt_min_shape_
};
this
->
trt_min_shape_
};
const
std
::
vector
<
int
>
max_input_shape
=
{
1
,
3
,
this
->
trt_max_shape_
,
const
std
::
vector
<
int
>
max_input_shape
=
{
1
,
3
,
this
->
trt_max_shape_
,
this
->
trt_max_shape_
};
this
->
trt_max_shape_
};
const
std
::
vector
<
int
>
opt_input_shape
=
{
1
,
3
,
this
->
trt_opt_shape_
,
const
std
::
vector
<
int
>
opt_input_shape
=
{
1
,
3
,
this
->
trt_opt_shape_
,
this
->
trt_opt_shape_
};
this
->
trt_opt_shape_
};
const
std
::
map
<
std
::
string
,
std
::
vector
<
int
>>
map_min_input_shape
=
{
const
std
::
map
<
std
::
string
,
std
::
vector
<
int
>>
map_min_input_shape
=
{
{
"image"
,
min_input_shape
}};
{
"image"
,
min_input_shape
}};
const
std
::
map
<
std
::
string
,
std
::
vector
<
int
>>
map_max_input_shape
=
{
const
std
::
map
<
std
::
string
,
std
::
vector
<
int
>>
map_max_input_shape
=
{
{
"image"
,
max_input_shape
}};
{
"image"
,
max_input_shape
}};
const
std
::
map
<
std
::
string
,
std
::
vector
<
int
>>
map_opt_input_shape
=
{
const
std
::
map
<
std
::
string
,
std
::
vector
<
int
>>
map_opt_input_shape
=
{
{
"image"
,
opt_input_shape
}};
{
"image"
,
opt_input_shape
}};
config
.
SetTRTDynamicShapeInfo
(
map_min_input_shape
,
map_max_input_shape
,
config
.
SetTRTDynamicShapeInfo
(
map_min_input_shape
,
map_max_input_shape
,
map_opt_input_shape
);
map_opt_input_shape
);
std
::
cout
<<
"TensorRT dynamic shape enabled"
<<
std
::
endl
;
std
::
cout
<<
"TensorRT dynamic shape enabled"
<<
std
::
endl
;
}
}
}
}
// } else if (this->device_ == "XPU"){
// } else if (this->device_ == "XPU"){
// config.EnableXpu(10*1024*1024);
// config.EnableXpu(10*1024*1024);
}
else
{
}
else
{
config
.
DisableGpu
();
config
.
DisableGpu
();
if
(
this
->
use_mkldnn_
)
{
if
(
this
->
use_mkldnn_
)
{
config
.
EnableMKLDNN
();
config
.
EnableMKLDNN
();
// cache 10 different shapes for mkldnn to avoid memory leak
// cache 10 different shapes for mkldnn to avoid memory leak
config
.
SetMkldnnCacheCapacity
(
10
);
config
.
SetMkldnnCacheCapacity
(
10
);
}
config
.
SetCpuMathLibraryNumThreads
(
this
->
cpu_math_library_num_threads_
);
}
config
.
SwitchUseFeedFetchOps
(
false
);
config
.
SwitchIrOptim
(
this
->
ir_optim_
);
config
.
DisableGlogInfo
();
// Memory optimization
config
.
EnableMemoryOptim
();
predictor_
=
std
::
move
(
CreatePredictor
(
config
));
}
}
config
.
SetCpuMathLibraryNumThreads
(
this
->
cpu_math_library_num_threads_
);
}
config
.
SwitchUseFeedFetchOps
(
false
);
config
.
SwitchIrOptim
(
this
->
ir_optim_
);
config
.
DisableGlogInfo
();
// Memory optimization
config
.
EnableMemoryOptim
();
predictor_
=
std
::
move
(
CreatePredictor
(
config
));
}
// Visualiztion MaskDetector results
// Visualiztion MaskDetector results
cv
::
Mat
VisualizeResult
(
const
cv
::
Mat
&
img
,
cv
::
Mat
VisualizeResult
(
const
cv
::
Mat
&
img
,
const
std
::
vector
<
ObjectResult
>
&
results
,
const
std
::
vector
<
ObjectResult
>
&
results
,
const
std
::
vector
<
std
::
string
>
&
lables
,
const
std
::
vector
<
std
::
string
>
&
lables
,
const
std
::
vector
<
int
>
&
colormap
,
const
std
::
vector
<
int
>
&
colormap
,
const
bool
is_rbox
=
false
)
{
const
bool
is_rbox
=
false
)
{
cv
::
Mat
vis_img
=
img
.
clone
();
cv
::
Mat
vis_img
=
img
.
clone
();
for
(
int
i
=
0
;
i
<
results
.
size
();
++
i
)
{
for
(
int
i
=
0
;
i
<
results
.
size
();
++
i
)
{
// Configure color and text size
// Configure color and text size
std
::
ostringstream
oss
;
std
::
ostringstream
oss
;
oss
<<
std
::
setiosflags
(
std
::
ios
::
fixed
)
<<
std
::
setprecision
(
4
);
oss
<<
std
::
setiosflags
(
std
::
ios
::
fixed
)
<<
std
::
setprecision
(
4
);
oss
<<
lables
[
results
[
i
].
class_id
]
<<
" "
;
oss
<<
lables
[
results
[
i
].
class_id
]
<<
" "
;
oss
<<
results
[
i
].
confidence
;
oss
<<
results
[
i
].
confidence
;
std
::
string
text
=
oss
.
str
();
std
::
string
text
=
oss
.
str
();
int
c1
=
colormap
[
3
*
results
[
i
].
class_id
+
0
];
int
c1
=
colormap
[
3
*
results
[
i
].
class_id
+
0
];
int
c2
=
colormap
[
3
*
results
[
i
].
class_id
+
1
];
int
c2
=
colormap
[
3
*
results
[
i
].
class_id
+
1
];
int
c3
=
colormap
[
3
*
results
[
i
].
class_id
+
2
];
int
c3
=
colormap
[
3
*
results
[
i
].
class_id
+
2
];
cv
::
Scalar
roi_color
=
cv
::
Scalar
(
c1
,
c2
,
c3
);
cv
::
Scalar
roi_color
=
cv
::
Scalar
(
c1
,
c2
,
c3
);
int
font_face
=
cv
::
FONT_HERSHEY_COMPLEX_SMALL
;
int
font_face
=
cv
::
FONT_HERSHEY_COMPLEX_SMALL
;
double
font_scale
=
0.5
f
;
double
font_scale
=
0.5
f
;
float
thickness
=
0.5
;
float
thickness
=
0.5
;
cv
::
Size
text_size
=
cv
::
Size
text_size
=
cv
::
getTextSize
(
text
,
font_face
,
font_scale
,
thickness
,
nullptr
);
cv
::
getTextSize
(
text
,
font_face
,
font_scale
,
thickness
,
nullptr
);
cv
::
Point
origin
;
cv
::
Point
origin
;
if
(
is_rbox
)
{
if
(
is_rbox
)
{
// Draw object, text, and background
// Draw object, text, and background
for
(
int
k
=
0
;
k
<
4
;
k
++
)
{
for
(
int
k
=
0
;
k
<
4
;
k
++
)
{
cv
::
Point
pt1
=
cv
::
Point
(
results
[
i
].
rect
[(
k
*
2
)
%
8
],
cv
::
Point
pt1
=
cv
::
Point
(
results
[
i
].
rect
[(
k
*
2
)
%
8
],
results
[
i
].
rect
[(
k
*
2
+
1
)
%
8
]);
results
[
i
].
rect
[(
k
*
2
+
1
)
%
8
]);
cv
::
Point
pt2
=
cv
::
Point
(
results
[
i
].
rect
[(
k
*
2
+
2
)
%
8
],
cv
::
Point
pt2
=
cv
::
Point
(
results
[
i
].
rect
[(
k
*
2
+
2
)
%
8
],
results
[
i
].
rect
[(
k
*
2
+
3
)
%
8
]);
results
[
i
].
rect
[(
k
*
2
+
3
)
%
8
]);
cv
::
line
(
vis_img
,
pt1
,
pt2
,
roi_color
,
2
);
cv
::
line
(
vis_img
,
pt1
,
pt2
,
roi_color
,
2
);
}
}
}
else
{
}
else
{
int
w
=
results
[
i
].
rect
[
2
]
-
results
[
i
].
rect
[
0
];
int
w
=
results
[
i
].
rect
[
2
]
-
results
[
i
].
rect
[
0
];
int
h
=
results
[
i
].
rect
[
3
]
-
results
[
i
].
rect
[
1
];
int
h
=
results
[
i
].
rect
[
3
]
-
results
[
i
].
rect
[
1
];
cv
::
Rect
roi
=
cv
::
Rect
(
results
[
i
].
rect
[
0
],
results
[
i
].
rect
[
1
],
w
,
h
);
cv
::
Rect
roi
=
cv
::
Rect
(
results
[
i
].
rect
[
0
],
results
[
i
].
rect
[
1
],
w
,
h
);
// Draw roi object, text, and background
// Draw roi object, text, and background
cv
::
rectangle
(
vis_img
,
roi
,
roi_color
,
2
);
cv
::
rectangle
(
vis_img
,
roi
,
roi_color
,
2
);
}
}
origin
.
x
=
results
[
i
].
rect
[
0
];
origin
.
x
=
results
[
i
].
rect
[
0
];
origin
.
y
=
results
[
i
].
rect
[
1
];
origin
.
y
=
results
[
i
].
rect
[
1
];
// Configure text background
// Configure text background
cv
::
Rect
text_back
=
cv
::
Rect
text_back
=
cv
::
Rect
(
results
[
i
].
rect
[
0
],
results
[
i
].
rect
[
1
]
-
text_size
.
height
,
cv
::
Rect
(
results
[
i
].
rect
[
0
],
results
[
i
].
rect
[
1
]
-
text_size
.
height
,
text_size
.
width
,
text_size
.
height
);
text_size
.
width
,
text_size
.
height
);
// Draw text, and background
// Draw text, and background
cv
::
rectangle
(
vis_img
,
text_back
,
roi_color
,
-
1
);
cv
::
rectangle
(
vis_img
,
text_back
,
roi_color
,
-
1
);
cv
::
putText
(
vis_img
,
text
,
origin
,
font_face
,
font_scale
,
cv
::
putText
(
vis_img
,
text
,
origin
,
font_face
,
font_scale
,
cv
::
Scalar
(
255
,
255
,
255
),
thickness
);
cv
::
Scalar
(
255
,
255
,
255
),
thickness
);
}
}
return
vis_img
;
return
vis_img
;
}
}
void
ObjectDetector
::
Preprocess
(
const
cv
::
Mat
&
ori_im
)
{
void
ObjectDetector
::
Preprocess
(
const
cv
::
Mat
&
ori_im
)
{
// Clone the image : keep the original mat for postprocess
// Clone the image : keep the original mat for postprocess
cv
::
Mat
im
=
ori_im
.
clone
();
cv
::
Mat
im
=
ori_im
.
clone
();
cv
::
cvtColor
(
im
,
im
,
cv
::
COLOR_BGR2RGB
);
cv
::
cvtColor
(
im
,
im
,
cv
::
COLOR_BGR2RGB
);
preprocessor_
.
Run
(
&
im
,
&
inputs_
);
preprocessor_
.
Run
(
&
im
,
&
inputs_
);
}
}
void
ObjectDetector
::
Postprocess
(
const
std
::
vector
<
cv
::
Mat
>
mats
,
void
ObjectDetector
::
Postprocess
(
const
std
::
vector
<
cv
::
Mat
>
mats
,
std
::
vector
<
ObjectResult
>
*
result
,
std
::
vector
<
ObjectResult
>
*
result
,
std
::
vector
<
int
>
bbox_num
,
std
::
vector
<
int
>
bbox_num
,
bool
is_rbox
=
false
)
{
bool
is_rbox
=
false
)
{
result
->
clear
();
result
->
clear
();
int
start_idx
=
0
;
int
start_idx
=
0
;
for
(
int
im_id
=
0
;
im_id
<
mats
.
size
();
im_id
++
)
{
for
(
int
im_id
=
0
;
im_id
<
mats
.
size
();
im_id
++
)
{
cv
::
Mat
raw_mat
=
mats
[
im_id
];
cv
::
Mat
raw_mat
=
mats
[
im_id
];
int
rh
=
1
;
int
rh
=
1
;
int
rw
=
1
;
int
rw
=
1
;
// if (config_.arch_ == "Face") {
// if (config_.arch_ == "Face") {
// rh = raw_mat.rows;
// rh = raw_mat.rows;
// rw = raw_mat.cols;
// rw = raw_mat.cols;
// }
// }
for
(
int
j
=
start_idx
;
j
<
start_idx
+
bbox_num
[
im_id
];
j
++
)
{
for
(
int
j
=
start_idx
;
j
<
start_idx
+
bbox_num
[
im_id
];
j
++
)
{
if
(
is_rbox
)
{
if
(
is_rbox
)
{
// Class id
// Class id
int
class_id
=
static_cast
<
int
>
(
round
(
output_data_
[
0
+
j
*
10
]));
int
class_id
=
static_cast
<
int
>
(
round
(
output_data_
[
0
+
j
*
10
]));
// Confidence score
// Confidence score
float
score
=
output_data_
[
1
+
j
*
10
];
float
score
=
output_data_
[
1
+
j
*
10
];
int
x1
=
(
output_data_
[
2
+
j
*
10
]
*
rw
);
int
x1
=
(
output_data_
[
2
+
j
*
10
]
*
rw
);
int
y1
=
(
output_data_
[
3
+
j
*
10
]
*
rh
);
int
y1
=
(
output_data_
[
3
+
j
*
10
]
*
rh
);
int
x2
=
(
output_data_
[
4
+
j
*
10
]
*
rw
);
int
x2
=
(
output_data_
[
4
+
j
*
10
]
*
rw
);
int
y2
=
(
output_data_
[
5
+
j
*
10
]
*
rh
);
int
y2
=
(
output_data_
[
5
+
j
*
10
]
*
rh
);
int
x3
=
(
output_data_
[
6
+
j
*
10
]
*
rw
);
int
x3
=
(
output_data_
[
6
+
j
*
10
]
*
rw
);
int
y3
=
(
output_data_
[
7
+
j
*
10
]
*
rh
);
int
y3
=
(
output_data_
[
7
+
j
*
10
]
*
rh
);
int
x4
=
(
output_data_
[
8
+
j
*
10
]
*
rw
);
int
x4
=
(
output_data_
[
8
+
j
*
10
]
*
rw
);
int
y4
=
(
output_data_
[
9
+
j
*
10
]
*
rh
);
int
y4
=
(
output_data_
[
9
+
j
*
10
]
*
rh
);
ObjectResult
result_item
;
ObjectResult
result_item
;
result_item
.
rect
=
{
x1
,
y1
,
x2
,
y2
,
x3
,
y3
,
x4
,
y4
};
result_item
.
rect
=
{
x1
,
y1
,
x2
,
y2
,
x3
,
y3
,
x4
,
y4
};
result_item
.
class_id
=
class_id
;
result_item
.
class_id
=
class_id
;
result_item
.
confidence
=
score
;
result_item
.
confidence
=
score
;
result
->
push_back
(
result_item
);
result
->
push_back
(
result_item
);
}
else
{
}
else
{
// Class id
// Class id
int
class_id
=
static_cast
<
int
>
(
round
(
output_data_
[
0
+
j
*
6
]));
int
class_id
=
static_cast
<
int
>
(
round
(
output_data_
[
0
+
j
*
6
]));
// Confidence score
// Confidence score
float
score
=
output_data_
[
1
+
j
*
6
];
float
score
=
output_data_
[
1
+
j
*
6
];
int
xmin
=
(
output_data_
[
2
+
j
*
6
]
*
rw
);
int
xmin
=
(
output_data_
[
2
+
j
*
6
]
*
rw
);
int
ymin
=
(
output_data_
[
3
+
j
*
6
]
*
rh
);
int
ymin
=
(
output_data_
[
3
+
j
*
6
]
*
rh
);
int
xmax
=
(
output_data_
[
4
+
j
*
6
]
*
rw
);
int
xmax
=
(
output_data_
[
4
+
j
*
6
]
*
rw
);
int
ymax
=
(
output_data_
[
5
+
j
*
6
]
*
rh
);
int
ymax
=
(
output_data_
[
5
+
j
*
6
]
*
rh
);
int
wd
=
xmax
-
xmin
;
int
wd
=
xmax
-
xmin
;
int
hd
=
ymax
-
ymin
;
int
hd
=
ymax
-
ymin
;
ObjectResult
result_item
;
ObjectResult
result_item
;
result_item
.
rect
=
{
xmin
,
ymin
,
xmax
,
ymax
};
result_item
.
rect
=
{
xmin
,
ymin
,
xmax
,
ymax
};
result_item
.
class_id
=
class_id
;
result_item
.
class_id
=
class_id
;
result_item
.
confidence
=
score
;
result_item
.
confidence
=
score
;
result
->
push_back
(
result_item
);
result
->
push_back
(
result_item
);
}
}
}
start_idx
+=
bbox_num
[
im_id
];
}
}
}
start_idx
+=
bbox_num
[
im_id
];
}
}
void
ObjectDetector
::
Predict
(
const
std
::
vector
<
cv
::
Mat
>
imgs
,
const
int
warmup
,
void
ObjectDetector
::
Predict
(
const
std
::
vector
<
cv
::
Mat
>
imgs
,
const
int
warmup
,
const
int
repeats
,
const
int
repeats
,
std
::
vector
<
ObjectResult
>
*
result
,
std
::
vector
<
ObjectResult
>
*
result
,
std
::
vector
<
int
>
*
bbox_num
,
std
::
vector
<
int
>
*
bbox_num
,
std
::
vector
<
double
>
*
times
)
{
std
::
vector
<
double
>
*
times
)
{
auto
preprocess_start
=
std
::
chrono
::
steady_clock
::
now
();
auto
preprocess_start
=
std
::
chrono
::
steady_clock
::
now
();
int
batch_size
=
imgs
.
size
();
int
batch_size
=
imgs
.
size
();
// in_data_batch
// in_data_batch
std
::
vector
<
float
>
in_data_all
;
std
::
vector
<
float
>
in_data_all
;
std
::
vector
<
float
>
im_shape_all
(
batch_size
*
2
);
std
::
vector
<
float
>
im_shape_all
(
batch_size
*
2
);
std
::
vector
<
float
>
scale_factor_all
(
batch_size
*
2
);
std
::
vector
<
float
>
scale_factor_all
(
batch_size
*
2
);
// Preprocess image
// Preprocess image
for
(
int
bs_idx
=
0
;
bs_idx
<
batch_size
;
bs_idx
++
)
{
for
(
int
bs_idx
=
0
;
bs_idx
<
batch_size
;
bs_idx
++
)
{
cv
::
Mat
im
=
imgs
.
at
(
bs_idx
);
cv
::
Mat
im
=
imgs
.
at
(
bs_idx
);
Preprocess
(
im
);
Preprocess
(
im
);
im_shape_all
[
bs_idx
*
2
]
=
inputs_
.
im_shape_
[
0
];
im_shape_all
[
bs_idx
*
2
]
=
inputs_
.
im_shape_
[
0
];
im_shape_all
[
bs_idx
*
2
+
1
]
=
inputs_
.
im_shape_
[
1
];
im_shape_all
[
bs_idx
*
2
+
1
]
=
inputs_
.
im_shape_
[
1
];
scale_factor_all
[
bs_idx
*
2
]
=
inputs_
.
scale_factor_
[
0
];
scale_factor_all
[
bs_idx
*
2
]
=
inputs_
.
scale_factor_
[
0
];
scale_factor_all
[
bs_idx
*
2
+
1
]
=
inputs_
.
scale_factor_
[
1
];
scale_factor_all
[
bs_idx
*
2
+
1
]
=
inputs_
.
scale_factor_
[
1
];
// TODO: reduce cost time
// TODO: reduce cost time
in_data_all
.
insert
(
in_data_all
.
end
(),
inputs_
.
im_data_
.
begin
(),
in_data_all
.
insert
(
in_data_all
.
end
(),
inputs_
.
im_data_
.
begin
(),
inputs_
.
im_data_
.
end
());
inputs_
.
im_data_
.
end
());
}
}
// Prepare input tensor
// Prepare input tensor
auto
input_names
=
predictor_
->
GetInputNames
();
auto
input_names
=
predictor_
->
GetInputNames
();
for
(
const
auto
&
tensor_name
:
input_names
)
{
for
(
const
auto
&
tensor_name
:
input_names
)
{
auto
in_tensor
=
predictor_
->
GetInputHandle
(
tensor_name
);
auto
in_tensor
=
predictor_
->
GetInputHandle
(
tensor_name
);
if
(
tensor_name
==
"image"
)
{
if
(
tensor_name
==
"image"
)
{
int
rh
=
inputs_
.
in_net_shape_
[
0
];
int
rh
=
inputs_
.
in_net_shape_
[
0
];
int
rw
=
inputs_
.
in_net_shape_
[
1
];
int
rw
=
inputs_
.
in_net_shape_
[
1
];
in_tensor
->
Reshape
({
batch_size
,
3
,
rh
,
rw
});
in_tensor
->
Reshape
({
batch_size
,
3
,
rh
,
rw
});
in_tensor
->
CopyFromCpu
(
in_data_all
.
data
());
in_tensor
->
CopyFromCpu
(
in_data_all
.
data
());
}
else
if
(
tensor_name
==
"im_shape"
)
{
}
else
if
(
tensor_name
==
"im_shape"
)
{
in_tensor
->
Reshape
({
batch_size
,
2
});
in_tensor
->
Reshape
({
batch_size
,
2
});
in_tensor
->
CopyFromCpu
(
im_shape_all
.
data
());
in_tensor
->
CopyFromCpu
(
im_shape_all
.
data
());
}
else
if
(
tensor_name
==
"scale_factor"
)
{
}
else
if
(
tensor_name
==
"scale_factor"
)
{
in_tensor
->
Reshape
({
batch_size
,
2
});
in_tensor
->
Reshape
({
batch_size
,
2
});
in_tensor
->
CopyFromCpu
(
scale_factor_all
.
data
());
in_tensor
->
CopyFromCpu
(
scale_factor_all
.
data
());
}
}
}
}
auto
preprocess_end
=
std
::
chrono
::
steady_clock
::
now
();
auto
preprocess_end
=
std
::
chrono
::
steady_clock
::
now
();
// Run predictor
// Run predictor
// warmup
// warmup
for
(
int
i
=
0
;
i
<
warmup
;
i
++
)
{
for
(
int
i
=
0
;
i
<
warmup
;
i
++
)
{
predictor_
->
Run
();
predictor_
->
Run
();
// Get output tensor
// Get output tensor
auto
output_names
=
predictor_
->
GetOutputNames
();
auto
output_names
=
predictor_
->
GetOutputNames
();
auto
out_tensor
=
predictor_
->
GetOutputHandle
(
output_names
[
0
]);
auto
out_tensor
=
predictor_
->
GetOutputHandle
(
output_names
[
0
]);
std
::
vector
<
int
>
output_shape
=
out_tensor
->
shape
();
std
::
vector
<
int
>
output_shape
=
out_tensor
->
shape
();
auto
out_bbox_num
=
predictor_
->
GetOutputHandle
(
output_names
[
1
]);
auto
out_bbox_num
=
predictor_
->
GetOutputHandle
(
output_names
[
1
]);
std
::
vector
<
int
>
out_bbox_num_shape
=
out_bbox_num
->
shape
();
std
::
vector
<
int
>
out_bbox_num_shape
=
out_bbox_num
->
shape
();
// Calculate output length
// Calculate output length
int
output_size
=
1
;
int
output_size
=
1
;
for
(
int
j
=
0
;
j
<
output_shape
.
size
();
++
j
)
{
for
(
int
j
=
0
;
j
<
output_shape
.
size
();
++
j
)
{
output_size
*=
output_shape
[
j
];
output_size
*=
output_shape
[
j
];
}
}
if
(
output_size
<
6
)
{
if
(
output_size
<
6
)
{
std
::
cerr
<<
"[WARNING] No object detected."
<<
std
::
endl
;
std
::
cerr
<<
"[WARNING] No object detected."
<<
std
::
endl
;
}
}
output_data_
.
resize
(
output_size
);
output_data_
.
resize
(
output_size
);
out_tensor
->
CopyToCpu
(
output_data_
.
data
());
out_tensor
->
CopyToCpu
(
output_data_
.
data
());
int
out_bbox_num_size
=
1
;
int
out_bbox_num_size
=
1
;
for
(
int
j
=
0
;
j
<
out_bbox_num_shape
.
size
();
++
j
)
{
for
(
int
j
=
0
;
j
<
out_bbox_num_shape
.
size
();
++
j
)
{
out_bbox_num_size
*=
out_bbox_num_shape
[
j
];
out_bbox_num_size
*=
out_bbox_num_shape
[
j
];
}
}
out_bbox_num_data_
.
resize
(
out_bbox_num_size
);
out_bbox_num_data_
.
resize
(
out_bbox_num_size
);
out_bbox_num
->
CopyToCpu
(
out_bbox_num_data_
.
data
());
out_bbox_num
->
CopyToCpu
(
out_bbox_num_data_
.
data
());
}
}
bool
is_rbox
=
false
;
bool
is_rbox
=
false
;
auto
inference_start
=
std
::
chrono
::
steady_clock
::
now
();
auto
inference_start
=
std
::
chrono
::
steady_clock
::
now
();
for
(
int
i
=
0
;
i
<
repeats
;
i
++
)
{
for
(
int
i
=
0
;
i
<
repeats
;
i
++
)
{
predictor_
->
Run
();
predictor_
->
Run
();
// Get output tensor
// Get output tensor
auto
output_names
=
predictor_
->
GetOutputNames
();
auto
output_names
=
predictor_
->
GetOutputNames
();
auto
out_tensor
=
predictor_
->
GetOutputHandle
(
output_names
[
0
]);
auto
out_tensor
=
predictor_
->
GetOutputHandle
(
output_names
[
0
]);
std
::
vector
<
int
>
output_shape
=
out_tensor
->
shape
();
std
::
vector
<
int
>
output_shape
=
out_tensor
->
shape
();
auto
out_bbox_num
=
predictor_
->
GetOutputHandle
(
output_names
[
1
]);
auto
out_bbox_num
=
predictor_
->
GetOutputHandle
(
output_names
[
1
]);
std
::
vector
<
int
>
out_bbox_num_shape
=
out_bbox_num
->
shape
();
std
::
vector
<
int
>
out_bbox_num_shape
=
out_bbox_num
->
shape
();
// Calculate output length
// Calculate output length
int
output_size
=
1
;
int
output_size
=
1
;
for
(
int
j
=
0
;
j
<
output_shape
.
size
();
++
j
)
{
for
(
int
j
=
0
;
j
<
output_shape
.
size
();
++
j
)
{
output_size
*=
output_shape
[
j
];
output_size
*=
output_shape
[
j
];
}
}
is_rbox
=
output_shape
[
output_shape
.
size
()
-
1
]
%
10
==
0
;
is_rbox
=
output_shape
[
output_shape
.
size
()
-
1
]
%
10
==
0
;
if
(
output_size
<
6
)
{
if
(
output_size
<
6
)
{
std
::
cerr
<<
"[WARNING] No object detected."
<<
std
::
endl
;
std
::
cerr
<<
"[WARNING] No object detected."
<<
std
::
endl
;
}
}
output_data_
.
resize
(
output_size
);
output_data_
.
resize
(
output_size
);
out_tensor
->
CopyToCpu
(
output_data_
.
data
());
out_tensor
->
CopyToCpu
(
output_data_
.
data
());
int
out_bbox_num_size
=
1
;
int
out_bbox_num_size
=
1
;
for
(
int
j
=
0
;
j
<
out_bbox_num_shape
.
size
();
++
j
)
{
for
(
int
j
=
0
;
j
<
out_bbox_num_shape
.
size
();
++
j
)
{
out_bbox_num_size
*=
out_bbox_num_shape
[
j
];
out_bbox_num_size
*=
out_bbox_num_shape
[
j
];
}
}
out_bbox_num_data_
.
resize
(
out_bbox_num_size
);
out_bbox_num_data_
.
resize
(
out_bbox_num_size
);
out_bbox_num
->
CopyToCpu
(
out_bbox_num_data_
.
data
());
out_bbox_num
->
CopyToCpu
(
out_bbox_num_data_
.
data
());
}
}
auto
inference_end
=
std
::
chrono
::
steady_clock
::
now
();
auto
inference_end
=
std
::
chrono
::
steady_clock
::
now
();
auto
postprocess_start
=
std
::
chrono
::
steady_clock
::
now
();
auto
postprocess_start
=
std
::
chrono
::
steady_clock
::
now
();
// Postprocessing result
// Postprocessing result
result
->
clear
();
result
->
clear
();
Postprocess
(
imgs
,
result
,
out_bbox_num_data_
,
is_rbox
);
Postprocess
(
imgs
,
result
,
out_bbox_num_data_
,
is_rbox
);
bbox_num
->
clear
();
bbox_num
->
clear
();
for
(
int
k
=
0
;
k
<
out_bbox_num_data_
.
size
();
k
++
)
{
for
(
int
k
=
0
;
k
<
out_bbox_num_data_
.
size
();
k
++
)
{
int
tmp
=
out_bbox_num_data_
[
k
];
int
tmp
=
out_bbox_num_data_
[
k
];
bbox_num
->
push_back
(
tmp
);
bbox_num
->
push_back
(
tmp
);
}
}
auto
postprocess_end
=
std
::
chrono
::
steady_clock
::
now
();
auto
postprocess_end
=
std
::
chrono
::
steady_clock
::
now
();
std
::
chrono
::
duration
<
float
>
preprocess_diff
=
std
::
chrono
::
duration
<
float
>
preprocess_diff
=
preprocess_end
-
preprocess_start
;
preprocess_end
-
preprocess_start
;
times
->
push_back
(
double
(
preprocess_diff
.
count
()
*
1000
));
times
->
push_back
(
double
(
preprocess_diff
.
count
()
*
1000
));
std
::
chrono
::
duration
<
float
>
inference_diff
=
inference_end
-
inference_start
;
std
::
chrono
::
duration
<
float
>
inference_diff
=
inference_end
-
inference_start
;
times
->
push_back
(
double
(
inference_diff
.
count
()
/
repeats
*
1000
));
times
->
push_back
(
double
(
inference_diff
.
count
()
/
repeats
*
1000
));
std
::
chrono
::
duration
<
float
>
postprocess_diff
=
std
::
chrono
::
duration
<
float
>
postprocess_diff
=
postprocess_end
-
postprocess_start
;
postprocess_end
-
postprocess_start
;
times
->
push_back
(
double
(
postprocess_diff
.
count
()
*
1000
));
times
->
push_back
(
double
(
postprocess_diff
.
count
()
*
1000
));
}
}
std
::
vector
<
int
>
GenerateColorMap
(
int
num_class
)
{
std
::
vector
<
int
>
GenerateColorMap
(
int
num_class
)
{
auto
colormap
=
std
::
vector
<
int
>
(
3
*
num_class
,
0
);
auto
colormap
=
std
::
vector
<
int
>
(
3
*
num_class
,
0
);
for
(
int
i
=
0
;
i
<
num_class
;
++
i
)
{
for
(
int
i
=
0
;
i
<
num_class
;
++
i
)
{
int
j
=
0
;
int
j
=
0
;
int
lab
=
i
;
int
lab
=
i
;
while
(
lab
)
{
while
(
lab
)
{
colormap
[
i
*
3
]
|=
(((
lab
>>
0
)
&
1
)
<<
(
7
-
j
));
colormap
[
i
*
3
]
|=
(((
lab
>>
0
)
&
1
)
<<
(
7
-
j
));
colormap
[
i
*
3
+
1
]
|=
(((
lab
>>
1
)
&
1
)
<<
(
7
-
j
));
colormap
[
i
*
3
+
1
]
|=
(((
lab
>>
1
)
&
1
)
<<
(
7
-
j
));
colormap
[
i
*
3
+
2
]
|=
(((
lab
>>
2
)
&
1
)
<<
(
7
-
j
));
colormap
[
i
*
3
+
2
]
|=
(((
lab
>>
2
)
&
1
)
<<
(
7
-
j
));
++
j
;
++
j
;
lab
>>=
3
;
lab
>>=
3
;
}
}
return
colormap
;
}
}
}
return
colormap
;
}
}
// namespace Detection
}
// namespace Detection
deploy/cpp_shitu/src/preprocess_op.cpp
浏览文件 @
29f8fb83
...
@@ -32,60 +32,60 @@
...
@@ -32,60 +32,60 @@
namespace
Feature
{
namespace
Feature
{
void
Permute
::
Run
(
const
cv
::
Mat
*
im
,
float
*
data
)
{
void
Permute
::
Run
(
const
cv
::
Mat
*
im
,
float
*
data
)
{
int
rh
=
im
->
rows
;
int
rh
=
im
->
rows
;
int
rw
=
im
->
cols
;
int
rw
=
im
->
cols
;
int
rc
=
im
->
channels
();
int
rc
=
im
->
channels
();
for
(
int
i
=
0
;
i
<
rc
;
++
i
)
{
for
(
int
i
=
0
;
i
<
rc
;
++
i
)
{
cv
::
extractChannel
(
*
im
,
cv
::
Mat
(
rh
,
rw
,
CV_32FC1
,
data
+
i
*
rh
*
rw
),
i
);
cv
::
extractChannel
(
*
im
,
cv
::
Mat
(
rh
,
rw
,
CV_32FC1
,
data
+
i
*
rh
*
rw
),
i
);
}
}
}
}
void
Normalize
::
Run
(
cv
::
Mat
*
im
,
const
std
::
vector
<
float
>
&
mean
,
void
Normalize
::
Run
(
cv
::
Mat
*
im
,
const
std
::
vector
<
float
>
&
mean
,
const
std
::
vector
<
float
>
&
std
,
float
scale
)
{
const
std
::
vector
<
float
>
&
std
,
float
scale
)
{
(
*
im
).
convertTo
(
*
im
,
CV_32FC3
,
scale
);
(
*
im
).
convertTo
(
*
im
,
CV_32FC3
,
scale
);
for
(
int
h
=
0
;
h
<
im
->
rows
;
h
++
)
{
for
(
int
h
=
0
;
h
<
im
->
rows
;
h
++
)
{
for
(
int
w
=
0
;
w
<
im
->
cols
;
w
++
)
{
for
(
int
w
=
0
;
w
<
im
->
cols
;
w
++
)
{
im
->
at
<
cv
::
Vec3f
>
(
h
,
w
)[
0
]
=
im
->
at
<
cv
::
Vec3f
>
(
h
,
w
)[
0
]
=
(
im
->
at
<
cv
::
Vec3f
>
(
h
,
w
)[
0
]
-
mean
[
0
])
/
std
[
0
];
(
im
->
at
<
cv
::
Vec3f
>
(
h
,
w
)[
0
]
-
mean
[
0
])
/
std
[
0
];
im
->
at
<
cv
::
Vec3f
>
(
h
,
w
)[
1
]
=
im
->
at
<
cv
::
Vec3f
>
(
h
,
w
)[
1
]
=
(
im
->
at
<
cv
::
Vec3f
>
(
h
,
w
)[
1
]
-
mean
[
1
])
/
std
[
1
];
(
im
->
at
<
cv
::
Vec3f
>
(
h
,
w
)[
1
]
-
mean
[
1
])
/
std
[
1
];
im
->
at
<
cv
::
Vec3f
>
(
h
,
w
)[
2
]
=
im
->
at
<
cv
::
Vec3f
>
(
h
,
w
)[
2
]
=
(
im
->
at
<
cv
::
Vec3f
>
(
h
,
w
)[
2
]
-
mean
[
2
])
/
std
[
2
];
(
im
->
at
<
cv
::
Vec3f
>
(
h
,
w
)[
2
]
-
mean
[
2
])
/
std
[
2
];
}
}
}
}
}
}
void
CenterCropImg
::
Run
(
cv
::
Mat
&
img
,
const
int
crop_size
)
{
void
CenterCropImg
::
Run
(
cv
::
Mat
&
img
,
const
int
crop_size
)
{
int
resize_w
=
img
.
cols
;
int
resize_w
=
img
.
cols
;
int
resize_h
=
img
.
rows
;
int
resize_h
=
img
.
rows
;
int
w_start
=
int
((
resize_w
-
crop_size
)
/
2
);
int
w_start
=
int
((
resize_w
-
crop_size
)
/
2
);
int
h_start
=
int
((
resize_h
-
crop_size
)
/
2
);
int
h_start
=
int
((
resize_h
-
crop_size
)
/
2
);
cv
::
Rect
rect
(
w_start
,
h_start
,
crop_size
,
crop_size
);
cv
::
Rect
rect
(
w_start
,
h_start
,
crop_size
,
crop_size
);
img
=
img
(
rect
);
img
=
img
(
rect
);
}
}
void
ResizeImg
::
Run
(
const
cv
::
Mat
&
img
,
cv
::
Mat
&
resize_img
,
void
ResizeImg
::
Run
(
const
cv
::
Mat
&
img
,
cv
::
Mat
&
resize_img
,
int
resize_short_size
,
int
size
)
{
int
resize_short_size
,
int
size
)
{
int
resize_h
=
0
;
int
resize_h
=
0
;
int
resize_w
=
0
;
int
resize_w
=
0
;
if
(
size
>
0
)
{
if
(
size
>
0
)
{
resize_h
=
size
;
resize_h
=
size
;
resize_w
=
size
;
resize_w
=
size
;
}
else
{
}
else
{
int
w
=
img
.
cols
;
int
w
=
img
.
cols
;
int
h
=
img
.
rows
;
int
h
=
img
.
rows
;
float
ratio
=
1.
f
;
float
ratio
=
1.
f
;
if
(
h
<
w
)
{
if
(
h
<
w
)
{
ratio
=
float
(
resize_short_size
)
/
float
(
h
);
ratio
=
float
(
resize_short_size
)
/
float
(
h
);
}
else
{
}
else
{
ratio
=
float
(
resize_short_size
)
/
float
(
w
);
ratio
=
float
(
resize_short_size
)
/
float
(
w
);
}
resize_h
=
round
(
float
(
h
)
*
ratio
);
resize_w
=
round
(
float
(
w
)
*
ratio
);
}
cv
::
resize
(
img
,
resize_img
,
cv
::
Size
(
resize_w
,
resize_h
));
}
}
resize_h
=
round
(
float
(
h
)
*
ratio
);
resize_w
=
round
(
float
(
w
)
*
ratio
);
}
cv
::
resize
(
img
,
resize_img
,
cv
::
Size
(
resize_w
,
resize_h
));
}
}
// namespace Feature
}
// namespace Feature
deploy/cpp_shitu/src/preprocess_op_det.cpp
浏览文件 @
29f8fb83
...
@@ -19,112 +19,112 @@
...
@@ -19,112 +19,112 @@
namespace
Detection
{
namespace
Detection
{
void
InitInfo
::
Run
(
cv
::
Mat
*
im
,
ImageBlob
*
data
)
{
void
InitInfo
::
Run
(
cv
::
Mat
*
im
,
ImageBlob
*
data
)
{
data
->
im_shape_
=
{
static_cast
<
float
>
(
im
->
rows
),
data
->
im_shape_
=
{
static_cast
<
float
>
(
im
->
rows
),
static_cast
<
float
>
(
im
->
cols
)};
static_cast
<
float
>
(
im
->
cols
)};
data
->
scale_factor_
=
{
1.
,
1.
};
data
->
scale_factor_
=
{
1.
,
1.
};
data
->
in_net_shape_
=
{
static_cast
<
float
>
(
im
->
rows
),
data
->
in_net_shape_
=
{
static_cast
<
float
>
(
im
->
rows
),
static_cast
<
float
>
(
im
->
cols
)};
static_cast
<
float
>
(
im
->
cols
)};
}
}
void
NormalizeImage
::
Run
(
cv
::
Mat
*
im
,
ImageBlob
*
data
)
{
void
NormalizeImage
::
Run
(
cv
::
Mat
*
im
,
ImageBlob
*
data
)
{
double
e
=
1.0
;
double
e
=
1.0
;
if
(
is_scale_
)
{
if
(
is_scale_
)
{
e
/=
255.0
;
e
/=
255.0
;
}
}
(
*
im
).
convertTo
(
*
im
,
CV_32FC3
,
e
);
(
*
im
).
convertTo
(
*
im
,
CV_32FC3
,
e
);
for
(
int
h
=
0
;
h
<
im
->
rows
;
h
++
)
{
for
(
int
h
=
0
;
h
<
im
->
rows
;
h
++
)
{
for
(
int
w
=
0
;
w
<
im
->
cols
;
w
++
)
{
for
(
int
w
=
0
;
w
<
im
->
cols
;
w
++
)
{
im
->
at
<
cv
::
Vec3f
>
(
h
,
w
)[
0
]
=
im
->
at
<
cv
::
Vec3f
>
(
h
,
w
)[
0
]
=
(
im
->
at
<
cv
::
Vec3f
>
(
h
,
w
)[
0
]
-
mean_
[
0
])
/
scale_
[
0
];
(
im
->
at
<
cv
::
Vec3f
>
(
h
,
w
)[
0
]
-
mean_
[
0
])
/
scale_
[
0
];
im
->
at
<
cv
::
Vec3f
>
(
h
,
w
)[
1
]
=
im
->
at
<
cv
::
Vec3f
>
(
h
,
w
)[
1
]
=
(
im
->
at
<
cv
::
Vec3f
>
(
h
,
w
)[
1
]
-
mean_
[
1
])
/
scale_
[
1
];
(
im
->
at
<
cv
::
Vec3f
>
(
h
,
w
)[
1
]
-
mean_
[
1
])
/
scale_
[
1
];
im
->
at
<
cv
::
Vec3f
>
(
h
,
w
)[
2
]
=
im
->
at
<
cv
::
Vec3f
>
(
h
,
w
)[
2
]
=
(
im
->
at
<
cv
::
Vec3f
>
(
h
,
w
)[
2
]
-
mean_
[
2
])
/
scale_
[
2
];
(
im
->
at
<
cv
::
Vec3f
>
(
h
,
w
)[
2
]
-
mean_
[
2
])
/
scale_
[
2
];
}
}
}
}
}
}
void
Permute
::
Run
(
cv
::
Mat
*
im
,
ImageBlob
*
data
)
{
void
Permute
::
Run
(
cv
::
Mat
*
im
,
ImageBlob
*
data
)
{
int
rh
=
im
->
rows
;
int
rh
=
im
->
rows
;
int
rw
=
im
->
cols
;
int
rw
=
im
->
cols
;
int
rc
=
im
->
channels
();
int
rc
=
im
->
channels
();
(
data
->
im_data_
).
resize
(
rc
*
rh
*
rw
);
(
data
->
im_data_
).
resize
(
rc
*
rh
*
rw
);
float
*
base
=
(
data
->
im_data_
).
data
();
float
*
base
=
(
data
->
im_data_
).
data
();
for
(
int
i
=
0
;
i
<
rc
;
++
i
)
{
for
(
int
i
=
0
;
i
<
rc
;
++
i
)
{
cv
::
extractChannel
(
*
im
,
cv
::
Mat
(
rh
,
rw
,
CV_32FC1
,
base
+
i
*
rh
*
rw
),
i
);
cv
::
extractChannel
(
*
im
,
cv
::
Mat
(
rh
,
rw
,
CV_32FC1
,
base
+
i
*
rh
*
rw
),
i
);
}
}
}
}
void
Resize
::
Run
(
cv
::
Mat
*
im
,
ImageBlob
*
data
)
{
void
Resize
::
Run
(
cv
::
Mat
*
im
,
ImageBlob
*
data
)
{
auto
resize_scale
=
GenerateScale
(
*
im
);
auto
resize_scale
=
GenerateScale
(
*
im
);
data
->
im_shape_
=
{
static_cast
<
float
>
(
im
->
cols
*
resize_scale
.
first
),
data
->
im_shape_
=
{
static_cast
<
float
>
(
im
->
cols
*
resize_scale
.
first
),
static_cast
<
float
>
(
im
->
rows
*
resize_scale
.
second
)};
static_cast
<
float
>
(
im
->
rows
*
resize_scale
.
second
)};
data
->
in_net_shape_
=
{
static_cast
<
float
>
(
im
->
cols
*
resize_scale
.
first
),
data
->
in_net_shape_
=
{
static_cast
<
float
>
(
im
->
cols
*
resize_scale
.
first
),
static_cast
<
float
>
(
im
->
rows
*
resize_scale
.
second
)};
static_cast
<
float
>
(
im
->
rows
*
resize_scale
.
second
)};
cv
::
resize
(
*
im
,
*
im
,
cv
::
Size
(),
resize_scale
.
first
,
resize_scale
.
second
,
cv
::
resize
(
*
im
,
*
im
,
cv
::
Size
(),
resize_scale
.
first
,
resize_scale
.
second
,
interp_
);
interp_
);
data
->
im_shape_
=
{
data
->
im_shape_
=
{
static_cast
<
float
>
(
im
->
rows
),
static_cast
<
float
>
(
im
->
cols
),
static_cast
<
float
>
(
im
->
rows
),
static_cast
<
float
>
(
im
->
cols
),
};
};
data
->
scale_factor_
=
{
data
->
scale_factor_
=
{
resize_scale
.
second
,
resize_scale
.
first
,
resize_scale
.
second
,
resize_scale
.
first
,
};
};
}
}
std
::
pair
<
double
,
double
>
Resize
::
GenerateScale
(
const
cv
::
Mat
&
im
)
{
std
::
pair
<
double
,
double
>
Resize
::
GenerateScale
(
const
cv
::
Mat
&
im
)
{
std
::
pair
<
double
,
double
>
resize_scale
;
std
::
pair
<
double
,
double
>
resize_scale
;
int
origin_w
=
im
.
cols
;
int
origin_w
=
im
.
cols
;
int
origin_h
=
im
.
rows
;
int
origin_h
=
im
.
rows
;
if
(
keep_ratio_
)
{
if
(
keep_ratio_
)
{
int
im_size_max
=
std
::
max
(
origin_w
,
origin_h
);
int
im_size_max
=
std
::
max
(
origin_w
,
origin_h
);
int
im_size_min
=
std
::
min
(
origin_w
,
origin_h
);
int
im_size_min
=
std
::
min
(
origin_w
,
origin_h
);
int
target_size_max
=
int
target_size_max
=
*
std
::
max_element
(
target_size_
.
begin
(),
target_size_
.
end
());
*
std
::
max_element
(
target_size_
.
begin
(),
target_size_
.
end
());
int
target_size_min
=
int
target_size_min
=
*
std
::
min_element
(
target_size_
.
begin
(),
target_size_
.
end
());
*
std
::
min_element
(
target_size_
.
begin
(),
target_size_
.
end
());
double
scale_min
=
double
scale_min
=
static_cast
<
double
>
(
target_size_min
)
/
static_cast
<
double
>
(
im_size_min
);
static_cast
<
double
>
(
target_size_min
)
/
static_cast
<
double
>
(
im_size_min
);
double
scale_max
=
double
scale_max
=
static_cast
<
double
>
(
target_size_max
)
/
static_cast
<
double
>
(
im_size_max
);
static_cast
<
double
>
(
target_size_max
)
/
static_cast
<
double
>
(
im_size_max
);
double
scale_ratio
=
std
::
min
(
scale_min
,
scale_max
);
double
scale_ratio
=
std
::
min
(
scale_min
,
scale_max
);
resize_scale
=
{
scale_ratio
,
scale_ratio
};
resize_scale
=
{
scale_ratio
,
scale_ratio
};
}
else
{
}
else
{
resize_scale
.
first
=
resize_scale
.
first
=
static_cast
<
double
>
(
target_size_
[
1
])
/
static_cast
<
double
>
(
origin_w
);
static_cast
<
double
>
(
target_size_
[
1
])
/
static_cast
<
double
>
(
origin_w
);
resize_scale
.
second
=
resize_scale
.
second
=
static_cast
<
double
>
(
target_size_
[
0
])
/
static_cast
<
double
>
(
origin_h
);
static_cast
<
double
>
(
target_size_
[
0
])
/
static_cast
<
double
>
(
origin_h
);
}
}
return
resize_scale
;
return
resize_scale
;
}
}
void
PadStride
::
Run
(
cv
::
Mat
*
im
,
ImageBlob
*
data
)
{
void
PadStride
::
Run
(
cv
::
Mat
*
im
,
ImageBlob
*
data
)
{
if
(
stride_
<=
0
)
{
if
(
stride_
<=
0
)
{
return
;
return
;
}
}
int
rc
=
im
->
channels
();
int
rc
=
im
->
channels
();
int
rh
=
im
->
rows
;
int
rh
=
im
->
rows
;
int
rw
=
im
->
cols
;
int
rw
=
im
->
cols
;
int
nh
=
(
rh
/
stride_
)
*
stride_
+
(
rh
%
stride_
!=
0
)
*
stride_
;
int
nh
=
(
rh
/
stride_
)
*
stride_
+
(
rh
%
stride_
!=
0
)
*
stride_
;
int
nw
=
(
rw
/
stride_
)
*
stride_
+
(
rw
%
stride_
!=
0
)
*
stride_
;
int
nw
=
(
rw
/
stride_
)
*
stride_
+
(
rw
%
stride_
!=
0
)
*
stride_
;
cv
::
copyMakeBorder
(
*
im
,
*
im
,
0
,
nh
-
rh
,
0
,
nw
-
rw
,
cv
::
BORDER_CONSTANT
,
cv
::
copyMakeBorder
(
*
im
,
*
im
,
0
,
nh
-
rh
,
0
,
nw
-
rw
,
cv
::
BORDER_CONSTANT
,
cv
::
Scalar
(
0
));
cv
::
Scalar
(
0
));
data
->
in_net_shape_
=
{
data
->
in_net_shape_
=
{
static_cast
<
float
>
(
im
->
rows
),
static_cast
<
float
>
(
im
->
cols
),
static_cast
<
float
>
(
im
->
rows
),
static_cast
<
float
>
(
im
->
cols
),
};
};
}
}
// Preprocessor op running order
// Preprocessor op running order
const
std
::
vector
<
std
::
string
>
Preprocessor
::
RUN_ORDER
=
{
const
std
::
vector
<
std
::
string
>
Preprocessor
::
RUN_ORDER
=
{
"InitInfo"
,
"Resize"
,
"NormalizeImage"
,
"PadStride"
,
"Permute"
};
"InitInfo"
,
"Resize"
,
"NormalizeImage"
,
"PadStride"
,
"Permute"
};
void
Preprocessor
::
Run
(
cv
::
Mat
*
im
,
ImageBlob
*
data
)
{
void
Preprocessor
::
Run
(
cv
::
Mat
*
im
,
ImageBlob
*
data
)
{
for
(
const
auto
&
name
:
RUN_ORDER
)
{
for
(
const
auto
&
name
:
RUN_ORDER
)
{
if
(
ops_
.
find
(
name
)
!=
ops_
.
end
())
{
if
(
ops_
.
find
(
name
)
!=
ops_
.
end
())
{
ops_
[
name
]
->
Run
(
im
,
data
);
ops_
[
name
]
->
Run
(
im
,
data
);
}
}
}
}
}
}
}
// namespace Detection
}
// namespace Detection
deploy/cpp_shitu/src/vector_search.cpp
浏览文件 @
29f8fb83
...
@@ -20,43 +20,43 @@
...
@@ -20,43 +20,43 @@
#include <regex>
#include <regex>
void
VectorSearch
::
LoadIndexFile
()
{
void
VectorSearch
::
LoadIndexFile
()
{
std
::
string
file_path
=
this
->
index_dir
+
OS_PATH_SEP
+
"vector.index"
;
std
::
string
file_path
=
this
->
index_dir
+
OS_PATH_SEP
+
"vector.index"
;
const
char
*
fname
=
file_path
.
c_str
();
const
char
*
fname
=
file_path
.
c_str
();
this
->
index
=
faiss
::
read_index
(
fname
,
0
);
this
->
index
=
faiss
::
read_index
(
fname
,
0
);
}
}
void
VectorSearch
::
LoadIdMap
()
{
void
VectorSearch
::
LoadIdMap
()
{
std
::
string
file_path
=
this
->
index_dir
+
OS_PATH_SEP
+
"id_map.txt"
;
std
::
string
file_path
=
this
->
index_dir
+
OS_PATH_SEP
+
"id_map.txt"
;
std
::
ifstream
in
(
file_path
);
std
::
ifstream
in
(
file_path
);
std
::
string
line
;
std
::
string
line
;
std
::
vector
<
std
::
string
>
m_vec
;
std
::
vector
<
std
::
string
>
m_vec
;
if
(
in
)
{
if
(
in
)
{
while
(
getline
(
in
,
line
))
{
while
(
getline
(
in
,
line
))
{
std
::
regex
ws_re
(
"
\\
s+"
);
std
::
regex
ws_re
(
"
\\
s+"
);
std
::
vector
<
std
::
string
>
v
(
std
::
vector
<
std
::
string
>
v
(
std
::
sregex_token_iterator
(
line
.
begin
(),
line
.
end
(),
ws_re
,
-
1
),
std
::
sregex_token_iterator
(
line
.
begin
(),
line
.
end
(),
ws_re
,
-
1
),
std
::
sregex_token_iterator
());
std
::
sregex_token_iterator
());
if
(
v
.
size
()
!=
2
)
{
if
(
v
.
size
()
!=
2
)
{
std
::
cout
<<
"The number of element for each line in : "
<<
file_path
std
::
cout
<<
"The number of element for each line in : "
<<
file_path
<<
"must be 2, exit the program..."
<<
std
::
endl
;
<<
"must be 2, exit the program..."
<<
std
::
endl
;
exit
(
1
);
exit
(
1
);
}
else
}
else
this
->
id_map
.
insert
(
std
::
pair
<
long
int
,
std
::
string
>
(
this
->
id_map
.
insert
(
std
::
pair
<
long
int
,
std
::
string
>
(
std
::
stol
(
v
[
0
],
nullptr
,
10
),
v
[
1
]));
std
::
stol
(
v
[
0
],
nullptr
,
10
),
v
[
1
]));
}
}
}
}
}
}
const
SearchResult
&
VectorSearch
::
Search
(
float
*
feature
,
int
query_number
)
{
const
SearchResult
&
VectorSearch
::
Search
(
float
*
feature
,
int
query_number
)
{
this
->
D
.
resize
(
this
->
return_k
*
query_number
);
this
->
D
.
resize
(
this
->
return_k
*
query_number
);
this
->
I
.
resize
(
this
->
return_k
*
query_number
);
this
->
I
.
resize
(
this
->
return_k
*
query_number
);
this
->
index
->
search
(
query_number
,
feature
,
return_k
,
D
.
data
(),
I
.
data
());
this
->
index
->
search
(
query_number
,
feature
,
return_k
,
D
.
data
(),
I
.
data
());
this
->
sr
.
return_k
=
this
->
return_k
;
this
->
sr
.
return_k
=
this
->
return_k
;
this
->
sr
.
D
=
this
->
D
;
this
->
sr
.
D
=
this
->
D
;
this
->
sr
.
I
=
this
->
I
;
this
->
sr
.
I
=
this
->
I
;
return
this
->
sr
;
return
this
->
sr
;
}
}
const
std
::
string
&
VectorSearch
::
GetLabel
(
faiss
::
Index
::
idx_t
ind
)
{
const
std
::
string
&
VectorSearch
::
GetLabel
(
faiss
::
Index
::
idx_t
ind
)
{
return
this
->
id_map
.
at
(
ind
);
return
this
->
id_map
.
at
(
ind
);
}
}
deploy/cpp_shitu/src/yaml_config.cpp
浏览文件 @
29f8fb83
...
@@ -19,60 +19,60 @@
...
@@ -19,60 +19,60 @@
#include <include/yaml_config.h>
#include <include/yaml_config.h>
std
::
vector
<
std
::
string
>
YamlConfig
::
ReadDict
(
const
std
::
string
&
path
)
{
std
::
vector
<
std
::
string
>
YamlConfig
::
ReadDict
(
const
std
::
string
&
path
)
{
std
::
ifstream
in
(
path
);
std
::
ifstream
in
(
path
);
std
::
string
line
;
std
::
string
line
;
std
::
vector
<
std
::
string
>
m_vec
;
std
::
vector
<
std
::
string
>
m_vec
;
if
(
in
)
{
if
(
in
)
{
while
(
getline
(
in
,
line
))
{
while
(
getline
(
in
,
line
))
{
m_vec
.
push_back
(
line
);
m_vec
.
push_back
(
line
);
}
}
else
{
std
::
cout
<<
"no such label file: "
<<
path
<<
", exit the program..."
<<
std
::
endl
;
exit
(
1
);
}
}
}
else
{
return
m_vec
;
std
::
cout
<<
"no such label file: "
<<
path
<<
", exit the program..."
<<
std
::
endl
;
exit
(
1
);
}
return
m_vec
;
}
}
std
::
map
<
int
,
std
::
string
>
YamlConfig
::
ReadIndexId
(
const
std
::
string
&
path
)
{
std
::
map
<
int
,
std
::
string
>
YamlConfig
::
ReadIndexId
(
const
std
::
string
&
path
)
{
std
::
ifstream
in
(
path
);
std
::
ifstream
in
(
path
);
std
::
string
line
;
std
::
string
line
;
std
::
map
<
int
,
std
::
string
>
m_vec
;
std
::
map
<
int
,
std
::
string
>
m_vec
;
if
(
in
)
{
if
(
in
)
{
while
(
getline
(
in
,
line
))
{
while
(
getline
(
in
,
line
))
{
std
::
regex
ws_re
(
"
\\
s+"
);
std
::
regex
ws_re
(
"
\\
s+"
);
std
::
vector
<
std
::
string
>
v
(
std
::
vector
<
std
::
string
>
v
(
std
::
sregex_token_iterator
(
line
.
begin
(),
line
.
end
(),
ws_re
,
-
1
),
std
::
sregex_token_iterator
(
line
.
begin
(),
line
.
end
(),
ws_re
,
-
1
),
std
::
sregex_token_iterator
());
std
::
sregex_token_iterator
());
if
(
v
.
size
()
!=
3
)
{
if
(
v
.
size
()
!=
3
)
{
std
::
cout
<<
"The number of element for each line in : "
<<
path
std
::
cout
<<
"The number of element for each line in : "
<<
path
<<
"must be 3, exit the program..."
<<
std
::
endl
;
<<
"must be 3, exit the program..."
<<
std
::
endl
;
exit
(
1
);
exit
(
1
);
}
else
}
else
m_vec
.
insert
(
std
::
pair
<
int
,
std
::
string
>
(
stoi
(
v
[
0
]),
v
[
2
]));
m_vec
.
insert
(
std
::
pair
<
int
,
std
::
string
>
(
stoi
(
v
[
0
]),
v
[
2
]));
}
}
}
}
return
m_vec
;
return
m_vec
;
}
}
YAML
::
Node
YamlConfig
::
ReadYamlConfig
(
const
std
::
string
&
path
)
{
YAML
::
Node
YamlConfig
::
ReadYamlConfig
(
const
std
::
string
&
path
)
{
YAML
::
Node
config
;
YAML
::
Node
config
;
try
{
try
{
config
=
YAML
::
LoadFile
(
path
);
config
=
YAML
::
LoadFile
(
path
);
}
catch
(
YAML
::
BadFile
&
e
)
{
}
catch
(
YAML
::
BadFile
&
e
)
{
std
::
cout
<<
"Something wrong in yaml file, please check yaml file"
std
::
cout
<<
"Something wrong in yaml file, please check yaml file"
<<
std
::
endl
;
<<
std
::
endl
;
exit
(
1
);
exit
(
1
);
}
}
return
config
;
return
config
;
}
}
void
YamlConfig
::
PrintConfigInfo
()
{
void
YamlConfig
::
PrintConfigInfo
()
{
std
::
cout
<<
this
->
config_file
<<
std
::
endl
;
std
::
cout
<<
this
->
config_file
<<
std
::
endl
;
// for (YAML::const_iterator
// for (YAML::const_iterator
// it=config_file.begin();it!=config_file.end();++it)
// it=config_file.begin();it!=config_file.end();++it)
// {
// {
// std::cout << it->as<std::string>() << "\n";
// std::cout << it->as<std::string>() << "\n";
// }
// }
}
}
deploy/cpp_shitu/tools/build.sh
浏览文件 @
29f8fb83
OPENCV_DIR
=
/work/project/project/cpp_infer/opencv-3.4.7/opencv3
OPENCV_DIR
=
${
opencv_install_dir
}
LIB_DIR
=
/work/project/project/cpp_infer/paddle_inference/
LIB_DIR
=
${
paddle_inference_dir
}
CUDA_LIB_DIR
=
/usr/local/cuda/lib64
CUDA_LIB_DIR
=
/usr/local/cuda/lib64
CUDNN_LIB_DIR
=
/usr/lib/x86_64-linux-gnu/
CUDNN_LIB_DIR
=
/usr/lib/x86_64-linux-gnu/
FAISS_DIR
=
/work/project/project/cpp_infer/faiss/faiss_install
FAISS_DIR
=
${
faiss_install_dir
}
FAISS_WITH_MKL
=
OFF
FAISS_WITH_MKL
=
OFF
BUILD_DIR
=
build
BUILD_DIR
=
build
...
@@ -21,4 +21,4 @@ cmake .. \
...
@@ -21,4 +21,4 @@ cmake .. \
-DFAISS_DIR
=
${
FAISS_DIR
}
\
-DFAISS_DIR
=
${
FAISS_DIR
}
\
-DFAISS_WITH_MKL
=
${
FAISS_WITH_MKL
}
-DFAISS_WITH_MKL
=
${
FAISS_WITH_MKL
}
make
-j
make
-j
\ No newline at end of file
deploy/cpp_shitu/tools/config.txt
已删除
100755 → 0
浏览文件 @
a96305c2
# model load config
use_gpu 0
gpu_id 0
gpu_mem 4000
cpu_threads 10
use_mkldnn 1
use_tensorrt 0
use_fp16 0
# cls config
cls_model_path /PaddleClas/inference/cls_infer.pdmodel
cls_params_path /PaddleClas/inference/cls_infer.pdiparams
resize_short_size 256
crop_size 224
# for log env info
benchmark 0
deploy/cpp_shitu/tools/run.sh
已删除
100755 → 0
浏览文件 @
a96305c2
./build/clas_system ../configs/inference_rec.yaml
docs/images/quick_start/shitu_c++_result.png
0 → 100644
浏览文件 @
29f8fb83
163.5 KB
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录