Google Depth API报错及相机坐标深度距离计算问题排查
问题分析与解决方案
错误1:IndexOutOfBoundsException 越界异常
原因
- 坐标不匹配:你直接使用相机预览的屏幕坐标(如100,100或2219*1080范围内的值)访问深度图像,但ARCore深度图像的分辨率远低于相机预览分辨率,直接传入超出深度图像尺寸的x/y值必然触发越界。
- 字节索引计算错误:
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
相关产品推荐
相关产品推荐

