Я пытаюсь улучшить производительность рисования скелета с отслеживанием тела для VNDetectHumanBodyPoseRequest
даже на расстоянии более 5 метров и с помощью стабильной камеры iPhone XS.
Отслеживание имеет низкую достоверность по нижним правым конечностям моего тела заметное отставание и есть дрожание. Я не могу воспроизвести продемонстрированную производительность в демонстрационном видео WWD C этого года .
Вот соответствующий код, адаптированный из образца кода Apple :
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
поверх обзора камеры, и dr aws точек с использованием подслоев CALayer
. Код AVCaptureSession
точно такой же, как код примера здесь .
Я пробовал использовать вариант VNDetectHumanBodyPoseRequest(completionHandler:)
, но это не повлияло на производительность для меня. Я мог бы попробовать сглаживание с помощью фильтра скользящего среднего .. но все еще есть проблема с прогнозами выбросов, которые очень неточны.
Что мне не хватает?