Commit 8072fc32ce5a3bc0e500627e75212d9d0b962716

Authored by Hu Chunming
1 parent fdfc223e

代码同步初步完成,人脸检测模型还不兼容

src/ai_engine_module/GatherDetect.cpp 0 → 100644
  1 +/*
  2 + * @Author: yangzilong
  3 + * @Date: 2021-12-16 14:25:13
  4 + * @Last Modified by: yangzilong
  5 + * @Email: yangzilong@objecteye.com
  6 + * @Description:
  7 + */
  8 +#include "GatherDetect.h"
  9 +#include "../helpers/img_util.h"
  10 +
  11 +GatherDetect::GatherDetect()
  12 +{
  13 + m_task_param_manager = task_param_manager::getInstance();
  14 +}
  15 +
  16 +void GatherDetect::init(algorithm_type_t eType)
  17 +{
  18 + m_eType = eType;
  19 +}
  20 +
  21 +std::vector<GatherResult> GatherDetect::process(vector<DeviceMemory*> vec_vptMem, vector<onelevel_det_result> &ol_det_result) {
  22 + std::vector<GatherResult> results;
  23 +
  24 + map<string, algor_open_config_param> && algor_config_param = m_task_param_manager->get_task_algor_params();
  25 + map<string, map<algo_type, task_param_manager::algo_param_type_t_*>> && algor_param = m_task_param_manager->get_task_other_params();
  26 +
  27 + for (size_t idx = 0; idx < vec_vptMem.size(); idx++)
  28 + {
  29 + DeviceMemory* cur_vptMem = vec_vptMem[idx];
  30 + string task_id = cur_vptMem->getId();
  31 +
  32 + auto it_algor = algor_param.find(task_id);
  33 + if (it_algor == algor_param.end()) {
  34 + continue;
  35 + }
  36 +
  37 + task_param_manager::algo_param_type_t_* cur_task_params = algor_param[task_id][m_eType];
  38 + if (nullptr == cur_task_params) {
  39 + continue;
  40 + }
  41 +
  42 + algor_basic_config_param_t* basic_param = (algor_basic_config_param_t*)cur_task_params->basic_param;
  43 + if (basic_param == nullptr || basic_param->adapt_param == nullptr) {
  44 + continue;
  45 + }
  46 + universal_algor_adapt_param *adapt_param = basic_param->adapt_param;
  47 +
  48 + map<string, std::vector<box_t>> taskid_to_boxes;
  49 +
  50 + onelevel_det_result &cur_task_ol_detres = ol_det_result[idx];
  51 + for (int c = 0; c < cur_task_ol_detres.obj_count; c++)
  52 + {
  53 + auto& obj_c = cur_task_ol_detres.obj[c];
  54 +
  55 + bool bHuman = m_eType == algorithm_type_t::HUMAN_GATHER || m_eType == algorithm_type_t::HUMAN_DENSITY || m_eType == algorithm_type_t::HUMAN_REGION_GATHER;
  56 +
  57 + bool bCount = false;
  58 + if(bHuman && obj_c.index == (int)det_class_label_t::HUMAN) {
  59 + bCount = true;
  60 + } else if (m_eType == algorithm_type_t::VEHICLE_GATHER && obj_c.index >= 4 && obj_c.index <= 8) {
  61 + bCount = true;
  62 + }
  63 +
  64 + sy_point center;
  65 + center.x_ = (obj_c.right + obj_c.left)/ 2 ;
  66 + center.y_ = (obj_c.bottom + obj_c.top) / 2;
  67 + // vec_pt.push_back(center);
  68 + if (bCount && common::isInPolygon(adapt_param->points, adapt_param->points_count, center)) {
  69 + box_t box;
  70 + box.top = obj_c.top;
  71 + box.left = obj_c.left;
  72 + box.right = obj_c.right;
  73 + box.bottom = obj_c.bottom;
  74 + box.score = obj_c.confidence;
  75 + taskid_to_boxes[task_id].emplace_back(std::move(box));
  76 + }
  77 + }
  78 +
  79 + int count_threshold = ((algor_config_param_human_gather*)cur_task_params->algor_param)->human_count_threshold;
  80 + int frame_stride = ((algor_config_param_human_gather*)cur_task_params->algor_param)->frame_stride;
  81 +
  82 + if (taskid_to_boxes[task_id].size() > count_threshold && cur_vptMem->getFrameNb() % frame_stride == 0)
  83 + {
  84 + GatherResult data;
  85 + data.origin_img = VPCUtil::vpc_devMem2vpcImg(vec_vptMem[idx]);
  86 + data.task_id = task_id;
  87 + data.boxes = std::move(taskid_to_boxes[task_id]);
  88 + data.id = gid_++;
  89 + results.emplace_back(std::move(data));
  90 + }
  91 + }
  92 +
  93 + return results;
  94 +}
0 \ No newline at end of file 95 \ No newline at end of file
src/ai_engine_module/GatherDetect.h 0 → 100644
  1 +/*
  2 + * @Author: yangzilong
  3 + * @Date: 2021-12-10 15:48:49
  4 + * @Last Modified by: yangzilong
  5 + * @Last Modified time: Do not edit
  6 + * @Email: yangzilong@objecteye.com
  7 + * @Description:
  8 + */
  9 +#pragma once
  10 +
  11 +#include <set>
  12 +#include <string>
  13 +#include <vector>
  14 +#include "../ai_platform/task_param_manager.h"
  15 +#include "./ai_engine_header.h"
  16 +#include "../decoder/interface/DeviceMemory.hpp"
  17 +
  18 +struct GatherResult
  19 +{
  20 + long long id;
  21 + vpc_img_info origin_img;
  22 + std::vector<box_t> boxes;
  23 + std::string task_id;
  24 +} ;
  25 +
  26 +class GatherDetect
  27 +{
  28 +public:
  29 + GatherDetect();
  30 +
  31 + void init(algorithm_type_t eType);
  32 +
  33 + std::vector<GatherResult> process(vector<DeviceMemory*> vec_vptMem, vector<onelevel_det_result> &ol_det_result);
  34 +
  35 +private:
  36 + task_param_manager *m_task_param_manager{nullptr};
  37 + long long gid_{0};
  38 +
  39 + algorithm_type_t m_eType{algorithm_type_t::UNKNOWN};
  40 +};
0 \ No newline at end of file 41 \ No newline at end of file
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 "../helpers/img_util.h"
  9 +
  10 +
  11 +namespace ai_engine_module {
  12 +
  13 +std::set<det_class_label_t> algor_type_to_det_label_set(const algorithm_type_t &algor_type) {
  14 + if (algorithm_type_t::HUMAN_LEAVE_REGION == algor_type || algorithm_type_t::HUMAN_REGION_DISMISS == algor_type
  15 + || algorithm_type_t::HUMAN_REGION_FAST_MOVING == algor_type) {
  16 + return {det_class_label_t::HUMAN};
  17 + } else if (algorithm_type_t::VEHICLE_LEAVE_REGION == algor_type) {
  18 + return {
  19 + det_class_label_t::LARGE_CAR, det_class_label_t::MEDIUM_BUS, det_class_label_t::SMALL_CAR,
  20 + det_class_label_t::TRUCK, det_class_label_t::TRACTOR,
  21 + };
  22 + } else {
  23 + return {};
  24 + }
  25 +}
  26 +
  27 +/* 是否是有效目标框的辅助判断函数 */
  28 +bool check_obj_cls(const int &cls, const algorithm_type_t &algor_type) {
  29 + return algor_type_to_det_label_set(algor_type).count(static_cast<det_class_label_t>(cls));
  30 +}
  31 +
  32 +RegionLeave::RegionLeave(){
  33 + m_task_param_manager = task_param_manager::getInstance();
  34 +}
  35 +
  36 +RegionLeave::~RegionLeave()
  37 +{
  38 + if (m_save_util)
  39 + {
  40 + delete m_save_util;
  41 + m_save_util = nullptr;
  42 + }
  43 +
  44 +}
  45 +void RegionLeave::init(int devId, algorithm_type_t eType){
  46 +
  47 + m_devId = devId;
  48 + m_eType = eType;
  49 +
  50 + m_save_util = new save_snapshot_reprocessing(m_devId);
  51 +}
  52 +
  53 +#ifdef POST_USE_RABBITMQ
  54 +void RegionLeave::set_callback(callback_t cb) {
  55 + m_save_util->set_callback(cb);
  56 +}
  57 +#endif
  58 +
  59 +bool RegionLeave::is_valid_box(string task_id, const box_t &box, const algorithm_type_t &algor_type) {
  60 + auto &&params_ptr = m_task_param_manager->get_task_other_param(task_id, algor_type);
  61 + if (!params_ptr)
  62 + {
  63 + LOG_ERROR("{} is nullptr when get algor param from task_param", task_id);
  64 + return false;
  65 + }
  66 +
  67 + if (params_ptr->basic_param == nullptr)
  68 + return false;
  69 +
  70 + if (params_ptr->algor_param == nullptr)
  71 + return false;
  72 +
  73 + auto *algor_params_ptr = (algor_config_param_trespass_basic *)(params_ptr->algor_param);
  74 +
  75 + if (box.width() == 0 || box.height() == 0)
  76 + return false;
  77 +
  78 + if (box.score < algor_params_ptr->conf_threshold || box.width() < algor_params_ptr->minmum_width ||
  79 + box.height() < algor_params_ptr->minmum_height)
  80 + return false;
  81 +
  82 + return check_obj_cls(box.cls, algor_type);
  83 +}
  84 +
  85 +/* 非法闯入禁区的 算法判断函数 */
  86 +void RegionLeave::process(std::vector<DeviceMemory*>& vec_gpuMem, const std::vector<onelevel_det_result> &det_results, const vector<vector<int>> &delete_objs)
  87 +{
  88 + if (det_results.size() <= 0) {
  89 + return ;
  90 + }
  91 +
  92 + for (int i = 0; i < det_results.size(); i++){
  93 + DeviceMemory* gpuMem = vec_gpuMem[i];
  94 + string task_id = gpuMem->getId();
  95 +
  96 + // 删除 已经删除的目标
  97 + for (auto obj_idx : delete_objs[i]) {
  98 + OBJ_KEY obj_key{task_id, obj_idx};
  99 +
  100 + if (obj_to_position_.find(obj_key) != obj_to_position_.end()) {
  101 + obj_to_position_.erase(obj_key);
  102 + }
  103 + }
  104 +
  105 + auto &&params_ptr = m_task_param_manager->get_task_other_param(task_id, m_eType);
  106 + if (!params_ptr || !params_ptr->basic_param)
  107 + {
  108 + continue;
  109 + }
  110 +
  111 + auto& basic_param = params_ptr->basic_param;
  112 + if (basic_param == nullptr || basic_param->adapt_param == nullptr) {
  113 + continue;
  114 + }
  115 + universal_algor_adapt_param *adapt_param = basic_param->adapt_param;
  116 +
  117 + string sep = "/";
  118 +
  119 + std::string cur_src_ts = std::to_string(helpers::timer::get_timestamp<std::chrono::milliseconds>());
  120 + std::string origin_file_path = basic_param->result_folder + sep + task_id + "_origin_" + cur_src_ts + ".jpg";
  121 +
  122 + /* 依次判断检测目标框 是否有非法闯入 判断逻辑:之前帧在禁区外 当前帧进入禁区 */
  123 + auto& one_result = det_results[i];
  124 + std::vector<box_t> boxes;
  125 + for (unsigned c = 0; c < one_result.obj_count; ++c) {
  126 +
  127 + auto obj_c = one_result.obj[c];
  128 +
  129 + box_t unique_box;
  130 + unique_box.id = obj_c.id;
  131 + unique_box.cls = obj_c.index;
  132 + unique_box.top = obj_c.top;
  133 + unique_box.left = obj_c.left;
  134 + unique_box.right = obj_c.right;
  135 + unique_box.bottom = obj_c.bottom;
  136 + unique_box.score = obj_c.confidence;
  137 +
  138 + OBJ_KEY obj_key{task_id, obj_c.id};
  139 +
  140 + if (!is_valid_box(task_id, unique_box, m_eType)){
  141 + obj_to_position_.erase(obj_key); // 如果不满足条件 非 合法框 依然删除
  142 + }
  143 +
  144 + sy_point center;
  145 + center.x_ = (obj_c.right + obj_c.left)/ 2 ;
  146 + center.y_ = (obj_c.bottom + obj_c.top) / 2;
  147 + if (common::isInPolygon(adapt_param->points, adapt_param->points_count, center)) {
  148 + // 禁区内
  149 + // 新加
  150 + obj_to_position_[obj_key] = unique_box;
  151 + } else {
  152 + // 更新
  153 + if (obj_to_position_.find(obj_key) != obj_to_position_.end()) // 之前在禁区内,可报警
  154 + {
  155 + box_t box;
  156 + box.left = obj_c.left;
  157 + box.right = obj_c.right;
  158 + box.top = obj_c.top;
  159 + box.bottom = obj_c.bottom;
  160 + box.score = obj_c.confidence;
  161 + boxes.push_back(box);
  162 +
  163 + // 报完警清除记录
  164 + obj_to_position_.erase(obj_key);
  165 + }
  166 + }
  167 + }
  168 +
  169 + if (boxes.size() <= 0)
  170 + {
  171 + continue;
  172 + }
  173 +
  174 + int algorithm_type = (int)m_eType;
  175 + string json_str = helpers::gen_json::gen_boxes_json(task_id, algorithm_type, boxes, origin_file_path);
  176 +
  177 + ImgSaveInfo info_origin;
  178 + info_origin.img_info = VPCUtil::vpc_devMem2vpcImg(gpuMem);
  179 + info_origin.file_path = origin_file_path;
  180 + info_origin.json_str = json_str;
  181 + m_save_util->reprocessing_process_wo_locus_async(info_origin);
  182 + }
  183 +}
  184 +
  185 +} // namespace ai_engine_module
0 \ No newline at end of file 186 \ No newline at end of file
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 +namespace ai_engine_module {
  17 +
  18 +class RegionLeave {
  19 +public:
  20 + RegionLeave();
  21 + ~RegionLeave();
  22 +
  23 + void init(int devId, algorithm_type_t eType);
  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 +#ifdef POST_USE_RABBITMQ
  28 + typedef std::function<bool(const char *msg)> callback_t;
  29 + void set_callback(callback_t cb);
  30 +#endif
  31 +
  32 +private:
  33 + bool is_valid_box(string task_id, const box_t &box, const algorithm_type_t &algor_type);
  34 +
  35 +private:
  36 + task_param_manager *m_task_param_manager{nullptr};
  37 + std::map<OBJ_KEY, box_t> obj_to_position_; // 保存物体上一帧的位置,基于非法闯入判断逻辑,上一帧在框外,下一帧闯入禁区
  38 + std::map<std::string, cv::Mat> region_map;
  39 +
  40 + int m_devId{0};
  41 + algorithm_type_t m_eType;
  42 +
  43 + save_snapshot_reprocessing *m_save_util{nullptr};
  44 +};
  45 +
  46 +
  47 +} // namespace ai_engine_module
  48 +
  49 +#endif // __REGION_LEAVE_H__
0 \ No newline at end of file 50 \ No newline at end of file
src/ai_engine_module/ai_engine_module.h 0 → 100644
  1 +#pragma once
  2 +
  3 +#include "./VPTProcess.h"
  4 +#include "./face_det_ai_engine.h"
  5 +#include "./pedestrian_vehicle_retrograde.h"
  6 +#include "./pedestrian_vehicle_trespass.h"
  7 +#include "./RegionLeave.h"
  8 +#include "./GatherDetect.h"
0 \ No newline at end of file 9 \ No newline at end of file
src/ai_engine_module/face_det_ai_engine.cpp 0 → 100755
  1 +#include "face_det_ai_engine.h"
  2 +
  3 +#include "../common/logger.hpp"
  4 +#include "../ai_platform/mvpt_process_assist.h"
  5 +#include "../ai_platform/macro_definition.h"
  6 +
  7 +#include "opencv2/opencv.hpp"
  8 +#include "face_detect.h"
  9 +
  10 +#include "../helpers/img_util.h"
  11 +
  12 +face_det_ai_engine::face_det_ai_engine(){
  13 + m_max_batchsize = 10;
  14 +}
  15 +
  16 +face_det_ai_engine::~face_det_ai_engine(){
  17 + fd_release(&handle);
  18 + clear();
  19 +
  20 + if(m_algorthim_ctx){
  21 + aclrtSetDevice(m_devId);
  22 + aclrtDestroyContext(m_algorthim_ctx);
  23 + }
  24 +}
  25 +
  26 +int face_det_ai_engine::init_ai_engine(const facedet_ai_engine_param &ai_param/*, person_det_algorthim_cache * cache*/){
  27 +
  28 + task_param_manager_ = task_param_manager::getInstance();
  29 +
  30 + m_devId = ai_param.sdk_param.devId;
  31 +
  32 + ACL_CALL(aclrtSetDevice(m_devId), ACL_ERROR_NONE, -1);
  33 + ACL_CALL(aclrtCreateContext(&m_algorthim_ctx, m_devId), ACL_ERROR_NONE, -1);
  34 +
  35 + return fd_init(&handle, ai_param.sdk_param);
  36 +}
  37 +
  38 +int face_det_ai_engine::ai_engine_process_batch(std::vector<std::string> &task_ids, sy_img *image_data_array, std::vector<onelevel_det_result> &result , std::vector<std::vector<int>> &deleteObjectID){
  39 +
  40 + map<string, map<algo_type, task_param_manager::algo_param_type_t_*>> && algor_param = task_param_manager_->get_task_other_params();
  41 +
  42 + const int total_batchsize = task_ids.size();
  43 + if (total_batchsize <= 0){
  44 + return 0;
  45 + }
  46 +
  47 + aclrtSetDevice(m_devId);
  48 + int ret = aclrtSetCurrentContext(m_algorthim_ctx);
  49 + if(ACL_ERROR_NONE != ret){
  50 + return 0;
  51 + }
  52 +
  53 + fd_result *fd_result_ = new fd_result[total_batchsize];
  54 + for (int i = 0; i < total_batchsize; ++i)
  55 + fd_result_[i].info = new fd_info[50];
  56 +
  57 + do{
  58 + int stride = m_max_batchsize;
  59 + int steps = (total_batchsize + stride - 1) / stride;
  60 +
  61 + bool bError = false;
  62 + for (int c = 0; c < steps; ++c) {
  63 + int offset = c * m_max_batchsize;
  64 + const int batchsize = (c == steps - 1) ? (total_batchsize - offset) : stride;
  65 +
  66 + int ret = fd_detect_batch(handle, image_data_array + offset, SY_FORMAT_BGR888, batchsize, fd_result_ + offset);
  67 + if(ret < 0){
  68 + LOG_ERROR(" fd_detect_batch error!!! image_size: {} model_batch_size: {}, step: [{}/{}] offset: {} batchsize: {}", total_batchsize, m_max_batchsize, c, steps, offset, batchsize);
  69 + bError = true;
  70 + break;
  71 + }
  72 + }
  73 +
  74 + if(bError){
  75 + break;
  76 + }
  77 +
  78 + // 属性检测使用人脸检测的原图,不需要切图
  79 + int cur_index = 0;
  80 + int img_index = 0;
  81 +
  82 + vector <vector< vector <float>>> detectResult(total_batchsize); // sort
  83 + auto task_id_iter = task_ids.cbegin();
  84 + for (int c = 0; c < total_batchsize; ++c)
  85 + {
  86 + string task_id = *task_id_iter;
  87 + task_id_iter++;
  88 +
  89 + task_param_manager::algo_param_type_t_* cur_task_params = algor_param[task_id][algorithm_type_t::FACE_SNAPSHOT];
  90 + if (cur_task_params->basic_param == nullptr) {
  91 + continue;
  92 + }
  93 +
  94 + auto adapt_param = cur_task_params->basic_param->adapt_param;
  95 + if (adapt_param == nullptr){
  96 + continue;
  97 + }
  98 +
  99 + for (int i = 0; i < fd_result_[c].count; ++i)
  100 + {
  101 + auto& obj_c = fd_result_[c].info[i];
  102 +
  103 + sy_point center;
  104 + center.x_ = obj_c.face_position.left_ + obj_c.face_position.width_ / 2 ;
  105 + center.y_ = obj_c.face_position.top_ + obj_c.face_position.height_ / 2;
  106 + if (!common::isInPolygon(adapt_param->points, adapt_param->points_count, center) || obj_c.face_pos_score < ((algor_config_param_snapshot *)cur_task_params->algor_param)->threshold) {
  107 + continue;
  108 + }
  109 +
  110 + vector <float> obj;
  111 + obj.push_back(fd_result_[c].info[i].face_position.left_);
  112 + obj.push_back(fd_result_[c].info[i].face_position.top_);
  113 + obj.push_back(fd_result_[c].info[i].face_position.left_ + fd_result_[c].info[i].face_position.width_); //right
  114 + obj.push_back(fd_result_[c].info[i].face_position.top_ + fd_result_[c].info[i].face_position.height_); //bottom
  115 + obj.push_back(fd_result_[c].info[i].score);
  116 + obj.push_back(1); //统一index值为1
  117 + //存入关键点信息
  118 + for(int j = 0; j < FACIALFEAPOINTSIZE; ++j)
  119 + {
  120 + obj.push_back(fd_result_[c].info[i].facial_fea_point[j].x_);
  121 + obj.push_back(fd_result_[c].info[i].facial_fea_point[j].y_);
  122 + }
  123 +
  124 + //-added by zsh 添加姿态角信息------------------------------
  125 + obj.push_back(fd_result_[c].info[i].roll);
  126 + obj.push_back(fd_result_[c].info[i].yaw);
  127 + obj.push_back(fd_result_[c].info[i].pitch);
  128 + // cout << fabs(fd_result_[c].info[i].roll) << " " << fabs(fd_result_[c].info[i].yaw) << " " << fabs(fd_result_[c].info[i].pitch) << endl;
  129 + //--------------------------------------------------------
  130 + detectResult[c].push_back(obj);
  131 +
  132 + #if 0
  133 + if (fd_result_[img_index].count > 1)
  134 + {
  135 + //选择居中且靠上的人脸作为唯一的结果
  136 + float min_dis = numeric_limits<float>::max();
  137 + int min_index = 0;
  138 + float person_center_x = (float)(cur_persondet_result[c]->obj[i].right - cur_persondet_result[c]->obj[i].left) / 2.0;
  139 + float person_center_y = (float)(cur_persondet_result[c]->obj[i].bottom - cur_persondet_result[c]->obj[i].top) / 6.0;
  140 + for (int j = 0; j < fd_result_[img_index].count; ++j)
  141 + {
  142 + float cx = (float)fd_result_[img_index].info[j].face_position.left_ + (float)(fd_result_[img_index].info[j].face_position.width_) / 2.0;
  143 + float cy = (float)fd_result_[img_index].info[j].face_position.top_ + (float)(fd_result_[img_index].info[j].face_position.height_) / 2.0;
  144 + float dis = (person_center_x - cx) * (person_center_x - cx) + (person_center_y - cy) * (person_center_y - cy);
  145 + if (dis < min_dis)
  146 + {
  147 + min_dis = dis;
  148 + min_index = j;
  149 + }
  150 + }
  151 + //姿态角控制
  152 + if (fabs(fd_result_[img_index].info[min_index].roll) < pose_thresld[c] && fabs(fd_result_[img_index].info[min_index].yaw) < pose_thresld[c] && fabs(fd_result_[img_index].info[min_index].pitch) < pose_thresld[c])
  153 + {
  154 + cur_res.count = 1;
  155 + cur_res.info = new fd_info[1];
  156 + memcpy(&cur_res.info[0], &fd_result_[img_index].info[min_index], sizeof(fd_info));
  157 + }
  158 + else
  159 + {
  160 + cur_res.info = new fd_info[1];
  161 + cur_res.count = 0;
  162 + }
  163 +
  164 + }
  165 + else if (fd_result_[img_index].count == 1 && fabs(fd_result_[img_index].info[0].roll) < pose_thresld[c] && fabs(fd_result_[img_index].info[0].yaw) < pose_thresld[c] && fabs(fd_result_[img_index].info[0].pitch) < pose_thresld[c]) //姿态角控制
  166 + {
  167 + cur_res.count = 1;
  168 + cur_res.info = new fd_info[1];
  169 + memcpy(&cur_res.info[0], &fd_result_[img_index].info[0], sizeof(fd_info));
  170 + }
  171 + else
  172 + {
  173 + cur_res.info = new fd_info[1];
  174 + cur_res.count = 0;
  175 + }
  176 + _fd_result[vec_ids[c]].push_back(cur_res);
  177 +
  178 + for (int j = 0; j < cur_res.count; ++j)
  179 + {
  180 + ++cur_index;
  181 + }
  182 + #endif
  183 +
  184 + }
  185 + }
  186 +
  187 + //跟踪
  188 + for (size_t real_index = 0; real_index < total_batchsize; real_index++) {
  189 + string task_id = task_ids[real_index];
  190 +
  191 + bool isUseDet = true;
  192 + vector<int> delete_ids;
  193 + const float maxLen = std::sqrt(image_data_array[real_index].w_ * image_data_array[real_index].w_ + image_data_array[real_index].h_ * image_data_array[real_index].h_); //-modified by zsh 220719
  194 + for (int j = 0; j < task_trackers[task_id].fusion_interval; ++j) {
  195 + if (j == 0) {
  196 + int objCount = task_trackers[task_id].tracker.update_v2(isUseDet, /*save lk = */true, /*center_dist = */true, maxLen, detectResult[real_index], result[real_index].obj, deleteObjectID[real_index]);
  197 + result[real_index].obj_count = objCount;
  198 + vector<vector<float>>().swap(detectResult[real_index]);
  199 + detectResult[real_index].clear();
  200 + isUseDet = false;
  201 + } else {
  202 + onelevel_det_result unresult;
  203 + unresult.obj_count = task_trackers[task_id].tracker.update_v2(isUseDet, true, true, maxLen, detectResult[real_index], unresult.obj, deleteObjectID[real_index]);
  204 + }
  205 + }
  206 +
  207 + ++real_index;
  208 + }
  209 +
  210 + vector <vector< vector <float>>>().swap(detectResult); // free memory.
  211 +
  212 + ret = total_batchsize;
  213 + }while(0);
  214 +
  215 + if (fd_result_) {
  216 + for (int i = 0; i < total_batchsize; ++i) {
  217 + delete[] fd_result_[i].info;
  218 + fd_result_[i].info = nullptr;
  219 + }
  220 + delete[] fd_result_;
  221 + fd_result_ = nullptr;
  222 + }
  223 +
  224 + return ret;
  225 +}
  226 +
  227 +void face_det_ai_engine::clear()
  228 +{
  229 + for (auto it = _fd_result.begin(); it != _fd_result.end();)
  230 + {
  231 + for (auto &fd : it->second)
  232 + {
  233 + delete[] fd.info;
  234 + fd.info = nullptr;
  235 + }
  236 + _fd_result.erase(it++);
  237 + }
  238 +}
  239 +
  240 +void face_det_ai_engine::add_tracker(std::string task_id, int fusion_interval){
  241 + LOG_INFO("face: tracker add task {}", task_id.c_str());
  242 + task_tracker t;
  243 + t.task_id = task_id;
  244 + t.tracker.FusionInterval = fusion_interval; // 221117byzsh
  245 + t.fusion_interval = fusion_interval;
  246 + task_trackers.insert(std::make_pair(task_id, t));
  247 +}
  248 +
  249 +
  250 +void face_det_ai_engine::finish_task(std::string task_id)
  251 +{
  252 + LOG_INFO("face: tracker finish task {}", task_id.c_str());
  253 + auto iter = task_trackers.find(task_id);
  254 + if (iter != task_trackers.end())
  255 + {
  256 + task_trackers.erase(task_id);
  257 + }
  258 +}
0 \ No newline at end of file 259 \ No newline at end of file
src/ai_engine_module/face_det_ai_engine.h 0 → 100755
  1 +#ifndef _FACE_DET_AI_ENGINE_
  2 +#define _FACE_DET_AI_ENGINE_
  3 +
  4 +#include "face_detect.h"
  5 +#include "./sort/Sort.h"
  6 +#include "../ai_platform/task_param_manager.h"
  7 +#include "../ai_platform/det_obj_header.h"
  8 +
  9 +#include "acl/acl.h"
  10 +#include "acl/ops/acl_dvpp.h"
  11 +
  12 +using namespace std;
  13 +
  14 +
  15 +typedef struct facedet_ai_engine_param
  16 +{
  17 + //int min_recg_frame_counts;
  18 + fd_param sdk_param;
  19 +} facedet_ai_engine_param;
  20 +
  21 +#ifndef _TASK_TRACKER_
  22 +#define _TASK_TRACKER_
  23 +struct task_tracker
  24 +{
  25 + std::string task_id;
  26 + int fusion_interval;//跳帧数
  27 + //tracker *trk;;
  28 + Sort tracker;
  29 +};
  30 +#endif
  31 +
  32 +class face_det_ai_engine/*: public base_ai_engine*/
  33 +{
  34 +public:
  35 + face_det_ai_engine();
  36 + ~face_det_ai_engine();
  37 +
  38 + int init_ai_engine(const facedet_ai_engine_param &ai_param/*, person_det_algorthim_cache * cache*/);
  39 + int ai_engine_process_batch(std::vector<std::string> &task_ids, sy_img *image_data_array, std::vector<onelevel_det_result> &result
  40 + , std::vector<std::vector<int>> &deleteObjectID);
  41 + void finish_task(std::string task_id);
  42 + void add_tracker(std::string task_id, int fusion_interval);
  43 + void clear();
  44 +
  45 +private:
  46 + //int cur_batchsize;
  47 + //person_det_algorthim_cache * _cache;
  48 + void* handle;
  49 + int m_max_batchsize;
  50 +
  51 + int m_devId;
  52 + aclrtContext m_algorthim_ctx;
  53 +
  54 + std::map<std::string, task_tracker> task_trackers;
  55 + //std::vector<sy_img > _cut_data_array;
  56 + std::map<std::string, std::vector<fd_result>> _fd_result;
  57 +
  58 + task_param_manager *task_param_manager_;
  59 +};
  60 +
  61 +#endif
0 \ No newline at end of file 62 \ No newline at end of file
src/ai_engine_module/face_detect.h 0 → 100755
  1 +/************************************************************
  2 +* Version: face_detect_v1.4.1.20201221.x86_64.gpu
  3 +* CopyRight: 中科视语(北京)科技有限公司
  4 +* UpdateDate: 20201221
  5 +* Content:
  6 +************************************************************/
  7 +#ifndef FACEDETECT_H_
  8 +#define FACEDETECT_H_
  9 +
  10 +#ifdef _MSC_VER
  11 +#ifdef FACEDETECT_EXPORTS
  12 +#define FACEDETECT_API __declspec(dllexport)
  13 +#else
  14 +#define FACEDETECT_API __declspec(dllimport)
  15 +#endif
  16 +#else
  17 +#define FACEDETECT_API __attribute__ ((visibility ("default")))
  18 +#endif
  19 +#ifdef __cplusplus
  20 +extern "C"
  21 +{
  22 +#endif
  23 +
  24 +#include "sy_common.h" //通用数据结构体定义
  25 +
  26 +// #define GPUIMG_PROCESS
  27 +
  28 +#ifndef FACIALFEAPOINTSIZE //关键点检测支持25个点
  29 +#define FACIALFEAPOINTSIZE 25
  30 +#endif
  31 +
  32 +
  33 +#ifndef __FD_INFO__
  34 +#define __FD_INFO__
  35 + typedef struct fd_info {
  36 + sy_rect face_position; //人脸位置
  37 + float face_pos_score; //人脸框置信度
  38 + sy_point facial_fea_point[FACIALFEAPOINTSIZE]; //人脸关键点位置信息
  39 + int occlusion; //人脸遮挡度,范围值为0-100,越大表示人脸遮挡程度越高
  40 + int clarity; //人脸清晰度,范围值为0-100,越大表示图像越清晰,人脸清晰度判别建议阈值为30
  41 + int brightness; //人脸亮度,只有3种可能的值:[-1->太暗,0->正常,1->太亮],亮度结果会受亮度阈值参数brightness_min和brightness_max影响
  42 + //int hat; //带帽子,范围为0-100,越大表示越可能有佩戴帽子,建议判别阈值为50
  43 + //int glass; //带眼镜,范围为0-100,越大表示越可能有戴眼镜,建议判别阈值为70
  44 + float roll; //姿态角
  45 + float yaw; //姿态角
  46 + float pitch; //姿态角
  47 + float score; //人脸置信度
  48 + } fd_info;
  49 +#endif
  50 +
  51 +#ifndef __FD_RESULT__
  52 +#define __FD_RESULT__
  53 + typedef struct fd_result { //结果结构体
  54 + fd_info *info; //内存由外部申请
  55 + int count; //人脸个数
  56 + } fd_result;
  57 +#endif
  58 +
  59 +#ifndef __FD_PARAM__
  60 +#define __FD_PARAM__
  61 + typedef struct fd_param
  62 + {
  63 + sy_command facial_fea_point_config; //是否启动关键点检测
  64 + sy_command pose_config; //是否启动姿态角
  65 + sy_command quality_config; //是否启动质量检测
  66 + sy_command score_config; //是否启动人脸置信度
  67 + // int log; //日志
  68 + // int mode; //运行模式(DEVICE_GPU / DEVICE_CPU)
  69 + int devId; //指定显卡id
  70 + float thresld; //检测阈值 建议0.7
  71 +
  72 + int max_result_count; //检测结果目标数上限
  73 + // int max_batch_size_detect; //检测批处理检测数量上限
  74 + // int max_batch_size_ldmk; //关键点批处理检测数量上限
  75 + // int max_batch_size_pose; //姿态角批处理检测数量上限
  76 + // int max_batch_size_score; //置信度批处理检测数量上限
  77 + // int max_batch_size_blurglass; //质量(模糊)批处理检测数量上限
  78 + // //int max_batch_size_hat; //质量(帽子)批处理检测数量上限
  79 + // int max_batch_size_occlusion; //质量(遮挡)批处理检测数量上限
  80 +
  81 + char * auth_license;
  82 + char* det_modelNames; //人脸检测
  83 + char* ldmk_modelNames; //人脸关键点
  84 + char* pose_modelNames; //人脸姿态
  85 + char* score_modelNames; //人脸置信度
  86 + char* fuzzy_modelNames; //人脸质量_模糊
  87 + char* occlusion_modelNames; //人脸质量_遮挡
  88 +
  89 + fd_param() : facial_fea_point_config(SY_CONFIG_OPEN), pose_config(SY_CONFIG_OPEN), \
  90 + quality_config(SY_CONFIG_OPEN), score_config(SY_CONFIG_OPEN), thresld(0.6), devId(0), max_result_count(20), auth_license("") {}; //默认功能全部启动
  91 + }fd_param;
  92 +#endif
  93 +
  94 + /*************************************************************************
  95 + * function: fd_init
  96 + * purpose: init resources
  97 + * param:
  98 + [in] handle - handle
  99 + [in] param - init param
  100 + * return: success(0) or error code(<0)
  101 + * notes: null
  102 + *************************************************************************/
  103 + FACEDETECT_API int fd_init(void ** handle, fd_param param);
  104 +
  105 +
  106 + /*************************************************************************
  107 + * function: fd_release
  108 + * purpose: release sources
  109 + * param:
  110 + [in] handle - handle
  111 + * return: null
  112 + * notes: null
  113 + *************************************************************************/
  114 + FACEDETECT_API void fd_release(void ** handle);
  115 +
  116 + /*************************************************************************
  117 + * function: fd_get_version
  118 + * purpose: get sdk version
  119 + * param: null
  120 + * return: null
  121 + * notes: null
  122 + *************************************************************************/
  123 + FACEDETECT_API const char * fd_get_version();
  124 +
  125 + /*************************************************************************
  126 + * function: fd_detect_batch
  127 + * purpose: detect faces
  128 + * param:
  129 + [in] handle - handle
  130 + [in] img_data_array - data array
  131 + [in] format - data format
  132 + [in] batch_size - batch size
  133 + [in] result - face detect result
  134 + * return: success(0) or error code(<0)
  135 + * notes: null
  136 + *************************************************************************/
  137 + //FACEDETECT_API int fd_detect_batch(void * handle, sy_img * img_data_array, sy_format format, int batch_size, fd_result *result);
  138 +
  139 + /*************************************************************************
  140 + * function: fd_detect
  141 + * purpose: detect faces
  142 + * param:
  143 + [in] handle - handle
  144 + [in] img_data_array - data array
  145 + [in] format - data format
  146 + [in] result - face detect result
  147 + * return: success(0) or error code(<0)
  148 + * notes: null
  149 + *************************************************************************/
  150 + FACEDETECT_API int fd_detect(void * handle, sy_img img_data, sy_format format, fd_result *result);
  151 +
  152 +
  153 + FACEDETECT_API int fd_detect_batch(void * handle, sy_img * img_data_array, sy_format format, int batch_size, fd_result *result);
  154 +#ifdef __cplusplus
  155 +};
  156 +#endif
  157 +
  158 +#endif
  159 +
src/ai_platform/MultiSourceProcess.cpp
@@ -93,6 +93,8 @@ int CMultiSourceProcess::InitAlgorthim(tsl_aiplatform_param vptParam){ @@ -93,6 +93,8 @@ int CMultiSourceProcess::InitAlgorthim(tsl_aiplatform_param vptParam){
93 93
94 m_devId = vptParam.gpuid; 94 m_devId = vptParam.gpuid;
95 95
  96 + string models_dir = vptParam.models_dir;
  97 +
96 VPTProcess_PARAM vparam; 98 VPTProcess_PARAM vparam;
97 vparam.gpuid = m_devId; 99 vparam.gpuid = m_devId;
98 vparam.max_batch = m_batch_size; 100 vparam.max_batch = m_batch_size;
@@ -105,6 +107,42 @@ int CMultiSourceProcess::InitAlgorthim(tsl_aiplatform_param vptParam){ @@ -105,6 +107,42 @@ int CMultiSourceProcess::InitAlgorthim(tsl_aiplatform_param vptParam){
105 return ret; 107 return ret;
106 } 108 }
107 109
  110 +#ifdef WITH_FACE_DET_SS
  111 + // 人脸检测初始化
  112 + facedet_ai_engine_param fd_param;
  113 + char model_path_yolov5s[100];
  114 + strcpy(model_path_yolov5s, (models_dir + "/models/face_detect/face_det_yolov5s_310p.om").c_str());
  115 + fd_param.sdk_param.det_modelNames = model_path_yolov5s;
  116 + char model_path_ldmk[100];
  117 + strcpy(model_path_ldmk, (models_dir + "/models/face_detect/face_ldmk_310p.om").c_str());
  118 + fd_param.sdk_param.ldmk_modelNames = model_path_ldmk;
  119 + char model_path_pose[100];
  120 + strcpy(model_path_pose, (models_dir + "/models/face_detect/face_pose_310p.om").c_str());
  121 + fd_param.sdk_param.pose_modelNames = model_path_pose;
  122 + char model_path_score[100];
  123 + strcpy(model_path_score, (models_dir + "/models/face_detect/face_score_310p.om").c_str());
  124 + fd_param.sdk_param.score_modelNames = model_path_score;
  125 + char model_path_fuzzy[100];
  126 + strcpy(model_path_fuzzy, (models_dir + "/models/face_detect/face_fuzzy_310p.om").c_str());
  127 + fd_param.sdk_param.fuzzy_modelNames = model_path_fuzzy;
  128 + char model_path_occlusion[100];
  129 + strcpy(model_path_occlusion, (models_dir + "/models/face_detect/face_occlusion_310p.om").c_str());
  130 + fd_param.sdk_param.occlusion_modelNames = model_path_occlusion;
  131 + fd_param.sdk_param.thresld = 0.6;
  132 + fd_param.sdk_param.devId = m_devId;
  133 + fd_param.sdk_param.auth_license = "sy_tongtu_aiplatform_sdk_2023";
  134 + fd_param.sdk_param.facial_fea_point_config = SY_CONFIG_OPEN; //是否启动关键点检测
  135 + fd_param.sdk_param.pose_config = SY_CONFIG_OPEN; //是否启动姿态角
  136 + fd_param.sdk_param.quality_config = SY_CONFIG_OPEN; //是否启动质量检测
  137 + fd_param.sdk_param.score_config = SY_CONFIG_OPEN; //是否启动人脸置信度 //SY_CONFIG_OPEN SY_CONFIG_CLOSE
  138 + fd_param.sdk_param.max_result_count = 50;
  139 + ret = m_face_det_ai_engine.init_ai_engine(fd_param);
  140 + if (ret < 0 ) {
  141 + LOG_FATAL("Init face detection failed");
  142 + return ret;
  143 + }
  144 +#endif
  145 +
108 m_algorthim_region_leave.init(vptParam.gpuid, algorithm_type_t::HUMAN_LEAVE_REGION); 146 m_algorthim_region_leave.init(vptParam.gpuid, algorithm_type_t::HUMAN_LEAVE_REGION);
109 m_algorthim_region_dismiss.init(vptParam.gpuid, algorithm_type_t::HUMAN_REGION_DISMISS); 147 m_algorthim_region_dismiss.init(vptParam.gpuid, algorithm_type_t::HUMAN_REGION_DISMISS);
110 m_algorthim_region_fastmoving.init(vptParam.gpuid, algorithm_type_t::HUMAN_REGION_FAST_MOVING); 148 m_algorthim_region_fastmoving.init(vptParam.gpuid, algorithm_type_t::HUMAN_REGION_FAST_MOVING);
@@ -279,6 +317,12 @@ bool CMultiSourceProcess::AddTask(task_param _cur_task_param){ @@ -279,6 +317,12 @@ bool CMultiSourceProcess::AddTask(task_param _cur_task_param){
279 if (task_has_vpt_algor(task_id)) 317 if (task_has_vpt_algor(task_id))
280 vpt_process.addTaskTracker(task_id, 1, 1, skip_frame_); 318 vpt_process.addTaskTracker(task_id, 1, 1, skip_frame_);
281 319
  320 +#ifdef WITH_FACE_DET_SS
  321 + // 人脸跟踪
  322 + if (m_task_param_manager->task_has_face_algor(task_id))
  323 + m_face_det_ai_engine.add_tracker(task_id, skip_frame_); // 跳帧数暂时写死
  324 +#endif
  325 +
282 m_FinishedTaskMtx.lock(); 326 m_FinishedTaskMtx.lock();
283 m_FinishedTaskMap[task_id] = false; 327 m_FinishedTaskMap[task_id] = false;
284 m_FinishedTaskMtx.unlock(); 328 m_FinishedTaskMtx.unlock();
@@ -449,6 +493,12 @@ bool CMultiSourceProcess::finish_task(const string taskID, const bool delete_sna @@ -449,6 +493,12 @@ bool CMultiSourceProcess::finish_task(const string taskID, const bool delete_sna
449 if (!vpt_process.finishTaskTracker(taskID)) 493 if (!vpt_process.finishTaskTracker(taskID))
450 LOG_ERROR("Finish VPT Tracker failed, task_id: {}", taskID); 494 LOG_ERROR("Finish VPT Tracker failed, task_id: {}", taskID);
451 495
  496 +#ifdef WITH_FACE_DET_SS
  497 + // 人脸任务结束
  498 + if (m_task_param_manager->task_has_face_algor(taskID))
  499 + m_face_det_ai_engine.finish_task(taskID);
  500 +#endif
  501 +
452 #ifdef POST_USE_RABBITMQ 502 #ifdef POST_USE_RABBITMQ
453 auto json_str = helpers::gen_json::gen_office_task_heart_beat_json({taskID}); 503 auto json_str = helpers::gen_json::gen_office_task_heart_beat_json({taskID});
454 mq_manager_->publish(mq_type_t::HEART_BEAT_MQ, json_str.c_str(), true); 504 mq_manager_->publish(mq_type_t::HEART_BEAT_MQ, json_str.c_str(), true);
@@ -514,6 +564,10 @@ int CMultiSourceProcess::algorthim_process_thread(){ @@ -514,6 +564,10 @@ int CMultiSourceProcess::algorthim_process_thread(){
514 aclrtSetCurrentContext(ctx); 564 aclrtSetCurrentContext(ctx);
515 algorthim_vpt(vec_gpuMem); 565 algorthim_vpt(vec_gpuMem);
516 566
  567 +#ifdef WITH_FACE_DET_SS
  568 + algorthim_face_detect(vec_gpuMem);
  569 +#endif
  570 +
517 for(int i=0;i < vec_gpuMem.size(); i++){ 571 for(int i=0;i < vec_gpuMem.size(); i++){
518 DeviceMemory* mem = vec_gpuMem[i]; 572 DeviceMemory* mem = vec_gpuMem[i];
519 if(mem->getSize() <= 0){ 573 if(mem->getSize() <= 0){
@@ -1085,6 +1139,64 @@ bool CMultiSourceProcess::save_snapshot_process(const OBJ_KEY &amp;obj_key, const al @@ -1085,6 +1139,64 @@ bool CMultiSourceProcess::save_snapshot_process(const OBJ_KEY &amp;obj_key, const al
1085 return true; 1139 return true;
1086 } 1140 }
1087 1141
  1142 +// 人脸检测抓拍算法模块
  1143 +void CMultiSourceProcess::algorthim_face_detect(vector<DeviceMemory*> vec_gpuMem) {
  1144 +
  1145 + vector<string> interest_task_list;
  1146 + vector<sy_img> interest_imgs;
  1147 + vector<DeviceMemory*> vec_vptMem;
  1148 + for (int i = 0; i < vec_gpuMem.size(); i++) {
  1149 + DeviceMemory* mem = vec_gpuMem[i];
  1150 + if (!m_task_param_manager->task_has_face_algor(mem->getId())){
  1151 + continue;
  1152 + }
  1153 +
  1154 + sy_img img;
  1155 + img.w_ = mem->getWidth();
  1156 + img.h_ = mem->getHeight();
  1157 + img.c_ = mem->getChannel();
  1158 + img.data_ = mem->getMem();
  1159 + interest_imgs.push_back(img);
  1160 + interest_task_list.push_back(mem->getId());
  1161 + vec_vptMem.push_back(mem);
  1162 + }
  1163 +
  1164 + if (!interest_imgs.empty()) {
  1165 +
  1166 + unsigned image_size = interest_imgs.size();
  1167 +
  1168 + // 人脸检测、跟踪
  1169 + std::vector<onelevel_det_result> facedet_result(image_size);
  1170 + std::vector<std::vector<int>> face_deleteObjectID(image_size);
  1171 +
  1172 + int ret = m_face_det_ai_engine.ai_engine_process_batch(interest_task_list, interest_imgs.data(), facedet_result, face_deleteObjectID);
  1173 + if(ret <= 0){
  1174 + LOG_ERROR("face detect error!!!");
  1175 + return;
  1176 + }
  1177 +
  1178 + // 跟踪结果送入快照更新
  1179 + m_snapshot_reprocessing->update_face_bestsnapshot(vec_vptMem, facedet_result, face_deleteObjectID);
  1180 +
  1181 + // 保存已结束轨迹的目标
  1182 + auto task_iter_face = interest_task_list.begin(); //debug by zsh
  1183 + for (int i = 0; i < face_deleteObjectID.size(); i++) {
  1184 + for (int j = 0; j < face_deleteObjectID[i].size(); ++j) {
  1185 + OBJ_KEY deleteObj = {*task_iter_face, face_deleteObjectID[i][j]};
  1186 + LOG_TRACE("{}: {}",*task_iter_face,face_deleteObjectID[i][j]);
  1187 + face_locus_finished(deleteObj);
  1188 + }
  1189 + ++task_iter_face;
  1190 + }
  1191 +
  1192 + for (int i = 0; i < face_deleteObjectID.size(); ++i){
  1193 + std::vector<int>().swap(face_deleteObjectID[i]);
  1194 + }
  1195 + std::vector<std::vector<int>>().swap(face_deleteObjectID);
  1196 + std::vector<onelevel_det_result>().swap(facedet_result);
  1197 + }
  1198 +}
  1199 +
1088 void CMultiSourceProcess::cross_line_process(vector<DeviceMemory*> vec_gpuMem, vector<onelevel_det_result>& vptResult, algorithm_type_t eType) 1200 void CMultiSourceProcess::cross_line_process(vector<DeviceMemory*> vec_gpuMem, vector<onelevel_det_result>& vptResult, algorithm_type_t eType)
1089 { 1201 {
1090 map<string, map<algo_type, task_param_manager::algo_param_type_t_*>> && algor_param = m_task_param_manager->get_task_other_params(); 1202 map<string, map<algo_type, task_param_manager::algo_param_type_t_*>> && algor_param = m_task_param_manager->get_task_other_params();
@@ -1334,6 +1446,56 @@ int CMultiSourceProcess::gather_process(vector&lt;DeviceMemory*&gt;&amp; vec_gpuMem, vecto @@ -1334,6 +1446,56 @@ int CMultiSourceProcess::gather_process(vector&lt;DeviceMemory*&gt;&amp; vec_gpuMem, vecto
1334 return 0; 1446 return 0;
1335 } 1447 }
1336 1448
  1449 +void CMultiSourceProcess::face_locus_finished(const OBJ_KEY obj_key) {
  1450 + map<OBJ_KEY, OBJ_VALUE> _total_face_snapshot_info = m_snapshot_reprocessing->get_total_face_snapshot_info();
  1451 +
  1452 + auto it = _total_face_snapshot_info.find(obj_key);
  1453 + if ( it == _total_face_snapshot_info.end()) {
  1454 + return;
  1455 + }
  1456 +
  1457 + LOG_DEBUG("face reprocessing {}:{}.", obj_key.video_id, obj_key.obj_id);
  1458 +
  1459 + auto task_other_params = m_task_param_manager->get_task_other_params();
  1460 +
  1461 + const algor_basic_config_param_t *cur_param =
  1462 + ((algor_init_config_param_t *)(task_other_params[obj_key.video_id][algorithm_type_t::FACE_SNAPSHOT]))->basic_param;
  1463 +
  1464 + OBJ_VALUE obj_value = it->second;
  1465 +
  1466 + std::string cur_time1 = std::to_string(helpers::timer::get_timestamp<std::chrono::milliseconds>());
  1467 +
  1468 + // 原图
  1469 + string fpath_src = std::string(cur_param->result_folder) + helpers::os::sep + obj_key.video_id + "_" +
  1470 + std::to_string(obj_key.obj_id) + "_" + cur_time1 + ".jpg";
  1471 +
  1472 + ImgSaveInfo origin_save_info;
  1473 + origin_save_info.file_path = fpath_src;
  1474 + origin_save_info.img_info = obj_value.snapShot;
  1475 + origin_save_info.obj_rect = obj_value.obj_pos;
  1476 + m_save_snapshot_reprocessing->reprocessing_process_wo_locus_async(origin_save_info);
  1477 +
  1478 + // 抠图
  1479 + string json_str = "";
  1480 + std::string cur_time2 = std::to_string(helpers::timer::get_timestamp<std::chrono::milliseconds>());
  1481 + string fpath_snapShotLittle = std::string(cur_param->result_folder_little) + helpers::os::sep + obj_key.video_id + "_" +
  1482 + std::to_string(obj_key.obj_id) + "_" + cur_time2 + ".jpg";
  1483 +
  1484 +#ifdef POST_USE_RABBITMQ
  1485 + json_str = helpers::gen_json::gen_face_detection_json( obj_key.video_id, obj_key.obj_id, fpath_snapShotLittle, fpath_src,
  1486 + obj_value.position, obj_value.confidence, obj_value.landmark_point, 25);
  1487 +#endif
  1488 +
  1489 + ImgSaveInfo roi_save_info;
  1490 + roi_save_info.file_path = fpath_snapShotLittle;
  1491 + roi_save_info.img_info = obj_value.snapShotLittle;
  1492 + roi_save_info.json_str = json_str;
  1493 + m_save_snapshot_reprocessing->reprocessing_process_wo_locus_async(roi_save_info);
  1494 +
  1495 + // 删除结束轨迹的数据
  1496 + m_snapshot_reprocessing->release_finished_face_locus_snapshot(obj_key.video_id, obj_key.obj_id, false);
  1497 +}
  1498 +
1337 int CMultiSourceProcess::CountRunningTask() { 1499 int CMultiSourceProcess::CountRunningTask() {
1338 DecoderManager* pDecManager = DecoderManager::getInstance(); 1500 DecoderManager* pDecManager = DecoderManager::getInstance();
1339 return pDecManager->count(); 1501 return pDecManager->count();
src/ai_platform/MultiSourceProcess.h
@@ -56,6 +56,8 @@ public: @@ -56,6 +56,8 @@ public:
56 private: 56 private:
57 // 算法相关 57 // 算法相关
58 int algorthim_vpt(vector<DeviceMemory*> vec_gpuMem); 58 int algorthim_vpt(vector<DeviceMemory*> vec_gpuMem);
  59 + // 人脸检测抓拍算法
  60 + void algorthim_face_detect(vector<DeviceMemory*> vec_gpuMem);
59 // 逆行 61 // 逆行
60 void algorthim_retrograde(vector<string>& vpt_interest_task_id, vector<DeviceMemory*> vpt_interest_imgs, vector<onelevel_det_result>& vptResult); 62 void algorthim_retrograde(vector<string>& vpt_interest_task_id, vector<DeviceMemory*> vpt_interest_imgs, vector<onelevel_det_result>& vptResult);
61 // 闯入 63 // 闯入
@@ -85,6 +87,8 @@ private: @@ -85,6 +87,8 @@ private:
85 87
86 int gather_process(vector<DeviceMemory*>& vec_gpuMem, vector<onelevel_det_result> &ol_det_result, algorithm_type_t algor_type); 88 int gather_process(vector<DeviceMemory*>& vec_gpuMem, vector<onelevel_det_result> &ol_det_result, algorithm_type_t algor_type);
87 89
  90 + void face_locus_finished(const OBJ_KEY obj_key);
  91 +
88 // 轨迹记录 92 // 轨迹记录
89 void trace_record(vector<DeviceMemory*>& vec_gpuMem, vector<onelevel_det_result>& vptResult); 93 void trace_record(vector<DeviceMemory*>& vec_gpuMem, vector<onelevel_det_result>& vptResult);
90 94
@@ -136,4 +140,6 @@ private: @@ -136,4 +140,6 @@ private:
136 GatherDetect m_human_region_gather; 140 GatherDetect m_human_region_gather;
137 GatherDetect m_vehicle_gather; 141 GatherDetect m_vehicle_gather;
138 142
  143 + face_det_ai_engine m_face_det_ai_engine; // 人脸检测
  144 +
139 }; 145 };
140 \ No newline at end of file 146 \ No newline at end of file
src/decoder/dvpp/VpcUtils.cpp 0 → 100644
  1 +#include "VpcUtils.h"
  2 +#include "depend_headers.h"
  3 +
  4 +#define ALIGN_UP(val, align) (((val) % (align) == 0) ? (val) : (((val) / (align) + 1) * (align)))
  5 +
  6 +#define CHECK_AND_RETURN(ret, message) \
  7 + if(ret != 0) {LOG_ERROR("{}", message); return ret;}
  8 +#define CHECK_NOT_RETURN(ret, message) \
  9 + if(ret != 0) {LOG_ERROR("{}", message);}
  10 +#define CHECK_AND_RETURN_NOVALUE(ret, message) \
  11 + if(ret != 0) {LOG_ERROR("{}", message); return;}
  12 +#define CHECK_AND_BREAK(ret, message) \
  13 + if(ret != 0) {LOG_ERROR("{}", message); break;}
  14 +
  15 +VpcUtils::VpcUtils(){
  16 +
  17 +}
  18 +
  19 +VpcUtils::~VpcUtils(){
  20 + release();
  21 +}
  22 +
  23 +int VpcUtils::init(int devId){
  24 +
  25 + m_devId = devId;
  26 +
  27 + aclError ret = aclrtCreateContext(&context_, m_devId);
  28 + if (ret != ACL_ERROR_NONE) {
  29 + LOG_ERROR("[{}]-aclrtCreateContext failed !", m_dec_name);
  30 + return false;
  31 + }
  32 +
  33 + do
  34 + {
  35 + dvppChannelDesc_ = acldvppCreateChannelDesc();
  36 +
  37 + ret = acldvppCreateChannel(dvppChannelDesc_);
  38 + CHECK_AND_BREAK(ret, "acldvppCreateChannel failed !");
  39 +
  40 + ret = acldvppSetChannelDescMode(dvppChannelDesc_, DVPP_CHNMODE_VPC);
  41 + CHECK_AND_BREAK(ret, "acldvppSetChannelDescMode failed !");
  42 + } while (0);
  43 +
  44 + return ret;
  45 +}
  46 +
  47 +void VpcUtils::release() {
  48 +
  49 + if(context_){
  50 + aclrtSetCurrentContext(context_);
  51 +
  52 + if (dvppChannelDesc_) {
  53 + (void)acldvppDestroyChannel(dvppChannelDesc_);
  54 + (void)acldvppDestroyChannelDesc(dvppChannelDesc_);
  55 + dvppChannelDesc_ = nullptr;
  56 + }
  57 +
  58 + aclrtDestroyContext(context_);
  59 + }
  60 +}
  61 +
  62 +DvppDataMemory* VpcUtils::convert2bgr(acldvppPicDesc *inputDesc_, int out_width, int out_height, bool key_frame){
  63 +
  64 + aclrtSetCurrentContext(context_);
  65 +
  66 + int out_buf_width = ALIGN_UP(out_width, 16) * 3;
  67 + int out_buf_height = ALIGN_UP(out_height, 2);
  68 + int out_buf_size = out_buf_width * out_buf_height;
  69 +
  70 + DvppDataMemory* rgbMem = new DvppDataMemory(3, out_buf_width, out_buf_width, out_buf_height, out_buf_height, out_buf_size, "", to_string(m_devId), key_frame, 0);
  71 + void *outBufferDev_ = (void*)rgbMem->getMem();
  72 +
  73 + acldvppPicDesc *outputDesc_= acldvppCreatePicDesc();
  74 + acldvppSetPicDescData(outputDesc_, outBufferDev_);
  75 + acldvppSetPicDescFormat(outputDesc_, PIXEL_FORMAT_BGR_888);
  76 + acldvppSetPicDescWidth(outputDesc_, out_width);
  77 + acldvppSetPicDescHeight(outputDesc_, out_height);
  78 + acldvppSetPicDescWidthStride(outputDesc_, out_buf_width);
  79 + acldvppSetPicDescHeightStride(outputDesc_, out_buf_height);
  80 + acldvppSetPicDescSize(outputDesc_, out_buf_size);
  81 +
  82 + aclError ret = ACL_ERROR_NONE;
  83 + aclrtStream stream_{nullptr};
  84 + aclrtCreateStream(&stream_);
  85 + do{
  86 + // 9. 执行异步色域转换,再调用aclrtSynchronizeStream接口阻塞程序运行,直到指定Stream中的所有任务都完成
  87 + ret = acldvppVpcConvertColorAsync(dvppChannelDesc_, inputDesc_, outputDesc_, stream_);
  88 + if(ret != ACL_ERROR_NONE){
  89 + LOG_ERROR("acldvppVpcConvertColorAsync failed - out_width:{} out_height:{} out_buf_width:{} out_buf_height:{} out_buf_size:{}", out_width, out_height, out_buf_width, out_buf_height, out_buf_size);
  90 + break;
  91 + }
  92 + ret = aclrtSynchronizeStream(stream_);
  93 + if(ret != ACL_ERROR_NONE){
  94 + LOG_ERROR("aclrtSynchronizeStream failed - out_width:{} out_height:{} out_buf_width:{} out_buf_height:{} out_buf_size:{}", out_width, out_height, out_buf_width, out_buf_height, out_buf_size);
  95 + break;
  96 + }
  97 + }while(0);
  98 +
  99 + if(nullptr != stream_){
  100 + aclrtDestroyStream(stream_);
  101 + stream_ = nullptr;
  102 + }
  103 +
  104 + acldvppDestroyPicDesc(outputDesc_);
  105 +
  106 + if(ret != ACL_ERROR_NONE){
  107 + delete rgbMem;
  108 + rgbMem = nullptr;
  109 + }
  110 +
  111 + return rgbMem;
  112 +}
  113 +
  114 +DvppDataMemory* VpcUtils::convert2bgr(DvppDataMemory* inMem){
  115 +
  116 + aclrtSetCurrentContext(context_);
  117 +
  118 + int out_width = inMem->getWidth();
  119 + int out_height = inMem->getHeight();
  120 +
  121 +
  122 + acldvppPicDesc *inputDesc_= acldvppCreatePicDesc();
  123 + acldvppSetPicDescData(inputDesc_, inMem->getMem());
  124 + acldvppSetPicDescFormat(inputDesc_, PIXEL_FORMAT_YUV_SEMIPLANAR_420);
  125 + acldvppSetPicDescWidth(inputDesc_, out_width);
  126 + acldvppSetPicDescHeight(inputDesc_, out_height);
  127 + acldvppSetPicDescWidthStride(inputDesc_, inMem->getWidthStride());
  128 + acldvppSetPicDescHeightStride(inputDesc_, inMem->getHeightStride());
  129 + acldvppSetPicDescSize(inputDesc_, inMem->getSize());
  130 +
  131 + int out_buf_width = ALIGN_UP(out_width, 16) * 3;
  132 + int out_buf_height = ALIGN_UP(out_height, 2);
  133 + int out_buf_size = out_buf_width * out_buf_height;
  134 +
  135 + DvppDataMemory* rgbMem = new DvppDataMemory(3, out_buf_width, out_buf_width, out_buf_height, out_buf_height, out_buf_size, inMem->getId(), inMem->getDeviceId(), false, inMem->getFrameNb());
  136 + void *outBufferDev_ = (void*)rgbMem->getMem();
  137 +
  138 + acldvppPicDesc *outputDesc_= acldvppCreatePicDesc();
  139 + acldvppSetPicDescData(outputDesc_, outBufferDev_);
  140 + acldvppSetPicDescFormat(outputDesc_, PIXEL_FORMAT_BGR_888);
  141 + acldvppSetPicDescWidth(outputDesc_, out_width);
  142 + acldvppSetPicDescHeight(outputDesc_, out_height);
  143 + acldvppSetPicDescWidthStride(outputDesc_, out_buf_width);
  144 + acldvppSetPicDescHeightStride(outputDesc_, out_buf_height);
  145 + acldvppSetPicDescSize(outputDesc_, out_buf_size);
  146 +
  147 + aclError ret = ACL_ERROR_NONE;
  148 + aclrtStream stream_{nullptr};
  149 + aclrtCreateStream(&stream_);
  150 + do{
  151 + // 9. 执行异步色域转换,再调用aclrtSynchronizeStream接口阻塞程序运行,直到指定Stream中的所有任务都完成
  152 + ret = acldvppVpcConvertColorAsync(dvppChannelDesc_, inputDesc_, outputDesc_, stream_);
  153 + if(ret != ACL_ERROR_NONE){
  154 + LOG_ERROR("acldvppVpcConvertColorAsync failed - out_width:{} out_height:{} out_buf_width:{} out_buf_height:{} out_buf_size:{}", out_width, out_height, out_buf_width, out_buf_height, out_buf_size);
  155 + break;
  156 + }
  157 + ret = aclrtSynchronizeStream(stream_);
  158 + if(ret != ACL_ERROR_NONE){
  159 + LOG_ERROR("aclrtSynchronizeStream failed - out_width:{} out_height:{} out_buf_width:{} out_buf_height:{} out_buf_size:{}", out_width, out_height, out_buf_width, out_buf_height, out_buf_size);
  160 + break;
  161 + }
  162 + }while(0);
  163 +
  164 + if(nullptr != stream_){
  165 + aclrtDestroyStream(stream_);
  166 + stream_ = nullptr;
  167 + }
  168 +
  169 + acldvppDestroyPicDesc(outputDesc_);
  170 + acldvppDestroyPicDesc(inputDesc_);
  171 +
  172 + if(ret != ACL_ERROR_NONE){
  173 + delete rgbMem;
  174 + rgbMem = nullptr;
  175 + }
  176 +
  177 + return rgbMem;
  178 +}
  179 +
  180 +DvppDataMemory* VpcUtils::resize(acldvppPicDesc *inputDesc_, int out_width, int out_height){
  181 +
  182 + aclrtSetCurrentContext(context_);
  183 +
  184 + int out_buf_width = ALIGN_UP(out_width, 16);
  185 + int out_buf_height = ALIGN_UP(out_height, 2);
  186 + int out_buf_size = out_buf_width * out_buf_height * 3 / 2;
  187 +
  188 + DvppDataMemory* rgbMem = new DvppDataMemory(1, out_width, out_buf_width, out_height, out_buf_height, out_buf_size, "", "", false, 0);
  189 + void *outBufferDev_ = (void*)rgbMem->getMem();
  190 +
  191 + acldvppPicDesc *outputDesc_= acldvppCreatePicDesc();
  192 + acldvppSetPicDescData(outputDesc_, outBufferDev_);
  193 + acldvppSetPicDescFormat(outputDesc_, acldvppGetPicDescFormat(inputDesc_));
  194 + acldvppSetPicDescWidth(outputDesc_, out_width);
  195 + acldvppSetPicDescHeight(outputDesc_, out_height);
  196 + acldvppSetPicDescWidthStride(outputDesc_, out_buf_width);
  197 + acldvppSetPicDescHeightStride(outputDesc_, out_buf_height);
  198 + acldvppSetPicDescSize(outputDesc_, out_buf_size);
  199 +
  200 + acldvppResizeConfig *resizeConfig_ = acldvppCreateResizeConfig();
  201 +
  202 + aclError ret = ACL_ERROR_NONE;
  203 + aclrtStream stream_{nullptr};
  204 + aclrtCreateStream(&stream_);
  205 + do{
  206 + // 9. 执行异步色域转换,再调用aclrtSynchronizeStream接口阻塞程序运行,直到指定Stream中的所有任务都完成
  207 + ret = acldvppVpcResizeAsync(dvppChannelDesc_, inputDesc_, outputDesc_, resizeConfig_, stream_);
  208 + if(ret != ACL_ERROR_NONE){
  209 + LOG_ERROR("acldvppVpcResizeAsync failed - out_width:{} out_height:{} out_buf_width:{} out_buf_height:{} out_buf_size:{}", out_width, out_height, out_buf_width, out_buf_height, out_buf_size);
  210 + break;
  211 + }
  212 + ret = aclrtSynchronizeStream(stream_);
  213 + if(ret != ACL_ERROR_NONE){
  214 + LOG_ERROR("aclrtSynchronizeStream failed - out_width:{} out_height:{} out_buf_width:{} out_buf_height:{} out_buf_size:{}", out_width, out_height, out_buf_width, out_buf_height, out_buf_size);
  215 + break;
  216 + }
  217 + }while(0);
  218 +
  219 + if(nullptr != stream_){
  220 + aclrtDestroyStream(stream_);
  221 + stream_ = nullptr;
  222 + }
  223 +
  224 + acldvppDestroyResizeConfig(resizeConfig_);
  225 + acldvppDestroyPicDesc(outputDesc_);
  226 +
  227 + if(ret != ACL_ERROR_NONE){
  228 + delete rgbMem;
  229 + rgbMem = nullptr;
  230 + }
  231 +
  232 + return rgbMem;
  233 +}
0 \ No newline at end of file 234 \ No newline at end of file
src/decoder/dvpp/VpcPicConverter.h renamed to src/decoder/dvpp/VpcUtils.h
@@ -3,18 +3,21 @@ @@ -3,18 +3,21 @@
3 #include "DvppDataMemory.hpp" 3 #include "DvppDataMemory.hpp"
4 4
5 5
6 -class VpcPicConverter{ 6 +class VpcUtils{
7 public: 7 public:
8 - VpcPicConverter();  
9 - ~VpcPicConverter();  
10 - int init(aclrtContext context, string dec_name); 8 + VpcUtils();
  9 + ~VpcUtils();
  10 + int init(int);
11 11
12 DvppDataMemory* convert2bgr(acldvppPicDesc *input, int out_width, int out_height, bool key_frame); 12 DvppDataMemory* convert2bgr(acldvppPicDesc *input, int out_width, int out_height, bool key_frame);
  13 + DvppDataMemory* convert2bgr(DvppDataMemory* inMem);
13 14
  15 + DvppDataMemory* resize(acldvppPicDesc *inputDesc_, int out_width, int out_height);
14 private: 16 private:
15 - aclrtContext context_;  
16 - aclrtStream stream_; 17 + void release();
  18 +private:
  19 + aclrtContext context_{nullptr};
17 int m_devId; 20 int m_devId;
18 - acldvppChannelDesc *dvppChannelDesc_ ; 21 + acldvppChannelDesc *dvppChannelDesc_ {nullptr};
19 string m_dec_name; 22 string m_dec_name;
20 }; 23 };
21 \ No newline at end of file 24 \ No newline at end of file
src/helpers/img_util.cpp 0 → 100644
  1 +#include "img_util.h"
  2 +#include "opencv2/opencv.hpp"
  3 +
  4 +namespace common {
  5 +
  6 +bool isInPolygon(const sy_point* point_array, int point_count, const sy_point& center) {
  7 +
  8 + std::vector<cv::Point> polygon;
  9 + for (size_t i = 0; i < point_count; i++)
  10 + {
  11 + polygon.push_back(cv::Point(point_array[i].x_, point_array[i].y_));
  12 + }
  13 +
  14 + if (polygon.size() <= 0)
  15 + {
  16 + return false;
  17 + }
  18 +
  19 + // 定义一个点
  20 + cv::Point pt(center.x_, center.y_);
  21 +
  22 + // 使用pointPolygonTest函数判断点是否在多边形内
  23 + double sign = cv::pointPolygonTest(polygon, pt, false);
  24 + if (sign > 0)
  25 + {
  26 + return true;
  27 + }
  28 +
  29 + return false;
  30 +}
  31 +
  32 +void save_result(int height, int width, sy_point* point_array, int point_count, std::vector<sy_point> vec_pt) {
  33 + cv::Mat image = cv::Mat::zeros(height, width, CV_8UC3);
  34 +
  35 + // 定义一个多边形的顶点数组(例如一个五边形)
  36 + std::vector<cv::Point> polyPoints;
  37 + for (size_t i = 0; i < point_count; i++)
  38 + {
  39 + polyPoints.push_back(cv::Point(point_array[i].x_, point_array[i].y_));
  40 + }
  41 +
  42 + // 绘制多边形边界,颜色为绿色,线宽 2
  43 + const cv::Point* pts = &polyPoints[0];
  44 + int npts = (int)polyPoints.size();
  45 + cv::polylines(image, &pts, &npts, 1, true, cv::Scalar(0, 255, 0), 2);
  46 +
  47 + for (size_t i = 0; i < vec_pt.size(); i++)
  48 + {
  49 + cv::circle(image, cv::Point(vec_pt[i].x_, vec_pt[i].y_), 2, cv::Scalar(0, 255, 255), -1);
  50 + }
  51 +
  52 + cv::imwrite("gahter.jpg", image);
  53 +
  54 +}
  55 +
  56 +}
0 \ No newline at end of file 57 \ No newline at end of file
src/helpers/img_util.h 0 → 100644
  1 +#ifndef __HELPERS_IMG_TUIL_H__
  2 +#define __HELPERS_IMG_TUIL_H__
  3 +
  4 +
  5 +#include "../common/sy_common.h"
  6 +#include <vector>
  7 +
  8 +namespace common {
  9 +
  10 +bool isInPolygon(const sy_point* point_array, int point_count, const sy_point& center);
  11 +
  12 +void save_result(int height, int width, sy_point* point_array, int point_count, std::vector<sy_point> vec_pt);
  13 +}
  14 +
  15 +#endif
0 \ No newline at end of file 16 \ No newline at end of file
src/reprocessing_module/mq_manager.cpp 0 → 100755
  1 +/*
  2 + * @Author: yangzilong
  3 + * @Date: 2021-12-15 15:00:28
  4 + * @Last Modified by: yangzilong
  5 + * @Email: yangzilong@objecteye.com
  6 + * @Description:
  7 + */
  8 +
  9 +#include "./mq_manager.hpp"
  10 +#include "../common/logger.hpp"
  11 +
  12 +
  13 +#ifdef POST_USE_RABBITMQ
  14 +
  15 +namespace mq
  16 +{
  17 +
  18 + Manager::Manager()
  19 + {
  20 +
  21 + };
  22 +
  23 + bool Manager::add_conn(const key_t &key, const value_param_t& value_param)
  24 + {
  25 + if (task_status_to_mq_handle_.find(key) != task_status_to_mq_handle_.end())
  26 + return false;
  27 + std::shared_ptr<value_t> value = std::make_shared<value_t>();
  28 + if (!value->init(value_param))
  29 + return false;
  30 +
  31 + task_status_to_mq_handle_[key] = value;
  32 + return true;
  33 + }
  34 +
  35 + bool Manager::del_conn(const key_t &key)
  36 + {
  37 + if (task_status_to_mq_handle_.find(key) == task_status_to_mq_handle_.end())
  38 + return false;
  39 + task_status_to_mq_handle_.erase(key);
  40 + return true;
  41 + }
  42 +
  43 + bool Manager::publish(const key_t &key, const char *msg, bool verbose)
  44 + {
  45 + if (task_status_to_mq_handle_.find(key) == task_status_to_mq_handle_.end())
  46 + return false;
  47 +
  48 + bool status;
  49 + if (!(status = task_status_to_mq_handle_[key]->sync_publish(msg)))
  50 + LOG_ERROR("rbMQ publish failed:{}", msg);
  51 + else
  52 + if (verbose)
  53 + LOG_DEBUG("rbMQ publish successful:{}", msg);
  54 + return status;
  55 + }
  56 +
  57 +}
  58 +
  59 +
  60 +#endif // #ifdef POST_USE_RABBITMQ
0 \ No newline at end of file 61 \ No newline at end of file
src/reprocessing_module/mq_manager.hpp 0 → 100755
  1 +/*
  2 + * @Author: yangzilong
  3 + * @Date: 2021-12-15 14:52:35
  4 + * @Last Modified by: yangzilong
  5 + * @Email: yangzilong@objecteye.com
  6 + * @Description:
  7 + */
  8 +
  9 +#pragma once
  10 +
  11 +#include "./post_reprocessing.hpp"
  12 +#include <map>
  13 +#include <memory>
  14 +
  15 +#ifdef POST_USE_RABBITMQ
  16 +
  17 +namespace mq
  18 +{
  19 + typedef mq_type_t key_t;
  20 + typedef post_rabbitmq_reprocessing value_t;
  21 + typedef rabbitmq_conn_params_t value_param_t;
  22 +
  23 + class Manager
  24 + {
  25 + /**
  26 + * @brief is not thread safe.
  27 + *
  28 + */
  29 + public:
  30 +
  31 + Manager();
  32 +
  33 + bool add_conn(const key_t &key, const value_param_t& value_param);
  34 +
  35 + bool del_conn(const key_t &key);
  36 +
  37 + bool publish(const key_t &key, const char *msg, bool verbose = false);
  38 +
  39 + /* remove copy construct and copy assignment. */
  40 + Manager(const Manager &) = delete;
  41 + Manager& operator=(const Manager &) = delete;
  42 +
  43 + private:
  44 + std::map<key_t, std::shared_ptr<value_t>> task_status_to_mq_handle_;
  45 +
  46 + };
  47 +} // namespace mq
  48 +
  49 +#endif // #ifdef POST_USE_RABBITMQ
src/reprocessing_module/post_reprocessing.cpp 0 → 100755
  1 +#include "post_reprocessing.hpp"
  2 +#include "../common/logger.hpp"
  3 +
  4 +#ifdef POST_USE_RABBITMQ
  5 +
  6 +
  7 +namespace mq
  8 +{
  9 +
  10 + post_rabbitmq_reprocessing::post_rabbitmq_reprocessing()
  11 + : rabbitmq_handle_(nullptr)
  12 + {
  13 +#ifdef _RBMQ_ASYNC_INTERFACE
  14 + is_run_.store(true);
  15 + run_thread_ = std::thread(std::bind(&post_rabbitmq_reprocessing::run, this));
  16 +#endif
  17 + }
  18 +
  19 + post_rabbitmq_reprocessing::~post_rabbitmq_reprocessing()
  20 + {
  21 +#ifdef _RBMQ_ASYNC_INTERFACE
  22 + is_run_.store(false);
  23 +
  24 + if (run_thread_.joinable())
  25 + run_thread_.join();
  26 +#endif
  27 + if (rabbitmq_handle_ != nullptr)
  28 + rabbitmq_handle_->Disconnect();
  29 + }
  30 +
  31 + post_rabbitmq_reprocessing::post_rabbitmq_reprocessing(post_rabbitmq_reprocessing &&other)
  32 + : params_(std::move(other.params_))
  33 + , rabbitmq_handle_(std::move(other.rabbitmq_handle_))
  34 + {
  35 +
  36 + }
  37 +
  38 + post_rabbitmq_reprocessing& post_rabbitmq_reprocessing::operator=(post_rabbitmq_reprocessing &&other)
  39 + {
  40 + if (this == &other)
  41 + return *this;
  42 +
  43 + this->params_ = std::move(other.params_);
  44 + this->rabbitmq_handle_ = std::move(other.rabbitmq_handle_);
  45 + return *this;
  46 + }
  47 +
  48 + bool post_rabbitmq_reprocessing::init(const rabbitmq_conn_params_t &params)
  49 + {
  50 + rabbitmq_handle_.reset(CRabbitmqClient::get_instance());
  51 + /* connection rabbitMQ. */
  52 + {
  53 + int ret = -1;
  54 + if (0 != (ret = rabbitmq_handle_->Connect(params.ip, params.port, params.uname, params.passwd, params.vhost)))
  55 + {
  56 + LOG_ERROR("RabbitMQ Connection {}:{} failed error code is {}!!!", params.ip, params.port, ret);
  57 + return false;
  58 + }
  59 +
  60 + if (0 != (ret = rabbitmq_handle_->ExchangeDeclare(params.exchange, params.exchange_type, params.durable_exchange)))
  61 + {
  62 + LOG_ERROR("RabbitMQ Declare Exchange {} failed error code is {}!!!", params.exchange, ret);
  63 + return false;
  64 + }
  65 +
  66 + if (0 != (ret = rabbitmq_handle_->QueueDeclare(params.queue, params.durable_queue)))
  67 + {
  68 + LOG_ERROR("RabbitMQ Declare Queue {} failed error code is {}!!!", params.queue, ret);
  69 + return false;
  70 + }
  71 +
  72 + if (0 != (ret = rabbitmq_handle_->QueueBind(params.queue, params.exchange, params.routing_key)))
  73 + {
  74 + LOG_ERROR("RabbitMQ Queue Bind failed queue is {} exchange is {} route key is {} error code is {}!!!", params.queue, params.exchange, params.routing_key, ret);
  75 + return false;
  76 + }
  77 + }
  78 +
  79 + {
  80 + params_ = params;
  81 + }
  82 +
  83 + return true;
  84 + }
  85 +
  86 + bool post_rabbitmq_reprocessing::sync_publish(const std::string &msg)
  87 + {
  88 + if (nullptr == rabbitmq_handle_)
  89 + {
  90 + LOG_ERROR("call Init before please !!!");
  91 + return false;
  92 + }
  93 + std::lock_guard<std::mutex> lk(run_mutex_);
  94 + return rabbitmq_handle_->Publish(msg, params_.exchange, params_.routing_key) == 0;
  95 + }
  96 +
  97 +#ifdef _RBMQ_ASYNC_INTERFACE
  98 + bool post_rabbitmq_reprocessing::async_publish(const std::string &msg)
  99 + {
  100 + if (nullptr == rabbitmq_handle_)
  101 + {
  102 + LOG_ERROR("call Init before please !!!");
  103 + return false;
  104 + }
  105 + std::lock_guard<std::mutex> lk(run_mutex_);
  106 + message_buffer_.push(msg);
  107 + run_cv_.notify_one();
  108 + return true;
  109 + }
  110 +
  111 +
  112 + void post_rabbitmq_reprocessing::run()
  113 + {
  114 + while (is_run_.load())
  115 + {
  116 + std::unique_lock<std::mutex> lk(run_mutex_);
  117 + run_cv_.wait(lk,
  118 + [this] { return !this->message_buffer_.empty(); });
  119 + std::string msg = message_buffer_.front();
  120 + message_buffer_.pop();
  121 +
  122 + if (rabbitmq_handle_->Publish(msg, params_.exchange, params_.routing_key) != 0)
  123 + LOG_ERROR("Publish {} failed!", msg);
  124 + else
  125 + LOG_INFO("Publish {} successful!", msg);
  126 + }
  127 + }
  128 +#endif
  129 +
  130 +}
  131 +
  132 +#endif // #ifdef POST_USE_RABBITMQ
  133 +
  134 +
src/reprocessing_module/post_reprocessing.hpp 0 → 100755
  1 +/*
  2 + * @Author: yangzilong
  3 + * @Last Modified by: yangzilong
  4 + * @Date: 2021-11-24 19:05:28
  5 + * @Email: yangzilong@objecteye.com
  6 + * @Description:
  7 + */
  8 +#pragma once
  9 +
  10 +#include "../ai_platform/header.h"
  11 +
  12 +#ifdef POST_USE_RABBITMQ
  13 +
  14 +#include "json/json.h"
  15 +#include <string.h>
  16 +
  17 +#include <mutex>
  18 +#include <memory>
  19 +
  20 +#ifdef _RBMQ_ASYNC_INTERFACE
  21 +#include <queue>
  22 +#include <atomic>
  23 +#include <thread>
  24 +#include <condition_variable>
  25 +#endif
  26 +
  27 +#include "spdlog/spdlog.h"
  28 +#include "./rbmq/RabbitmqClient.hpp"
  29 +
  30 +namespace mq
  31 +{
  32 +
  33 + class post_rabbitmq_reprocessing
  34 + {
  35 + /**
  36 + * @brief
  37 + * 1. move able only.
  38 + * 2. thread safe class.
  39 + * 3. support async api.
  40 + * */
  41 + public:
  42 + post_rabbitmq_reprocessing();
  43 + ~post_rabbitmq_reprocessing();
  44 +
  45 + bool init(const rabbitmq_conn_params_t &params);
  46 + bool sync_publish(const std::string &msg);
  47 +#ifdef _RBMQ_ASYNC_INTERFACE
  48 + bool async_publish(const std::string &msg);
  49 +#endif
  50 +
  51 + post_rabbitmq_reprocessing(post_rabbitmq_reprocessing &&other);
  52 + post_rabbitmq_reprocessing& operator=(post_rabbitmq_reprocessing &&other);
  53 +
  54 + /* remove copy construct and copy assignment. */
  55 + post_rabbitmq_reprocessing(const post_rabbitmq_reprocessing &) = delete;
  56 + post_rabbitmq_reprocessing& operator=(const post_rabbitmq_reprocessing &) = delete;
  57 +
  58 + private:
  59 +#ifdef _RBMQ_ASYNC_INTERFACE
  60 + void run();
  61 + std::thread run_thread_;
  62 + std::atomic_bool is_run_;
  63 + std::condition_variable run_cv_;
  64 + std::queue<std::string> message_buffer_;
  65 +#endif
  66 + std::mutex run_mutex_;
  67 + rabbitmq_conn_params_t params_;
  68 + std::shared_ptr<CRabbitmqClient> rabbitmq_handle_;
  69 + };
  70 +
  71 +}
  72 +#endif // #ifdef POST_USE_RABBITMQ
  73 +
  74 +
  75 +
src/reprocessing_module/rbmq/RabbitmqClient.hpp 0 → 100755
  1 +#pragma once
  2 +
  3 +#include <string>
  4 +#include <memory>
  5 +#include <vector>
  6 +
  7 +typedef void (*RABBITMQ_CALLBACK)(void* contex, const char * msg);
  8 +
  9 +class CRabbitmqClient
  10 +{
  11 +/**
  12 + * @brief not single instance;
  13 + *
  14 + */
  15 +public:
  16 + static CRabbitmqClient* get_instance();
  17 + static void destory(CRabbitmqClient *instance);
  18 +
  19 +
  20 + virtual int Connect(const std::string &strHostname, int iPort, const std::string &strUser, const std::string &strPasswd, const std::string &vhost = "/") = 0;
  21 +
  22 + /**
  23 + * @brief Disconnect 关闭连接
  24 + *
  25 + * @return int 等于0值成功, 小于0代表错误
  26 + */
  27 + virtual int Disconnect() = 0;
  28 +
  29 + /**
  30 + * @brief ExchangeDeclare 声明exchange
  31 + * @param [in] strExchange
  32 + * @param [in] strType
  33 + * @return 等于0值代表成功创建exchange,小于0代表错误
  34 + */
  35 + virtual int ExchangeDeclare(const std::string &strExchange, const std::string &strType, const bool durable = false) = 0;
  36 +
  37 + /**
  38 + * @brief QueueDeclare 声明消息队列
  39 + * @param [in] strQueueName 消息队列实例
  40 + * @param
  41 + * @return 等于0值代表成功创建queue,小于0代表错误
  42 + */
  43 + virtual int QueueDeclare(const std::string &strQueueName, const bool durable = false) = 0;
  44 +
  45 + /**
  46 + * @brief QueueBind 将队列,交换机和绑定规则绑定起来形成一个路由表
  47 + * @param [in] strQueueName 消息队列
  48 + * @param [in] strExchange 交换机名称
  49 + * @param [in] strBindKey 路由名称 “msg.#” “msg.weather.**”
  50 + * @return 等于0值代表成功绑定,小于0代表错误
  51 + */
  52 + virtual int QueueBind(const std::string &strQueueName, const std::string &strExchange, const std::string &strBindKey) = 0;
  53 +
  54 + /**
  55 + * @brief QueueUnbind 将队列,交换机和绑定规则绑定解除
  56 + * @param [in] strQueueName 消息队列
  57 + * @param [in] strExchange 交换机名称
  58 + * @param [in] strBindKey 路由名称 “msg.#” “msg.weather.**”
  59 + * @return 等于0值代表成功绑定,小于0代表错误
  60 + */
  61 + virtual int QueueUnbind(const std::string &strQueueName, const std::string &strExchange, const std::string &strBindKey) = 0;
  62 +
  63 + /**
  64 + * @brief QueueDelete 删除消息队列。
  65 + * @param [in] strQueueName 消息队列名称
  66 + * @param [in] iIfUnused 消息队列是否在用,1 则论是否在用都删除
  67 + * @return 等于0值代表成功删除queue,小于0代表错误
  68 + */
  69 + virtual int QueueDelete(const std::string &strQueueName, int iIfUnused) = 0;
  70 +
  71 + /**
  72 + * @brief Publish 发布消息
  73 + * @param [in] strMessage 消息实体
  74 + * @param [in] strExchange 交换器
  75 + * @param [in] strRoutekey 路由规则
  76 + * 1.Direct Exchange – 处理路由键。需要将一个队列绑定到交换机上,要求该消息与一个特定的路由键完全匹配。
  77 + * 2.Fanout Exchange – 不处理路由键。将队列绑定到交换机上。一个发送到交换机的消息都会被转发到与该交换机绑定的所有队列上。
  78 + * 3.Topic Exchange – 将路由键和某模式进行匹配。此时队列需要绑定要一个模式上。符号“#”匹配一个或多个词,符号“*”匹配不多不少一个词。
  79 + * 因此“audit.#”能够匹配到“audit.irs.corporate”,但是“audit.*” 只会匹配到“audit.irs”
  80 + * @return 等于0值代表成功发送消息实体,小于0代表发送错误
  81 + */
  82 + virtual int Publish(const std::string &strMessage, const std::string &strExchange, const std::string &strRoutekey) = 0;
  83 +
  84 + /**
  85 + * @brief consumer 消费消息
  86 + * @param [in] strQueueName 队列名称
  87 + * @param [out] message_array 获取的消息实体
  88 + * @param [int] GetNum 需要取得的消息个数
  89 + * @param [int] timeout 取得的消息是延迟,若为NULL,表示持续取,无延迟,阻塞状态
  90 + * @return 等于0值代表成功,小于0代表错误,错误信息从ErrorReturn返回
  91 + */
  92 + virtual int Consumer_limit(const std::string &strQueueName, std::vector<std::string> &message_array, int GetNum = 1, struct timeval *timeout = NULL) = 0;
  93 +
  94 + /**
  95 + * @brief consumer 消费消息
  96 + * @param [in] strQueueName 队列名称
  97 + * @param [out] message_array 获取的消息实体
  98 + * @param [int] GetNum 需要取得的消息个数
  99 + * @param [int] timeout 取得的消息是延迟,若为NULL,表示持续取,无延迟,阻塞状态
  100 + * @return 等于0值代表成功,小于0代表错误,错误信息从ErrorReturn返回
  101 + */
  102 + virtual int Consumer(const std::string &strQueueName, RABBITMQ_CALLBACK callback, void * contex, struct timeval *timeout = NULL) = 0;
  103 +
  104 +
  105 +
  106 +};
  107 +
src/reprocessing_module/rbmq/RabbitmqClientImpl.cpp 0 → 100755
  1 +#include "RabbitmqClientImpl.hpp"
  2 +#include <unistd.h>
  3 +
  4 +
  5 +CRabbitmqClientImpl::CRabbitmqClientImpl()
  6 +: m_strHostname("")
  7 +, m_iPort(0)
  8 +, m_strUser("")
  9 +, m_strPasswd("")
  10 +, m_iChannel(1) //默认用1号通道,通道无所谓
  11 +, m_pSock(NULL)
  12 +, m_pConn(NULL)
  13 +, m_max_reconnection(5)
  14 +{
  15 +
  16 +}
  17 +
  18 +CRabbitmqClientImpl::~CRabbitmqClientImpl()
  19 +{
  20 + if (NULL != m_pConn) {
  21 + Disconnect();
  22 + m_pConn = NULL;
  23 + }
  24 +}
  25 +
  26 +int CRabbitmqClientImpl::Connect(const string &strHostname, int iPort, const string &strUser, const string &strPasswd, const string &vhost)
  27 +{
  28 + m_strHostname = strHostname;
  29 + m_iPort = iPort;
  30 + m_strUser = strUser;
  31 + m_strPasswd = strPasswd;
  32 + m_strVHost = vhost;
  33 +
  34 + m_pConn = amqp_new_connection();
  35 + if (NULL == m_pConn)
  36 + {
  37 + spdlog::error("amqp new connection failed");
  38 + return -1;
  39 + }
  40 +
  41 + m_pSock = amqp_tcp_socket_new(m_pConn);
  42 + if (NULL == m_pSock)
  43 + {
  44 + spdlog::error("amqp tcp new socket failed");
  45 + return -2;
  46 + }
  47 +
  48 + if (0 > amqp_socket_open(m_pSock, m_strHostname.c_str(), m_iPort))
  49 + {
  50 + spdlog::error("amqp socket open failed");
  51 + return -3;
  52 + }
  53 +
  54 + error_code_t err = ErrorMsg(amqp_login(m_pConn, m_strVHost.c_str(), 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, m_strUser.c_str(), m_strPasswd.c_str()), "Logging in");
  55 + if (error_code_t::NORMAL != err)
  56 + return -4;
  57 +
  58 + return 0;
  59 +}
  60 +
  61 +int CRabbitmqClientImpl::Disconnect() {
  62 + if (NULL != m_pConn)
  63 + {
  64 +
  65 + if (error_code_t::NORMAL != ErrorMsg(amqp_connection_close(m_pConn, AMQP_REPLY_SUCCESS), "Closing connection"))
  66 + return -1;
  67 +
  68 + int ret_code = 0;
  69 + if (0 > (ret_code = amqp_destroy_connection(m_pConn)))
  70 + {
  71 + fprintf(stderr, "%s: %s\n", "destory connection", amqp_error_string2(ret_code));
  72 + return -2;
  73 + }
  74 + m_pConn = NULL;
  75 + }
  76 +
  77 + return 0;
  78 +}
  79 +
  80 +error_code_t CRabbitmqClientImpl::Reconnection()
  81 +{
  82 + Disconnect();
  83 + Connect(m_strHostname, m_iPort, m_strUser, m_strPasswd, m_strVHost);
  84 +}
  85 +
  86 +
  87 +int CRabbitmqClientImpl::ExchangeDeclare(const string &strExchange, const string &strType, const bool durable)
  88 +{
  89 + amqp_channel_open(m_pConn, m_iChannel);
  90 +
  91 + amqp_bytes_t _exchange = amqp_cstring_bytes(strExchange.c_str());
  92 + amqp_bytes_t _type = amqp_cstring_bytes(strType.c_str());
  93 + int _passive= 0;
  94 + amqp_exchange_declare(m_pConn, m_iChannel, _exchange, _type, _passive, durable, 0, 0, amqp_empty_table);
  95 + if (error_code_t::NORMAL != ErrorMsg(amqp_get_rpc_reply(m_pConn), "exchange_declare")) {
  96 + amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
  97 + return -1;
  98 + }
  99 +
  100 + amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
  101 + return 0;
  102 +}
  103 +
  104 +int CRabbitmqClientImpl::QueueDeclare(const string &strQueueName, const bool durable) {
  105 + if(NULL == m_pConn) {
  106 + spdlog::error("QueueDeclare m_pConn is null");
  107 + return -1;
  108 + }
  109 +
  110 + amqp_channel_open(m_pConn, m_iChannel);
  111 + amqp_bytes_t _queue = amqp_cstring_bytes(strQueueName.c_str());
  112 + int32_t _passive = 0;
  113 + // int32_t _durable = 0;
  114 + int32_t _exclusive = 0;
  115 + //int32_t _auto_delete = 1;
  116 + int32_t _auto_delete = 0;
  117 + amqp_queue_declare(m_pConn, m_iChannel, _queue, _passive, durable, _exclusive, _auto_delete, amqp_empty_table);
  118 + if (error_code_t::NORMAL != ErrorMsg(amqp_get_rpc_reply(m_pConn), "queue_declare")) {
  119 + amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
  120 + return -1;
  121 + }
  122 +
  123 + amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
  124 + return 0;
  125 +}
  126 +
  127 +int CRabbitmqClientImpl::QueueBind(const string &strQueueName, const string &strExchange, const string &strBindKey) {
  128 + if(NULL == m_pConn) {
  129 + spdlog::error("QueueBind m_pConn is null");
  130 + return -1;
  131 + }
  132 +
  133 + amqp_channel_open(m_pConn, m_iChannel);
  134 + amqp_bytes_t _queue = amqp_cstring_bytes(strQueueName.c_str());
  135 + amqp_bytes_t _exchange = amqp_cstring_bytes(strExchange.c_str());
  136 + amqp_bytes_t _routkey = amqp_cstring_bytes(strBindKey.c_str());
  137 + amqp_queue_bind(m_pConn, m_iChannel, _queue, _exchange, _routkey, amqp_empty_table);
  138 + if(error_code_t::NORMAL != ErrorMsg(amqp_get_rpc_reply(m_pConn), "queue_bind")) {
  139 + amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
  140 + return -1;
  141 + }
  142 +
  143 + amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
  144 + return 0;
  145 +}
  146 +
  147 +int CRabbitmqClientImpl::QueueUnbind(const string &strQueueName, const string &strExchange, const string &strBindKey) {
  148 + if(NULL == m_pConn) {
  149 + spdlog::error("QueueUnbind m_pConn is null");
  150 + return -1;
  151 + }
  152 +
  153 + amqp_channel_open(m_pConn, m_iChannel);
  154 + amqp_bytes_t _queue = amqp_cstring_bytes(strQueueName.c_str());
  155 + amqp_bytes_t _exchange = amqp_cstring_bytes(strExchange.c_str());
  156 + amqp_bytes_t _routkey = amqp_cstring_bytes(strBindKey.c_str());
  157 + amqp_queue_unbind(m_pConn, m_iChannel, _queue, _exchange, _routkey, amqp_empty_table);
  158 + if(error_code_t::NORMAL != ErrorMsg(amqp_get_rpc_reply(m_pConn), "queue_unbind")) {
  159 + amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
  160 + return -1;
  161 + }
  162 +
  163 + amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
  164 + return 0;
  165 +}
  166 +
  167 +int CRabbitmqClientImpl::QueueDelete(const string &strQueueName, int iIfUnused) {
  168 + if(NULL == m_pConn) {
  169 + spdlog::error("QueueDelete m_pConn is null");
  170 + return -1;
  171 + }
  172 +
  173 + amqp_channel_open(m_pConn, m_iChannel);
  174 + if(error_code_t::NORMAL != ErrorMsg(amqp_get_rpc_reply(m_pConn), "open channel")) {
  175 + amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
  176 + return -2;
  177 + }
  178 +
  179 + amqp_queue_delete(m_pConn, m_iChannel, amqp_cstring_bytes(strQueueName.c_str()), iIfUnused, 0);
  180 + if(error_code_t::NORMAL != ErrorMsg(amqp_get_rpc_reply(m_pConn), "delete queue")) {
  181 + amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
  182 + return -3;
  183 + }
  184 +
  185 + amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
  186 + return 0;
  187 +}
  188 +
  189 +int CRabbitmqClientImpl::Publish(const string &strMessage, const string &strExchange, const string &strRoutekey) {
  190 + if (NULL == m_pConn)
  191 + {
  192 + spdlog::error("publish m_pConn is null, publish failed");
  193 + return -1;
  194 + }
  195 +
  196 +#if 1
  197 + for (int i = 0; i < m_max_reconnection; ++i)
  198 + {
  199 + amqp_channel_open(m_pConn, m_iChannel);
  200 + if (error_code_t::NORMAL == ErrorMsg(amqp_get_rpc_reply(m_pConn), "publish open channel"))
  201 + goto _continue;
  202 + spdlog::error("Publish try {:d} reconnection", i+1);
  203 + amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
  204 + Reconnection();
  205 + }
  206 + return -2;
  207 +_continue:
  208 +#else
  209 +
  210 + amqp_channel_open(m_pConn, m_iChannel);
  211 + if (error_code_t::NORMAL != ErrorMsg(amqp_get_rpc_reply(m_pConn), "publish open channel"))
  212 + {
  213 + amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
  214 + return -2;
  215 + }
  216 +
  217 +#endif
  218 + amqp_bytes_t message_bytes;
  219 + message_bytes.len = strMessage.length();
  220 + message_bytes.bytes = (void *)(strMessage.c_str());
  221 +
  222 + /*
  223 + amqp_basic_properties_t props;
  224 + props._flags = AMQP_BASIC_CONTENT_TYPE_FLAG | AMQP_BASIC_DELIVERY_MODE_FLAG;
  225 + props.content_type = amqp_cstring_bytes(m_type.c_str());
  226 + props.delivery_mode = m_durable; // persistent delivery mode
  227 + */
  228 +
  229 + amqp_bytes_t exchange = amqp_cstring_bytes(strExchange.c_str());
  230 + amqp_bytes_t routekey = amqp_cstring_bytes(strRoutekey.c_str());
  231 +
  232 +
  233 + if (0 != amqp_basic_publish(m_pConn, m_iChannel, exchange, routekey, 0, 0, NULL, message_bytes))
  234 + {
  235 + spdlog::error("publish amqp_basic_publish failed");
  236 + if (error_code_t::NORMAL != ErrorMsg(amqp_get_rpc_reply(m_pConn), "amqp_basic_publish")) {
  237 + amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
  238 + return -3;
  239 + }
  240 + }
  241 +
  242 + amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
  243 + return 0;
  244 +}
  245 +
  246 +int CRabbitmqClientImpl::Consumer(const string &strQueueName, RABBITMQ_CALLBACK callback, void *contex, struct timeval *timeout)
  247 +{
  248 + if (NULL == m_pConn)
  249 + {
  250 + spdlog::error("Consumer m_pConn is null, Consumer failed");
  251 + return -1;
  252 + }
  253 +
  254 +#if 0
  255 + for (int i = 0; i < m_max_connection; ++i)
  256 + {
  257 + amqp_channel_open(m_pConn, m_iChannel);
  258 + if (0 == ErrorMsg(amqp_get_rpc_reply(m_pConn), "consumer open channel"))
  259 + goto _continue;
  260 + spdlog::error("Consumer try {:d} reconnection", i+1);
  261 + amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
  262 + Disconnect();
  263 + Connect(m_strHostname, m_iPort, m_strUser, m_strPasswd, m_strVHost);
  264 + }
  265 +
  266 + return -2;
  267 +
  268 +
  269 +_continue:
  270 +
  271 +#else
  272 +
  273 + amqp_channel_open(m_pConn, m_iChannel);
  274 + if (error_code_t::NORMAL != ErrorMsg(amqp_get_rpc_reply(m_pConn), "Consumer open channel"))
  275 + {
  276 + amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
  277 + return -2;
  278 + }
  279 +
  280 +#endif
  281 +
  282 + int GetNum = 1;
  283 + amqp_basic_qos(m_pConn, m_iChannel, 0, GetNum, 0);
  284 + int ack = 1; // no_ack 是否需要确认消息后再从队列中删除消息
  285 + amqp_bytes_t queuename= amqp_cstring_bytes(strQueueName.c_str());
  286 + amqp_basic_consume(m_pConn, m_iChannel, queuename, amqp_empty_bytes, 0, ack, 0, amqp_empty_table);
  287 +
  288 + if (error_code_t::NORMAL != ErrorMsg(amqp_get_rpc_reply(m_pConn), "Consuming")) {
  289 + amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
  290 + return -3;
  291 + }
  292 +
  293 + int hasget = 0;
  294 + amqp_rpc_reply_t res;
  295 + amqp_envelope_t envelope;
  296 +
  297 + while (1)
  298 + {
  299 + amqp_maybe_release_buffers(m_pConn);
  300 + res = amqp_consume_message(m_pConn, &envelope, timeout, 0);
  301 + if (AMQP_RESPONSE_NORMAL != res.reply_type) {
  302 +
  303 + spdlog::error("Consumer amqp_channel_close failed then continue");
  304 +#if 1
  305 + amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
  306 + if (0 == hasget)
  307 + return -res.reply_type;
  308 + else
  309 + return 0;
  310 +#endif
  311 + }
  312 +
  313 + char *temp = new char[envelope.message.body.len + 1]();
  314 + memcpy(temp, (char *)envelope.message.body.bytes, sizeof(char)*envelope.message.body.len);
  315 + amqp_destroy_envelope(&envelope);
  316 + callback(contex, temp);
  317 + hasget++;
  318 + usleep(1);
  319 + }
  320 +
  321 + return 0;
  322 +}
  323 +
  324 +
  325 +int CRabbitmqClientImpl::Consumer_limit(const string &strQueueName, vector<string> &message_array, int GetNum, struct timeval *timeout)
  326 +{
  327 + if (NULL == m_pConn) {
  328 + spdlog::error("Consumer m_pConn is null, Consumer failed");
  329 + return -1;
  330 + }
  331 +
  332 +#if 0
  333 + for (int i = 0; i < m_max_connection; ++i)
  334 + {
  335 + amqp_channel_open(m_pConn, m_iChannel);
  336 + if (0 == ErrorMsg(amqp_get_rpc_reply(m_pConn), "consumer open channel"))
  337 + goto _continue;
  338 + spdlog::error("Consumer_limit try {:d} reconnection", i+1);
  339 + amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
  340 + Disconnect();
  341 + Connect(m_strHostname, m_iPort, m_strUser, m_strPasswd, m_strVHost);
  342 + }
  343 +
  344 + return -2;
  345 +
  346 +
  347 +_continue:
  348 +
  349 +#else
  350 +
  351 + amqp_channel_open(m_pConn, m_iChannel);
  352 + if (error_code_t::NORMAL != ErrorMsg(amqp_get_rpc_reply(m_pConn), "Consumer_limit open channel"))
  353 + {
  354 + amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
  355 + return -2;
  356 + }
  357 +
  358 +#endif
  359 +
  360 + amqp_basic_qos(m_pConn, m_iChannel, 0, GetNum, 0);
  361 + int ack = 1; // no_ack 是否需要确认消息后再从队列中删除消息
  362 + amqp_bytes_t queuename= amqp_cstring_bytes(strQueueName.c_str());
  363 + amqp_basic_consume(m_pConn, m_iChannel, queuename, amqp_empty_bytes, 0, ack, 0, amqp_empty_table);
  364 +
  365 + if (error_code_t::NORMAL != ErrorMsg(amqp_get_rpc_reply(m_pConn), "Consuming"))
  366 + {
  367 + amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
  368 + return -3;
  369 + }
  370 +
  371 + int hasget = 0;
  372 + amqp_rpc_reply_t res;
  373 + amqp_envelope_t envelope;
  374 + while (GetNum > 0)
  375 + {
  376 + amqp_maybe_release_buffers(m_pConn);
  377 + res = amqp_consume_message(m_pConn, &envelope, timeout, 0);
  378 + if (AMQP_RESPONSE_NORMAL != res.reply_type) {
  379 + spdlog::error("Consumer amqp_channel_close failed then continue");
  380 +#if 1
  381 + amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
  382 + if (0 == hasget)
  383 + return -res.reply_type;
  384 + else
  385 + return 0;
  386 +#endif
  387 + }
  388 +
  389 + string str((char *)envelope.message.body.bytes, (char *)envelope.message.body.bytes + envelope.message.body.len);
  390 + message_array.push_back(str);
  391 + int rtn = amqp_basic_ack(m_pConn, m_iChannel, envelope.delivery_tag, 1);
  392 + amqp_destroy_envelope(&envelope);
  393 + if (rtn != 0) {
  394 + amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
  395 + return -4;
  396 + }
  397 +
  398 + GetNum--;
  399 + hasget++;
  400 + usleep(1);
  401 + }
  402 +
  403 + return 0;
  404 +}
  405 +
  406 +error_code_t CRabbitmqClientImpl::ErrorMsg(amqp_rpc_reply_t x, char const *context)
  407 +{
  408 + switch (x.reply_type)
  409 + {
  410 + case AMQP_RESPONSE_NORMAL:
  411 + return error_code_t::NORMAL;
  412 +
  413 + case AMQP_RESPONSE_NONE:
  414 + spdlog::error("{:s}: missing RPC reply type!", context);
  415 + return error_code_t::RESPONSE_NONE;
  416 +
  417 + case AMQP_RESPONSE_LIBRARY_EXCEPTION:
  418 + spdlog::error("{:s}: {:s}", context, amqp_error_string2(x.library_error));
  419 + return error_code_t::LIBRARY_EXCEPTION;
  420 +
  421 + case AMQP_RESPONSE_SERVER_EXCEPTION:
  422 + switch (x.reply.id) {
  423 + case AMQP_CONNECTION_CLOSE_METHOD: {
  424 + amqp_connection_close_t *m = (amqp_connection_close_t *)x.reply.decoded;
  425 + std::printf("%s: server connection error %uh, message: %.*s",
  426 + context, m->reply_code, (int)m->reply_text.len,
  427 + (char *)m->reply_text.bytes);
  428 + return error_code_t::CONNECTION_CLOSED;
  429 + }
  430 + case AMQP_CHANNEL_CLOSE_METHOD: {
  431 + amqp_channel_close_t *m = (amqp_channel_close_t *)x.reply.decoded;
  432 + std::printf("%s: server channel error %uh, message: %.*s",
  433 + context, m->reply_code, (int)m->reply_text.len,
  434 + (char *)m->reply_text.bytes);
  435 + return error_code_t::CHANNEL_CLOSED;
  436 + }
  437 + default:
  438 + std::printf("%s: unknown server error, method id 0x%08X",
  439 + context, x.reply.id);
  440 + return error_code_t::UNKNOWN;
  441 + }
  442 + }
  443 + return error_code_t::NORMAL;
  444 +}
  445 +
  446 +CRabbitmqClient* CRabbitmqClient::get_instance()
  447 +{
  448 + CRabbitmqClient* instance_ptr = nullptr;
  449 + if (instance_ptr == nullptr)
  450 + instance_ptr = new CRabbitmqClientImpl();
  451 + return instance_ptr;
  452 +}
  453 +
  454 +
  455 +void CRabbitmqClient::destory(CRabbitmqClient* instance)
  456 +{
  457 + if (instance != nullptr)
  458 + {
  459 + delete instance;
  460 + instance = nullptr;
  461 + }
  462 +}
  463 +
src/reprocessing_module/rbmq/RabbitmqClientImpl.hpp 0 → 100755
  1 +#pragma once
  2 +#include "RabbitmqClient.hpp"
  3 +
  4 +#include <spdlog/spdlog.h>
  5 +#include <string>
  6 +#include <cstring>
  7 +#include <vector>
  8 +#include "amqp_tcp_socket.h"
  9 +#include <memory>
  10 +
  11 +
  12 +using std::string;
  13 +using std::vector;
  14 +
  15 +typedef void (*RABBITMQ_CALLBACK)(void* contex, const char * msg);
  16 +
  17 +enum class error_code_t
  18 +{
  19 + UNKNOWN = -1,
  20 + NORMAL = 0,
  21 + CONNECTION_CLOSED,
  22 + CHANNEL_CLOSED,
  23 + RESPONSE_NONE,
  24 + LIBRARY_EXCEPTION,
  25 +};
  26 +
  27 +class CRabbitmqClientImpl: virtual public CRabbitmqClient{
  28 +public:
  29 + CRabbitmqClientImpl();
  30 + ~CRabbitmqClientImpl();
  31 +
  32 + virtual int Connect(const string &strHostname, int iPort, const string &strUser, const string &strPasswd, const string &vhost = "/");
  33 + virtual int Disconnect();
  34 +
  35 + /**
  36 + * @brief ExchangeDeclare 声明exchange
  37 + * @param [in] strExchange
  38 + * @param [in] strType
  39 + * @return 等于0值代表成功创建exchange,小于0代表错误
  40 + */
  41 + virtual int ExchangeDeclare(const string &strExchange, const string &strType, const bool durable = false);
  42 +
  43 + /**
  44 + * @brief QueueDeclare 声明消息队列
  45 + * @param [in] strQueueName 消息队列实例
  46 + * @param
  47 + * @return 等于0值代表成功创建queue,小于0代表错误
  48 + */
  49 + virtual int QueueDeclare(const string &strQueueName, const bool durable = false);
  50 +
  51 + /**
  52 + * @brief QueueBind 将队列,交换机和绑定规则绑定起来形成一个路由表
  53 + * @param [in] strQueueName 消息队列
  54 + * @param [in] strExchange 交换机名称
  55 + * @param [in] strBindKey 路由名称 “msg.#” “msg.weather.**”
  56 + * @return 等于0值代表成功绑定,小于0代表错误
  57 + */
  58 + virtual int QueueBind(const string &strQueueName, const string &strExchange, const string &strBindKey);
  59 +
  60 + /**
  61 + * @brief QueueUnbind 将队列,交换机和绑定规则绑定解除
  62 + * @param [in] strQueueName 消息队列
  63 + * @param [in] strExchange 交换机名称
  64 + * @param [in] strBindKey 路由名称 “msg.#” “msg.weather.**”
  65 + * @return 等于0值代表成功绑定,小于0代表错误
  66 + */
  67 + virtual int QueueUnbind(const string &strQueueName, const string &strExchange, const string &strBindKey);
  68 +
  69 + /**
  70 + * @brief QueueDelete 删除消息队列。
  71 + * @param [in] strQueueName 消息队列名称
  72 + * @param [in] iIfUnused 消息队列是否在用,1 则论是否在用都删除
  73 + * @return 等于0值代表成功删除queue,小于0代表错误
  74 + */
  75 + virtual int QueueDelete(const string &strQueueName, int iIfUnused);
  76 +
  77 + /**
  78 + * @brief Publish 发布消息
  79 + * @param [in] strMessage 消息实体
  80 + * @param [in] strExchange 交换器
  81 + * @param [in] strRoutekey 路由规则
  82 + * 1.Direct Exchange – 处理路由键。需要将一个队列绑定到交换机上,要求该消息与一个特定的路由键完全匹配。
  83 + * 2.Fanout Exchange – 不处理路由键。将队列绑定到交换机上。一个发送到交换机的消息都会被转发到与该交换机绑定的所有队列上。
  84 + * 3.Topic Exchange – 将路由键和某模式进行匹配。此时队列需要绑定要一个模式上。符号“#”匹配一个或多个词,符号“*”匹配不多不少一个词。
  85 + * 因此“audit.#”能够匹配到“audit.irs.corporate”,但是“audit.*” 只会匹配到“audit.irs”
  86 + * @return 等于0值代表成功发送消息实体,小于0代表发送错误
  87 + */
  88 + virtual int Publish(const string &strMessage, const string &strExchange, const string &strRoutekey);
  89 +
  90 + /**
  91 + * @brief consumer 消费消息
  92 + * @param [in] strQueueName 队列名称
  93 + * @param [out] message_array 获取的消息实体
  94 + * @param [int] GetNum 需要取得的消息个数
  95 + * @param [int] timeout 取得的消息是延迟,若为NULL,表示持续取,无延迟,阻塞状态
  96 + * @return 等于0值代表成功,小于0代表错误,错误信息从ErrorReturn返回
  97 + */
  98 + virtual int Consumer_limit(const string &strQueueName, vector<string> &message_array, int GetNum = 1, struct timeval *timeout = NULL);
  99 +
  100 + /**
  101 + * @brief consumer 消费消息
  102 + * @param [in] strQueueName 队列名称
  103 + * @param [out] message_array 获取的消息实体
  104 + * @param [int] GetNum 需要取得的消息个数
  105 + * @param [int] timeout 取得的消息是延迟,若为NULL,表示持续取,无延迟,阻塞状态
  106 + * @return 等于0值代表成功,小于0代表错误,错误信息从ErrorReturn返回
  107 + */
  108 + virtual int Consumer(const string &strQueueName, RABBITMQ_CALLBACK callback, void * contex, struct timeval *timeout = NULL);
  109 +
  110 +
  111 + CRabbitmqClientImpl(const CRabbitmqClientImpl &lh) = delete;
  112 + void operator=(const CRabbitmqClientImpl &lh) = delete;
  113 +
  114 +private:
  115 + error_code_t ErrorMsg(amqp_rpc_reply_t x, char const *context);
  116 +
  117 + error_code_t Reconnection();
  118 +
  119 + string m_strHostname; // amqp主机
  120 + int m_iPort; // amqp端口
  121 + string m_strUser;
  122 + string m_strPasswd;
  123 + string m_strVHost;
  124 + int m_iChannel;
  125 + int m_max_reconnection;
  126 +
  127 + amqp_socket_t *m_pSock;
  128 + amqp_connection_state_t m_pConn;
  129 +
  130 +};
src/reprocessing_module/rbmq/common.h 0 → 100755
  1 +/*
  2 + * @Author: yangzilong
  3 + * @Date: 2021-12-07 16:39:17
  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 +
  13 +typedef struct rabbitmq_conn_params_t
  14 +{
  15 + int port;
  16 + // char *ip[12+3+1];
  17 + const char *ip;
  18 + const char *uname;
  19 + const char *passwd;
  20 + const char *vhost;
  21 +
  22 + const char *exchange;
  23 + const char *exchange_type;
  24 + const char *queue;
  25 + const char *routing_key;
  26 +
  27 + bool durable_exchange, durable_queue;
  28 +} rabbitmq_conn_params_t;
  29 +
  30 +
src/reprocessing_module/snapshot_reprocessing.cpp
@@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
3 #include "../common/logger.hpp" 3 #include "../common/logger.hpp"
4 #include "../ai_platform/mvpt_process_assist.h" 4 #include "../ai_platform/mvpt_process_assist.h"
5 #include "../decoder/interface/DeviceMemory.hpp" 5 #include "../decoder/interface/DeviceMemory.hpp"
  6 +#include "../helpers/img_util.h"
6 7
7 8
8 snapshot_reprocessing::snapshot_reprocessing(int devId) 9 snapshot_reprocessing::snapshot_reprocessing(int devId)
@@ -49,6 +50,16 @@ vector&lt;multi_obj_data_t&gt; snapshot_reprocessing::get_vehicle_snapshot(vector&lt;Devi @@ -49,6 +50,16 @@ vector&lt;multi_obj_data_t&gt; snapshot_reprocessing::get_vehicle_snapshot(vector&lt;Devi
49 if (algor_config_param.count(task_id) && algor_config_param[task_id].vehicle_algors.count(algorithm_type_t::VEHICLE_SNAPSHOT)) 50 if (algor_config_param.count(task_id) && algor_config_param[task_id].vehicle_algors.count(algorithm_type_t::VEHICLE_SNAPSHOT))
50 { 51 {
51 task_param_manager::algo_param_type_t_* cur_task_params = algor_param[task_id][algorithm_type_t::VEHICLE_SNAPSHOT]; 52 task_param_manager::algo_param_type_t_* cur_task_params = algor_param[task_id][algorithm_type_t::VEHICLE_SNAPSHOT];
  53 + if (!cur_task_params || !cur_task_params->basic_param || !cur_task_params->basic_param->adapt_param)
  54 + {
  55 + continue;
  56 + }
  57 +
  58 + // 多边形区域
  59 + auto adapt_param = cur_task_params->basic_param->adapt_param;
  60 + if (adapt_param->points_count <= 0) {
  61 + continue;
  62 + }
52 63
53 // 同一目标间隔多少帧保存 64 // 同一目标间隔多少帧保存
54 int snap_frame_interval = ((algor_config_param_snapshot*)cur_task_params->algor_param)->snap_frame_interval; 65 int snap_frame_interval = ((algor_config_param_snapshot*)cur_task_params->algor_param)->snap_frame_interval;
@@ -61,9 +72,14 @@ vector&lt;multi_obj_data_t&gt; snapshot_reprocessing::get_vehicle_snapshot(vector&lt;Devi @@ -61,9 +72,14 @@ vector&lt;multi_obj_data_t&gt; snapshot_reprocessing::get_vehicle_snapshot(vector&lt;Devi
61 if(snap_frame_interval > 0 && det_obj.num % snap_frame_interval >= skip_frame){ 72 if(snap_frame_interval > 0 && det_obj.num % snap_frame_interval >= skip_frame){
62 continue; 73 continue;
63 } 74 }
  75 +
  76 + sy_point center;
  77 + center.x_ = (det_obj.left + det_obj.right) * 0.5;
  78 + center.y_ = det_obj.bottom;
  79 +
64 int type_index = det_obj.index; 80 int type_index = det_obj.index;
65 if ((type_index == 4 || type_index == 5 || type_index == 6 || type_index ==7 || type_index ==8) 81 if ((type_index == 4 || type_index == 5 || type_index == 6 || type_index ==7 || type_index ==8)
66 - && snapshot_legal_inarea(cur_task_params->basic_param->algor_valid_rect, det_obj.left, det_obj.top, det_obj.right, det_obj.bottom)) 82 + && common::isInPolygon(adapt_param->points, adapt_param->points_count, center))
67 { 83 {
68 video_object_info obj_info; 84 video_object_info obj_info;
69 obj_info.top = det_obj.top; 85 obj_info.top = det_obj.top;
@@ -202,6 +218,30 @@ void snapshot_reprocessing::update_bestsnapshot(vector&lt;DeviceMemory*&gt; vec_devMem @@ -202,6 +218,30 @@ void snapshot_reprocessing::update_bestsnapshot(vector&lt;DeviceMemory*&gt; vec_devMem
202 index = total_snapshot_info[new_obj].index.index; 218 index = total_snapshot_info[new_obj].index.index;
203 } 219 }
204 220
  221 + algorithm_type_t algor_type;
  222 + if (index ==0) algor_type = algorithm_type_t::HUMAN_SNAPSHOT;
  223 + if (index ==1 || index ==2 || index ==3) algor_type = algorithm_type_t::NONMOTOR_VEHICLE_SNAPSHOT;
  224 + if (index ==4 || index ==5 || index ==6 || index ==7 || index ==8) algor_type = algorithm_type_t::VEHICLE_SNAPSHOT;
  225 + if (!(algor_config_param.count(task_id) && algor_param.count(task_id) && algor_param[task_id].count(algor_type)))
  226 + continue;
  227 + task_param_manager::algo_param_type_t_* cur_task_params = algor_param[task_id][algor_type];
  228 + if (!cur_task_params || !cur_task_params->basic_param || !cur_task_params->basic_param->adapt_param) {
  229 + continue;
  230 + }
  231 +
  232 + // 多边形区域
  233 + auto adapt_param = cur_task_params->basic_param->adapt_param;
  234 + if (adapt_param->points_count <= 0) {
  235 + continue;
  236 + }
  237 +
  238 + sy_point center;
  239 + center.x_ = (obj_info.left + obj_info.right) * 0.5;
  240 + center.y_ = obj_info.bottom;
  241 + if (!common::isInPolygon(adapt_param->points, adapt_param->points_count, center)) {
  242 + continue;
  243 + }
  244 +
205 int cur_real_width = (obj_info.right - obj_info.left); 245 int cur_real_width = (obj_info.right - obj_info.left);
206 int cur_real_height = (obj_info.bottom - obj_info.top); 246 int cur_real_height = (obj_info.bottom - obj_info.top);
207 int cur_real_index = obj_info.index; 247 int cur_real_index = obj_info.index;
@@ -220,17 +260,6 @@ void snapshot_reprocessing::update_bestsnapshot(vector&lt;DeviceMemory*&gt; vec_devMem @@ -220,17 +260,6 @@ void snapshot_reprocessing::update_bestsnapshot(vector&lt;DeviceMemory*&gt; vec_devMem
220 { 260 {
221 /* manager insert new object. */ 261 /* manager insert new object. */
222 /* 判断目标合法 */ 262 /* 判断目标合法 */
223 - algorithm_type_t algor_type;  
224 - if (index ==0) algor_type = algorithm_type_t::HUMAN_SNAPSHOT;  
225 - if (index ==1 || index ==2 || index ==3) algor_type = algorithm_type_t::NONMOTOR_VEHICLE_SNAPSHOT;  
226 - if (index ==4 || index ==5 || index ==6 || index ==7 || index ==8) algor_type = algorithm_type_t::VEHICLE_SNAPSHOT;  
227 - if (!(algor_config_param.count(task_id) && algor_param.count(task_id) && algor_param[task_id].count(algor_type)))  
228 - continue;  
229 - task_param_manager::algo_param_type_t_* cur_task_params = algor_param[task_id][algor_type];  
230 - if (!snapshot_legal_inarea(cur_task_params->basic_param->algor_valid_rect,obj_info.left, obj_info.top, obj_info.right, obj_info.bottom)){  
231 - continue;  
232 - }  
233 -  
234 if(!snapshot_legal_minarea(index, cur_real_width, cur_real_height)){ 263 if(!snapshot_legal_minarea(index, cur_real_width, cur_real_height)){
235 continue; 264 continue;
236 } 265 }
@@ -265,15 +294,6 @@ void snapshot_reprocessing::update_bestsnapshot(vector&lt;DeviceMemory*&gt; vec_devMem @@ -265,15 +294,6 @@ void snapshot_reprocessing::update_bestsnapshot(vector&lt;DeviceMemory*&gt; vec_devMem
265 } else { 294 } else {
266 total_snapshot_info[new_obj].last_area = (obj_info.right - obj_info.left) * (obj_info.bottom - obj_info.top); 295 total_snapshot_info[new_obj].last_area = (obj_info.right - obj_info.left) * (obj_info.bottom - obj_info.top);
267 296
268 - algorithm_type_t algor_type;  
269 - if (index ==0) algor_type = algorithm_type_t::HUMAN_SNAPSHOT;  
270 - if (index ==1 || index ==2 || index ==3) algor_type = algorithm_type_t::NONMOTOR_VEHICLE_SNAPSHOT;  
271 - if (index ==4 || index ==5 || index ==6 || index ==7 || index ==8) algor_type = algorithm_type_t::VEHICLE_SNAPSHOT;  
272 - if (!(algor_config_param.count(task_id) && algor_param.count(task_id) && algor_param[task_id].count(algor_type)))  
273 - continue;  
274 - task_param_manager::algo_param_type_t_* cur_task_params = algor_param[task_id][algor_type];  
275 - if (!snapshot_legal_inarea(cur_task_params->basic_param->algor_valid_rect,obj_info.left, obj_info.top, obj_info.right, obj_info.bottom))  
276 - continue;  
277 //--------------------------------------------------------------- 297 //---------------------------------------------------------------
278 if (!best_snapshot_judge_algor(new_obj, total_snapshot_info[new_obj], obj_info.left, obj_info.top, 298 if (!best_snapshot_judge_algor(new_obj, total_snapshot_info[new_obj], obj_info.left, obj_info.top,
279 cur_real_width, cur_real_height, frame_width, frame_height)) 299 cur_real_width, cur_real_height, frame_width, frame_height))
@@ -330,6 +350,431 @@ void snapshot_reprocessing::update_bestsnapshot(vector&lt;DeviceMemory*&gt; vec_devMem @@ -330,6 +350,431 @@ void snapshot_reprocessing::update_bestsnapshot(vector&lt;DeviceMemory*&gt; vec_devMem
330 } 350 }
331 } 351 }
332 352
  353 +
  354 +/* 获取农村违法分析要求的目标快照图--轨迹起始 最佳 轨迹结束 */
  355 +void snapshot_reprocessing::update_village_bestsnapshot(vector<DeviceMemory*> vec_devMem, vector<onelevel_det_result> &ol_det_result, vector<vector<int>>& delete_object_id){
  356 + map<string, algor_open_config_param> && algor_config_param = m_task_param_manager->get_task_algor_params();
  357 + map<string, map<algo_type, task_param_manager::algo_param_type_t_*>> && algor_param = m_task_param_manager->get_task_other_params();
  358 +
  359 + VPCUtil* pVpcUtil = VPCUtil::getInstance();
  360 +
  361 + for (size_t i = 0; i < vec_devMem.size(); i++){
  362 +
  363 + onelevel_det_result det_result = ol_det_result[i];
  364 + if (0 == det_result.obj_count){
  365 + continue;
  366 + }
  367 +
  368 + DeviceMemory* memPtr = vec_devMem[i];
  369 +
  370 + string task_id = memPtr->getId();
  371 + int frame_height = memPtr->getHeight();
  372 + int frame_width = memPtr->getWidth();
  373 +
  374 + vector<video_object_info> vec_obj_info;
  375 + vector<video_object_info> last_vec_obj_info;
  376 + for (int c = 0; c < det_result.obj_count; c++){
  377 +
  378 + det_objinfo obj_info = det_result.obj[c];
  379 + OBJ_KEY new_obj = { task_id, obj_info.id };
  380 +
  381 + int index = 0;
  382 +
  383 + /* 投票确定目标index */
  384 + if (total_village_snapshot_info.find(new_obj) == total_village_snapshot_info.end()){
  385 + index = obj_info.index;
  386 + } else {
  387 + index = total_village_snapshot_info[new_obj].snapShots[1].index.index;
  388 + }
  389 +
  390 + int cur_real_width = (obj_info.right - obj_info.left);
  391 + int cur_real_height = (obj_info.bottom - obj_info.top);
  392 + int cur_real_index = obj_info.index;
  393 +
  394 + int expansion_width = cur_real_width * EXPANSION_PROPORTION;
  395 + int expansion_height = cur_real_height * EXPANSION_PROPORTION;
  396 + // DEBUG-----------------------------------------------------------------
  397 + // 0-行人 1-自行车 2-摩托车 3-三轮车 4-小型车 5-大车 6-卡车 7-拖拉机 8-中巴
  398 + if(index ==0 || index ==1 || index ==2 || index ==3) { //行人和非机动车外扩指定像素即可
  399 + expansion_width = 10;
  400 + expansion_height = 10;
  401 + }
  402 +
  403 + /* 若该目标第一次出现 */
  404 + if (total_village_snapshot_info.find(new_obj) == total_village_snapshot_info.end())
  405 + {
  406 + if (total_village_snapshot_info.size() > 400)
  407 + {//确保显存不会无限增长
  408 + return;
  409 + }
  410 +
  411 + /* manager insert new object. */
  412 + /* 判断目标合法 */
  413 + if (!(algor_config_param.count(task_id) && algor_param.count(task_id)))
  414 + continue;
  415 + if (!(algor_param[task_id].count(algorithm_type_t::TRICYCLE_MANNED) || algor_param[task_id].count(algorithm_type_t::TRUCK_MANNED) ||
  416 + algor_param[task_id].count(algorithm_type_t::NONMOTOR_VEHICLE_NOHELMET) || algor_param[task_id].count(algorithm_type_t::NONMOTOR_VEHICLE_OVERMAN) ||
  417 + algor_param[task_id].count(algorithm_type_t::NONMOTOR_VEHICLE_USEPHONE) || algor_param[task_id].count(algorithm_type_t::NONMOTOR_VEHICLE_REFIT) ||
  418 + algor_param[task_id].count(algorithm_type_t::PERSON_RUNNING_REDLIGHTS) || algor_param[task_id].count(algorithm_type_t::NONMOTOR_RUNNING_REDLIGHTS) ||
  419 + algor_param[task_id].count(algorithm_type_t::PERSON_IN_VEHICLELANE) || algor_param[task_id].count(algorithm_type_t::NONMOTOR_IN_VEHICLELANE) ||
  420 + algor_param[task_id].count(algorithm_type_t::NONMOTOR_CEOSSPARKLINE) || algor_param[task_id].count(algorithm_type_t::PERSON_CROSS) ||
  421 + algor_param[task_id].count(algorithm_type_t::NONMOTOR_WRONGDIRECTION) || algor_param[task_id].count(algorithm_type_t::VEHICLE_WRONGDIRECTION) ||
  422 + algor_param[task_id].count(algorithm_type_t::VEHICLE_SOLIDLINETURNAROUND) || algor_param[task_id].count(algorithm_type_t::VEHICLE_NOTGIVEWAY) ||
  423 + algor_param[task_id].count(algorithm_type_t::VEHICLE_NOTDECELERATION)))
  424 + continue;
  425 +
  426 + if(!snapshot_legal_minarea(index, cur_real_width, cur_real_height)){
  427 + continue;
  428 + }
  429 + // 过滤边缘位置
  430 + if(obj_info.left < 80 || obj_info.top < 50 || (obj_info.right > frame_width - 80) || (obj_info.bottom > frame_height - 50)){
  431 + continue;
  432 + }
  433 + total_village_snapshot_info[new_obj].exists[1] = true;
  434 + /* 存入当前抠图目标参数 flags用于判断目标从画面什么位置出现 方便之后排除出画面边缘的快照图 */
  435 + total_village_snapshot_info[new_obj].snapShots[1].index.count++;
  436 + total_village_snapshot_info[new_obj].snapShots[1].index.index = cur_real_index;
  437 + total_village_snapshot_info[new_obj].snapShots[1].confidence = obj_info.confidence;
  438 + total_village_snapshot_info[new_obj].snapShots[1].flags[0] = obj_info.left < minDistance[0] + SCALE_OUT ? 0 : 1; //left
  439 + total_village_snapshot_info[new_obj].snapShots[1].flags[1] = obj_info.top < minDistance[1] + SCALE_OUT ? 0 : 1; //top
  440 + total_village_snapshot_info[new_obj].snapShots[1].flags[2] = obj_info.right > frame_width - minDistance[2] - SCALE_OUT ? 0 : 1; //right
  441 + total_village_snapshot_info[new_obj].snapShots[1].flags[3] = obj_info.bottom > frame_height - minDistance[3] - SCALE_OUT ? 0 : 1; //bottom
  442 +
  443 + int cur_left = max(obj_info.left - 10, 0);
  444 + int cur_top = max(obj_info.top - 10, 0);
  445 + int cur_right = min(obj_info.right + 10, frame_width - 1);
  446 + int cur_bottom = min(obj_info.bottom + 10, frame_height - 1);
  447 + total_village_snapshot_info[new_obj].snapShots[1].obj_pos = { cur_left, cur_top, cur_right - cur_left, cur_bottom - cur_top }; //debug by zsh 推出的坐标外扩10像素
  448 + total_village_snapshot_info[new_obj].snapShots[1].last_area = total_village_snapshot_info[new_obj].snapShots[1].max_area = (cur_right - cur_left) * (cur_bottom - cur_top);
  449 +
  450 + video_object_info info;
  451 + info.left = max(obj_info.left - expansion_width, 0);
  452 + info.top = max(obj_info.top - expansion_height, 0);
  453 + info.right = min(obj_info.right + expansion_width, frame_width - 1);
  454 + info.bottom = min(obj_info.bottom + expansion_height, frame_height - 1);
  455 + strcpy(info.task_id, task_id.c_str());
  456 + info.object_id = obj_info.id;
  457 + info.confidence = obj_info.confidence;
  458 + info.index = index;
  459 +
  460 + vec_obj_info.push_back(info);//用于最佳抓拍图
  461 +
  462 + // 首张抓拍图:切图+信息存储
  463 + vpc_img_info crop_img = pVpcUtil->crop(memPtr, info);
  464 + total_village_snapshot_info[new_obj].exists[0] = true;
  465 + total_village_snapshot_info[new_obj].snapShots[0].index.index = cur_real_index;
  466 + total_village_snapshot_info[new_obj].snapShots[0].confidence = obj_info.confidence;
  467 + total_village_snapshot_info[new_obj].snapShots[0].obj_pos = { cur_left, cur_top, cur_right - cur_left, cur_bottom - cur_top };
  468 + total_village_snapshot_info[new_obj].snapShots[0].snapShot = VPCUtil::vpc_devMem2vpcImg(memPtr);
  469 + total_village_snapshot_info[new_obj].snapShots[0].snapShotLittle = crop_img;
  470 +
  471 + // 缓存末张抓拍图
  472 + total_village_snapshot_info[new_obj].exists[2] = true;
  473 + total_village_snapshot_info[new_obj].snapShots[2].index.index = cur_real_index;
  474 + total_village_snapshot_info[new_obj].snapShots[2].confidence = obj_info.confidence;
  475 + total_village_snapshot_info[new_obj].snapShots[2].obj_pos = { cur_left, cur_top, cur_right - cur_left, cur_bottom - cur_top };
  476 + last_vec_obj_info.push_back(info);
  477 +
  478 + } else {
  479 + total_village_snapshot_info[new_obj].snapShots[1].last_area = (obj_info.right - obj_info.left) * (obj_info.bottom - obj_info.top);
  480 +
  481 + if (!(algor_config_param.count(task_id) && algor_param.count(task_id)))
  482 + continue;
  483 + if (!(algor_param[task_id].count(algorithm_type_t::TRICYCLE_MANNED) || algor_param[task_id].count(algorithm_type_t::TRUCK_MANNED) ||
  484 + algor_param[task_id].count(algorithm_type_t::NONMOTOR_VEHICLE_NOHELMET) || algor_param[task_id].count(algorithm_type_t::NONMOTOR_VEHICLE_OVERMAN) ||
  485 + algor_param[task_id].count(algorithm_type_t::NONMOTOR_VEHICLE_USEPHONE) || algor_param[task_id].count(algorithm_type_t::NONMOTOR_VEHICLE_REFIT) ||
  486 + algor_param[task_id].count(algorithm_type_t::PERSON_RUNNING_REDLIGHTS) || algor_param[task_id].count(algorithm_type_t::NONMOTOR_RUNNING_REDLIGHTS) ||
  487 + algor_param[task_id].count(algorithm_type_t::PERSON_IN_VEHICLELANE) || algor_param[task_id].count(algorithm_type_t::NONMOTOR_IN_VEHICLELANE) ||
  488 + algor_param[task_id].count(algorithm_type_t::NONMOTOR_CEOSSPARKLINE) || algor_param[task_id].count(algorithm_type_t::PERSON_CROSS) ||
  489 + algor_param[task_id].count(algorithm_type_t::NONMOTOR_WRONGDIRECTION) || algor_param[task_id].count(algorithm_type_t::VEHICLE_WRONGDIRECTION) ||
  490 + algor_param[task_id].count(algorithm_type_t::VEHICLE_SOLIDLINETURNAROUND) || algor_param[task_id].count(algorithm_type_t::VEHICLE_NOTGIVEWAY) ||
  491 + algor_param[task_id].count(algorithm_type_t::VEHICLE_NOTDECELERATION)))
  492 + continue;
  493 +
  494 + // 过滤边缘位置
  495 + if(obj_info.left < 80 || obj_info.top < 50 || (obj_info.right > frame_width - 80) || (obj_info.bottom > frame_height - 50)){
  496 + continue;
  497 + }
  498 +
  499 + int cur_left = max(obj_info.left - 10, 0);
  500 + int cur_top = max(obj_info.top - 10, 0);
  501 + int cur_right = min(obj_info.right + 10, frame_width - 1);
  502 + int cur_bottom = min(obj_info.bottom + 10, frame_height - 1);
  503 +
  504 + video_object_info info;
  505 + info.left = max(obj_info.left - expansion_width, 0);
  506 + info.top = max(obj_info.top - expansion_height, 0);
  507 + info.right = min(obj_info.right + expansion_width, frame_width - 1);
  508 + info.bottom = min(obj_info.bottom + expansion_height, frame_height - 1);
  509 + strcpy(info.task_id, task_id.c_str());
  510 + info.object_id = obj_info.id;
  511 + info.confidence = obj_info.confidence;
  512 + info.index = index;
  513 +
  514 + // 缓存末张抓拍图
  515 + total_village_snapshot_info[new_obj].snapShots[2].index.index = cur_real_index;
  516 + total_village_snapshot_info[new_obj].snapShots[2].confidence = obj_info.confidence;
  517 + total_village_snapshot_info[new_obj].snapShots[2].obj_pos = { cur_left, cur_top, cur_right - cur_left, cur_bottom - cur_top };
  518 + last_vec_obj_info.push_back(info);
  519 + //---------------------------------------------------------------
  520 + if (!best_snapshot_judge_algor(new_obj, total_village_snapshot_info[new_obj].snapShots[1], obj_info.left, obj_info.top,
  521 + cur_real_width, cur_real_height, frame_width, frame_height))
  522 + {
  523 + continue;
  524 + }
  525 + /* 若更优于之前的快照 做快照的更新 */
  526 + if (total_village_snapshot_info[new_obj].snapShots[1].index.count == 0)
  527 + {
  528 + total_village_snapshot_info[new_obj].snapShots[1].index.count++;
  529 + total_village_snapshot_info[new_obj].snapShots[1].index.index = cur_real_index;
  530 + }
  531 + else
  532 + {
  533 + if (total_village_snapshot_info[new_obj].snapShots[1].index.index == cur_real_index)
  534 + total_village_snapshot_info[new_obj].snapShots[1].index.count++;
  535 + else
  536 + total_village_snapshot_info[new_obj].snapShots[1].index.count--;
  537 + }
  538 +
  539 + total_village_snapshot_info[new_obj].snapShots[1].obj_pos = { cur_left, cur_top, cur_right - cur_left, cur_bottom - cur_top }; //debug by zsh 推出的坐标外扩10像素
  540 + total_village_snapshot_info[new_obj].snapShots[1].last_area = total_village_snapshot_info[new_obj].snapShots[1].max_area = (cur_right - cur_left) * (cur_bottom - cur_top);
  541 +
  542 +
  543 + vec_obj_info.push_back(info);//用于最佳抓拍图
  544 + }
  545 + }
  546 +
  547 + vector<vpc_img_info> imgList = pVpcUtil->crop_batch(memPtr, vec_obj_info);
  548 + vec_obj_info.clear();
  549 + for (size_t i = 0; i < imgList.size(); i++) {
  550 + vpc_img_info obj_info = imgList[i];
  551 + OBJ_KEY objKey = { obj_info.task_id, obj_info.object_id };
  552 + VPCUtil::vpc_img_release(total_village_snapshot_info[objKey].snapShots[1].snapShot);
  553 + total_village_snapshot_info[objKey].snapShots[1].snapShot = VPCUtil::vpc_devMem2vpcImg(memPtr);
  554 + VPCUtil::vpc_img_release(total_village_snapshot_info[objKey].snapShots[1].snapShotLittle);
  555 + total_village_snapshot_info[objKey].snapShots[1].snapShotLittle = obj_info;
  556 + }
  557 + imgList.clear();
  558 +
  559 + vector<vpc_img_info> last_imgList = pVpcUtil->crop_batch(memPtr, last_vec_obj_info);
  560 + last_vec_obj_info.clear();
  561 + for (size_t i = 0; i < last_imgList.size(); i++) {
  562 + vpc_img_info obj_info = last_imgList[i];
  563 + OBJ_KEY objKey = { obj_info.task_id, obj_info.object_id };
  564 + VPCUtil::vpc_img_release(total_village_snapshot_info[objKey].snapShots[2].snapShot);
  565 + total_village_snapshot_info[objKey].snapShots[2].snapShot = VPCUtil::vpc_devMem2vpcImg(memPtr);
  566 + VPCUtil::vpc_img_release(total_village_snapshot_info[objKey].snapShots[2].snapShotLittle);
  567 + total_village_snapshot_info[objKey].snapShots[2].snapShotLittle = obj_info;
  568 + }
  569 + last_imgList.clear();
  570 + }
  571 +}
  572 +
  573 +map<OBJ_KEY, OBJ_VALUES> snapshot_reprocessing::get_total_village_snapshot_info(){
  574 + return total_village_snapshot_info;
  575 +}
  576 +
  577 +bool snapshot_reprocessing::best_face_snapshot_judge_algor_v2(const OBJ_KEY& obj_key, const OBJ_VALUE& obj_value, int left, int top, int width, int height, int image_width, int image_height, float roll, float yaw, float pitch)
  578 +{
  579 + return snapshot_legal_pos(obj_value.flags, left, top, left + width, top + height, image_width, image_height)
  580 + && snapshot_legal_inarea(width, height)
  581 + && snapshot_legal_area(obj_value.max_area, obj_value.last_area, left, top, left + width, top + height)
  582 + && snapshot_legal_pose(obj_value.roll, obj_value.yaw, obj_value.pitch, roll, yaw, pitch);
  583 +}
  584 +
  585 +//人脸快照保存更新
  586 +int snapshot_reprocessing::update_face_bestsnapshot(vector<DeviceMemory*> vec_devMem, vector<onelevel_det_result> &ol_det_result, vector<vector<int>>& delete_object_id)
  587 +{
  588 + //230327added
  589 + map<string, algor_open_config_param> && algor_config_param = m_task_param_manager->get_task_algor_params();
  590 + map<string, map<algo_type, task_param_manager::algo_param_type_t_*>> && algor_param = m_task_param_manager->get_task_other_params();
  591 +
  592 + VPCUtil* pVpcUtil = VPCUtil::getInstance();
  593 + for(int idx=0; idx < vec_devMem.size(); idx++){
  594 +
  595 + DeviceMemory* memPtr = vec_devMem[idx];
  596 + string task_id = memPtr->getId();
  597 + int frame_height = memPtr->getHeight();
  598 + int frame_width = memPtr->getWidth();
  599 +
  600 + if (0 == ol_det_result[idx].obj_count) {
  601 + continue;
  602 + }
  603 +
  604 + LOG_DEBUG("{}: {}",task_id,ol_det_result[idx].obj_count);
  605 +
  606 + int copy_obj_count = 0; //用于记录该路有多少个目标需要进行显存图像的更新
  607 + vector<video_object_info> vec_obj_info;
  608 + for (int c = 0; c < ol_det_result[idx].obj_count; c++) {
  609 +
  610 + det_objinfo obj_info = ol_det_result[idx].obj[c];
  611 + OBJ_KEY new_obj = { task_id, obj_info.id };
  612 +
  613 + if (obj_info.confidence < 0.6)
  614 + continue;
  615 + //---------------------------------------------
  616 + //230327 增加指定区域过滤------------------------------------------
  617 + if (!(algor_config_param.count(task_id) && algor_param.count(task_id) && algor_param[task_id].count(algorithm_type_t::FACE_SNAPSHOT)))
  618 + continue;
  619 +
  620 + task_param_manager::algo_param_type_t_* cur_task_params = algor_param[task_id][algorithm_type_t::FACE_SNAPSHOT];
  621 + if (!cur_task_params || !cur_task_params->basic_param || !cur_task_params->basic_param->adapt_param) {
  622 + continue;
  623 + }
  624 +
  625 + auto adapt_param = cur_task_params->basic_param->adapt_param;
  626 + if (adapt_param->points_count <= 0) {
  627 + continue;
  628 + }
  629 +
  630 + //增加指定区域过滤------------------------------------------
  631 + sy_point center;
  632 + center.x_ = (obj_info.left + obj_info.right) * 0.5;
  633 + center.y_ = obj_info.bottom;
  634 + if (!common::isInPolygon(adapt_param->points, adapt_param->points_count, center)) {
  635 + continue;
  636 + }
  637 +
  638 + int cur_real_width = (obj_info.right - obj_info.left);
  639 + int cur_real_height = (obj_info.bottom - obj_info.top);
  640 + int cur_real_index = obj_info.index;
  641 + LOG_DEBUG(" {}: {} roll:{} yaw:{} pitch:{}",task_id, obj_info.id, fabs(obj_info.roll),fabs(obj_info.yaw),fabs(obj_info.pitch));
  642 + // 该目标的第一张
  643 + if (total_face_snapshot_info.find(new_obj) == total_face_snapshot_info.end()){
  644 +
  645 + /* manager insert new object. */
  646 + // 有效区域和最小面积过滤
  647 + if (cur_real_width * cur_real_height < 30 * 30)
  648 + {
  649 + continue;
  650 + }
  651 +
  652 + //---------------------------------------------------------------
  653 +
  654 + LOG_DEBUG(" {}: {}",task_id, obj_info.id);
  655 + total_face_snapshot_info[new_obj].index.count++;
  656 + total_face_snapshot_info[new_obj].index.index = cur_real_index; //debug by zsh
  657 + total_face_snapshot_info[new_obj].confidence = obj_info.confidence;
  658 + // 人脸姿态角 added by zsh 220719-------------------------------------------
  659 + total_face_snapshot_info[new_obj].roll = obj_info.roll;
  660 + total_face_snapshot_info[new_obj].yaw = obj_info.yaw;
  661 + total_face_snapshot_info[new_obj].pitch = obj_info.pitch;
  662 + //-------------------------------------------------------------------------
  663 +
  664 + //判断是否有余地外扩
  665 + total_face_snapshot_info[new_obj].flags[0] = obj_info.left < minDistance[0] + SCALE_OUT ? 0 : 1; //left
  666 + total_face_snapshot_info[new_obj].flags[1] = obj_info.top < minDistance[1] + SCALE_OUT ? 0 : 1; //top
  667 + total_face_snapshot_info[new_obj].flags[2] = obj_info.right > frame_width - minDistance[2] - SCALE_OUT ? 0 : 1; //right
  668 + total_face_snapshot_info[new_obj].flags[3] = obj_info.bottom > frame_height - minDistance[3] - SCALE_OUT ? 0 : 1; //bottom
  669 +
  670 + int cur_left = max(obj_info.left - 10, 0);
  671 + int cur_top = max(obj_info.top - 10, 0);
  672 + int cur_right = min(obj_info.right + 10, frame_width - 1);
  673 + int cur_bottom = min(obj_info.bottom + 10, frame_height - 1);
  674 + total_face_snapshot_info[new_obj].last_area = total_face_snapshot_info[new_obj].max_area = (cur_right - cur_left) * (cur_bottom - cur_top);
  675 +
  676 +
  677 + //人脸 按长边2倍外扩 --modified by zsh-------------------------------------------------------
  678 + int cur_real_max_length = cur_real_width > cur_real_height ? cur_real_width:cur_real_height;
  679 + int expansion_width = cur_real_max_length * FACE_EXPANSION_PROPORTION;
  680 + int expansion_height = cur_real_max_length * FACE_EXPANSION_PROPORTION;
  681 +
  682 + video_object_info info;
  683 + info.left = max(obj_info.left - expansion_width, 0);
  684 + info.top = max(obj_info.top - expansion_height, 0);
  685 + info.right = min(obj_info.right + expansion_width, frame_width - 1);
  686 + info.bottom = min(obj_info.bottom + expansion_height, frame_height - 1);
  687 + strcpy(info.task_id, task_id.c_str());
  688 + info.object_id = obj_info.id;
  689 + info.confidence = obj_info.confidence;
  690 + info.index = obj_info.index;
  691 +
  692 + vec_obj_info.push_back(info);
  693 +
  694 + total_face_snapshot_info[new_obj].obj_pos = { info.left , info.top ,info.right - info.left , info.bottom - info.top };
  695 +
  696 + // 存人脸关键点、检测框及大图
  697 + memcpy(total_face_snapshot_info[new_obj].landmark_point, obj_info.landmark_point, sizeof(sy_point) * 25);
  698 + total_face_snapshot_info[new_obj].position = { obj_info.left, obj_info.top, obj_info.right - obj_info.left, obj_info.bottom - obj_info.top };
  699 + }
  700 + else
  701 + {
  702 + // 最佳快照判断
  703 + if (!best_face_snapshot_judge_algor_v2(new_obj, total_face_snapshot_info[new_obj], obj_info.left, obj_info.top,
  704 + cur_real_width, cur_real_height, frame_width, frame_height, obj_info.roll, obj_info.yaw, obj_info.pitch ))
  705 + continue;
  706 +
  707 + // 满足更新条件则进行更新
  708 + if (total_face_snapshot_info[new_obj].index.count == 0)
  709 + {
  710 + total_face_snapshot_info[new_obj].index.count++;
  711 + total_face_snapshot_info[new_obj].index.index = cur_real_index;
  712 + }
  713 + else
  714 + {
  715 + if (total_face_snapshot_info[new_obj].index.index == cur_real_index)
  716 + total_face_snapshot_info[new_obj].index.count++;
  717 + else
  718 + total_face_snapshot_info[new_obj].index.count--;
  719 + }
  720 +
  721 + // 人脸姿态角 added by zsh 220719-------------------------------------------
  722 + total_face_snapshot_info[new_obj].roll = obj_info.roll;
  723 + total_face_snapshot_info[new_obj].yaw = obj_info.yaw;
  724 + total_face_snapshot_info[new_obj].pitch = obj_info.pitch;
  725 + //-------------------------------------------------------------------------
  726 +
  727 + int cur_left = max(obj_info.left - 10, 0);
  728 + int cur_top = max(obj_info.top - 10, 0);
  729 + int cur_right = min(obj_info.right + 10, frame_width - 1);
  730 + int cur_bottom = min(obj_info.bottom + 10, frame_height - 1);
  731 + // total_face_snapshot_info[new_obj].obj_pos = { cur_left, cur_top, cur_right - cur_left, cur_bottom - cur_top }; //debug by zsh 推出的坐标外扩10像素
  732 + total_face_snapshot_info[new_obj].last_area = total_face_snapshot_info[new_obj].max_area = (cur_right - cur_left) * (cur_bottom - cur_top);
  733 +
  734 + //人脸 按长边2倍外扩 --modified by zsh-------------------------------------------------------
  735 + int cur_real_max_length = cur_real_width > cur_real_height ? cur_real_width:cur_real_height;
  736 + int expansion_width = cur_real_max_length * FACE_EXPANSION_PROPORTION;
  737 + int expansion_height = cur_real_max_length * FACE_EXPANSION_PROPORTION;
  738 +
  739 + video_object_info info;
  740 + info.left = max(obj_info.left - expansion_width, 0);
  741 + info.top = max(obj_info.top - expansion_height, 0);
  742 + info.right = min(obj_info.right + expansion_width, frame_width - 1);
  743 + info.bottom = min(obj_info.bottom + expansion_height, frame_height - 1);
  744 + strcpy(info.task_id, task_id.c_str());
  745 + info.object_id = obj_info.id;
  746 + info.confidence = obj_info.confidence;
  747 + info.index = obj_info.index;
  748 +
  749 + vec_obj_info.push_back(info);
  750 +
  751 + total_face_snapshot_info[new_obj].obj_pos = { info.left , info.top ,info.right - info.left , info.bottom - info.top };
  752 +
  753 + //存人脸关键点、检测框及大图
  754 + memcpy(total_face_snapshot_info[new_obj].landmark_point, obj_info.landmark_point, sizeof(sy_point) * 25);
  755 + total_face_snapshot_info[new_obj].position = { obj_info.left, obj_info.top, obj_info.right - obj_info.left, obj_info.bottom - obj_info.top };
  756 + }
  757 + }
  758 +
  759 + LOG_DEBUG("total_face_snapshot_info size: {}", total_face_snapshot_info.size());
  760 +
  761 + vector<vpc_img_info> imgList = pVpcUtil->crop_batch(memPtr, vec_obj_info);
  762 + vec_obj_info.clear();
  763 +
  764 + for (size_t i = 0; i < imgList.size(); i++) {
  765 + vpc_img_info obj_info = imgList[i];
  766 + OBJ_KEY objKey = { obj_info.task_id, obj_info.object_id };
  767 + VPCUtil::vpc_img_release(total_face_snapshot_info[objKey].snapShot);
  768 + total_face_snapshot_info[objKey].snapShot = VPCUtil::vpc_devMem2vpcImg(memPtr);
  769 + VPCUtil::vpc_img_release(total_face_snapshot_info[objKey].snapShotLittle);
  770 + total_face_snapshot_info[objKey].snapShotLittle = obj_info;
  771 + }
  772 + imgList.clear();
  773 + }
  774 +
  775 + return 0;
  776 +}
  777 +
333 map<OBJ_KEY, OBJ_VALUE> snapshot_reprocessing::get_total_snapshot_info(){ 778 map<OBJ_KEY, OBJ_VALUE> snapshot_reprocessing::get_total_snapshot_info(){
334 return total_snapshot_info; 779 return total_snapshot_info;
335 } 780 }
@@ -367,7 +812,90 @@ void snapshot_reprocessing::release_finished_locus_snapshot(const string taskid, @@ -367,7 +812,90 @@ void snapshot_reprocessing::release_finished_locus_snapshot(const string taskid,
367 return; 812 return;
368 } 813 }
369 814
370 - for(auto ss = total_snapshot_info.begin(); ss != total_snapshot_info.end(); ss++) 815 + for(auto ss = total_snapshot_info.begin(); ss != total_snapshot_info.end();)
  816 + {
  817 + if (strcmp(ss->first.video_id.c_str(), taskid.c_str()) == 0)
  818 + {
  819 + if (bRelease){
  820 + VPCUtil::vpc_img_release(ss->second.snapShot);
  821 + VPCUtil::vpc_img_release(ss->second.snapShotLittle);
  822 + }
  823 + total_snapshot_info.erase(ss++);
  824 + }
  825 + else ss++;
  826 + }
  827 + return;
  828 +}
  829 +
  830 +
  831 +void snapshot_reprocessing::release_village_finished_locus_snapshot(const string taskid, const int obj_id, bool bRelease)
  832 +{
  833 + LOG_DEBUG("task_id {} delete obj_id {}", taskid, obj_id); //221026
  834 + if (obj_id != -1)
  835 + {
  836 + OBJ_KEY cur_key = { taskid , obj_id };
  837 + auto it = total_village_snapshot_info.find(cur_key);
  838 + if (it == total_village_snapshot_info.end()){
  839 + return;
  840 + }
  841 +
  842 + if (bRelease){
  843 + for (int i = 0; i < 3; i++) {
  844 + OBJ_VALUE ss = total_village_snapshot_info[cur_key].snapShots[i];
  845 + VPCUtil::vpc_img_release(ss.snapShot);
  846 + VPCUtil::vpc_img_release(ss.snapShotLittle);
  847 + }
  848 +
  849 + }
  850 +
  851 + total_village_snapshot_info.erase(cur_key);
  852 + return;
  853 + }
  854 +
  855 + for(auto ss = total_village_snapshot_info.begin(); ss != total_village_snapshot_info.end();)
  856 + {
  857 + if (strcmp(ss->first.video_id.c_str(), taskid.c_str()) == 0)
  858 + {
  859 + if (bRelease){
  860 + for (int i = 0; i < 3; i++) {
  861 + VPCUtil::vpc_img_release(ss->second.snapShots[i].snapShot);
  862 + VPCUtil::vpc_img_release(ss->second.snapShots[i].snapShotLittle);
  863 + }
  864 + }
  865 + total_village_snapshot_info.erase(ss++);
  866 + }
  867 + else ss++;
  868 + }
  869 + return;
  870 +}
  871 +
  872 +
  873 +map<OBJ_KEY, OBJ_VALUE> snapshot_reprocessing::get_total_face_snapshot_info(){
  874 + return total_face_snapshot_info;
  875 +}
  876 +
  877 +void snapshot_reprocessing::release_finished_face_locus_snapshot(const string taskid, const int obj_id, bool bRelease) {
  878 +
  879 + LOG_DEBUG("task_id {} delete obj_id {}", taskid, obj_id); //221026
  880 + if (obj_id != -1) {
  881 + OBJ_KEY cur_key = { taskid , obj_id };
  882 + auto it = total_face_snapshot_info.find(cur_key);
  883 + if (it == total_face_snapshot_info.end()){
  884 + return;
  885 + }
  886 +
  887 + if (bRelease){
  888 + OBJ_VALUE ss = total_face_snapshot_info[cur_key];
  889 +
  890 + VPCUtil::vpc_img_release(ss.snapShot);
  891 + VPCUtil::vpc_img_release(ss.snapShotLittle);
  892 + }
  893 +
  894 + total_face_snapshot_info.erase(cur_key);
  895 + return;
  896 + }
  897 +
  898 + for(auto ss = total_face_snapshot_info.begin(); ss != total_face_snapshot_info.end();)
371 { 899 {
372 if (strcmp(ss->first.video_id.c_str(), taskid.c_str()) == 0) 900 if (strcmp(ss->first.video_id.c_str(), taskid.c_str()) == 0)
373 { 901 {
@@ -375,7 +903,9 @@ void snapshot_reprocessing::release_finished_locus_snapshot(const string taskid, @@ -375,7 +903,9 @@ void snapshot_reprocessing::release_finished_locus_snapshot(const string taskid,
375 VPCUtil::vpc_img_release(ss->second.snapShot); 903 VPCUtil::vpc_img_release(ss->second.snapShot);
376 VPCUtil::vpc_img_release(ss->second.snapShotLittle); 904 VPCUtil::vpc_img_release(ss->second.snapShotLittle);
377 } 905 }
378 - total_snapshot_info.erase(ss); 906 + total_face_snapshot_info.erase(ss++);
379 } 907 }
  908 + else ss++;
380 } 909 }
  910 + return;
381 } 911 }
382 \ No newline at end of file 912 \ No newline at end of file
src/reprocessing_module/snapshot_reprocessing.h
@@ -54,7 +54,11 @@ struct OBJ_VALUE { @@ -54,7 +54,11 @@ struct OBJ_VALUE {
54 float yaw = 0.0; 54 float yaw = 0.0;
55 float pitch = 0.0; 55 float pitch = 0.0;
56 //------------------------------- 56 //-------------------------------
  57 +};
57 58
  59 +struct OBJ_VALUES {
  60 + OBJ_VALUE snapShots[3]; //缓存三张抓拍图 0-轨迹首张 1-轨迹最佳 2-轨迹末张
  61 + bool exists[3] = {false, false, false}; //标识对应抓拍图是否存在
58 }; 62 };
59 63
60 class snapshot_reprocessing 64 class snapshot_reprocessing
@@ -72,13 +76,24 @@ public: @@ -72,13 +76,24 @@ public:
72 void update_bestsnapshot(vector<DeviceMemory*> vec_devMem, vector<onelevel_det_result> &ol_det_result, vector<vector<int>>& delete_object_id); 76 void update_bestsnapshot(vector<DeviceMemory*> vec_devMem, vector<onelevel_det_result> &ol_det_result, vector<vector<int>>& delete_object_id);
73 map<OBJ_KEY, OBJ_VALUE> get_total_snapshot_info(); 77 map<OBJ_KEY, OBJ_VALUE> get_total_snapshot_info();
74 78
75 - void release_finished_locus_snapshot(const string taskid, const int obj_id, bool bRelease); 79 + int update_face_bestsnapshot(vector<DeviceMemory*> vec_devMem, vector<onelevel_det_result> &ol_det_result, vector<vector<int>>& delete_object_id);
  80 + map<OBJ_KEY, OBJ_VALUE> get_total_face_snapshot_info();
  81 +
  82 + void update_village_bestsnapshot(vector<DeviceMemory*> vec_devMem, vector<onelevel_det_result> &ol_det_result, vector<vector<int>>& delete_object_id);
  83 + map<OBJ_KEY, OBJ_VALUES> get_total_village_snapshot_info();
  84 +
  85 + void release_finished_locus_snapshot(const string taskid, const int objid = -1, bool bRelease = true); //-1为删除该路所有任务的快照图
  86 + void release_village_finished_locus_snapshot(const string taskid, const int objid = -1, bool bRelease = true);
  87 + void release_finished_face_locus_snapshot(const string taskid, const int objid = -1, bool bRelease = true);
76 88
77 private: 89 private:
78 bool best_snapshot_judge_algor(const OBJ_KEY& obj_key, const OBJ_VALUE& obj_value, int left, int top, int width, int height, int image_width, int image_height); 90 bool best_snapshot_judge_algor(const OBJ_KEY& obj_key, const OBJ_VALUE& obj_value, int left, int top, int width, int height, int image_width, int image_height);
  91 + bool best_face_snapshot_judge_algor_v2(const OBJ_KEY& obj_key, const OBJ_VALUE& obj_value, int left, int top, int width, int height, int image_width, int image_height, float roll, float yaw, float pitch);
79 92
80 private: 93 private:
81 map<OBJ_KEY, OBJ_VALUE> total_snapshot_info; 94 map<OBJ_KEY, OBJ_VALUE> total_snapshot_info;
  95 + map<OBJ_KEY, OBJ_VALUE> total_face_snapshot_info;
  96 + map<OBJ_KEY, OBJ_VALUES> total_village_snapshot_info;
82 97
83 map<string, set<int>> algor_index_table; 98 map<string, set<int>> algor_index_table;
84 task_param_manager *m_task_param_manager; 99 task_param_manager *m_task_param_manager;
src/util/common_tool.cpp 0 → 100644
  1 +#include "common_tool.h"
  2 +
  3 +
  4 +namespace common {
  5 +
  6 + bool is_intersect(jxline myline1, jxline myline2)
  7 + {
  8 + // 快速排斥实验
  9 + if (myline1.get_max_x() < myline2.get_min_x() ||
  10 + myline2.get_max_x() < myline1.get_min_x() ||
  11 + myline1.get_max_y() < myline2.get_min_y() ||
  12 + myline2.get_max_y() < myline1.get_min_y())
  13 + return false;
  14 +
  15 + // 跨立实验(叉积异号)
  16 + if (((((float)myline1.xa - (float)myline2.xa)*((float)myline2.yb - (float)myline2.ya) - ((float)myline1.ya - (float)myline2.ya)*((float)myline2.xb - (float)myline2.xa))*
  17 + (((float)myline1.xb - (float)myline2.xa)*((float)myline2.yb - (float)myline2.ya) - ((float)myline1.yb - (float)myline2.ya)*((float)myline2.xb - (float)myline2.xa))) > 0 ||
  18 + ((((float)myline2.xa - (float)myline1.xa)*((float)myline1.yb - (float)myline1.ya) - ((float)myline2.ya - (float)myline1.ya)*((float)myline1.xb - (float)myline1.xa))*
  19 + (((float)myline2.xb - (float)myline1.xa)*((float)myline1.yb - (float)myline1.ya) - ((float)myline2.yb - (float)myline1.ya)*((float)myline1.xb - (float)myline1.xa))) > 0)
  20 + return false;
  21 +
  22 + return true;
  23 + }
  24 +}
src/util/common_tool.h 0 → 100644
  1 +#ifndef __COMMON_TOOL_H__
  2 +#define __COMMON_TOOL_H__
  3 +
  4 +
  5 +struct jxline
  6 +{
  7 + int xa;
  8 + int ya;
  9 + int xb;
  10 + int yb;
  11 +
  12 + jxline() {}
  13 + jxline(int xa, int ya, int xb, int yb)
  14 + {
  15 + this->xa = xa;
  16 + this->ya = ya;
  17 + this->xb = xb;
  18 + this->yb = yb;
  19 + }
  20 + int get_max_x()
  21 + {
  22 + return xa > xb ? xa : xb;
  23 + }
  24 + int get_min_x()
  25 + {
  26 + return xa > xb ? xb : xa;
  27 + }
  28 + int get_max_y()
  29 + {
  30 + return ya > yb ? ya : yb;
  31 + }
  32 + int get_min_y()
  33 + {
  34 + return ya > yb ? yb : ya;
  35 + }
  36 +};
  37 +
  38 +namespace common {
  39 + bool is_intersect(jxline myline1, jxline myline2);
  40 +}
  41 +
  42 +
  43 +#endif
0 \ No newline at end of file 44 \ No newline at end of file