iOS 16下VNDetectFaceRectanglesRequest人脸追踪异常求助
问题描述
本人确认该问题仅在iOS 16中出现,iOS旧版本无此现象。我的应用使用Apple Vision Framework追踪相机输入中的人脸矩形,并在相机画面上用视图覆盖层标记人脸。
正常行为
- 相机画面显示在屏幕上
- 持续检测相机输入帧中的人脸
- 识别人脸后用圆形视图覆盖,并持续追踪同一人脸,不会重复绘制圆形
异常行为
- 相机画面正常显示
- 人脸检测流程正常
- 初始人脸追踪正常,但将人脸移至画面边缘后,应用无法识别为同一人脸,持续将其判定为新出现的人脸,导致圆形覆盖层持续抖动,最终触发错误:
Exceeded maximum allowed number of Trackers for a tracker type: VNObjectTrackerRevision2Type
另外,更新Xcode后收到提示:
Thread Performance Checker: -[AVCaptureSession startRunning] should be called from background thread. Calling it on the main thread can lead to UI unresponsiveness
我已将相关方法移至后台线程,但问题反而加剧。
请问iOS 16的哪些变更会导致该问题?更可能是线程、相机输入、Vision框架还是其他问题?该如何排查此问题?(我已花2天日志排查人脸追踪,未发现逻辑问题)
分析与解决方案
一、iOS 16相关变更点
- Vision框架追踪逻辑调整:iOS 16对
VNObjectTracker的边界处理逻辑做了优化,当追踪目标移出画面边缘一定范围后,旧版本会维持追踪状态,新版本则直接判定追踪丢失,触发重新检测。这会导致代码不断创建新追踪器,最终达到上限报错。 - AVCaptureSession线程约束强化:iOS 16对相机会话的线程要求更严格,虽Xcode提示移至后台线程,但如果后台队列配置不当(比如用串行队列而非专用并发队列、队列优先级设置错误),会导致相机帧传递延迟,干扰Vision追踪的连续性。
二、问题定位
核心问题是Vision框架的追踪逻辑变更,线程问题为次要诱因。因为核心错误是追踪器数量超限,本质是人脸被反复判定为新目标;线程调整后问题加剧,说明线程配置错误进一步打乱了帧处理时序,让Vision更难关联前后帧的人脸。
三、排查与修复步骤
- 限制并清理追踪器
- 创建新
VNObjectTracker前,检查当前活跃追踪器数量,达到上限时主动销毁最早或已丢失的追踪器。 - 监听
VNRequest的追踪状态,当返回VNStatus.trackingFailed或tracked状态变为false时,立即移除对应追踪器并释放资源。
- 创建新
- 优化人脸关联逻辑
- 自定义边界过滤规则:当人脸矩形超出画面范围的比例低于阈值(比如20%)时,仍视为同一目标,不触发重新检测。
- 优先使用
VNFaceObservation的trackingID关联前后帧人脸,不要仅依赖矩形位置判断是否为新目标。
- 修正AVCaptureSession线程配置
- 创建专用的串行后台队列管理相机会话的启动和帧处理,避免和其他后台任务抢占资源。示例代码:
let captureQueue = DispatchQueue(label: "com.yourapp.captureQueue", qos: .userInitiated) captureQueue.async { self.captureSession.startRunning() } - 确保Vision请求处理也在同一个后台队列执行,避免跨线程传递帧数据导致的时序混乱。
- 创建专用的串行后台队列管理相机会话的启动和帧处理,避免和其他后台任务抢占资源。示例代码:
- 升级Vision追踪器版本
- iOS 16推荐使用
VNObjectTracker.init(revision:)指定VNObjectTrackerRevision3Type,而非旧的VNObjectTrackerRevision2Type,新版追踪器的边界追踪稳定性更好。
- iOS 16推荐使用
内容的提问来源于stack exchange,提问作者deltakroneker
相关产品推荐
相关产品推荐

