# rox_roft **Repository Path**: shenyachuan/rox_roft ## Basic Information - **Project Name**: rox_roft - **Description**: rox_soft仓库 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: feat/face-chain-20261021 - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-10-27 - **Last Updated**: 2026-10-27 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # rox_soft:V851S 双目人脸识别与 LCD 显示程序 > **最新项目主页:[共同开发分支 README](https://gitee.com/shenyachuan/rox_roft/blob/integration/v851s-unified-20261027/README.md)**(2026-10-27 更新) > > 后续开发统一使用 `integration/v851s-unified-20261027`,最新功能、构建、运行路径和验证范围见上方入口。本页所在 `feat/face-chain-20261021` 为历史来源分支;下方保留其原说明,不代表当前共同开发版本或现板部署状态。 活体架构、测试结论和启用/回退入口统一见 [活体方案重构](docs/work/活体方案重构.md)。`diagnostics/ir_liveness/scripts/` 保留可重复运行的诊断验收工具,诊断功能不进入正式生产接口。 **当前源码(2026-10-09):** 正式识别使用 A 原 RGB+IR 双路和 B 独立 RGB 三帧两条通过路径。B 每帧活体 ≥0.70、独立 MobileFaceNet 身份复核,提交时三帧均满足 500 ms;IR 异步调曝光不阻塞 B,最终统一提交。IR 输入仍为 FLIR `112×112 → CLAHE → 三通道 Q15`,RGB 活体仍使用 80×80 BGR 输入;未更换模型或放宽阈值。 A 保留单帧 `min(IR, RGB) >= 0.60` 或三帧均值 `>= 0.50` 的规则。已完成声明范围内的静态回放、软件回归和四项最小真人功能验收;用户已要求默认启用新策略,最终板端版本和发布核验见 [默认开启与回退](docs/work/活体方案重构.md#默认开启与回退)。新开关 `ROX_RGB_INDEPENDENT_PASS_ENABLE=1` 生效时忽略旧恢复预算 `13000`;新开关关闭才恢复旧行为。下方早期设备记录保留历史背景。 ## 1. 项目说明 `rox_soft` 是运行在全志 V851S/V853 系列平台上的人脸识别应用包。当前工程把 RGB/IR 双路摄像头、MPP ISP、VIPLite NPU、人脸检测与识别、活体检测、LCD 实时预览、实体录入按键以及 TX510 串口协议整合在同一个进程中。 编译后的主程序为: ```text /usr/sbin/mobilefacenet_test ``` 本 README 的工程基线说明整理于 2026-09-04(`dfdf98b`);活体概览已按 2026-10-09 工作区更新。现役源码、打包资源和第三方依赖已经按功能分区;历史设备记录不代表当前安装状态。活体维护以最新方案、发布证据和当前源码为准。 ### 1.1 项目目录简介 项目按正式源码、运行资源、第三方依赖、回归测试和正式文档划分: | 目录 | 主要用途 | 是否参与构建/打包 | | --- | --- | --- | | `src/` | 当前程序源码:主流程、人脸识别、采集、显示、活体和串口协议 | 参与编译 | | `vendor/` | OpenCV、VIPLite 头文件及 ARM musl 预编译库 | 参与编译/链接,部分库进入 IPK | | `files/` | NPU 模型、RGB/IR ISP 参数和开机脚本 | 不编译,但进入 IPK | | `tests/` | 正式业务回归测试源码及固定测试样例 | 主机测试使用,不进入固件 | | `docs/` | 正式使用说明、维护规则和经审核的最终总结 | 不参与构建 | | `diagnostics/` | 受版本管理的复现工具,以及本地实验、采样和报告 | 仅 `.gitignore` 白名单工具纳入 Git,不进入正式固件 | 2026-10-17:RGB 白光补光正式接入,详见[RGB补光接入](docs/RGB补光接入.md)。 `src/` 内部按功能继续划分:`app/` 是程序入口和主状态机,`recognition/` 负责人脸检测、识别与录入,`capture/` 负责 RGB/IR 采集,`display/` 负责 LCD/G2D/RGN,`liveness/` 负责活体检测,`protocols/` 包含 TX510 和文本串口协议,`common/` 是公共图像/JPEG 组件,`platform/uart/` 是共享 UART 底层实现。 ## 2. 当前状态 2026-09-28 检测链迁移为 SCRFD DFP16,模型位于 `files/models/detection/scrfd_320x320_dfp16.nb`,固件路径为 `/usr/sbin/scrfd_320x320_dfp16.nb`。输入编码、输出反量化及全部检测入口已统一;先看[新检测模型接到主业务链文档](),详细测试数据见 [SCRFD DFP16 接入与验收]()。 ### 2.1 既有构建与设备记录(非本次部署) | 项目 | 当前结论 | | --- | --- | | SDK 目标 | `v851s_ipc_dual_camera-tina`,对应 `TARGET_BOARD=v851s-ipc_dual_camera` | | 软件包 | `.config` 已启用 `CONFIG_PACKAGE_rox_soft=y` | | 编译 | 2026-09-04 已执行 clean 后全量编译,成功生成 ARM32 musl 可执行文件和 IPK | | 目录整理 | 现役源码、依赖、模型和 ISP 已按功能分区;资源哈希、ELF 依赖及 IPK 文件清单与整理前一致 | | 主程序 | `mobilefacenet_test`,约 2.2 MiB,已 strip | | IPK | `out/v851s-ipc_dual_camera/packages/base/rox_soft_1.0-1_sunxi.ipk`,约 3.9 MiB | | LCD | 源码中默认启用 `/dev/fb0` + `/dev/disp`;G2D 硬件直出默认启用 | | 摄像头 | RGB `/dev/video0`,IR `/dev/video1`;均走 MPP ISP | | NPU | SCRFD、MobileFaceNet、MiniFASNet 均通过 VIPLite 运行 | | 启动方式 | `/etc/init.d/S51hlk` 开机启动持久目录中的最新红外多帧聚合程序;已实际重启核对 | | Git 状态 | 以当前仓库分支和提交记录为准 | 本次全量编译只有警告,没有编译错误。现有警告主要是 `main.cpp` 中四处单行 `if` 的缩进提示、全局 `g_lcd` 的 lambda 捕获提示,以及两个已赋值但未使用变量;暂不影响生成程序,但后续可清理。 ### 2.2 仍需在新板上确认 本机只能确认代码和交叉编译,不能据此代替真实硬件测试。新板已经烧录的固件版本也不一定与当前 SDK 的 `dfdf98b` 完全一致。以下项目应作为第一轮上板测试重点: - LCD 分辨率、画面方向、是否镜像、是否有撕裂或黑边。 - RGB/IR 两路 sensor 与 `/dev/video0`、`/dev/video1` 的实际对应关系。 - 新板的 RGB/IR ISP 参数是否与 `files/` 中 GC1084 配置匹配。 - RGB/IR 各自原生检测与同帧配对;当前 IR 裁剪不使用 RGB 坐标映射。 - PH13 是否确实接录入按键,PH14 是否确实接红外补光灯,且高低电平逻辑一致。 - `/dev/ttyS0`、`/dev/ttyS2` 是否与板上 TX510 主口/蓝牙透传口接线一致,两个串口不能配到同一设备。 - `/mnt/UDISK` 是否可写、空间是否足够,掉电后人脸库是否能正常保存和恢复。 - 识别阈值、活体阈值、最小人脸尺寸是否适合新摄像头和新屏幕视场。 - 开机自启动时 NPU、ISP、LCD 和文件系统的稳定性。 ## 3. 已实现功能 ### 3.1 摄像头与图像采集 - RGB 主摄像头默认使用 `/dev/video0`、ISP 0、VIPP 0,加载 `/usr/sbin/color/` 下的 ISP 参数。 - IR 摄像头默认使用 `/dev/video1`、ISP 1、VIPP 1,加载 `/usr/sbin/ir/` 下的 ISP 参数。 - 默认请求 `480x640 @ 30 fps`;RGB 启动失败会回退到 `640x480`,IR 也有相应回退。 - VI 输出格式为 NV12,识别路径转换为 BGR;采集在独立线程中运行,主循环消费最新帧。 - IR 平时按需采集:进行活体判断时打开,空闲时停止取帧;IR 预览或活体测试模式下可常开。 - 支持摄像头画面 0/90/180/270 度方向补偿。 ### 3.2 人脸检测、识别与录入 - SCRFD INT16 DFP 模型执行 320x320 人脸检测,并输出人脸框和 5 个关键点。 - 使用 ArcFace 标准 5 点模板把人脸对齐到 112x112。 - MobileFaceNet 输出 512 维 L2 归一化特征。 - 人脸质量模块检查尺寸、关键点、清晰度和稳定性等条件。 - 识别使用 V3 多帧证据决策,不只依赖单帧相似度;包含确认、陌生人、身份保持和身份切换逻辑。 - 录入使用多帧候选采集、质量筛选、融合模板、代表模板和两级重复检查。 - 人脸靠近图像边缘或落到 LCD 实际可见裁剪区外时,可阻止识别,避免“屏幕只看到半张脸但后台仍识别”。 - 正式模式的主流程为:匹配 -> 活体 -> 显示结果 -> 清状态重新识别。 人脸数据保存在: | 文件/目录 | 用途 | | --- | --- | | `/mnt/UDISK/face/face_db.bin` | FDB3 多模板人脸特征库(每用户带 1 字节来源),只认 FDB3 | | `/mnt/UDISK/face/face_desc.bin` | TX510 用户描述符 | | `/mnt/UDISK/face/tx510_cfg.bin` | TX510 波特率和自动检测配置 | | `/mnt/UDISK/png/personN.jpg` | 录入成功时保存的最佳人脸 JPG | 注意:删除某个用户时当前实现按 `vector` 下标删除,后面的用户 ID 会前移。上位机如果长期保存 ID,需要把这一行为纳入测试。 ### 3.3 活体检测与红外补光 - FLIR IR 和 RGB MiniFASNet 双分支活体检测;IR 输入按官方裁剪生成 112×112,RGB 保持 80×80。 - RGB/IR 两路模型通过阈值均为 0.50,主循环支持多帧活体窗口融合。 - 启用分支的模型或相机故障会阻止业务放行。受控 RGB-only 只在正式恢复条件完整满足时进入,不能绕过设备故障。 - PH14 用作 IR 补光控制,低电平点亮;只在活体评估期间开启,空闲自动关闭。 - 提供“纯 IR 活体测试预览”模式,便于单独检查 IR 图像、SCRFD 检测框和活体分数。 ### 3.4 LCD 显示 - LCD 默认开启,设备节点为 `/dev/fb0` 和 `/dev/disp`。 - 默认使用 `/dev/g2d` 把 VI 的 NV12 物理帧旋转、缩放后直写 framebuffer,降低 CPU 占用。 - framebuffer 支持双缓冲和 DE shadow/vsync 翻页,用于减少撕裂。 - SCRFD 检测输入的 320x320 缩放也默认尝试使用 G2D,失败时回退软件缩放。 - 人脸框优先使用 RGN ORL 硬件 OSD;不可用或关闭时回退 CPU 绘制。 - 正式模式默认开启:画检测框,并在左上角固定结果条显示识别、陌生人、活体失败和录入结果。 - 中文点阵字库已经集成;总文字开关 `ROX_TEXT` 默认关闭,但正式模式的结果条不受该总开关限制。 - 支持 TX510 控制显示开关、字符串显示、JPG 显示和识别结果显示。 ### 3.5 本机按键与 GPIO | 输入/输出 | 功能 | | --- | --- | | 键盘 `q` | 退出程序 | | 键盘 `r` | 开始一次多帧录入 | | 键盘 `c` | 取消当前录入 | | PH13 短按 | 实体录入按键,低电平按下,带简单去抖;**释放时**触发一次多帧录入 | | PH13 长按 ≥5s | 删除全部人脸数据(`face_db.bin` + `face_desc.bin`),屏幕显示"已成功" | | PH14 | 红外补光灯,低电平点亮 | | PE2 / GPIO130 | RGB 白光补光灯,高电平点亮;正式自动补光默认启用 | GPIO 当前通过 `/sys/class/sunxi_dump` 直接读写寄存器,属于强板级绑定代码。更换引脚或内核接口时,应优先检查 `main.cpp` 中 `enroll_key_*` 和 `ir_led_*` 代码。 ### 3.6 串口与上位机接口 工程中同时存在两套串口接口(外加 TX510 的第二路蓝牙透传口): | 接口 | 默认设备 | 当前作用 | | --- | --- | --- | | TX510 | `/dev/ttyS0` | Slave 模式;实现手册第五章的业务指令与厂商扩展(分发共 23 条分支,含 `0xEC` 用户列表),覆盖识别、注册、用户管理、特征读写、显示、配置、自检等 | | TX510 第二口 | `/dev/ttyS2` | 蓝牙透传;与主口共用一套协议状态机,回包只回来源口,`off`/`none` 关闭 | | 简单文本串口 | 默认不启用 | 可输出 `RECOG/UNKNOWN` 文本结果,并接收 `LIST/INFO/THRESH` 命令 | 关键说明: - TX510 初始化失败不会终止主识别程序,只会关闭协议能力。 - TX510 的识别和录入通过共享桥交给主循环,避免多个线程同时提交 VIPLite NPU 命令。 - TX510 支持双串口(`ROX_TX510_TTY` 主口 + `ROX_TX510_TTY_B` 蓝牙透传口):两个口各自独立收发,命令回包**只回来源口**,事件上报(`0xD2`)按 `ROX_TX510_EVENT_BOTH` 决定是否两口都发。 - TX510 的白光灯 `0xC2` 已接入 PE2/GPIO130 主循环请求桥,执行确认后回复;人工覆盖 10 秒,正式自动补光默认启用。 - 简单文本串口能解析 `CLEAR`,但主循环目前没有执行 `CMD_CLEAR_DB` 的分支,所以该命令实际上不会清库。 - 不要把 `ROX_TX510_TTY`、`ROX_TX510_TTY_B` 或 `ROX_TEXT_SERIAL` 配成同一个串口节点,否则会发生双开抢数据。 - **TX510 用户 ID 在册期间稳定**:删除用户只把该槽位置空(库文件里编码为 `tcnt=0`),其它用户的 ID 永不搬移;空槽会被新用户**复用**(取最小空闲槽),因此 16 位 ID 的上限是同时在册人数峰值而非历史注册次数,**已删除的 ID 可能重新分配给新人**——客户端不得缓存 ID→姓名,须每次重取 `0xEC`。`0xC4` 的应答是 `count(2,大端) + count×user_id(2,大端)`,ID 可能不连续,客户端必须按 ID 建索引;对已删除的 ID 执行 `0xCE/0xCF/0x20` 一律回 `Result=0x01`;空槽不参与识别匹配。**回退旧固件前必须先清库或重新录入**,否则旧固件会把含空槽的库判为坏库并拒绝启动。 - **TX510 `0x13` 注册支持携带姓名**(厂商扩展):`Size==0` 保持手册原行为;`Size=1..32` 表示 UTF-8 姓名,由固件与特征一次性提交(要么都成功、要么都失败);`Size>32` 直接失败。成功应答仍是手册形状(`Size=4`,只含 `user_id`);失败应答为 `Size=6+text_len`:`detail(1) | duplicate_id(2,大端, 0xFFFF=无) | text_len(1) | text(UTF-8 中文原因, ≤48 B)`,`detail` 码表见 `src/recognition/enrollment_outcome.h`。小程序也可以走 `0xC5` + `0xCE` 两条指令达到同样效果。 - 本树不包含 `src/protocols/fm223/`,`src/Makefile` 也不编译它;`tests/` 不在本仓库内,引用 FM223 源码的旧测试需在 vendor 树内运行。 ## 4. 软件结构 ```text rox_soft/ ├── Makefile Tina/OpenWrt 软件包定义、安装清单 ├── README.md 本文档 ├── src/ │ ├── Makefile 应用交叉编译规则 │ ├── app/ 程序入口、状态机、数据库和模块编排 │ ├── recognition/ 检测、对齐、质量、识别决策和录入 │ ├── capture/ RGB/IR 采集线程及 MPP VI/ISP 封装 │ ├── display/ fb0、G2D、RGN 和中英文字体 │ ├── liveness/ FLIR + RGB MiniFASNet 活体引擎 │ ├── protocols/ │ │ ├── tx510/ TX510 协议栈、配置和接口 │ │ └── text_serial/ 简单文本串口 │ ├── common/ 图像结构和 JPEG 编解码 │ └── platform/uart/ TX510 共享 UART 实现 ├── vendor/ │ ├── opencv-4.1/include/ 当前 ABI 使用的 OpenCV 4.1 头文件 │ ├── viplite/include/ VIPLite 头文件 │ └── arm-musl/lib/ 当前编译、链接和随包安装的 ARM 库 ├── files/ │ ├── init/S51hlk 开机服务脚本 │ ├── models/ 当前打包的检测、识别及活体模型 │ └── isp/{rgb,ir}/ 当前 RGB/IR ISP 参数 ├── tests/ 正式回归测试与固定样例 └── docs/ 正式文档与 Git 管理规则 ``` 根 `Makefile`、`src/`、`vendor/` 和 `files/` 是正式构建输入。`tests/` 用于主机回归,`docs/` 保存正式文档,两者不进入固件。`diagnostics/`、`datasets/` 和历史备份仅在本地使用。 主数据流如下: ```text RGB sensor -> MPP VI/ISP -> NV12 -> G2D LCD 直出 | +-> BGR -> SCRFD -> 质量/可见性检查 | +-> 5点对齐 -> MobileFaceNet -> 多帧识别/录入 IR sensor -> MPP VI/ISP -> 原生检测 -> FLIR112/CLAHE/Q15 --+ RGB 人脸 ROI --------------------------> MiniFASNet RGB -+-> A 双路融合 --+ | | +-> 每帧身份复核 | -> B 三帧 --+-> 统一提交 IR 曝光:采集线程异步设置/读回 -> 稳定等待 -> A 获取新 IR;等待不阻塞 B 键盘/PH13/TX510 -> 主循环录入或识别状态机 -> LCD/串口/人脸库 ``` ## 5. 编译方法 历史完整工程应放在 SDK 的 `rox_soft_archives/` 等 `package/` 之外的位置。SDK 会递归扫描包级 Makefile;把同名工程备份留在 `package/` 或本工程 `.build/` 内,会覆盖正式软件包的构建入口。 建议始终从 SDK 根目录编译软件包,不要直接在 `src/` 中裸跑 `make`。顶层构建会正确设置交叉编译器、staging sysroot 和 MPP 路径。 ```sh cd /home/rose/V851S_SDK/V85X_SDK_v1.3 source build/envsetup.sh lunch v851s_ipc_dual_camera-tina make package/rox_soft/compile V=s -j4 ``` 强制从干净的 `rox_soft` 构建目录重新编译: ```sh cd /home/rose/V851S_SDK/V85X_SDK_v1.3 source build/envsetup.sh lunch v851s_ipc_dual_camera-tina make package/rox_soft/clean make package/rox_soft/compile V=s -j4 ``` 如果没有先执行 `source build/envsetup.sh` 和 `lunch`,顶层 `make` 会因为 `TARGET_BOARD` 为空而寻找 `target/allwinner//BoardConfig.mk`,随后失败。 主要输出: ```text out/v851s-ipc_dual_camera/compile_dir/target/rox_soft/src/mobilefacenet_test out/v851s-ipc_dual_camera/packages/base/rox_soft_1.0-1_sunxi.ipk out/v851s-ipc_dual_camera/staging_dir/target/rootfs/usr/sbin/mobilefacenet_test ``` 如需生成完整固件,完成 lunch 后从 SDK 根目录执行项目既有的整包构建流程;在不了解当前产品打包约定时,不要只根据本软件包 README 直接覆盖生产镜像。 ## 6. 固件内安装内容 `package/rox_soft/Makefile` 会安装: - `/usr/sbin/mobilefacenet_test` - `/usr/sbin/scrfd_320x320_dfp16.nb` - `/usr/sbin/mobilefacenet.nb` - `/usr/sbin/flir_v851s.nb` - `/usr/sbin/rgb_minifasnetv2_dfp16_v851s.nb` - `/usr/sbin/color/` 下的 RGB ISP 参数 - `/usr/sbin/ir/` 下的 IR ISP 参数 - `/usr/lib/libVIPlite.so`、`libVIPuser.so`、`libjpeg.so.9`、`libz.so.1` - `/etc/init.d/S51hlk` OpenCV core 等部分库没有由本包重复安装,默认依赖 SDK 根文件系统中已有的对应库。 ## 7. 板端启动与调试 ### 7.1 开机服务 ```sh /etc/init.d/S51hlk start /etc/init.d/S51hlk stop /etc/init.d/S51hlk restart ``` 脚本使用 `start-stop-daemon` 后台启动,并把 PID 写到 `/var/run/hlk.pid`。当前脚本的 IR 预览测试环境变量默认都被注释,因此正常开机进入完整人脸识别模式。 ### 7.2 前台运行 调试时建议先停服务,避免两个实例抢占 NPU、摄像头、LCD 和串口: ```sh /etc/init.d/S51hlk stop cd /usr/sbin ./mobilefacenet_test ``` 程序当前不解析命令行参数,配置全部通过环境变量完成;旧脚本中的 `./mobilefacenet_test 0` 与不带参数效果相同。 ### 7.3 常用运行示例 正常全功能模式: ```sh ROX_DEBUG=1 /usr/sbin/mobilefacenet_test ``` 只看 RGB LCD 预览,不跑识别: ```sh ROX_PREVIEW_ONLY=1 /usr/sbin/mobilefacenet_test ``` 诊断构建中,只看 IR 画面并运行 FLIR 活体测试(每帧必须有原生检测框): ```sh ROX_PREVIEW_ONLY=1 \ ROX_LCD_IR=1 \ ROX_LIVENESS_TEST=1 \ /usr/sbin/mobilefacenet_test ``` 如果只想检查 IR 画面、不跑 SCRFD: ```sh ROX_PREVIEW_ONLY=1 \ ROX_LCD_IR=1 \ /usr/sbin/mobilefacenet_test ``` 回退到 CPU 显示/缩放路径进行对比: ```sh ROX_G2D=0 ROX_DET_G2D=0 ROX_RGN_OSD=0 /usr/sbin/mobilefacenet_test ``` ## 8. 主要环境变量 ### 8.1 摄像头、LCD 和显示 | 环境变量 | 默认值 | 说明 | | --- | --- | --- | | `ROX_VI_W` / `ROX_VI_H` | `480` / `640` | RGB/IR 请求分辨率 | | `ROX_VI_FPS` | `30` | VI 请求帧率,合法范围 1~120 | | `ROX_IR_DEVICE` | `/dev/video1` | IR 摄像头设备 | | `ROX_CAM_ROTATE` | `0` | 摄像头方向补偿:0/90/180/270 | | `ROX_LCD_PREVIEW` | 开 | 设为 `0` 才关闭 LCD | | `ROX_LCD_FB` | `/dev/fb0` | framebuffer 节点 | | `ROX_LCD_DISP` | `/dev/disp` | Display Engine 节点 | | `ROX_LCD_ROTATE` | `0` | LCD 软件路径旋转角度 | | `ROX_LCD_IR` | `0` | `1` 时 LCD 显示 IR,否则显示 RGB | | `ROX_LCD_BOX_SYNC` | `1` | RGB 检测帧与该帧 bbox 绑定后异步上屏 | | `ROX_G2D` | 开 | `0` 回退 CPU LCD 通路 | | `ROX_DET_G2D` | 开 | `0` 关闭检测输入的 G2D 缩放 | | `ROX_RGN_OSD` | 开 | `0` 关闭硬件人脸框 | | `ROX_FORMAL` | 开 | `0` 关闭正式显示状态机 | | `ROX_TEXT` | 关 | `1` 开启普通 overlay/banner 文字 | | `ROX_PREVIEW_ONLY` | 未设置 | 只要该变量存在即进入纯预览,`ROX_PREVIEW_ONLY=0` 也会生效 | | `ROX_LCD_PROFILE` | `0` | `1` 输出 LCD 性能日志 | ### 8.2 识别、录入和活体 | 环境变量 | 默认值 | 说明 | | --- | --- | --- | | `ROX_DET_THRESH` | `0.38` | SCRFD 检测阈值 | | `ROX_RECOG_THRESH` | `0.70`(程序默认);量产脚本 `0.65` | 人脸余弦匹配阈值 | | `ROX_MIN_FACE` | `96` | 识别最小人脸短边 | | `ROX_ENROLL_MIN_FACE` | `96` | 录入粗筛最小人脸短边 | | `ROX_ENROLL_MIN_FACE_W/H` | `105` / `125` | 录入最小人脸宽高 | | `ROX_ENROLL_BORDERLINE_W` | `130` | 临界小脸二次门控宽度 | | `ROX_MIN_FRAME_QUALITY` | `62` | 最低帧质量 | | `ROX_CONFIRM_EVIDENCE` | `2.15` | 多帧确认所需证据 | | `ROX_STRANGER_SCORE` | `0.56` | 陌生人分数阈值 | | `ROX_DET_INTERVAL` | LCD 时 `1`,无 LCD 时 `3` | 每隔多少主循环帧重新检测;同步活体阶段强制逐帧检测 | | `ROX_FEAT_INTERVAL` | `3` | 每隔多少帧提取特征 | | `ROX_FACE_EDGE_MARGIN` | `8` | 人脸框距离图像边缘的最小像素 | | `ROX_LCD_CROP_L/T/R/B` | `0` | LCD 相对源图各边裁剪比例,范围 0~0.45 | | `ROX_LIVENESS` | 开 | 仅诊断构建可用 `0` 关闭;生产构建始终保留活体 | | `ROX_LIV_WINDOW` | `3` | 活体融合窗口帧数 | | `ROX_LIV_THRESH` | `0.70`(程序默认);量产脚本 `0.50` | A 双路三帧融合均值阈值;模型融合层 RGB/IR 单路通过阈值为 `0.50`,B 独立三帧要求每帧 RGB ≥`0.70` | | `ROX_LIV_IR_FAST` | `0` | `1` 开启 IR 快速通过策略 | | `ROX_LIV_IR_FAST_THRESH` | `0.85` | IR 快速通过阈值 | | `ROX_RGB_IR_MAX_DELTA_MS` | `40` | RGB/IR 采集时间戳配对硬门限 | | `ROX_SYNC_FRAME_MAX_AGE_MS` | `300` | 摄像头停滞看门狗,仅允许 200–300 ms,不用于同步判定 | | `ROX_LIVENESS_IR_BACKEND` | `flir` | 唯一有效 IR 后端;旧 legacy/shadow 值拒绝启动模型 | | `ROX_FLIR_CLAHE` | `1` | 正式 112 输入增强;0 仅作明确对照 | | `ROX_RGB_INDEPENDENT_PASS_ENABLE` | 缺失时关闭;量产脚本 `1` | 仅精确 `1` 开启正式 A/B 双路径;其他值回到旧策略 | | `ROX_IR_RECOVERY_BUDGET_MS` | `0`(程序默认);量产脚本 `13000` | 旧恢复/降级预算,有效范围 3000–30000 ms;新开关为 `1` 时忽略,仅回退旧策略时生效,见[启用与回退](docs/work/活体方案重构.md#默认开启与回退) | | `ROX_ENROLL_MIN_SHOW_MS` | `3000` | LCD“录入中”最短显示时间 | | `ROX_EARLY_FINISH_PREVIEW` | 开 | `0` 关闭录入提前完成预览策略 | | `ROX_VERIFY_LEGACY` | `0` | `1` 让独立识别 API 回退为单帧匹配 | | `ROX_ENROLL_LEGACY` | `0` | `1` 让独立录入 API 回退为旧版连续稳定单帧流程 | | `ROX_DEBUG` | `0` | `1` 输出详细算法和录入日志 | | `ROX_SCRFD_PROFILE` | `0` | `1` 输出 RGB 检测性能日志 | 活体模型路径可通过 `ROX_LIVENESS_FLIR_MODEL` 和 `ROX_LIVENESS_RGB_MODEL` 覆盖;FLIR 文件仍须通过固定哈希及张量契约校验。旧 IR 模型路径、crop scale、检测框缓存和映射偏移参数已退役。 ### 8.3 串口 | 环境变量 | 默认值 | 说明 | | --- | --- | --- | | `ROX_TX510_TTY` | `/dev/ttyS0` | TX510 主串口(`off`/`none` 可关闭) | | `ROX_TX510_TTY_B` | `/dev/ttyS2` | TX510 第二串口(蓝牙透传;`off`/`none` 关闭) | | `ROX_TX510_BAUD_B` | `115200` | TX510 第二串口波特率(十进制速率);独立于主口,值变化时固化进配置 | | `ROX_TX510_EVENT_BOTH` | `0` | `1` 事件上报(`0xD2`)同时发两个口 | | `ROX_TEXT_SERIAL` | 未设置 | 简单文本串口;设置后启用 | | `ROX_QUIET_MAINLOOP` | `0` | `1` 压低主循环预览日志 | | `ROX_RGB_FILL_MODE` | `auto` | `off` 关闭自动补光;`auto` 让正式识别/录入链按需补光,`manual` 只走上位机 `0xC2` | | `ROX_TX510_AUTO_VERIFY` | 开 | `0` 关闭 TX510 上电自动识别 | | `ROX_TX510_DEBUG` | 关 | 设置后输出 TX510 协议调试日志 | | `ROX_TX510_VERIFY_ARM_MS` | `1000` | 0x12 触发后的证据等待窗口,允许 300~10000 ms | | `ROX_TX510_VERIFY_TIMEOUT_MS` | `10000` | 0x12 最终超时(与其它正式入口的 10 s 窗口一致,5 s 会先耗尽采集侧的 2.5 s 证据余量),允许 500~60000 ms | ## 9. 建议的新板测试顺序 每完成一步再进入下一步,出现问题时更容易定位到硬件、驱动、显示、算法或协议层。 1. 确认固件版本和程序:检查 `/usr/sbin/mobilefacenet_test`、四个 `.nb` 模型、RGB/IR ISP 目录是否存在。 2. 停止开机服务,使用前台纯 RGB 预览启动,观察 LCD 分辨率、方向、镜像、颜色、帧率和稳定性。 3. 切换 IR 预览,确认 `/dev/video1`、IR ISP 和 PH14 补光。 4. 开启 IR 活体测试,分别用真人、手机照片/屏幕测试 PASS/REJECT。 5. 清理测试库后,用键盘 `r` 和 PH13 各录入一次,重启程序确认人脸库持久化。 6. 测试已录入人员、陌生人、戴眼镜、侧脸、远近距离、半脸越界和多人场景。 7. 测试 TX510 主口与第二口;每次只接入一套上位机,核对端口与波特率。 8. 最后恢复 `S51hlk` 自启动,连续重启和长时间运行,观察 NPU/ISP 错误、内存和文件系统日志。 建议记录每项的:固件/提交号、环境变量、测试距离、光照、是否通过、日志和照片。后续调阈值时不要只保留“感觉变好”,应能回归同一组样本。 ### 9.1 常用检查命令 ```sh ps | grep mobilefacenet_test cat /var/run/hlk.pid ls -l /dev/video0 /dev/video1 /dev/fb0 /dev/disp /dev/g2d /dev/ttyS0 /dev/ttyS1 ls -lh /usr/sbin/*.nb /usr/sbin/color /usr/sbin/ir ls -lh /mnt/UDISK/face /mnt/UDISK/png dmesg | tail -n 100 ``` 如果程序后台运行,可结合系统实际日志方案使用 `logread`、串口控制台或重定向文件;`main.cpp` 已把非终端 stdout/stderr 设置为行缓冲,便于实时 `tail -f`。 ## 10. 已知问题与风险 1. **新板尚未由本次整理进行上板复验。** 代码编译成功不代表传感器、LCD、GPIO 和串口接线完全匹配。 2. **串口实机覆盖有限。** TX510 主口与第二口已通过主机伪终端传输与业务回包回归,外部 UART 电气、驱动和上位机端到端测试本轮未执行。 3. **简单串口 CLEAR 未落地。** 能解析命令,但主循环没有对应清库分支。 4. **TX510 白光灯依赖板级 GPIO 与驱动。** `0xC2` 已真实驱动 PE2/GPIO130(10 秒人工覆盖),但需要 `files/init/rox_rgb_fill_gpio` 与内核 gpio 导出可用,否则只回失败。 6. **已删除的用户 ID 可能被新用户复用。** ID 在册期间稳定,但空槽会被新用户按最小空闲槽复用,客户端不得缓存 ID→姓名。 7. **部分历史脚本已过时。** `legacy/scripts/push_to_board.sh` 默认寻找不存在的旧 `src/models/`;优先使用固件/IPK 部署。模型路径不再写死:`/data/rox/models` 优先,缺失回落 `/usr/sbin`。 8. **板级寄存器强绑定。** PH13/PH14 通过 `sunxi_dump` 操作,换板或换引脚必须重新核对寄存器。 9. **旧项目曾出现 JFFS2 GC 与 NPU/IOMMU 相关内核崩溃。** `docs/history/日报_20260611.md` 记录了历史现象;新 SDK/新固件是否仍存在,需要用录入写盘、重复重启和长稳测试验证。 10. **LCD/G2D/RGN 存在硬件依赖。** 初始化失败会尽量降级继续识别,但画面性能和标注能力可能变化。 11. **源代码存在少量编译警告和重复/遗留代码。** 当前不阻断构建,修改主状态机前应先建立回归测试。 ## 11. 修改建议 - 改功能前先保存一份板端可工作的固件、程序、模型、ISP 文件及人脸库格式样本。 - 每次修改尽量只动一个层次:采集、显示、算法、活体或协议,避免故障难以归因。 - 修改默认环境变量时同步更新 `files/init/S51hlk` 和本 README。 - 修改模型时同时记录模型文件哈希、输入尺寸、量化格式和阈值,不要只替换同名 `.nb`。 - 修改 FaceDB 结构时必须同步升级 magic 与格式文档:固件只认当前 magic(其它一律按坏库拒绝启动、不做旧格式兼容读),现场有存量库时须先导出或清库再升级。 - NPU 推理应继续保持主循环串行提交;新增协议线程时不要直接调用 NPU。 - 提交前至少执行一次 `package/rox_soft/clean` 后单包编译,并在板上完成启动、预览、录入、识别、活体、退出六项冒烟测试。 ## 12. 历史资料 历史资料已移出当前 Git 跟踪范围,可通过 Git 历史或工程外 `../rox_soft_backups/` 备份查阅。但这些文档对应不同开发阶段,阅读时要核对日期和当前代码,尤其注意以下变化: - LCD 现在默认开启,不再是“必须 `ROX_LCD_PREVIEW=1` 才开启”。 - 默认 VI 已从过去的 640x360/640x480 演进为 480x640,并保留 640x480 回退。 - 当前已加入 IR 双路活体、G2D、双缓冲、RGN、正式显示模式、PH13/PH14 和 TX510。 - 历史文档中的行号随主程序扩展已经变化,定位代码应使用函数名或 `rg` 搜索。 ## 13. Git bundle 交接 交付包通过 `git bundle create rox_soft.bundle --all` 生成,包含所有分支、标签和提交历史,以及当前正式源码、模型、第三方库、回归测试及白名单诊断工具;不包含 Tina SDK、交叉工具链、本地 `.build/` 证据或板端人脸库。构建依赖本项目对应的 V85X SDK v1.3 和 Linux 主机工具。 接收方可在空目录的上级执行(把文件名替换为实际收到的包): ```sh git clone -b delivery-20260914 /path/to/rox_soft.bundle rox_soft cd rox_soft git log -1 --oneline make -C src test ``` 主机回归依赖 `make`、`g++`、Python 3,以及 `libopencv_core.so.4.2`(见 `src/Makefile` 的 `HOST_OPENCV_LIBS`)。在已有 SDK 环境中独立构建正式程序可使用: ```sh make -C src V851S_WS=/path/to/V85X_SDK_v1.3 ``` 输出为 `.build/production/mobilefacenet_test`;完整软件包编译见第 5 节。固件使用 `files/init/S51hlk`,持久部署模板 `S51hlk_ir_multiframe_latest` 含设备专用路径和程序校验值,新板须按自身资源布局适配。已部署版本、验证范围及回退记录见 [活体方案重构](docs/work/活体方案重构.md#默认开启与回退)。