关于VNDetectTrajectoriesRequest来球轨迹获取及衔接问题的技术咨询
关于VNDetectTrajectoriesRequest轨迹衔接问题的解决方案
针对你遇到的轨迹无法衔接问题,核心原因在于VNDetectTrajectoriesRequest生成的轨迹UUID并不保证在连续帧中持续绑定同一个运动物体——当球出现短暂遮挡、检测置信度波动或运动状态变化时,系统可能会生成新的UUID,导致旧轨迹无法关联新的观测结果。结合你的代码,给出以下修复方案:
关键修改点
- 放弃单纯依赖UUID做轨迹匹配,改用空间距离+运动一致性关联帧间轨迹
- 增加轨迹超时机制,避免误删暂时未被检测到的轨迹
- 优化检测点的追加逻辑,确保轨迹点的连续性
修改后的代码
guard let observations = request.results as? [VNTrajectoryObservation] else { return } // 先更新所有已有轨迹的计数器(用于超时清理) for (uuid, property) in trajectoryDictionary { property.count += 1 // 连续5帧未匹配到则删除轨迹 if property.count > 5 { trajectoryDictionary.removeValue(forKey: uuid) } } for observation in observations { /// 适当放宽置信度阈值,避免临时波动导致轨迹断裂 if observation.confidence < 0.7 { continue } let detectedPoints: [CGPoint] = observation.detectedPoints.compactMap { point in CGPoint(x: point.x, y: 1 - point.y) } let projectedPoints: [CGPoint] = observation.projectedPoints.compactMap { point in CGPoint(x: point.x, y: 1 - point.y) } var matchedUUID: UUID? let currentLastPoint = detectedPoints.last! let maxMatchDistance: CGFloat = 0.05 // 可根据画面尺寸调整 // 遍历已有轨迹,寻找空间上连续的匹配项 for (uuid, property) in trajectoryDictionary { guard let existingLastPoint = property.detectedPoints.last else { continue } let distance = hypot(currentLastPoint.x - existingLastPoint.x, currentLastPoint.y - existingLastPoint.y) if distance < maxMatchDistance { matchedUUID = uuid break } } if let uuid = matchedUUID { // 匹配到已有轨迹,追加新的检测点并更新数据 trajectoryDictionary[uuid]!.detectedPoints.append(currentLastPoint) trajectoryDictionary[uuid]!.projectedPoints = projectedPoints trajectoryDictionary[uuid]!.equationCoefficients = observation.equationCoefficients trajectoryDictionary[uuid]!.confidence = observation.confidence trajectoryDictionary[uuid]!.count = 0 // 重置超时计数器 } else { // 无匹配轨迹,创建新条目 trajectoryDictionary[observation.uuid] = TrajectoryProperty( detectedPoints: detectedPoints, projectedPoints: projectedPoints, equationCoefficients: observation.equationCoefficients, confidence: observation.confidence ) } } drawTrajectories(trajectoryDictionary)
额外建议
- 你可以进一步优化匹配逻辑,比如结合
observation.equationCoefficients比较轨迹的运动方向和加速度,提升匹配准确性 - 如果你的场景中球的尺寸固定,可以结合
VNDetectRectanglesRequest先检测球的位置,再辅助轨迹匹配,进一步提升稳定性

内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

