Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何裁剪和调整矩形边界框内图像部分的大小?_Android_Kotlin_Tensorflow Lite_Android Camerax_Google Mlkit - Fatal编程技术网

Android 如何裁剪和调整矩形边界框内图像部分的大小?

Android 如何裁剪和调整矩形边界框内图像部分的大小?,android,kotlin,tensorflow-lite,android-camerax,google-mlkit,Android,Kotlin,Tensorflow Lite,Android Camerax,Google Mlkit,在使用CameraX和MLKit检测到人脸后,我需要将图像传递到一个自定义TFLite模型(我正在使用),该模型检测到一个面罩。该模型接受224x224像素的图像,因此我需要取出ImageProxy#getImage()对应于Face#getBoundingBox()的部分,并相应地调整其大小 我已经看到了可以使用的选项,但是ThumbnailUtils.extractThumbnailUtils()无法使用4个坐标的Rect,并且它相对于图像的中心,而人脸的边界框可能在其他位置 TFLite模

在使用CameraX和MLKit检测到人脸后,我需要将图像传递到一个自定义TFLite模型(我正在使用),该模型检测到一个面罩。该模型接受224x224像素的图像,因此我需要取出
ImageProxy#getImage()
对应于
Face#getBoundingBox()
的部分,并相应地调整其大小

我已经看到了可以使用的选项,但是
ThumbnailUtils.extractThumbnailUtils()
无法使用4个坐标的
Rect
,并且它相对于图像的中心,而人脸的边界框可能在其他位置

TFLite模型接受如下输入:

val inputFeature0 = TensorBuffer
    .createFixedSize(intArrayOf(1, 224, 224, 3), DataType.FLOAT32)
    .loadBuffer(/* the resized image as ByteBuffer */)
请注意,
ByteBuffer
的大小将为
224*224*3*4
字节(其中4是
DataType.FLOAT32.byteSize()


编辑:我已经清理了一些旧文本,因为它变得越来越难以理解。实际上是这样的:我只是忘记了删除我自己的一段代码,它已经将相同的
ImageProxy
转换为
Bitmap
,它一定导致一些内部缓冲区一直被读取到最后,所以要么需要手动倒带,要么完全删除无用的代码

但是,即使将
cropRect
应用于
ImageProxy
和底层的
图像
,生成的位图仍然是全尺寸的,因此必须执行其他操作。模型仍然返回
NaN
值,因此我将对原始输出进行一段时间的实验

fun hasMask(imageProxy: ImageProxy, boundingBox: Rect): Boolean {
    val model = MaskDetector.newInstance(context)
    val inputFeature0 = TensorBuffer.createFixedSize(intArrayOf(1, 224, 224, 3), DataType.FLOAT32)

    // now the cropRect is set correctly but the image itself isn't
    // cropped before being converted to Bitmap
    imageProxy.setCropRect(box)
    imageProxy.image?.cropRect = box

    val bitmap = BitmapUtils.getBitmap(imageProxy) ?: return false
    val resized = Bitmap.createScaledBitmap(bitmap, 224, 224, false)

    // input for the model
    val buffer = ByteBuffer.allocate(224 * 224 * 3 * DataType.FLOAT32.byteSize())
    resized.copyPixelsToBuffer(buffer)

    // use the model and get the result as 2 Floats
    val outputFeature0 = model.process(inputFeature0).outputFeature0AsTensorBuffer
    val maskProbability = outputFeature0.floatArray[0]
    val noMaskProbability = outputFeature0.floatArray[1]

    model.close()
    return maskProbability > noMaskProbability
}

在使用ML工具包时,我们将提供更好的方法来处理图像处理

目前,您可以尝试以下方法:


它会将ImageProxy转换为位图,并将其旋转为直立。人脸检测的边界框应直接应用于位图,这意味着您应该能够使用矩形边界框裁剪位图。

谢谢,我等不及CameraX未来的改进了。通过说“边界框应直接应用于位图”,您的意思是在使用
InputImage.fromBitmap()
调用
detector.process()
后,我必须执行
imageProxy.cropRect=boundingBox
并将
imageProxy
再次转换为位图?我肯定我没有得到什么东西,因为它看起来有点复杂。在修复了一些东西之后,你建议的代码终于工作了,但是图像仍然没有被裁剪。我已经用最近的更改更新了问题。
imageProxy.setCropRect(box)
不会为您裁剪图像。调整图像大小后,可以使用此方法裁剪带有检测到的边界框的图像。是的,我已经发现最好(可能也是唯一)的方法是从另一个分区创建一个新位图,如
val cropped=bitmap.createBitmap(bitmap,boundingbox.left,boundingbox.top,boundingbox.width(),boundingBox.height())
。您好,您可以看看我在这里给出的解决方案。它应该可以帮助您获得裁剪图像,而无需将其转换为位图。