Преобразование ImageProxy в растровое изображение - PullRequest
2 голосов
/ 26 июня 2019

Итак, я хотел изучить новый Google Camera API - CameraX.Что я хочу сделать, так это снимать изображение с камеры и каждую секунду передавать его в функцию, которая принимает растровое изображение для целей машинного обучения.

Я прочитал документацию по Camera X Image Analyzer:

Сценарий использования анализа изображения предоставляет вашему приложению доступное для процессора изображение для обработки изображения, компьютерного зрения или компьютера.вывод на обучение.Приложение реализует метод Analyzer, который запускается в каждом кадре.

.., который в основном то, что мне нужно.Итак, я реализовал этот анализатор изображений следующим образом:

imageAnalysis.setAnalyzer { image: ImageProxy, _: Int ->
    viewModel.onAnalyzeImage(image)
}

Я получаю image: ImageProxy.Как я могу перевести это ImageProxy в Bitmap?

Я пытался решить это так:

fun decodeBitmap(image: ImageProxy): Bitmap? {
    val buffer = image.planes[0].buffer
    val bytes = ByteArray(buffer.capacity()).also { buffer.get(it) }
    return BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
}

Но он возвращает null - потому что decodeByteArray не получаетдействительные (?) битовые байты.Есть идеи?

1 Ответ

3 голосов
/ 28 июня 2019

Вам нужно будет проверить image.format, чтобы увидеть, если это ImageFormat.YUV_420_888. Если это так, то вы можете использовать это расширение для преобразования изображения в растровое изображение:

fun Image.toBitmap(): Bitmap {
    val yBuffer = planes[0].buffer // Y
    val uBuffer = planes[1].buffer // U
    val vBuffer = planes[2].buffer // V

    val ySize = yBuffer.remaining()
    val uSize = uBuffer.remaining()
    val vSize = vBuffer.remaining()

    val nv21 = ByteArray(ySize + uSize + vSize)

    //U and V are swapped
    yBuffer.get(nv21, 0, ySize)
    vBuffer.get(nv21, ySize, vSize)
    uBuffer.get(nv21, ySize + vSize, uSize)

    val yuvImage = YuvImage(nv21, ImageFormat.NV21, this.width, this.height, null)
    val out = ByteArrayOutputStream()
    yuvImage.compressToJpeg(Rect(0, 0, yuvImage.width, yuvImage.height), 50, out)
    val imageBytes = out.toByteArray()
    return BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size)
}

Это работает для меня.

...