二、软件开发
本系列设备使用 TACO-SDK 进行软件功能开发。 TACO-SDK 是一套完整的开发工具包,提供了丰富的视频处理、计算机视觉和AI推理功能。该 SDK 包含了必要的库文件、工具和示例,使开发者能够快速构建和部署视频分析应用。
2.1 SDK 架构说明
其目录架构及其作用如下所示:
tps-future/
├── README.md # 当前 SDK 总体说明文档
├── start_tanntc_docker.sh # 启动 NPU 推理编译环境 Docker 容器脚本
├── start_workshop_docker.sh # 启动 SDK 编译工作环境 Docker 容器脚本
├── ta-base # 基础运行库
│ ├── ta-cv # 计算机视觉相关库
│ │ ├── include # 计算机视觉库头文件
│ │ └── lib # 计算机视觉库文件
│ └── ta-runtime # 运行时库
│ ├── include # 运行时头文件
│ └── lib # 运行时库文件
├── ta-docker-image # Docker 镜像相关文件和说明
│ └── README.md # Docker 镜像使用说明
├── ta-image # 系统镜像工具
│ ├── firmware # 固件文件
│ │ └── sdcard.img # 镜像文件
│ ├── install_sdk_img.sh # 固件下载脚本
│ ├── README.md # 镜像工具说明文档
│ └── update # 更新工具
│ └── mk-tf.sh # 系统镜像制作和烧录工具
└── ta-vsp # 视频处理相关组件
├── others # 其他库
├── README.md # 运行时说明文档
├── ta-ffmpeg # FFmpeg 相关库和工具
│ ├── include # FFmpeg 头文件
│ └── lib # FFmpeg 静态库
├── ta-libdec # 视频解码库
│ ├── include # 解码库头文件
│ └── lib # 解码库文件
├── ta-libenc # 视频编码库
│ ├── include # 编码库头文件
│ └── lib # 编码库文件
├── ta-opencv # OpenCV 相关库和工具
│ ├── include # OpenCV 头文件
│ └── lib # OpenCV 库文件
├── ta-pipeworks # 管道处理框架
│ └── lib # 库文件
├── ta-samples # 示例代码集合
│ ├── model-zoo # 预训练模型集合
│ │ └── YOLO11 # YOLOv11 模型文件及配置
│ ├── avframe_to_mat # AVFrame 到 OpenCV Mat 转换示例
│ │ ├── ta-samples-npu # 基于 NPU 的转换示例
│ │ └── data # 示例测试数据
│ ├── copy_to # 数据拷贝到 Tacv 张量示例
│ │ ├── copy_to_tacv # 拷贝到 Tacv 张量实现
│ │ └── data # 测试数据
│ ├── crop # 图像裁剪示例
│ │ ├── crop_tacv # 基于 Tacv 的裁剪
│ │ ├── crop_taopencv # 基于 OpenCV 的裁剪
│ │ └── data # 测试数据
│ ├── crop_and_resize_padding # 裁剪+缩放+填充示例
│ │ ├── crop_and_resize_padding_tacv # 基于 Tacv 的实现
│ │ └── data # 测试数据
│ ├── csc # 色彩空间转换示例
│ │ ├── csc_tacv # 基于 Tacv 的色彩转换
│ │ ├── csc_taopencv # 基于 OpenCV 的色彩转换
│ │ └── data # 测试数据
│ ├── decode # 视频解码示例
│ │ ├── ffmpeg_decoder_sample.cpp # FFmpeg 解码器示例源码
│ │ └── Makefile # 编译脚本
│ ├── encode # 视频编码示例
│ │ ├── ffmpeg_encoder_sample.cpp # FFmpeg 编码器示例源码
│ │ └── Makefile # 编译脚本
│ ├── hdmi_in_out # HDMI 输入输出示例
│ │ ├── CMakeLists.txt # CMake 构建文件
│ │ ├── hdmi.c # HDMI 操作源码
│ │ ├── README.md # 示例说明
│ │ └── Makefile # 编译脚本
│ ├── jpeg_dec_enc # JPEG 编解码示例
│ │ ├── data # 测试数据
│ │ ├── jpeg_dec_enc_taopencv # 基于 OpenCV 的 JPEG 编解码
│ │ ├── jpeg_dec_tacv # 基于 Tacv 的 JPEG 解码
│ │ └── jpeg_enc_tacv # 基于 Tacv 的 JPEG 编码
│ ├── Makefile # 顶层示例 Makefile
│ ├── mat_to_avframe # OpenCV Mat 转 AVFrame 示例
│ │ ├── mat_to_avframe_taopencv # 基于 OpenCV 的实现
│ │ └── data # 测试数据
│ ├── mot # 多目标跟踪示例
│ │ ├── configs # 配置文件
│ │ ├── include # 头文件
│ │ ├── models # 模型文件
│ │ ├── README.md # 示例说明
│ │ ├── simple_demo # 简单示例
│ │ └── src # 源代码
│ ├── others # 其他示例
│ │ ├── log # 日志组件
│ │ └── nlohmann # nlohmann json 库示例
│ ├── output # 输出组件
│ ├── peripherals # 外设组件
│ │ ├── can.py # CAN 示例
│ │ ├── gpio.py # GPIO 示例
│ │ ├── i2c.py # I2C 示例
│ │ ├── README.md # 示例说明
│ │ ├── relay.py # 继电器示例
│ │ ├── uart.py # UART 示例
│ │ └── xspi.py # XSPI 示例
│ ├── README.md # 示例说明
│ ├── reference.json # 示例配置文件
│ ├── resize # 图像缩放示例
│ │ ├── resize_tacv # 基于 Tacv 的缩放
│ │ ├── resize_taopencv # 基于 OpenCV 的缩放
│ │ └── data # 测试数据
│ ├── start_workshop_docker.sh # 启动工作环境 Docker 脚本
│ ├── start_nntc_docker.sh # 启动 NPU 编译 Docker 脚本
│ └── stitch # 图像拼接示例
│ ├── data # 测试数据
│ └── stitch_tacv # 基于 Tacv 的图像拼接
├── ta-sys # 系统相关组件
│ ├── include # 头文件
│ └── lib # 库文件
├── ta-unify-9200O # NPU 统一推理接口库NPU 统一推理接口库
│ ├── include # 头文件
│ └── lib # 库文件
└── ta-viplite-9200o # 低层驱动库
├── include # 头文件
└── lib # 库文件
2.2 SDK示例使用
在 PC 端打开下载镜像中的 ta-workshop-xxx 文件夹中的 tps-future 文件,执行 ./start_workshop_docker.sh 进入docker镜像中进行编译。
以 avframe_to_mat 为例:
- 进入
sample代码目录
cd /tps-future/ta-vsp/ta-samples/mot
- 创建并进入
build目录
cd mot_sample/simple_demo
mkdir build && cd build
- 使用
cmake配置工程
cmake .. && make
以上示例均在 Docker 开发环境中编译,并将生成的可执行程序通过 scp 拷贝到目标板运行。
2.2.1 AVFrame 到 OpenCV Mat 转换示例 (avframe_to_mat)
taOpenCV 图像处理 sample 集合,演示 taOpenCV 库的各项功能。在执行sample前,请先确认各项输入参数是否正确。另外 /data 目录下存放了测试数据,可以自行替换测试数据。
演示如何将 FFmpeg 解码得到的 AVFrame 转换为 OpenCV 的 cv::Mat 格式。
输入说明:
- H264/HEVC 视频:使用
h264_taco/hevc_taco硬件解码为 NV12
由 AVFrame 构造的 Mat 对象获取 AVFrame 数据,并存储为二进制文件。
taopencv_sample_avframe_to_mat <input_file>
| 参数 | 说明 |
|---|---|
| input_file | 输入视频流(MP4) |
./taopencv_sample_avframe_to_mat output.mp4
2.2.2 数据拷贝到 Tacv 张量示例 (copy_to)
展示如何将外部数据拷贝到 Tacv 张量结构中。
输入说明:
- JPEG 图片:使用
ta_cv_image_jpeg_dec硬件解码为 NV12 - H264/HEVC 视频:使用
h264_taco/hevc_taco硬件解码为 NV12
将图像复制到目标画布指定位置,为了效果展示输出 JPEG。
tacv_sample_copy_to <input_file> src_fmt crop_to_stx crop_to_sty dst_w dst_h dst_fmt copy_num <output_file>
| 参数 | 说明 |
|---|---|
| input_file | 输入图片或视频文件 |
| src_fmt | 源格式(3=NV12) |
| crop_to_stx / crop_to_sty | 复制起始坐标 |
| dst_w / dst_h | 目标画布尺寸 |
| dst_fmt | 目标格式(3=NV12) |
| copy_num | 复制次数 |
| output_file | 输出 JPEG 文件路径 |
./tacv_sample_copy_to output.mp4 1280 720 100 50 copy_to_out.jpg
2.2.3 视频解码示例 (decode)
- 在 docker 中,进入
taco_ffmpeg_decode_sample目录,输入make开始编译,即可获得板端可执行程序taco_decoder_sample:
cd ta-vsp/ta-samples/taco_ffmpeg_decode_sample
make
- 通过
scp命令将程序发送到板端的/usr/data/vdec目录下:
scp -r taco_decoder_sample root@192.168.56.171:/usr/data/vdec # IP 地址按照实际情况更改
- 登录到板端的
/usr/data/vdec目录,目录下有一个视频文件input.mp4,它用于测试解码功能:
./taco_decoder_sample
-
解码停止后,会在当前目录下生成
result.yuv文件,它包含一组分辨率为640x640的NV12视频帧。 -
将
result.yuv拷回主机,用ffmpeg提供的ffplay工具进行播放,观察图像正确性。播放命令为:
ffplay -video_size 640x640 -pixel_format nv12 -i result.yuv
2.2.4 视频编码示例 (encode)
- 在 docker 中,进入
taco_ffmpeg_encode_sample目录,输入make开始编译,即可获得板端可执行程序taco_encoder_sample:
cd ta-vsp/ta-samples/taco_ffmpeg_encode_sample
make
- 通过
scp命令将程序发送到板端的/usr/data/venc目录下:
scp -r taco_encoder_sample root@192.168.56.171:/usr/data/venc # IP 地址按照实际情况更改
- 登录到板端的
/usr/data/venc目录:
./taco_encoder_sample
-
编码停止后,会在当前目录下生成
output_yuv420p_10f.h264文件,它是h264格式的文件。 -
将
output_yuv420p_10f.h264拷回主机,用ffmpeg提供的ffplay工具进行播放,观察图像正确性。播放命令为:
ffplay -f h264 output_yuv420p_10f.h264
2.2.5 图像裁剪示例 (crop)
输入说明:
- JPEG 图片:使用解码为 NV12
- H264/HEVC 视频:使用
h264_taco/hevc_taco硬件解码为 NV12
裁剪图像指定区域,输出 JPEG。
tacv_sample_crop <input_file> <out_w> <out_h> <crop_x> <crop_y> <output_file>
| 参数 | 说明 |
|---|---|
| input_file | 输入图片(jpeg) |
| out_w / out_h | 裁剪输出尺寸 |
| crop_x / crop_y | 裁剪起始坐标 |
| output_file | 输出 JPEG 文件路径 |
./tacv_sample_crop dog_bike_car_640x640.jpg 320 320 50 50 crop_out.jpg
2.2.6 裁剪+缩放+填充示例 (crop_and_resize_padding)
输入说明:
- JPEG 图片:使用
ta_cv_image_jpeg_dec硬件解码为 NV12 - H264/HEVC 视频:使用
h264_taco/hevc_taco硬件解码为 NV12
裁剪 + 缩放 + padding 转换,用 tacv 实现了 letterbox 算法。
tacv_sample_convert_padding <input_file> src_fmt crop_to_stx crop_to_sty crop_w crop_h dst_w dst_h dst_fmt <output_file>
| 参数 | 说明 |
|---|---|
| input_file | 输入图片或视频文件 |
| src_fmt | 源格式(3=NV12) |
| crop_to_stx / crop_to_sty | 裁剪起始坐标 |
| crop_w / crop_h | 裁剪尺寸 |
| dst_w / dst_h | 目标尺寸 |
| dst_fmt | 目标格式(3=NV12, 10=RGB_PACKED, 11=BGR_PACKED) |
| output_file | 输出文件路径 |
./tacv_sample_convert_padding dog_bike_car_640x640.jpg 0 0 320 320 160 240 3 letterbox.jpg
2.2.7 色彩空间转换示例 (csc)
输入说明:
- JPEG 图片:使用
ta_cv_image_jpeg_dec硬件解码为 NV12 - H264/HEVC 视频:使用
h264_taco/hevc_taco硬件解码为 NV12
展示了一个标准的前处理操作,crop ROI -> resize -> CSC 。最终效果编码成 JPEG 输出。
tacv_sample_csc <input_file> <out_w> <out_h> <crop_h> <crop_w> <output_file>
| 参数 | 说明 |
|---|---|
| input_file | 输入图片或视频文件 |
| out_w / out_h | 输出尺寸 |
| crop_w / crop_h | 裁剪尺寸 |
| output_file | 输出 RGB bin 文件路径 |
./tacv_sample_csc output.mp4 128 128 224 224 csc_output.bin
ffplay csc_output.bin -f rawvideo -pix_fmt rgb24 -video_size 128x128
2.2.8 外设接口测试 ( peripherals )
peripherals 外设接口测试工具用于验证开发板上的各种接口功能,包括 SPI、I2C、serial 和 GPIO 等。
-
在 docker 中,进入
peripherals目录,存在can.py、gpio.py、i2c.py、relay.py、uart.py、xspi.py脚本。 -
通过
scp命令将想要运行的程序发送到板端的/usr/data/目录下:
scp -r gpio.py root@192.168.56.171:/usr/data/ # IP 地址按照实际情况更改
- 登录到板端的
/usr/data/目录,对 CAN、I2C、relay、UART、XSPI 及 GPIO 外设模块执行相应的测试命令:
- XSPI 测试
通过 spidev 测试 SPI Flash 设备。支持读取 JEDEC ID、擦除扇区、读写数据。
示例:
# 读取 /dev/spidev2.0 上的 Flash ID
xspi.py id /dev/spidev2.0
# 擦除 0x10000 开始的 4KB
xspi.py erase /dev/spidev2.0 0x10000 4k
# 从起始地址读取 256 字节
xspi.py read /dev/spidev2.0 0x0 256
# 在地址 0x100 写入三个字节
xspi.py write /dev/spidev2.0 0x100 0x11 0x22 0x33
# 设置 SPI 速度为 1 MHz(默认 1 MHz)
xspi.py -s 1000000 read /dev/spidev2.0 0x0 256
- UART 测试
综合性 UART 工具:扫描端口、打开、发送/接收、回环测试及互联测试。
示例:
# 扫描端口
uart.py scan
# 以 115200 波特率打开 /dev/ttyPS0(交互式)
uart.py open 0 -b 115200
# 在端口 0(索引)上发送 “Hello”
uart.py send "Hello" -p 0
# 发送十六进制字节
uart.py send "48656c6c6f" -p /dev/ttyPS0 --hex
# 接收最多 100 字节,超时 10 秒
uart.py receive -p 0 -n 100 -t 10
# 在端口 0 上进行回环测试
uart.py loopback 0 -b 115200 --test "Test123"
# 在两个端口之间进行互联测试
uart.py inter 0 1 -b 115200
- I2C 测试
使用 sysfs 接口的简单 I2C 工具。支持扫描设备、读写寄存器、转储内存。
示例:
# 扫描总线 0
i2c.py 0 scan
# 从设备 0x40 的寄存器 0x10 读取一个字节
i2c.py 0 read 0x40 0x10
# 从寄存器 0x10 读取 4 个字节
i2c.py 0 read 0x40 0x10 4
# 向寄存器 0x10 写入 0xAB
i2c.py 0 write 0x40 0x10 0xAB
# 转储设备 0x40 的寄存器 0x00–0x0F
i2c.py 0 dump 0x40 0x00 0x0F
- CAN 测试
通过 SocketCAN(ctypes)发送和接收 CAN 帧。支持设置比特率和过滤器。
示例:
# 在 can0 上发送 ID 0x123,数据 0x11 0x22 0x33 0x44
can.py send can0 123 11 22 33 44
# 无限接收 can0 上的所有帧
can.py receive can0
# 接收 ID 为 0x123 的帧,持续 10 秒
can.py receive can0 -f 123 -t 10
# 接收 5 帧,并配置接口比特率为 500 kbit/s
can.py receive can0 -n 5 --bitrate 500000
- RELAY 测试
控制连接到 GPIO 引脚的继电器。支持自动测试(开/关)和交互式手动模式。
# 使用默认 GPIO 276 进行自动测试(开/关并验证)
relay.py
# 使用 GPIO 277 进行自动测试,完成后清理
relay.py --gpio 277 --cleanup
# 交互式手动控制
relay.py --manual
- GPIO 测试
使用域概念(CPU/RTC/SAP)控制 GPIO。每个域在基础 GPIO 编号上加上固定偏移量。支持手动控制、设置/读取和清理。
用法:
gpio.py manual --domain {cpu,rtc,sap} --gpio BASE
gpio.py set --domain {cpu,rtc,sap} --gpio BASE VALUE
gpio.py get --domain {cpu,rtc,sap} --gpio BASE
gpio.py cleanup --domain {cpu,rtc,sap} --gpio BASE
gpio.py (交互式)
域偏移: cpu:+200 rtc:+400 sap:0
示例:
# 交互模式(询问域和基础 GPIO)
gpio.py
# CPU 域基础 34(实际 GPIO 234)手动控制
gpio.py manual --domain cpu --gpio 34
# 设置 GPIO 高电平(1)和低电平(0)
gpio.py set --domain cpu --gpio 34 1
gpio.py set --domain cpu --gpio 34 0
# 读取当前值
gpio.py get --domain cpu --gpio 34
# 清理(取消导出)
gpio.py cleanup --domain cpu --gpio 34
2.2.9 HDMI 输入输出示例 (hdmi_in_out)
演示 HDMI OUT 和 HDMI IN OUT 以及 tavo 九宫格处理功能。在执行 sample 前,请先确认各项输入参数是否正确。另外测试 HDMI OUT 需要额外在 /root/ 目录下需存放 video.nv12 测试数据,可以自行替换其他测试数据。
输入说明:
- HDMI OUT: 需要
/root/video.nv12 - HDMI IN OUT: 需要两根 HDMI 线,HDMI IN 接 PC,HDMI OUT 接 HDMI 显示设备
裁剪图像指定区域,输出 JPEG。
hdmi <function>
| 参数 | 说明 |
|---|---|
| function | 测试输出或者输入输出 |
./hdmi out
./hdmi in-out
2.2.10 JPEG 编解码示例 ( jpeg_dec_enc )
- taopencv_sample_jpeg_dec_enc
输入说明: JPEG 图片:使用解码为 NV12。
JPEG图像的解码及编码,输出 JPEG。
taopencv_sample_jpeg_dec_enc <input_file>
| 参数 | 说明 |
|---|---|
| input_file | 输入图片(jpeg) |
./taopencv_sample_jpeg_dec_enc src_jpeg_1920x1080.jpg
- tacv_sample_jpeg_dec
输入说明:
- JPEG 图片:使用
ta_cv_image_jpeg_dec硬件解码为 NV12 - H264/HEVC 视频:使用
h264_taco/hevc_taco硬件解码为 NV12
JPEG 硬件解码,输出二进制文件,可用ffplay播放测试。
tacv_sample_jpeg_dec <jpeg_file> <width> <height> <output_file>
| 参数 | 说明 |
|---|---|
| jpeg_file | 输入 JPEG 文件 |
| width / height | 图像尺寸 |
| output_file | 输出 JPEG 文件路径 |
./tacv_sample_jpeg_dec dog_bike_car_640x640.jpg 640 640 output_dec.bin
ffplay -f rawvideo -pix_fmt nv12 -video_size 640x640 output_dec.bin
- tacv_sample_jpeg_enc
输入说明:
- JPEG 图片:使用
ta_cv_image_jpeg_dec硬件解码为 NV12 - H264/HEVC 视频:使用
h264_taco/hevc_taco硬件解码为 NV12
缩放图像,为了效果展示,保存成JPEG文件。
tacv_sample_jpeg_enc <input_file> <output_file>
| 参数 | 说明 |
|---|---|
| input_file | 输入图片或视频文件 |
| out_w / out_h | 缩放输出尺寸 |
| output_file | 输出 JPEG 文件路径 |
./tacv_sample_jpeg_enc dog_bike_car_640x640.jpg jpeg_enc_output.jpg
2.2.11 OpenCV Mat 转 AVFrame 示例 (mat_to_avframe)
输入说明: H264/HEVC 视频:使用 h264_taco/hevc_taco 硬件解码为 NV12。
由AVFrame构造的Mat对象,并进行格式转换操作,输出为JPEG文件。
taopencv_sample_mat_to_avframe <input_file>
| 参数 | 说明 |
|---|---|
| input_file | 输入视频流(MP4) |
./taopencv_sample_mat_to_avframe output.mp4
ffplay load_avframe.nv12 -f rawvideo -pix_fmt nv12 -video_size 640x360
2.2.12 多目标跟踪示例 (mot)
属于 pipeline类型的 demo,其中包含解码、图像处理、模型处理、编码、后处理等模块
- 编译
在x86主机上,需使用TACO SDK进行交叉编译环境的搭建。推荐通过Docker构建交叉编译环境,具体操作如下:
1.获取 TACO SDK
2.将 mot 代码拷贝到 TACO SDK 目录下
3.启动Docker编译环境 进入解压后的目录,并执行脚本以启动并进入已预配置好的Docker容器:
./start_workshop_docker.sh
此时即可在容器内进行程序编译。
cd mot_sample/simple_demo
mkdir build && cd build
cmake .. && make
- 运行
执行完编译操作盒,可以获得可执行文件 simple_demo 。在板端运行还需要准备模型文件、config 文件以及数据文件,我们可以通过 scp 命令将文件拷贝到板端。 运行命令:
./simple_demo config.json
注意:
- config.json 为配置文件,请根据实际情况进行修改。
- conifg.json 中的模型文件路径或者数据文件路径为板端的路径,请根据实际情况进行修改。
- 通过修改 config.json 可以设置 opencv 解码或者 ffmpeg 解码
- 修改 config.json 中的 output 字段可以保存输出视频为 mp4 文件
2.2.13 图像缩放示例 ( resize )
- tacv_sample_resize
缩放图像,为了效果展示,保存成 JPEG 文件。
tacv_sample_resize <input_file> <out_w> <out_h> <output_file>
| 参数 | 说明 |
|---|---|
| input_file | 输入图片或视频文件 |
| out_w / out_h | 缩放输出尺寸 |
| output_file | 输出 JPEG 文件路径 |
./tacv_sample_resize dog_bike_car_640x640.jpg 320 320 resize_output.jpg
- tacv_sample_resize
图像缩小,输出 JPEG。
taopencv_sample_resize <input_file> <out_width> <out_height>
| 参数 | 说明 |
|---|---|
| input_file | 输入图片(jpeg) |
| out_width / out_height | resize 输出尺寸 |
./taopencv_sample_resize src_jpeg_1920x1080.jpg 360 640
./taopencv_sample_resize output.mp4 360 640
2.2.14 图像拼接示例 (tacv_sample_stitch)
实现四宫格 sample,注意这里是采取了一个输入复制了多份,然后拼接到目标画布,NV12 输出为 JPEG,并将效果图编码成了 JPEG 文件。
tacv_sample_stitch <input_file> src_fmt src_crop_stx src_crop_sty src_crop_w src_crop_h dst_w dst_h dst_fmt dst_crop_w dst_crop_h input_num <output_file>
| 参数 | 说明 |
|---|---|
| input_file | 输入图片或视频文件 |
| src_fmt | 源格式(3 = NV12) |
| src_crop_stx / src_crop_sty | 源裁剪起始坐标 |
| src_crop_w / src_crop_h | 源裁剪尺寸 |
| dst_w / dst_h | 目标画布尺寸 |
| dst_fmt | 目标格式(3=NV12, 10=RGB_PACKED, 11=BGR_PACKED) |
| dst_crop_w / dst_crop_h | 每个 tile 在目标画布中的尺寸 |
| input_num | 输入图像数量 |
| output_file | 输出文件路径 |
./tacv_sample_stitch dog_bike_car_640x640.jpg stitch_out.jpg