x‑cube‑n6‑ai‑hand‑landmarks是 ST 官方面向 STM32N6 平台推出的经典 AI 入门软件包,基于 FreeRTOS 搭建,采用双模型级联方案实现手掌检测与 21 点手部关键点标记。该 Demo 完整覆盖 CSI 摄像头采集、DCMIPP ISP 图像流水线、NPU 模型推理、CPU 后处理、LCD 实时可视化全链路,很多做手势识别、人机交互的开发者都会以此作为二次开发模板STMCU。
很多开发者初次接触这套工程,容易混淆两套模型输入输出、DCMIPP 多 Pipe 图像裁剪缩放模式、检测 / 跟踪双模式切换逻辑,以及 STEdgeAI 模型部署配置。本文基于 LAT1708 官方文档,完整梳理数据流、摄像头配置、AI 线程逻辑、模型细节、部署脚本以及工程踩坑要点。
资料获取:实战经验 | LAT1708 STM32N6_Hand Landmarks_Demo介绍
1. 工程整体数据流总览
整套 Demo 的硬件链路:CSI‑2 摄像头输入原始图像,送入 STM32N6 DCMIPP 图像子系统,分出两条图像流水线。
- Pipe1(显示流水线):原始 2592×1940 图像缩放为 800×480,输出到 PSRAM,供给 LTDC 驱动 LCD 屏幕做画面显示;
- Pipe2(神经网络流水线):原始图像缩放为 192×192,存入 NN 输入缓冲区,送入第一套手掌检测(Palm detector)模型。
Palm detector 模型推理完成,经过 CPU 后处理,输出手掌 ROI 框、7 个手掌关键点、手掌旋转角度。CPU/GPU 对显示缓冲区图像执行 Crop、Resize、旋转,裁剪出手掌区域调整至 224×224,送入第二套 Hand‑landmark 关键点模型推理,输出 21 个手部关键点。最终将边框、关键点坐标映射到屏幕坐标系,在 LCD 叠加绘制可视化结果STMCU。
核心运行策略:检测 + 跟踪双模式。手掌丢失时执行完整手掌检测;手掌跟踪稳定后跳过手掌检测模型,只运行关键点模型,降低算力开销。
2. 摄像头与 DCMIPP 图像子系统配置
2.1 支持的摄像头硬件
Demo 原生支持三款 CSI 摄像头传感器:
- Sony IMX335:STM32N6570‑DK 开发板板载摄像头;
- ST VD66GY:ST 全局快门 CIS;
- ST VD55G1:ST 全局快门 CIS。
图像翻转镜像宏定义:
#define CAMERA_FLIP CMW_MIRRORFLIP_MIRROR
可选模式:CMW_MIRRORFLIP_NONE、CMW_MIRRORFLIP_FLIP、CMW_MIRRORFLIP_MIRROR、CMW_MIRRORFLIP_FLIP_MIRROR。
2.2 DCMIPP 多 Pipe 架构
DCMIPP 内置多路 ISP 处理 Pipe:Pipe0、Pipe1、Pipe2。工程中约定:
- Pipe1:输出用于 LCD 显示图像;
- Pipe2:输出送给神经网络推理的图像。 数据源支持 CSI‑2 接口或者并行摄像头接口,完成降采样、YUV 格式转换等预处理,输出至 AXI 总线,写入外部 PSRAM 缓冲区,详细寄存器参考 RM0486 参考手册。
2.3 四种图像纵横比处理模式
DCMIPP 输出图像尺寸与神经网络输入尺寸、LCD 屏幕尺寸不一致,软件层提供 4 种处理模式,这是移植自定义摄像头非常容易踩坑的环节:
- CMW_Aspect_ratio_crop:NN 管道直接按目标宽高做比例裁剪,图像边缘像素直接丢弃;显示管道复用 NN 管道画面放大输出;
- CMW_Aspect_ratio_fit:将原图直接压缩到 NN 输入尺寸,会造成图像拉伸变形;显示管道复用该变形图像放大;
- CMW_Aspect_ratio_fullscreen:NN 管道同样压缩变形;显示管道按原始画面比例适配全屏 800×480;
- CMW_Aspect_ratio_manual_roi(Demo 实际使用):先对原图做 ROI 裁剪适配 LCD 比例,NN 管道再对裁剪后画面压缩(会变形)。
移植第三方摄像头,必须确认使用哪一种纵横比模式,模式选错会导致手掌检测模型识别率大幅下降。
3. AI 主线程 nn_thread_fct 运行逻辑
nn_thread_fct()是 FreeRTOS 下 AI 推理核心工作线程,承担:ST‑AI 运行时初始化、两套模型初始化、相机管线启动、帧循环推理、检测 / 跟踪模式切换、结果输出给显示线程。
3.1 两种工作模式
- 检测模式(is_tracking = 0):取完整帧图像运行 Palm detector 手掌检测模型,解析得到手掌 ROI;
- 跟踪模式(is_tracking != 0):跳过开销大的 Palm detector,直接复用上一帧计算得到的 ROI,仅运行 Hand‑landmark 关键点模型;当关键点置信度低于阈值,判定跟踪丢失,切回检测模式。
完整循环流程:
- 从 NN 输入队列取出一帧预处理完成图像;
- 如果跟踪丢失,执行 Palm detector 手掌检测;
- 获取手掌 ROI,执行裁剪、旋转、缩放,准备 224×224 图像;
- 运行 Hand‑landmark 关键点推理;
- 判断关键点置信度是否有效:
- 有效:把关键点坐标反解映射到屏幕坐标系,计算下一帧跟踪使用的 ROI;
- 无效:标记跟踪丢失,下一帧退回完整手掌检测;
- 将计时信息、绘制数据发布给显示线程刷新屏幕。
4. 两套 AI 模型输入输出与后处理细节
4.1 模型一:Palm‑Detector 手掌检测模型
- 输入:
1 × 192 × 192 ×3,uint8,channel‑last,整帧 RGB 图像; - 输出张量(float32):
- score:2016×1×1,每个 anchor 候选框置信 logit;
- boxes:2016×18;每个 anchor 输出 4 个 box 参数 +7 个手掌关键点(每个关键点 x/y,合计 14 值)。
后处理分为两大函数:
- pd_pp_decode () 解码:遍历 2016 组 anchor,sigmoid 转换置信,解码框坐标、7 个手掌关键点;
- pd_pp_nms () 非极大抑制:按置信排序,IoU 阈值过滤重叠检测框,保留置信最高手掌目标。
坐标转换与 ROI 生成:
cvt_pd_coord_to_screen_coord():将归一化坐标换算为 LCD 屏幕像素坐标;pd_box_to_roi()生成关键点模型输入 ROI:利用手掌关键点 0、2 估算手掌旋转角度;以手掌框为中心,y=-0.5向上偏移,scale=2.6 放大,生成 ROI 区域。
4.2 模型二:Hand‑Landmark 手部关键点模型
- 输入:
1 ×224 ×224 ×3,uint8,channel‑last,裁剪旋转之后的手掌局部图像; - 输出 4 路 float32 张量,工程实际只使用两路:
- 置信度输出:判断当前 ROI 内手掌是否有效,阈值默认
LD_PROB_THRESHOLD=0.25; - 关键点输出:21 个关键点,每个关键点输出 x/y/z 三维,Demo 只取用 x、y 坐标,丢弃 z 深度值。
- 置信度输出:判断当前 ROI 内手掌是否有效,阈值默认
后处理关键步骤:
hand_landmark_prepare_input():ROI 边界 clamp、裁剪、缩放、旋转;支持 CPU 软件双线性缩放或者 GPU2D/NemaGFX 硬件加速;ld_post_process():置信度阈值过滤,将原始输出归一化到 ROI 局部坐标系;decode_ld_landmark():将 ROI 局部归一化坐标,结合 ROI 中心、尺寸、旋转角反解到 LCD 屏幕像素;compute_next_roi():如果本帧跟踪有效,基于 21 个关键点,y=-0.1偏移,scale=2.0 缩放,生成下一帧跟踪用 ROI。
关键点:跟踪模式性能优势来自跳过 Palm detector;一旦置信低于 0.25,跟踪失效,强制回到检测模式。
5. STEdgeAI 模型部署流程
工程提供generate‑n6‑model.sh脚本完成 TFLite 模型转换、代码生成、bin 转 hex。
5.1 部署关键步骤
- 输入原始
.tflite模型文件(palm_detector、hand_landmark 两套); - 调用
stedgeai generate命令,读取user_neuralart.json配置文件;‑‑no‑inputs‑allocation:模型输入内存不由 NPU 管理,上层应用自行管理图像缓冲区;‑‑target stm32n6指定硬件目标;- json 配置引用
.mpool内存池文件,定义 AXISRAM、HyperRAM、OctoFlash 内存分区;
- 生成
.c/.h推理代码、模型权重.bin; - 使用
arm‑none‑eabi‑objcopy把 bin 转换为带烧录地址信息 hex 文件(示例地址0x70380000),烧录到外部 XSPI2 Flash。
5.2 配置文件说明
user_neuralart.json:分别配置 palm_detector 与 hand_landmark 两套模型,关联对应的 mpool 内存布局;.mpool内存池文件:定义 NPU RAM、AXIS‑RAM、HyperRAM、OctoFlash 内存大小、偏移地址。如果硬件内存布局修改,必须同步修改 mpool 配置,否则 NPU 运行异常。
6. 工程落地排查清单
- 摄像头图像镜像翻转不对:核对
CAMERA_FLIP宏,摄像头物理安装方向改变,该宏必须同步修改,否则手掌检测识别率暴跌; - 纵横比模式选择错误:手动更换摄像头模组,不要直接沿用默认
CMW_Aspect_ratio_manual_roi,根据摄像头分辨率评估裁剪 / 缩放模式; - NPU 推理直接死机:优先核查
user_neuralart.json和.mpool内存池配置;模型权重 hex 烧录地址是否与配置一致; - 关键点跟踪容易丢失:
- 检查
LD_PROB_THRESHOLD=0.25置信阈值;阈值设置过高容易频繁退回检测模式;阈值过低会出现错误关键点; - ROI 生成参数 shift、scale 参数修改会直接影响跟踪稳定性;
- 检查
- 只运行跟踪模式,完全不触发手掌检测:置信阈值设置过低,跟踪状态一直置位;遮挡手掌确认是否能够退出跟踪模式;
- 坐标绘制关键点错位:ROI 旋转、偏移参数修改后,需要同步检查
decode_ld_landmark()屏幕坐标映射逻辑。
7. 小结
x‑cube‑n6‑ai‑hand‑landmarks是 STM32N6 平台非常有参考价值的端侧 AI 范例,完整演示 CSI 摄像头 + DCMIPP ISP、NPU 双模型级联推理、检测‑跟踪状态机、LCD 可视化整套机器视觉链路,适合手势识别、人机交互类项目二次开发。- 整套系统分为 Palm detector 手掌检测模型(192×192 输入)和 Hand‑landmark 关键点模型(224×224 手掌 ROI 输入);依靠 is_tracking 状态做模式切换,跟踪稳定时跳过手掌检测降低算力消耗。
- DCMIPP 多 Pipe 图像预处理、4 种纵横比处理模式,是移植第三方摄像头的重点;不同模式会改变送入神经网络的图像,直接影响识别效果。
- 模型部署依靠 STEdgeAI 工具链,
user_neuralart.json、.mpool内存池配置是部署关键点,内存布局变更必须同步修改配置文件。 - 21 个关键点输出原始坐标是 ROI 局部归一化坐标,需要经过坐标反解换算才是屏幕像素坐标,很多二次开发在这里出错。
8. FAQ
Q:我只想做手势识别,是否可以直接去掉 Palm detector,只跑 Hand‑landmark?
A:不建议。Hand‑landmark 模型只接受裁剪后的手掌 ROI 图像输入,不能直接输入完整大图;没有 Palm detector 就无法获取手掌 ROI 区域。
Q:跟踪模式是否会永远不运行手掌检测?
A:不会。当关键点置信度低于 0.25 阈值,会判定跟踪丢失,下一轮循环自动切回检测模式重新搜索手掌。
Q:更换别的摄像头模组,只改硬件接线就可以吗?
A:不行,需要同步修改:摄像头驱动、CAMERA_FLIP 镜像翻转宏、DCMIPP 纵横比处理模式。
免责声明:本文全部内容基于 ST 官方 LAT1708 文档,实际项目以 GitHub 官方软件包源码、ST 官方手册为准。
273