I have an android app in Kotlin which depends on CameraX to analyze images and pass them to tensorflow lite image detection model ( not classification ). The problem is we get YUV or RGBA Output images and we need an argb bitmap to pass to tflite model to detect objects we have been struggling for weeks and we have a deadline soon help please.
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
}
}
}