boost - 如何读取/转换 stanford bunny .ply-files 的范围图像?

标签 boost 3d quaternions point-clouds ply-file-format

我想从 Stanford Bunny 中读取未重建的数据.点数据存储为多个范围图像,必须将其转换为一个大的点云,如自述文件中所写:

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.

这是 .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

对于每个距离图像,存储了七个值。但是我不知道,从这些值中可以得到什么信息。
我猜其中三个将包含一些有关平移的信息,也许三个包含有关旋转的信息。但是我没有找到有关这些值的顺序以及如何转换这些值以获得一个点云的信息。

wiki page不处理范围图像,我在斯坦福页面上找不到更多内容。他们只是说,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();

我假设四元数的第一个分量是 w组件等引用x , yz就像来自 here 的等式 2 .如有必要,我可以提供错误转换的屏幕截图。

编辑:它写在zipper.c文件中zipper的源代码中,7个值保存如下:
transX transY transZ quatX quatY quatZ quatW

然后将四元数转换为旋转矩阵,然后使用这个新矩阵执行旋转。但即使有了这些信息,我也无法正确转换它。为了测试它,我在我的项目中从 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;
}

现在我正在用一个向量和这个矩阵进行平移和旋转:
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;

结果与我的四元数旋转不同(为什么?应该是一样的。),但不正确。

调试信息:
  • 所有变换的输入都是正确的
  • 所有点输入正确
  • 最佳答案

    正如我从 stanford 3d scan 读到的

    For all the Stanford models, alignment was done using a modified ICP algorithm, as described in this paper. These alignments are stored in ".conf" files, which list each range image in the model along with a translation and a quaternion rotation.



    这是“this paper”的链接

    编辑:这两种方法称为 zipper 和 volmetric merging

    关于boost - 如何读取/转换 stanford bunny .ply-files 的范围图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30783446/

    相关文章:

    c++ - Boost asio - udp 服务器

    c++ - 生成时CMake错误。项目使用Boost库

    python - 3D 旋转

    3d - 我可以在 Three.js 中让圆柱体发光,使其看起来像管灯吗?

    c++ - 将 2D 位图转换为 3D 立方体模型的有效方法?

    opengl - 将四元数旋转转换为旋转矩阵?

    c++ - 在两个四元数之间插值很长

    c++ - FastCGI 和 boost::asio 用于单元测试

    c++ - boost - timed_wait 不等待

    c++ - OpenGL 中的 3 轴四元数旋转