Commit 29b64a886460151f1638251fe2eb09ae99a934ce
1 parent
9b4d4adf
添加行人逆行算法
Showing
15 changed files
with
1241 additions
and
78 deletions
bin/libvpt_det.so
No preview for this file type
src/ai_engine_module/ai_engine_header.h
0 → 100644
1 | +/* | |
2 | + * @Author: yangzilong | |
3 | + * @Date: 2021-12-01 15:14:02 | |
4 | + * @Last Modified by: yangzilong | |
5 | + * @Last Modified time: Do not edit | |
6 | + * @Email: yangzilong@objecteye.com | |
7 | + * @Description: | |
8 | + */ | |
9 | + | |
10 | +#pragma once | |
11 | + | |
12 | +#include <cmath> | |
13 | +#include <type_traits> | |
14 | +#include <string> | |
15 | +#include "../ai_platform/det_obj_header.h" | |
16 | +#include "../util/vpc_util.h" | |
17 | +#include "../ai_platform/common_header.h" | |
18 | + | |
19 | +namespace ai_engine_module { | |
20 | +template <typename T> T clip(const T &val, const T &min, const T &max) { | |
21 | + if (std::is_integral<T>::value) | |
22 | + return std::min(std::max(val, min), max); | |
23 | + return val; | |
24 | +} | |
25 | + | |
26 | +using obj_id_t = long; | |
27 | +using task_id_t = std::string; | |
28 | + | |
29 | +enum class direction_t { | |
30 | + NEGATIVE = 0, | |
31 | + POSITIVE = 1, | |
32 | +}; | |
33 | + | |
34 | +struct unique_obj_id_t { | |
35 | + obj_id_t obj_id; | |
36 | + task_id_t task_id; | |
37 | + | |
38 | + bool operator<(const unique_obj_id_t &obj) const { | |
39 | + if (obj_id < obj.obj_id) | |
40 | + return true; | |
41 | + | |
42 | + else if (obj_id == obj.obj_id) { | |
43 | + if (strcmp(task_id.c_str(), obj.task_id.c_str()) < 0) | |
44 | + return true; | |
45 | + } | |
46 | + return false; | |
47 | + } | |
48 | + | |
49 | +}; | |
50 | + | |
51 | +struct obj_key_t { | |
52 | + obj_id_t obj_id; | |
53 | + task_id_t task_id; | |
54 | + algorithm_type_t algor_type; | |
55 | + | |
56 | + bool operator<(const obj_key_t &obj) const { | |
57 | + if (obj_id < obj.obj_id) | |
58 | + return true; | |
59 | + | |
60 | + else if (obj_id == obj.obj_id) { | |
61 | + if (strcmp(task_id.c_str(), obj.task_id.c_str()) < 0) | |
62 | + return true; | |
63 | + | |
64 | + else if (strcmp(task_id.c_str(), obj.task_id.c_str()) == 0) { | |
65 | + if (static_cast<int>(algor_type) < static_cast<int>(obj.algor_type)) | |
66 | + return true; | |
67 | + else | |
68 | + return false; | |
69 | + } | |
70 | + } | |
71 | + return false; | |
72 | + } | |
73 | +}; | |
74 | + | |
75 | +struct trace_t { | |
76 | + box_t box; | |
77 | + point_t point; | |
78 | +}; | |
79 | + | |
80 | +typedef struct result_data_t { | |
81 | + box_t box; | |
82 | + acldvppPicDesc* origin_img_desc{nullptr}; | |
83 | + acldvppPicDesc* roi_img_desc{nullptr}; | |
84 | +} result_data_t; | |
85 | + | |
86 | +} // namespace ai_engine_module | ... | ... |
src/ai_engine_module/pedestrian_vehicle_retrograde.cpp
0 → 100644
1 | +/* | |
2 | + * File: pedestrian_vehicle_retrograde.cpp | |
3 | + * Created Date: Tuesday February 22nd 2022 | |
4 | + * Author: yangzilong (yangzilong@objecteye.com) | |
5 | + * Description: | |
6 | + * ----- | |
7 | + * Last Modified: Tuesday, 22nd February 2022 4:38:48 pm | |
8 | + * Modified By: yangzilong (yangzilong@objecteye.com>) | |
9 | + * ----- | |
10 | + * Copyright 2022 | |
11 | + */ | |
12 | + | |
13 | +#include "./pedestrian_vehicle_retrograde.h" | |
14 | +#include <cmath> | |
15 | +#include "../decoder/interface/DeviceMemory.hpp" | |
16 | +#include "../common/logger.hpp" | |
17 | +#include "../ai_platform/mvpt_process_assist.h" | |
18 | + | |
19 | +namespace ai_engine_module { | |
20 | +namespace pedestrian_vehicle_retrograde { | |
21 | + | |
22 | +#define MAX_TRACE_NUM 5 | |
23 | +#define MINIMUM_DISTANCE 10 | |
24 | + | |
25 | +static std::set<algorithm_type_t> algor_type_list_ = { | |
26 | + algorithm_type_t::PEDESTRIAN_RETROGRADE, | |
27 | + algorithm_type_t::VEHICLE_RETROGRADE, | |
28 | +}; | |
29 | + | |
30 | +std::set<det_class_label_t> algor_type_to_det_label_set(const algorithm_type_t &algor_type) { | |
31 | + if (algorithm_type_t::PEDESTRIAN_RETROGRADE == algor_type) { | |
32 | + return {det_class_label_t::HUMAN}; | |
33 | + } else if (algorithm_type_t::VEHICLE_RETROGRADE == algor_type) { | |
34 | + return { | |
35 | + det_class_label_t::LARGE_CAR, det_class_label_t::MEDIUM_BUS, det_class_label_t::SMALL_CAR, | |
36 | + det_class_label_t::TRUCK, det_class_label_t::TRACTOR, | |
37 | + | |
38 | + // det_class_label_t::BICYCLE, | |
39 | + // det_class_label_t::MOTOCYCLE, | |
40 | + // det_class_label_t::TRICYCLE, | |
41 | + }; | |
42 | + } else { | |
43 | + return {}; | |
44 | + } | |
45 | +} | |
46 | + | |
47 | +bool is_valid_box(const int &cls, const algorithm_type_t &algor_type) { | |
48 | + return algor_type_to_det_label_set(algor_type).count(static_cast<det_class_label_t>(cls)); | |
49 | +} | |
50 | + | |
51 | +bool is_valid_box(const box_t &box, const algorithm_type_t &algor_type, | |
52 | + const task_param_manager::algo_param_type_t_ *params_ptr = nullptr) { | |
53 | + if (!params_ptr) | |
54 | + return false; | |
55 | + | |
56 | + if (!snapshot_legal_inarea(params_ptr->basic_param->algor_valid_rect, box.left, box.top, box.right, box.bottom)) | |
57 | + return false; | |
58 | + | |
59 | + if (params_ptr->algor_param == nullptr) | |
60 | + return false; | |
61 | + | |
62 | + if (box.width() == 0 || box.height() == 0) | |
63 | + return false; | |
64 | + | |
65 | + using data_t = algor_config_param_retrograde_basic; | |
66 | + data_t *algor_params_ptr = (data_t *)(params_ptr->algor_param); | |
67 | + | |
68 | + if (box.score < algor_params_ptr->conf_threshold || box.width() < algor_params_ptr->minmum_width || | |
69 | + box.height() < algor_params_ptr->minmum_height) | |
70 | + return false; | |
71 | + | |
72 | + return is_valid_box(box.cls, algor_type); | |
73 | +} | |
74 | + | |
75 | +const task_param_manager::algo_param_type_t_ *get_task_param_ptr(const task_id_t &task_id, | |
76 | + const algorithm_type_t &algor_type, | |
77 | + task_param_manager *const task_param_manager) { | |
78 | + if (!task_param_manager) | |
79 | + return nullptr; | |
80 | + | |
81 | + auto &&algor_param_wrap = task_param_manager->get_task_other_param(task_id, algor_type); | |
82 | + if (!algor_param_wrap) | |
83 | + LOG_ERROR("{} is nullptr when get algor param from task_param", task_id); | |
84 | + return algor_param_wrap; | |
85 | +} | |
86 | + | |
87 | +std::vector<algorithm_type_t> task_id_to_algorithm_type_seq(const task_id_t &task_id, | |
88 | + task_param_manager *const task_param) { | |
89 | + std::vector<algorithm_type_t> seq; | |
90 | + auto &&algor_map = task_param->get_task_other_param(task_id); | |
91 | + for (auto iter = algor_map->begin(); iter != algor_map->end(); ++iter) { | |
92 | + // LOG_TRACE("task id is {} algor type is {}", task_id, int(iter->first)); | |
93 | + if (algor_type_list_.count(iter->first) > 0) | |
94 | + seq.emplace_back(iter->first); | |
95 | + } | |
96 | + return seq; // N(RVO) | |
97 | +} | |
98 | + | |
99 | +// ############################################################ // | |
100 | +// ! Class Member ! // | |
101 | +// ############################################################ // | |
102 | + | |
103 | +PedestrianVehicleRetrograde::PedestrianVehicleRetrograde() : task_param_manager_(nullptr) { | |
104 | + if (!task_param_manager_) | |
105 | + task_param_manager_ = task_param_manager::getInstance(); | |
106 | +} | |
107 | + | |
108 | +PedestrianVehicleRetrograde::~PedestrianVehicleRetrograde() = default; | |
109 | + | |
110 | +void PedestrianVehicleRetrograde::force_release_result(const task_id_t &task_id) { | |
111 | + for (auto iter = obj_to_alarm_boxes_.begin(); iter != obj_to_alarm_boxes_.end();) { | |
112 | + const auto &key = iter->first; | |
113 | + if (key.task_id == task_id) { | |
114 | + auto &values = iter->second; | |
115 | + for (auto &value : values) { | |
116 | + | |
117 | + if (value.roi_img_desc) { | |
118 | + VPCUtil::vpc_pic_desc_release(value.roi_img_desc); | |
119 | + } | |
120 | + | |
121 | + if (value.origin_img_desc) { | |
122 | + VPCUtil::vpc_pic_desc_release(value.origin_img_desc); | |
123 | + } | |
124 | + } | |
125 | + values.clear(); | |
126 | + iter = obj_to_alarm_boxes_.erase(iter); | |
127 | + } else { | |
128 | + ++iter; | |
129 | + } | |
130 | + } | |
131 | + //-221024 byzsh删除存储的轨迹信息-------------------------------------------------- | |
132 | + for (auto iter = obj_to_traces_.begin(); iter != obj_to_traces_.end();) { | |
133 | + const auto &key = iter->first; | |
134 | + if (key.task_id == task_id) { | |
135 | + auto &values = iter->second; | |
136 | + values.clear(); | |
137 | + iter = obj_to_traces_.erase(iter); | |
138 | + } else { | |
139 | + ++iter; | |
140 | + } | |
141 | + } | |
142 | + //------------------------------------------------------------------------- | |
143 | + | |
144 | + | |
145 | +} | |
146 | + | |
147 | +vector<result_data_t> PedestrianVehicleRetrograde::get_results_by_id(const obj_key_t &id, bool do_erase) { | |
148 | + LOG_DEBUG("obj_to_alarm_boxes_ size:{}", obj_to_alarm_boxes_.size()); | |
149 | + | |
150 | + vector<result_data_t> res; | |
151 | + | |
152 | + auto it = obj_to_alarm_boxes_.find(id); | |
153 | + if (it == obj_to_alarm_boxes_.end()) { | |
154 | + return res; | |
155 | + } | |
156 | + | |
157 | + res = it->second; | |
158 | + if (do_erase) | |
159 | + obj_to_alarm_boxes_.erase(id); | |
160 | + | |
161 | + if (obj_to_traces_.find(id) != obj_to_traces_.end()) { | |
162 | + obj_to_traces_.erase(id); //221009 !不删除会出现轨迹已消失但继续报警的情况,导致内存泄露 | |
163 | + } | |
164 | + | |
165 | + return res; | |
166 | +} | |
167 | + | |
168 | +vector<obj_key_t> PedestrianVehicleRetrograde::retrograde_aux() { | |
169 | + /** | |
170 | + * @brief 使用box的历史轨迹点和当前轨迹点结合超参中的线段进行逻辑判断出是否逆行. | |
171 | + * | |
172 | + */ | |
173 | + // LOG_TRACE("---> retrograde_aux called."); | |
174 | + | |
175 | + vector<obj_key_t> ret; | |
176 | + const unsigned minimum_boxes_num = MAX_TRACE_NUM - 1; | |
177 | + for (auto &obj_to_trace : obj_to_traces_) { | |
178 | + | |
179 | + auto &obj_key = obj_to_trace.first; | |
180 | + auto &task_id = obj_key.task_id; | |
181 | + auto &algor_type = obj_key.algor_type; | |
182 | + auto &&algor_type_seq = task_id_to_algorithm_type_seq(task_id, task_param_manager_); | |
183 | + // LOG_DEBUG("55555555555 {} {} {}", obj_key.task_id, obj_key.obj_id, obj_key.algor_type); | |
184 | + // LOG_TRACE("---> Ckpt-0"); | |
185 | + | |
186 | + const task_param_manager::algo_param_type_t_ *param_ptr_wrap = | |
187 | + get_task_param_ptr(task_id, algor_type, task_param_manager_); | |
188 | + if (!param_ptr_wrap) | |
189 | + continue; | |
190 | + | |
191 | + using param_type_t = algor_config_param_retrograde_basic; | |
192 | + const param_type_t *param_ptr = (param_type_t *)(param_ptr_wrap->algor_param); | |
193 | + | |
194 | + // LOG_TRACE("---> Ckpt-1"); | |
195 | + | |
196 | + auto &boxes = obj_to_trace.second; | |
197 | + const auto box_size = boxes.size(); | |
198 | + | |
199 | + if (box_size < minimum_boxes_num) | |
200 | + continue; | |
201 | + | |
202 | + // LOG_TRACE("---> Ckpt-2"); | |
203 | + | |
204 | + int point_x = boxes[box_size - minimum_boxes_num].cx(); | |
205 | + const int point_y = boxes[box_size - minimum_boxes_num].cy(); | |
206 | + | |
207 | + double k = 0.0, b = 0.0; | |
208 | + double dist_c = 0.0, dist_p = 0.0; // current point and prev(history) point. | |
209 | + | |
210 | + //! 使用超参中的点 连成的线水平还是垂直. | |
211 | + const bool is_horizontal_line = std::abs(int(param_ptr->px1 - param_ptr->px2)) >= 1; | |
212 | + if (is_horizontal_line) { | |
213 | + k = double(param_ptr->py1 - param_ptr->py2) / (param_ptr->px1 - param_ptr->px2); | |
214 | + b = double(param_ptr->px1 * param_ptr->py2 - param_ptr->px2 * param_ptr->py1) / (param_ptr->px1 - param_ptr->px2); | |
215 | + | |
216 | + dist_c = fabs(k * boxes[box_size - 1].cx() - boxes[box_size - 1].cy() + b) / sqrt(k * k + 1.0); | |
217 | + dist_p = fabs(k * point_x - point_y + b) / sqrt(k * k + 1.0); | |
218 | + } else { | |
219 | + k = 0.0; | |
220 | + b = double(param_ptr->px1); | |
221 | + | |
222 | + dist_c = fabs(boxes[box_size - 1].cx() - b); | |
223 | + dist_p = fabs(point_x - b); | |
224 | + } | |
225 | + | |
226 | + // 从历史轨迹点中找到当前点距离超过阈值的最小点. | |
227 | + bool flag = true; | |
228 | + if (abs(dist_c - dist_p) < MINIMUM_DISTANCE) { | |
229 | + flag = false; | |
230 | + int prev_idx = box_size - MAX_TRACE_NUM; | |
231 | + while (prev_idx >= 0) { | |
232 | + point_x = boxes[prev_idx].cx(); | |
233 | + dist_p = is_horizontal_line ? fabs(k * point_x - point_y + b) / sqrt(k * k + 1.0) : fabs(point_x - b); | |
234 | + if (abs(dist_c - dist_p) >= MINIMUM_DISTANCE) { | |
235 | + flag = true; | |
236 | + break; | |
237 | + } | |
238 | + --prev_idx; | |
239 | + } | |
240 | + } | |
241 | + | |
242 | + // LOG_TRACE("---> Ckpt-10"); | |
243 | + | |
244 | + if (!flag) | |
245 | + continue; | |
246 | + | |
247 | + // 当前轨迹点和历史轨迹点是否越线 | |
248 | + bool flag_c = is_horizontal_line ? (k * boxes[box_size - 1].cx() + b >= boxes[box_size - 1].cy()) | |
249 | + : (boxes[box_size - 1].cx() >= b); | |
250 | + bool flag_p = is_horizontal_line ? (k * point_x + b >= point_y) : (point_x >= b); | |
251 | + | |
252 | + /** | |
253 | + * PS. 拌线: 使用超参中的两点模拟的线段. | |
254 | + * 1. POSITIVE && is_horizontal_line: 方向点在拌线上方,正常方向为从下到上(↑),越界方向为从上到下(↓) | |
255 | + * 2. NEGATIVE && is_horizontal_line: 方向点在拌线下方,正常方向为从上到下(↓),越界方向为从下到上(↑) | |
256 | + * 3. POSITIVE && !is_horizontal_line: 方向点在拌线右边,正常方向为从左到右(→),越界方向为从右到左(←) | |
257 | + * 4. NEGATIVE && !is_horizontal_line: 方向点在拌线左边,正常方向为从右到左(←),越界方向为从左到右(→) | |
258 | + */ | |
259 | + bool is_alarmed = false; | |
260 | + if (direction_t::POSITIVE == static_cast<direction_t>(param_ptr->direction)) { | |
261 | + if (flag_c * flag_p == 1) { | |
262 | + if (dist_c <= dist_p) { | |
263 | + is_alarmed = true; | |
264 | + } | |
265 | + } else if (flag_c == 0 && flag_p == 1) { | |
266 | + is_alarmed = true; | |
267 | + } else if (flag_c == 0 && flag_p == 0) { | |
268 | + if (dist_p <= dist_c) { | |
269 | + is_alarmed = true; | |
270 | + } | |
271 | + } | |
272 | + } else { | |
273 | + if (flag_c == 0 && flag_p == 0) { | |
274 | + if (dist_c <= dist_p) { | |
275 | + is_alarmed = true; | |
276 | + } | |
277 | + } else if (flag_c == 1 && flag_p == 0) { | |
278 | + is_alarmed = true; | |
279 | + } else if (flag_c == 1 && flag_p == 1) { | |
280 | + if (dist_p <= dist_c) { | |
281 | + is_alarmed = true; | |
282 | + } | |
283 | + } | |
284 | + } | |
285 | + | |
286 | + if (is_alarmed) { | |
287 | + ret.emplace_back(obj_key); | |
288 | + } | |
289 | + } | |
290 | + return ret; | |
291 | +} | |
292 | + | |
293 | +bool PedestrianVehicleRetrograde::update_mstreams(const std::vector<task_id_t> &tasks_id, vector<DeviceMemory*> vec_det_input_images, | |
294 | + const std::vector<onelevel_det_result> &det_results) { | |
295 | + //! check. | |
296 | + if (tasks_id.empty() || tasks_id.size() != det_results.size()) | |
297 | + return false; | |
298 | + | |
299 | + //! loop. | |
300 | + unsigned stream_idx = 0; | |
301 | + std::map<task_id_t, unsigned> task_id_to_stream_idx; | |
302 | + for (auto task_id_iter = tasks_id.begin(); task_id_iter != tasks_id.end(); ++task_id_iter, ++stream_idx) { | |
303 | + auto task_id = *task_id_iter; | |
304 | + task_id_to_stream_idx[task_id] = stream_idx; | |
305 | + auto &&algor_type_seq = task_id_to_algorithm_type_seq(task_id, task_param_manager_); | |
306 | + if (algor_type_seq.empty()) | |
307 | + continue; | |
308 | + | |
309 | + auto &det_result = det_results[stream_idx]; | |
310 | + for (unsigned box_idx = 0; box_idx < det_result.obj_count; ++box_idx) { | |
311 | + auto &box = det_result.obj[box_idx]; | |
312 | + // LOG_DEBUG("333333333333 {} {}", task_id, box.id); | |
313 | + box_t unique_box; | |
314 | + { | |
315 | + unique_box.id = box.id; | |
316 | + unique_box.cls = box.index; | |
317 | + | |
318 | + unique_box.top = box.top; | |
319 | + unique_box.left = box.left; | |
320 | + unique_box.right = box.right; | |
321 | + unique_box.bottom = box.bottom; | |
322 | + unique_box.score = box.confidence; | |
323 | + } | |
324 | + | |
325 | + //! loop algor | |
326 | + for (auto algor_type : algor_type_seq) { | |
327 | + obj_key_t obj_key{box.id, task_id, algor_type}; | |
328 | + if (!is_valid_box(unique_box, algor_type, get_task_param_ptr(task_id, algor_type, task_param_manager_))) | |
329 | + continue; | |
330 | + | |
331 | + if (obj_to_traces_.find(obj_key) == obj_to_traces_.end()) { | |
332 | + obj_to_traces_[obj_key].emplace_back(std::move(unique_box)); | |
333 | + } else { | |
334 | + auto &traces = obj_to_traces_[obj_key]; | |
335 | + traces.emplace_back(std::move(unique_box)); | |
336 | + if (traces.size() > MAX_TRACE_NUM) | |
337 | + traces.pop_front(); | |
338 | + } | |
339 | + } | |
340 | + } | |
341 | + } | |
342 | + | |
343 | + vector<obj_key_t> &&alarm_objs = retrograde_aux(); // 右值引用 | |
344 | + | |
345 | + VPCUtil* pVpcUtil = VPCUtil::getInstance(); | |
346 | + | |
347 | + for (const auto &obj_key : alarm_objs) { | |
348 | + auto &traces = obj_to_traces_[obj_key]; | |
349 | + | |
350 | + if (traces.empty()) | |
351 | + continue; | |
352 | + | |
353 | + if (obj_to_alarm_boxes_.find(obj_key) != obj_to_alarm_boxes_.end() && obj_to_alarm_boxes_[obj_key].size() >= 10) | |
354 | + continue; | |
355 | + | |
356 | + auto &trace = traces.at(0); | |
357 | + auto &&it = task_id_to_stream_idx.find(obj_key.task_id); | |
358 | + if (it == task_id_to_stream_idx.end()) | |
359 | + continue; | |
360 | + | |
361 | + const unsigned stream_idx = it->second; | |
362 | + auto &src_img = vec_det_input_images[stream_idx]; | |
363 | + | |
364 | + result_data_t result_data; | |
365 | + result_data.box = trace; | |
366 | + | |
367 | + // 原图 | |
368 | + vpc_img_info src_img_info = VPCUtil::vpc_devMem2vpcImg(src_img); | |
369 | + result_data.origin_img_desc = src_img_info.pic_desc; | |
370 | + | |
371 | + // 抠图 | |
372 | + int width = src_img->getWidth(); | |
373 | + int height = src_img->getHeight(); | |
374 | + video_object_info obj; | |
375 | + strcpy(obj.task_id, obj_key.task_id.c_str()); | |
376 | + obj.object_id = obj_key.obj_id; | |
377 | + obj.left = clip(trace.left, 0, width); | |
378 | + obj.top = clip(trace.top, 0, height); | |
379 | + obj.right = clip(trace.right, 0, width); | |
380 | + obj.bottom = clip(trace.bottom, 0, height); | |
381 | + | |
382 | + vpc_img_info img_info = pVpcUtil->crop(src_img, obj); | |
383 | + result_data.roi_img_desc = img_info.pic_desc; | |
384 | + | |
385 | + // 保存结果 | |
386 | + obj_to_alarm_boxes_[obj_key].emplace_back(std::move(result_data)); | |
387 | + } | |
388 | + | |
389 | + LOG_DEBUG("obj_to_alarm_boxes_ size: {}", obj_to_alarm_boxes_.size()); | |
390 | + | |
391 | + return true; | |
392 | +} | |
393 | + | |
394 | +} // namespace pedestrian_vehicle_retrograde | |
395 | +} // namespace ai_engine_module | ... | ... |
src/ai_engine_module/pedestrian_vehicle_retrograde.h
0 → 100644
1 | +/* | |
2 | + * File: pedestrian_vehicle_retrograde.hpp | |
3 | + * Created Date: Tuesday February 22nd 2022 | |
4 | + * Author: yangzilong (yangzilong@objecteye.com) | |
5 | + * Description: | |
6 | + * ----- | |
7 | + * Last Modified: Tuesday, 22nd February 2022 4:35:04 pm | |
8 | + * Modified By: yangzilong (yangzilong@objecteye.com>) | |
9 | + * ----- | |
10 | + * Copyright 2022 | |
11 | + */ | |
12 | + | |
13 | +#pragma once | |
14 | + | |
15 | +#include <deque> | |
16 | +#include <map> | |
17 | +#include <vector> | |
18 | +#include "../util/vpc_util.h" | |
19 | +#include "../ai_platform/task_param_manager.h" | |
20 | +#include "ai_engine_header.h" | |
21 | + | |
22 | +class DeviceMemory; | |
23 | + | |
24 | +namespace ai_engine_module { | |
25 | +namespace pedestrian_vehicle_retrograde { | |
26 | + | |
27 | + | |
28 | +class PedestrianVehicleRetrograde { | |
29 | + /** | |
30 | + * @brief | |
31 | + * 1. move able | |
32 | + */ | |
33 | +public: | |
34 | + PedestrianVehicleRetrograde(); | |
35 | + | |
36 | + ~PedestrianVehicleRetrograde(); | |
37 | + | |
38 | + bool update_mstreams(const std::vector<task_id_t> &tasks_id, vector<DeviceMemory*> vec_det_input_images, | |
39 | + const std::vector<onelevel_det_result> &det_result); | |
40 | + | |
41 | + vector<result_data_t> get_results_by_id(const obj_key_t &id, bool do_erase = true); | |
42 | + | |
43 | + void force_release_result(const task_id_t &task_id); | |
44 | + | |
45 | + PedestrianVehicleRetrograde(const PedestrianVehicleRetrograde &) = delete; | |
46 | + PedestrianVehicleRetrograde &operator=(const PedestrianVehicleRetrograde &) = delete; | |
47 | + | |
48 | + PedestrianVehicleRetrograde(PedestrianVehicleRetrograde &&) = default; | |
49 | + PedestrianVehicleRetrograde &operator=(PedestrianVehicleRetrograde &&) = default; | |
50 | + | |
51 | +private: | |
52 | + vector<obj_key_t> retrograde_aux(); | |
53 | + | |
54 | + task_param_manager *task_param_manager_; | |
55 | + std::map<obj_key_t, vector<result_data_t> > obj_to_alarm_boxes_; | |
56 | + std::map<obj_key_t, std::deque<box_t>> obj_to_traces_; | |
57 | +}; | |
58 | +} // namespace pedestrian_vehicle_retrograde | |
59 | +} // namespace ai_engine_module | ... | ... |
src/ai_engine_module/pedestrian_vehicle_trespass.cpp
0 → 100644
1 | +/* | |
2 | + * File: pedestrian_vehicle_trespass.cpp | |
3 | + * Created Date: Tuesday February 22nd 2022 | |
4 | + * Author: yangzilong (yangzilong@objecteye.com) | |
5 | + * Description: | |
6 | + * ----- | |
7 | + * Last Modified: Tuesday, 22nd February 2022 4:38:48 pm | |
8 | + * Modified By: yangzilong (yangzilong@objecteye.com>) | |
9 | + * ----- | |
10 | + * Copyright 2022 | |
11 | + */ | |
12 | + | |
13 | +#include "./pedestrian_vehicle_trespass.h" | |
14 | +#include "opencv2/imgproc/imgproc.hpp" | |
15 | +#include "opencv2/opencv.hpp" | |
16 | +#include <cmath> | |
17 | +#include "../decoder/interface/DeviceMemory.hpp" | |
18 | +#include "../common/logger.hpp" | |
19 | +#include "../ai_platform/mvpt_process_assist.h" | |
20 | + | |
21 | + | |
22 | +namespace ai_engine_module { | |
23 | +namespace pedestrian_vehicle_trespass { | |
24 | + | |
25 | +#define MAX_TRACE_NUM 5 | |
26 | +#define MINIMUM_DISTANCE 10 | |
27 | + | |
28 | +static std::set<algorithm_type_t> algor_type_list_ = { | |
29 | + algorithm_type_t::PEDESTRIAN_TRESPASS, | |
30 | + algorithm_type_t::VEHICLE_TRESPASS, | |
31 | +}; | |
32 | + | |
33 | +// void show_algorthim_result(sy_img img, box_t cur_box, const obj_key_t &key); | |
34 | +// ############################################################ // | |
35 | +// ! Auxiliary Function ! // | |
36 | +// ############################################################ // | |
37 | + | |
38 | +std::set<det_class_label_t> algor_type_to_det_label_set(const algorithm_type_t &algor_type) { | |
39 | + if (algorithm_type_t::PEDESTRIAN_TRESPASS == algor_type) { | |
40 | + return {det_class_label_t::HUMAN}; | |
41 | + } else if (algorithm_type_t::VEHICLE_TRESPASS == algor_type) { | |
42 | + return { | |
43 | + det_class_label_t::LARGE_CAR, det_class_label_t::MEDIUM_BUS, det_class_label_t::SMALL_CAR, | |
44 | + det_class_label_t::TRUCK, det_class_label_t::TRACTOR, | |
45 | + }; | |
46 | + } else { | |
47 | + return {}; | |
48 | + } | |
49 | +} | |
50 | + | |
51 | +/* 是否是有效目标框的辅助判断函数 */ | |
52 | +bool is_valid_box(const int &cls, const algorithm_type_t &algor_type) { | |
53 | + return algor_type_to_det_label_set(algor_type).count(static_cast<det_class_label_t>(cls)); | |
54 | +} | |
55 | + | |
56 | +bool is_valid_box(const box_t &box, const algorithm_type_t &algor_type, | |
57 | + const task_param_manager::algo_param_type_t_ *params_ptr = nullptr) { | |
58 | + if (!params_ptr) | |
59 | + return false; | |
60 | + | |
61 | + if (!snapshot_legal_inarea(params_ptr->basic_param->algor_valid_rect, box.left, box.top, box.right, box.bottom)) | |
62 | + return false; | |
63 | + | |
64 | + if (params_ptr->algor_param == nullptr) | |
65 | + return false; | |
66 | + | |
67 | + if (box.width() == 0 || box.height() == 0) | |
68 | + return false; | |
69 | + | |
70 | + using data_t = algor_config_param_trespass_basic; | |
71 | + auto *algor_params_ptr = (data_t *)(params_ptr->algor_param); | |
72 | + | |
73 | + if (box.score < algor_params_ptr->conf_threshold || box.width() < algor_params_ptr->minmum_width || | |
74 | + box.height() < algor_params_ptr->minmum_height) | |
75 | + return false; | |
76 | + | |
77 | + return is_valid_box(box.cls, algor_type); | |
78 | +} | |
79 | + | |
80 | +/* 获取指定任务的算法配置参数 */ | |
81 | +const task_param_manager::algo_param_type_t_ *get_task_param_ptr(const task_id_t &task_id, | |
82 | + const algorithm_type_t &algor_type, | |
83 | + task_param_manager *const task_param_manager) { | |
84 | + if (!task_param_manager) | |
85 | + return nullptr; | |
86 | + | |
87 | + auto &&algor_param_wrap = task_param_manager->get_task_other_param(task_id, algor_type); | |
88 | + if (!algor_param_wrap) | |
89 | + LOG_ERROR("{} is nullptr when get algor param from task_param", task_id); | |
90 | + return algor_param_wrap; | |
91 | +} | |
92 | + | |
93 | +/* 按照目标任务 检索指定任务的算法配置列表 */ | |
94 | +std::vector<algorithm_type_t> task_id_to_algorithm_type_seq(const task_id_t &task_id, | |
95 | + task_param_manager *const task_param) { | |
96 | + std::vector<algorithm_type_t> seq; | |
97 | + auto &&algor_map = task_param->get_task_other_param(task_id); | |
98 | + for (auto iter = algor_map->begin(); iter != algor_map->end(); ++iter) { | |
99 | + // LOG_TRACE("task id is {} algor type is {}", task_id, int(iter->first)); | |
100 | + if (algor_type_list_.count(iter->first) > 0) | |
101 | + seq.emplace_back(iter->first); | |
102 | + } | |
103 | + return seq; // N(RVO) | |
104 | +} | |
105 | + | |
106 | +// ############################################################ // | |
107 | +// ! Class Member ! // | |
108 | +// ############################################################ // | |
109 | + | |
110 | +PedestrianVehicleTrespass::PedestrianVehicleTrespass() : task_param_manager_(nullptr) { | |
111 | + if (!task_param_manager_) | |
112 | + task_param_manager_ = task_param_manager::getInstance(); | |
113 | +} | |
114 | + | |
115 | +PedestrianVehicleTrespass::~PedestrianVehicleTrespass() = default; | |
116 | + | |
117 | +/* 根据目标id 获取该目标的算法分析结果 */ | |
118 | +vector<result_data_t> PedestrianVehicleTrespass::get_results_by_id(const obj_key_t &id, bool do_erase) { | |
119 | + | |
120 | + vector<result_data_t> res; | |
121 | + auto it = obj_to_alarm_boxes_.find(id); | |
122 | + if (it == obj_to_alarm_boxes_.end()) { | |
123 | + // printf("cant find %s\n", id.task_id.c_str()); | |
124 | + return res; | |
125 | + } | |
126 | + | |
127 | + res = it->second; | |
128 | + if (do_erase) | |
129 | + obj_to_alarm_boxes_.erase(id); | |
130 | + | |
131 | + return res; | |
132 | +} | |
133 | + | |
134 | +/* 目标在禁区内外的辅助判断函数 */ | |
135 | +bool PedestrianVehicleTrespass::in_rect_analysis(const obj_key_t &id, const box_t &cur_bos) { | |
136 | + int center_x = int((cur_bos.left + cur_bos.right) / 2.0); | |
137 | + int center_y = int((cur_bos.top + cur_bos.bottom) / 2.0); | |
138 | + | |
139 | + obj_key_t tmp_id = {0, id.task_id, id.algor_type}; | |
140 | + cv::Mat &dst_mat = trespass_regions[tmp_id]; | |
141 | + // printf("id=%d center: %d %d ", id.obj_id, center_x, center_y); | |
142 | + if (dst_mat.data[center_y * dst_mat.cols + center_x] && dst_mat.data[center_y * dst_mat.cols + center_x + 1] && | |
143 | + dst_mat.data[center_y * dst_mat.cols + center_x - 1] && dst_mat.data[(center_y + 1) * dst_mat.cols + center_x] && | |
144 | + dst_mat.data[(center_y - 1) * dst_mat.cols + center_x]) { | |
145 | + // printf(" true\n"); | |
146 | + return true; // 进入禁区 | |
147 | + } else { | |
148 | + // printf(" false\n"); | |
149 | + return false; // 未进入禁区 | |
150 | + } | |
151 | +} | |
152 | + | |
153 | +/* 根据用户输入的点 初始化禁区区域mask */ | |
154 | +void PedestrianVehicleTrespass::pedestrianvehicletrespass_init_region(const string &task_id, | |
155 | + const algorithm_type_t algor_type, | |
156 | + const int width, const int height) { | |
157 | + obj_key_t obj_key = {0, task_id, algor_type}; | |
158 | + | |
159 | + auto &&algor_type_seq = task_id_to_algorithm_type_seq(task_id, task_param_manager_); | |
160 | + | |
161 | + const task_param_manager::algo_param_type_t_ *param_ptr_wrap = | |
162 | + get_task_param_ptr(task_id, algor_type, task_param_manager_); | |
163 | + if (!param_ptr_wrap) { | |
164 | + printf("cant find %s algorthim params\n", task_id.c_str()); | |
165 | + return; | |
166 | + } | |
167 | + | |
168 | + using param_type_t = algor_config_param_trespass_basic; | |
169 | + const param_type_t *param_ptr = (param_type_t *)(param_ptr_wrap->algor_param); | |
170 | + | |
171 | + cv::Mat src(height, width, CV_8UC3); | |
172 | + src.setTo(0); | |
173 | + | |
174 | + std::vector<cv::Point> contour; | |
175 | + contour.reserve(param_ptr->points_count); | |
176 | + // printf("region points count: %d\n", param_ptr->points_count); | |
177 | + for (int idx = 0; idx < param_ptr->points_count; idx++) { | |
178 | + contour.emplace_back(param_ptr->points[idx].x_, param_ptr->points[idx].y_); | |
179 | + // printf(" =point:%d x:%d y:%d\n", idx, param_ptr->points[idx].x_, param_ptr->points[idx].y_); | |
180 | + } | |
181 | + | |
182 | + std::vector<std::vector<cv::Point>> contours; | |
183 | + contours.push_back(contour); | |
184 | + | |
185 | + cv::polylines(src, contours, true, cv::Scalar(255, 255, 255), 2, 8); // 第2个参数可以采用contour或者contours,均可 | |
186 | + cv::fillPoly(src, contours, cv::Scalar(255, 255, 255)); // fillPoly函数的第二个参数是二维数组 | |
187 | + | |
188 | + cv::Mat &dst_mat = trespass_regions[obj_key]; | |
189 | + cv::cvtColor(src, trespass_regions[obj_key], cv::COLOR_BGR2GRAY); | |
190 | + cv::threshold(trespass_regions[obj_key], trespass_regions[obj_key], 100, 255, cv::THRESH_BINARY); | |
191 | + | |
192 | + if (false) { | |
193 | + cv::imwrite("ori.jpg", src); | |
194 | + cv::imwrite("region.jpg", trespass_regions[obj_key]); | |
195 | + } | |
196 | +} | |
197 | + | |
198 | +/* 非法闯入禁区的 算法判断函数 */ | |
199 | +bool PedestrianVehicleTrespass::update_mstreams(const std::vector<task_id_t> &tasks_id, vector<DeviceMemory*> det_input_images, | |
200 | + const std::vector<onelevel_det_result> &det_results, | |
201 | + const vector<vector<int>> &delete_objs) { | |
202 | + //! check. | |
203 | + if (tasks_id.empty() || tasks_id.size() != det_results.size()) | |
204 | + return false; | |
205 | + | |
206 | + vector<obj_key_t> alarm_objs; | |
207 | + //! loop. | |
208 | + unsigned stream_idx = 0U; | |
209 | + std::map<task_id_t, unsigned> task_id_to_stream_idx; | |
210 | + for (auto task_id_iter = tasks_id.begin(); task_id_iter != tasks_id.end(); ++task_id_iter, ++stream_idx) { | |
211 | + const auto &task_id = *task_id_iter; | |
212 | + task_id_to_stream_idx[task_id] = stream_idx; | |
213 | + // printf("\nbegin judge: %s\n", task_id.c_str()); | |
214 | + | |
215 | + /* 判断该路任务 是否开启该算法 */ | |
216 | + auto &&algor_type_seq = task_id_to_algorithm_type_seq(task_id, task_param_manager_); | |
217 | + if (algor_type_seq.empty()) | |
218 | + continue; | |
219 | + | |
220 | + // 删除 已经删除的目标 | |
221 | + for (auto obj_idx : delete_objs[stream_idx]) { | |
222 | + for (auto algor_type : algor_type_seq) { | |
223 | + obj_key_t obj_key{obj_idx, task_id, algor_type}; | |
224 | + | |
225 | + if (obj_to_position_.find(obj_key) != obj_to_position_.end()) { | |
226 | + // printf("delete obj: %s %d\n", task_id.c_str(), obj_idx); | |
227 | + obj_to_position_.erase(obj_key); | |
228 | + } | |
229 | + } | |
230 | + | |
231 | + // delete obj | |
232 | + } | |
233 | + | |
234 | + /* 依次判断检测目标框 是否有非法闯入 判断逻辑:之前帧在禁区外 当前帧进入禁区 */ | |
235 | + auto &det_result = det_results[stream_idx]; | |
236 | + // printf("det count: %d\n", det_result.obj_count); | |
237 | + for (unsigned box_idx = 0; box_idx < det_result.obj_count; ++box_idx) { | |
238 | + auto &box = det_result.obj[box_idx]; | |
239 | + | |
240 | + box_t unique_box{}; | |
241 | + { | |
242 | + unique_box.id = box.id; | |
243 | + unique_box.cls = box.index; | |
244 | + | |
245 | + unique_box.top = box.top; | |
246 | + unique_box.left = box.left; | |
247 | + unique_box.right = box.right; | |
248 | + unique_box.bottom = box.bottom; | |
249 | + unique_box.score = box.confidence; | |
250 | + } | |
251 | + | |
252 | + //! loop algor | |
253 | + for (auto algor_type : algor_type_seq) { | |
254 | + obj_key_t obj_key{box.id, task_id, algor_type}; | |
255 | + | |
256 | + if (!is_valid_box(unique_box, algor_type, get_task_param_ptr(task_id, algor_type, task_param_manager_))) | |
257 | + obj_to_position_.erase(obj_key); // 如果不满足条件 非 合法框 依然删除 | |
258 | + | |
259 | + //! add or update. | |
260 | + if (!in_rect_analysis(obj_key, unique_box)) // 禁区外 | |
261 | + { | |
262 | + // printf("push in: %s %d\n", task_id.c_str(), box.id); | |
263 | + obj_to_position_[obj_key] = unique_box; | |
264 | + } | |
265 | + | |
266 | + else { // 进入禁区 | |
267 | + if (obj_to_position_.find(obj_key) != obj_to_position_.end()) // 之前在禁区外,可报警 | |
268 | + { | |
269 | + obj_to_position_[obj_key] = unique_box; | |
270 | + | |
271 | + alarm_objs.emplace_back(obj_key); | |
272 | + } | |
273 | + | |
274 | + } | |
275 | + } | |
276 | + } | |
277 | + } | |
278 | + | |
279 | + /* 针对需要报警的目标 缓存当前大图&抠图 等待报警返回 */ | |
280 | + VPCUtil* pVpcUtil = VPCUtil::getInstance(); | |
281 | + for (const auto &obj_key : alarm_objs) { | |
282 | + auto &&it = task_id_to_stream_idx.find(obj_key.task_id); | |
283 | + if (it == task_id_to_stream_idx.end()) | |
284 | + continue; | |
285 | + | |
286 | + // 221009 byzsh记录10条即可-------------------------------------------------------------------------------------- | |
287 | + if (obj_to_alarm_boxes_.find(obj_key) != obj_to_alarm_boxes_.end() && obj_to_alarm_boxes_[obj_key].size() >= 10) | |
288 | + continue; | |
289 | + //-------------------------------------------------------------------------------------------------------------- | |
290 | + const unsigned stream_idx = it->second; | |
291 | + auto &src_img = det_input_images[stream_idx]; | |
292 | + | |
293 | + result_data_t result_data; | |
294 | + result_data.box = obj_to_position_[obj_key]; | |
295 | + | |
296 | + // 原图 | |
297 | + vpc_img_info src_img_info = VPCUtil::vpc_devMem2vpcImg(src_img); | |
298 | + result_data.origin_img_desc = src_img_info.pic_desc; | |
299 | + | |
300 | + // 抠图 | |
301 | + int width = src_img->getWidth(); | |
302 | + int height = src_img->getHeight(); | |
303 | + video_object_info obj; | |
304 | + strcpy(obj.task_id, obj_key.task_id.c_str()); | |
305 | + // obj.task_id = obj_key.task_id.c_str(); | |
306 | + obj.object_id = obj_key.obj_id; | |
307 | + obj.left = clip(result_data.box.left, 0, width); | |
308 | + obj.top = clip(result_data.box.top, 0, height); | |
309 | + obj.right = clip(result_data.box.right, 0, width); | |
310 | + obj.bottom = clip(result_data.box.bottom, 0, height); | |
311 | + | |
312 | + vpc_img_info img_info = pVpcUtil->crop(src_img, obj); | |
313 | + result_data.roi_img_desc = img_info.pic_desc; | |
314 | + | |
315 | + obj_to_alarm_boxes_[obj_key].emplace_back(std::move(result_data)); | |
316 | + obj_to_position_.erase(obj_key); | |
317 | + } | |
318 | + | |
319 | + return true; | |
320 | +} | |
321 | + | |
322 | +/* 辅助函数 显示算法结果 */ | |
323 | +// void show_algorthim_result(sy_img img, box_t cur_box, const obj_key_t &key) { | |
324 | +// const unsigned size = img.c_ * img.h_ * img.w_; | |
325 | +// auto *img_data = new unsigned char[size]; | |
326 | + | |
327 | +// CHECK(cudaMemcpy(img_data, img.data_, size * sizeof(unsigned char), cudaMemcpyDeviceToHost)); | |
328 | +// cv::Mat show_image(img.h_, img.w_, CV_8UC3, img_data); | |
329 | + | |
330 | +// std::vector<cv::Point> contour; | |
331 | +// /* | |
332 | +// contour.push_back(cv::Point(200, 200)); | |
333 | +// contour.push_back(cv::Point(600, 200)); | |
334 | +// contour.push_back(cv::Point(600, 500)); | |
335 | +// contour.push_back(cv::Point(200, 500)); | |
336 | +// */ | |
337 | +// contour.emplace_back(500, 500); | |
338 | +// contour.emplace_back(1500, 500); | |
339 | +// contour.emplace_back(1500, 900); | |
340 | +// contour.emplace_back(500, 900); | |
341 | + | |
342 | +// std::vector<std::vector<cv::Point>> contours; | |
343 | +// contours.push_back(contour); | |
344 | + | |
345 | +// cv::polylines(show_image, contours, true, cv::Scalar(255, 255, 255), 2, | |
346 | +// 8); // 第2个参数可以采用contour或者contours,均可 | |
347 | + | |
348 | +// cv::rectangle(show_image, cv::Point(cur_box.left, cur_box.top), cv::Point(cur_box.right, cur_box.bottom), | |
349 | +// cv::Scalar(0, 250, 0), 2, 8); | |
350 | + | |
351 | +// char filename[256]; | |
352 | +// sprintf(filename, "res_image/%s_%ld.jpg", key.task_id.c_str(), key.obj_id); | |
353 | +// cv::imwrite(filename, show_image); | |
354 | +// printf("\n *****ERROR finish save %s %ld\n", key.task_id.c_str(), key.obj_id); | |
355 | +// } | |
356 | + | |
357 | +} // namespace pedestrian_vehicle_trespass | |
358 | +} // namespace ai_engine_module | ... | ... |
src/ai_engine_module/pedestrian_vehicle_trespass.h
0 → 100644
1 | +/* | |
2 | + * File: pedestrian_vehicle_trespass.hpp | |
3 | + * Created Date: Tuesday February 22nd 2022 | |
4 | + * Author: yangzilong (yangzilong@objecteye.com) | |
5 | + * Description: | |
6 | + * ----- | |
7 | + * Last Modified: Tuesday, 22nd February 2022 4:35:04 pm | |
8 | + * Modified By: yangzilong (yangzilong@objecteye.com>) | |
9 | + * ----- | |
10 | + * Copyright 2022 | |
11 | + */ | |
12 | + | |
13 | +#pragma once | |
14 | +#include "opencv2/highgui/highgui.hpp" | |
15 | +#include <deque> | |
16 | +#include <map> | |
17 | +#include <vector> | |
18 | +#include "../util/vpc_util.h" | |
19 | +#include "../ai_platform/task_param_manager.h" | |
20 | +#include "ai_engine_header.h" | |
21 | + | |
22 | +class DeviceMemory; | |
23 | + | |
24 | +namespace ai_engine_module { | |
25 | +namespace pedestrian_vehicle_trespass { | |
26 | + | |
27 | +class PedestrianVehicleTrespass { | |
28 | + /** | |
29 | + * @brief | |
30 | + * 1. move able | |
31 | + */ | |
32 | +public: | |
33 | + PedestrianVehicleTrespass(); | |
34 | + | |
35 | + ~PedestrianVehicleTrespass(); | |
36 | + | |
37 | + void pedestrianvehicletrespass_init_region(const string &task_id, const algorithm_type_t algor_type, const int width, | |
38 | + const int height); | |
39 | + | |
40 | + bool update_mstreams(const std::vector<task_id_t> &tasks_id, vector<DeviceMemory*> det_input_images, | |
41 | + const std::vector<onelevel_det_result> &det_result, const vector<vector<int>> &delete_objs); | |
42 | + | |
43 | + vector<result_data_t> get_results_by_id(const obj_key_t &id, bool do_erase = true); | |
44 | + | |
45 | + PedestrianVehicleTrespass(const PedestrianVehicleTrespass &) = delete; | |
46 | + PedestrianVehicleTrespass &operator=(const PedestrianVehicleTrespass &) = delete; | |
47 | + | |
48 | + PedestrianVehicleTrespass(PedestrianVehicleTrespass &&) = default; | |
49 | + PedestrianVehicleTrespass &operator=(PedestrianVehicleTrespass &&) = default; | |
50 | + | |
51 | +private: | |
52 | + bool in_rect_analysis(const obj_key_t &id, const box_t &cur_bos); | |
53 | + | |
54 | + task_param_manager *task_param_manager_; | |
55 | + std::map<obj_key_t, vector<result_data_t> > obj_to_alarm_boxes_; | |
56 | + std::map<obj_key_t, box_t> obj_to_position_; // 保存物体上一帧的位置,基于非法闯入判断逻辑,上一帧在框外,下一帧闯入禁区 | |
57 | + std::map<obj_key_t, cv::Mat> trespass_regions; | |
58 | +}; | |
59 | +} // namespace pedestrian_vehicle_trespass | |
60 | +} // namespace ai_engine_module | ... | ... |
src/ai_platform/MultiSourceProcess.cpp
... | ... | @@ -17,6 +17,8 @@ |
17 | 17 | #include "macro_definition.h" |
18 | 18 | #include "SourceSingleton.hpp" |
19 | 19 | |
20 | +#include "../util/vpc_util.h" | |
21 | + | |
20 | 22 | // #define VEHICLE_MULTI_BOXES |
21 | 23 | |
22 | 24 | using namespace std; |
... | ... | @@ -72,7 +74,6 @@ CMultiSourceProcess::CMultiSourceProcess(){ |
72 | 74 | } |
73 | 75 | |
74 | 76 | CMultiSourceProcess::~CMultiSourceProcess(){ |
75 | - vpc_util.release(); | |
76 | 77 | } |
77 | 78 | |
78 | 79 | int CMultiSourceProcess::InitAlgorthim(tsl_aiplatform_param vptParam){ |
... | ... | @@ -103,7 +104,8 @@ int CMultiSourceProcess::InitAlgorthim(tsl_aiplatform_param vptParam){ |
103 | 104 | m_snapshot_reprocessing = new snapshot_reprocessing(m_devId); |
104 | 105 | m_save_snapshot_reprocessing = new save_snapshot_reprocessing(m_devId); |
105 | 106 | |
106 | - vpc_util.init(m_devId); | |
107 | + VPCUtil* pVpcUtil = VPCUtil::getInstance(); | |
108 | + pVpcUtil->init(m_devId); | |
107 | 109 | |
108 | 110 | m_pAlgorthimThread = new thread([](void* arg) { |
109 | 111 | CMultiSourceProcess* process = (CMultiSourceProcess*)arg ; |
... | ... | @@ -499,23 +501,32 @@ int CMultiSourceProcess::algorthim_vpt(vector<DeviceMemory*> vec_gpuMem){ |
499 | 501 | /* 一级检测器,内部已完成跟踪操作 */ |
500 | 502 | vpt_process.process_gpu(vpt_interest_imgs.data(), vpt_interest_task_id, vptResult, deleteObjectID, unUsedResult); // do det & track. |
501 | 503 | |
502 | -// m_snapshot_reprocessing->screen_effective_snapshot(vptResult); | |
504 | + m_snapshot_reprocessing->screen_effective_snapshot(vptResult); | |
505 | + | |
506 | +#ifndef VEHICLE_MULTI_BOXES | |
507 | + /* 快照优选(内部可实现不同的快照优选策略) */ | |
508 | + m_snapshot_reprocessing->update_bestsnapshot(vec_vptMem, vptResult, deleteObjectID); | |
509 | + | |
510 | + /* for snapshot algorithm. 轨迹结束目标 做最后的结果返回(当前返回算法结果+快照保存路径)*/ | |
511 | + vehicle_snapshot(vpt_interest_task_id, deleteObjectID); | |
512 | +#else | |
513 | + algorithm_vehicle_relult(vec_vptMem, vptResult, deleteObjectID); | |
514 | + | |
515 | + send_locus_finished_msg(vpt_interest_task_id, deleteObjectID); | |
516 | +#endif | |
503 | 517 | |
504 | -// #ifndef VEHICLE_MULTI_BOXES | |
505 | -// /* 快照优选(内部可实现不同的快照优选策略) */ | |
506 | -// m_snapshot_reprocessing->update_bestsnapshot(vec_vptMem, vptResult, deleteObjectID); | |
518 | +// #ifdef WITH_SECOND_PROCESS | |
519 | + /* for pedestrian safety det. 行人安全分析算法模块 */ | |
520 | + // algorthim_pedestrian_safety(vpt_interest_task_id, vpt_interest_imgs,vptResult); | |
507 | 521 | |
508 | -// /* for snapshot algorithm. 轨迹结束目标 做最后的结果返回(当前返回算法结果+快照保存路径)*/ | |
509 | -// vehicle_snapshot(vpt_interest_task_id, deleteObjectID); | |
510 | -// #else | |
511 | -// algorithm_vehicle_relult(vec_vptMem, vptResult, deleteObjectID); | |
522 | + /* for retrograde & trespass algor 逆行&非法闯入算法模块 */ | |
523 | + algorthim_retrograde_trespass(vpt_interest_task_id, vec_vptMem, vptResult, deleteObjectID); | |
512 | 524 | |
513 | -// send_locus_finished_msg(vpt_interest_task_id, deleteObjectID); | |
514 | 525 | // #endif |
515 | 526 | |
516 | -// if(vptResult.size() > 0){ | |
517 | -// cout << vptResult[0].obj_count<< endl; | |
518 | -// } | |
527 | + if(vptResult.size() > 0){ | |
528 | + cout << vptResult[0].obj_count<< endl; | |
529 | + } | |
519 | 530 | vptResult.clear(); |
520 | 531 | unUsedResult.clear(); |
521 | 532 | deleteObjectID.clear(); |
... | ... | @@ -532,6 +543,7 @@ int CMultiSourceProcess::algorithm_vehicle_relult(vector<DeviceMemory*> vec_devM |
532 | 543 | |
533 | 544 | vector<multi_obj_data_t> results = m_snapshot_reprocessing->get_vehicle_snapshot(vec_devMem, vptResult, skip_frame_); |
534 | 545 | |
546 | + VPCUtil* pVPCUtil = VPCUtil::getInstance(); | |
535 | 547 | for (auto &result : results) { |
536 | 548 | if(result.objs.size() <= 0){ |
537 | 549 | continue; |
... | ... | @@ -551,13 +563,13 @@ int CMultiSourceProcess::algorithm_vehicle_relult(vector<DeviceMemory*> vec_devM |
551 | 563 | |
552 | 564 | ImgSaveInfo saveInfo; |
553 | 565 | saveInfo.file_path = fpath_origin; |
554 | - saveInfo.img_info = vpc_util.vpc_devMem2vpcImg(result.memPtr); | |
566 | + saveInfo.img_info = VPCUtil::vpc_devMem2vpcImg(result.memPtr); | |
555 | 567 | m_save_snapshot_reprocessing->reprocessing_process_wo_locus_async(saveInfo); |
556 | 568 | |
557 | - vector<vpc_img_info> vec_obj_info_list = vpc_util.crop_batch(result.memPtr, result.objs); | |
569 | + vector<vpc_img_info> vec_obj_info_list = pVPCUtil->crop_batch(result.memPtr, result.objs); | |
558 | 570 | if(vec_obj_info_list.size() != result.objs.size()){ |
559 | 571 | LOG_ERROR("vpc_crop size error !"); |
560 | - vpc_util.vpc_imgList_release(vec_obj_info_list); | |
572 | + VPCUtil::vpc_imgList_release(vec_obj_info_list); | |
561 | 573 | continue; |
562 | 574 | } |
563 | 575 | |
... | ... | @@ -645,22 +657,73 @@ void CMultiSourceProcess::vehicle_snapshot(vector<string>& vpt_interest_task_id, |
645 | 657 | } |
646 | 658 | |
647 | 659 | /* 轨迹结束帧需要做的算法模块 */ |
648 | -/* 轨迹结束帧需要做的算法模块 */ | |
649 | 660 | int CMultiSourceProcess::endframe_obj_process(const OBJ_KEY &obj_key, algorithm_type_t algor_type) { |
661 | + | |
662 | + // 该路任务开启了抓拍功能 开始抓拍保存;若未开启抓拍,清空显存资源 | |
663 | + vehicle_locus_finished(obj_key); | |
664 | + | |
665 | + /* 开启行人&机动车逆行算法模块,获取该目标的算法分析结果 返回结果+快照 最后释放资源 */ | |
666 | + endframe_retrograde_obj_process(obj_key); | |
667 | +} | |
668 | + | |
669 | +int CMultiSourceProcess::endframe_retrograde_obj_process(const OBJ_KEY &obj_key) { | |
670 | + auto task_param_ptr = m_task_param_manager->get_task_algor_param(obj_key.video_id); | |
671 | + | |
672 | + /* 开启行人&机动车逆行算法模块,获取该目标的算法分析结果 返回结果+快照 最后释放资源 */ | |
673 | + if (task_param_ptr->human_algors.find(algorithm_type_t::PEDESTRIAN_RETROGRADE) != | |
674 | + task_param_ptr->human_algors.end()) | |
675 | + retrograde_alarm(obj_key, algorithm_type_t::PEDESTRIAN_RETROGRADE); | |
676 | + | |
677 | + if (task_param_ptr->vehicle_algors.find(algorithm_type_t::VEHICLE_RETROGRADE) != | |
678 | + task_param_ptr->vehicle_algors.end()) | |
679 | + retrograde_alarm(obj_key, algorithm_type_t::VEHICLE_RETROGRADE); | |
680 | +} | |
681 | + | |
682 | +void CMultiSourceProcess::retrograde_alarm(const OBJ_KEY &obj_key, const algorithm_type_t &algor_type) { | |
683 | + | |
684 | + auto results = pedestrian_vehicle_retrograde_.get_results_by_id( | |
685 | + ai_engine_module::obj_key_t{obj_key.obj_id, obj_key.video_id, algor_type}); | |
686 | + | |
687 | + bool bRetroGrade = true ; | |
688 | + for (unsigned idx = 0; idx < results.size(); ++idx) { | |
689 | + auto &result = results[idx]; | |
690 | + | |
691 | + vpc_img_info src_img; | |
692 | + src_img.pic_desc = result.origin_img_desc; | |
693 | + src_img.task_id = obj_key.video_id; | |
694 | + | |
695 | + vpc_img_info roi_img; | |
696 | + roi_img.pic_desc = result.roi_img_desc; | |
697 | + roi_img.task_id = obj_key.video_id; | |
698 | + roi_img.object_id = obj_key.obj_id; | |
699 | + | |
700 | + if(bRetroGrade){ | |
701 | + auto &&json_str = helpers::gen_json::gen_retrograde_json(obj_key.video_id, obj_key.obj_id, result.box, algor_type); | |
702 | + save_snapshot_process(obj_key, algor_type, src_img, roi_img, idx, json_str); | |
703 | + } else { | |
704 | + VPCUtil::vpc_img_release(src_img); | |
705 | + VPCUtil::vpc_img_release(roi_img); | |
706 | + } | |
707 | + | |
708 | + if (bRetroGrade == true) { | |
709 | + bRetroGrade = false; | |
710 | + } | |
711 | + | |
712 | + } | |
713 | + | |
714 | +} | |
715 | + | |
716 | +void CMultiSourceProcess::vehicle_locus_finished(const OBJ_KEY obj_key) { | |
650 | 717 | auto task_param_ptr = m_task_param_manager->get_task_algor_param(obj_key.video_id); |
651 | 718 | auto task_other_param_ptr = m_task_param_manager->get_task_other_param(obj_key.video_id); |
652 | 719 | |
653 | 720 | // 该路任务开启了抓拍功能 开始抓拍保存;若未开启抓拍,清空显存资源 |
654 | - if ((task_param_ptr->human_algors.find(algorithm_type_t::HUMAN_SNAPSHOT) != task_param_ptr->human_algors.end() || | |
655 | - task_param_ptr->vehicle_algors.find(algorithm_type_t::VEHICLE_SNAPSHOT) != task_param_ptr->vehicle_algors.end() || | |
721 | + if ((task_param_ptr->human_algors.find(algorithm_type_t::HUMAN_SNAPSHOT) == task_param_ptr->human_algors.end() && | |
722 | + task_param_ptr->vehicle_algors.find(algorithm_type_t::VEHICLE_SNAPSHOT) != task_param_ptr->vehicle_algors.end() && | |
656 | 723 | task_param_ptr->nonmotor_vehicle_algors.find(algorithm_type_t::NONMOTOR_VEHICLE_SNAPSHOT) != task_param_ptr->nonmotor_vehicle_algors.end())) { |
657 | - | |
658 | - vehicle_locus_finished(obj_key); | |
659 | - | |
724 | + return; | |
660 | 725 | } |
661 | -} | |
662 | 726 | |
663 | -void CMultiSourceProcess::vehicle_locus_finished(const OBJ_KEY obj_key){ | |
664 | 727 | map<OBJ_KEY, OBJ_VALUE> _total_snapshot_info = m_snapshot_reprocessing->get_total_snapshot_info(); |
665 | 728 | |
666 | 729 | LOG_DEBUG("_total_snapshot_info size: {}", _total_snapshot_info.size()); |
... | ... | @@ -780,4 +843,88 @@ void CMultiSourceProcess::timing_snapshot_thread(){ |
780 | 843 | jpegUtil.jpeg_release(); |
781 | 844 | |
782 | 845 | LOG_INFO("timing_snapshot_thread end."); |
846 | +} | |
847 | + | |
848 | +void CMultiSourceProcess::algorthim_retrograde_trespass(vector<string>& vpt_interest_task_id, vector<DeviceMemory*> vpt_interest_imgs, | |
849 | + vector<onelevel_det_result>& vptResult ,vector<vector<int>>& deleteObjectID){ | |
850 | + vector<string> interest_task_id; | |
851 | + vector<onelevel_det_result> interest_vpt_result; | |
852 | + vector<DeviceMemory*> interest_imgs; | |
853 | + | |
854 | + vector<string> trespass_interest_task_id; | |
855 | + vector<onelevel_det_result> trespass_interest_vpt_result; | |
856 | + vector<vector<int>> trespass_interest_deleteobjs; | |
857 | + vector<DeviceMemory*> trespass_interest_imgs; | |
858 | + | |
859 | + int _idx = 0; | |
860 | + for (auto _task_id_iter = vpt_interest_task_id.begin(); _task_id_iter != vpt_interest_task_id.end(); | |
861 | + ++_task_id_iter, ++_idx) // loop task_id; | |
862 | + { | |
863 | + auto task_id = *_task_id_iter; | |
864 | + auto algor_map = m_task_param_manager->get_task_other_param(task_id); | |
865 | + | |
866 | + if (algor_map->find(algorithm_type_t::PEDESTRIAN_RETROGRADE) != algor_map->end() || | |
867 | + algor_map->find(algorithm_type_t::VEHICLE_RETROGRADE) != algor_map->end()) { | |
868 | + interest_task_id.emplace_back(task_id); | |
869 | + interest_imgs.emplace_back(vpt_interest_imgs[_idx]); | |
870 | + interest_vpt_result.emplace_back(vptResult[_idx]); | |
871 | + } | |
872 | + | |
873 | + if (algor_map->find(algorithm_type_t::PEDESTRIAN_TRESPASS) != algor_map->end() || | |
874 | + algor_map->find(algorithm_type_t::VEHICLE_TRESPASS) != algor_map->end()) { | |
875 | + trespass_interest_task_id.emplace_back(task_id); | |
876 | + trespass_interest_imgs.emplace_back(vpt_interest_imgs[_idx]); | |
877 | + trespass_interest_vpt_result.emplace_back(vptResult[_idx]); | |
878 | + trespass_interest_deleteobjs.emplace_back(deleteObjectID[_idx]); | |
879 | + } | |
880 | + } | |
881 | + | |
882 | + LOG_DEBUG("trespass_interest_vpt_result size: {}", trespass_interest_vpt_result.size()); | |
883 | + | |
884 | + if (!interest_imgs.empty()) | |
885 | + pedestrian_vehicle_retrograde_.update_mstreams(interest_task_id, interest_imgs, | |
886 | + interest_vpt_result); | |
887 | + | |
888 | + if (!trespass_interest_imgs.empty()) { | |
889 | + pedestrian_vehicle_trespass_.update_mstreams( | |
890 | + trespass_interest_task_id, trespass_interest_imgs, trespass_interest_vpt_result, | |
891 | + trespass_interest_deleteobjs); | |
892 | + } | |
893 | +} | |
894 | + | |
895 | +bool CMultiSourceProcess::save_snapshot_process(const OBJ_KEY &obj_key, const algorithm_type_t &algorithm_type, vpc_img_info src_img, vpc_img_info roi_img, | |
896 | + const long long id,const std::string &json_str) { | |
897 | + auto task_other_params = m_task_param_manager->get_task_other_param(obj_key.video_id); | |
898 | + const auto &algor_other_params = task_other_params->find(algorithm_type); | |
899 | + if (algor_other_params == task_other_params->end()) { | |
900 | + LOG_ERROR("task_id {} not found {} error", obj_key.video_id, int(algorithm_type)); | |
901 | + return false; | |
902 | + } | |
903 | + | |
904 | + const algor_basic_config_param_t *basic_param = algor_other_params->second->basic_param; | |
905 | + | |
906 | + std::string cur_timestamp_ms = std::to_string(helpers::timer::get_timestamp<std::chrono::milliseconds>()); | |
907 | + const std::string fpath_origin = basic_param->result_folder + helpers::os::sep + obj_key.video_id + "_" + | |
908 | + std::to_string(obj_key.obj_id) + "_" + std::to_string(id) + "_" + cur_timestamp_ms + ".jpg"; | |
909 | + | |
910 | + ImgSaveInfo obj_save_info; | |
911 | + obj_save_info.file_path = fpath_origin; | |
912 | + obj_save_info.img_info = src_img; | |
913 | + m_save_snapshot_reprocessing->reprocessing_process_wo_locus_async(obj_save_info); | |
914 | + | |
915 | + { | |
916 | + // 抠图保存 | |
917 | + const std::string fpath_roi = basic_param->result_folder_little + helpers::os::sep + obj_key.video_id + "_" + | |
918 | + std::to_string(obj_key.obj_id) + "_" + std::to_string(id) + "_" + cur_timestamp_ms + ".jpg"; | |
919 | + | |
920 | + // 调用快照保存后处理模块 将快照保存 | |
921 | + ImgSaveInfo obj_save_info; | |
922 | + obj_save_info.file_path = fpath_roi; | |
923 | + obj_save_info.img_info = roi_img; | |
924 | + obj_save_info.json_str = json_str; | |
925 | + m_save_snapshot_reprocessing->reprocessing_process_wo_locus_async(obj_save_info); | |
926 | + } | |
927 | + | |
928 | + | |
929 | + return true; | |
783 | 930 | } |
784 | 931 | \ No newline at end of file | ... | ... |
src/ai_platform/MultiSourceProcess.h
... | ... | @@ -5,7 +5,8 @@ |
5 | 5 | #include "../ai_engine_module/VPTProcess.h" |
6 | 6 | #include "../reprocessing_module/snapshot_reprocessing.h" |
7 | 7 | #include "../reprocessing_module/save_snapshot_reprocessing.h" |
8 | -#include "../util/vpc_util.h" | |
8 | +#include "../ai_engine_module/pedestrian_vehicle_retrograde.h" | |
9 | +#include "../ai_engine_module/pedestrian_vehicle_trespass.h" | |
9 | 10 | #include "../util/JpegUtil.h" |
10 | 11 | |
11 | 12 | #include <map> |
... | ... | @@ -48,6 +49,9 @@ public: |
48 | 49 | private: |
49 | 50 | // 算法相关 |
50 | 51 | int algorthim_vpt(vector<DeviceMemory*> vec_gpuMem); |
52 | + // 逆行&非法闯入算法模块 | |
53 | + void algorthim_retrograde_trespass(vector<string>& vpt_interest_task_id, vector<DeviceMemory*> vpt_interest_imgs, | |
54 | + vector<onelevel_det_result>& vptResult ,vector<vector<int>>& deleteObjectID); | |
51 | 55 | |
52 | 56 | private: |
53 | 57 | // 工具处理函数 |
... | ... | @@ -61,6 +65,12 @@ private: |
61 | 65 | |
62 | 66 | int endframe_obj_process(const OBJ_KEY &obj_key, algorithm_type_t algor_type); |
63 | 67 | |
68 | + bool save_snapshot_process(const OBJ_KEY &obj_key, const algorithm_type_t &algorithm_type, vpc_img_info img_info, vpc_img_info roi_img, | |
69 | + const long long id,const std::string &json_str); | |
70 | + | |
71 | + int endframe_retrograde_obj_process(const OBJ_KEY &obj_key); | |
72 | + void retrograde_alarm(const OBJ_KEY &obj_key, const algorithm_type_t &algor_type) ; | |
73 | + | |
64 | 74 | private: |
65 | 75 | int m_devId; |
66 | 76 | |
... | ... | @@ -87,11 +97,14 @@ private: |
87 | 97 | set<OBJ_KEY> m_total_snapshot_info_multi_object; |
88 | 98 | mutex m_total_mutex; |
89 | 99 | |
90 | - VPCUtil vpc_util; | |
91 | 100 | JpegUtil jpegUtil; |
92 | 101 | |
93 | 102 | #ifdef POST_USE_RABBITMQ |
94 | 103 | mq::Manager *mq_manager_{nullptr}; |
95 | 104 | #endif |
96 | 105 | |
106 | + | |
107 | + ai_engine_module::pedestrian_vehicle_retrograde::PedestrianVehicleRetrograde pedestrian_vehicle_retrograde_; | |
108 | + ai_engine_module::pedestrian_vehicle_trespass::PedestrianVehicleTrespass pedestrian_vehicle_trespass_; | |
109 | + | |
97 | 110 | }; |
98 | 111 | \ No newline at end of file | ... | ... |
src/demo/demo.cpp
... | ... | @@ -478,9 +478,9 @@ static long long get_cur_time(){ |
478 | 478 | string createTask(void *handle, std::vector<algorithm_type_t> algor_vec, int gi){ |
479 | 479 | task_param tparam; |
480 | 480 | // tparam.ipc_url = "rtsp://admin:ad123456@192.168.60.108:554/cam/realmonitor?channel=1&subtype=0"; |
481 | - // tparam.ipc_url = "/home/cmhu/data/bayue.mp4"; | |
482 | - // tparam.ipc_url = "/home/cmhu/data/Street.uvf"; | |
483 | - tparam.ipc_url = "rtsp://admin:ad123456@192.168.60.165:554/cam/realmonitor?channel=1&subtype=0"; | |
481 | + // tparam.ipc_url = "/data1/cmhu/data/bayue.mp4"; | |
482 | + tparam.ipc_url = "/data1/cmhu/data/Street.uvf"; | |
483 | + // tparam.ipc_url = "rtsp://admin:ad123456@192.168.60.165:554/cam/realmonitor?channel=1&subtype=0"; | |
484 | 484 | tparam.algor_counts = algor_vec.size(); |
485 | 485 | tparam.dec_type = 2; |
486 | 486 | |
... | ... | @@ -521,7 +521,7 @@ void test_gpu(int gpuID){ |
521 | 521 | printf("Init Success\n"); |
522 | 522 | } |
523 | 523 | |
524 | - std::vector<algorithm_type_t> algor_vec = {algorithm_type_t::FACE_SNAPSHOT, algorithm_type_t::HUMAN_SNAPSHOT,algorithm_type_t::ROAD_WORK_DET, | |
524 | + std::vector<algorithm_type_t> algor_vec = {algorithm_type_t::FACE_SNAPSHOT, algorithm_type_t::HUMAN_SNAPSHOT,algorithm_type_t::ROAD_WORK_DET, algorithm_type_t::PEDESTRIAN_RETROGRADE, algorithm_type_t::VEHICLE_RETROGRADE, | |
525 | 525 | algorithm_type_t::VEHICLE_SNAPSHOT, algorithm_type_t::NONMOTOR_VEHICLE_SNAPSHOT, algorithm_type_t::VIDEO_TIMING_SNAPSHOT}; |
526 | 526 | |
527 | 527 | string task_id = createTask(handle, algor_vec, 0 + gpuID * 10); | ... | ... |
src/reprocessing_module/save_snapshot_reprocessing.cpp
... | ... | @@ -5,6 +5,7 @@ |
5 | 5 | #include <opencv2/imgproc/types_c.h> |
6 | 6 | #include <algorithm> |
7 | 7 | #include "../common/logger.hpp" |
8 | +#include "../util/vpc_util.h" | |
8 | 9 | |
9 | 10 | const bool DRAW_ON_IMG = false; |
10 | 11 | |
... | ... | @@ -46,7 +47,7 @@ void save_snapshot_reprocessing::save_snapshot_reprocessing_release() { |
46 | 47 | waitforsave_img_queue.pop(); |
47 | 48 | |
48 | 49 | if(!cur_image.file_path.empty()){ |
49 | - vpc_util.vpc_img_release(cur_image.img_info); | |
50 | + VPCUtil::vpc_img_release(cur_image.img_info); | |
50 | 51 | } |
51 | 52 | } |
52 | 53 | |
... | ... | @@ -96,7 +97,7 @@ void save_snapshot_reprocessing::save_img_process() { |
96 | 97 | if(!cur_image.file_path.empty()){ |
97 | 98 | jpegUtil.jpeg_encode(cur_image.img_info.pic_desc, cur_image.file_path); |
98 | 99 | } |
99 | - vpc_util.vpc_img_release(cur_image.img_info); | |
100 | + VPCUtil::vpc_img_release(cur_image.img_info); | |
100 | 101 | |
101 | 102 | #ifdef POST_USE_RABBITMQ |
102 | 103 | if (callback_ != nullptr && cur_image.json_str.length() > 0) { | ... | ... |
src/reprocessing_module/save_snapshot_reprocessing.h
... | ... | @@ -15,8 +15,8 @@ |
15 | 15 | #include <thread> |
16 | 16 | |
17 | 17 | #include "../ai_platform/det_obj_header.h" |
18 | -#include "../util/vpc_util.h" | |
19 | 18 | #include "../util/JpegUtil.h" |
19 | +#include "../util/vpc_util.h" | |
20 | 20 | |
21 | 21 | #ifdef POST_USE_RABBITMQ |
22 | 22 | #include "post_reprocessing.hpp" |
... | ... | @@ -60,7 +60,6 @@ private: |
60 | 60 | int m_devId; |
61 | 61 | |
62 | 62 | JpegUtil jpegUtil; |
63 | - VPCUtil vpc_util; | |
64 | 63 | |
65 | 64 | #ifdef POST_USE_RABBITMQ |
66 | 65 | callback_t callback_; | ... | ... |
src/reprocessing_module/snapshot_reprocessing.cpp
... | ... | @@ -12,13 +12,10 @@ snapshot_reprocessing::snapshot_reprocessing(int devId) |
12 | 12 | algor_index_table["human"] = { (int)det_class_label_t::HUMAN }; |
13 | 13 | algor_index_table["nonmotor_vehicle"] = { (int)det_class_label_t::BICYCLE, (int)det_class_label_t::MOTOCYCLE, (int)det_class_label_t::TRICYCLE }; |
14 | 14 | algor_index_table["vehicle"] = { (int)det_class_label_t::SMALL_CAR, (int)det_class_label_t::LARGE_CAR, (int)det_class_label_t::TRUCK, (int)det_class_label_t::TRACTOR, (int)det_class_label_t::MEDIUM_BUS }; |
15 | - | |
16 | - vpcUtil.init(devId); | |
17 | 15 | } |
18 | 16 | |
19 | 17 | snapshot_reprocessing::~snapshot_reprocessing() |
20 | 18 | { |
21 | - vpcUtil.release(); | |
22 | 19 | } |
23 | 20 | |
24 | 21 | static void box_expansion(video_object_info& obj_info, float expand_ratio, int frame_width, int frame_height){ |
... | ... | @@ -175,6 +172,8 @@ void snapshot_reprocessing::update_bestsnapshot(vector<DeviceMemory*> vec_devMem |
175 | 172 | map<string, algor_open_config_param> && algor_config_param = m_task_param_manager->get_task_algor_params(); |
176 | 173 | map<string, map<algo_type, task_param_manager::algo_param_type_t_*>> && algor_param = m_task_param_manager->get_task_other_params(); |
177 | 174 | |
175 | + VPCUtil* pVpcUtil = VPCUtil::getInstance(); | |
176 | + | |
178 | 177 | for (size_t i = 0; i < vec_devMem.size(); i++){ |
179 | 178 | |
180 | 179 | onelevel_det_result det_result = ol_det_result[i]; |
... | ... | @@ -316,15 +315,15 @@ void snapshot_reprocessing::update_bestsnapshot(vector<DeviceMemory*> vec_devMem |
316 | 315 | } |
317 | 316 | } |
318 | 317 | |
319 | - vector<vpc_img_info> imgList = vpcUtil.crop_batch(memPtr, vec_obj_info); | |
318 | + vector<vpc_img_info> imgList = pVpcUtil->crop_batch(memPtr, vec_obj_info); | |
320 | 319 | vec_obj_info.clear(); |
321 | 320 | |
322 | 321 | for (size_t i = 0; i < imgList.size(); i++) { |
323 | 322 | vpc_img_info obj_info = imgList[i]; |
324 | 323 | OBJ_KEY objKey = { obj_info.task_id, obj_info.object_id }; |
325 | - vpcUtil.vpc_img_release(total_snapshot_info[objKey].snapShot); | |
326 | - total_snapshot_info[objKey].snapShot = vpcUtil.vpc_devMem2vpcImg(memPtr); | |
327 | - vpcUtil.vpc_img_release(total_snapshot_info[objKey].snapShotLittle); | |
324 | + VPCUtil::vpc_img_release(total_snapshot_info[objKey].snapShot); | |
325 | + total_snapshot_info[objKey].snapShot = VPCUtil::vpc_devMem2vpcImg(memPtr); | |
326 | + VPCUtil::vpc_img_release(total_snapshot_info[objKey].snapShotLittle); | |
328 | 327 | total_snapshot_info[objKey].snapShotLittle = obj_info; |
329 | 328 | } |
330 | 329 | imgList.clear(); |
... | ... | @@ -360,8 +359,8 @@ void snapshot_reprocessing::release_finished_locus_snapshot(const string taskid, |
360 | 359 | if (bRelease){ |
361 | 360 | OBJ_VALUE ss = total_snapshot_info[cur_key]; |
362 | 361 | |
363 | - vpcUtil.vpc_img_release(ss.snapShot); | |
364 | - vpcUtil.vpc_img_release(ss.snapShotLittle); | |
362 | + VPCUtil::vpc_img_release(ss.snapShot); | |
363 | + VPCUtil::vpc_img_release(ss.snapShotLittle); | |
365 | 364 | } |
366 | 365 | |
367 | 366 | total_snapshot_info.erase(cur_key); |
... | ... | @@ -373,8 +372,8 @@ void snapshot_reprocessing::release_finished_locus_snapshot(const string taskid, |
373 | 372 | if (strcmp(ss->first.video_id.c_str(), taskid.c_str()) == 0) |
374 | 373 | { |
375 | 374 | if (bRelease){ |
376 | - vpcUtil.vpc_img_release(ss->second.snapShot); | |
377 | - vpcUtil.vpc_img_release(ss->second.snapShotLittle); | |
375 | + VPCUtil::vpc_img_release(ss->second.snapShot); | |
376 | + VPCUtil::vpc_img_release(ss->second.snapShotLittle); | |
378 | 377 | } |
379 | 378 | total_snapshot_info.erase(ss); |
380 | 379 | } | ... | ... |
src/reprocessing_module/snapshot_reprocessing.h
src/util/vpc_util.cpp
... | ... | @@ -28,15 +28,6 @@ void VPCUtil::release() |
28 | 28 | ret = acldvppDestroyChannel(dvppChannelDesc_); |
29 | 29 | ret = acldvppDestroyChannelDesc(dvppChannelDesc_); |
30 | 30 | |
31 | - if (stream_ != nullptr) { | |
32 | - ret = aclrtDestroyStream(stream_); | |
33 | - if (ret != ACL_SUCCESS) { | |
34 | - LOG_ERROR("destroy stream failed"); | |
35 | - } | |
36 | - stream_ = nullptr; | |
37 | - } | |
38 | - LOG_INFO("end to destroy stream"); | |
39 | - | |
40 | 31 | if (context_ != nullptr) { |
41 | 32 | ret = aclrtDestroyContext(context_); |
42 | 33 | if (ret != ACL_SUCCESS) { |
... | ... | @@ -54,8 +45,17 @@ void VPCUtil::release() |
54 | 45 | } |
55 | 46 | |
56 | 47 | |
57 | -int VPCUtil::vpc_crop(acldvppPicDesc *input_pic_desc, video_object_info obj) | |
58 | -{ | |
48 | +vpc_img_info VPCUtil::crop(DeviceMemory *devMem, video_object_info obj) { | |
49 | + | |
50 | + acldvppPicDesc *vpcInputDesc_ = acldvppCreatePicDesc(); | |
51 | + acldvppSetPicDescData(vpcInputDesc_, devMem->getMem()); | |
52 | + acldvppSetPicDescFormat(vpcInputDesc_, PIXEL_FORMAT_YUV_SEMIPLANAR_420); | |
53 | + acldvppSetPicDescWidth(vpcInputDesc_, devMem->getWidth()); | |
54 | + acldvppSetPicDescHeight(vpcInputDesc_, devMem->getHeight()); | |
55 | + acldvppSetPicDescWidthStride(vpcInputDesc_, devMem->getWidthStride()); | |
56 | + acldvppSetPicDescHeightStride(vpcInputDesc_, devMem->getHeightStride()); | |
57 | + acldvppSetPicDescSize(vpcInputDesc_, devMem->getSize()); | |
58 | + | |
59 | 59 | const int orimodelInputWidth = obj.right - obj.left; // cur model shape is 224 * 224 |
60 | 60 | const int orimodelInputHeight = obj.bottom - obj.top; |
61 | 61 | const int modelInputLeft = obj.left; // cur model shape is 224 * 224 |
... | ... | @@ -87,22 +87,39 @@ int VPCUtil::vpc_crop(acldvppPicDesc *input_pic_desc, video_object_info obj) |
87 | 87 | acldvppSetPicDescHeightStride(vpcOutputDesc_, modelInputHeight); |
88 | 88 | acldvppSetPicDescSize(vpcOutputDesc_, vpcOutBufferSize_); |
89 | 89 | |
90 | - int ret = acldvppVpcCropAsync(dvppChannelDesc_, input_pic_desc, vpcOutputDesc_, cropArea_, stream_); | |
91 | - | |
90 | + aclrtStream stream_; | |
91 | + aclrtCreateStream(&stream_); | |
92 | + int ret = acldvppVpcCropAsync(dvppChannelDesc_, vpcInputDesc_, vpcOutputDesc_, cropArea_, stream_); | |
92 | 93 | ret = aclrtSynchronizeStream(stream_); |
93 | 94 | |
95 | + if (stream_ != nullptr) { | |
96 | + aclrtDestroyStream(stream_); | |
97 | + } | |
98 | + | |
99 | + acldvppDestroyPicDesc(vpcInputDesc_); | |
100 | + | |
94 | 101 | /* DestroycropResource */ |
95 | 102 | (void)acldvppDestroyRoiConfig(cropArea_); |
96 | 103 | cropArea_ = nullptr; |
97 | - (void)acldvppDestroyPicDesc(vpcOutputDesc_); | |
98 | - vpcOutputDesc_ = nullptr; | |
99 | 104 | |
100 | - if (vpcOutBufferDev_ != nullptr) { | |
101 | - (void)acldvppFree(vpcOutBufferDev_); | |
102 | - vpcOutBufferDev_ = nullptr; | |
103 | - } | |
105 | + vpc_img_info img_info ; | |
106 | + img_info.pic_desc = vpcOutputDesc_; | |
107 | + img_info.object_id = obj.object_id; | |
108 | + img_info.task_id = obj.task_id; //该物体属于的任务ID号 | |
109 | + img_info.task_frame_count = obj.task_frame_count; //该物体当前出现的帧号 | |
110 | + img_info.index = obj.index; //该物体所属类别的编号 | |
111 | + img_info.confidence = obj.confidence; //该物体的置信度 | |
112 | + | |
113 | + | |
114 | + // (void)acldvppDestroyPicDesc(vpcOutputDesc_); | |
115 | + // vpcOutputDesc_ = nullptr; | |
116 | + | |
117 | + // if (vpcOutBufferDev_ != nullptr) { | |
118 | + // (void)acldvppFree(vpcOutBufferDev_); | |
119 | + // vpcOutBufferDev_ = nullptr; | |
120 | + // } | |
104 | 121 | |
105 | - return 0; | |
122 | + return img_info; | |
106 | 123 | } |
107 | 124 | |
108 | 125 | int VPCUtil::init(int32_t devId){ |
... | ... | @@ -112,7 +129,6 @@ int VPCUtil::init(int32_t devId){ |
112 | 129 | /* 2.Run the management resource application, including Device, Context, Stream */ |
113 | 130 | aclrtSetDevice(deviceId_); |
114 | 131 | aclrtCreateContext(&context_, deviceId_); |
115 | - aclrtCreateStream(&stream_); | |
116 | 132 | |
117 | 133 | // channel 准备 |
118 | 134 | dvppChannelDesc_ = acldvppCreateChannelDesc(); |
... | ... | @@ -153,6 +169,10 @@ vector<vpc_img_info> VPCUtil::crop_batch(DeviceMemory *devMem, vector<video_obje |
153 | 169 | |
154 | 170 | // 输入 |
155 | 171 | acldvppBatchPicDesc *vpcInputBatchDesc_ = acldvppCreateBatchPicDesc(1); |
172 | + if (vpcInputBatchDesc_ == nullptr) { | |
173 | + LOG_ERROR("acldvppCreatePicDesc outBatchPicDesc failed"); | |
174 | + return vec_img_info; | |
175 | + } | |
156 | 176 | acldvppPicDesc *vpcInputDesc_ = acldvppGetPicDesc(vpcInputBatchDesc_, 0); |
157 | 177 | acldvppSetPicDescData(vpcInputDesc_, devMem->getMem()); |
158 | 178 | acldvppSetPicDescFormat(vpcInputDesc_, PIXEL_FORMAT_YUV_SEMIPLANAR_420); |
... | ... | @@ -166,6 +186,7 @@ vector<vpc_img_info> VPCUtil::crop_batch(DeviceMemory *devMem, vector<video_obje |
166 | 186 | acldvppBatchPicDesc *outputBatchPicDesc_ = acldvppCreateBatchPicDesc(outputBatchSize_); |
167 | 187 | if (outputBatchPicDesc_ == nullptr) { |
168 | 188 | LOG_ERROR("acldvppCreatePicDesc outBatchPicDesc failed"); |
189 | + (void)acldvppDestroyBatchPicDesc(vpcInputBatchDesc_); | |
169 | 190 | return vec_img_info; |
170 | 191 | } |
171 | 192 | vector<void *> vecOutPtr_; |
... | ... | @@ -216,10 +237,17 @@ vector<vpc_img_info> VPCUtil::crop_batch(DeviceMemory *devMem, vector<video_obje |
216 | 237 | (void)acldvppSetPicDescSize(vpcOutputDesc, vpcOutBufferSize_); |
217 | 238 | } |
218 | 239 | |
240 | + aclrtStream stream_; | |
241 | + aclrtCreateStream(&stream_); | |
242 | + | |
219 | 243 | uint32_t roiNums[] = { outputBatchSize_ }; |
220 | 244 | ret = acldvppVpcBatchCropAsync(dvppChannelDesc_, vpcInputBatchDesc_, roiNums, 1, outputBatchPicDesc_, cropAreas, stream_); |
221 | 245 | ret = aclrtSynchronizeStream(stream_); |
222 | 246 | |
247 | + if (stream_ != nullptr) { | |
248 | + aclrtDestroyStream(stream_); | |
249 | + } | |
250 | + | |
223 | 251 | for (uint32_t i = 0; i < outputBatchSize_; i++) { |
224 | 252 | video_object_info obj = objs[i]; |
225 | 253 | |
... | ... | @@ -281,7 +309,6 @@ vector<vpc_img_info> VPCUtil::crop_batch(DeviceMemory *devMem, vector<video_obje |
281 | 309 | // acldvppDestroyPicDesc(vec_img_info[i].pic_desc); |
282 | 310 | // } |
283 | 311 | // } |
284 | - | |
285 | 312 | |
286 | 313 | for (uint32_t i = 0; i < outputBatchSize_; i++) { |
287 | 314 | if (cropAreas[i] != nullptr) { |
... | ... | @@ -326,6 +353,12 @@ vpc_img_info VPCUtil::vpc_devMem2vpcImg(DeviceMemory *devMem){ |
326 | 353 | return img_info; |
327 | 354 | } |
328 | 355 | |
356 | +void VPCUtil::vpc_pic_desc_release(acldvppPicDesc* pic_desc){ | |
357 | + void *outputDataDev = acldvppGetPicDescData(pic_desc); | |
358 | + acldvppFree(outputDataDev); | |
359 | + acldvppDestroyPicDesc(pic_desc); | |
360 | +} | |
361 | + | |
329 | 362 | void VPCUtil::vpc_img_release(vpc_img_info img_info){ |
330 | 363 | if(img_info.pic_desc != nullptr){ |
331 | 364 | void *outputDataDev = acldvppGetPicDescData(img_info.pic_desc); | ... | ... |
src/util/vpc_util.h
... | ... | @@ -25,24 +25,39 @@ class DeviceMemory; |
25 | 25 | class VPCUtil { |
26 | 26 | |
27 | 27 | public: |
28 | - int vpc_crop(acldvppPicDesc *input_pic_desc, video_object_info obj); | |
28 | + static VPCUtil* getInstance(){ | |
29 | + static VPCUtil* singleton = nullptr; | |
30 | + if (singleton == nullptr){ | |
31 | + singleton = new VPCUtil(); | |
32 | + } | |
33 | + return singleton; | |
34 | + } | |
29 | 35 | |
30 | - int init(int32_t devId); | |
36 | + ~VPCUtil() | |
37 | + { | |
38 | + release(); | |
39 | + } | |
31 | 40 | |
32 | - vector<vpc_img_info> crop_batch(DeviceMemory *devMem, vector<video_object_info> objs); | |
41 | + static void vpc_pic_desc_release(acldvppPicDesc* ); | |
33 | 42 | |
34 | - void vpc_img_release(vpc_img_info ); | |
43 | + static void vpc_img_release(vpc_img_info ); | |
35 | 44 | |
36 | - void vpc_imgList_release(vector<vpc_img_info>& ); | |
45 | + static void vpc_imgList_release(vector<vpc_img_info>& ); | |
37 | 46 | |
38 | - void release(); | |
47 | + static vpc_img_info vpc_devMem2vpcImg(DeviceMemory *devMem); | |
48 | + | |
49 | +public: | |
50 | + vpc_img_info crop(DeviceMemory *devMem, video_object_info obj); | |
39 | 51 | |
40 | - vpc_img_info vpc_devMem2vpcImg(DeviceMemory *devMem); | |
52 | + int init(int32_t devId); | |
53 | + | |
54 | + vector<vpc_img_info> crop_batch(DeviceMemory *devMem, vector<video_object_info> objs); | |
55 | + | |
56 | + void release(); | |
41 | 57 | |
42 | 58 | private: |
43 | 59 | int32_t deviceId_; |
44 | 60 | aclrtContext context_; |
45 | - aclrtStream stream_; | |
46 | 61 | |
47 | 62 | acldvppChannelDesc *dvppChannelDesc_; |
48 | 63 | }; | ... | ... |