Dan*_*gel 8 3d boost quaternions point-clouds ply-file-format
我想阅读斯坦福兔子的未重建数据.点数据存储为多个范围图像,必须将其转换为组合成一个大点云,如README中所写:
These data files were obtained with a Cyberware 3030MS optical
triangulation scanner. They are stored as range images in the "ply"
format. The ".conf" file contains the transformations required to
bring each range image into a single coordinate system.
Run Code Online (Sandbox Code Playgroud)
这是.conf文件:
camera -0.0172 -0.0936 -0.734 -0.0461723 0.970603 -0.235889 0.0124573
bmesh bun000.ply 0 0 0 0 0 0 1
bmesh bun045.ply -0.0520211 -0.000383981 -0.0109223 0.00548449 -0.294635 -0.0038555 0.955586
bmesh bun090.ply 2.20761e-05 -3.34606e-05 -7.20881e-05 0.000335889 -0.708202 0.000602459 0.706009
bmesh bun180.ply 0.000116991 2.47732e-05 -4.6283e-05 -0.00215148 0.999996 -0.0015001 0.000892527
bmesh bun270.ply 0.000130273 1.58623e-05 0.000406764 0.000462632 0.707006 -0.00333301 0.7072
bmesh top2.ply -0.0530127 0.138516 0.0990356 0.908911 -0.0569874 0.154429 0.383126
bmesh top3.ply -0.0277373 0.0583887 -0.0796939 0.0598923 0.670467 0.68082 -0.28874
bmesh bun315.ply -0.00646017 -1.36122e-05 -0.0129064 0.00449209 0.38422 -0.00976512 0.923179
bmesh chin.ply 0.00435102 0.0882863 -0.108853 -0.441019 0.213083 0.00705734 0.871807
bmesh ear_back.ply -0.0829384 0.0353082 0.0711536 0.111743 0.925689 -0.215443 -0.290169
Run Code Online (Sandbox Code Playgroud)
对于每个范围图像,存储七个值.但我不知道,从这些价值中可以获得什么信息.我想其中三个将包含有关翻译的一些信息,也许三个包含有关旋转的信息.但我没有找到关于这些值的顺序以及如何转换值以获得一个点云的信息.
该wiki页面不与范围图像处理,我发现仅此而已在斯坦福页.他们只是说,Turk94的方法用于扫描这个数据集,但该方法没有关于所需转换的信息.(或者我无法从本文中获取信息.)
有人知道如何正确读取这些值吗?为什么相机位置会发生变化?这只是查看整点云的良好初始值吗?
谢谢你的帮助.
编辑:
好.此时,我已经尝试读取数据并正确转换它们,但一切都不起作用.我使用boost库来处理四元数
这是我的代码:
boost::math::quaternion<double> translation, quaternionRotation;
//Get Transformation
translation = boost::math::quaternion<double>(0.0, lineData[2].toDouble(), lineData[3].toDouble(), lineData[4].toDouble());
quaternionRotation = boost::math::quaternion<double>(lineData[5].toDouble(),lineData[6].toDouble(),lineData[7].toDouble(),lineData[8].toDouble());
//do some file related stuff
//...
//for each line: read the point data and transform it and store the point in a data array
pointData[j].x = stringPointData[0].toDouble();
pointData[j].y = stringPointData[1].toDouble();
pointData[j].z = stringPointData[2].toDouble();
tmpQuat = boost::math::quaternion<double> (0.0,pointData[j].x,pointData[j].y,pointData[j].z);
//first translation
tmpQuat += translation;
//then quaternion rotation
tmpQuat = (quaternionRotation * (tmpQuat) * boost::math::conj(quaternionRotation));
//read the data from quaternion to a usual type
pointData[j].x = tmpQuat.R_component_2();
pointData[j].y = tmpQuat.R_component_3();
pointData[j].z = tmpQuat.R_component_4();
Run Code Online (Sandbox Code Playgroud)
我假设四元数的第一个分量是w组件而其他组件是指的x,y并且z在这里从方程式2 开始.如有必要,我可以提供错误转换的屏幕截图.
编辑:它是在zipper.c文件的zipper源代码中编写的,7个值保存如下:
transX transY transZ quatX quatY quatZ quatW
Run Code Online (Sandbox Code Playgroud)
然后将四元数转换为旋转矩阵,然后使用该新矩阵执行旋转.但即使有这些信息,我也无法正确转换它.为了测试它,我在我的项目中从zipper实现了函数quat_to_mat():
glm::dmat4 cPlyObjectLoader::quat_to_mat(boost::math::quaternion<double> quat) const
{
float s;
float xs,ys,zs;
float wx,wy,wz;
float xx,xy,xz;
float yy,yz,zz;
glm::dmat4 mat(1.0);
s = 2 / (quat.R_component_2()*quat.R_component_2() +
quat.R_component_3()*quat.R_component_3() +
quat.R_component_4()*quat.R_component_4() +
quat.R_component_1()*quat.R_component_1());
xs = quat.R_component_2() * s;
ys = quat.R_component_3() * s;
zs = quat.R_component_4() * s;
wx = quat.R_component_1() * xs;
wy = quat.R_component_1() * ys;
wz = quat.R_component_1() * zs;
xx = quat.R_component_2() * xs;
xy = quat.R_component_2() * ys;
xz = quat.R_component_2() * zs;
yy = quat.R_component_3() * ys;
yz = quat.R_component_3() * zs;
zz = quat.R_component_4() * zs;
mat[0][0] = 1 - (yy + zz);
mat[0][1] = xy - wz;
mat[0][2] = xz + wy;
mat[0][3] = 0;
mat[1][0] = xy + wz;
mat[1][1] = 1 - (xx + zz);
mat[1][2] = yz - wx;
mat[1][3] = 0;
mat[2][0] = xz - wy;
mat[2][1] = yz + wx;
mat[2][2] = 1 - (xx + yy);
mat[2][3] = 0;
mat[3][0] = 0;
mat[3][1] = 0;
mat[3][2] = 0;
mat[3][3] = 1;
return mat;
}
Run Code Online (Sandbox Code Playgroud)
现在我正在使用向量和此矩阵进行平移和旋转:
quaternionRotation = boost::math::quaternion<double>(lineData[8].toDouble(),lineData[5].toDouble(),lineData[6].toDouble(),lineData[7].toDouble());
rotationMat = this->quat_to_mat(quaternionRotation);
translationVec = glm::dvec4(lineData[2].toDouble(), lineData[3].toDouble(), lineData[4].toDouble(),0.0);
//same stuff as above
//...
glm::dvec4 curPoint = glm::dvec4(pointData[j].x,pointData[j].y,pointData[j].z,1.0);
curPoint += translationVec;
curPoint = rotationMat*curPoint;
Run Code Online (Sandbox Code Playgroud)
结果与我的四元数旋转不同(为什么?它应该是相同的.),但不正确.
调试信息:
正如我从斯坦福3d扫描中读到的那样
对于所有斯坦福模型,使用修改后的ICP算法进行对齐,如本文所述.这些对齐存储在".conf"文件中,这些文件列出了模型中的每个范围图像以及平移和四元数旋转.
这是" 本文 " 的链接
编辑:这两种方法称为拉链和volmetric合并
正如埃洛所说,它是在斯坦福3D回购中写的:
对于所有斯坦福模型,使用修改后的ICP算法进行对齐,如本文所述.这些对齐存储在".conf"文件中,这些文件列出了模型中的每个范围图像以及平移和四元数旋转.
但这还不足以理解这个数据文件的所有内容.
这是正确的,第一行:
camera -0.0172 -0.0936 -0.734 -0.0461723 0.970603 -0.235889 0.0124573
Run Code Online (Sandbox Code Playgroud)
存储一个良好的初始摄像机位置,每隔一行开始bmesh指的是一个.ply存储远程图像的文件.
转换值存储如下:
transX transY transZ quatX quatY quatZ quatW
Run Code Online (Sandbox Code Playgroud)
where trans...指翻译值并quat...指四元数的值.目前,我不知道,为什么它不能单独使用四元数旋转,而是通过将其转换为带有拉链代码的旋转矩阵,转换是正确的.请注意,首先存储转换,但要获得正确的转换,必须在开始时进行旋转,然后在转换后进行.
我的代码片段用于读取文件并对其进行转换,如下所示:
boost::math::quaternion<double> translation, quaternionRotation;
//Get Transformation
translationVec = glm::dvec4(lineData[2].toDouble(), lineData[3].toDouble(), lineData[4].toDouble(),0.0);
quaternionRotation = boost::math::quaternion<double>(lineData[8].toDouble(),lineData[5].toDouble(),lineData[6].toDouble(),lineData[7].toDouble());
//calculate the unit quaternion
double magnitude = std::sqrt(
quaternionRotation.R_component_1()*quaternionRotation.R_component_1()+
quaternionRotation.R_component_2()*quaternionRotation.R_component_2()+
quaternionRotation.R_component_3()*quaternionRotation.R_component_3()+
quaternionRotation.R_component_4()*quaternionRotation.R_component_4());
quaternionRotation /= magnitude;
rotationMat = this->quat_to_mat(quaternionRotation);
//do some file related stuff
//...
//for each line: read the point data and transform it and store the point in a data array
pointData[j].x = stringPointData[0].toDouble();
pointData[j].y = stringPointData[1].toDouble();
pointData[j].z = stringPointData[2].toDouble();
//transform the curren point
glm::dvec4 curPoint = glm::dvec4(pointData[j].x,pointData[j].y,pointData[j].z,1.0);
//first rotation
curPoint = rotationMat*curPoint;
//then translation
curPoint += translationVec;
//store the data in a data array
pointData[j].x = curPoint.x;
pointData[j].y = curPoint.y;
pointData[j].z = curPoint.z;
Run Code Online (Sandbox Code Playgroud)
我知道,这不是最好的,但它有效.随意自己优化它.
| 归档时间: |
|
| 查看次数: |
886 次 |
| 最近记录: |