Как преобразовать формат Bundler bundle.out в формат проекта Meshlab (.mlp) - PullRequest
0 голосов
/ 05 апреля 2019

Я использую MeshLab для обработки 3D-сканов, и в частности для придания сетке текстуры.Я пытаюсь автоматизировать некоторые функции Meshlab с помощью командной строки, и meshlabserver хорошо работает для некоторых задач.Тем не менее, я использую формат bundle.out для хранения положения камеры, и, похоже, нет возможности открыть файл bundle.out с помощью meshlabserver.Мне нужно получить положения камеры из моего 3D-сканирования, чтобы применить текстуру.

Я попытался преобразовать данные из файла bundle.out в файл .mlp, используя скрипт Python, открыв двасоответствующие файлы и сравнивая форматирование внутри, но в процессе написания скрипта я заметил, что два файла не содержат абсолютно одинаковые данные даже для одной и той же камеры.В частности, вектор перевода, содержащийся в файле bundle.out, не соответствует вектору перевода в файле .mlp.

Вот пример файла .mlp, который я создал в MeshLab путем импорта пакета.выходной файл:

<!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» и значения в нем.

Вот файл bundle.out, который использовался для создания файла .mlp:

# 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 голосов
/ 05 апреля 2019

Я нашел решение.

После копания в исходном коде 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]));
...
}

Здесь происходит преобразование вектора перевода Бундлера в вектор перевода Мешлаба.

Информация, которую я извлек из кода выше, была следующей:

Рецепт для преобразования вектора перевода из bundle.out в .mlp:

  1. читать матрицу вращения (из bundle.out), хранить как R
  2. читать вектор перевода (из bundle.out), хранить как t
  3. транспонировать матрицу вращения R
  4. Умножьте R-транспонированный на t, сохраните как pos
  5. установить pos в качестве вектора перевода .mlp

Я тестировал этот рецепт на Python, и вывод такой же, как в файле .mlp

...