簡體   English   中英

如何轉換相機圖像以在 tflite 中使用它

[英]How to convert camera image to use it in tflite

我在 Kotlin 中有一個 android 應用程序,它依賴於 CameraX 來分析圖像並將它們傳遞給 tensorflow 精簡圖像檢測 model(不是分類)。 問題是我們得到 YUV 或 RGBA Output 圖像,我們需要一個 argb bitmap 傳遞給 tflite model 來檢測我們已經苦苦掙扎了數周的物體,我們很快就有了截止日期,請幫忙。

    ImageAnalysis.Analyzer {
    private val supportedImages = listOf(ImageFormat.FLEX_RGBA_8888, ImageFormat.FLEX_RGB_888)
    private var data = ""

    @SuppressLint("UnsafeOptInUsageError")
    override fun analyze(image: ImageProxy) {
        if (image.format in supportedImages) {
            val options = ObjectDetector.ObjectDetectorOptions.builder()
                .setScoreThreshold(0.2F)
                .setBaseOptions(BaseOptions.builder().build())
                .build()
            val objectDetector =
                ObjectDetector.createFromFileAndOptions(
                    context, Model.createModel(context, "model.tflite").path, options
                )
            val bitmap = toBitmap(image)
            val tfImage = TensorImage.fromBitmap(bitmap)
            val results: List<Detection> = objectDetector.detect(tfImage)
            for (result in results) {
                val categories = result.categories
                for (category in categories) {
                    val label = category.label
                    val boundingBox = result.boundingBox
                    data += "label : $label | bounding : $boundingBox"
                }
            }
            listener(data)
            image.close()
        }
    }

    private fun toBitmap(image: ImageProxy): Bitmap {
        val r = image.planes[0].buffer.int
        val g = image.planes[1].buffer.int
        val b = image.planes[2].buffer.int
        val a = image.planes[3].buffer.int
        var color = Color.argb(a, r, g, b)
        val rect = Rect(0, 0, 1, 1)
        color = ColorUtils.compositeColors(color, Color.WHITE)
        val bitmap = Bitmap.createBitmap(rect.width(), rect.height(), Bitmap.Config.ARGB_8888)
        val canvas = Canvas(bitmap)
        val paint = Paint()
        paint.color = color
        canvas.drawRect(rect, paint)
        savePic(bitmap = bitmap!!, display_name = Random(100000L).toString())
        return bitmap
    }
    private fun savePic(bitmap: Bitmap, display_name: String): Boolean {
        val mediaCollection = latest {
            MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
        } ?: MediaStore.Images.Media.EXTERNAL_CONTENT_URI
        val contentValues = ContentValues().apply {
            put(MediaStore.Images.Media.DISPLAY_NAME, "${display_name}.jpg")
            put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg")
            put(MediaStore.Images.Media.WIDTH, bitmap.width)
            put(MediaStore.Images.Media.HEIGHT, bitmap.height)
        }
        return try {
            context.contentResolver.insert(mediaCollection, contentValues)?.also { uri ->
                context.contentResolver.openOutputStream(uri).use { outputStream ->
                    if (!bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream)) {
                        throw IOException("could not save bitmap!")
                    }
                }
            } ?: throw IOException("could not create media store entry")
            return true
        } catch (e: IOException) {
            e.printStackTrace()
            false
        }
    }

}```


這里是將YUV_420_888 imageproxy轉成argb格式的function bitmap。

我知道一個遲到的答案,但為其他人提供。

fun imageToBitmap(image: Image): Bitmap {
    val planes: Array<Image.Plane> = image.planes
    val yBuffer: ByteBuffer = planes[0].buffer
    val uBuffer: ByteBuffer = planes[1].buffer
    val vBuffer: ByteBuffer = planes[2].buffer
    val ySize = yBuffer.remaining()
    val uSize = uBuffer.remaining()
    val vSize = vBuffer.remaining()
    val nv21 = ByteArray(ySize + uSize + vSize)
    //U and V are swapped
    yBuffer[nv21, 0, ySize]
    vBuffer[nv21, ySize, vSize]
    uBuffer[nv21, ySize + vSize, uSize]
    val yuvImage = YuvImage(nv21, ImageFormat.NV21, image.width, image.height, null)
    val out = ByteArrayOutputStream()
    yuvImage.compressToJpeg(Rect(0, 0, yuvImage.width, yuvImage.height), 75, out)
    val imageBytes: ByteArray = out.toByteArray()
    return BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size)
}

從 cameraX 分析器向這個 function 提供圖像代理,它將提供 bitmap。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM