简体   繁体   English

使用 AVAssetWriter 和 CoreML 的相机上的 FPS 不一致

[英]FPS not consistent on Camera using AVAssetWriter and CoreML

I'm trying to create an app that can record video at 100 FPS using AVAssetWriter AND detect if a person is performing an action using the ActionClassifier from Create ML.我正在尝试创建一个应用程序,该应用程序可以使用 AVAssetWriter 以 100 FPS 的速度录制视频,并使用 Create ML 中的 ActionClassifier 检测一个人是否正在执行操作。 But when I try to put the 2 together the FPS drops to 30 when recording and detecting actions.但是当我尝试将 2 放在一起时,在记录和检测动作时 FPS 会下降到 30。

If I do the recording by itself then it records at 100 FPS.如果我自己进行录制,那么它会以 100 FPS 的速度录制。

I am able to set the FPS of the camera to 100 FPS through the device configuration.我可以通过设备配置将相机的 FPS 设置为 100 FPS。

Capture output Function is setup捕获输出功能设置

  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))")
        }
        
        

    }

Performing action classification is quite expensive if you want to run it every frame so it may affect overall performance of the app (including video footage FPS).如果您想每帧都运行它,那么执行动作分类非常昂贵,因此它可能会影响应用程序的整体性能(包括视频片段 FPS)。 I don't know how often you need prediction but I would suggest you to try running Action Classifier 2-3 times per second maximum and see if that helps.我不知道您需要多久进行一次预测,但我建议您尝试每秒最多运行 2-3 次 Action Classifier,看看是否有帮助。

Running action classifier every frame won't change your classification that much because you're adding just one frame to your classifier action window so there is no need to run it so often.每一帧运行动作分类器不会改变你的分类,因为你只向分类器动作窗口添加了一帧,所以没有必要经常运行它。

For example if your action classifier was setup with window 3s and trained on 30fps videos, your classification is based on 3 * 30 = 90 frames.例如,如果您的动作分类器设置为窗口 3s 并在 30fps 视频上进行训练,则您的分类基于 3 * 30 = 90 帧。 One frame won't make a difference.一帧不会有什么不同。

Also make sure that your 100fps matches footage that you used for training action classifier.还要确保您的 100fps 与您用于训练动作分类器的素材相匹配。 Otherwise you can get wrong predictions because running Action Classifier trained on 30fps video will treat 1s of 100fps footage as more than 3,333s.否则,您可能会得到错误的预测,因为运行在 30fps 视频上训练的动作分类器会将 100fps 素材的 1 秒视为超过 3,333 秒。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM