Как создать разные решающие блоки для одного и того же решения в Ceres?

Я хочу использовать Церера рассчитать координаты треугольника.

Для задачи мне нужно решить для координат сетки в сетке. Каждый треугольник имеет свои вершины, но доступна структура, такая как треугольники (3 вершины) и ребра (4 вершины).

Пример данных (псевдокод):

triangles = [[v1, v2, v3], [v4, v5, v6]]
inner_edges = [[[v1, v4], [v2, v5]]]

Края [v1, v2] а также [v4, v5] изначально одинаковы, которые могут измениться при решении.

Теперь у меня есть две функции стоимости, одна на треугольниках и одна на внутренних краях

f([v1, v2, v3]) = res_t1
g([v1, v4, v2, v5]) = res_2

Есть две простые блочные структуры

  • Два блока, один со всеми остатками треугольника, один со всеми ребрами остатка.
  • Один блок на треугольник и один блок на ребра.

Первый решает для вектора x со всеми координатами (2*|V| поскольку каждая вершина имеет две координаты), так как блоки зависят от всех вершин. Во втором случае блоки треугольников должны зависеть только от трех вершин, а блоки ребер — от четырех вершин.
Теперь я хочу использовать второй, так как ожидаю лучшей производительности и лучшей конвергенции.

Как мне настроить ceres для решения тех же координат, но только с учетом подмножества вершин, соответствующих текущему остатку?

Я попытался установить проблему с размерами 6 и 8 и указателем в нужном месте в x, но ceres не позволяет использовать один и тот же указатель результата с другим смещением.

Далее я попытался использовать SubsetParameterization например вот так

vector<double> x(mesh.n_faces()*6);
for(int i=0; i < mesh.n_faces(); i++){
vector<int> const_params;
for(int j = 0; j < mesh.n_faces(); j++) {
if(i != j) {
const_params.push_back(6*j);
const_params.push_back(6*j+1);
const_params.push_back(6*j+2);
const_params.push_back(6*j+3);
const_params.push_back(6*j+4);
const_params.push_back(6*j+5);
}
}
//auto *ssp = new ceres::SubsetParameterization(6, const_params); // (1)
auto *ssp = new ceres::SubsetParameterization(mesh.n_faces() * 6, const_params); // (2)
problem.AddParameterBlock(x.data(), mesh.n_faces() * 6, ssp);
problem.AddResidualBlock(face_cost_function, NULL, x.data());
}

Но черешние проверки говорят мне, что оба варианта неверны.

за (1) я получаю

local_parameterization.cc:98 Check failed: constant.back() < size Indices indicating constant parameter must be less than the size of the parameter block.

и за (2) я получаю

problem_impl.cc:135 Check failed: size == existing_size Tried adding a parameter block with the same double pointer, 000002D736397260, twice, but with different block sizes. Original size was 1152 but new size is 6

Как мне установить ceres up, чтобы я мог разделить одну и ту же проблему на перекрывающиеся блоки, которые влияют только на несколько переменных результата?

0

Решение

Я понял. Вам разрешено использовать несколько указателей в одном массиве, вам просто не разрешено иметь блоки разных размеров для одного и того же указателя.
Это означает, что ваши блоки внутри массива могут не перекрываться внутри массива, но разные функции стоимости могут использовать одни и те же блоки.

Решение состоит в том, чтобы использовать один блок на пару координат:

for(int i = 0; i < mesh.n_faces(); i++) {
face_cost_functors.push_back(new FaceFunctor());
ceres::DynamicAutoDiffCostFunctionFaceFunctor> *face_cost_function = new ceres::DynamicAutoDiffCostFunction<FaceFunctor>(face_cost_functors.back());
face_cost_function->SetNumResiduals(1);
face_cost_function->AddParameterBlock(2);
face_cost_function->AddParameterBlock(2);
face_cost_function->AddParameterBlock(2);
problem.AddResidualBlock(face_cost_function, NULL, &x.data()[6*i], &x.data()[6*i+2], &x.data()[6*i+4]);
}

Затем вы можете добавить дополнительные функции стоимости, если они используют одинаковые блоки (т. Е. Начальный адрес и размер блока одинаковы). Я здесь не использую никакой SubsetParametrization.

Это не сработало раньше, потому что я пытался использовать блок размером 6 для треугольников и 4 блока размера 2 для пар ребер, которые перекрывают блоки размера 6.

Теперь он работает намного быстрее, чем раньше, и сходится без проблем.

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector