未在 android 上使用 firebase ml 套件检测 QR 码,但在 ios 上有效(抖动)

Not detecting QR codes with firebase ml kit on android but works on ios (flutter)

我的二维码扫描器在 Android 上停止工作,我不明白为什么...它以前工作过,但扫描器在 iOS 上仍然工作。

Firebase ML 套件在扫描时只是 returns 一个空列表,我尝试了许多不同的 android 设备和 QR 码,但 none 工作(不再)。

我已经尝试清理并重新安装所有依赖项, 我试图清除 Google Play 服务中的所有数据并重新安装应用程序(以便它重新安装 ML 模型)

我想这可能是图像格式不正确,相机的格式是 YUV_420_888 我认为它是用下面的代码转换成 NV21,但不是 100 % 确定它是如何工作的。

恼人的是,这之前确实有效,但突然停止了。

这是我实现的 QR 扫描仪,它从相机流中接收图像

class QRCodeReader {

  BarcodeDetector _barcodeDetector = FirebaseVision.instance.barcodeDetector(BarcodeDetectorOptions(barcodeFormats: BarcodeFormat.qrCode));

  void dispose() {
    _barcodeDetector.close();
  }

  void scanImage(CameraImage availableImage, ScanCompleted scanCompleted) async {
    final FirebaseVisionImageMetadata metadata = FirebaseVisionImageMetadata(
      rawFormat: availableImage.format.raw,
      size: Size(availableImage.width.toDouble(), availableImage.height.toDouble()),
      planeData: availableImage.planes.map((currentPlane) => FirebaseVisionImagePlaneMetadata(
        bytesPerRow: currentPlane.bytesPerRow,
        height: currentPlane.height,
        width: currentPlane.width
        )).toList(),
      rotation: ImageRotation.rotation0,
    );

    final FirebaseVisionImage visionImage = FirebaseVisionImage.fromBytes(availableImage.planes[0].bytes, metadata);

    //this list is empty on android
    List barCodes = await _barcodeDetector.detectInImage(visionImage);

    for(Barcode barcode in barCodes) {
      //process barcode...
    }

    scanCompleted();
  } 
}

我这样初始化流...

_initializeControllerFuture = _controller.initialize();
_initializeControllerFuture.whenComplete(() {
  setState((){
    _controller.startImageStream(_handleImageStream);
  });
});

void _handleImageStream(CameraImage availableImage) {
    if (!_isScanning && !_disposed) {
      final state = Provider.of<ScannerState>(context);
      _isScanning = true;

      qrReader.scanImage(availableImage, () => _isScanning = false);
    }
}

app/build.gradle

...
dependencies {
    ...
    api 'com.google.firebase:firebase-ml-vision-image-label-model:17.0.2'
}

apply plugin: 'com.google.gms.google-services'

build.gradle

buildscript {
    ...
    dependencies {
        classpath 'com.android.tools.build:gradle:3.4.1'
        classpath 'com.google.gms:google-services:4.2.0'
    }
}

AndroidManifest.xml

...
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.VIBRATE"/>
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.FLASHLIGHT" />


    <application
        android:name="io.flutter.app.FlutterApplication"
        ...>
        <meta-data
            android:name="com.google.firebase.ml.vision.DEPENDENCIES"
            android:value="barcode" />
        ...
    </application>

pubspec.yaml

...
dependencies:
  ...
  camera: ^0.5.4+2
  firebase_core: ^0.4.0+9
  cloud_firestore: ^0.12.9+4
  cloud_functions: ^0.4.1+1
  firebase_ml_vision: ^0.9.2+1
...

编辑:按照 Frank 的建议,问题出在摄像头的分辨率设置上,如果分辨率太低,则无法检测到 QR 码。将其设置为 "high" 或更高版本可解决此问题。

我通过将相机插件回滚到以下版本解决了这个问题:"camera: ^0.5.2+2"

不确定是什么破坏了新版本中 android 的 ML 视觉包,但这暂时解决了这个问题。