首先,我想说的是,我知道这里已经发布了很多类似的问题,但没有一个提供解释步骤和背后逻辑的答案——只是简单地指向不同的教程回购。
我已经浏览了几个展示如何做到这一点的演示回购。大多数解决方案都不同,但遗憾的是,它们包含 5 个类,代码非常复杂,可以完成如此简单的任务,所以我想寻找:
这就是我所拥有的。
最大的挑战是转换检测到的边界框坐标,以便在您将它们显示在
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
当前结果:
根据显示的内容,您似乎正在使用 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部分,其他忽略即可。我从整个代码库开始进行文本和人脸识别,只是去掉了我不想要的部分。