如何将Bundler的bundle.out格式转换为Meshlab的项目格式(.mlp)

时间:2019-04-05 12:31:42

标签: python meshlab

我正在使用MeshLab处理3D扫描,尤其是为网格赋予纹理。 我正在尝试使用命令行自动执行Meshlab的某些功能,并且meshlabserver可以很好地完成某些任务。但是,我使用bundle.out格式存储相机位置,并且似乎没有使用Meshlabserver打开bundle.out文件的选项。我需要从3D扫描中获取相机位置才能应用纹理。

我尝试通过使用Python脚本打开两个各自的文件并比较其中的格式,将bundle.out文件中的数据转换为.mlp文件,但是在编写脚本的过程中,我注意到即使对于同一台摄像机,两个文件也不包含完全相同的数据。特别是,bundle.out文件中包含的翻译向量与.mlp文件中的翻译向量不匹配。

这是我通过导入bundle.out文件在MeshLab中创建的.mlp文件的示例:

<!DOCTYPE MeshLabDocument>
<MeshLabProject>
 <MeshGroup/>
 <RasterGroup>
  <MLRaster label="IMG_1923.JPG">
   <VCGCamera TranslationVector="1.47497 -1.02971 3.11087 1" LensDistortion="0 0" CameraType="0" PixelSizeMm="1 1" ViewportPx="4032 3024" CenterPx="2016 1512" RotationMatrix="0.874226 0.050346 -0.482903 0 0.0346906 -0.998544 -0.0413029 0 -0.484279 0.0193558 -0.8747 0 0 0 0 1 " FocalMm="3345.59"/>
   <Plane semantic="1" fileName="images/IMG_1923.JPG"/>
  </MLRaster>
...

请注意“ TranslationVector”属性及其中的值。

这是用于创建.mlp文件的bundle.out文件:

# Bundle file v0.3
91 4888
3345.59 0.0177087 0
0.874226 0.050346 -0.482903
0.0346906 -0.998544 -0.0413029
-0.484279 0.0193558 -0.8747
-0.264628 0.950892 -3.4553
...

捆绑文件应解释如下:

# Bundle file v0.3
<number of images> <number of points>
<f> <k1> <k2>
<r_1,1> <r_1,2> <r_1,3>
<r_2,1> <r_2,2> <r_2,3>
<r_3,1> <r_3,2> <r_3,3>
<t_1> <t_2> <t_3>
...

其中: f:焦距 k1和k2:径向失真系数 r_i,j:旋转矩阵的元素 t_i:翻译向量元素

最后一行的三个值t_1,t_2和t_3是存储转换向量的位置。它与.mlp文件不匹配。这两个文件共有的所有其他值都匹配。

bundle.out文件格式规范的链接:http://www.cs.cornell.edu/~snavely/bundler/bundler-v0.3-manual.html#S6 (向下滚动到“ VI。输出格式和场景表示”)

我希望.mlp文件将包含与bundle.out文件相同的有关摄影机和栅格的信息,但是两个文件中不包含一个属性(转换向量)。

如果有人可以解释为什么存在差异,并且可能提供一种将bundle.out文件中的向量转换为.mlp文件中的向量的方法,将会很有帮助。

1 个答案:

答案 0 :(得分:0)

我找到了解决方法。

在深入研究MeshLab的源代码之后,我遇到了这个文件: https://github.com/cnr-isti-vclab/meshlab/blob/d596d7c086c51fbdfb56050f9c30b55dd0286d4c/src/meshlabplugins/filter_layer/filter_layer.cpp

从630行开始:

//// Import cameras
for (uint i = 0; i < num_cams; ++i)
{
    float f, k1, k2;
    float R[16] = { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1 };
    vcg::Point3f t;

    fgets(line, 100, fp);; if (line[0] == '\0') return false; sscanf(line, "%f %f %f", &f, &k1, &k2);

    fgets(line, 100, fp);; if (line[0] == '\0') return false; sscanf(line, "%f %f %f", &(R[0]), &(R[1]), &(R[2]));  R[3] = 0;
    fgets(line, 100, fp);; if (line[0] == '\0') return false; sscanf(line, "%f %f %f", &(R[4]), &(R[5]), &(R[6]));  R[7] = 0;
    fgets(line, 100, fp);; if (line[0] == '\0') return false; sscanf(line, "%f %f %f", &(R[8]), &(R[9]), &(R[10])); R[11] = 0;

    fgets(line, 100, fp);; if (line[0] == '\0') return false; sscanf(line, "%f %f %f", &(t[0]), &(t[1]), &(t[2]));

    Matrix44f mat = Matrix44f::Construct(Matrix44f(R));

    Matrix33f Rt = Matrix33f(Matrix44f(mat), 3);
    Rt.Transpose();

    Point3f pos = Rt * Point3f(t[0], t[1], t[2]);

    md.rasterList[i]->shot.Extrinsics.SetTra(Point3f(-pos[0], -pos[1], -pos[2]));
...
}

这是从Bundler的翻译向量到Meshlab的翻译向量发生的地方。

我从上面的代码中提取的信息如下:

将翻译矢量从bundle.out转换为.mlp的方法:

  1. 读取旋转矩阵(从bundle.out),存储为R
  2. 读取翻译矢量(来自bundle.out),存储为t
  3. 转置旋转矩阵R
  4. 将R乘以t,存储为pos
  5. 将pos设置为.mlp翻译向量

我在Python中测试了此食谱,输出结果与.mlp文件中的结果相同