跳转至

svp_quick_start

svp 快速入门(ive 与 svp_npu)

1. 概述与作用

本文档包含对两个独立模块样例的说明:

  • ive :对应samples/mpp/svp/ive,演示 HiSilicon IVE(Intelligent Video Engine)固定功能 CV 加速器的各种算子
  • svp_npu :对应samples/mpp/svp/svp_npu,演示通过 SVP_ACL 接口调用 NPU 。

在编译本样例之前,请参照Hi3516CV610环境搭建指南和快速上手指南完成编译环境的搭建。

ive

A.1 概述与作用

sample_ive_main 演示 IVE 算子链:Canny、GMM2、Memory test、Sobel、St&LK 光流、Perspective transform、Occlusion detection、Motion detection、Resize。其中 case 0–5/8 是纯 FILE→IVE→FILE 离线测试,case 6/7 走 VI→VPSS→IVE→VENC/VGS 的在线链路。

专业名词与缩写:

  • SVP — Smart Vision Platform,海思智能视觉平台,含 IVE/NPU
  • IVE — Intelligent Video Engine,固定功能 CV 加速器
  • Canny — 边缘检测算法
  • GMM2 — Gaussian Mixture Model v2,背景减除
  • Sobel — Sobel 梯度滤波
  • St&LK — SAD Tracker + Lucas-Kanade 光流
  • PerspTrans — Perspective Transform 透视变换 warp
  • OD — Occlusion Detection 遮挡检测
  • MD — Motion Detection 运动检测(ss_mpi_ivs_md)
  • Resize — IVE 缩放算子
  • MemoryTest — IVE 内存 cached/uncached 测试

A.2 执行准备

A.2.1 编译

进入样例目录执行 make 即可完成编译:

cd samples/mpp/svp/ive && make

编译成功之后,在当前目录下会生成一个sample_ive_main的可执行文件,可以放社区支持的开发板上运行。

A.2.2 加载 KO

ko加载脚本位于 output/mpp/ko/load_ko,有两个脚本,load3516cv610_20s和load3516cv610_20s_debug。区别为load3516cv610_20s_debug脚本会打开 logmpp_show=1(日志记录)、proc_show=1(proc信息打印),并将 mem_process_isolation 置为 0(不启用进程间mmz隔离)。

由于当前版本不支持进程间mmz隔离,因此需要在load3516cv610_20s脚本中将 mem_process_isolation 置为 0或者使用load3516cv610_20s_debug脚本,此处以load3516cv610_20s_debug脚本为例,20s内存大小为128MB,默认分配为 32MB OS、96MB MMZ,加载命令为:

./load3516cv610_20s_debug -i

可以通过-h命令查看具体用法:

./load3516cv610_20s_debug -h
Usage:  ./load3516cv610_20s_debug [-option] [-sensor0~1] 
options:
    -i                       insert modules
    -r                       remove modules
    -a                       remove modules first, then insert modules
    -sensor0~1 sensor_name   config sensor type    [default: hy006_3814_0011]
    -mmz_start               config MMZ start addr [default: 0x42000000]
    -mmz_size                config MMZ mem size [unit: M, default: 96M]
    -ir_auto                 config ir_auto enable [default: 0]
    -profile                 config sys_profile [default: 0]
    -h                       help information
Available sensors:hy006_3814_0011 bt1120/bt656/bt601
for example: ./load3516cv610_20s_debug -i -sensor0 hy006_3814_0011 -sensor1 hy006_3814_0011 -mmz_start 0x42000000 -mmz_size 96M -ir_auto 1

如果需要调整os和mmz的大小,需要参考《内存布局调整指南》对内存大小进行调整。

如果是使用社区默认提供的镜像,这些ko已经打包到文件系统中,烧录到单板上后位于/ko目录下,在系统启动后会自动加载这些ko。

A.2.3 运行时依赖文件

在运行样例前,需要提前准备:

  • 指定运行时依赖的so库路径

MPP样例依赖的so库位于soc/libs/musl下,需要将该目录下的so库拷贝到开发板上(或将这些so库所在的目录挂载到开发板上),并指定运行时依赖库的环境变量,假设这些so库位于/mnt/libs/,执行如下命令:

```shell
export LD_LIBRARY_PATH=/mnt/libs/:$LD_LIBRARY_PATH
```

如果是使用社区默认提供的镜像,这些so库已经打包到文件系统中,烧录到单板上后位于/usr/lib目录下,该目录是系统默认搜索目录,不需要执行export LD_LIBRARY_PATH命令去指定。

  • 启动MPP服务

当前MPP媒体模块处于用户态,通过一个独立进程提供相关接口的调用服务,该进程位于samples/mpp/sdk_server下,执行如下命令即可生成sdk_server可执行文件:

```shell
cd samples/mpp/sdk_server && make
```

在单板上执行./sdk_server &即可启动MPP服务。

  1. sdk_server同样依赖soc/libs/musl下的so库,因此也需要参照上述export LD_LIBRARY_PATH指定路径;
  2. 如果是使用社区默认提供的镜像,sdk_server进程已经打包到文件系统中,烧录到单板上后位于/usr/bin目录下,并在系统启动时会自动启动sdk_server。
  • 样例运行时候需要的资源文件

对于本样例,依赖文件位于samples/mpp/svp/ive/data/,包括:

  • input/canny/canny.yuv — 414720 字节
  • input/gmm2/gmm2_352x288_sp400_frm1000.yuv — 约 97MB
  • input/resize/resize_720x576_420sp.yuv — 约6MB
  • input/sobel/sobel.yuv — 414720 字节
  • input/stlk/st_lk_720x576_420sp.yuv — 约6MB
  • input/testmem/test_mem_in.yuv — 414720 字节
  • input/psp/src/box_640x480_420sp_nv21.yuv — persp trans 输入
  • output/{canny,gmm2,resize,sobel,stlk,testmem,psp}/ — 空目录用于结果输出

缺失时控制台报错(如 fopen canny.yuv failed),程序异常退出。

A.3 支持的 Case 列表

调用语法:./sample_ive_main <index> [complete],argc 必须为 2 或 3。

index 名称 数据通路 说明
0 Canny FILE→IVE→FILE 边缘检测;可选 complete:0=部分 canny,1=完整 canny
1 Gmm2 FILE→IVE→FILE 背景建模
2 Memory test FILE→IVE→FILE IVE 内存 cached/uncached 测试
3 Sobel FILE→IVE→FILE 梯度滤波
4 St&LK FILE→IVE→FILE SAD Tracker + Lucas-Kanade 光流
5 PerspTrans FILE→IVE→FILE 透视变换 warp
6 OD VI→VPSS→IVE→VENC 遮挡检测;DDR 限制:10B/608 不可运行
7 MD VI→VPSS→IVE→VGS→VENC 运动检测(ss_mpi_ivs_md);DDR 限制:10B/608 不可运行
8 Resize FILE→IVE→FILE IVE 缩放算子

无交互菜单;离线 case 运行完成后自动退出,在线 case 6/7 运行中按回车退出。

A.3.1 case 0 - Canny

Canny 操作是一种经典的边缘检测算法,Sample中共提供了两种不同的实现方式,主要区别在于是否包含了完整的Canny步骤。Sample中读取灰度图进行边缘检测,得到运算后的检测结果图并保存为文件,两种Canny边缘提取流程如图1所示。

图 1 Canny边缘提取

  • part canny 仅实现了Canny算法的部分步骤,只进行了滤波和梯度计算,省略了极大值抑制和双阈值检测。特点是实现简单,计算速度快,边缘检测效果较差,容易出现噪声或断裂的边缘,适用于对实时性要求高,但对边缘精度要求不高的场景。

核心步骤:

①梯度计算 ss_mpi_ive_mag_and_ang;

②阈值化处理 ss_mpi_ive_threshold_u16。

part canny边缘检测效果如图2所示。

图 2 part canny

执行命令:./sample_ive_main 0 0

执行结果验证: 执行无报错,执行结果输出在samples/mpp/svp/ive/data/output/canny/cannyout_complete_0.yuv。

  • complete canny 严格遵循了Canny算法的所有步骤,包括高斯滤波、梯度计算、非极大值抑制、双阈值检测和边缘连接。特点是实现复杂,计算量较大,边缘检测效果较好,能够提取出连续、清晰的边缘。

核心步骤:

① ss_mpi_ive_canny_hys_edge 灰度图的Canny边缘提取的前半部:求梯度、计算梯度幅值幅角、磁滞阈值化及非极大抑制。

② ss_mpi_ive_canny_edge 灰度图的Canny边缘提取的后半部:连接边缘点,形成Canny边缘图。

complete canny边缘检测效果如图3所示。

图 3 complete canny

执行命令:./sample_ive_main 0 1

执行结果验证: 执行无报错,执行结果输出在samples/mpp/svp/ive/data/output/canny/cannyout_complete_1.yuv。

A.3.2 case 1 - Gmm2

Gmm2背景建模示例。主要演示了如何利用Gmm2实现建模,提取前景。Gmm2建模提取前景流程如图4所示。

图 4 Gmm2建模提取前景流程

Gmm2效果如图5和图6所示。

图 5 Gmm2示例输入的视频帧

图 6 识别到的背景和前景

执行命令:./sample_ive_main 1

执行结果验证: 执行无报错,执行结果输出在samples/mpp/svp/ive/data/output/gmm2/下,bg_352x288_sp400.yuv(背景识别)和fg_352x288_sp400.yuv(前景提取)。

A.3.3 case 2 - Memory test

DMA操作示例。主要演示了如何创建直接内存访问任务。sample流程示例如图7所示。

图 7 MemoryTest流程

执行命令:./sample_ive_main 2

执行结果验证: 执行无报错,执行结果输出在samples/mpp/svp/ive/data/output/testmem/test_mem_out.yuv。

A.3.4 case 3 - Sobel

Sobel示例,主要演示了Sobel的用法,同时演示了mmz_alloc_cache、flush_cache的正确用法。主要流程如图8所示。

图 8 Sobel流程

执行命令:./sample_ive_main 3

执行结果验证: 执行无报错,执行结果输出在samples/mpp/svp/ive/data/output/sobel/下。

A.3.5 case 4 - St&LK

ShiTomasi + LK 示例。主要演示了如何利用角点提取及LK跟踪,具体实现流程如图9所示。

图 9 ShiTomasi + LK 流程

执行命令:./sample_ive_main 4

执行结果验证: 执行无报错,执行结果输出在samples/mpp/svp/ive/data/output/stlk/下。

A.3.6 case 5 - PerspTrans

透视变换示例。主要演示了如何根据输入源图的区域位置和点对信息做相应的透视变换,透视变换流程如下图10所示。

图 10 透视变换流程

执行命令:./sample_ive_main 5

执行结果验证: 执行无报错,执行结果输出在samples/mpp/svp/ive/data/output/psp/下。

A.3.7 case 6 - OD

检测摄像头是否被遮挡的示例实现,通过检测VI传入的视频帧,识别摄像头是否有遮挡,当检测到遮挡时在控制台打印告警信息,检测流程如图11所示。

核心代码:sample_ive_od_proc,演示了实现遮挡检测的接口调用。

图 11 遮挡检测流程

执行命令:./sample_ive_main 6

执行结果验证: 执行无报错,摄像头采集画面会保存在samples/mpp/svp/ive/stream_chn0.h264, 当镜头出现遮挡时,控制台打印 “Occlusion detected!”。

A.3.8 case 7 - MD

移动侦测示例,移动侦测是通过分析图像或视频序列来检测场景中的运动目标。sample演示了如何利用md实现移动侦测,通过检测VI传入的视频帧,对运动物体进行画框,并编码保存成文件。移动侦测流程如下图12所示。

图 12 移动侦测流程

执行命令:./sample_ive_main 7

执行结果验证:执行无报错, 摄像头采集画面会保存在samples/mpp/svp/ive/stream_chn0.h264,会对移动物体进行画框。

A.3.9 case 8 - Resize

图像大小缩放示例,示例演示了对YUV420SP格式的图像大小镜像缩小并保存输出图像。

核心API:ss_mpi_ive_resize,详细API接口描述及配置参数可参考《IVE API 参考》。

Sample Resize效果如图13所示。

图 13 Resize效果

执行命令:./sample_ive_main 8

执行结果验证:执行无报错, 执行结果输出在samples/mpp/svp/ive/data/output/resize/resize_out_360x288_420sp.yuv。

如需根据业务调整以上Sample对应配置的接口参数,请参考《IVE API 参考》进行配置。


svp_npu

B.1 概述与作用

sample_svp_npu_main 演示通过 SVP_ACL 接口调用 NPU 跑 ResNet50、LSTM、YOLO 端到端检测、NPU 任务抢占、动态 batch 推理。NPU 是 Hi3516CV610 的神经网络处理单元,SVP_ACL 是 HiSilicon SVP ACL(Smart Vision Processing Advanced Computing Language)提供的C语言API库。

专业名词与缩写:

  • NPU — Neural Processing Unit,神经网络处理单元
  • SVP_ACL — Smart Vision Processing Advanced Computing Language API,svp_acl_* 系列函数
  • ResNet50 — 50 层残差 CNN 分类网络
  • LSTM — Long Short-Term Memory 循环神经网络
  • YOLOv5/YOLOv8 — You Only Look Once 目标检测器
  • OM — Offline Model,ATC转换的板端模型文件 .om 格式
  • Dynamic batch — 动态 batch 推理
  • AIPP — AI Pre-Processing,图像预处理

B.2 执行准备

B.2.1 编译

进入样例目录执行 make 即可完成编译:

cd samples/mpp/svp/svp_npu && make

编译成功之后,在当前目录下会生成一个sample_svp_npu_main的可执行文件,可以放社区支持的开发板上运行。

B.2.2 加载 KO

ko加载脚本位于 output/mpp/ko/load_ko,有两个脚本,load3516cv610_20s和load3516cv610_20s_debug。区别为load3516cv610_20s_debug脚本会打开 logmpp_show=1(日志记录)、proc_show=1(proc信息打印),并将 mem_process_isolation 置为 0(不启用进程间mmz隔离)。

由于当前版本不支持进程间mmz隔离,因此需要在load3516cv610_20s脚本中将 mem_process_isolation 置为 0或者使用load3516cv610_20s_debug脚本,此处以load3516cv610_20s_debug脚本为例,20s内存大小为128MB,默认分配为 32MB OS、96MB MMZ,加载命令为:

./load3516cv610_20s_debug -i

如果需要调整os和mmz的大小,需要参考《内存布局调整指南》对内存大小进行调整。

如果是使用社区默认提供的镜像,这些ko已经打包到文件系统中,烧录到单板上后位于/ko目录下,在系统启动后会自动加载这些ko。

B.2.3 运行时依赖

在运行样例前,需要提前准备:

  • 指定运行时依赖的so库路径

MPP样例依赖的so库位于soc/libs/musl下,需要将该目录下的so库拷贝到开发板上(或将这些so库所在的目录挂载到开发板上),并指定运行时依赖库的环境变量,假设这些so库位于/mnt/libs/,执行如下命令:

```shell
export LD_LIBRARY_PATH=/mnt/libs/:$LD_LIBRARY_PATH
```

如果是使用社区默认提供的镜像,这些so库已经打包到文件系统中,烧录到单板上后位于/usr/lib目录下,该目录是系统默认搜索目录,不需要执行export LD_LIBRARY_PATH命令去指定。

  • 启动MPP服务

当前MPP媒体模块处于用户态,通过一个独立进程提供相关接口的调用服务,该进程位于samples/mpp/sdk_server下,执行如下命令即可生成sdk_server可执行文件:

```shell
cd samples/mpp/sdk_server && make
```

在单板上执行./sdk_server &即可启动MPP服务。

  1. sdk_server同样依赖soc/libs/musl下的so库,因此也需要参照上述export LD_LIBRARY_PATH指定路径;
  2. 如果是使用社区默认提供的镜像,sdk_server进程已经打包到文件系统中,烧录到单板上后位于/usr/bin目录下,并在系统启动时会自动启动sdk_server。
  • 样例运行时候需要的资源文件

对于本样例,依赖文件位于samples/mpp/svp/svp_npu/data/,包括:

  • model/:resnet50.om(26MB)、resnet50_with_preemption.om(26MB)、lstm.om(45KB)、yolov5.om(8.5MB)、yolov8.om(3.9MB)
  • image/:3_224_224_batch_1.bgr(150KB)、3_224_224_batch_8.bgr(1.2MB)、dolls_video.h264(2.9MB)、st_lk_720x576_420sp.yuv(622KB)
  • vector/:xt.txt.bin、cont.txt.bin(LSTM 输入)

缺失时 svp_acl_model_load 报错,程序异常退出。

B.3 支持的 Case 列表

调用语法:./sample_svp_npu_main <index> [yolo_version],argc 2 或 3,无交互菜单;case 0–4 运行完成后自动退出,case a 运行中按回车退出。

index 名称 说明
0 svp_acl_resnet50 单次 ResNet50 推理
1 svp_acl_resnet50_multi_thread 多线程 ResNet50
2 svp_acl_resnet50_dynamic_batch_with_mem_cached 动态 batch
3 svp_acl_lstm LSTM 推理
4 svp_acl_preemption NPU 任务抢占演示;DDR 限制:10B/608 不可运行
a 端到端 YOLO pipeline VI→VPSS→SVP_NPU→VGS→VENC;调用示例 ./sample_svp_npu_main a 8(YOLOv8);目前仅接受 8,代码 sprintf("./data/model/yolov%u.om", index);DDR 限制:10B/608 不可运行

代码中提供了NPU通用智能模型接口的调用流程,接口调用如图1所示。

图 1 通用模型推理流程

B.3.1 case 0 - svp_acl_resnet50

resnet50模型示例代码,主要演示了NPU加载resnet50模型,并推理单张图片的过程。

应用场景:NPU 分类网模型的加载推理,以及如何处理分类网模型的推理结果。

核心代码:sample_common_svp_npu_output_classification_result,通过获取分类网输出结果,对每种类的分值进行排序,并输出分值最高的前五个分类。

执行命令:./sample_svp_npu_main 0

执行结果验证:控制台输出ResNet50 top-5 类别及置信度。

B.3.2 case 1 - svp_acl_resnet50_multi_thread

NPU推理多线程示例代码,在svp_acl_resnet50的基础上,加入了多线程的实现。

核心代码:sample_svp_npu_acl_model_execute_multithread,通过创建多个NPU task, 将任务分发给不同线程,从而达到多线程调用NPU任务的效果。

执行命令:./sample_svp_npu_main 1

执行结果:控制台输出ResNet50 top-5 类别及置信度。

B.3.3 case 2 - svp_acl_resnet50_dynamic_batch_with_mem_cached

动态batch示例代码,主要演示了如何调用接口动态配置batch,并完成多batch推理。svp_acl_resnet50输入数据为一张单batch图片,该用例在svp_acl_resnet50基础上,通过配置模型batch_size,使模型每次处理图片的数量达到8张。同时,该sample演示了如何配置NPU task是否带cache调用。

核心参数配置:

g_svp_npu_task[0].cfg.max_batch_num = 8;
g_svp_npu_task[0].cfg.is_cached = TD_TRUE;

核心代码:sample_common_svp_npu_set_dynamic_batch, 通过调用svp_acl_mdl_set_dynamic_batch_size接口,配置模型batch_num。batch_num值约束请查看《ATC工具使用指南》中batch_num参数说明。

执行命令:./sample_svp_npu_main 2

执行结果验证:控制台输出ResNet50 top-5 类别及置信度。

B.3.4 case 3 - svp_acl_lstm

lstm模型实例代码,主要演示了如何配置lstm模型推理所需的参数。lstm具有两路输入,且lstm模型推理需要额外配置total_t参数(Recurrent网络包含LSTM/RNN/GRU层每一句话的最大帧数),该sample演示了lstm模型推理的参数配置。

特殊参数配置:

g_svp_npu_task[0].cfg.total_t = 3;

核心代码:svp_acl_mdl_set_total_t,调用ACL接口配置模型所需的total_t参数。

执行命令:./sample_svp_npu_main 3

执行结果验证:执行无报错。

B.3.5 case 4 - svp_acl_preemption

模型抢占示例代码,主要演示了当开启模型抢占时,高优先级的模型推理任务可以打断低优先级的推理任务,从而抢占NPU资源优先执行。该sample中加载的模型为可抢占模型(模型是否可被抢占参考《ATC工具使用指南》“--hwts_preemption_enable”章节), NPU通过两次加载该模型,并配置其中一个模型的抢占级别更高,进而使高优先级的模型可以抢占低优先级的模型,获取对应NPU资源优先执行。

核心代码:sample_svp_npu_set_model_prior_info,通过配置抢占参数,使分别加载进来的模型拥有不同的抢占优先级,进而在推理任务开始时,优先执行抢占优先级高的模型推理任务

核心参数示例:

g_svp_npu_model.prior_cfg.priority = 2; // 模型优先级值
g_svp_npu_model.prior_cfg.prior_preemp_en = 1; // 是否开启优先级抢占
g_svp_npu_model.prior_cfg.prior_up_step_timeout = 1200; // 优先级提升超时值

执行命令:./sample_svp_npu_main 4

执行结果验证:执行无报错,打印线程调度推理时对应的model_index和完成推理的数量complete cnt。

B.3.6 case a - 端到端 YOLO pipeline

yolov8模型示例代码,主要演示了如何全流程跑通VI、VPSS、NPU推理、VGS、VENC,为实际应用场景提供了接口调用的流程示例。整个流程涉及到VI, VPSS, VB, NPU, VGS, VENC, VO多个模块的协同工作,各个模块调用流程如图2所示。

图 2 yolov8 sample流程图

主要流程:

  • VI模块进行摄像头传感器流输入。
  • 视频流会送入VPSS模块进行图像处理,这里将原始流截取出yuv420P图像,并resize成模型需要用到的图像大小。
  • VB模块负责管理缓冲池,接受来自VPSS输出信号。
  • NPU不断从VB缓冲池中获取对应帧,创建任务并进行推理。
  • VGS模块根据推理结果,在展示帧上进行画框。
  • VENC模块将展示帧进行编码。

核心代码:sample_common_svp_npu_start_vi_vpss_venc,示例代码中描述了如何配置vi参数、创建vb、启动vi、绑定vpss、启动vpss、vpss连接vb、启动venc等。

执行命令:./sample_svp_npu_main a 8

执行结果验证:执行无报错。输出结果文件在samples/mpp/svp/svp_npu/stream_chn0.h264,对摄像头采集画面的物体进行识别画框。