带有VNDetectBarcodeRequest的QR阅读器

时间:2017-07-28 18:02:32

标签: ios avfoundation qr-code apple-vision

我设置了一个带有视频数据输出的AVCaptureSession,并尝试使用iOS 11的Vision框架来读取QR码。相机的设置基本上与任何AVCaptureSession相同。我将缩写并显示设置输出。

let output = AVCaptureVideoDataOutput()
output.setSampleBufferDelegate(self, queue: captureQueue)
captureSession.addOutput(output)

// I did this to get the CVPixelBuffer to be oriented in portrait.
// I don't know if it's needed and I'm not sure it matters anyway.
output.connection(with: .video)!.videoOrientation = .portrait

所以相机一如既往地正常运行。以下是我用来为QR码执行VNImageRequestHandler的代码。

func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
    guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return }
    let imageRequestHandler = VNImageRequestHandler(cvPixelBuffer: pixelBuffer, orientation: .up, options: [:])

    let qrRequest = VNDetectBarcodesRequest { request, error in
        let barcodeObservations = request.results as? [VNBarcodeObservation]
        guard let qrCode = barcodeObservations?.flatMap({ $0.barcodeDescriptor as? CIQRCodeDescriptor }).first else { return }
        if let code = String(data: qrCode.errorCorrectedPayload, encoding: .isoLatin1) {
            debugPrint(code)
        }
    }

    qrRequest.symbologies = [.QR]
    try! imageRequestHandler.perform([qrRequest])
}

我正在使用编码http://www.google.com的QR码作为测试。打印出debugPrint行:

  

AVGG\u{03}¢ò÷wwrævöövÆRæ6öÐì\u{11}ì

我使用已经存在一段时间的AVCaptureMetadataOutput测试了相同的QR码,该方法正确解码了QR码。所以我的问题是,我错过了什么来得到我得到的输出?

(显然我可以使用AVCaptureMetadataOutput作为解决方案,因为我可以看到它有效。但这并不能帮助我学习如何使用Vision框架。)

3 个答案:

答案 0 :(得分:0)

问题很可能就在这里:

if let code = String(data: qrCode.errorCorrectedPayload, encoding: .isoLatin1) 

尝试使用.utf8。

另外我建议看一下' errorCorrectedPayload'的原始输出。没有编码。也许它已经有正确的编码。

答案 1 :(得分:0)

errorCorrectedPayload的定义说:   - QR码在ISO / IEC 18004:2006(E)中正式规定。第6.4.10节“码流到码字转换”指定在将消息分成块并应用纠错之前的符号中的8位码字集。 -

答案 2 :(得分:0)

这似乎可以与VNBarcodeObservation.payloadStringValue配合使用,而不是转换VNBarcodeObservation.barcodeDescriptor