2017-07-28 2 views
0

Ich habe eine AVCaptureSession mit einer Video-Datenausgabe eingerichtet und versuche, das Vision-Framework von iOS 11 zu verwenden, um QR-Codes zu lesen. Die Kamera ist eingerichtet wie grundsätzlich jede AVCaptureSession ist. Ich werde abkürzen und nur die Einrichtung der Ausgabe zeigen.QR Reader mit VNDetectBarcodeRequest

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 

Also die Kamera läuft und läuft wie immer. Hier ist der Code, den ich verwende, um eine VNImageRequestHandler für QR-Codes durchzuführen.

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]) 
} 

Ich bin mit einem QR-Code, der http://www.google.com als Test kodiert. Die debugPrint Zeile ausdruckt:

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

ich diesen gleichen QR Code getestet haben mit dem AVCaptureMetadataOutput, die für eine Weile gewesen ist und diese Methode entschlüsselt den QR-Code korrekt. Also meine Frage ist, was habe ich verpasst, um die Ausgabe zu bekommen, die ich bekomme?

(Natürlich könnte ich einfach die AVCaptureMetadataOutput als Lösung, weil ich sehen kann, dass es funktioniert. Aber das hilft mir nicht lernen, wie man den Vision-Framework verwenden.)

Antwort

0

Wahrscheinlich ist das Problem hier :

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

Versuchen Sie, .utf8 zu verwenden.

Auch ich würde vorschlagen, die rohe Ausgabe des "errorCorrectedPayload" ohne Codierung zu betrachten. Vielleicht hat es schon die richtige Kodierung.

+0

Ich ging mit '.isoLatin1 ', weil das der Standard für QR-Codes ist ([Referenz] (https://www.ibm.com/support/knowledgecenter/en/SSBJG3_2.5.0/com.ibm.gen_studug .doc/c_grd_barcodes_qr_code.htm)). Ich werde in andere Codierungen schauen, um zu sehen, ob es hilft. Ich werde auch sehen, ob ich irgendwie die rohen Bytes verstehen kann. Danke für den Vorschlag. – keithbhunter

+0

Keine der anderen Codierungen, die ich ausprobierte, waren besser. Einige gaben "nil" zurück und einige gaben den gleichen verschlüsselten Text zurück. – keithbhunter

+0

Nach einigen Tests denke ich, errorCorrectedPayload ist nicht die QR-Daten selbst. In der Quelldatei des CIQRCodeDescriptor heißt es, dass errorCorrectedPayload - "Die fehlerkorrigierten Codewörter, die das QR-Code-Symbol umfassen." Das ist nicht sehr klar. –

0

Die Definition von errorCorrectedPayload sagt: - QR-Codes sind formal in ISO/IEC 18004: 2006 (E) angegeben. Abschnitt 6.4.10 "Umwandlung von Bitstrom in Codewort" spezifiziert den Satz von 8-Bit-Codewörtern in dem Symbol unmittelbar vor dem Teilen der Nachricht in Blöcke und Anwenden einer Fehlerkorrektur. -