我正在使用com.google.mlkit:barcode-scanning:17.0.2
检测图片中的QR码。
从图库中获取URI后,我创建InputImage
,然后使用BarcodeScanner
处理此图像以查找QR码。当我选择纸上QR码的照片时,找到了QR码。但当我拍摄监视器屏幕上QR码的照片时,却从未找到QR码。我应该做些什么才能在监视器屏幕的照片中检测到QR码?
- (当我使用与
CameraX
相同的扫描仪进行实时QR码检测时,它在监视器屏幕上找到代码)*
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
}
}
1条答案
按热度按时间ux6nzvsh1#
您很可能正在与Moiré effect对抗。根据QR检测算法的不同,Moiré效应引入的高频可能会使检测器偏离轨道。令人沮丧的是,通常是"更好"的QR码检测器被Moiré图案击败。
较好的解决方法是:
执行大致相同操作的另一种方法是
第二种方法的结果较差,但通常可以使用设备原语实现。
显示器的另一个问题来源(据我所见不在你的图片中)是刷新率,有时候,您会发现,二维码实际上是图片上半部分曝光过度的二维码,图片下半部分曝光不足的二维码,两者都无法识别,这种影响是由于显示器的刷新率和刷新策略造成的,不容易解决-您可以尝试降低显示器的亮度以增加曝光时间,直到超过1/50或1/25秒,或者从更远的地方拍摄照片并使用数字变焦。现代显示器具有更高的刷新率,实际上刷新时间超过其自身的停留时间,因此不应该发生这种情况;然而,使用旧的模拟显示器,每次都会发生这种情况。
∮第三种疯狂的方式∮
这是偶然发现的,但即使在廉价的硬件上也能很好地工作,只要QR SDK或库提供一些小的额外装饰。
1.以您能获得的最高帧速率(25 fps?)拍摄长度约为1秒的视频。
1.从中间(例如,第13帧),提取三个QR "路点"-SDK中可能有一个名为"containsQRCode"的低级函数()"执行此操作。如果它返回 * true *,找到航点并返回其坐标,以便执行定标/估计。它可能返回置信度图("此图片 * 似乎 * 包含概率为X %的QR码")。这些是应用程序用来在候选QR码周围显示边框或红点的API。如果您的SDK没有这些API,抱歉......您的运气不好。
1.获取之前和之后的帧(第12和14帧),然后是第11和15帧,依此类推。如果其中任何帧返回有效的QR码,则您可以高枕无忧。
1.如果在足够多的帧中找到QR码(即使没有正确解码),但航点坐标变化很大,则手不稳定-告诉用户。
1.如果你有足够多的坐标变化很小的帧,你可以在这些帧上居中和对齐,并平均帧。然后在生成的图像上运行真正的QRCode识别。这可以100%消除莫尔效应,并大幅减少显示器驻留噪声,几乎没有信息损失。结果比分辨率变化要好得多。这在分辨率改变时重置相机的(一些)设备上不容易执行。
这在一个19美元的ESP32物联网设备上工作,该设备在嘈杂、振动丰富的环境中运行(它从移动运输带上的纸箱的相机图像中获取QR代码)。