#include "MultiSourceProcess.h" #ifdef POST_USE_RABBITMQ #include "../helpers/gen_json.hpp" #endif #include "../helpers/logger.hpp" #include "../helpers/os_helper.hpp" #include "authority.h" #ifdef AUTHORIZATION #include #ifdef _MSC_VER #define productSN "4ACFCBE67EF645AB8F0B4CFCDD1926F1" // WINDOWS #else #define productSN "4FD45501D5104F0C8C4BE530FC872F46" // LINUX #endif #endif #define SKIP_FRAME 5 /** * 注意: gpuFrame 在解码器设置的显卡上,后续操作要十分注意这一点,尤其是多线程情况 * */ void decoded_cbk(const void * userPtr, AVFrame * gpuFrame){ decode_cbk_userdata* ptr = (decode_cbk_userdata*)userPtr; if (ptr!= nullptr) { CMultiSourceProcess* _this = (CMultiSourceProcess*)ptr->opaque; if(nullptr != _this){ _this->post_decode_thread(ptr->_cur_task_param, gpuFrame); } } } void decode_finished_cbk(const void * userPtr){ decode_cbk_userdata* ptr = (decode_cbk_userdata*)userPtr; if (ptr!= nullptr) { CMultiSourceProcess* _this = (CMultiSourceProcess*)ptr->opaque; if(nullptr != _this){ _this->decode_finished_thread(ptr->_cur_task_param); } } } /* @InitAlgorthim * @Description: 初始化全局参数 + 根据配置初始化算法模型 */ int CMultiSourceProcess::InitAlgorthim(tsl_aiplatform_param vptParam) { licence_status_ = -1; thread_status_ = -1; int ret = SUCCESS; #ifdef AUTHORIZATION #ifdef _WIN32 if (SUCCESS == (ret = sy_licence(productSN))) #elif __linux__ char wtime[15]; memset(wtime, 0, 15); char *time = wtime; if (SUCCESS == (ret = sy_licence(productSN, &time))) #endif // #else // ifdef AUTHORIZATION ret = sy_time_check(2023, 2); // license_check(param.auth_license, productSN);// if (ret == SUCCESS) #endif // ifdef AUTHORIZATION { /*初始化全局参数*/ viewTaskID = -1; TaskInPlay = 0; TotalTask = 0; ProcessFlag = false; SourceFlag = false; mModeSnapshotVideo = "cpu"; mModeSnapshotLittle = "cpu"; taskFinishCallbackFunc = nullptr; taskObjInfoCallbackFunc = nullptr; set_default_logger(LogLevel(vptParam.log_level), "multi_source_video_process", vptParam.log_path, vptParam.log_mem, vptParam.log_mem); cuInit(0); int device_count = 0; cuDeviceGetCount(&device_count); if (vptParam.gpuid >= device_count) { LOG_ERROR("gpu id ge host gpu device num ({} vs {})", vptParam.gpuid, device_count); return GPUID_PARAM_ERROR; } CUdevice dev = 0; size_t memSize = 0; dev = vptParam.gpuid; CUresult rlt = CUDA_SUCCESS; rlt = cuDeviceTotalMem(&memSize, dev); gpu_total_memory = (float)memSize / (1024 * 1024); if (gpu_total_memory < 9000) // small gpu memory section_batch_size_ = 10; else section_batch_size_ = 20; /*初始化各个模块:任务管理、快照处理、快照保存、MQ*/ m_task_param_manager = task_param_manager::getInstance(); m_snapshot_reprocessing = snapshot_reprocessing::getInstance(); m_save_snapshot_reprocessing = new save_snapshot_reprocessing(); #ifdef POST_USE_RABBITMQ mq_manager_ = new mq::Manager(); #endif /*初始化各个算法模块*/ /* Init Model */ { VPTProcess_PARAM param{}; { param.gpuid = vptParam.gpuid; // param.threshold = 0.6; param.threshold = 0.45; param.max_batch = section_batch_size_; param.serialize_file = "./serialize_file/FPN_VPT"; param.auth_license = /*vptParam.auth_license*/ "sy_tsl_aiplatform_sdk_2021"; gpu_id_ = vptParam.gpuid; } VPT_Handle_ = nullptr; if (0 != (ret = VPT_Init(VPT_Handle_, param))) { LOG_FATAL("Init VPT failed"); return ret; } #ifdef WITH_SECOND_PROCESS if (!takeaway_member_.init(vptParam.gpuid)) { LOG_FATAL("Init TakeAwayMember failed"); return FALSE; } if (!fight_fall_cls_.init(vptParam.gpuid)) { LOG_FATAL("Init FightFellCls failed"); return FALSE; } if (m_human_gather_statistics.human_gather_statistics_init() != 0) { LOG_FATAL("Init Human Gather failed"); return FALSE; } { hat_callsmoke_vestuniform_det_param init_param; { init_param.gpuid = vptParam.gpuid; init_param.mode = init_param.gpuid >= 0 ? DEVICE_GPU : DEVICE_CPU; init_param.engine = ENGINE_TENSORRT; init_param.max_batch = section_batch_size_; init_param.auth_license = "shiyu_zhian_2021_jetson_sdk"; init_param.serialize_file = "./serialize_file/pedestrian_safety_det"; } if (!pedestrian_safety_detector_.init(init_param)) { LOG_FATAL("Init Pedestrian Safety failure"); return FALSE; } } { // pedestrian_vehicle_retrograde_.init() } #endif #ifdef WITH_FACE_DET_SS // 人脸检测初始化 facedet_ai_engine_param fd_param; fd_param.sdk_param.gpuid = vptParam.gpuid; fd_param.sdk_param.mode = DEVICE_GPU; fd_param.sdk_param.log = SY_CONFIG_CLOSE; fd_param.sdk_param.thresld = 0.6; fd_param.sdk_param.facial_fea_point_config = SY_CONFIG_OPEN; fd_param.sdk_param.pose_config = SY_CONFIG_OPEN; fd_param.sdk_param.quality_config = SY_CONFIG_CLOSE; fd_param.sdk_param.score_config = SY_CONFIG_OPEN; fd_param.sdk_param.max_result_count = 50; fd_param.sdk_param.max_batch_size_detect = section_batch_size_; fd_param.sdk_param.max_batch_size_ldmk = section_batch_size_; fd_param.sdk_param.max_batch_size_score = section_batch_size_; fd_param.sdk_param.max_batch_size_pose = section_batch_size_; fd_param.sdk_param.serialize_file = "./serialize_file/FD"; fd_param.sdk_param.auth_license = "sy_tsl_aiplatform_sdk_2021"; if (0 > m_face_det_ai_engine.init_ai_engine(fd_param)) { LOG_FATAL("Init face detection failed"); return FALSE; } #endif } if (ret == SUCCESS) // { licence_status_ = 0; #ifdef AUTHORIZATION thread_ = boost::thread(check_thread, this); #endif thread_status_ = 0; } } else { return AUTHOR_ERROR; } #ifdef AUTHORIZATION #ifdef __linux__ if (wtime) { delete[] wtime; wtime = NULL; } #endif // #ifdef __linux__ #endif // #ifdef AUTHORIZATION return ret; } bool CMultiSourceProcess::add_task_operation(task_param _cur_task_param){ FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance(); MgrDecConfig config; config.name = _cur_task_param.task_id; config.cfg.uri = _cur_task_param.ipc_url; config.cfg.post_decoded_cbk = decoded_cbk; config.cfg.decode_finished_cbk = decode_finished_cbk; config.cfg.force_tcp = true; // rtsp用tcp config.cfg.gpuid = _cur_task_param.gpu_id_; FFNvDecoder* dec = pDecManager->createDecoder(config); if (!dec) { return false; } decode_cbk_userdata* userPtr = new decode_cbk_userdata; userPtr->_cur_task_param = _cur_task_param; userPtr->opaque = this; pDecManager->setUserPtr(config.name, userPtr); // pDecManager->setDecKeyframe(config.name, true); // 只对关键帧解码 pDecManager->startDecodeByName(config.name); const char* task_id = _cur_task_param.task_id; // 保存新添加任务的配置参数 m_task_param_manager->add_task_param(task_id, _cur_task_param); int input_image_width = 0, input_image_height = 0; pDecManager->getResolution(config.name, input_image_width, input_image_height); #ifdef WITH_SECOND_PROCESS /* 如果开启了行人 机动车非法闯入功能 生成闯入区域mask */ auto new_task_algor_param = m_task_param_manager->get_task_other_param(task_id); if (new_task_algor_param->find(algorithm_type_t::PEDESTRIAN_TRESPASS) != new_task_algor_param->end()) { pedestrian_vehicle_trespass_.pedestrianvehicletrespass_init_region( task_id, algorithm_type_t::PEDESTRIAN_TRESPASS, input_image_width, input_image_height); } if (new_task_algor_param->find(algorithm_type_t::VEHICLE_TRESPASS) != new_task_algor_param->end()) { pedestrian_vehicle_trespass_.pedestrianvehicletrespass_init_region( task_id, algorithm_type_t::VEHICLE_TRESPASS, input_image_width, input_image_height); } #endif ((save_snapshot_reprocessing *)m_save_snapshot_reprocessing)->add_newtask(task_id); // 人车物跟踪 if (task_has_vpt_algor(task_id)) AddTaskTracker(VPT_Handle_, task_id); // 人脸跟踪 #ifdef WITH_FACE_DET_SS if (task_has_face_algor(task_id)) m_face_det_ai_engine.operator_tracker(task_id, ADDTASK, SKIP_FRAME); // 跳帧数暂时写死 #endif // 启动算法处理线程 startProcessByGpuid(_cur_task_param.gpu_id_); } // 启动算法处理线程 void CMultiSourceProcess::startProcessByGpuid(const string gpuid){ struct ThreadArg{ const string gpu_id; void* opaque; }; ThreadArg thread_arg = {gpuid, this}; pthread_t* processThread = gpuProcessthreadMap[gpuid]; if(processThread){ pthread_t* pTread = new pthread_t; pthread_create(pTread,0, [](void* arg) { ThreadArg* ptr=(ThreadArg*)arg; if(ptr != nullptr){ CMultiSourceProcess* process = (CMultiSourceProcess*)ptr->opaque ; process->algorthim_process_thread(ptr->gpu_id); } return (void*)0; } ,&thread_arg); gpuProcessthreadMap[gpuid] = pTread; } } void CMultiSourceProcess::post_decode_thread(task_param _cur_task_param, AVFrame * gpuFrame){ if (gpuFrame->format == AV_PIX_FMT_CUDA){ GpuRgbMemory* gpuMem = new GpuRgbMemory(3, gpuFrame->width, gpuFrame->height, _cur_task_param.task_id, _cur_task_param.gpu_id_ , true); cudaSetDevice(atoi(_cur_task_param.gpu_id_)); cuda_common::setColorSpace( ITU_709, 0 ); cudaError_t cudaStatus = cuda_common::CUDAToBGR((CUdeviceptr)gpuFrame->data[0],(CUdeviceptr)gpuFrame->data[1], gpuFrame->linesize[0], gpuFrame->linesize[1], gpuMem->getMem(), gpuFrame->width, gpuFrame->height); cudaDeviceSynchronize(); if (cudaStatus != cudaSuccess) { cout << "CUDAToBGR failed !!!" << endl; return; } do{ // TODO 本循环需要一个可以手动终止的开关 m_QueueMtx.lock(); if(m_queueRgbData.size() >= 40){ m_QueueMtx.unlock(); std::this_thread::sleep_for(std::chrono::milliseconds(1)); continue; } m_queueRgbData.push(gpuMem); m_QueueMtx.unlock(); break; }while (true); } } void CMultiSourceProcess::decode_finished_thread(task_param t_param){ // 任务结束,关闭跟踪 if (!FinishTaskTracker(VPT_Handle_, t_param.task_id)) LOG_ERROR("Finish VPT Tracker failed, task_id: {}", t_param.task_id); } bool CMultiSourceProcess::task_has_vpt_algor(const std::string &task_id){ //! TODO: create enum iterator. auto algor_map = m_task_param_manager->get_task_other_param(task_id); if (algor_map == nullptr) return false; return (algor_map->find(algorithm_type_t::HUMAN_GATHER) != algor_map->end() || algor_map->find(algorithm_type_t::HUMAN_SNAPSHOT) != algor_map->end() || algor_map->find(algorithm_type_t::NONMOTOR_VEHICLE_SNAPSHOT) != algor_map->end() || algor_map->find(algorithm_type_t::SMOKING_DET) != algor_map->end() || algor_map->find(algorithm_type_t::NO_REFLECTIVE_CLOTHING) != algor_map->end() || algor_map->find(algorithm_type_t::NO_SAFETY_HELMET) != algor_map->end() || algor_map->find(algorithm_type_t::CALL_PHONE_DET) != algor_map->end() || algor_map->find(algorithm_type_t::VEHICLE_SNAPSHOT) != algor_map->end() || algor_map->find(algorithm_type_t::TAKEAWAY_MEMBER_CLASSIFICATION) != algor_map->end() || algor_map->find(algorithm_type_t::PEDESTRIAN_FALL) != algor_map->end() || algor_map->find(algorithm_type_t::PEDESTRIAN_FIGHT) != algor_map->end() || algor_map->find(algorithm_type_t::PEDESTRIAN_RETROGRADE) != algor_map->end() || algor_map->find(algorithm_type_t::VEHICLE_RETROGRADE) != algor_map->end() || algor_map->find(algorithm_type_t::PEDESTRIAN_TRESPASS) != algor_map->end() || algor_map->find(algorithm_type_t::VEHICLE_TRESPASS) != algor_map->end()); } bool CMultiSourceProcess::task_has_face_algor(const std::string &task_id){ auto algor_map = m_task_param_manager->get_task_other_param(task_id); return algor_map->find(algorithm_type_t::FACE_SNAPSHOT) != algor_map->end(); } void CMultiSourceProcess::cuda_free_wrap(sy_img &img) { CHECK(cudaFree(img.data_)) { img.c_ = 0; img.h_ = 0; img.w_ = 0; img.data_ = nullptr; } } // 算法处理函数,由算法线程调用 void CMultiSourceProcess::algorthim_process_thread(const string gpuid){ map task_id_to_n_frame; while(true){ /* step1. 授权check */ if (licence_status_ <= -3) { LOG_FATAL("authority failed!"); break; } /* step5. 凑齐的解码数据 拼batch */ m_QueueMtx.lock(); int batch_size = m_queueRgbData.size(); if(batch_size > 20){ batch_size = 20; } vector task_list; sy_img *batch_img = new sy_img[batch_size]; vector vec_gpuMem; for (size_t i = 0; i < batch_size; i++){ GpuRgbMemory* gpuMem = m_queueRgbData.front(); batch_img[i].set_data(gpuMem->getWidth(), gpuMem->getHeight(), gpuMem->getChannel(), gpuMem->getMem()); task_list.push_back(gpuMem->getId()); ++task_id_to_n_frame[gpuMem->getId()]; vec_gpuMem.push_back(gpuMem); m_queueRgbData.pop(); } m_QueueMtx.unlock(); // VPT 检测 algorthim_vpt(task_list, batch_img); #ifdef WITH_FACE_DET_SS algorthim_face_detect(task_list, batch_img); #endif // 清理显存 for (size_t i = 0; i < vec_gpuMem.size(); i++){ GpuRgbMemory* gpuMem = vec_gpuMem[i]; delete gpuMem; gpuMem = nullptr; } vec_gpuMem.clear(); if (batch_img != nullptr) { delete[] batch_img; batch_img = nullptr; } } #ifdef WITH_SECOND_PROCESS { std::string msg("taskId to n_frame pair has"); for (auto &iter : task_id_to_n_frame) msg.append(fmt::format("({}: {})", iter.first.c_str(), iter.second)); for (auto &iter : task_id_to_n_frame) { auto &task_id = iter.first; pedestrian_safety_detector_.force_release_result(task_id); pedestrian_vehicle_retrograde_.force_release_result(task_id); takeaway_member_.force_release_result(task_id); } LOG_DEBUG("{}", msg); } #endif } // VPT 检测 void CMultiSourceProcess::algorthim_vpt(vector& task_list, sy_img *batch_img){ vector vpt_interest_task_id; std::vector vpt_interest_imgs(0); for (size_t i = 0; i < task_list.size(); i++){ string task_id = task_list[i]; if (!task_has_vpt_algor(task_id)) continue; vpt_interest_task_id.push_back(task_id); vpt_interest_imgs.emplace_back(batch_img[i]); } /* 待检测的图片不为空 开始检测 */ if (!vpt_interest_imgs.empty()) { vector> deleteObjectID; deleteObjectID.resize(vpt_interest_task_id.size()); vector> unUsedResult; vector vptResult(0); /* 一级检测器,内部已完成跟踪操作 */ VPT_Process_GPU2(VPT_Handle_, vpt_interest_imgs.data(), vpt_interest_task_id, vptResult, deleteObjectID, unUsedResult); // do det & track. /* 每帧都需要进行的操作函数(如人数统计功能) */ everyframe_process(vpt_interest_task_id, vpt_interest_imgs.data(), vptResult); // modified by zsh /* 根据任务的配置 对目标进行筛选 */ m_snapshot_reprocessing->screen_effective_snapshot2(vpt_interest_task_id, vptResult); // #ifdef MTASK_DEBUG_ int idx_tmp = 0; for (auto task_id : vpt_interest_task_id) LOG_DEBUG("after screen_effective_snapshot task_id {} obj count {}", task_id, vptResult[idx_tmp++].obj_count); #endif /* 快照优选(内部可实现不同的快照优选策略) */ m_snapshot_reprocessing->update_bestsnapshot2(vpt_interest_task_id, vpt_interest_imgs.data(), vptResult, deleteObjectID); #ifdef WITH_SECOND_PROCESS /* for pedestrian safety det. 行人安全分析算法模块 */ algorthim_pedestrian_safety(vpt_interest_task_id, vpt_interest_imgs,vptResult); /* for retrograde & trespass algor 逆行&非法闯入算法模块 */ algorthim_retrograde_trespass(vpt_interest_task_id, vpt_interest_imgs,vptResult,deleteObjectID); #endif /* for snapshot algorithm. 轨迹结束目标 做最后的结果返回(当前返回算法结果+快照保存路径)*/ algorithm_snapshot(vpt_interest_task_id, deleteObjectID); #ifdef WITH_SECOND_PROCESS /* for fight fall cls. sync code. 打架跌倒算法模块 */ algorithm_fight_fall(vpt_interest_task_id, vpt_interest_imgs, vptResult); /* for takeaway member. 外卖员分析模块 */ algorithm_takeaway_member_cls(vpt_interest_task_id, vpt_interest_imgs, vptResult); #endif } } // 行人安全分析算法模块 void CMultiSourceProcess::algorthim_pedestrian_safety(vector& vpt_interest_task_id, vector& vpt_interest_imgs, vector& vptResult){ #ifdef WITH_SECOND_PROCESS vector interest_task_id; vector interest_vpt_result; vector interest_imgs(0); int _idx = 0; for (auto _task_id_iter = vpt_interest_task_id.begin(); _task_id_iter != vpt_interest_task_id.end(); ++_task_id_iter, ++_idx) // loop task_id; { auto task_id = *_task_id_iter; auto algor_map = m_task_param_manager->get_task_other_param(task_id); if (algor_map->find(algorithm_type_t::NO_REFLECTIVE_CLOTHING) != algor_map->end() || algor_map->find(algorithm_type_t::NO_SAFETY_HELMET) != algor_map->end() || algor_map->find(algorithm_type_t::CALL_PHONE_DET) != algor_map->end() || algor_map->find(algorithm_type_t::SMOKING_DET) != algor_map->end()) { interest_task_id.emplace_back(task_id); interest_imgs.emplace_back(vpt_interest_imgs[_idx]); interest_vpt_result.emplace_back(vptResult[_idx]); } } if (!interest_imgs.empty()) pedestrian_safety_detector_.update_mstreams2(interest_task_id, interest_imgs.data(), interest_vpt_result); #endif } // 逆行&非法闯入算法模块 void CMultiSourceProcess::algorthim_retrograde_trespass(vector& vpt_interest_task_id, vector& vpt_interest_imgs , vector& vptResult ,vector>& deleteObjectID){ #ifdef WITH_SECOND_PROCESS vector interest_task_id; vector interest_vpt_result; vector interest_imgs(0); vector trespass_interest_task_id; vector trespass_interest_vpt_result; vector> trespass_interest_deleteobjs; vector trespass_interest_imgs(0); int _idx = 0; for (auto _task_id_iter = vpt_interest_task_id.begin(); _task_id_iter != vpt_interest_task_id.end(); ++_task_id_iter, ++_idx) // loop task_id; { auto task_id = *_task_id_iter; auto algor_map = m_task_param_manager->get_task_other_param(task_id); if (algor_map->find(algorithm_type_t::PEDESTRIAN_RETROGRADE) != algor_map->end() || algor_map->find(algorithm_type_t::VEHICLE_RETROGRADE) != algor_map->end()) { interest_task_id.emplace_back(task_id); interest_imgs.emplace_back(vpt_interest_imgs[_idx]); interest_vpt_result.emplace_back(vptResult[_idx]); } if (algor_map->find(algorithm_type_t::PEDESTRIAN_TRESPASS) != algor_map->end() || algor_map->find(algorithm_type_t::VEHICLE_TRESPASS) != algor_map->end()) { trespass_interest_task_id.emplace_back(task_id); trespass_interest_imgs.emplace_back(vpt_interest_imgs[_idx]); trespass_interest_vpt_result.emplace_back(vptResult[_idx]); trespass_interest_deleteobjs.emplace_back(deleteObjectID[_idx]); } } if (!interest_imgs.empty()) pedestrian_vehicle_retrograde_.update_mstreams2(interest_task_id, interest_imgs.data(), interest_vpt_result); if (!trespass_interest_imgs.empty()) { pedestrian_vehicle_trespass_.update_mstreams2( trespass_interest_task_id, trespass_interest_imgs.data(), trespass_interest_vpt_result, trespass_interest_deleteobjs); } #endif } // for snapshot algorithm. 轨迹结束目标 做最后的结果返回(当前返回算法结果+快照保存路径) void CMultiSourceProcess::algorithm_snapshot(vector& vpt_interest_task_id, vector> deleteObjectID) { auto task_iter = vpt_interest_task_id.begin(); for (int i = 0; i < deleteObjectID.size(); i++, ++task_iter) // loop taskId. { for (int &j : deleteObjectID[i]) // loop algor type. { OBJ_KEY obj_key = {*task_iter, j}; endframe_obj_process(obj_key, algorithm_type_t::PLACEHOLDER); } vector().swap(deleteObjectID[i]); // free. } vector>().swap(deleteObjectID); // free. } /* 轨迹结束帧需要做的算法模块 */ int CMultiSourceProcess::endframe_obj_process(const OBJ_KEY &obj_key, algorithm_type_t algor_type) { auto task_param_ptr = m_task_param_manager->get_task_algor_param(obj_key.video_id); auto task_other_param_ptr = m_task_param_manager->get_task_other_param(obj_key.video_id); // 该路任务开启了抓拍功能 开始抓拍保存;若未开启抓拍,清空显存资源 if ((task_param_ptr->human_algors.find(algorithm_type_t::HUMAN_SNAPSHOT) != task_param_ptr->human_algors.end() || task_param_ptr->vehicle_algors.find(algorithm_type_t::VEHICLE_SNAPSHOT) != task_param_ptr->vehicle_algors.end() || task_param_ptr->nonmotor_vehicle_algors.find(algorithm_type_t::NONMOTOR_VEHICLE_SNAPSHOT) != task_param_ptr->nonmotor_vehicle_algors.end())) { #ifdef MTASK_DEBUG_ LOG_DEBUG("task_id {} endframe_obj_process obj_id {}", obj_key.video_id, obj_key.obj_id); #endif m_save_snapshot_reprocessing->reprocessing_process(obj_key); } else { // printf("delete snapshot\n"); m_snapshot_reprocessing->delete_finishtask_snapshot(obj_key.video_id, obj_key.obj_id); } #ifdef WITH_SECOND_PROCESS /* 开启外卖员算法模块,获取该目标的算法分析结果 返回结果+快照 最后释放资源 */ if (task_param_ptr->nonmotor_vehicle_algors.find(algorithm_type_t::TAKEAWAY_MEMBER_CLASSIFICATION) != task_param_ptr->nonmotor_vehicle_algors.end()) { auto result = takeaway_member_.get_result_by_objectid(ai_engine_module::obj_key_t{ obj_key.obj_id, obj_key.video_id, algorithm_type_t::TAKEAWAY_MEMBER_CLASSIFICATION}); if (result.get()) { auto json_str = helpers::gen_json::gen_takeaway_member_cls_json(obj_key.video_id, obj_key.obj_id, result->box, result->category); save_snapshot_process(obj_key, algorithm_type_t::TAKEAWAY_MEMBER_CLASSIFICATION, result->ori_img, result->roi_img, 0, json_str); CHECK(cudaFree((void *)(result->roi_img.data_))); CHECK(cudaFree((void *)(result->ori_img.data_))); } } /* 开启行人&机动车逆行算法模块,获取该目标的算法分析结果 返回结果+快照 最后释放资源 */ if (task_param_ptr->human_algors.find(algorithm_type_t::PEDESTRIAN_RETROGRADE) != task_param_ptr->human_algors.end() || task_param_ptr->vehicle_algors.find(algorithm_type_t::VEHICLE_RETROGRADE) != task_param_ptr->vehicle_algors.end()) { auto func_wrap = [&](const algorithm_type_t &algor_type) { auto results = pedestrian_vehicle_retrograde_.get_results_by_id( ai_engine_module::obj_key_t{obj_key.obj_id, obj_key.video_id, algor_type}); if (results) { bool flag_pRetroGrade{true}, flag_vRetroGrade{true}; // modified by zsh for (unsigned idx = 0; idx < results->size(); ++idx) { auto &result = results->at(idx); // modified by zsh 一个id一种事件只报警一次------------------------------------------------------------------ if(algor_type==algorithm_type_t::PEDESTRIAN_RETROGRADE && flag_pRetroGrade == true) { auto &&json_str = helpers::gen_json::gen_retrograde_json(obj_key.video_id, obj_key.obj_id, result.box, algor_type); save_snapshot_process(obj_key, algor_type, result.ori_img, result.roi_img, /*id=*/idx, json_str, true, result.ori_img_is_in_gpu, result.roi_img_is_in_gpu); flag_pRetroGrade = false; } if(algor_type==algorithm_type_t::VEHICLE_RETROGRADE && flag_vRetroGrade == true) { auto &&json_str = helpers::gen_json::gen_retrograde_json(obj_key.video_id, obj_key.obj_id, result.box, algor_type); save_snapshot_process(obj_key, algor_type, result.ori_img, result.roi_img, /*id=*/idx, json_str, true, result.ori_img_is_in_gpu, result.roi_img_is_in_gpu); flag_vRetroGrade = false; } // ------------------------------------------------------------------------------------------------------- if(0) { auto &&json_str = helpers::gen_json::gen_retrograde_json(obj_key.video_id, obj_key.obj_id, result.box, algor_type); save_snapshot_process(obj_key, algor_type, result.ori_img, result.roi_img, /*id=*/idx, json_str, true, result.ori_img_is_in_gpu, result.roi_img_is_in_gpu); } if (result.roi_img.data_ != nullptr) { if (result.roi_img_is_in_gpu) { LOG_DEBUG("free roi gpu memory."); CHECK(cudaFree((void *)(result.roi_img.data_))) } result.roi_img.data_ = nullptr; } if (result.ori_img.data_ != nullptr) { if (result.ori_img_is_in_gpu) { LOG_DEBUG("free ori gpu memory."); CHECK(cudaFree((void *)(result.ori_img.data_))) } result.ori_img.data_ = nullptr; } } } }; if (task_param_ptr->human_algors.find(algorithm_type_t::PEDESTRIAN_RETROGRADE) != task_param_ptr->human_algors.end()) func_wrap(algorithm_type_t::PEDESTRIAN_RETROGRADE); if (task_param_ptr->vehicle_algors.find(algorithm_type_t::VEHICLE_RETROGRADE) != task_param_ptr->vehicle_algors.end()) func_wrap(algorithm_type_t::VEHICLE_RETROGRADE); } /* 开启行人&机动车非法闯入算法模块,获取该目标的算法分析结果 返回结果+快照 最后释放资源 */ if (task_param_ptr->human_algors.find(algorithm_type_t::PEDESTRIAN_TRESPASS) != task_param_ptr->human_algors.end() || task_param_ptr->vehicle_algors.find(algorithm_type_t::VEHICLE_TRESPASS) != task_param_ptr->vehicle_algors.end()) { auto func_wrap = [&](const algorithm_type_t &algor_type) { auto results = pedestrian_vehicle_trespass_.get_results_by_id( ai_engine_module::obj_key_t{obj_key.obj_id, obj_key.video_id, algor_type}); if (results) { bool flag_pThePass{true}, flag_vThePass{true}; // modified by zsh for (unsigned idx = 0; idx < results->size(); ++idx) { auto &result = results->at(idx); // modified by zsh 一个id一种事件只报警一次------------------------------------------------------------------ if(algor_type==algorithm_type_t::PEDESTRIAN_TRESPASS && flag_pThePass == true) { auto &&json_str = helpers::gen_json::gen_retrograde_json(obj_key.video_id, obj_key.obj_id, result.box, algor_type); save_snapshot_process(obj_key, algor_type, result.ori_img, result.roi_img, /*id=*/idx, json_str, true, result.ori_img_is_in_gpu, result.roi_img_is_in_gpu); flag_pThePass = false; } if(algor_type==algorithm_type_t::VEHICLE_TRESPASS && flag_vThePass == true) { auto &&json_str = helpers::gen_json::gen_retrograde_json(obj_key.video_id, obj_key.obj_id, result.box, algor_type); save_snapshot_process(obj_key, algor_type, result.ori_img, result.roi_img, /*id=*/idx, json_str, true, result.ori_img_is_in_gpu, result.roi_img_is_in_gpu); flag_vThePass = false; } // ------------------------------------------------------------------------------------------------------- if(0) { auto &&json_str = helpers::gen_json::gen_retrograde_json(obj_key.video_id, obj_key.obj_id, result.box, algor_type); // printf("%s\n", json_str.c_str()); save_snapshot_process(obj_key, algor_type, result.ori_img, result.roi_img, /*id=*/idx, json_str, true, result.ori_img_is_in_gpu, result.roi_img_is_in_gpu); } if (result.roi_img.data_ != nullptr) { if (result.roi_img_is_in_gpu) CHECK(cudaFree((void *)(result.roi_img.data_))) result.roi_img.data_ = nullptr; } if (result.ori_img.data_ != nullptr) { if (result.ori_img_is_in_gpu) CHECK(cudaFree((void *)(result.ori_img.data_))) result.ori_img.data_ = nullptr; } } } }; if (task_param_ptr->human_algors.find(algorithm_type_t::PEDESTRIAN_TRESPASS) != task_param_ptr->human_algors.end()) func_wrap(algorithm_type_t::PEDESTRIAN_TRESPASS); if (task_param_ptr->vehicle_algors.find(algorithm_type_t::VEHICLE_TRESPASS) != task_param_ptr->vehicle_algors.end()) func_wrap(algorithm_type_t::VEHICLE_TRESPASS); } /* 开启行人安全分析算法模块,获取该目标的算法分析结果 返回结果+快照 最后释放资源 */ if (task_param_ptr->human_algors.find(algorithm_type_t::NO_REFLECTIVE_CLOTHING) != task_param_ptr->human_algors.end() || task_param_ptr->human_algors.find(algorithm_type_t::NO_SAFETY_HELMET) != task_param_ptr->human_algors.end() || task_param_ptr->human_algors.find(algorithm_type_t::CALL_PHONE_DET) != task_param_ptr->human_algors.end() || task_param_ptr->human_algors.find(algorithm_type_t::SMOKING_DET) != task_param_ptr->human_algors.end()) { LOG_TRACE("get result task_id {} obj_id {}", obj_key.video_id, obj_key.obj_id); auto results = pedestrian_safety_detector_.get_results_by_id( ai_engine_module::unique_obj_id_t{obj_key.obj_id, obj_key.video_id}); // auto results = std::shared_ptr(nullptr); if (results) { //! loop per pedestrian safety attribute. long id = 0; bool flag_nReflect{true}, flag_nHelmet{true}, flag_cPhone{true}, flag_smoking{true}; // modified by zsh LOG_DEBUG(" size of results is {}", results->size()); for (auto result : *results) { for (auto algor_type_iter = result.algorithm_type_seq.begin(); algor_type_iter != result.algorithm_type_seq.end(); ++algor_type_iter) { auto algor_type = *algor_type_iter; // modified by zsh 一个id一种事件只报警一次------------------------------------------------------------------ if(algor_type==algorithm_type_t::NO_REFLECTIVE_CLOTHING && flag_nReflect == true) { auto json_str = helpers::gen_json::gen_pedestrian_safety_json(obj_key.video_id, obj_key.obj_id, result.box, algor_type); save_snapshot_process(obj_key, algor_type, result.ori_img, result.roi_img, /*id=*/id++, json_str, true, result.ori_img_is_in_gpu, result.roi_img_is_in_gpu); flag_nReflect = false; LOG_TRACE("PEDESTRIAN task_id {} obj_id {} algor_type {}", obj_key.video_id, obj_key.obj_id, int(algor_type)); } if(algor_type==algorithm_type_t::NO_SAFETY_HELMET && flag_nHelmet == true) { auto json_str = helpers::gen_json::gen_pedestrian_safety_json(obj_key.video_id, obj_key.obj_id, result.box, algor_type); save_snapshot_process(obj_key, algor_type, result.ori_img, result.roi_img, /*id=*/id++, json_str, true, result.ori_img_is_in_gpu, result.roi_img_is_in_gpu); flag_nHelmet = false; LOG_TRACE("PEDESTRIAN task_id {} obj_id {} algor_type {}", obj_key.video_id, obj_key.obj_id, int(algor_type)); } if(algor_type==algorithm_type_t::CALL_PHONE_DET && flag_cPhone == true) { auto json_str = helpers::gen_json::gen_pedestrian_safety_json(obj_key.video_id, obj_key.obj_id, result.box, algor_type); save_snapshot_process(obj_key, algor_type, result.ori_img, result.roi_img, /*id=*/id++, json_str, true, result.ori_img_is_in_gpu, result.roi_img_is_in_gpu); flag_cPhone = false; LOG_TRACE("PEDESTRIAN task_id {} obj_id {} algor_type {}", obj_key.video_id, obj_key.obj_id, int(algor_type)); } if(algor_type==algorithm_type_t::SMOKING_DET && flag_smoking == true) { auto json_str = helpers::gen_json::gen_pedestrian_safety_json(obj_key.video_id, obj_key.obj_id, result.box, algor_type); save_snapshot_process(obj_key, algor_type, result.ori_img, result.roi_img, /*id=*/id++, json_str, true, result.ori_img_is_in_gpu, result.roi_img_is_in_gpu); flag_smoking = false; LOG_TRACE("PEDESTRIAN task_id {} obj_id {} algor_type {}", obj_key.video_id, obj_key.obj_id, int(algor_type)); } // ------------------------------------------------------------------------------------------------------- if(0) { LOG_TRACE("PEDESTRIAN task_id {} obj_id {} algor_type {}", obj_key.video_id, obj_key.obj_id, int(algor_type)); auto json_str = helpers::gen_json::gen_pedestrian_safety_json(obj_key.video_id, obj_key.obj_id, result.box, algor_type); save_snapshot_process(obj_key, algor_type, result.ori_img, result.roi_img, /*id=*/id++, json_str, true, result.ori_img_is_in_gpu, result.roi_img_is_in_gpu); } } if (result.roi_img.data_ != nullptr) { if (result.roi_img_is_in_gpu) CHECK(cudaFree((void *)(result.roi_img.data_))); result.roi_img.data_ = nullptr; } if (result.ori_img.data_ != nullptr) { if (result.ori_img_is_in_gpu) CHECK(cudaFree((void *)(result.ori_img.data_))); result.ori_img.data_ = nullptr; } } } } #endif /* 开启人脸抓拍分析算法模块,获取该目标的算法分析结果 返回结果+快照 最后释放资源 */ if (task_other_param_ptr->find(algorithm_type_t::FACE_SNAPSHOT) != task_other_param_ptr->end() && algor_type == algorithm_type_t::FACE_SNAPSHOT) { LOG_TRACE("--- face snapshot will save snapshot IAMGE, task: {} obj: {}.", obj_key.video_id, obj_key.obj_id); m_save_snapshot_reprocessing->reprocessing_process_face(obj_key); } return 0; } // 打架跌倒算法模块 void CMultiSourceProcess::algorithm_fight_fall(vector& vpt_interest_task_id, vector& vpt_interest_imgs, vector& vptResult){ #ifdef WITH_SECOND_PROCESS /* a. find fight or fall classification taskId. */ vector interest_task_id; vector interest_vpt_result; vector interest_imgs(0); int _idx = 0; for (auto _task_id_iter = vpt_interest_task_id.begin(); _task_id_iter != vpt_interest_task_id.end(); ++_task_id_iter, ++_idx) // loop task_id; { const auto &task_id = *_task_id_iter; auto algor_map = m_task_param_manager->get_task_other_param(task_id); if (algor_map->find(algorithm_type_t::PEDESTRIAN_FIGHT) != algor_map->end() || algor_map->find(algorithm_type_t::PEDESTRIAN_FALL) != algor_map->end()) { interest_task_id.emplace_back(task_id); interest_imgs.emplace_back(vpt_interest_imgs[_idx]); interest_vpt_result.emplace_back(vptResult[_idx]); } } /* b. process result. */ if (!interest_imgs.empty()) { std::vector results; fight_fall_cls_.process_mstreams2(interest_task_id, interest_imgs.data(), interest_vpt_result, results); for (auto &result : results) { for (auto &res : result.fight_data) { auto &taskId = res.taskid; auto json_str = helpers::gen_json::gen_pedestrian_fight_json(res, ""); save_snapshot_process(OBJ_KEY{taskId, (int)*res.objectids.begin()}, algorithm_type_t::PEDESTRIAN_FIGHT, res.ori_img, res.roi_img, res.id, json_str, false); cuda_free_wrap(res.roi_img); } for (auto &res : result.fall_data) { auto &taskId = res.taskid; auto json_str = helpers::gen_json::gen_pedestrian_fall_json(res, ""); save_snapshot_process(OBJ_KEY{taskId, (int)res.objectid}, algorithm_type_t::PEDESTRIAN_FALL, res.ori_img, res.roi_img, res.id, json_str, false); cuda_free_wrap(res.roi_img); } } } #endif } void CMultiSourceProcess::algorithm_takeaway_member_cls(vector& vpt_interest_task_id, vector& vpt_interest_imgs , vector& vptResult){ #ifdef WITH_SECOND_PROCESS /* find takeaway member classification taskId. */ vector interest_task_id; vector interest_vpt_result; vector interest_imgs(0); int _idx = 0; for (auto _task_id_iter = vpt_interest_task_id.begin(); _task_id_iter != vpt_interest_task_id.end(); ++_task_id_iter, ++_idx) // loop task_id; { const auto &task_id = *_task_id_iter; auto algor_map = m_task_param_manager->get_task_other_param(task_id); if (algor_map->find(algorithm_type_t::TAKEAWAY_MEMBER_CLASSIFICATION) == algor_map->end()) continue; interest_task_id.emplace_back(task_id); interest_imgs.emplace_back(vpt_interest_imgs[_idx]); interest_vpt_result.emplace_back(vptResult[_idx]); } if (!interest_imgs.empty()) takeaway_member_.update_mstreams2(interest_task_id, interest_imgs.data(), interest_vpt_result); #endif } /* 每帧都需要做的算法模块 */ int CMultiSourceProcess::everyframe_process(vector &task_in_play_id, sy_img *images, vector &ol_det_result) { #ifdef WITH_SECOND_PROCESS /* 人数聚集算法功能 每帧都会获取算法结果 并返回 */ auto results = m_human_gather_statistics.human_gather_statistics_process2(task_in_play_id, images, ol_det_result); for (auto &result : results) { #ifdef POST_USE_RABBITMQ auto json_str = helpers::gen_json::gen_human_gather_json(result.task_id, result.boxes, ""); #endif auto task_id = result.task_id; auto task_other_params = m_task_param_manager->get_task_other_param(task_id); const auto &algor_other_params = task_other_params->find(algorithm_type_t::HUMAN_GATHER); if (algor_other_params == task_other_params->end()) { LOG_ERROR("[Error] taskId {} not found algor {}", task_id.c_str(), (int)algorithm_type_t::HUMAN_GATHER); continue; } const algor_basic_config_param_t *basic_param = algor_other_params->second->basic_param; // modified by zsh 图片名添加时间戳---------------------------------------------------------------------------------------- std::string cur_timestamp_ms = std::to_string(helpers::timer::get_timestamp()); const std::string fpath_ori = basic_param->result_folder + helpers::os::sep + task_id + "_" + std::to_string(result.boxes.size()) + "_" + std::to_string(result.id) + "_" + cur_timestamp_ms + ".jpg"; //------------------------------------------------------------------------------------------------------------------------ multi_image_t m_image(*result.img, sy_img()); { m_image.ori_fpath = fpath_ori; m_image.ori_data_device = data_device_t::GPU; } OBJ_KEY obj_key{task_id, 0}; m_save_snapshot_reprocessing->reprocessing_process_wo_locus(obj_key, m_image, true #ifdef POST_USE_RABBITMQ , json_str #endif ); } #endif return 0; } /* 实现快照保存功能(还未真正保存 将显存图片cp到内存 * 直接保存本地或者存入缓存队列异步保存,保存方式看需求,报警类需要同步保存报警,分析类可异步保存后返回) */ bool CMultiSourceProcess::save_snapshot_process(const OBJ_KEY &obj_key, const algorithm_type_t &algorithm_type, const sy_img &ori_img, const sy_img &roi_img, const long long id, const std::string &json_str, bool enable_async, const bool ori_img_is_in_gpu, const bool roi_img_is_in_gpu) { auto task_other_params = m_task_param_manager->get_task_other_param(obj_key.video_id); const auto &algor_other_params = task_other_params->find(algorithm_type); if (algor_other_params == task_other_params->end()) { LOG_ERROR("task_id {} not found {} error", obj_key.video_id, int(algorithm_type)); return false; } // TODO const algor_basic_config_param_t *basic_param = algor_other_params->second->basic_param; // modified by zsh 图片名添加时间戳---------------------------------------------------------------------------------------- std::string cur_timestamp_ms = std::to_string(helpers::timer::get_timestamp()); const std::string fpath_ori = basic_param->result_folder + helpers::os::sep + obj_key.video_id + "_" + std::to_string(obj_key.obj_id) + "_" + std::to_string(id) + "_" + cur_timestamp_ms + ".jpg"; const std::string fpath_roi = basic_param->result_folder_little + helpers::os::sep + obj_key.video_id + "_" + std::to_string(obj_key.obj_id) + "_" + std::to_string(id) + "_" + cur_timestamp_ms + ".jpg"; //------------------------------------------------------------------------------------------------------------------------ multi_image_t m_image(ori_img, roi_img); { m_image.ori_fpath = fpath_ori; m_image.roi_fpath = fpath_roi; m_image.ori_data_device = ori_img_is_in_gpu ? data_device_t::GPU : data_device_t::CPU; m_image.roi_data_device = roi_img_is_in_gpu ? data_device_t::GPU : data_device_t::CPU; } // 调用快照保存后处理模块 将快照保存 m_save_snapshot_reprocessing->reprocessing_process_wo_locus(obj_key, m_image, enable_async #ifdef POST_USE_RABBITMQ , json_str #endif ); return true; } // 人脸检测抓拍算法模块 void CMultiSourceProcess::algorthim_face_detect(vector& task_list, sy_img *batch_img){ #if 0 unsigned image_size = task_list.size(); std::vector facedet_result(image_size); std::vector> face_deleteObjectID(image_size); m_face_det_ai_engine.ai_engine_process_batch2(task_list, batch_img, image_size, facedet_result, face_deleteObjectID); // 跟踪结果送入快照更新 m_snapshot_reprocessing->update_face_bestsnapshot2(task_list, batch_img, facedet_result, face_deleteObjectID); #else vector face_det_interest_task_id; std::vector face_det_interest_imgs(0); int _idx = 0; for (auto _task_id_iter = task_list.begin(); _task_id_iter != task_list.end(); ++_task_id_iter, ++_idx) // loop task_id; { const auto &task_id = *_task_id_iter; if (!task_has_face_algor(task_id)) continue; face_det_interest_task_id.emplace_back(task_id); face_det_interest_imgs.emplace_back(batch_img[_idx]); } if (!face_det_interest_imgs.empty()) { unsigned image_size = face_det_interest_imgs.size(); // 人脸检测、跟踪 std::vector facedet_result(image_size); std::vector> face_deleteObjectID(image_size); m_face_det_ai_engine.ai_engine_process_batch2(face_det_interest_task_id, face_det_interest_imgs.data(), face_det_interest_imgs.size(), facedet_result, face_deleteObjectID); #if 0 // accum int32_t accum = 0; for (const auto &it: facedet_result) accum += it.obj_count; LOG_TRACE(" face result has: {}", accum); #endif // 跟踪结果送入快照更新 m_snapshot_reprocessing->update_face_bestsnapshot2( face_det_interest_task_id, face_det_interest_imgs.data(), facedet_result, face_deleteObjectID); // 保存已结束轨迹的目标 // auto task_iter_face = pThreadParam->TaskInPlayID.begin(); auto task_iter_face = face_det_interest_task_id.begin(); //debug by zsh for (int i = 0; i < face_deleteObjectID.size(); i++) { for (int j = 0; j < face_deleteObjectID[i].size(); ++j) { OBJ_KEY deleteObj = {*task_iter_face, face_deleteObjectID[i][j]}; LOG_TRACE("[info]22222: {}: {}",*task_iter_face,face_deleteObjectID[i][j]); endframe_obj_process(deleteObj, algorithm_type_t::FACE_SNAPSHOT); } ++task_iter_face; } for (int i = 0; i < face_deleteObjectID.size(); ++i) std::vector().swap(face_deleteObjectID[i]); std::vector>().swap(face_deleteObjectID); std::vector().swap(facedet_result); } #endif }