提高VNDetectHumanBodyPoseRequest的body跟踪性能



我正在努力提高VNDetectHumanBodyPoseRequest的身体跟踪绘制骨骼的性能,即使在5米以外的地方,也要使用稳定的iPhone XS相机。

跟踪对我身体的右下肢信心很低,明显滞后,还有抖动。我无法复制今年WWDC演示视频中展示的表现。

以下是相关代码,改编自苹果的示例代码:

class Predictor {
  func extractPoses(_ sampleBuffer: CMSampleBuffer) throws -> [VNRecognizedPointsObservation] {
    let requestHandler = VNImageRequestHandler(cmSampleBuffer: sampleBuffer, orientation: .down)
    
    let request = VNDetectHumanBodyPoseRequest()
    
    do {
      // Perform the body pose-detection request.
      try requestHandler.perform([request])
    } catch {
      print("Unable to perform the request: (error).n")
    }
    
    return (request.results as? [VNRecognizedPointsObservation]) ?? [VNRecognizedPointsObservation]()
  }
}

我已经捕获了视频数据,并在这里处理样本缓冲区:

class CameraViewController: AVCaptureVideoDataOutputSampleBufferDelegate {
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
    let observations = try? predictor.extractPoses(sampleBuffer)
    observations?.forEach { processObservation($0) }
}
func processObservation(_ observation: VNRecognizedPointsObservation) {
    
    // Retrieve all torso points.
    guard let recognizedPoints =
            try? observation.recognizedPoints(forGroupKey: .all) else {
      return
    }
    
    let storedPoints = Dictionary(uniqueKeysWithValues: recognizedPoints.compactMap { (key, point) -> (String, CGPoint)? in
      return (key.rawValue, point.location)
    })
    
    DispatchQueue.main.sync {
      let mappedPoints = Dictionary(uniqueKeysWithValues: recognizedPoints.compactMap { (key, point) -> (String, CGPoint)? in
        guard point.confidence > 0.1 else { return nil }
        let norm = VNImagePointForNormalizedPoint(point.location,
                                                  Int(drawingView.bounds.width),
                                                  Int(drawingView.bounds.height))
        return (key.rawValue, norm)
      })
      
      let time = 1000 * observation.timeRange.start.seconds
      
      
      // Draw the points onscreen.
      DispatchQueue.main.async {
        self.drawingView.draw(points: mappedPoints)
      }
    }
  }
}

drawingView.draw函数用于相机视图顶部的自定义UIView,并使用CALayer子层绘制点。AVCaptureSession代码与此处的示例代码完全相同。

我尝试使用VNDetectHumanBodyPoseRequest(completionHandler:)变体,但这对我的性能没有影响。不过我可以尝试使用移动平均滤波器进行平滑。。但是仍然存在非常不准确的异常值预测的问题。

我错过了什么?

我认为这是iOS 14测试版v1-v3上的一个错误。升级到v4和更高版本的测试版后,跟踪效果会更好。随着最新的测试版更新,API的细粒度类型名称也变得更加清晰。

注意,我没有从苹果公司得到关于这个错误的官方答案,但这个问题可能会在iOS 14的官方版本中完全消失。

最新更新