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.

373 lines
13 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!--
* @Author: turboLIU
* @Date: 2025-04-16 13:13:08
* @LastEditTime: 2025-04-18 11:55:00
* @Description: Do not edit
* @FilePath: /Algo_ACL_Common/readme.md
-->
# <div align="center">使用说明文档</div>
## 结构体说明
**光源类型**
```
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.cpp](./demo/AI_API_demo.cpp)中[test_class](./demo/AI_API_demo.cpp:1660)函数
```
std::vector<objinfo> dets
ret = detAPI->AIGOpreprocess(img, true);
ret = detAPI->AIGOinfer();
ret = detAPI->AIGOpostprocess(dets);
```
**异步调用**
具体使用demo参见[AI_API_demo.cpp](./demo/AI_API_demo.cpp)中[test_class_async](./demo/AI_API_demo.cpp:1660)函数
```
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
# <div align="center">开发说明文档</div>
## 平台开发说明
## 算法开发说明