diff --git a/bin/models/motor_phone/motor_phone1127_310p.om b/bin/models/motor_phone/motor_phone1127_310p.om new file mode 100755 index 0000000..c36e634 --- /dev/null +++ b/bin/models/motor_phone/motor_phone1127_310p.om diff --git a/bin/models/rainshed/motor_rainshed_231123_310p.om b/bin/models/rainshed/motor_rainshed_231123_310p.om new file mode 100755 index 0000000..ba08590 --- /dev/null +++ b/bin/models/rainshed/motor_rainshed_231123_310p.om diff --git a/build/src/Makefile b/build/src/Makefile index 743c55c..9137579 100644 --- a/build/src/Makefile +++ b/build/src/Makefile @@ -18,6 +18,7 @@ ALGORITHM_PATH = $(PROJ_ALL_PATH)/algorithm INCLUDES = -I$(PROJ_ALL_PATH)/src/common \ -I$(PROJ_ALL_PATH)/src/common/dvpp \ + -I$(PROJ_ALL_PATH)/src/common/cnn \ -I$(PROJ_ALL_PATH)/src/common/cnn_cls \ -I$(PROJ_ALL_PATH)/src/common/dvppx \ -I$(PROJ_ALL_PATH)/src/common/model_process \ @@ -64,6 +65,7 @@ SRCS := $(wildcard $(CUR_PROJ_PATH)/*.cpp) \ $(wildcard $(CUR_PROJ_PATH)/common/*.cpp) \ $(wildcard $(CUR_PROJ_PATH)/common/dvpp/*.cpp) \ $(wildcard $(CUR_PROJ_PATH)/common/cnn_cls/*.cpp) \ + $(wildcard $(CUR_PROJ_PATH)/common/cnn/*.cpp) \ $(wildcard $(CUR_PROJ_PATH)/common/dvppx/*.cpp) \ $(wildcard $(CUR_PROJ_PATH)/common/model_process/*.cpp) \ @@ -87,6 +89,9 @@ $(TARGET):$(OBJS) %.o:$(CUR_PROJ_PATH)/common/dvpp/%.cpp $(XX) $(CXXFLAGS) -c $< +%.o:$(CUR_PROJ_PATH)/common/cnn/%.cpp + $(XX) $(CXXFLAGS) -c $< + %.o:$(CUR_PROJ_PATH)/common/cnn_cls/%.cpp $(XX) $(CXXFLAGS) -c $< diff --git a/src/PicAnalysis.cpp b/src/PicAnalysis.cpp index ef0e9e5..f8723d6 100644 --- a/src/PicAnalysis.cpp +++ b/src/PicAnalysis.cpp @@ -17,30 +17,40 @@ int PicAnalysis::init(int dev_id) { int ret = SY_FAILED; - ret = m_vehicle_analysis.init(dev_id, 16); - if(0 != ret){ - return -1; - } - - head_tail_param ht_param; - ht_param.devId = dev_id; - ht_param.max_batch = 16; - ret = m_head_tail_algorithm.init(ht_param); - if(0 != ret){ - return -1; - } - - ret = m_clothes_algorithm.init(dev_id); - if(0 != ret){ - return -1; - } - - ret = m_human_algorithm.init(dev_id); - if(0 != ret){ - return -1; - } - - ret = m_human_car_algorithm.init(dev_id); + // ret = m_vehicle_analysis.init(dev_id, 16); + // if(0 != ret){ + // return -1; + // } + + // head_tail_param ht_param; + // ht_param.devId = dev_id; + // ht_param.max_batch = 16; + // ret = m_head_tail_algorithm.init(ht_param); + // if(0 != ret){ + // return -1; + // } + + // ret = m_clothes_algorithm.init(dev_id); + // if(0 != ret){ + // return -1; + // } + + // ret = m_human_algorithm.init(dev_id); + // if(0 != ret){ + // return -1; + // } + + // ret = m_human_car_algorithm.init(dev_id); + // if(0 != ret){ + // return -1; + // } + + // ret = m_motor_rainshed_algorithm.init(dev_id); + // if(0 != ret){ + // return -1; + // } + + ret = m_motor_phone_algorithm.init(dev_id); if(0 != ret){ return -1; } @@ -90,20 +100,24 @@ int PicAnalysis::analysis_sync(vector vec_file_path){ vec_img.push_back(img); } - m_vehicle_analysis.detect(vec_img); + // m_vehicle_analysis.detect(vec_img); - vector head_tail_result; - ret = m_head_tail_algorithm.detect(vec_img, head_tail_result); - if (0 != ret) { - LOG_ERROR("m_head_tail_algorithm failed!"); - head_tail_result.clear(); - } + // vector head_tail_result; + // ret = m_head_tail_algorithm.detect(vec_img, head_tail_result); + // if (0 != ret) { + // LOG_ERROR("m_head_tail_algorithm failed!"); + // head_tail_result.clear(); + // } + + // m_clothes_algorithm.detect(vec_img); + + // m_human_algorithm.detect(vec_img); - m_clothes_algorithm.detect(vec_img); + // m_human_car_algorithm.detect(vec_img); - m_human_algorithm.detect(vec_img); + // m_motor_rainshed_algorithm.detect(vec_img); - m_human_car_algorithm.detect(vec_img); + m_motor_phone_algorithm.detect(vec_img); LOG_INFO("analysis_sync finished!"); diff --git a/src/PicAnalysis.h b/src/PicAnalysis.h index fa71368..95805eb 100644 --- a/src/PicAnalysis.h +++ b/src/PicAnalysis.h @@ -4,6 +4,8 @@ #include "./ai_engine_module/VidClothes.h" #include "./ai_engine_module/HumanAnalysis.h" #include "./ai_engine_module/HumanCarAnalysis.h" +#include "./ai_engine_module/MotorRainshedAnalysis.h" +#include "./ai_engine_module/MotorPhoneAnalysis.h" using namespace std; @@ -31,6 +33,8 @@ private: VidClothes m_clothes_algorithm; HumanAnalysis m_human_algorithm; HumanCarAnalysis m_human_car_algorithm; + MotorRainshedAnalysis m_motor_rainshed_algorithm; + MotorPhoneAnalysis m_motor_phone_algorithm; }; diff --git a/src/ai_engine_module/HumanAnalysis.cpp b/src/ai_engine_module/HumanAnalysis.cpp index 3504163..18d9e05 100644 --- a/src/ai_engine_module/HumanAnalysis.cpp +++ b/src/ai_engine_module/HumanAnalysis.cpp @@ -41,7 +41,7 @@ int HumanAnalysis::detect(vector vec_img){ { ret = hp_batch(m_handle, vec_img.data(), batchsize, results); if (SY_SUCCESS != ret) { - printf("vidclothesClassification process failed!"); + printf("hp_batch failed!"); break; } diff --git a/src/ai_engine_module/HumanCarAnalysis.cpp b/src/ai_engine_module/HumanCarAnalysis.cpp index 2be2cbf..25a10dd 100644 --- a/src/ai_engine_module/HumanCarAnalysis.cpp +++ b/src/ai_engine_module/HumanCarAnalysis.cpp @@ -41,7 +41,7 @@ int HumanCarAnalysis::detect(vector vec_img){ { ret = hcp_batch(m_handle, vec_img.data(), batchsize, results); if (SY_SUCCESS != ret) { - printf("vidclothesClassification process failed!"); + printf("hcp_batch failed!"); break; } diff --git a/src/ai_engine_module/MotorPhoneAnalysis.cpp b/src/ai_engine_module/MotorPhoneAnalysis.cpp new file mode 100644 index 0000000..46ca943 --- /dev/null +++ b/src/ai_engine_module/MotorPhoneAnalysis.cpp @@ -0,0 +1,78 @@ +#include "MotorPhoneAnalysis.h" +#include "motor_phone_det.h" + +MotorPhoneAnalysis::MotorPhoneAnalysis(/* args */) +{ +} + +MotorPhoneAnalysis::~MotorPhoneAnalysis() +{ + release(); +} + +int MotorPhoneAnalysis::init(int devId){ + ACL_CALL(aclrtCreateContext(&ctx, devId), SY_SUCCESS, SY_FAILED); + + motor_phone_param param; + param.modelNames = "./models/motor_phone/motor_phone1127_310p.om"; + param.thresld = 0.25; + param.devId = devId; + + cout << "motor_phone_init start " << endl; + int ret = motor_phone_init(&m_handle, param); + if (ret != 0) { + return -1; + } + + cout << "motor_phone_init success " << endl; + + return SY_SUCCESS; +} + +int MotorPhoneAnalysis::detect(vector vec_img){ + + ACL_CALL(aclrtSetCurrentContext(ctx), SY_SUCCESS, SY_FAILED); + + const int batchsize = vec_img.size(); + motor_phone_result * results = new motor_phone_result[batchsize]; + + int ret = SY_FAILED; + + do + { + ret = motor_phone_process_batch(m_handle, vec_img.data(), batchsize, results); + if (SY_SUCCESS != ret) { + printf("motor_phone_process_batch failed!"); + break; + } + + for(int batchIdx = 0; batchIdx < batchsize; batchIdx ++){ + printf("debug det num:%d\n",results[batchIdx].objcount); + for (int i = 0; i < results[batchIdx].objcount; i++) { + printf(" %d:%.2f \n", results[batchIdx].objinfo[i].index,results[batchIdx].objinfo[i].confidence); + } + } + } while (0); + + if (results) { + delete [] results; + } + + return ret; +} + +int MotorPhoneAnalysis::release() { + + ACL_CALL(aclrtSetCurrentContext(ctx), SY_SUCCESS, SY_FAILED); + + if (m_handle) { + motor_phone_release(&m_handle); + } + + if(ctx){ + aclrtDestroyContext(ctx); + ctx = nullptr; + } + + return SY_SUCCESS; +} \ No newline at end of file diff --git a/src/ai_engine_module/MotorPhoneAnalysis.h b/src/ai_engine_module/MotorPhoneAnalysis.h new file mode 100644 index 0000000..7563a46 --- /dev/null +++ b/src/ai_engine_module/MotorPhoneAnalysis.h @@ -0,0 +1,20 @@ +#include "include.h" + +class MotorPhoneAnalysis +{ +public: + MotorPhoneAnalysis(/* args */); + ~MotorPhoneAnalysis(); + + int init(int devId); + + int detect(vector vec_img); + +private: + int release(); + +private: + void* m_handle{nullptr}; + aclrtContext ctx{nullptr}; +}; + diff --git a/src/ai_engine_module/MotorRainshedAnalysis.cpp b/src/ai_engine_module/MotorRainshedAnalysis.cpp new file mode 100644 index 0000000..c85e6c8 --- /dev/null +++ b/src/ai_engine_module/MotorRainshedAnalysis.cpp @@ -0,0 +1,75 @@ +#include "MotorRainshedAnalysis.h" +#include "motor_rainshed_cls.h" + +MotorRainshedAnalysis::MotorRainshedAnalysis(/* args */) +{ +} + +MotorRainshedAnalysis::~MotorRainshedAnalysis() +{ + release(); +} + +int MotorRainshedAnalysis::init(int devId){ + ACL_CALL(aclrtCreateContext(&ctx, devId), SY_SUCCESS, SY_FAILED); + + mrc_param param; + param.modelNames = "./models/rainshed/motor_rainshed_231123_310p.om"; + param.thresld = 0.0; + param.devId = devId; + + cout << "mrc_init start " << endl; + int ret = mrc_init(&m_handle, param); + if (ret != 0) { + return -1; + } + + cout << "mrc_init success " << endl; + + return SY_SUCCESS; +} + +int MotorRainshedAnalysis::detect(vector vec_img){ + + ACL_CALL(aclrtSetCurrentContext(ctx), SY_SUCCESS, SY_FAILED); + + const int batchsize = vec_img.size(); + mrc_result * results = new mrc_result[batchsize]; + + int ret = SY_FAILED; + + do + { + ret = mrc_batch(m_handle, vec_img.data(), batchsize, results); + if (SY_SUCCESS != ret) { + printf("mrc_batch failed!"); + break; + } + + for(int batchIdx = 0;batchIdx vec_img); + +private: + int release(); + +private: + void* m_handle{nullptr}; + aclrtContext ctx{nullptr}; +}; + diff --git a/src/ai_engine_module/motor_phone_det.cpp b/src/ai_engine_module/motor_phone_det.cpp new file mode 100755 index 0000000..e738851 --- /dev/null +++ b/src/ai_engine_module/motor_phone_det.cpp @@ -0,0 +1,307 @@ +#include "motor_phone_det.h" +#include "sy_errorinfo.h" +#include "cnn_extractor.h" +#include "dvpp_processx.h" +#include +#include +#include "stream_data.h" +#include +#include +#include + + +using namespace atlas_utils; +using namespace std; + +struct Resource { + aclrtContext ctx; + aclrtStream stream; +}; + +typedef struct Tools { + Resource src; + CNNExtract* phoneDetMotor; + DvppProcessx* dvpp; +}Tools; + + +int motor_phone_init(void **handle, motor_phone_param param){ + + int ret = SY_SUCCESS; + Tools* tools = new Tools; + // init resource + // ACL_CALL(aclInit(nullptr), ACL_SUCCESS, SY_FAILED); + // ACL_CALL(aclrtSetDevice(param.devId), ACL_SUCCESS, SY_FAILED); + // ACL_CALL(aclrtCreateContext(&tools->src.ctx, param.devId), ACL_SUCCESS, SY_FAILED); + ACL_CALL(aclrtCreateStream(&tools->src.stream), ACL_SUCCESS, SY_FAILED); + + // head_shoulder detection init + tools->phoneDetMotor = new CNNExtract(); + tools->phoneDetMotor->config.confThr = param.thresld; + + ret = tools->phoneDetMotor->Init(param.modelNames); + if (ret != SY_SUCCESS) { + delete tools->phoneDetMotor; + tools->phoneDetMotor = nullptr; + return SY_FAILED; + } + + tools->dvpp = new DvppProcessx(); + tools->dvpp->InitResource(tools->src.stream); + + *handle = tools; + + return SY_SUCCESS; +} + + +//======================= yolo v8 postprocess ============================// +float iou(float *lbox, float *rbox) { + float interBox[] = { + (std::max)(lbox[0] - lbox[2] / 2.f , rbox[0] - rbox[2] / 2.f), //left + (std::min)(lbox[0] + lbox[2] / 2.f , rbox[0] + rbox[2] / 2.f), //right + (std::max)(lbox[1] - lbox[3] / 2.f , rbox[1] - rbox[3] / 2.f), //top + (std::min)(lbox[1] + lbox[3] / 2.f , rbox[1] + rbox[3] / 2.f), //bottom + }; + + if (interBox[2] > interBox[3] || interBox[0] > interBox[1]) + return 0.0f; + + float interBoxS = (interBox[1] - interBox[0])*(interBox[3] - interBox[2]); + return interBoxS / (lbox[2] * lbox[3] + rbox[2] * rbox[3] - interBoxS); +} + +bool cmp(const vector& a, const vector& b) { + return a[4] > b[4]; +} + +//wh20230330 +//yolov5的数据结构是4个bbox + 检测置信度+ 多cls +//yolov8的数据结构是4个bbox + 多cls ,选多cls中最大值作为检测置信度 +// void nms_yolov8(std::vector>& res, float *output, int outnum, int CLS_NUM, float conf_thresh, float nms_thresh = 0.5) +void nms_yolov8(std::vector>& res, std::vector &output, int outnum, int CLS_NUM, float conf_thresh, float nms_thresh = 0.5) +{ + //printf("nms_yolov8:outnum=%d,CLS_NUM=%d,conf_thresh=%f,nms_thresh=%f \n",outnum,CLS_NUM,conf_thresh,nms_thresh); + int det_size = 6;// sizeof(Yolo::Detection) / sizeof(float); + std::map>> m; + for (int i = 0; i < outnum; i++) + { + //vector cls_prob(CLS_NUM - 5); + vector cls_prob(CLS_NUM - 4);//wh多cls的值 + //memcpy(cls_prob.data(), &output[CLS_NUM * i + 5], (CLS_NUM - 5) * sizeof(float)); + memcpy(cls_prob.data(), &output[CLS_NUM * i + 4], (CLS_NUM - 4) * sizeof(float)); + auto maxPosition = max_element(cls_prob.begin(), cls_prob.end());//wh多cls的最大值 + + //if (output[CLS_NUM * i + 4] <= conf_thresh) continue; + if (*maxPosition <= conf_thresh ) continue; + //if(1) + //{ + // printf("nms_yolov8:output:["); + // for(int kk=0;kk det(det_size); + //Yolo::Detection det; + //memcpy(&det[0], &output[CLS_NUM * i], (det_size - 1) * sizeof(float)); + memcpy(&det[0], &output[CLS_NUM * i], (det_size - 2) * sizeof(float)); + //det[4] = det[4]*(*maxPosition); + det[4] = (*maxPosition); + det[5] = maxPosition - cls_prob.begin(); + //printf("nms_yolov8 det =%f-%f-%f-%f %f %f \n",det[0],det[1],det[2],det[3],det[4],det[5]); + + if (m.count(det[5]) == 0) + m.emplace(det[5], std::vector>()); + m[det[5]].push_back(det); + + /*det.conf = det.conf*(*maxPosition); + det.class_id = maxPosition - cls_prob.begin(); + if (m.count(det.class_id) == 0) + m.emplace(det.class_id, std::vector()); + m[det.class_id].push_back(det);*/ + } + + for (auto it = m.begin(); it != m.end(); it++) { + //std::cout << it->second[0].class_id << " --- " << std::endl; + auto& dets = it->second; + std::sort(dets.begin(), dets.end(), cmp); + + for (size_t m = 0; m < dets.size(); ++m) { + auto& item = dets[m]; + + vector det_temp(det_size); + //Yolo::Detection det_temp; + /*det_temp.conf = item.conf; + det_temp.class_id = item.class_id; + det_temp.bbox[0] = item.bbox[0] - item.bbox[2] / 2; + det_temp.bbox[1] = item.bbox[1] - item.bbox[3] / 2; + det_temp.bbox[2] = item.bbox[2]; + det_temp.bbox[3] = item.bbox[3];*/ + + det_temp[4] = item[4]; + det_temp[5] = item[5]; + det_temp[0] = item[0] - item[2] / 2; + det_temp[1] = item[1] - item[3] / 2; + det_temp[2] = item[2]; + det_temp[3] = item[3]; + + res.push_back(det_temp); + + for (size_t n = m + 1; n < dets.size(); ++n) { + if (iou(&item[0], &dets[n][0]) > nms_thresh) { + dets.erase(dets.begin() + n); + --n; + } + } + } + } +} + +int motor_phone_process_batch(void * handle, sy_img *image_data_array, int batchsize, motor_phone_result *result){ + Tools* tools = (Tools*) handle; + + int inputW = tools->phoneDetMotor->GetInputWidth(); + int inputH = tools->phoneDetMotor->GetInputHeight(); + + //printf("debug inputw:%d,inputh:%d\n",inputW,inputH); + + for (int b = 0; b < batchsize; b++) { + if (image_data_array[b].data_ == NULL || image_data_array[b].w_ == 0 || image_data_array[b].h_ == 0) { + ERROR_LOG(" Headshoulder get null input ptr!"); + return SY_FAILED; + } + + ImageData resizeImg, src; + // Utils::CopysyImageDataToDvpp(src, image_data_array[b]); + ACL_CALL(Utils::CopysyImageDataToDvppV2(src, image_data_array[b]), SY_SUCCESS, SY_FAILED); + ACL_CALL(tools->dvpp->CropAndPadding(resizeImg, src, inputW, inputH), SY_SUCCESS, SY_FAILED); + // forward + // double t1, t2; + // t1 = msecond(); + int ret = tools->phoneDetMotor->Inference(resizeImg); + if (ret != SY_SUCCESS) { + return SY_MODEL_FORWARD_ERROR; + } + // t2 = msecond(); + // printf("debug infer time: %.2f\n", t2 - t1); + + vector detRes; + ret = tools->phoneDetMotor->PostProcess(detRes); + if (ret != SY_SUCCESS) { + return SY_MODEL_GETRESULT_ERROR; + } + + int img_w = image_data_array[b].w_; + int img_h = image_data_array[b].h_; + int INPUT_W = 224;//模型输入 + int INPUT_H = 224; + // int max_obj_data_count = 10;//4+多类置信度(这里是6类) 0912/1013 + int max_obj_data_count = 9;//4+多类置信度(这里是5类) 1127模型 + + // printf("datacount:%d\n",detRes.size()); + int num_det = detRes.size() / max_obj_data_count; + + int w, h, x, y; + float r_w = (float)INPUT_W / (img_w*1.0); + float r_h = (float)INPUT_H / (img_h*1.0); + float ratio = r_w < r_h ? r_w : r_h; + if (r_h > r_w) { + w = INPUT_W; + h = r_w * img_h; + x = 0; + y = (INPUT_H - h) / 2; + } + else { + w = r_h * img_w; + h = INPUT_H; + x = (INPUT_W - w) / 2; + y = 0; + } + + + vector> nms_res; + //printf("%d %d %d %d %d %d\n", img_w, img_h, w, h, x, y); + nms_yolov8(nms_res, detRes, num_det, max_obj_data_count, tools->phoneDetMotor->config.confThr, 0.7); + + int obj_count = 0; + result[b].objcount = 0; + for (int i = 0; i < nms_res.size(); i++) + { + //class_id, score, x1, y1, x2, y2 + int index = nms_res[i][5]; + + float detect_score = nms_res[i][4]; + if(detect_score > tools->phoneDetMotor->config.confThr) + { + + int x1 = (nms_res[i][0] - x) / ratio; + int y1 = (nms_res[i][1] - y) / ratio; + int x2 = nms_res[i][2] / ratio + x1; + int y2 = nms_res[i][3] / ratio + y1; + + //边界判断 + if(x1<0)x1=0; + if(y1<0)y1=0; + if(x2>=img_w) x2 = img_w-1; + if(y2>=img_h) y2 = img_h-1; + + result[b].objinfo[obj_count].left = x1; + result[b].objinfo[obj_count].top = y1; + result[b].objinfo[obj_count].right = x2; + result[b].objinfo[obj_count].bottom = y2; + + result[b].objinfo[obj_count].confidence = detect_score; + result[b].objinfo[obj_count].index = index; + + obj_count++; + } + } + result[b].objcount =obj_count; + + vector>().swap(nms_res); + vector().swap(detRes); + + + + // result[i].objcount = detRes.size() > MAX_OBJ_COUNT ? MAX_OBJ_COUNT : detRes.size(); + // int objIdx = 0; + // for (auto& det : detRes) { + // if (objIdx >= MAX_OBJ_COUNT) continue; + // result[i].objinfo[objIdx].left = det[2]; + // result[i].objinfo[objIdx].top = det[3]; + // result[i].objinfo[objIdx].right = det[4]; + // result[i].objinfo[objIdx].bottom = det[5]; + // result[i].objinfo[objIdx].confidence = det[1]; + // objIdx++; + + // } + + + } + + return SY_SUCCESS; +} + +void motor_phone_release(void **handle) { + Tools* tools = (Tools*) handle; + if (tools) { + if (tools->phoneDetMotor) { + //delete tools->phoneDetMotor; + tools->phoneDetMotor = nullptr; + } + if (tools->dvpp) { + //delete tools->dvpp; + tools->dvpp = nullptr; + } + // aclFinalize(); + //delete tools; + tools = NULL; + } +} + +const char * motor_phone_getversion() { + return "motor_phone_vdec_arm_v310p_0.0.2.20231127_without_timelimit"; +} diff --git a/src/ai_engine_module/motor_phone_det.h b/src/ai_engine_module/motor_phone_det.h new file mode 100755 index 0000000..8f9e372 --- /dev/null +++ b/src/ai_engine_module/motor_phone_det.h @@ -0,0 +1,108 @@ +/******************************************************************************************* +* Version: motor_phone_det_x64_v0.0.1 +* CopyRight: 中科视语(北京)科技有限公司 +* UpdateDate: 20230911 +* Content:二轮车玩手机检测 +********************************************************************************************/ +#ifndef MOTOR_PHONE_DET_H_ +#define MOTOR_PHONE_DET_H_ + +#ifdef _MSC_VER +#ifdef MOTOR_PHONE_DET_EXPORTS +#define MOTOR_PHONE_DET_API __declspec(dllexport) +#else +#define MOTOR_PHONE_DET_API __declspec(dllimport) +#endif +#else +#define MOTOR_PHONE_DET_API __attribute__ ((visibility ("default"))) +#endif + +#include "sy_common.h" + +#define MAX_OBJ_COUNT 1000 + +#ifdef __cplusplus +extern "C" +{ +#endif + + typedef struct motor_phone_info //结果结构体 + { + int left; + int top; + int right; + int bottom; + int index; + double confidence; // 置信度 + }motor_phone_info; + + typedef struct motor_phone_result + { + motor_phone_info objinfo[MAX_OBJ_COUNT]; + int objcount; + }; + + typedef struct motor_phone_param + { + //int mode; //运行模式 GPU_MODE 或者 CPU_MODE + int devId; //运行卡号 GPU模式下有效 + char* modelNames; + float thresld; //检测阈值 默认为0.3 + + //int engine; //指定运行引擎(ENGINE_MCAFFE2 / ENGINE_TENSORRT) + //int max_batch; //ָ指定trt最大batch数 + //char* trt_serialize_file; + //motor_phone_param() :mode(DEVICE_GPU), gpuid(0), thresld(0.4), engine(ENGINE_MCAFFE2), max_batch(10){}; + }motor_phone_param; + + /************************************************************************* + * FUNCTION: hst_init + * PURPOSE: 初始化 + * PARAM: + [in] handle -处理句柄 + [in] param -初始化参数 + * RETURN: handle + * NOTES:成功(0)或者错误代码(<0) + *************************************************************************/ + MOTOR_PHONE_DET_API int motor_phone_init(void **handle, motor_phone_param param); + MOTOR_PHONE_DET_API int motor_phone_process_batch(void * handle, sy_img *image_data_array, int batchsize, motor_phone_result *result); + + /************************************************************************* + * FUNCTION: hst_release + * PURPOSE: 资源释放 + * PARAM: + [in] handle - 处理句柄 + * RETURN: NULL + * NOTES: + *************************************************************************/ + MOTOR_PHONE_DET_API void motor_phone_release(void **handle); + + + /************************************************************************* + * FUNCTION: hst_process_gpu + * PURPOSE: + * PARAM: + [in] handle - 处理句柄 + [in] rgb - 图片数据(3通道BGR数据 cv::Mat格式) + [in] width - 图片宽度 + [in] height - 图片高度 + [in] result - 搜索结果,在外部申请足够内存 + * RETURN: -1:图像错误; 其他:检测到的个数 + * NOTES: + *************************************************************************/ + MOTOR_PHONE_DET_API int motor_phone_process(void * handle, sy_img image, motor_phone_result *result); + + /************************************************************************* + * FUNCTION: hst_getversion + * PURPOSE: 释放 + * PARAM: NULL + * RETURN: 版本号 + * NOTES: + *************************************************************************/ + MOTOR_PHONE_DET_API const char * motor_phone_getversion(); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/src/ai_engine_module/motor_rainshed_cls.cpp b/src/ai_engine_module/motor_rainshed_cls.cpp new file mode 100755 index 0000000..3c499bc --- /dev/null +++ b/src/ai_engine_module/motor_rainshed_cls.cpp @@ -0,0 +1,135 @@ +#include "motor_rainshed_cls.h" +#include "sy_errorinfo.h" +#include "cnn_cls.h" +#include "dvpp_processx.h" +#include +#include +#include "stream_data.h" + + +using namespace atlas_utils; +using namespace std; + +struct Resource { + aclrtContext ctx; + aclrtStream stream; +}; + +typedef struct Tools { + Resource src; + CnnCls* mRainCls; + DvppProcessx* dvpp; +}Tools; + +int mrc_init(void** handle, mrc_param param) { + + int ret = SY_SUCCESS; + Tools* tools = new Tools; + // init resource + // ACL_CALL(aclInit(nullptr), ACL_SUCCESS, SY_FAILED); + // ACL_CALL(aclrtSetDevice(param.devId), ACL_SUCCESS, SY_FAILED); + // ACL_CALL(aclrtCreateContext(&tools->src.ctx, param.devId), ACL_SUCCESS, SY_FAILED); + ACL_CALL(aclrtCreateStream(&tools->src.stream), ACL_SUCCESS, SY_FAILED); + + // motor rainshed classfication init + tools->mRainCls = new CnnCls(); + tools->mRainCls->config.confThr = param.thresld; + ret = tools->mRainCls->Init(param.modelNames); + if (ret != SY_SUCCESS) { + delete tools->mRainCls; + tools->mRainCls = nullptr; + return SY_FAILED; + } + + tools->dvpp = new DvppProcessx(); + tools->dvpp->InitResource(tools->src.stream); + + *handle = tools; + + return SY_SUCCESS; +} + + +// double msecond() { +// struct timeval tv; +// gettimeofday(&tv, 0); +// return (tv.tv_sec * 1000.0 + tv.tv_usec / 1000.0); +// } + +int mrc_batch(void * handle, sy_img *img_data_array, int batch_size, mrc_result *result) { + Tools* tools = (Tools*) handle; + + int inputW = tools->mRainCls->GetInputWidth(); + int inputH = tools->mRainCls->GetInputHeight(); + + // printf("debug inputw:%d,inputh:%d\n",inputW,inputH); + + for (int i = 0; i < batch_size; i++) { + if (img_data_array[i].data_ == NULL || img_data_array[i].w_ == 0 || img_data_array[i].h_ == 0) { + ERROR_LOG("mRainCls get null input ptr!"); + return SY_FAILED; + } + ImageData resizeImg, src; + //debug======================================================================== + // src.width = img_data_array[i].w_; + // src.height = img_data_array[i].h_; + // src.alignWidth = ((src.width + 127) & ~(127)); + // src.alignHeight = ((src.height + 15) & ~(15)); + // src.size = src.alignWidth * src.alignHeight * 1.5; + // src.data.reset((uint8_t*)img_data_array[i].data_, [](uint8_t* p) { acldvppFree((void *)p); }); + //debug end==================================================================== + // Utils::CopysyImageDataToDvpp(src, img_data_array[i]); + ACL_CALL(Utils::CopysyImageDataToDvppV2(src, img_data_array[i]), SY_SUCCESS, SY_FAILED); + ACL_CALL(tools->dvpp->CropAndPaste(resizeImg, src, inputW, inputH), SY_SUCCESS, SY_FAILED); + // forward + //double t1, t2; + //t1 = msecond(); + int ret = tools->mRainCls->Inference(resizeImg); + if (ret != SY_SUCCESS) { + return SY_MODEL_FORWARD_ERROR; + } + //t2 = msecond(); + //printf("debug infer time: %.2f\n", t2 - t1); + + vector mRainClsRes; + ret = tools->mRainCls->PostProcess(mRainClsRes); + if (ret != SY_SUCCESS) { + return SY_MODEL_GETRESULT_ERROR; + } + result[i].index = mRainClsRes[0]; + result[i].score = mRainClsRes[1]; + // printf("debug index:%d,confidence:%f\n",result[i].index,result[i].score); + // for (auto res : mRainClsRes) { + // printf("debug info: %f\n",res); + // } + + } + + return SY_SUCCESS; +} + +void mrc_release(void **handle) { + Tools* tools = (Tools*) handle; + // printf("debug line:%d\n",__LINE__); + if (tools) { + if (tools->mRainCls) { + // delete tools->mRainCls; + tools->mRainCls = nullptr; + } + // printf("debug line:%d\n",__LINE__); + if (tools->dvpp) { + // delete tools->dvpp; + tools->dvpp = nullptr; + } + //printf("debug line:%d\n",__LINE__); + // aclFinalize(); + aclrtDestroyStream(&tools->src.stream); + // delete tools; + tools = NULL; + //printf("debug line:%d\n",__LINE__); + } +} + +const char * mrc_get_version() { + return "motorrc_arm_vdec_310p_v0.0.1.20230921_without_timelimit"; +} \ No newline at end of file diff --git a/src/ai_engine_module/motor_rainshed_cls.h b/src/ai_engine_module/motor_rainshed_cls.h new file mode 100755 index 0000000..c4ca8e3 --- /dev/null +++ b/src/ai_engine_module/motor_rainshed_cls.h @@ -0,0 +1,120 @@ +/************************************************************************* +* Version: motor_rainshed_cls_v0.0.0.20230921 +* CopyRight : 中国科学院自动化所模式识别实验室图像视频组 +* UpdateDate:20230921 +* Content : 二轮车是否加装雨棚 +*************************************************************************/ +#ifndef MOTORRAINCLS_H_ +#define MOTORRAINCLS_H_ + +#if _MSC_VER +#ifdef MOTORRAINCLS_EXPORTS +#define MOTORRAINCLS_API __declspec(dllexport) +#else +#define MOTORRAINCLS_API __declspec(dllimport) +#endif +#else +#define MOTORRAINCLS_API __attribute__ ((visibility ("default"))) +#endif + +#include "sy_common.h" + + + +#ifndef MAX_BATCH_SIZE +#define MAX_BATCH_SIZE 16 +#endif + + +#ifdef __cplusplus +extern "C" +{ +#endif + + + +//分类结果 +#ifndef MRCRESULT_ +#define MRCRESULT_ +typedef struct mrc_result +{ + float score; + int index; +}mrc_result; +#endif + + +#ifndef __MRCPARAM__ +#define __MRCPARAM__ + typedef struct mrc_param + { + //int mode; //运行模式(DEVICE_GPU / DEVICE_CPU) + //mrc_param() :mode(DEVICE_GPU), gpuid(0) {}; + int devId; //ָ指定显卡id + char* modelNames; + float thresld; //阈值 + }mrc_param; +#endif + + /************************************************************************* + * FUNCTION: mrc_init + * PURPOSE: 载入模型 + * PARAM: + [in] handle - 句柄 + [in] params - 参数 + * RETURN: 成功(0)或者错误代码 + * NOTES: + *************************************************************************/ + MOTORRAINCLS_API int mrc_init(void ** handle, mrc_param param); + + /************************************************************************* + * FUNCTION: mrc_process + * PURPOSE: 二轮车加装雨棚分类 + * PARAM: + [in] handle - 检测句柄 + [in] img_data - 图像数据 + [in] result - 结果 内存在外部申请 + * RETURN: 成功(0) 或 错误代码(< 0) + * NOTES: + *************************************************************************/ + MOTORRAINCLS_API int mrc_process(void *handle, sy_img img_data, mrc_result * result); + + /************************************************************************* + * FUNCTION: mrc_batch + * PURPOSE: 二轮车加装雨棚分类 batch + * PARAM: + [in] handle - 检测句柄 + [in] img_data_array - 图像数据 + [in] batch_size - 图像数目 + [in] result - 结果 内存在外部申请 + * RETURN: 成功(0) 或 错误代码(< 0) + * NOTES: + *************************************************************************/ + MOTORRAINCLS_API int mrc_batch(void *handle, sy_img* img_data_array, int batch_size, mrc_result * result); + + + /************************************************************************* + * FUNCTION: mrc_release + * PURPOSE: 释放 + * PARAM: + [in] handle - handle + * RETURN: NULL + * NOTES: + *************************************************************************/ + MOTORRAINCLS_API void mrc_release(void ** handle); + + + /************************************************************************* + * FUNCTION: mrc_get_version + * PURPOSE: + * PARAM: NULL + * RETURN: 版本号 + * NOTES: + *************************************************************************/ + MOTORRAINCLS_API const char * mrc_get_version(); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/src/common/cnn/cnn_extractor.cpp b/src/common/cnn/cnn_extractor.cpp new file mode 100755 index 0000000..94f90c9 --- /dev/null +++ b/src/common/cnn/cnn_extractor.cpp @@ -0,0 +1,94 @@ +#include "cnn_extractor.h" +#include +#include "acl/acl.h" +#include "model_process.h" +#include "sy_errorinfo.h" +#include +#include +#include + +using namespace std; + +namespace atlas_utils { + +int CNNExtract::Init(const char* modelPath) { + ACL_CALL(aclrtGetRunMode(&runMode_), SY_SUCCESS, SY_FAILED);//获取当前昇腾AI软件栈的运行模式,根据不同的运行模式,后续的接口调用方式不同 + ACL_CALL(model_.LoadModelFromFileWithMem(modelPath), SY_SUCCESS, SY_FAILED);//从文件加载离线模型数据,由用户自行管理模型运行的内存 + ACL_CALL(model_.CreateDesc(), SY_SUCCESS, SY_FAILED);//获取模型的描述信息 + ACL_CALL(model_.CreateOutput(outDims_), SY_SUCCESS, SY_FAILED); + ACL_CALL(model_.GetInputDims(inDims_), SY_SUCCESS, SY_FAILED); + modelHeight_ = inDims_[0][1]; + modelWidth_ = inDims_[0][2]; + + return SY_SUCCESS; +} + + +int CNNExtract::Inference(ImageData& input) { + model_.CreateInput(input.data.get(), input.size); + ACL_CALL(model_.Execute(), SY_SUCCESS, SY_FAILED); + model_.DestroyInput(); //需调用CreateInput的销毁类接口DestroyInput!!! + return SY_SUCCESS; +} + +int CNNExtract::GetInputWidth() { + return modelWidth_; +} + +int CNNExtract::GetInputHeight() { + return modelHeight_; +} + +int CNNExtract::PostProcess(vector& results) { + aclmdlDataset* modelOutput = model_.GetModelOutputData(); + int outDatasetNum = aclmdlGetDatasetNumBuffers(modelOutput); + for (int i = 0; i < outDatasetNum; i++) { + aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(modelOutput, i); + if (dataBuffer == nullptr) { + return SY_FAILED; + } + uint32_t dataBufferSize = aclGetDataBufferSize(dataBuffer); + void* data = aclGetDataBufferAddr(dataBuffer); + if (data == nullptr) { + return SY_FAILED; + } + + int length = dataBufferSize/sizeof(float); + float outInfo[length]; + + if (runMode_ == ACL_HOST) { + ACL_CALL(aclrtMemcpy(outInfo, sizeof(outInfo), data, sizeof(outInfo), ACL_MEMCPY_DEVICE_TO_HOST), + ACL_SUCCESS, SY_FAILED); + } else { + ACL_CALL(aclrtMemcpy(outInfo, sizeof(outInfo), data, sizeof(outInfo), ACL_MEMCPY_DEVICE_TO_DEVICE),ACL_SUCCESS, SY_FAILED); + //return SY_FAILED; + } + + // //归一化 + // float sum = 0.0; + // for(int j=0;j +#include "utils.h" +#include "acl/acl.h" +#include "model_process.h" + +using namespace std; + +namespace atlas_utils { + + +#ifndef DATA_TYPE_SIZE +#define DATA_TYPE_SIZE 4 +#endif + +class CNNExtract { +public: + struct ConfigParams { + float confThr = 0.0; + }; + + CNNExtract() {} + ~CNNExtract() { + Release(); + } + + int Init(const char* modelPath); + int Inference(ImageData& input); + int PostProcess(vector& result); + + int GetInputWidth(); + int GetInputHeight(); + + ConfigParams config; + +private: + void Release(); + + vector> outDims_; + vector> inDims_; + ModelProcess model_; + uint32_t modelWidth_; + uint32_t modelHeight_; + aclrtRunMode runMode_; + +}; + +} + +#endif