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您可以轻松地将值传递给完成处理程序
}抓住{
打印(错误)
}