对象检测 - 使用边界框在对象周围绘制矩形

问题描述 投票:0回答:1

首先,我想说的是,我知道这里已经发布了很多类似的问题,但没有一个提供解释步骤和背后逻辑的答案——只是简单地指向不同的教程回购。

我已经浏览了几个展示如何做到这一点的演示回购。大多数解决方案都不同,但遗憾的是,它们包含 5 个类,代码非常复杂,可以完成如此简单的任务,所以我想寻找:

  1. 满足需要的解决方案 - 在实时提要运行时围绕检测到的对象(多个)绘制矩形
  2. 代码要简洁、优雅、易懂
  3. 我也很想了解它背后的逻辑(这在演示回购中是不可能的)

这就是我所拥有的。

最大的挑战是转换检测到的边界框坐标,以便在您将它们显示在

Preview
上时它们有意义。
Preview
图像与输入图像的大小不同,因此应相应调整坐标。

现在,我有一个问题是绘制矩形时出现巨大错误(矩形偏离实际对象,因此坐标计算不正确)。

override fun draw(canvas: Canvas) {
    super.draw(canvas)

    // Get the dimensions of the preview image
    val previewWidth = previewImageSize.width
    val previewHeight = previewImageSize.height

    // Get the dimensions of the input image
    val inputWidth = inputImageSize.width
    val inputHeight = inputImageSize.height

    // Calculate the scaling factor for each dimension
    val scaleX: Float = previewWidth.toFloat() / inputWidth.toFloat()
    val scaleY: Float = previewHeight.toFloat() / inputHeight.toFloat()

    for (result in results) {
        val boundingBox = result.boundingBox

        val left = boundingBox.left * scaleX
        val top = boundingBox.top * scaleY
        val right = boundingBox.right * scaleX
        val bottom = boundingBox.bottom * scaleY

        // Draw bounding box around detected objects
        val drawableRect = RectF(left, top, right, bottom)
        canvas.drawRect(drawableRect, boxPaint)

        // Create text to display alongside detected objects
        val drawableText =
            result.categories[0].label + " " +
                    String.format("%.2f", result.categories[0].score)

        // Draw rect behind display text
        textBackgroundPaint.getTextBounds(drawableText, 0, drawableText.length, bounds)
        val textWidth = bounds.width()
        val textHeight = bounds.height()
        canvas.drawRect(
            left,
            top,
            left + textWidth + BOUNDING_RECT_TEXT_PADDING,
            top + textHeight + BOUNDING_RECT_TEXT_PADDING,
            textBackgroundPaint
        )

        // Draw text for detected object
        canvas.drawText(drawableText, left, top + bounds.height(), textPaint)
    }
}

附加信息:

输入图像大小:

320x320
(通过模型内部传递的预览调整图像大小以获得结果)

预览尺寸:

1857x1080
(1857为身高)

从 CameraX 接收到的 ImageAnalsys 图像:W:640, H:480

计算。 ScaledX 值:

3.375

计算。缩放 Y 值:

5.803125

当前结果:

android kotlin object-detection object-detection-api bounding-box
1个回答
0
投票

根据显示的内容,您似乎正在使用 MLKit 对象检测,或者与 TensorFlow 类似的变体。

绝对推荐阅读: https://developers.google.com/ml-kit/vision/object-detection/android https://developers.google.com/ml-kit/vision/object-detection/custom-models/android

接下来,在您的具体示例中,问题似乎是缩放到错误的图像。

如您所见,图像分析图像实际上是 640x480,然后使用类似的方法将其调整为 320x320:

InputImage image = InputImage.fromMediaImage(
    mediaImage,imageProxy.getImageInfo().getRotationDegrees()
);

但是,没有提供细节。

之后,您将缩放到 1080x1857 图像,而不是 640x480。这些结果看起来与您看到的失真相似。如果相对于 640x480 进行缩放,则框的宽度为 60%,高度为 26%。基本上,一个不太能装柠檬的小盒子。

另请注意,它可能正在为您执行自动旋转校正。

如果您正在寻找一个“相当”简单的实现,那么: https://github.com/googlesamples/mlkit/tree/master/android/vision-quickstart

比较轻,只要只关注Object Detection部分,其他忽略即可。我从整个代码库开始进行文本和人脸识别,只是去掉了我不想要的部分。

© www.soinside.com 2019 - 2024. All rights reserved.