8.0 KiB
Vision Anti-Pinch
C++ / TensorRT 实时摄像头风险推理,算法来自最新 run_risk.py。 持续取图、推理并更新内存中的 FrameResult;可视化可选。
相机每次取帧默认等待 2000 ms,连续超时 6 次才停止流水线(纯超时约 12 秒);成功取得有效帧后清零超时计数。单次等待时间由 config/camera.json 的 camera.timeout_ms 配置。运行中的坏帧、取流错误共用该重试期限;设备失效时尝试重新打开相机,恢复有效帧后继续推理。GPU 错误仍按原有异常处理退出。
Orin 直接运行
适用环境:Jetson AGX Orin、JetPack 5.1.2 / L4T R35.4.1、CUDA 11.4、TensorRT 8.5.2、OpenCV 4.5.4。 仓库已包含该板端编译的程序和重新构建的 TensorRT 引擎。
git clone https://git.kendeji.fun/zmv/vision-anti-pinch.git
cd vision-anti-pinch/orin
./scripts/initialize_camera.sh # 开机后初始化 /dev/video5 摄像头链路
./run.sh # 持续推理,结果只保存在内存
可选板端本地可视化:
./run.sh --visualize
Ctrl+C / SIGTERM 停止程序。 关闭预览窗口或按 q/Esc 只关闭预览,推理继续。
摄像头为 /dev/video5,1920×1536 UYVY,30 FPS。 当前 door mask 是指定的 constant_door_mask.json 副本,标定状态为 false;装车后应更换与实际画面匹配的门区并更新标定状态。
下游获取结果
main.cpp 注释中也包含以下示例。下游通过自己的调用位置或线程读取:
auto result = pipeline.latest();
if (result) {
const auto& risk = result->risk;
const auto& people = result->persons;
// result->frame_index / track_ids / boxes
// result->image / door_mask_pixels / capture / timing
// people[i].selected / smoothed / temporal:各 133 个关键点
}
latest() 返回 shared_ptr;首帧尚未完成时为空。 公共定义位于 include/camera_pipeline.hpp 和 include/frame_result.hpp。
从源码构建
./scripts/build.sh
./scripts/initialize_camera.sh
./run_camera.sh
源码构建要求 CMake 3.24+、CUDA/NPP、TensorRT 和 OpenCV 开发依赖。 构建脚本会优先使用 Orin 上已有的 ~/miniconda3/envs/yolo/bin/cmake。 源码配置直接使用 orin/engines/ 中的板端引擎。该引擎仅适用于上述 Orin 环境;仓库不包含 ONNX 或模型转换脚本。 独立库目标为 camera_risk_core;可视化在 camera_risk_visualizer。
目录
- src/、include/:采集、推理、结果变量及可选绘制。
- config/:源码构建程序的配置和固定门区。
- scripts/:构建和摄像头初始化脚本。
- orin/:已编译程序、TensorRT 引擎、配置、当前 GMSL 驱动及启动脚本。
- third_party/:nlohmann JSON 及其许可证。
NPP 用于 UYVY 转换、YOLO 缩放填充、RTMW 仿射裁剪;CUDA 用于通道转换与归一化。 风险几何计算仍包含 CPU/OpenCV 操作;算法内部的临时 JSON 对象只在内存中使用。
当前摄像头驱动启动时偶发首帧 ERROR,应用会丢弃并计数;持续错误、采集超时或推理错误会明确报错并退出。 现有 GMSL 驱动停止采集时可产生 videobuf2 缓冲区告警,v4l2-ctl 同样复现;需在驱动侧完成量产修复和验证。
可选保存(默认全部关闭)
三个独立参数可以单独使用,也可以组合:
./run_camera.sh --save-original --save-annotated --save-results
# 独立包:./orin/run.sh --save-original --save-annotated --save-results
开启任一项时,程序自动创建可执行文件所属工程的 output/ 及三个子目录:
original/:--save-original保存未叠加的原图,JPEG 质量 95。annotated/:--save-annotated保存带框、关键点及风险文字的 JPEG,无需开启可视化窗口。results/:--save-results每个完成推理的帧保存一个 JSON,包含帧号、检测框、跟踪 ID、关键点及置信度、风险和耗时;有 CAN 的分支还包含相应状态。
同一帧三类文件同名(扩展名不同),文件名包含运行标识和帧号,多次运行不覆盖。JSON 的 images 提供相对于 output/ 的图片路径,未选择保存的图片为 null。源码入口写入工程 output/;独立包入口写入 orin/output/。默认不创建目录、不保存文件。
保存对象是完成推理的帧;惰性分支暂停时不新增文件。开启保存会增加编码和磁盘 I/O 开销。写入失败时报告错误并停止,不静默丢失文件。
相机超时回归测试:./tests/run_camera_timeout.sh;加 --wall-clock 验证默认 6 次超时约 12 秒。测试直接编译实际相机代码,使用模拟采集和转换器,无需摄像头、GPU 或 OpenCV;不覆盖视频回放路径。
板端真实摄像头 / TensorRT 恢复与停止测试记录见 Orin 测试报告。
推理过程录制与视频回灌
当前 inference-only 分支支持 H.264/MP4 会话;默认关闭,不再为会话逐帧保存图片。
# 录制实际完成推理的帧,Ctrl+C / SIGTERM 正常停止并封装视频
./run_camera.sh --record-session output/sessions/drive-001
# 视频解码后重新运行 YOLO、RTMW、融合与风险推理;文件结束自动退出
./run_camera.sh --replay-session output/sessions/drive-001 --save-results
# 同时保存回灌后的新视频及推理过程,便于对比
./run_camera.sh --replay-session output/sessions/drive-001 \
--record-session output/sessions/drive-001-replay
独立包使用同样参数,例如 ./orin/run.sh --record-session output/sessions/drive-001。
会话路径相对于当前工作目录;录制目录必须尚不存在,避免覆盖原始记录。
会话内容:
frames.mp4:H.264 有损压缩视频,按完成推理的顺序编码,尺寸与原图一致。frames/*.json:对应视频帧序号、原推理帧号、完整采集元数据、检测框、原始/隔离关键点、融合记录、最终结果与耗时。frames.txt:视频帧与 JSON 的顺序索引。session.json、door_mask.json:录制时的推理参数、分辨率、名义帧率、门区副本、模型路径与大小。complete.json:正常停止后写入的帧数与视频大小,用于检查会话是否完成。
回灌不打开摄像头。它恢复会话中的分辨率、检测阈值、人数上限、风险阈值和门区,使用 --config 指定的当前 TensorRT 引擎,按顺序尽快推理,不按墙钟时间限速。视频使用配置的固定名义帧率;真实采集间隔和断流间隔以 JSON 中的纳秒时间戳为准。原始采集时间在再次录制时保存为 source_capture,回灌耗时使用本次运行的单调时钟。
编码使用 OpenCV 的 FFmpeg H.264 编码器;需 OpenCV videoio 与可用的 H.264 编码支持,宽高必须为正偶数。不支持时明确报错。当前使用软件编解码,会增加 CPU、编码延迟和磁盘开销;保存对象是完成推理的帧,并非相机全部原始帧。H.264 有损压缩和不同引擎可能改变检测、关键点与风险结果,不承诺逐位一致。模型只记录来源和大小,不复制引擎,也不保证大小相同即模型相同;精确对比应使用同一组引擎。
Ctrl+C / SIGTERM 会封装已写入的视频,CameraPipeline::join() 返回前完成收尾。强制杀进程、断电或写入失败可能留下 frames.pending.mp4;缺少完成标记的会话拒绝回灌。编码器封装后检查帧数,回灌遇到缺帧、缺失 JSON、损坏索引或解码错误会报错,不静默跳帧。录制没有自动限时或磁盘轮转,请按可用空间控制录制时长。
编解码及会话回归:./tests/run_session.sh,无需摄像头或 TensorRT。真实摄像头与 TensorRT 验证脚本:python3 tests/orin_session_test.py --binary build/camera_risk --config config/camera.json --output /tmp/new-session-test;输出目录必须不存在,脚本不会停止已有部署进程。
本次实机结果与未覆盖范围见 H.264 会话测试报告。