2017-06-21 9 views
5

私は、AppleがWWDC2017で導入した新しいVisionフレームワークのテストを実装しています。私は特にバーコードの検出を見ています - カメラ/ギャラリーからバーコード画像であるかどうかをスキャンした後に取得できました。しかし、barcodeDescriptorを見ると、実際のバーコード値やペイロードデータがわかりません。プロパティのいずれかを特定するために、https://developer.apple.com/documentation/coreimage/cibarcodedescriptorページには何も公開されていないようです。Vision Framework iOS 11のバーコード検出

私はこれらのエラー取得しています:

  • がリモートサービスに接続できません:
  • libMobileGestaltエラードメイン= NSCocoaErrorDomainコード= 4097 "
    com.apple.BarcodeSupport.BarcodeNotificationServiceという名前のサービスへの接続" MobileGestalt.c:555:InverseDeviceIDへのアクセスなし(問題/ 11744455を参照)
  • com.apple.BarcodeSupport.BarcodeNotificationServiceという名前のサービスへの接続エラー
    ドメイン= NSCocoaErrorDomainコード= 4097

VNBarcodeObservationからバーコード値にアクセスする方法はありますか? ご協力いただければ幸いです。ありがとうございました!

@IBAction func chooseImage(_ sender: Any) { 
     imagePicker.allowsEditing = true 
     imagePicker.sourceType = .photoLibrary 

     present(imagePicker, animated: true, completion: nil) 
    } 

    @IBAction func takePicture(_ sender: Any) { 
     if(UIImagePickerController .isSourceTypeAvailable(UIImagePickerControllerSourceType.camera)){ 
      imagePicker.sourceType = UIImagePickerControllerSourceType.camera 
      self .present(imagePicker, animated: true, completion: nil) 
     } 
     else{ 
      let alert = UIAlertController(title: "Warning", message: "Camera not available", preferredStyle: UIAlertControllerStyle.alert) 
      alert.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.default, handler: nil)) 
      self.present(alert, animated: true, completion: nil) 
     } 
    } 

    //PickerView Delegate Methods 

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) { 

     imagePicker .dismiss(animated: true, completion: nil) 
     classificationLabel.text = "Analyzing Image…" 

     guard let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage 
      else { fatalError("no image from image picker") } 
     guard let ciImage = CIImage(image: pickedImage) 
      else { fatalError("can't create CIImage from UIImage") } 

     imageView.image = pickedImage 
     inputImage = ciImage 

     // Run the rectangle detector, which upon completion runs the ML classifier. 
     let handler = VNImageRequestHandler(ciImage: ciImage, options: [.properties : ""]) 
     DispatchQueue.global(qos: .userInteractive).async { 
      do { 
       try handler.perform([self.barcodeRequest]) 
      } catch { 
       print(error) 
      } 
     } 
    } 

    func imagePickerControllerDidCancel(_ picker: UIImagePickerController){ 
     picker .dismiss(animated: true, completion: nil) 
     print("picker cancel.") 
    } 

    lazy var barcodeRequest: VNDetectBarcodesRequest = { 
     return VNDetectBarcodesRequest(completionHandler: self.handleBarcodes) 
    }() 

    func handleBarcodes(request: VNRequest, error: Error?) { 
     guard let observations = request.results as? [VNBarcodeObservation] 
      else { fatalError("unexpected result type from VNBarcodeRequest") } 
     guard observations.first != nil else { 
      DispatchQueue.main.async { 
       self.classificationLabel.text = "No Barcode detected." 
      } 
      return 
     } 

     // Loop through the found results 
     for result in request.results! { 

      // Cast the result to a barcode-observation 
      if let barcode = result as? VNBarcodeObservation { 

       // Print barcode-values 
       print("Symbology: \(barcode.symbology.rawValue)") 

       if let desc = barcode.barcodeDescriptor as? CIQRCodeDescriptor { 
        let content = String(data: desc.errorCorrectedPayload, encoding: .utf8) 

        // FIXME: This currently returns nil. I did not find any docs on how to encode the data properly so far. 
        print("Payload: \(String(describing: content))\n") 
        print("Error-Correction-Level: \(desc.errorCorrectedPayload)\n") 
        print("Symbol-Version: \(desc.symbolVersion)\n") 
       } 
      } 
     } 
    } 
+0

チェックアウト[ - - フィルター、金属、ビジョン、およびその他のWWDC 2017のコアイメージの進歩セッション#510]何の問題もなくQRコードから情報を読み取ることができます.com/videos/play/wwdc2017/510 /)で35分、CIBarcodeDescriptorとerrorCorrectedPayloadについて話を始めます。残念ながら私はペイロード内のメッセージを読むことができませんでした。 – nathan

+0

ええ、 "Edit Scheme" - > Run-> Argumentsで "OS_ACTIVITY_MODE"を無効にしてこれらのエラーを修正できましたが、ペイロードからデータを抽出できません。私はバーコードをスキャンして、ビデオに表示されているものからイメージを作り出すことができますが、データ型から情報文字列を抽出することにはまだまだ取り組んでいます。 –

+0

私は自分のテストの基礎としてあなたのコードを使いました。私はいくつかの*運がありましたが(iOS 11 beta 3)、結果は困惑していました。 'errorCorrectedPayload'は*時には読み込み可能なデータを含んでいます。 https://stackoverflow.com/questions/45037418/zlib-stream-in-ios-11-vision-framework-barcodes-sometimes-decompress-sometimes – oelna

答えて

2

をAppleは、このためのライブラリを提供するつもりはない場合は、次のようなものは動作します:ここに は、私が使用していたコードである

extension CIQRCodeDescriptor { 
    var bytes: Data? { 
     return errorCorrectedPayload.withUnsafeBytes { (pointer: UnsafePointer<UInt8>) in 
      var cursor = pointer 

      let representation = (cursor.pointee >> 4) & 0x0f 
      guard representation == 4 /* byte encoding */ else { return nil } 

      var count = (cursor.pointee << 4) & 0xf0 
      cursor = cursor.successor() 
      count |= (cursor.pointee >> 4) & 0x0f 

      var out = Data(count: Int(count)) 
      guard count > 0 else { return out } 

      var prev = (cursor.pointee << 4) & 0xf0 
      for i in 2...errorCorrectedPayload.count { 
       if (i - 2) == count { break } 

       let cursor = pointer.advanced(by: Int(i)) 
       let byte = cursor.pointee 
       let current = prev | ((byte >> 4) & 0x0f) 
       out[i - 2] = current 
       prev = (cursor.pointee << 4) & 0xf0 
      } 
      return out 
     } 
    } 
} 

そして

String(data: descriptor.bytes!, encoding: .utf8 /* or whatever */) 
+0

'表現変数のガーディングの説明/リンクはできますか?私は 'CIQRCodeDescriptor'と' representation'(つまり2)の値を解析しようとしていますが、私の 'descriptor.bytes'がnilになっています。 – raoul

+1

あなたの表現は「英数字」なので、別のアルゴリズムが必要です。 http://www.thonky.com/qr-code-tutorial/alphanumeric-mode-encoding –

6

明らかに、iOS 11ベータ5では、Appleは新しいpayloadStringValueというプロパティーをVNBarcodeObservationというように導入しました。 (https://developer.apple:今、あなたは

if let payload = barcodeObservation.payloadStringValue { 
    print("payload is \(payload)") 
} 
関連する問題