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

<!--
* @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>
## 平台开发说明
## 算法开发说明