【问题标题】:Why are these log statements not printing?为什么这些日志语句不打印?
【发布时间】:2021-12-13 22:13:45
【问题描述】:

我正在构建一个对象检测应用程序(在 Kotlin 中,用于 Android)。该应用程序使用 CameraX 来构建相机预览,并使用 Google ML 来提供机器学习专业知识。仅供参考;我使用了this CameraX 文档和这个this Google ML Kit 文档。

我目前正在尝试将Log.d("TAG", "onSuccess" + it.size) 打印到我的IDE 控制台,以确定.addonSuccessListener 是否正在实际运行。如果是这样,它应该打印一些类似于onSuccess1 的内容。然而,事实并非如此。事实上,它甚至没有从.addOnFailureListener 打印日志语句,这真的让我很困惑,因为我什至不完全确定 objectDetector 代码是否正在运行。真正让我困惑的是,我在Java中相对完成了同一个项目,并没有遇到过这个问题。

确实有人指出,在我的 YourImageAnalyzer.kt 类中,如果 mediaImage 为空,那么我将看不到任何日志记录。然而,在我自己调试时(这实际上是我第一次调试),我无法确定我这一段的第一句话是真是假。我想这个问题可能会引导我如何解决这个问题,并学习如何正确调试。

这是我的YourImageAnalyzer.kt 类,我还将在下面添加我的MainActivity.kt 类的代码。

YourImageAnalyzer.kt

private class YourImageAnalyzer : ImageAnalysis.Analyzer {

    override fun analyze(imageProxy: ImageProxy) {
        val mediaImage = imageProxy.image
        if (mediaImage != null) {
            val image =
                    InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees)

            val localModel = LocalModel.Builder()
                    .setAssetFilePath("mobilenet_v1_0.75_192_quantized_1_metadata_1.tflite")
                    .build()

            val customObjectDetectorOptions =
                    CustomObjectDetectorOptions.Builder(localModel)
                            .setDetectorMode(CustomObjectDetectorOptions.STREAM_MODE)
                            .enableClassification()
                            .setClassificationConfidenceThreshold(0.5f)
                            .setMaxPerObjectLabelCount(3)
                            .build()


            val objectDetector =
                    ObjectDetection.getClient(customObjectDetectorOptions)

            objectDetector           //Here is where the issue stems, with the following listeners
                    .process(image)
                    .addOnSuccessListener {
                        Log.i("TAG", "onSuccess" + it.size)
                        for (detectedObjects in it)
                        {
                            val boundingBox = detectedObjects.boundingBox
                            val trackingId = detectedObjects.trackingId
                            for (label in detectedObjects.labels) {
                                val text = label.text
                                val index = label.index
                                val confidence = label.confidence
                            }
                        }
                    }
                    .addOnFailureListener { e -> Log.e("TAG", e.getLocalizedMessage()) }
                    .addOnCompleteListener { it -> imageProxy.close() }
        }
    }
}

MainActivity.kt

class MainActivity : AppCompatActivity() {
    
    private lateinit var cameraProviderFuture: ListenableFuture<ProcessCameraProvider>
    override fun onCreate(savedInstanceState: Bundle?) {
        cameraProviderFuture = ProcessCameraProvider.getInstance(this)
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        cameraProviderFuture.addListener(Runnable {
            val cameraProvider = cameraProviderFuture.get()
            bindPreview(cameraProvider)
        }, ContextCompat.getMainExecutor(this))

    }

    fun bindPreview(cameraProvider: ProcessCameraProvider) {
        val previewView = findViewById<PreviewView>(R.id.previewView)
        var preview : Preview = Preview.Builder()
                .build()

        var cameraSelector : CameraSelector = CameraSelector.Builder()
                .requireLensFacing(CameraSelector.LENS_FACING_BACK)
                .build()

        preview.setSurfaceProvider(previewView.surfaceProvider)

        var camera = cameraProvider.bindToLifecycle(this as LifecycleOwner, cameraSelector, preview)
    }

}

【问题讨论】:

  • 您是否验证了是否调用了 analyze() 方法或者 mediaImage 是否为空?您可以添加一些日志来检查。如果你能看到日志告诉 mediaImage 不为空,你看到了多少次?如果您的相机设置正确,您应该会经常看到它,因为相机正在运行。
  • 您也可以检查您的 adb 日志,看看是否有任何其他错误。我注意到您正在使用自定义模型。如果模型无效,则 ML Kit 检测器将无法创建。在这种情况下,您应该会看到一些提到“MlKitException”的日志
  • @Steven 我确实只是验证了analyze() 方法是否已被调用,或者不仅发现它确实没有被调用。这让我想知道为什么会这样。但是,相机运行良好。
  • 在这种情况下,主要是 CameraX 设置问题。您可以尝试将 android-camerax 标签添加到您的问题中以寻求更多帮助。 stackoverflow.com/questions/tagged/android-camerax

标签: kotlin debugging logging android-camerax google-mlkit


【解决方案1】:

您没有绑定您的 ImageAnalysis 用例。类似的东西:

val imageAnalysis = ImageAnalysis.Builder()
    .setTargetResolution(Size(1280, 720))
    .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
    .setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_RGBA_8888)
    .build()

然后;

imageAnalysis.setAnalyzer(executor, YourImageAnalyzer())

cameraProvider.bindToLifecycle(this as LifecycleOwner, cameraSelector, imageAnalysis, preview)

还有一个建议作为奖励: 您应该从analyze 中取出您的LocalModel.Builder(),因为每次图像到达时都会调用它。您不需要每次都执行此代码段,因为它会使您的分析变慢。 所以移动这段代码:

val localModel = LocalModel.Builder()
                    .setAssetFilePath("mobilenet_v1_0.75_192_quantized_1_metadata_1.tflite")
                    .build()

到班级的正下方private class YourImageAnalyzer : ImageAnalysis.Analyzer {

【讨论】:

  • 一个简单的问题; executor 显示为红色,说明它是一个未解决的引用,那么解决这个问题的方法是什么?除此之外,其他一切都检查出来!
  • Executors.newSingleThreadExecutor()
  • 所以我已经尝试诊断这个问题已经有一段时间了,但是虽然你的所有代码确实都已经实现了,但问题仍然存在。我放在 OP 中的日志语句仍然没有打印出来。你知道原因吗?
  • 我会将日志移动到override fun analyze(imageProxy: ImageProxy) { 的开头,以查看是否调用了分析方法。如果它被打印出来,那么你的代码会在某处失败。如果它仍然没有打印,那么它可能是你可能遗漏的一个小细节。那么我建议你按照这个分步教程进行操作:developer.android.com/codelabs/camerax-getting-started#0
  • 在将日志移到开头查看是否调用了analyze方法后,我发现它实际上一直没有被调用。但是,是的,我会按照本教程来解决这个问题,谢谢!
猜你喜欢
  • 1970-01-01
  • 2020-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-07
  • 1970-01-01
  • 2017-08-07
  • 2010-11-06
相关资源
最近更新 更多