|
|
|
|
<!--
|
|
|
|
|
* @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为1,RGBA/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 ×tamp, # 透传参数,可做数据同步时使用
|
|
|
|
|
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>
|
|
|
|
|
## 平台开发说明
|
|
|
|
|
## 算法开发说明
|