我正在使用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文件中的向量的方法,将会很有帮助。
答案 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的方法:
我在Python中测试了此食谱,输出结果与.mlp文件中的结果相同