Commit 7cf9e4fe762e0cbd4a94dd3b8f17f6ad722eb9a0

Authored by Hu Chunming
1 parent 35fac12d

人员区域离开、人员逃散、车辆区域离开

src/ai_engine_module/RegionLeave.cpp 0 → 100644
  1 +#include "./RegionLeave.h"
  2 +#include "opencv2/highgui.hpp"
  3 +#include "opencv2/imgproc.hpp"
  4 +#include "opencv2/opencv.hpp"
  5 +#include <cmath>
  6 +
  7 +#include "../helpers/gen_json.hpp"
  8 +#include "../ai_platform/mvpt_process_assist.h"
  9 +
  10 +
  11 +
  12 +std::set<det_class_label_t> algor_type_to_det_label_set(const algorithm_type_t &algor_type) {
  13 + if (algorithm_type_t::HUMAN_LEAVE_REGION == algor_type || algorithm_type_t::HUMAN_REGION_DISMISS == algor_type
  14 + || algorithm_type_t::HUMAN_REGION_FAST_MOVING == algor_type) {
  15 + return {det_class_label_t::HUMAN};
  16 + } else if (algorithm_type_t::VEHICLE_LEAVE_REGION == algor_type) {
  17 + return {
  18 + det_class_label_t::LARGE_CAR, det_class_label_t::MEDIUM_BUS, det_class_label_t::SMALL_CAR,
  19 + det_class_label_t::TRUCK, det_class_label_t::TRACTOR,
  20 + };
  21 + } else {
  22 + return {};
  23 + }
  24 +}
  25 +
  26 +/* 是否是有效目标框的辅助判断函数 */
  27 +bool check_obj_cls(const int &cls, const algorithm_type_t &algor_type) {
  28 + return algor_type_to_det_label_set(algor_type).count(static_cast<det_class_label_t>(cls));
  29 +}
  30 +
  31 +RegionLeave::RegionLeave(){
  32 + m_task_param_manager = task_param_manager::getInstance();
  33 +}
  34 +
  35 +RegionLeave::~RegionLeave()
  36 +{
  37 +
  38 +}
  39 +void RegionLeave::init(int devId, algorithm_type_t eType){
  40 +
  41 + m_devId = devId;
  42 + m_eType = eType;
  43 +
  44 + m_save_util = new save_snapshot_reprocessing(m_devId);
  45 +}
  46 +
  47 +#ifdef POST_USE_RABBITMQ
  48 +void RegionLeave::set_callback(callback_t cb) {
  49 + m_save_util->set_callback(cb);
  50 +}
  51 +#endif
  52 +
  53 +/* 根据用户输入的点 初始化禁区区域mask */
  54 +bool RegionLeave::add_task(const string &task_id, const int width, const int height) {
  55 +
  56 + auto &&params_ptr = m_task_param_manager->get_task_other_param(task_id, m_eType);
  57 + if (!params_ptr)
  58 + {
  59 + LOG_ERROR("{} is nullptr when get algor param from task_param", task_id);
  60 + return false;
  61 + }
  62 +
  63 + if (params_ptr->algor_param == nullptr)
  64 + return false;
  65 +
  66 + auto *algor_params_ptr = (algor_config_param_trespass_basic *)(params_ptr->algor_param);
  67 + if (algor_params_ptr == nullptr)
  68 + {
  69 + return false;
  70 + }
  71 +
  72 + cv::Mat src(height, width, CV_8UC3);
  73 + src.setTo(0);
  74 +
  75 + std::vector<cv::Point> contour;
  76 + for (int idx = 0; idx < algor_params_ptr->points_count; idx++) {
  77 + contour.emplace_back(algor_params_ptr->points[idx].x_, algor_params_ptr->points[idx].y_);
  78 + }
  79 +
  80 + if(contour.size() <= 0){
  81 + return false;
  82 + }
  83 +
  84 + std::vector<std::vector<cv::Point>> contours;
  85 + contours.push_back(contour);
  86 +
  87 + cv::polylines(src, contours, true, cv::Scalar(255, 255, 255), 2, 8); // 第2个参数可以采用contour或者contours,均可
  88 + cv::fillPoly(src, contours, cv::Scalar(255, 255, 255)); // fillPoly函数的第二个参数是二维数组
  89 +
  90 + cv::Mat &dst_mat = region_map[task_id];
  91 + cv::cvtColor(src, region_map[task_id], cv::COLOR_BGR2GRAY);
  92 + cv::threshold(region_map[task_id], region_map[task_id], 100, 255, cv::THRESH_BINARY);
  93 +
  94 + return true;
  95 +}
  96 +
  97 +/* 目标在禁区内外的辅助判断函数 */
  98 +bool RegionLeave::in_rect_analysis(string task_id, const box_t &cur_bos) {
  99 + int center_x = int((cur_bos.left + cur_bos.right) / 2.0);
  100 + int center_y = int((cur_bos.top + cur_bos.bottom) / 2.0);
  101 +
  102 + cv::Mat &dst_mat = region_map[task_id];
  103 + if (dst_mat.data[center_y * dst_mat.cols + center_x] && dst_mat.data[center_y * dst_mat.cols + center_x + 1] &&
  104 + dst_mat.data[center_y * dst_mat.cols + center_x - 1] && dst_mat.data[(center_y + 1) * dst_mat.cols + center_x] &&
  105 + dst_mat.data[(center_y - 1) * dst_mat.cols + center_x]) {
  106 + return true; // 进入禁区
  107 + } else {
  108 + return false; // 未进入禁区
  109 + }
  110 +}
  111 +
  112 +bool RegionLeave::is_valid_box(string task_id, const box_t &box, const algorithm_type_t &algor_type) {
  113 + auto &&params_ptr = m_task_param_manager->get_task_other_param(task_id, algor_type);
  114 + if (!params_ptr)
  115 + {
  116 + LOG_ERROR("{} is nullptr when get algor param from task_param", task_id);
  117 + return false;
  118 + }
  119 +
  120 + if (params_ptr->basic_param == nullptr)
  121 + return false;
  122 +
  123 + if (!snapshot_legal_inarea(params_ptr->basic_param->algor_valid_rect, box.left, box.top, box.right, box.bottom))
  124 + return false;
  125 +
  126 + if (params_ptr->algor_param == nullptr)
  127 + return false;
  128 +
  129 + auto *algor_params_ptr = (algor_config_param_trespass_basic *)(params_ptr->algor_param);
  130 +
  131 + if (box.width() == 0 || box.height() == 0)
  132 + return false;
  133 +
  134 + if (box.score < algor_params_ptr->conf_threshold || box.width() < algor_params_ptr->minmum_width ||
  135 + box.height() < algor_params_ptr->minmum_height)
  136 + return false;
  137 +
  138 + return check_obj_cls(box.cls, algor_type);
  139 +}
  140 +
  141 +/* 非法闯入禁区的 算法判断函数 */
  142 +void RegionLeave::process(std::vector<DeviceMemory*>& vec_gpuMem, const std::vector<onelevel_det_result> &det_results, const vector<vector<int>> &delete_objs)
  143 +{
  144 + if (det_results.size() <= 0) {
  145 + return ;
  146 + }
  147 +
  148 + for (int i = 0; i < det_results.size(); i++){
  149 + DeviceMemory* gpuMem = vec_gpuMem[i];
  150 + string task_id = gpuMem->getId();
  151 +
  152 + // 删除 已经删除的目标
  153 + for (auto obj_idx : delete_objs[i]) {
  154 + OBJ_KEY obj_key{task_id, obj_idx};
  155 +
  156 + if (obj_to_position_.find(obj_key) != obj_to_position_.end()) {
  157 + obj_to_position_.erase(obj_key);
  158 + }
  159 + }
  160 +
  161 + auto it = region_map.find(task_id);
  162 + if (it == region_map.end()) {
  163 + continue;
  164 + }
  165 +
  166 + auto &&params_ptr = m_task_param_manager->get_task_other_param(task_id, m_eType);
  167 + if (!params_ptr && !params_ptr->basic_param)
  168 + {
  169 + LOG_ERROR("{} is nullptr when get algor param from task_param", task_id);
  170 + continue;
  171 + }
  172 +
  173 + bool b_src_saved = false;
  174 +
  175 + string sep = "/";
  176 +
  177 + auto& basic_param = params_ptr->basic_param;
  178 + std::string cur_src_ts = std::to_string(helpers::timer::get_timestamp<std::chrono::milliseconds>());
  179 + std::string origin_file_path = basic_param->result_folder + sep + task_id + "_origin_" + cur_src_ts + ".jpg";
  180 +
  181 + /* 依次判断检测目标框 是否有非法闯入 判断逻辑:之前帧在禁区外 当前帧进入禁区 */
  182 + auto& one_result = det_results[i];
  183 + std::vector<box_t> boxes;
  184 + for (unsigned c = 0; c < one_result.obj_count; ++c) {
  185 +
  186 + auto obj_c = one_result.obj[c];
  187 +
  188 + box_t unique_box;
  189 + unique_box.id = obj_c.id;
  190 + unique_box.cls = obj_c.index;
  191 + unique_box.top = obj_c.top;
  192 + unique_box.left = obj_c.left;
  193 + unique_box.right = obj_c.right;
  194 + unique_box.bottom = obj_c.bottom;
  195 + unique_box.score = obj_c.confidence;
  196 +
  197 + OBJ_KEY obj_key{task_id, obj_c.id};
  198 +
  199 + if (!is_valid_box(task_id, unique_box, m_eType)){
  200 + obj_to_position_.erase(obj_key); // 如果不满足条件 非 合法框 依然删除
  201 + }
  202 +
  203 + //! add or update.
  204 + if (in_rect_analysis(task_id, unique_box)) {
  205 + // 禁区内
  206 + // 新加
  207 + obj_to_position_[obj_key] = unique_box;
  208 + } else {
  209 + if (obj_to_position_.find(obj_key) != obj_to_position_.end()) // 之前在禁区内,可报警
  210 + {
  211 + box_t box;
  212 + box.left = obj_c.left;
  213 + box.right = obj_c.right;
  214 + box.top = obj_c.top;
  215 + box.bottom = obj_c.bottom;
  216 + box.score = obj_c.confidence;
  217 + boxes.push_back(box);
  218 +
  219 + // 报完警清除记录
  220 + obj_to_position_.erase(obj_key);
  221 + }
  222 + }
  223 + }
  224 +
  225 + if (boxes.size() <= 0)
  226 + {
  227 + continue;
  228 + }
  229 +
  230 + int algorithm_type = (int)m_eType;
  231 + string json_str = helpers::gen_json::gen_boxes_json(task_id, algorithm_type, boxes, origin_file_path);
  232 +
  233 + ImgSaveInfo info_origin;
  234 + info_origin.img_info = VPCUtil::vpc_devMem2vpcImg(gpuMem);
  235 + info_origin.file_path = origin_file_path;
  236 + info_origin.json_str = json_str;
  237 + m_save_util->reprocessing_process_wo_locus_async(info_origin);
  238 + }
  239 +}
  240 +
  241 +void RegionLeave::release_task(string task_id){
  242 + auto it = region_map.find(task_id);
  243 + if (it != region_map.end())
  244 + {
  245 + region_map.erase(it);
  246 + }
  247 +}
  248 +
  249 +
  250 +
... ...
src/ai_engine_module/RegionLeave.h 0 → 100644
  1 +#ifndef __REGION_LEAVE_H__
  2 +#define __REGION_LEAVE_H__
  3 +
  4 +#include <deque>
  5 +#include <map>
  6 +#include <vector>
  7 +
  8 +#include "opencv2/highgui/highgui.hpp"
  9 +
  10 +#include "ai_engine_header.h"
  11 +#include "../ai_platform/task_param_manager.h"
  12 +#include "../decoder/interface/DeviceMemory.hpp"
  13 +#include "../reprocessing_module/save_snapshot_reprocessing.h"
  14 +
  15 +
  16 +class RegionLeave {
  17 +public:
  18 + RegionLeave();
  19 + ~RegionLeave();
  20 +
  21 + void init(int devId, algorithm_type_t eType);
  22 +
  23 + bool add_task(const string &task_id, const int width, const int height);
  24 +
  25 + void process(std::vector<DeviceMemory*>& vec_gpuMem, const std::vector<onelevel_det_result> &det_result, const vector<vector<int>> &delete_objs);
  26 +
  27 + void release_task(string task_id);
  28 +
  29 +#ifdef POST_USE_RABBITMQ
  30 + typedef std::function<bool(const char *msg)> callback_t;
  31 + void set_callback(callback_t cb);
  32 +#endif
  33 +
  34 +private:
  35 + bool in_rect_analysis(string task_id, const box_t &cur_bos);
  36 +
  37 + bool is_valid_box(string task_id, const box_t &box, const algorithm_type_t &algor_type);
  38 +
  39 +private:
  40 + task_param_manager *m_task_param_manager{nullptr};
  41 + std::map<OBJ_KEY, box_t> obj_to_position_; // 保存物体上一帧的位置,基于非法闯入判断逻辑,上一帧在框外,下一帧闯入禁区
  42 + std::map<std::string, cv::Mat> region_map;
  43 +
  44 + int m_devId{0};
  45 + algorithm_type_t m_eType;
  46 +
  47 + save_snapshot_reprocessing *m_save_util{nullptr};
  48 +};
  49 +
  50 +
  51 +#endif // __REGION_LEAVE_H__
0 52 \ No newline at end of file
... ...
src/ai_engine_module/ai_engine_module.h
... ... @@ -13,4 +13,5 @@
13 13 #include "./traffic_light_process.h"
14 14 #include "./road_seg_statistics.h"
15 15 #include "./road_seg_3cls_statistics.h"
16   -#include "./road_seg_correlation_algor.h"
17 16 \ No newline at end of file
  17 +#include "./road_seg_correlation_algor.h"
  18 +#include "./RegionLeave.h"
18 19 \ No newline at end of file
... ...
src/ai_platform/MultiSourceProcess.cpp
... ... @@ -225,6 +225,10 @@ int CMultiSourceProcess::InitAlgorthim(tsl_aiplatform_param vptParam){
225 225 return -1;
226 226 }
227 227  
  228 + m_algorthim_region_leave.init(vptParam.gpuid, algorithm_type_t::HUMAN_LEAVE_REGION);
  229 + m_algorthim_region_dismiss.init(vptParam.gpuid, algorithm_type_t::HUMAN_REGION_DISMISS);
  230 + m_algorthim_region_fastmoving.init(vptParam.gpuid, algorithm_type_t::HUMAN_REGION_FAST_MOVING);
  231 +
228 232 m_task_param_manager = task_param_manager::getInstance();
229 233  
230 234 m_snapshot_reprocessing = new snapshot_reprocessing(m_devId);
... ... @@ -290,11 +294,23 @@ int CMultiSourceProcess::AddMqConn(mq_type_t mq_type, rabbitmq_conn_params_t mq_
290 294  
291 295 LOG_INFO("为报警类 绑定MQ回调");
292 296 /* 为报警类 绑定回调 传入mq_manager_.publish 内部直接调用*/
293   - if (m_save_snapshot_reprocessing!= nullptr && mq_type_t::ALARM_MQ == mq_type) {
294   - m_save_snapshot_reprocessing->set_callback(
295   - std::bind(&mq::Manager::publish, mq_manager_, mq_type, std::placeholders::_1, true));
296   - LOG_INFO("为报警类 绑定MQ回调 成功!");
  297 + if( mq_type_t::ALARM_MQ == mq_type){
  298 + if (m_save_snapshot_reprocessing!= nullptr) {
  299 + m_save_snapshot_reprocessing->set_callback(
  300 + std::bind(&mq::Manager::publish, mq_manager_, mq_type, std::placeholders::_1, true));
  301 + LOG_INFO("为报警类 绑定MQ回调 成功!");
  302 + }
  303 +
  304 + m_algorthim_region_leave.set_callback(
  305 + std::bind(&mq::Manager::publish, mq_manager_, mq_type, std::placeholders::_1, true));
  306 +
  307 + m_algorthim_region_dismiss.set_callback(
  308 + std::bind(&mq::Manager::publish, mq_manager_, mq_type, std::placeholders::_1, true));
  309 +
  310 + m_algorthim_region_fastmoving.set_callback(
  311 + std::bind(&mq::Manager::publish, mq_manager_, mq_type, std::placeholders::_1, true));
297 312 }
  313 +
298 314  
299 315 LOG_INFO("初始化MQ队列成功!");
300 316  
... ... @@ -385,6 +401,9 @@ bool CMultiSourceProcess::AddTask(task_param _cur_task_param){
385 401  
386 402 // pDecManager->setDecKeyframe(config.name, true); // 只对关键帧解码
387 403  
  404 + int input_image_width = 0;
  405 + int input_image_height = 0;
  406 + pDecManager->getResolution(config.name, input_image_width, input_image_height);
388 407  
389 408 // 保存新添加任务的配置参数
390 409 m_task_param_manager->add_task_param(task_id, _cur_task_param);
... ... @@ -407,12 +426,17 @@ bool CMultiSourceProcess::AddTask(task_param _cur_task_param){
407 426 if (m_task_param_manager->task_has_vpt_algor(task_id))
408 427 vpt_process.addTaskTracker(task_id, 1, 1, skip_frame_);
409 428  
410   - // 人脸跟踪
411 429 #ifdef WITH_FACE_DET_SS
  430 + // 人脸跟踪
412 431 if (m_task_param_manager->task_has_face_algor(task_id))
413 432 m_face_det_ai_engine.add_tracker(task_id, skip_frame_); // 跳帧数暂时写死
414 433 #endif
415 434  
  435 + // 必须在 add_task_param 之后 todo 这里需要用参数过滤是否初始化
  436 + m_algorthim_region_leave.add_task(task_id, input_image_width, input_image_height);
  437 + m_algorthim_region_dismiss.add_task(task_id, input_image_width, input_image_height);
  438 + m_algorthim_region_fastmoving.add_task(task_id, input_image_width, input_image_height);
  439 +
416 440 m_FinishedTaskMtx.lock();
417 441 m_FinishedTaskMap[task_id] = false;
418 442 m_FinishedTaskMtx.unlock();
... ... @@ -664,6 +688,11 @@ bool CMultiSourceProcess::finish_task(const string taskID, const bool delete_sna
664 688 // #ifdef WITH_SECOND_PROCESS
665 689 pedestrian_vehicle_retrograde_.force_release_result(taskID); //221024 byzsh
666 690 // #endif
  691 +
  692 + m_algorthim_region_leave.release_task(taskID);
  693 + m_algorthim_region_dismiss.release_task(taskID);
  694 + m_algorthim_region_fastmoving.release_task(taskID);
  695 +
667 696 #ifdef USE_VILLAGE
668 697 tricycle_manned_.force_release_result(taskID);
669 698 truck_manned_.force_release_result(taskID);
... ... @@ -925,8 +954,10 @@ int CMultiSourceProcess::algorthim_vpt(vector&lt;DeviceMemory*&gt; vec_gpuMem){
925 954 algorthim_trespass(vpt_interest_task_id, vec_vptMem, vptResult, deleteObjectID);
926 955 trespass_snapshot(vpt_interest_task_id, deleteObjectID);
927 956  
928   -// #endif
929   -#ifdef USE_VILLAGE
  957 + m_algorthim_region_leave.process(vec_vptMem, vptResult, deleteObjectID);
  958 + m_algorthim_region_dismiss.process(vec_vptMem, vptResult, deleteObjectID);
  959 + m_algorthim_region_fastmoving.process(vec_vptMem, vptResult, deleteObjectID);
  960 +
930 961 cross_line_process(vec_vptMem, vptResult, algorithm_type_t::HUMAN_CROSSING_LINE);
931 962 cross_line_process(vec_vptMem, vptResult, algorithm_type_t::HUMAN_CLIMB);
932 963 cross_line_process(vec_vptMem, vptResult, algorithm_type_t::VEHICLE_ILLEGAL_CROSSING_LINE);
... ... @@ -935,6 +966,9 @@ int CMultiSourceProcess::algorthim_vpt(vector&lt;DeviceMemory*&gt; vec_gpuMem){
935 966 wander_detect(vec_vptMem, vptResult, algorithm_type_t::VEHICLE_ILLEGAL_PARKING);
936 967 // 轨迹记录
937 968 trace_record(vec_vptMem, vptResult);
  969 +
  970 +// #endif
  971 +#ifdef USE_VILLAGE
938 972 // 农村违法分析的快照缓存
939 973 m_snapshot_reprocessing->update_village_bestsnapshot(vec_vptMem, vptResult, deleteObjectID);
940 974 // 三轮车载人
... ...
src/ai_platform/MultiSourceProcess.h
... ... @@ -180,6 +180,10 @@ private:
180 180  
181 181 face_det_ai_engine m_face_det_ai_engine; // 人脸检测
182 182  
  183 + RegionLeave m_algorthim_region_leave;
  184 + RegionLeave m_algorthim_region_dismiss;
  185 + RegionLeave m_algorthim_region_fastmoving;
  186 +
183 187 deque<RecoderInfo> m_recoderinfo_queue;
184 188 mutex m_recoderinfo_queue_mtx;
185 189 thread* m_recode_thread {nullptr};
... ...
src/ai_platform/header.h
... ... @@ -35,8 +35,11 @@ enum class algorithm_type_t {
35 35 ROAD_WORK_DET = 212, // 221026byzsh施工占道
36 36  
37 37 HUMAN_LINGER = 214, // 人员徘徊
  38 + HUMAN_REGION_DISMISS = 216, // 人员逃散
  39 + HUMAN_REGION_FAST_MOVING = 217, // 人员快速移动
38 40 HUMAN_CLIMB = 220, // 人员攀爬
39 41 HUMAN_CROSSING_LINE = 221, // 人员越线
  42 + HUMAN_LEAVE_REGION = 222, // 区域离开
40 43  
41 44 VEHICLE_SNAPSHOT = 301,
42 45 VEHICLE_RETROGRADE = 310,
... ... @@ -44,6 +47,7 @@ enum class algorithm_type_t {
44 47 VEHICLE_GATHER = 312, // 车辆聚集
45 48 VEHICLE_ILLEGAL_PARKING = 313, // 车辆违停
46 49 VEHICLE_ILLEGAL_CROSSING_LINE = 314, // 车辆压线
  50 + VEHICLE_LEAVE_REGION = 315, // 区域离开
47 51  
48 52 NONMOTOR_VEHICLE_SNAPSHOT = 401,
49 53 TAKEAWAY_MEMBER_CLASSIFICATION = 402,
... ...
src/ai_platform/mvpt_process_assist.h
... ... @@ -25,17 +25,15 @@ using namespace std;
25 25  
26 26 int CreateDir(char *pszDir);
27 27 void CreateResultFolder(char* resultFolder, const char* jointFolder);
28   -//bool sy_legal_pos(bitset<EDGESIZE> flags, int left, int top, int right, int bottom, int imgHeight, int imgWidth);
  28 +
29 29 bool LegalArea(int maxArea, int lastArea, int left, int top, int right, int bottom);
30 30 bool LegalMinArea(int width, int height, sy_rect min_box);
31   -void ExpandMargin(int direction_x, int direction_y, int boundary_w, int boundary_h,
32   - int &boundary_left, int &boundary_right, int &boundary_top, int &boundary_bottom);
33   -void CreateResultFolder(char* resultFolder, const char* jointFolder);
  31 +void ExpandMargin(int direction_x, int direction_y, int boundary_w, int boundary_h, int &boundary_left, int &boundary_right, int &boundary_top, int &boundary_bottom);
34 32  
35 33 bool snapshot_legal_inarea(int width, int height);
36 34 bool snapshot_legal_inarea(sy_rect algor_area, int left, int top, int right, int bottom);
37 35 bool snapshot_legal_minarea(int index, int width, int height);
38   -// bool snapshot_algor_open_config(const OBJ_KEY& obj_key);
  36 +
39 37 bool snapshot_legal_pos(bitset<EDGESIZE> flags, int left, int top, int right, int bottom, int image_width, int image_height);
40 38 bool snapshot_legal_area(int max_area, int last_area, int left, int top, int right, int bottom);
41 39 bool snapshot_legal_pose(float last_roll, float last_yaw, float last_pitch, float roll, float yaw, float pitch); // added by zsh 220719 判断人脸姿态角
... ...