我正在使用以下代码创建我的请求:
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"该请求用于进一步处理?我应该存储它的时间版本吗?
答案 0 :(得分:2)
我找不到从CVPixelBuffer
检索VNRequest
的任何方法或属性。
因此,在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.
//...
}
答案 1 :(得分:0)
这是一个很好的问题。
我的app(https://github.com/snakajima/MobileNet-iOS)遇到了类似的问题,需要保留对CMSampleBuffer对象的引用,直到调用完成处理程序为止(以便关联的pixelBuffer不会被重用)视频捕捉会议。)
我通过将其存储为视图控制器(self.sampleBuffer)的属性来解决它。结果,它一次只能处理一个pixelBuffer - 这对我的应用程序来说很好但不是最佳的。
如果你需要进行双缓冲(或更多),你需要引入一个(pixelBuffers)队列,假设完成的顺序与请求相同 - 这是考虑底层架构的合理假设。
答案 2 :(得分:0)
https://github.com/maxvol/RxVision使您无需重新创建每张图片的请求即可轻松完成操作(如接受的答案一样)。
let mlRequest: RxVNCoreMLRequest<CGImage> = VNCoreMLRequest.rx.request(model: model, imageCropAndScaleOption: .scaleFit)
mlRequest
.observable
.subscribe { [unowned self] (event) in
switch event {
case .next(let completion):
let cgImage = completion.value // NB you can easily pass the value along to the completion handler
if let result = completion.request.results?[0] as? VNClassificationObservation {
os_log("results: %@", type: .debug, result.identifier)
}
default:
break
}
}
.disposed(by: disposeBag)
let imageRequestHandler = VNImageRequestHandler(cgImage: cgImage, orientation: .up, options: requestOptions)
do {
try imageRequestHandler.rx.perform([mlRequest], with: cgImage) // NB you can easily pass the value along to the completion handler
} catch {
print(error)
}