ML Kit を使用すると、バーコードの認識とデコードを行うことができます。
試してみる
- サンプルアプリを試してみましょう。 この API の使用例をご覧ください
始める前に
- Podfile に次の ML Kit Pod を追加します。
pod 'GoogleMLKit/BarcodeScanning', '15.5.0'
- プロジェクトの Pod をインストールまたは更新したら、Xcode プロジェクトを開きます。
.xcworkspace
。ML Kit は Xcode バージョン 12.4 以降でサポートされています。
入力画像のガイドライン
-
ML Kit でバーコードを正確に読み取るには、入力画像に 十分なピクセルデータによって表されるバーコードです。
特定のピクセルデータ要件は、使用するピクセルと エンコードされたデータの量 可変サイズのペイロードをサポートします一般的に、ラベルに対して 幅 2 ピクセル以上で、かつ 2 次元コード、高さ 2 ピクセル。
たとえば、EAN-13 バーコードは、バーとスペースで構成されています。 幅が 2、3、または 4 単位の場合、EAN-13 バーコード画像には、バーと 少なくとも 2、4、6、8 ピクセル幅のスペース。EAN-13 は バーコードは合計で 95 ユニットの幅があり、バーコードは 190 以上である必要があります。 ピクセル幅。
PDF417 などの高密度形式では、 確実に読み取ることができますたとえば、PDF417 のコードには最大で 17 単位幅の「単語」が 34 個少なくとも 1 行あたり 幅 1,156 ピクセル。
-
画像のフォーカスが不適切だと、スキャンの精度に影響する可能性があります。アプリがインストールされていない 画像をキャプチャし直すようユーザーに求めます。
-
一般的なアプリケーションでは、より高帯域幅の 1280x720 や 1920x1080 など解像度の画像を使用することになり、 カメラから遠く離れた場所でスキャンできます。
ただし、レイテンシが重要なアプリケーションでは、 パフォーマンスは向上しますが バーコードが入力画像の大部分を占めます関連ドキュメント リアルタイムのパフォーマンスを改善するためのヒント
1. バーコード スキャナを構成する
読み取るバーコードの形式がわかっている場合は、 その形式のみをスキャンするように設定できます。たとえば、Aztec コードと QR コードのみをスキャンするには、
BarcodeScannerOptions
オブジェクト(
次の例をご覧ください。
Swift
let format = .all let barcodeOptions = BarcodeScannerOptions(formats: format)
次の形式がサポートされています。
- code128
- code39
- code93
- codaBar
- dataMatrix
- EAN13
- EAN8
- ITF
- qrCode
- UPCA
- UPCE
- PDF417
- Aztec
Objective-C
MLKBarcodeScannerOptions *options = [[MLKBarcodeScannerOptions alloc] initWithFormats: MLKBarcodeFormatQRCode | MLKBarcodeFormatAztec];
次の形式がサポートされています。
- Code-128(
MLKBarcodeFormatCode128
) - Code-39(
MLKBarcodeFormatCode39
) - Code-93(
MLKBarcodeFormatCode93
) - Codabar(
MLKBarcodeFormatCodaBar
) - Data Matrix(
MLKBarcodeFormatDataMatrix
) - EAN-13(
MLKBarcodeFormatEAN13
) - EAN-8(
MLKBarcodeFormatEAN8
) - ITF(
MLKBarcodeFormatITF
) - QR コード(
MLKBarcodeFormatQRCode
) - UPC-A(
MLKBarcodeFormatUPCA
) - UPC-E(
MLKBarcodeFormatUPCE
) - PDF-417(
MLKBarcodeFormatPDF417
) - Aztec コード(
MLKBarcodeFormatAztec
)
2. 入力画像を準備する
画像内のバーコードをスキャンするには、画像をUIImage
または
BarcodeScanner
の process()
または results(in:)
まで CMSampleBufferRef
メソッド:
VisionImage
オブジェクトを作成するには、UIImage
または
CMSampleBuffer
。
UIImage
を使用する場合は、次の手順を行います。
UIImage
を使用してVisionImage
オブジェクトを作成します。正しい.orientation
を指定してください。Swift
let image = VisionImage(image: UIImage) visionImage.orientation = image.imageOrientation
Objective-C
MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image]; visionImage.orientation = image.imageOrientation;
CMSampleBuffer
を使用する場合は、次の手順を行います。
-
格納されている画像データの向きを指定します。
CMSampleBuffer
。画像の向きを取得するには:
Swift
func imageOrientation( deviceOrientation: UIDeviceOrientation, cameraPosition: AVCaptureDevice.Position ) -> UIImage.Orientation { switch deviceOrientation { case .portrait: return cameraPosition == .front ? .leftMirrored : .right case .landscapeLeft: return cameraPosition == .front ? .downMirrored : .up case .portraitUpsideDown: return cameraPosition == .front ? .rightMirrored : .left case .landscapeRight: return cameraPosition == .front ? .upMirrored : .down case .faceDown, .faceUp, .unknown: return .up } }
Objective-C
- (UIImageOrientation) imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation cameraPosition:(AVCaptureDevicePosition)cameraPosition { switch (deviceOrientation) { case UIDeviceOrientationPortrait: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationLeftMirrored : UIImageOrientationRight; case UIDeviceOrientationLandscapeLeft: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationDownMirrored : UIImageOrientationUp; case UIDeviceOrientationPortraitUpsideDown: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationRightMirrored : UIImageOrientationLeft; case UIDeviceOrientationLandscapeRight: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationUpMirrored : UIImageOrientationDown; case UIDeviceOrientationUnknown: case UIDeviceOrientationFaceUp: case UIDeviceOrientationFaceDown: return UIImageOrientationUp; } }
- 次のコマンドを使用して、
VisionImage
オブジェクトを作成します。CMSampleBuffer
オブジェクトと向き:Swift
let image = VisionImage(buffer: sampleBuffer) image.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition)
Objective-C
MLKVisionImage *image = [[MLKVisionImage alloc] initWithBuffer:sampleBuffer]; image.orientation = [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation cameraPosition:cameraPosition];
3. BarcodeScanner のインスタンスを取得する
BarcodeScanner
のインスタンスを取得します。
Swift
let barcodeScanner = BarcodeScanner.barcodeScanner() // Or, to change the default settings: // let barcodeScanner = BarcodeScanner.barcodeScanner(options: barcodeOptions)
Objective-C
MLKBarcodeScanner *barcodeScanner = [MLKBarcodeScanner barcodeScanner]; // Or, to change the default settings: // MLKBarcodeScanner *barcodeScanner = // [MLKBarcodeScanner barcodeScannerWithOptions:options];
4. 画像を処理する
次に、画像をprocess()
メソッドに渡します。
Swift
barcodeScanner.process(visionImage) { features, error in guard error == nil, let features = features, !features.isEmpty else { // Error handling return } // Recognized barcodes }
Objective-C
[barcodeScanner processImage:image completion:^(NSArray<MLKBarcode *> *_Nullable barcodes, NSError *_Nullable error) { if (error != nil) { // Error handling return; } if (barcodes.count > 0) { // Recognized barcodes } }];
5. バーコードから情報を取得する
バーコード スキャン処理が成功すると、スキャナはBarcode
オブジェクト。各 Barcode
オブジェクトは、
バーコードが表示されます。バーコードごとに、
入力画像の境界座標と、入力画像の境界座標と、
できます。また、バーコード スキャナでデータの種類が判別できた場合も、
解析されたデータを含むオブジェクトを取得できます。
例:
Swift
for barcode in barcodes { let corners = barcode.cornerPoints let displayValue = barcode.displayValue let rawValue = barcode.rawValue let valueType = barcode.valueType switch valueType { case .wiFi: let ssid = barcode.wifi?.ssid let password = barcode.wifi?.password let encryptionType = barcode.wifi?.type case .URL: let title = barcode.url!.title let url = barcode.url!.url default: // See API reference for all supported value types } }
Objective-C
for (MLKBarcode *barcode in barcodes) { NSArray *corners = barcode.cornerPoints; NSString *displayValue = barcode.displayValue; NSString *rawValue = barcode.rawValue; MLKBarcodeValueType valueType = barcode.valueType; switch (valueType) { case MLKBarcodeValueTypeWiFi: ssid = barcode.wifi.ssid; password = barcode.wifi.password; encryptionType = barcode.wifi.type; break; case MLKBarcodeValueTypeURL: url = barcode.URL.url; title = barcode.URL.title; break; // ... default: break; } }
リアルタイムのパフォーマンスを改善するためのヒント
リアルタイム アプリケーションでバーコードをスキャンする場合は、 実現するためのガイドラインは次のとおりです。
-
カメラのネイティブ解像度で入力をキャプチャしないでください。デバイスによっては ネイティブ解像度で入力をキャプチャすると、 ありますが、レイテンシが非常に低くなり、分析に 向上します代わりに、必要なサイズのみをカメラにリクエストしてください。 (通常は 2 メガピクセル以下)
名前付きキャプチャ セッションのプリセット -
AVCaptureSessionPresetDefault
、AVCaptureSessionPresetLow
、AVCaptureSessionPresetMedium
、 使用できますが、推奨されません。 一部のデバイスで不適切な解像度が発生することがあります。代わりに、特定のプリセットを使用してくださいAVCaptureSessionPreset1280x720
など。スキャン速度が重要な場合は、画像のキャプチャ速度を 解決します。ただし、バーコードのサイズの最小要件には 概要をご覧ください。
一連のストリーミングからバーコードを認識する場合 認識機能は、フレームごとに結果が異なる場合があります。 クリックします。同じ注文が連続して届くまでお待ちください。 正しい結果を返していると確信できます。
チェックサムは、ITF および CODE-39 ではサポートされていません。
- 動画フレームの処理には、検出機能の
results(in:)
同期 API を使用します。発信 このメソッドは、AVCaptureVideoDataOutputSampleBufferDelegate
の <ph type="x-smartling-placeholder"></ph> 指定された動画から結果を同期的に取得するcaptureOutput(_, didOutput:from:)
関数 クリックします。<ph type="x-smartling-placeholder"></ph>のままにするAVCaptureVideoDataOutput
さんのalwaysDiscardsLateVideoFrames
をtrue
として、検出機能の呼び出しをスロットリングします。新しい 検出機能の実行中に利用可能になった動画フレームは破棄されます。 - 検出機能の出力を使用して、ディスプレイにグラフィックをオーバーレイする場合、 まず ML Kit から結果を取得してから、画像をレンダリングする 1 ステップでオーバーレイできますこれにより、ディスプレイ サーフェスにレンダリングされます。 各入力フレームに対して 1 回だけです。updatePreviewOverlayViewWithLastFrame をご覧ください。 をご覧ください。