如何解决从DEPTH16生成世界坐标点云
在具有单独的摄像头传感器和深度传感器的android设备上,我试图将DEPTH16输出映射到ARcore中可用的世界坐标点云。为此,需要进行的主要计算是将深度输出映射到主相机的坐标系(ARcore可以从那里进行平移)。
据我了解,我需要应用深度相机的内在函数(焦距,主点偏移等),然后将镜头姿势旋转应用于主相机的配准系统,然后应用平移,这说明了以下事实:深度传感器距离相机镜头只有几毫米。大部分记录在Camera Characteristics 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,(double)x,(double)y,depth);
Mat K = new Mat(3,3,CvType.CV_32F);
K.put(0,i.f_x,i.s,i.c_x,i.f_y,i.c_y,1.0);
Mat Kinverse = K.inv();
Mat instrinsicAdjusted = new Mat(1,CvType.CV_32F);
Core.gemm(Kinverse,point,new Mat(),instrinsicAdjusted,0);
偏度为零,所以我认为这些方法应该能达到相同的效果,但事实并非如此。
- 应用API文档建议的旋转,以将坐标更改为主要摄像机的坐标。我从以下(使用OpenCV)获得非常虚假的结果:
Mat point = new Mat(3,instrinsicAdjusted[0],instrinsicAdjusted[1],instrinsicAdjusted[2]);
Mat R = new Mat(3,CvType.CV_32F);
R.put(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,CvType.CV_32F);
Core.gemm(R,rotated,0);
- 如果轮换中没有出现异常,则推测翻译可以正常工作
Mat translated = new Mat(3,CvType.CV_32F);
translated.put(0,i.t_x,i.t_y,i.t_z);
Core.add(translated,translated);
因此,这种整体方法正确吗?为什么对于内部调整我会得到两个不同的结果?为什么轮换似乎不起作用?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com(将#修改为@)