Swift ARKit 如何稳定追踪移动猫/狗以实现呼吸频率检测
猫狗呼吸频率检测AR应用开发问题
实现思路
计划开发一款可识别猫、狗并测量其每分钟呼吸次数的应用,核心实现逻辑:
- 每100毫秒从宠物躯体区域采集100个点位的颜色值
- 通过*Fourier Transform(傅里叶变换)*基于颜色的周期性变化计算宠物呼吸频率
当前问题
目前使用Vision库可通过相机快照检测猫、狗目标,但存在几个核心问题:
- 担忧每100毫秒执行检测时,
ARAnchor会被放置到错误位置,导致无法持续采集宠物区域的固定100个采样点 - 现有代码运行后,渲染生成的sphereNode被绘制在分散的不同位置,并未落在猫的目标区域(腹部或头部)
- 苹果官方提供了人体、面部追踪的配套能力,可通过
ARFaceAnchor、ARBodyAnchor实现对应目标的稳定追踪,希望找到适用于猫的同类锚点追踪能力,确认「稳定追踪猫目标、持续获取锚点范围内固定采样点」的需求是否具备实现可行性
现有实现代码
import SceneKit import ARKit import Vision class ViewController: UIViewController, ARSCNViewDelegate, ARSessionDelegate { var detectionAvailableUntil: Int64 = .zero @IBOutlet var sceneView: ARSCNView! private var viewportSize: CGSize! override func viewDidLoad() { super.viewDidLoad() sceneView.delegate = self viewportSize = sceneView.frame.size } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) resetTracking() } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) sceneView.session.pause() } private func resetTracking() { let configuration = ARWorldTrackingConfiguration() configuration.planeDetection = [] sceneView.session.run(configuration) } lazy var catRequest: VNRecognizeAnimalsRequest = { do { let req = VNRecognizeAnimalsRequest() { [weak self] request, error in self?.processCatDetections(for: request as! VNRecognizeAnimalsRequest, error: error) } return req } catch { fatalError("Fatal error") } }() func processCatDetections(for request: VNRecognizeAnimalsRequest, error: Error?) { guard error == nil else { print("Object detection error: \(error!.localizedDescription)") return } if let result = request.results?.first as? VNRecognizedObjectObservation { let cats = result.labels.filter({$0.identifier == "Cat"}) for _ in cats { guard let currentFrame = self.sceneView.session.currentFrame, result.confidence > 0.3 else { continue } let fromCameraImageToViewTransform = currentFrame.displayTransform(for: .portrait, viewportSize: self.viewportSize) let boundingBox = result.boundingBox let viewNormalizedBoundingBox = boundingBox.applying(fromCameraImageToViewTransform) let t = CGAffineTransform(scaleX: self.viewportSize.width, y: self.viewportSize.height) let viewBoundingBox = viewNormalizedBoundingBox.applying(t) let midPoint = CGPoint(x: viewBoundingBox.midX, y: viewBoundingBox.midY) let results = self.sceneView.hitTest(midPoint, types: .featurePoint) guard let result = results.first else { continue } let anchor = ARAnchor(name: "catAnchor", transform: result.worldTransform) self.sceneView.session.add(anchor: anchor) } } } func renderer(_ renderer: SCNSceneRenderer, willRenderScene scene: SCNScene, atTime time: TimeInterval) { guard let capturedImage = sceneView.session.currentFrame?.capturedImage else { return } let requestHandler = VNImageRequestHandler(cvPixelBuffer: capturedImage) do { try requestHandler.perform([self.catRequest]) } catch { print("Error: Vision request failed") } } func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) { let date = Int64(NSDate().timeIntervalSince1970 * 1000) guard anchor.name == "catAnchor", date > self.detectionAvailableUntil else { return } print("catAnchor added") self.detectionAvailableUntil = Int64(NSDate().timeIntervalSince1970 * 1000 + 500) let sphereNode = SCNNode(geometry: SCNSphere(radius: 0.01)) sphereNode.geometry?.firstMaterial?.diffuse.contents = UIColor.red sphereNode.simdWorldTransform = anchor.transform node.addChildNode(sphereNode) } }
可行性结论
- 苹果原生ARKit没有提供猫、狗等宠物对应的专用追踪锚点,不存在和
ARFaceAnchor、ARBodyAnchor对等的系统级宠物躯体追踪能力,无法直接调用原生API实现猫的稳定3D锚点追踪。 - 你当前代码锚点分散的核心原因:一是每次检测到猫后直接取检测框中点做特征点hitTest,ARKit的特征点是环境稀疏点云,很多时候点落在猫身后的背景上,锚点自然不会落在猫身上;二是每帧检测都新增锚点,没有做锚点和跟踪目标的关联,新旧锚点位置没有连续性,自然会到处分散。
- 你的整体需求完全可以实现,不需要依赖系统提供的宠物专用锚点,优化方案如下:
- 不要每帧跑全量动物检测、不要重复创建
ARAnchor。首次检测到猫目标后,用Vision自带的VNTrackObjectRequest做目标持续跟踪,跟踪稳定性远高于每帧重检,性能开销也更低。 - 采样逻辑不需要绑定3D
ARAnchor,直接在2D摄像头帧的跟踪框内,固定选取胸腹部区域的100个采样点即可。呼吸频率检测只需要颜色的周期性变化,不需要精确3D位置,2D采样的误差更小、实现更简单。 - 如果确实需要3D锚点做位置标注,只需要在首次检测确认猫的位置后创建1个锚点,后续每帧根据跟踪到的目标位置偏移,微调锚点位置即可,不要重复新增锚点。
- 不要每帧跑全量动物检测、不要重复创建
内容的提问来源于stack exchange,提问作者Roman Polanski
相关产品推荐
相关产品推荐

