You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
wangchongwu be948f7bab
包含目标识别和目标跟踪的流水线式调用仿真 HI3403
2 weeks ago
..
demo 包含目标识别和目标跟踪的流水线式调用仿真 HI3403 2 weeks ago
include 包含目标识别和目标跟踪的流水线式调用仿真 HI3403 2 weeks ago
libs 包含目标识别和目标跟踪的流水线式调用仿真 HI3403 2 weeks ago
models 包含目标识别和目标跟踪的流水线式调用仿真 HI3403 2 weeks ago
src 包含目标识别和目标跟踪的流水线式调用仿真 HI3403 2 weeks ago
thirdparty/opencv4.3 包含目标识别和目标跟踪的流水线式调用仿真 HI3403 2 weeks ago
CMakeLists.txt 包含目标识别和目标跟踪的流水线式调用仿真 HI3403 2 weeks ago
readme.md 包含目标识别和目标跟踪的流水线式调用仿真 HI3403 2 weeks ago

readme.md

使用说明文档

结构体说明

光源类型

typedef enum{
    IR = 1, # 红外
    VIS = 2 # 可见光,微光,黑白
}MODE;

数据存储结构

typedef enum{
    CHW = 1,
    HWC = 2,
    WHC = 3,
}DATA_LAYOUT;

图像存储格式

typedef enum{
    RGB = 1,
    BGR = 2,
    RGBA = 3,
    BGRA = 4,
    NV12 = 5, // uv
    NV21 = 6, // vu
    GRAY = 7,
}INPUT_LAYOUT;

数据类型

typedef enum{
  AI_DT_UNDEFINED = -1,   //未知数据类型,默认值。
  AI_FLOAT = 0,
  AI_FLOAT16 = 1,
  AI_INT8 = 2,
  AI_INT32 = 3,
  AI_UINT8 = 4,
  AI_INT16 = 6,
  AI_UINT16 = 7,
  AI_UINT32 = 8,
  AI_INT64 = 9,
  AI_UINT64 = 10,
  AI_DOUBLE = 11,
  AI_BOOL = 12,
  AI_STRING = 13,
  AI_COMPLEX64 = 16,
  AI_COMPLEX128 = 17,
  AI_BF16 = 27
}DATATYPE;

同步信息结构体 注: 该结构体种数据必须和传入图像严格同步。后续根据项目需求会增加对应结构内容数据传递时建议使用void* 解析时采用SyncInfos *)解析结构体

typedef struct tag_syncInfos
{
    /* all sync infos , add when need more infos */ 
    float fAz = 0;
    float fPt = 0;
    double focal = 0;               # 焦距
    double camera_pitch_angle = 0;  # 俯仰角
    double camera_yaw_angle = 0;    # 偏转角
    double camera_roll_angle = 0;   # 横滚角 
    double pixel_size = 0;          # 像元尺寸
}SyncInfos;

检测结果结构体

typedef struct tag_Objinfo
{
    /* data */
    float x1;     # 左上
    float y1;     # 左上
    float x2;     # 右下
    float y2;     # 右下
    float score;  # 置信度
    int classNum; # 目标种类
    int ID;       # 待使用
    int trackID;  # 管道ID
    float area;   # 目标像素面积
}objinfo;

图像输入结构体

typedef struct tag_ImgMat
{
    /* data */
    unsigned char* data=NULL;       # 数据buffer首地址要求连续内存
    int width=0;                    # 传入图像的宽
    int height=0;                   # 传入图像的高
    int depth=0;                    # 传入图像的深度, RGB/BGR为3 NV12/NV21为1RGBA/BGRA为4
    DATA_LAYOUT layout=HWC;         # 图像数据排布方式
    INPUT_LAYOUT inlayout = RGB;    # 图像像素格式
    int frameID=0;                  # 帧编号
    MODE mode = IR;                 # 传感器类型
    long long timestamp = 0;        # 纯C接口下透传数据首地址
    long long cfg = 0;              # class类接口下的透传参数常用于GD_VIDEO_FRAME_S or SyncInfos数据结构体
}ImgMat;

分割结果结构体

typedef struct tag_TenMat
{
    /* data */
    void * data = nullptr;      # 输出数据首地址,内存空间需在外部提前分配好
    int width=0;                # 输出图像的宽,算法内部写入,传出数据
    int height=0;               # 输出图像的高,算法内部写入,传出数据
    int depth=0;                # 输出图像的深度,算法内部写入,传出数据
    size_t dataByte=0;          # 单个像素所占字节数
    DATATYPE type;              # 输出图像的数据类型
    DATA_LAYOUT layout;         # 输出图像的数据排布方式
    int elementNum = 0;         # 输出图像的像素个数
    long long timestamp = 0;    # 纯C接口下透传数据首地址
    long long cfg = 0;          # class类接口下的透传参数常用于GD_VIDEO_FRAME_S or SyncInfos数据结构体
}TenMat;

函数接口说明

注: 所有函数接口均有int返回值

返回值为0: 表示函数正常执行;
返回值非0: 函数执行失败,需确认返回值数据,定位问题原因。

文档上未说明的函数接口,后续迭代会做删除处理,请勿调用,存在未知风险

硬件初始化接口

不同平台,理论上初始化函数不同,该接口已统一接口函数,无需根据平台再做设置 硬件初始化函数,系统开机时调用一次,中途不可重复调用

int Init_ACL();

硬件反初始化函数,系统关机时调用一次,中途不可调用

int Uninit_ACL();

C接口调用说明 <不推荐使用>

算法初始化函数开启算法时调用一次不需要重复调用与Uninit_AI成对使用 后续会删除该接口

int Init_AI(const char* irdetmodel,    # 红外检测模型 or NULL
            const char* visdetmodel,   # 可见光检测模型 or NULL
            const char* irsegmodel,    # 红外分割模型 or NULL
            const char* vissegmodel    # 可见光分割模型 or NULL
            );

算法反初始化函数关闭算法时使用与Init_AI成对使用不可单独使用 后续会删除该接口

int Uninit_AI();

队列参数设置接口,默认参数调用即可,无需修改参数,后续会删除该接口

int set_deque_size(int irdetin=3, int visdetin=3, int irsegin=3, int vissegin=3, int irdetout=5, int visdetout = 5, int irsegout = 5, int vissegout = 5,
                    int irdetres = 10, int visdetres = 10, int irsegres = 10, int vissegres = 10);

设置模型宽高, 后续会删除该接口

int set_stream_size(int width, int height, MODE mode);

可见光检测同步接口, 后续会删除该接口

int Det_VL(ImgMat frame, std::vector<objinfo> &outputs);

可见光分割同步接口, 后续会删除该接口

int Seg_VL(ImgMat frame, TenMat* output);

红外检测同步接口, 后续会删除该接口

int Det_IR(ImgMat frame, std::vector<objinfo> &outputs);

红外分割同步接口, 后续会删除该接口

int Seg_IR(ImgMat frame, TenMat* output);

异步接口与get_result函数一起使用 后续会删除该接口

int runAsync(ImgMat img,          # 输入图像
             bool GoDet=true,     # 是否执行检测算法
             bool GoSeg=true,     # 是否执行分割算法
             bool cropFlag=false  # 是否中心裁减,裁减大小通过 set_ROIArea 设置
             );

获取结果接口, 后续会删除该接口

int get_result(long long &timestamp,        # 透传参数,可做数据同步时使用
               std::vector<objinfo> &dets,  # 检测结果
               TenMat * maskImg,            # 分割结果
               bool front=true,             # true: 先进先出, false: 后进先出
               MODE mode=VIS              # 获取VL或IR的结果 
               );
返回值说明:
    0 : 从结果队列中成功获取结果
    1 : 算法推理未完成,结果队列中无数据,需等待算法结果
    -1: 队列已经被释放,无法获取结果

设置队列是否阻塞,默认为阻塞队列, 后续会删除该接口

int set_dropout_param(bool drop);  # true: 非阻塞队列,队列满时丢弃队列前端数据   false: 阻塞队列,队列满时,等待队列出列程序执行后方可写入队列

裁减区域设置, 后续会删除该接口

int set_ROIArea(int x1, int y1, int x2, int y2); # 左上,右下

C++接口调用说明 <推荐使用>

检测类

class DETECTION_API
{
private:
    /* data */
public:
    DETECTION_API(/* args */);
    ~DETECTION_API();
public:
    # 模型宽
    int netWidth=0;
    # 模型高
    int netHeight = 0;
    # 识别类型总数
    int clsnum = 0;
    # anchor超参数
    std::vector<std::vector<float>> anchors;// = {{7,11, 9,21, 21,15},{16,39, 31,24, 57,27},{43,59, 90,59, 131,116}};
    # 算法句柄
    void* AIGOhandle=NULL;
    # 设置类别标签映射图
    int AIGOsetLabelMap(uint32_t A[], 
                        uint32_t B[], 
                        uint32_t len);
    # 设置NMS阈值
    int AIGOsetNMSThr(float thr);
    # 获取当前NMS阈值
    int AIGOgetNMSThr(float &thr);
    # 设置对应种类的置信度
    int AIGOsetConfThr(float thr, 
                       int classidx);
    # 获取当前种类的置信度
    int AIGOgetConfThr(float &thr, 
                       int classidx);
    # 算法初始化初始化之前需设置netWidth, netHeight, clsnum, anchors参数
    int AIGOinit(const char* modename,   # 模型路径
                 int deviceID=0          # 设备ID当前算法需要在哪个ID设备上加载执行   
                 );
    # 算法初始化无需设置相关参数具体参数会自动从json文件中读取
    int AIGOinit(const char* modename,   # 模型路径
                 const char* paramname,  # 模型参数文件json文件
                 int deviceID=0          # 设备ID
                 );
    # 图像预处理过程会将预处理的图像直接写入NPU内存中
    int AIGOpreprocess(ImgMat img,       # 输入图像
                       bool doCopy=true  # 是否对输入图像进行深拷贝
                       );
    # 执行图像推理操作AIGOpreprocess之后使用
    int AIGOinfer();
    # 后处理操作,解析推理结果,筛选可用结果
    int AIGOpostprocess(std::vector<objinfo> &results);
    # 算法异步接口送入检测图像与AIGOgetResult成对使用
    int AIGOrunAsync(ImgMat img,         # 输入图像
                     bool Dcopy=true     # 是否对输入图像进行深拷贝
                     );
    # 算法异步接口获取检测结果与AIGOrunAsync成对使用
    int AIGOgetResult(long long& cfg,              # 透传参数
                      std::vector<objinfo> &dets,  # 检测结果
                      bool front=true);            # true: 先进先出, false: 后进先出
    # 算法反初始化函数与AIGOinit成对使用
    int AIGOdeinit();
};

算法调用逻辑说明

C++

构造输入图像

以opencv图像为例
    cv::Mat visdetImage = cv::imread("./test.jpg");
    cv::cvtColor(visdetImage,  visdetImage, cv::COLOR_BGR2RGB);
    if(visdetImage.empty()){
        printf("read image error %s\n", visdetimgname.c_str());
        return 1;
    }
    cv::Mat visdetresize;
    cv::resize(visdetImage, visdetresize, cv::Size(NETWIDTH, NETHEIGHT));
    cv::Mat NV12Matvis;
    # RGB转NV12数据格式
    BGR2YUV_nv12(visdetresize, NV12Matvis);
    ImgMat img;
    # RGB数据
    img.data = visdetresize.data;
    img.inlayout = RGB;
    img.depth = visdetresize.channels();
    img.layout = HWC;
    img.mode = VIS;
    # NV12数据
    img.data = NV12Matvis.data;
    img.inlayout = NV12;
    img.depth = 1;
    img.layout = HWC;
    img.mode = VIS;

构造透传参数

以GD_VIDEO_FRAME_S为例
    GD_VIDEO_FRAME_S* config = (GD_VIDEO_FRAME_S*)malloc(sizeof(GD_VIDEO_FRAME_S));
    config->u32Width = IMAGEWIDTH;
    config->u32Height = IMAGEHEIGHT;
    img.cfg = (long long)config;

同步调用

初始化
    std::string detmodelname = "../models/Detect/1684x/10kg_VL_1920x1088_bm1684x_F16_false.bmodel";
实例化检测算法
    DETECTION_API*  detAPI = new DETECTION_API();
设置相关参数
    if(带json文件的初始化){
        ret = detAPI->AIGOinit(visdetmodelname.c_str(), visdetparamname.c_str(), 0);
    }else{
        detAPI->netWidth = 640;
        detAPI->netHeight = 640;
        detAPI->clsnum = 15;
        detAPI->anchors = {{10,13, 16,30, 33,23},{30,61, 62,45, 59,119},{116,90, 156,198, 373,326}};
        // 标签标请咨询对应的算法工程师
        uint32_t modelclass[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14};
        uint32_t standerclass[] = {10000, 20000, 30000, 40000, 50000,
                                60000, 70000, 80000, 90000, 100000, 
                                110000, 120000, 130000, 140000, 150000};
        ret = detAPI->AIGOsetLabelMap(modelclass, standerclass, sizeof(modelclass)/sizeof(uint32_t));
        if(ret){
            printf("setLabelMap error with ret=%d\n", ret);
            return ret;
        }
        ret = detAPI->AIGOinit(visdetmodelname.c_str(), 0);
        if(ret){
            printf("init error with ret=%d\n", ret);
            return ret;
        }
    }

同步推理 具体使用demo参见AI_API_demo.cpptest_class函数

    std::vector<objinfo> dets
    ret = detAPI->AIGOpreprocess(img, true);
    ret = detAPI->AIGOinfer();
    ret = detAPI->AIGOpostprocess(dets);

异步调用 具体使用demo参见AI_API_demo.cpptest_class_async函数

    feed_data = std::thread(run_image_, detAPI, imgvis);
    result_data = std::thread(get_result_, detAPI, imgvis, std::ref(dets));

更新说明

支持GD_Video_frame输入的平台

  • atlas200
  • atlas300
  • hisi3404
  • hisi3519

开发说明文档

平台开发说明

算法开发说明