FPS不一致的相机使用avassetwwriter和CoreML



我正在尝试创建一个应用程序,可以使用avassetwwriter以100 FPS记录视频,并检测一个人是否正在使用create ML中的ActionClassifier执行动作,但是当我尝试将2放在一起时,记录和检测动作时FPS下降到30。

如果我自己录制,那么它会以100 FPS的速度录制。

我可以通过设备配置将相机的FPS设置为100 FPS。

捕获输出功能设置

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

bufferImage = sampleBuffer
guard let calibrationData = CMGetAttachment(sampleBuffer, key: kCMSampleBufferAttachmentKey_CameraIntrinsicMatrix, attachmentModeOut: nil) as? Data else {
return
}

cameraCalibrationMatrix = calibrationData.withUnsafeBytes { $0.pointee }

if self.isPredictorActivated == true {
do  {
let poses = try predictor.processFrame(sampleBuffer)
if (predictor.isReadyToMakePrediction) {
let prediction =  try predictor.makePrediction()
let confidence = prediction.confidence * 100
DispatchQueue.main.async {
self.predictionLabel.text = prediction.label + " " + String(confidence.rounded(toPlaces: 0))
if (prediction.label == "HandsUp" && prediction.confidence > 0.85) {
print("Challenging")
self.didChallengeVideo()
}
}
}
} catch {
print(error.localizedDescription)
}
}




let presentationTimeStamp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)

if assetWriter == nil {
createWriterInput(for: presentationTimeStamp)
} else {
let chunkDuration = CMTimeGetSeconds(CMTimeSubtract(presentationTimeStamp, chunkStartTime))
//            print("Challenge(isChallenging)")

if chunkDuration > 1500 || isChallenging {
assetWriter.endSession(atSourceTime: presentationTimeStamp)

// make a copy, as finishWriting is asynchronous
let newChunkURL = chunkOutputURL!
let chunkAssetWriter = assetWriter!

chunkAssetWriter.finishWriting {
print("finishWriting says: (chunkAssetWriter.status.rawValue) (String(describing: chunkAssetWriter.error))")
print("queuing (newChunkURL)")
print("Chunk Duration: (chunkDuration)")

let asset = AVAsset(url: newChunkURL)

print("FPS of CHUNK (asset.tracks.first?.nominalFrameRate)")

if self.isChallenging {
self.challengeVideoProcess(video: asset)
}

self.isChallenging = false


}
createWriterInput(for: presentationTimeStamp)

}
}

if !assetWriterInput.append(sampleBuffer) {
print("append says NO: (assetWriter.status.rawValue) (String(describing: assetWriter.error))")
}


}

如果你想每帧都运行动作分类,那么执行动作分类是非常昂贵的,所以它可能会影响应用程序的整体性能(包括视频片段FPS)。我不知道你需要预测的频率,但我建议你尝试每秒最多运行2-3次动作分类器,看看是否有帮助。

每帧运行动作分类器不会改变你的分类,因为你只添加了一帧到你的分类器动作窗口,所以没有必要经常运行它。

例如,如果你的动作分类器设置为窗口3秒,并在30fps视频上训练,你的分类是基于3 * 30 = 90帧。一帧没有区别。

还要确保你的100fps与你用于训练动作分类器的素材相匹配。否则你可能会得到错误的预测,因为在30帧/秒的视频上运行动作分类器会将100帧/秒的片段中的15帧视为超过3333秒。