You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MLKit目标检测无法识别物体且无法绘制边界框求助

问题排查与修复

1. 未正确关闭ImageProxy(核心问题)

在ObjectDetectorProcessor的analyze方法中,仅在mediaImage为null时调用了imageProxy.close(),但MLKit检测成功或失败的回调中未关闭ImageProxy。这会阻塞CameraX的图像分析管道,导致后续帧无法被处理,表现为“无法识别物体”。

修复代码:

@SuppressLint("UnsafeOptInUsageError")
override fun analyze(imageProxy: ImageProxy) {
    val mediaImage = imageProxy.image ?: kotlin.run {
        Log.e(TAG, "Error: imageProxy null")
        imageProxy.close()
        return
    }

    val image = InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees)
    detector.process(image)
        .addOnSuccessListener { objectList ->
            listener(objectList, image.mediaImage?.cropRect!!)
            imageProxy.close() // 必须关闭图像代理
        }
        .addOnFailureListener {
            Log.e(TAG, "Error: ${it.message}", it)
            imageProxy.close() // 必须关闭图像代理
        }
}

2. 边界框坐标映射错误

GraphicOverlay.Graphics.calculateRect方法中,边界框的左右坐标被错误反转,导致绘制的框位置完全偏移(可能超出屏幕),看起来像是没有识别结果:

// 错误代码
val mappedBox = RectF().apply {
    left = boundingBoxT.right * scale + offsetX
    top = boundingBoxT.top * scale + offsetY
    right = boundingBoxT.left * scale + offsetX
    bottom = boundingBoxT.bottom * scale + offsetY
}

// 修复后
val mappedBox = RectF().apply {
    left = boundingBoxT.left * scale + offsetX
    top = boundingBoxT.top * scale + offsetY
    right = boundingBoxT.right * scale + offsetX
    bottom = boundingBoxT.bottom * scale + offsetY
}

3. 多物体检测模式未启用(按需修复)

从ScanFragment代码看,你传入了multiObjectMode参数但未在处理器中使用。如果需要检测多个物体,需在MLKit配置中启用该模式:

// 修改ObjectDetectorProcessor构造函数与配置
class ObjectDetectorProcessor(
    private val multiObjectMode: Boolean,
    private val listener: (MutableList<DetectedObject>, Rect) -> Unit
) : ImageAnalysis.Analyzer {

    private val options = ObjectDetectorOptions.Builder()
        .apply {
            setDetectorMode(ObjectDetectorOptions.STREAM_MODE)
            setMultipleObjectsEnabled(multiObjectMode) // 启用多物体检测
        }.build()

    // ... 其余代码
}

4. UI操作未切换到主线程

createOverlay中操作GraphicOverlay属于UI操作,而MLKit回调运行在后台线程,直接操作会导致异常或不生效,需切换到主线程执行:

private fun createOverlay(objectList: MutableList<DetectedObject>, rect: Rect) {
    requireActivity().runOnUiThread {
        binding.cameraPreviewGraphicOverlay.clear()
        objectList.forEach { detectedObject ->
            val overlayView = ObjectDetectorGraphic(binding.cameraPreviewGraphicOverlay, detectedObject, rect)
            binding.cameraPreviewGraphicOverlay.add(overlayView)
        }
    }
}

内容的提问来源于stack exchange,提问作者archisei

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 10:20:08