android - ML Kit 条码扫描未检测到显示器屏幕照片中的二维码

标签 android kotlin qr-code barcode-scanner google-mlkit

我正在使用 com.google.mlkit:barcode-scanning:17.0.2检测图片中的二维码。

从图库获取 URI 后,我创建了 InputImage,然后使用 BarcodeScanner 处理此图像以查找 QR 码。当我选择一张纸质代码上的二维码照片时,就会找到代码。但是当我拍下显示器屏幕上二维码的照片时,却找不到代码。我应该怎么做才能检测到监视器屏幕照片中的二维码?

(当我使用与 CameraX 相同的扫描仪进行实时二维码检测时,它会在监视器屏幕上找到代码)

val image = InputImage.fromFilePath(context, uri)

val scanOptions =
    BarcodeScannerOptions.Builder()
        .setBarcodeFormats(
            Barcode.FORMAT_QR_CODE,
        )
        .build()

val scanner = BarcodeScanning.getClient(scanOptions)

scanner.process(image)
    .addOnSuccessListener {
        val code = it.getOrNull(0)?.rawValue
        if (code == null) {
            // code NOT found
        } else {
            // code was found
        }
    }

在纸上找到的二维码示例

enter image description here

未找到监控屏幕上的二维码示例

enter image description here

最佳答案

很有可能你正在对抗 Moiré effect .根据 QR 检测算法,莫尔效应引入的高频会使检测器偏离轨道。令人沮丧的是,通常是 更好 QRcode 检测器被莫尔图案击败。

一个好的解决方法是:

  • 以最高分辨率拍摄照片
  • 对图片进行模糊处理
  • 如果可能,将对比度提高到最大值
  • (可选)运行 sigma 阈值,或者只是将亮度分量低于 32 的所有像素重写为 0,所有高于 224 的像素重写为 255。

进行大致相同操作的另一种方法是

  • 以最高分辨率拍摄照片
  • 如果可能,将对比度提高到最大值
  • 将图片降采样到更低的分辨率

第二种方法的结果较差,但通常可以使用设备原语实现。

显示器问题的另一个来源(据我所知不在您的图片中)是刷新率。有时候,你会发现二维码实际上是图片上半部分曝光过度的二维码,图片下半部分曝光不足的二维码。两者都不被认可。这种影响是由于显示器的刷新率和策略造成的,不容易解决——您可以尝试降低显示器的亮度以增加曝光时间,直到超过 1/50 或 1/25 秒,或者从更远的地方拍摄照片远离并使用数码变焦。现代显示器具有更高的刷新率并且实际上刷新时间超过了它们自己的驻留时间,所以这不应该发生;使用旧的模拟显示器,但它每次都会发生。

关于android - ML Kit 条码扫描未检测到显示器屏幕照片中的二维码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71694206/

相关文章:

android - 如何在inapp v3 android中获取订阅到期日期

java - 如何将 RecyclerView LayoutManager 从列表更改为网格?

android - Android 应用程序安装超时错误

android - 如何强制 Jacoco 在 Gradle 中使用特定版本

spring-boot - 如何调试,为什么Spring Boot集成测试上下文不会在测试之间重用?

ios - AVFoundation 无法扫描低对比度二维码

android - PowerMockito.whenNew 不适用于 android 的 Intent 类

kotlin - Kotlin 函数引用是否有一个简单的空安全运算符?

javascript - 使用来自 javascript 的输出 base64 创建 qrCode

windows-runtime - 用于 WinRT 的 QrCode 开源库