You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何借助AndroidX Camera库将ImageProxy转换为深度图?

问题描述

我使用Google的androidx.camera:camera-*类库实现了Bitmap生成功能,编写的代码如下:

internal fun ImageProxy.useAndConvertToBitmap(): Bitmap{
    use {
        val imageRotationDegrees = imageInfo.rotationDegrees.toFloat()
        val bitmap = image!!.toBitmap()
        return bitmap.rotate(imageRotationDegrees)
    }
}

internal fun Image.toBitmap(): Bitmap {
    val yBuffer = planes[0].buffer // Y
    val vuBuffer = planes[2].buffer // VU

    val ySize = yBuffer.remaining()
    val vuSize = vuBuffer.remaining()

    val nv21 = ByteArray(ySize + vuSize)

    yBuffer.get(nv21, 0, ySize)
    vuBuffer.get(nv21, ySize, vuSize)

    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)
}

现在我需要为业务需求获取深度图,请问是否可以通过该类库实现ImageProxy到深度图的转换?

解答

可以通过androidx.camera:camera-*类库实现ImageProxy到深度图的转换,但需要满足前提条件并遵循特定的转换逻辑:

  • 前提条件
    设备必须支持深度采集硬件(如TOF镜头、双摄深度模组),同时在CameraX配置阶段要开启深度数据输出:

    1. 用CameraSelector指定支持深度输出的相机;
    2. 在ImageCapture或ImageAnalysis的配置中添加深度格式(如ImageFormat.DEPTH16、ImageFormat.DEPTH_POINT_CLOUD)的输出选项。
  • 核心转换逻辑
    深度图的像素数据通常为单平面存储,以DEPTH16格式为例,每个像素是16位的毫米级深度值,需要将其映射为可显示的Bitmap格式(如灰度图):

    internal fun ImageProxy.useAndConvertToDepthBitmap(): Bitmap? {
        use {
            // 先判断是否为深度格式
            if (image?.format != ImageFormat.DEPTH16) {
                return null
            }
            val depthPlane = image!!.planes[0]
            val depthBuffer = depthPlane.buffer
            val depthBytes = ByteArray(depthBuffer.remaining())
            depthBuffer.get(depthBytes)
    
            // 创建ARGB格式Bitmap,将16位深度值映射为灰度
            val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
            val pixels = IntArray(width * height)
            val pixelStride = depthPlane.pixelStride
            val rowStride = depthPlane.rowStride
    
            for (y in 0 until height) {
                for (x in 0 until width) {
                    val bufferIndex = y * rowStride + x * pixelStride
                    // 解析16位深度值
                    val depthValue = (depthBytes[bufferIndex].toInt() shl 8) or (depthBytes[bufferIndex + 1].toInt() and 0xFF)
                    // 将深度值归一化到0-255灰度范围(可根据硬件参数调整映射逻辑)
                    val gray = (depthValue / 65535f * 255).toInt()
                    pixels[y * width + x] = Color.argb(255, gray, gray, gray)
                }
            }
            bitmap.setPixels(pixels, 0, width, 0, 0, width, height)
            // 处理图像旋转
            return bitmap.rotate(imageInfo.rotationDegrees.toFloat())
        }
    }
    
  • 注意事项

    • 不同设备的深度格式可能不同:DEPTH_POINT_CLOUD格式输出的是点云数据(含X/Y/Z坐标),解析逻辑与DEPTH16完全不同;
    • 深度值的有效范围因硬件而异,需要根据设备参数调整灰度映射比例,避免显示失真;
    • 配置CameraX时需同时请求普通图像与深度图像输出,确保ImageProxy能获取到深度数据。

内容的提问来源于stack exchange,提问作者Svetl9chok

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 20:00:58