代码之家  ›  专栏  ›  技术社区  ›  Andy Jazz

CVPixelBuffer如何在每秒60帧中捕获每三帧?

  •  1
  • Andy Jazz  · 技术社区  · 7 年前

    我只需要每秒60帧中的20帧进行处理( CVPixelBuffer

    如何在ARKit会话中捕获每三个ARFrame ? 我需要大约20 fps的捕捉速度(我知道可能会有下降帧)。

    func updateCoreML() {
    
        let pixelBuffer: CVPixelBuffer? = (sceneView.session.currentFrame?.capturedImage)
    
        if pixelBuffer == nil { return }
        let ciImage = CIImage(cvPixelBuffer: pixelBuffer!)
        let imageRequestHandler = VNImageRequestHandler(ciImage: ciImage, options: [:])
    
        do {
            try imageRequestHandler.perform(self.visionRequests)
        } catch {
            print(error)
        }
    }
    
    2 回复  |  直到 6 年前
        1
  •  1
  •   Maxim Volgin    7 年前

    我所知道的最简单的方法就是使用 RxARKit 申请 .throttle() session.rx.didUpdateFrame .节流阀() RxVision ,这将确保 CoreML .

    import RxSwift
    import RxARKit
    import RxVision
    
    
    let disposeBag = DisposeBag()
    let mlRequest: RxVNCoreMLRequest<CVPixelBuffer> = VNCoreMLRequest.rx.request(model: model, imageCropAndScaleOption: .scaleFit)
    
    mlRequest
        .observable
        .subscribe { [unowned self] (event) in
            switch event {
                case .next(let completion):       
                    let cvPixelBuffer = completion.value
                    if let result = completion.request.results?[0] as? VNClassificationObservation {
                        os_log("results: %@", type: .debug, result.identifier)
                    }
                default:
                    break
            }
        }
        .disposed(by: disposeBag)
    
    session
        .rx
        .didUpdateFrame
        .throttle(1/20)
        .subscribe { event in
            switch event {
            case .next(let didUpdateFrame):
            let frame: ARFrame = didUpdateFrame.frame        
            let imageRequestHandler = VNImageRequestHandler(cvPixelBuffer: frame.capturedImage, orientation: .up, options: requestOptions)
            do {
                try imageRequestHandler.rx.perform([mlRequest], with: frame.capturedImage) } catch {
                print(error)
            }            
            break
            default:
                break
            }
        }
        .disposed(by: disposeBag)
    
        2
  •  0
  •   Tahir Iqbal    7 年前

    您可以设置自定义帧速率,以便只获得20帧,也可以接收所有帧,但只使用每三帧,方法是获取一个标志变量并将其递增。

      func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
           totalFrameCount += 1
           if totalFrameCount % 3 != 0{ return }
    }
    

     lockForConfiguration()
     activeVideoMinFrameDuration = CMTimeMake(1, 20)
     activeVideoMaxFrameDuration = CMTimeMake(1, 20)
     unlockForConfiguration()
    
    推荐文章