代码之家  ›  专栏  ›  技术社区  ›  allo

如何在CIES中为同一解决方案创建不同的求解块?

  •  1
  • allo  · 技术社区  · 6 年前

    我想用 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| 因为每个顶点有两个坐标),因为块依赖于所有顶点。在第二块中,三角形块只依赖于三个顶点和四个顶点上的边缘块。 我现在想使用第二个,因为我期望更好的性能和更好的收敛性。

    如何设置CURES来解决相同的坐标,而只考虑顶点的子集与当前残渣相关?

    我试着用大小6和8设置问题,并在 X 但是,CIES不允许使用具有不同偏移量的相同结果指针。

    接下来我试着用 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
    

    如何设置CURES,这样我就可以在重叠块中分割相同的问题,这只会影响一些结果变量?

    1 回复  |  直到 6 年前
        1
  •  2
  •   allo    6 年前

    我得到了它。允许在同一个数组中使用多个指针,不允许为同一指针设置不同的块大小。 这意味着数组内的块可能不在数组内重叠,但允许不同的成本函数使用相同的块。

    解决方案是每个坐标对使用一个块:

    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]);
        }
    

    然后,可以添加更多的成本函数,只要它们使用相同的块(即起始地址和块大小是相同的)。在这里我不使用任何子集参数化。

    它以前没有用过,因为我试着用一个块大小为6的三角形和4块大小为2的边缘对,它们重叠了大小为6的块。

    现在它的运行速度比以前快得多,而且收敛没有问题。