gpt4 book ai didi

swift - 观察者导致 AVFoundation captureOutput 方法出现滞后

转载 作者:行者123 更新时间:2023-11-30 11:10:35 24 4
gpt4 key购买 nike

我有一个非常具体的问题,但希望有人可以帮助我。我正在使用 AVFoundation 创建具有实时预览功能的摄像机。我使用 AVCaptureVideoDataOutput 来获取各个帧,并使用 AVCaptureMetadataOutput 来检测面部。我还使用 Dlib 的面部标志预测器来显示用户脸上的标志点并测量他们的眼睛之间的距离。最后,我使用 AVAssetWriter 来录制视频。

View Controller 上有一个椭圆形,因此用户知道将脸放在哪里。当眼间距离在一定距离之间时,我希望椭圆变成蓝色,以便用户知道他们的脸位于正确的位置。

目前,我通过从 SessionHandler 类向 View Controller 发送通知来实现这一目标。这是有效的,但是它会导致视频中的每秒帧数严重下降。我的帧率为 25fps(由我手动设置),现在范围在 8-16 之间。

是否有另一种方法来通知 View Controller 椭圆应该变成绿色?

这是我出现问题的代码。我知道发生了很多事情。

    // MARK: AVCaptureVideoDataOutputSampleBufferDelegate, AVCaptureAudioOutputSampleBufferDelegate
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {

if !currentMetadata.isEmpty {
let boundsArray = currentMetadata
.compactMap { $0 as? AVMetadataFaceObject }
.map { (faceObject) -> NSValue in
let convertedObject = output.transformedMetadataObject(for: faceObject, connection: connection)
return NSValue(cgRect: convertedObject!.bounds)
}

if user.hasDlib {
wrapper?.doWork(on: sampleBuffer, inRects: boundsArray)
// Get the interocular distance so face is the correct place in the oval
let interocularDistance = wrapper?.getEyeDistance()
//print("Interocular Distance: \(interocularDistance)")

if user.hasInterocularDistance {
if interocularDistance! < 240 || interocularDistance! > 315 {
let name = Notification.Name(rawValue: setRemoveGreenEllipse)
NotificationCenter.default.post(name: name, object: nil)
//print("face not correct distance")
if videoRecorder.isRecording {
eyeDistanceCounter += 1
//print(eyeDistanceCounter)
if eyeDistanceCounter == 30 {
cancelledByUser = false
cancelledByEyeDistance = true
videoRecorder.cancel()
eyeDistanceCounter = 0
}
}
} else {
//print("face correct distance")
eyeDistanceCounter = 0
let name = Notification.Name(rawValue: setGreenEllipse)
NotificationCenter.default.post(name: name, object: nil)
}
}

}
} else {

// Check if face is detected during recording. If it isn't, then cancel recording
if videoRecorder.isRecording {
noFaceCount += 1
if noFaceCount == 50 {
cancelledByUser = false
videoRecorder.cancel()
noFaceCount = 0
}
}

}

if layer.status == .failed {
layer.flush()
}

layer.enqueue(sampleBuffer)

let writable = videoRecorder.canWrite()

if writable {

if videoRecorder.sessionAtSourceTime == nil {
// Start Writing
videoRecorder.sessionAtSourceTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
videoRecorder.videoWriter.startSession(atSourceTime: videoRecorder.sessionAtSourceTime!)
print("video session started")
}

if videoRecorder.videoWriterInput.isReadyForMoreMediaData {
// write video buffer
videoRecorder.videoWriterInput.append(sampleBuffer)
//print("video buffering")
}
}
}

最佳答案

例如,您可以每 30 帧调用一次通知,而不是每帧调用一次。

如果在同一个 View Controller 中,您也可以直接调用颜色更改函数。如果没有,您可以定义一个委托(delegate)方法并直接调用它,而不是发送通知。

关于swift - 观察者导致 AVFoundation captureOutput 方法出现滞后,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52212765/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com