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

Google Depth API报错及相机坐标深度距离计算问题排查

问题分析与解决方案

错误1:IndexOutOfBoundsException 越界异常

原因

  1. 坐标不匹配:你直接使用相机预览的屏幕坐标(如100,100或2219*1080范围内的值)访问深度图像,但ARCore深度图像的分辨率远低于相机预览分辨率,直接传入超出深度图像尺寸的x/y值必然触发越界。
  2. 字节索引计算错误:getMillimetersDepth中byteIndex的计算顺序颠倒,深度图像数据是行优先存储,应先计算y对应的行偏移,再叠加x对应的列偏移,你写反了x和y的位置,导致索引计算完全错误。

验证方式

可以先打印深度图像的实际尺寸确认:

val depthWidth = depthImage.width
val depthHeight = depthImage.height
Log.d("DepthSize", "width: $depthWidth, height: $depthHeight")

你会发现深度图像的宽高远小于2219*1080。

错误2:初始化地标不足异常

原因

该错误与深度获取代码无关,是ARCore视觉惯性初始化模块无法从当前环境中检测到足够的特征点(要求至少9个,实际为0)。通常触发场景:

  • 环境纹理极度单调(如纯白墙面、空房间)
  • 光线过暗/过强,导致特征点无法被识别
  • 相机快速移动,无法稳定捕捉环境特征

从相机坐标获取深度的正确方式

步骤1:将屏幕坐标转换为深度图像坐标

使用ARCore提供的transformCoordinates2d方法,将屏幕/相机预览坐标转换为深度图像的对应坐标,避免手动缩放的误差:

if (camera.trackingState == TrackingState.TRACKING && shouldGetDepthImage) {
    try {
        val depthImage = frame.acquireDepthImage16Bits()
        val point = render.point
        
        // 把屏幕坐标转为深度图像的对应坐标
        val inputCoords = floatArrayOf(point.x, point.y)
        val depthCoords = frame.transformCoordinates2d(
            Coordinates2d.COORDINATES_2D_NORMALIZED_SCREEN,
            inputCoords,
            Coordinates2d.COORDINATES_2D_IMAGE,
            depthImage
        )
        
        val depthX = depthCoords[0].toInt()
        val depthY = depthCoords[1].toInt()
        
        // 确保坐标在深度图像有效范围内
        if (depthX in 0 until depthImage.width && depthY in 0 until depthImage.height) {
            val depthValue = getMillimetersDepth(depthImage, depthX, depthY)
            Log.d("DepthValue", depthValue.toString())
        }

        backgroundRenderer.updateCameraDepthTexture(depthImage)
        depthImage.close()
    } catch (e: NotYetAvailableException) {
        // 深度数据暂不可用,无需处理
    }
}

步骤2:修正getMillimetersDepth函数的索引计算

调整字节索引的计算顺序为行优先:

/** Obtain the depth in millimeters for [depthImage] at coordinates ([x], [y]). */
fun getMillimetersDepth(depthImage: Image, x: Int, y: Int): Int {
    val plane = depthImage.planes[0]
    // 正确索引计算:行偏移(y * rowStride) + 列偏移(x * pixelStride)
    val byteIndex = y * plane.rowStride + x * plane.pixelStride
    val buffer = plane.buffer.order(ByteOrder.nativeOrder())
    val depthSample = buffer.getShort(byteIndex)
    // 注意:返回值为0表示该像素无有效深度数据
    return depthSample.toInt()
}

额外注意事项

  • 深度图像中返回的0值表示该像素无有效深度数据(如透明物体、超出检测范围),使用前需判断
  • 必须在调用depthImage.close()前完成所有深度数据的读取,避免资源泄漏
  • 针对错误2,可移动到纹理丰富的环境(如有图案的墙面、摆放物品的桌面),缓慢移动相机,让ARCore有足够时间检测特征点

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 02:40:00