ML Kit条形码扫描性能差

4

我正在使用谷歌的ML Kit进行条形码扫描,并从谷歌提供的示例和教程中收集了下面的代码。然而,性能非常低下;需要几秒钟,可以是10、15秒,才能识别出一个条形码。是否有任何方法可以改善这种情况?

此外,如何用于反转的条形码?我发现需要反转图像,但如果在分析器中尝试获取image.bitmapInternal或image.byteBuffer,则始终为null。

Build.gradle

 implementation 'com.google.mlkit:barcode-scanning:17.0.0'
 // CameraX core library using camera2 implementation
implementation "androidx.camera:camera-camera2:1.0.2"
// CameraX Lifecycle Library
implementation "androidx.camera:camera-lifecycle:1.0.2"
// CameraX View class
implementation "androidx.camera:camera-view:1.0.0-alpha31"

然后,在一个片段中:

typealias BarCodeListener = (barCode: String) -> Unit
const val TAG = "ConnectorScanner"
[...]

override fun onResume() {
    super.onResume()
    cameraExecutor = Executors.newSingleThreadExecutor()
    startCamera()
}

private fun startCamera() {
    val cameraProviderFuture = ProcessCameraProvider.getInstance(requireContext())
    val resolution = Size(720, 1280)
    cameraProviderFuture.addListener({
        // Used to bind the lifecycle of cameras to the lifecycle owner
        val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()

        // Preview
        val preview = Preview.Builder()
            .setTargetResolution(resolution)
            .build()
            .also {
                it.setSurfaceProvider(binding.viewFinder.surfaceProvider)
            }

        imageCapture = ImageCapture.Builder()
            .setTargetResolution(resolution)
            .setCaptureMode(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY)
            .build()

        val imageAnalyzer = ImageAnalysis.Builder()
            .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
            .build()
            .also {
                it.setAnalyzer(cameraExecutor, BarCodeAnalyzer { barCode ->
                    if (BuildConfig.DEBUG) {
                        Toast.makeText(context, "Code: $barCode", Toast.LENGTH_LONG).show()
                    }
                    viewModel.onConnectorCodeScanned(barCode)
                    cameraProvider.unbindAll()
                })
            }

        // Select back camera as a default
        val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA

        try {
            // Unbind use cases before rebinding
            cameraProvider.unbindAll()

            // Bind use cases to camera
            cameraProvider.bindToLifecycle(
                this, cameraSelector, preview, imageCapture, imageAnalyzer
            )

        } catch (exc: Exception) {
            Log.e(TAG, "Use case binding failed", exc)
            showErrorDialog()
        }

    }, ContextCompat.getMainExecutor(requireContext()))
}

图像分析器
private class BarCodeAnalyzer(private val listener: BarCodeListener) : ImageAnalysis.Analyzer {
    val options = BarcodeScannerOptions.Builder()
        .setBarcodeFormats(
            Barcode.FORMAT_DATA_MATRIX
        )
        .build()

    @SuppressLint("UnsafeOptInUsageError")
    override fun analyze(imageProxy: ImageProxy) {
        val mediaImage = imageProxy.image
        mediaImage?.let {
            val image =
                InputImage.fromMediaImage(it, imageProxy.imageInfo.rotationDegrees)
                val scanner = BarcodeScanning.getClient(options)

            scanner.process(image)
                .addOnSuccessListener { barcodes ->
                    if (barcodes.isNotEmpty()) {
                        barcodes.firstOrNull()?.rawValue?.let { barcode ->
                            Log.d(TAG, barcode)
                            listener(barcode)
                        }
                        imageProxy.close()
                    }
                }
        }
        imageProxy.close()
    }
}

你可以在这里查看我的QR码示例 - https://dev59.com/klIG5IYBdhLWcg3wig8k#64504871。条形码也是非常相似的。 - Siddharth Kamaria
3个回答

8

有些幸运的是,我找到了解决性能问题的方法,即添加OnCompleteListener并在那里关闭图像。这样分析器就会

scanner.process(image)
                .addOnSuccessListener { barcodes ->
                    if (barcodes.isNotEmpty()) {
                        barcodes.firstOrNull()?.rawValue?.let { barcode ->
                            Log.d(TAG, barcode)
                                listener(barcode)
                        }
                    }
                }
                .addOnCompleteListener {
                    imageProxy.close()
                }
        }

现在条形码扫描速度非常快!


这个对我有用,非常感谢Bruce Wayne。 - Funyinoluwa Kashimawo

1

像这样使用图像处理。

scanner.process(InputImage.fromBitmap(image.toBitmap(), image.imageInfo.rotationDegrees))
                .addOnSuccessListener { barcodes ->
                    if (barcodes.isNotEmpty()) {
                        barcodes.firstOrNull()?.rawValue?.let { barcode ->
                            Log.d(TAG, barcode)
                                listener(barcode)
                        }
                    }
                }
                .addOnCompleteListener {
                    imageProxy.close()
                }
        }

在处理完像下面的代码中的图片后,请关闭图像代理。

imageProxy.close()

-1

无论 @布鲁斯·韦恩建议什么都是有效的!!!

.addOnCompleteListener {
    imageProxy.close()
 }


你应该删除答案,转而点赞并接受Bruce的答案。 - MrMikimn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接