Ios 获取VNDetectTextRectanglesRequest完成处理程序上的VNImageRequestHandler中使用的cvPixelBuffer

Ios 获取VNDetectTextRectanglesRequest完成处理程序上的VNImageRequestHandler中使用的cvPixelBuffer,ios,swift,swift3,apple-vision,Ios,Swift,Swift3,Apple Vision,我正在使用以下代码创建我的请求: let textRequest = VNDetectTextRectanglesRequest(completionHandler: self.detectTextHandler) textRequest.reportCharacterBoxes = true self.requests = [textRequest] 在我的AVCaptureVideoDataOutputSampleBufferDelegate中,我正在创建一个VNImageRequest

我正在使用以下代码创建我的请求:

let textRequest = VNDetectTextRectanglesRequest(completionHandler: 
self.detectTextHandler)
textRequest.reportCharacterBoxes = true
self.requests = [textRequest]
在我的AVCaptureVideoDataOutputSampleBufferDelegate中,我正在创建一个VNImageRequestHandler并执行它:

let imageRequestHandler = VNImageRequestHandler(cvPixelBuffer: pixelBuffer, orientation: CGImagePropertyOrientation(rawValue: 6)!, options: requestOptions)

do {
    try imageRequestHandler.perform(self.requests)
} catch {
    print(error)
}
这将提供具有以下签名的处理程序内部的检测结果:

func detectTextHandler(request: VNRequest, error: Error?)

我的问题是,如何获取此请求用于进一步处理的“cvPixelBuffer”?我应该存储它的临时版本吗

我找不到从
VNRequest
检索
CVPixelBuffer
的任何方法或属性

因此,在
completionHandler
的闭包中捕获它将是一种简单的方法:

AVCaptureVideoDataOutputSampleBufferDelegate
的方法中:

    let pixelBuffer = ...
    let requestOptions: [VNImageOption: Any] = ...

    let textRequest = VNDetectTextRectanglesRequest {request, error in
        //### Capture `pixelBuffer` inside this closure.
        self.detectText(from: pixelBuffer, request: request, error: error)
    }
    textRequest.reportCharacterBoxes = true

    let imageRequestHandler = VNImageRequestHandler(cvPixelBuffer: pixelBuffer, orientation: CGImagePropertyOrientation(rawValue: 6)!, options: requestOptions)

    do {
        try imageRequestHandler.perform([textRequest])
    } catch {
        print(error)
    }
并将其用作:

func detectText(from buffer: CVPixelBuffer, request: VNRequest, error: Error?) {
    //### Use `buffer` passed from the closure.
    //...
}

这是一个好问题

我的app()也遇到了类似的问题,它需要在调用完成处理程序之前保留对CMSampleBuffer对象的引用(这样关联的pixelBuffer就不会被视频捕获会话重用)

我通过将其存储为视图控制器(self.sampleBuffer)的属性来解决这个问题。因此,它一次只能处理一个像素缓冲区——这对我的应用程序来说很好,但不是最优的

如果需要进行双缓冲(或更多),则需要引入一个队列(pixelBuffers),假设完成顺序与请求相同——考虑到底层架构,这是合理的假设

无需重新创建每个图像的请求(如已接受的答案中所示),即可轻松完成

let mlRequest:RxVNCoreMLRequest=VNCoreMLRequest.rx.request(型号:model,imageCropAndScaleOption:.scaleFit)
mlRequest
.可见
.在中订阅{[无主自我](事件)
切换事件{
案例。下一步(让我们完成):
让cgImage=completion.value//NB您可以轻松地将值传递给完成处理程序
如果let result=completion.request.results?[0]作为VN分类观察{
操作系统日志(“结果:%@”,类型:。调试,结果。标识符)
}
违约:
打破
}
}
.处置(由:处置人)
让imageRequestHandler=VNImageRequestHandler(cgImage:cgImage,方向:.up,选项:requestOptions)
做{
尝试imageRequestHandler.rx.perform([mlRequest],with:cgImage)//NB您可以轻松地将值传递给完成处理程序
}抓住{
打印(错误)
}