【问题标题】:how to select a portion of the image when using CameraX analyze使用 CameraX 分析时如何选择图像的一部分
【发布时间】:2019-10-12 09:19:05
【问题描述】:

我使用 CameraX,然后使用 FirebaseVision 从图像中读取一些文本。当我分析图像时,我想选择图像的一部分,而不是整个图像,就像使用条形码扫描仪时一样。

class Analyzer : ImageAnalysis.Analyzer {
    override fun analyze(imageProxy: ImageProxy?, rotationDegrees: Int) {

        // how to crop the image in here?

        val image = imageProxy.image
        val imageRotation = degreesToFirebaseRotation(degrees)
        if (image != null) {
        val visionImage = FirebaseVisionImage.fromMediaImage(image, imageRotation)
        val textRecognizer = FirebaseVision.getInstance().onDeviceTextRecognizer
        textRecognizer.processImage(visionImage)
    }
}

我想知道,有什么办法可以裁剪图片吗?

【问题讨论】:

  • 这方面有什么进展吗?我被困在同一点上。我尝试imageProxy.setCropRect,但图像没有被裁剪。

标签: android kotlin firebase-mlkit android-camerax


【解决方案1】:

你的问题正是我 2 个月前解决的问题......

object YuvNV21Util {

    fun yuv420toNV21(image: Image): ByteArray {
        val crop = image.cropRect
        val format = image.format
        val width = crop.width()
        val height = crop.height()
        val planes = image.planes
        val data =
            ByteArray(width * height * ImageFormat.getBitsPerPixel(format) / 8)
        val rowData = ByteArray(planes[0].rowStride)
        var channelOffset = 0
        var outputStride = 1
        for (i in planes.indices) {
            when (i) {
                0 -> {
                    channelOffset = 0
                    outputStride = 1
                }
                1 -> {
                    channelOffset = width * height + 1
                    outputStride = 2
                }
                2 -> {
                    channelOffset = width * height
                    outputStride = 2
                }
            }
            val buffer = planes[i].buffer
            val rowStride = planes[i].rowStride
            val pixelStride = planes[i].pixelStride
            val shift = if (i == 0) 0 else 1
            val w = width shr shift
            val h = height shr shift
            buffer.position(rowStride * (crop.top shr shift) + pixelStride * (crop.left shr shift))
            for (row in 0 until h) {
                var length: Int
                if (pixelStride == 1 && outputStride == 1) {
                    length = w
                    buffer[data, channelOffset, length]
                    channelOffset += length
                } else {
                    length = (w - 1) * pixelStride + 1
                    buffer[rowData, 0, length]
                    for (col in 0 until w) {
                        data[channelOffset] = rowData[col * pixelStride]
                        channelOffset += outputStride
                    }
                }
                if (row < h - 1) {
                    buffer.position(buffer.position() + rowStride - length)
                }
            }
        }
        return data
    }
}

然后将字节数组转换为位图

object BitmapUtil {
    fun getBitmap(data: ByteArray, metadata: FrameMetadata): Bitmap {

        val image = YuvImage(
            data, ImageFormat.NV21, metadata.width, metadata.height, null
        )
        val stream = ByteArrayOutputStream()
        image.compressToJpeg(
            Rect(0, 0, metadata.width, metadata.height),
            80,
            stream
        )
        val bmp = BitmapFactory.decodeByteArray(stream.toByteArray(), 0, stream.size())
        stream.close()
        return rotateBitmap(bmp, metadata.rotation, false, false)
    }

    private fun rotateBitmap(
        bitmap: Bitmap, rotationDegrees: Int, flipX: Boolean, flipY: Boolean
    ): Bitmap {
        val matrix = Matrix()

        // Rotate the image back to straight.
        matrix.postRotate(rotationDegrees.toFloat())

        // Mirror the image along the X or Y axis.
        matrix.postScale(if (flipX) -1.0f else 1.0f, if (flipY) -1.0f else 1.0f)
        val rotatedBitmap =
            Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)

        // Recycle the old bitmap if it has changed.
        if (rotatedBitmap != bitmap) {
            bitmap.recycle()
        }
        return rotatedBitmap
    }
}

请查看我的开源项目https://github.com/minkiapps/Firebase-ML-Kit-Scanner-Demo,我构建了一个演示应用程序,其中图像代理的一部分在由 ml 套件处理之前被裁剪。

【讨论】:

  • 问题是关于裁剪的。这是在您发布的代码中实现的?
  • checkout YuvNV21Util,从image proxy中取出图片并裁剪croprect类的部分,字节数组输出可以转换成位图,也就是代码sn- p 下面。
猜你喜欢
  • 1970-01-01
  • 2020-09-26
  • 2011-09-23
  • 1970-01-01
  • 1970-01-01
  • 2020-09-30
  • 2011-01-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多