Skip to content

Commit 5c5704c

Browse files
authored
Merge pull request #28 from liwuhen/feat_lwh
feature: add function
2 parents 42ca24b + f3320ba commit 5c5704c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+469
-131
lines changed

.github/workflows/linters.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,7 @@ jobs:
5353
-whitespace/comments, \
5454
-whitespace/line_length,\
5555
-whitespace/indent_namespace,\
56+
-readability/casting, \
57+
-whitespace/parens, \
58+
-whitespace/braces, \
5659
-runtime/string" # Ignore runtime checks on string usage.

modules/app_yolo/app/inferpipeline.cpp

100644100755
File mode changed.

modules/app_yolo/app/inferpipeline.h

100644100755
File mode changed.

modules/app_yolo/appinterface/interface.cpp

100644100755
File mode changed.

modules/app_yolo/appinterface/interface.h

100644100755
File mode changed.

modules/app_yolo/architecture/common/appconfig.cpp

100644100755
Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ std::string AppConfig::predict_path_;
4444
std::string AppConfig::log_path_;
4545
std::string AppConfig::imgs_path_;
4646

47-
std::vector<int> AppConfig::predict_dim_;
47+
std::vector<std::vector<int>> AppConfig::predict_dim_;
48+
std::vector<std::vector<int>> AppConfig::branchs_dim_;
4849

4950
YAML::Node& AppConfig::getYamlNode() { return yaml_node_; }
5051

@@ -91,7 +92,6 @@ AppConfig::AppConfig(const std::string& config_filename) : config_filename_(conf
9192
dst_img_c_ = yaml_node_["preprocessor_config"]["dst_img_channel"].as<int>();
9293
batchsizes_ = yaml_node_["preprocessor_config"]["batch_size"].as<int>();
9394
branch_num_ = yaml_node_["predict_config"]["branch_num"].as<int>();
94-
predict_dim_ = yaml_node_["predict_config"]["predict_dim"].as<std::vector<int>>();
9595
decode_type_ = yaml_node_["predict_config"]["decode_type"].as<int>();
9696
max_objects_ = yaml_node_["predict_config"]["max_objects"].as<int>();
9797
obj_threshold_ = yaml_node_["predict_config"]["obj_threshold"].as<float>();
@@ -105,6 +105,14 @@ AppConfig::AppConfig(const std::string& config_filename) : config_filename_(conf
105105
log_path_ = yaml_node_["common_config"]["log_path"].as<std::string>();
106106
imgs_path_ = yaml_node_["common_config"]["imgs_path"].as<std::string>();
107107

108+
for (int index = 0; index < yaml_node_["predict_config"]["predict_dim"].size(); index++) {
109+
predict_dim_.push_back(yaml_node_["predict_config"]["predict_dim"][index].as<std::vector<int>>());
110+
}
111+
112+
for (int index = 0; index < yaml_node_["predict_config"]["branchs_dim"].size(); index++) {
113+
branchs_dim_.push_back(yaml_node_["predict_config"]["branchs_dim"][index].as<std::vector<int>>());
114+
}
115+
108116
if (trt_path_ == "") {
109117
throw std::invalid_argument("engine_path is empty");
110118
}

modules/app_yolo/architecture/common/appconfig.h

100644100755
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ class AppConfig {
8484
REG_YAML_VAR(std::string, predict_path_);
8585
REG_YAML_VAR(std::string, log_path_);
8686

87-
REG_YAML_VAR(std::vector<int>, predict_dim_);
87+
REG_YAML_VAR(std::vector<std::vector<int>>, predict_dim_);
88+
REG_YAML_VAR(std::vector<std::vector<int>>, branchs_dim_);
8889

8990
protected:
9091
explicit AppConfig(const std::string& config_filename);

modules/app_yolo/architecture/common/parseconfig.cpp

100644100755
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ void ParseMsgs::ReadYamlParam() {
3939
dst_img_c_ = app_config->get_dst_img_c_();
4040
model_acc_ = app_config->get_model_acc_();
4141
branch_num_ = app_config->get_branch_num_();
42+
branchs_dim_ = app_config->get_branchs_dim_();
4243
batchsizes_ = app_config->get_batchsizes_();
4344
predict_dim_ = app_config->get_predict_dim_();
4445
decode_type_ = app_config->get_decode_type_();

modules/app_yolo/architecture/common/parseconfig.h

100644100755
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ class ParseMsgs {
8585
std::string log_path_; // log file path
8686
std::string imgs_path_; // Offline test image collection path
8787

88-
std::vector<int> predict_dim_; // Model prediction output dimensions
88+
std::vector<std::vector<int>> predict_dim_; // Model prediction output dimensions
89+
std::vector<std::vector<int>> branchs_dim_;
8990
};
9091

9192
} // namespace common

modules/app_yolo/architecture/cuda/gpu_decode.cu

100644100755
File mode changed.

modules/app_yolo/architecture/cuda/warpaffine.cu

100644100755
File mode changed.

modules/app_yolo/architecture/cuda/warpaffine.hpp

100644100755
File mode changed.

modules/app_yolo/architecture/decode/iou.cpp

100644100755
File mode changed.

modules/app_yolo/architecture/decode/iou.h

100644100755
File mode changed.

modules/app_yolo/architecture/decode/nms.cpp

100644100755
File mode changed.

modules/app_yolo/architecture/decode/nms.h

100644100755
File mode changed.
Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
#include "postdecode.h"
2+
3+
namespace hpc {
4+
namespace appinfer {
5+
6+
/**
7+
* @description: init.
8+
*/
9+
bool ModelDecode::Init() {
10+
nms_plugin_ = std::make_shared<NmsPlugin>();
11+
nms_plugin_->SetParam(parsemsgs_);
12+
nms_plugin_->Init();
13+
14+
feat_sizes_ = {{64, 120}, {32, 60}, {16, 30}};
15+
16+
anchor_points_ = Generate_Anchor_Points();
17+
18+
GLOG_INFO("[Init]: ModelV5Decode module init ");
19+
return true;
20+
}
21+
22+
/**
23+
* @brief The inference algorithm handles threads.
24+
*/
25+
bool ModelDecode::RunStart() {
26+
GLOG_INFO("[RunStart]: ModelDecode module start ");
27+
return true;
28+
}
29+
30+
/**
31+
* @description: Thread stop.
32+
*/
33+
bool ModelDecode::RunStop() {
34+
GLOG_INFO("[RunStop]: ModelDecode module stop ");
35+
return true;
36+
}
37+
38+
/**
39+
* @description: Software function stops.
40+
*/
41+
bool ModelDecode::RunRelease() {
42+
GLOG_INFO("[RunRelease]: ModelDecode module release ");
43+
return true;
44+
}
45+
46+
/**
47+
* @description: Configuration parameters.
48+
*/
49+
bool ModelDecode::SetParam(shared_ptr<ParseMsgs>& parse_msgs) {
50+
if (parse_msgs != nullptr) {
51+
this->parsemsgs_ = parse_msgs;
52+
} else {
53+
this->parsemsgs_ = nullptr;
54+
GLOG_ERROR("[SetParam]: ModelDecode module set param failed ");
55+
return false;
56+
}
57+
imgshape_["dst"] = make_pair(parsemsgs_->dst_img_h_, parsemsgs_->dst_img_w_);
58+
59+
GLOG_INFO("[SetParam]: ModelDecode module set param ");
60+
return true;
61+
}
62+
63+
/**
64+
* @description: Cal anchor.
65+
*/
66+
AnchorPointsVector ModelDecode::Generate_Anchor_Points() {
67+
AnchorPointsVector anchor_points;
68+
for (int i = 0; i < 3; i++) {
69+
std::vector<std::pair<int, int>> anchors;
70+
int feat_size = feat_sizes_[i].first * feat_sizes_[i].second;
71+
for (int j = 0; j < feat_size; j++) {
72+
int grid_x = j % feat_sizes_[i].second;
73+
int grid_y = j / feat_sizes_[i].second;
74+
anchors.push_back(std::make_pair(grid_x, grid_y));
75+
}
76+
anchor_points.push_back(anchors);
77+
}
78+
79+
return anchor_points;
80+
}
81+
82+
/**
83+
* @description: Bounding box decoding at feature level.
84+
*/
85+
void ModelDecode::BboxDecodeFeatureLevel(std::vector<float*>& predict,
86+
InfertMsg& infer_msg, vector<Box>& box_result) {
87+
int label = 0;
88+
float prob = 0.0f;
89+
float objness = 0.0f;
90+
int stride = 0;
91+
float grid_x, grid_y = 0.0f;
92+
float cx, cy, width, height = 0.0f;
93+
94+
vector<Box> boxes;
95+
96+
int l_size = parsemsgs_->branchs_dim_[0][1] * parsemsgs_->branchs_dim_[0][2] * parsemsgs_->branchs_dim_[0][3];
97+
int d_size = parsemsgs_->branchs_dim_[1][1] * parsemsgs_->branchs_dim_[1][2] * parsemsgs_->branchs_dim_[1][3];
98+
int s_size = parsemsgs_->branchs_dim_[2][1] * parsemsgs_->branchs_dim_[2][2] * parsemsgs_->branchs_dim_[2][3];
99+
100+
int predict_outs = parsemsgs_->predict_dim_[0][1];
101+
for (int i = 0; i < predict_outs; ++i)
102+
{
103+
// cal anchor point
104+
if (i < l_size) {
105+
grid_x = anchor_points_[0][i].first;
106+
grid_y = anchor_points_[0][i].second;
107+
stride = 8;
108+
} else if (i >= l_size && i < l_size + d_size) {
109+
grid_x = anchor_points_[1][i-l_size].first;
110+
grid_y = anchor_points_[1][i-l_size].second;
111+
stride = 16;
112+
} else if (i >= l_size + d_size && i < l_size + d_size + s_size) {
113+
grid_x = anchor_points_[2][i-l_size-d_size].first;
114+
grid_y = anchor_points_[2][i-l_size-d_size].second;
115+
stride = 32;
116+
}
117+
118+
std::vector<float*> outvec;
119+
int label_num = parsemsgs_->predict_dim_[0][2] - 5;
120+
if (parsemsgs_->branch_num_ == (int)DecodeBranch::FEATURE_THREE) {
121+
for (int j = 0; j < parsemsgs_->branch_num_; j++) {
122+
outvec.push_back(predict[j] + i * parsemsgs_->predict_dim_[j][2]); // cls score boxes 特征图级别
123+
}
124+
125+
label = std::max_element(outvec[0], outvec[0] + label_num) - outvec[0];
126+
prob = outvec[0][label];
127+
objness = outvec[1][0];
128+
129+
// 特征图级别 -> 输入图像层级
130+
cx = (outvec[2][0] + grid_x) * stride; // 输入图像级别
131+
cy = (outvec[2][1] + grid_y) * stride;
132+
width = exp(outvec[2][2]) * stride;
133+
height = exp(outvec[2][3]) * stride; // anchor free
134+
135+
} else if (parsemsgs_->branch_num_ == (int)DecodeBranch::FEATURE_ONE) {
136+
outvec.push_back(predict[0] + i * parsemsgs_->predict_dim_[0][2]); // boxes infos 特征图级别
137+
138+
float* lable_score = outvec[0] + 5;
139+
label = std::max_element(lable_score, lable_score + label_num) - lable_score;
140+
prob = lable_score[label];
141+
objness = outvec[0][5];
142+
143+
// 特征图级别 -> 输入图像层级
144+
cx = (outvec[0][0] + grid_x) * stride; // 输入图像级别
145+
cy = (outvec[0][1] + grid_y) * stride;
146+
width = exp(outvec[0][2]) * stride;
147+
height = exp(outvec[0][3]) * stride; // anchor free
148+
}
149+
150+
float confidence = prob * objness;
151+
if(confidence < parsemsgs_->obj_threshold_)
152+
continue;
153+
154+
// 输入图像级别
155+
float left = cx - width * 0.5;
156+
float top = cy - height * 0.5;
157+
float right = cx + width * 0.5;
158+
float bottom = cy + height * 0.5;
159+
160+
// 输入图像层级模型预测框 ==> 映射回原图上尺寸
161+
float image_left = infer_msg.affineMatrix_inv(0, 0) * left + infer_msg.affineMatrix_inv(0, 2);
162+
float image_top = infer_msg.affineMatrix_inv(1, 1) * top + infer_msg.affineMatrix_inv(1, 2);
163+
float image_right = infer_msg.affineMatrix_inv(0, 0) * right + infer_msg.affineMatrix_inv(0, 2);
164+
float image_bottom = infer_msg.affineMatrix_inv(1, 1) * bottom + infer_msg.affineMatrix_inv(1, 2);
165+
boxes.emplace_back(image_left, image_top, image_right, image_bottom, confidence, label);
166+
}
167+
nms_plugin_->Nms(boxes, box_result, parsemsgs_->nms_threshold_);
168+
}
169+
170+
/**
171+
* @description: Bounding box decoding at input level.
172+
*/
173+
void ModelDecode::BboxDecodeInputLevel(std::vector<float*>& predict,
174+
InfertMsg& infer_msg, vector<Box>& box_result)
175+
{
176+
vector<Box> boxes;
177+
int num_classes = parsemsgs_->predict_dim_[0][2] - 5;
178+
for (int i = 0; i < parsemsgs_->predict_dim_[0][1]; ++i)
179+
{
180+
float* pitem = predict[0] + i * parsemsgs_->predict_dim_[0][2];
181+
float objness = pitem[4];
182+
if (objness < parsemsgs_->obj_threshold_) continue;
183+
float* pclass = pitem + 5;
184+
185+
int label = std::max_element(pclass, pclass + num_classes) - pclass;
186+
float prob = pclass[label];
187+
float confidence = prob * objness;
188+
if (confidence < parsemsgs_->obj_threshold_) continue;
189+
190+
float cx = pitem[0];
191+
float cy = pitem[1];
192+
float width = pitem[2];
193+
float height = pitem[3];
194+
float left = cx - width * 0.5;
195+
float top = cy - height * 0.5;
196+
float right = cx + width * 0.5;
197+
float bottom = cy + height * 0.5;
198+
199+
// 输入图像层级模型预测框 ==> 映射回原图上尺寸
200+
float image_left = infer_msg.affineMatrix_inv(0, 0) * left + infer_msg.affineMatrix_inv(0, 2);
201+
float image_top = infer_msg.affineMatrix_inv(1, 1) * top + infer_msg.affineMatrix_inv(1, 2);
202+
float image_right = infer_msg.affineMatrix_inv(0, 0) * right + infer_msg.affineMatrix_inv(0, 2);
203+
float image_bottom = infer_msg.affineMatrix_inv(1, 1) * bottom + infer_msg.affineMatrix_inv(1, 2);
204+
205+
boxes.emplace_back(image_left, image_top, image_right, image_bottom, confidence, label);
206+
}
207+
nms_plugin_->Nms(boxes, box_result, parsemsgs_->nms_threshold_);
208+
}
209+
210+
} // namespace appinfer
211+
} // namespace hpc

0 commit comments

Comments
 (0)