android - 从 DEPTH16 生成世界坐标点云
问题描述
在具有单独相机传感器和深度传感器的 android 设备上,我试图将 DEPTH16 输出映射到 ARcore 中可用的世界坐标点云。执行此操作所需的主要计算是将深度输出映射到主相机的坐标系(ARcore 可以从那里平移)。
据我了解,我需要应用深度相机内在函数(焦距、主点偏移等),然后将镜头姿势旋转应用于主相机坐标系统,然后应用解释深度传感器这一事实的平移距离相机镜头几毫米。这主要记录在相机特性 API 文档中,但在实践中似乎对我不起作用。
这就是我正在做的事情:
- 从深度传感器的 CameraCharacteristics 中提取内部函数、镜头姿态旋转和镜头姿态平移。这允许填充以下参数:
public class Intrinsics {
float width;
float height;
float focalLength;
// intrinsic matrix:
float f_x;
float f_y;
float c_x;
float c_y;
float s;
// lens pose rotation
float r_x;
float r_y;
float r_z;
float r_w;
// lens pose translation
float t_x;
float t_y;
float t_z;
}
- 应用内在转换。从传感器坐标系来看,假设我的右下角像素记录了 1m 的深度。这给出了 x, y, z 的 [239, 179, 1.00] 坐标。
如果我根据焦距和主要点执行以下算术,我似乎会得到看起来正确的输出:
double[] intrinsicAdjusted = new double[]{
(x - i.c_x) * depth / i.f_x,
(y - i.c_y) * depth / i.f_y,
depth
};
但是,我也尝试过使用 Camera2 文档中建议的转换矩阵(但相反,因为我想要相机到世界,而不是世界到相机):
Mat point = new Mat(3, 1, CvType.CV_32F);
point.put(0, 0, (double)x, (double)y, depth);
Mat K = new Mat(3, 3, CvType.CV_32F);
K.put(0,0,
i.f_x, i.s, i.c_x,
0, i.f_y, i.c_y,
0, 0, 1.0);
Mat Kinverse = K.inv();
Mat instrinsicAdjusted = new Mat(1, 3, CvType.CV_32F);
Core.gemm(Kinverse, point, 1, new Mat(), 0, instrinsicAdjusted, 0);
偏斜为零,所以我认为这些方法应该是一样的,但事实并非如此。
- 应用 API 文档建议的旋转将坐标更改为主相机的坐标。我从以下(使用 OpenCV)得到了非常虚假的结果:
Mat point = new Mat(3, 1, CvType.CV_32F);
point.put(0, 0, instrinsicAdjusted[0], instrinsicAdjusted[1], instrinsicAdjusted[2]);
Mat R = new Mat(3, 3, CvType.CV_32F);
R.put(0, 0,
1 - 2*(i.r_y*i.r_y) - 2*(i.r_z*i.r_z), 2*i.r_x*i.r_y - 2*i.r_z*i.r_w, 2*i.r_x*i.r_z + 2*i.r_y*i.r_w,
2*i.r_x*i.r_y + 2*i.r_z*i.r_w, 1 - 2*i.r_x*i.r_x - 2*i.r_z*i.r_z, 2*i.r_y*i.r_z - 2*i.r_x*i.r_w,
2*i.r_x*i.r_z - 2*i.r_y*i.r_w, 2*i.r_y*i.r_z + 2*i.r_x*i.r_w, 1 - 2*i.r_x*i.r_x - 2*i.r_y*i.r_y);
Mat rotated = new Mat(1, 3, CvType.CV_32F);
Core.gemm(R, point, 1, new Mat(), 0, rotated, 0);
- 如果事情在轮换中没有出错,大概翻译会起作用:
Mat translated = new Mat(3, 1, CvType.CV_32F);
translated.put(0, 0, i.t_x, i.t_y, i.t_z);
Core.add(translated, rotated, translated);
因此,这种总体方法是否正确?为什么我的内在调整会得到两个不同的结果?为什么轮换似乎不起作用?
解决方案
推荐阅读
- excel - Excel VBA 中有没有办法检查一个工作簿中的数字序列,找到最后一个,然后在另一个工作簿中继续?
- node.js - 一段时间后,Socket io 连接断开
- c# - 如何访问从asp.net核心中的jquery文件上传发送的附加表单数据?
- r - 如何在 R 中重现以下涉及 for 循环的 matlab 代码?
- php - 过滤 Laravel 资源集合有没有更好的方法
- cordova - 如何修复 Phonegap 中的“FCMPlugin Ready ERROR”?
- r - 如何在 dplyr 中改变 for 循环
- pandas - Pandas 不会将 EIA API 数据拆分为两个不同的列以便于访问
- python - 如何在 Python 3.7 中向 bytearray 添加字节?
- php - 在 PHP 表单中选中取消选中