【问题标题】:Mesh smoothing with Gaussian高斯网格平滑
【发布时间】:2011-01-20 08:39:34
【问题描述】:

我希望使用高斯函数平滑给定的 3D 网格,该网格使用半边结构来存储邻接信息。提出的算法如下:

通过移动每个顶点来平滑网格 到由加权确定的位置 其直接邻居的平均值 (权重由高斯确定 sigma 等于平均长度 连接到顶点的边, 归一化,使得权重总和 到一个)。

所以对于每个顶点curr_vertex,我

  1. 计算其附加边的平均长度
  2. 获取所有相邻顶点
  3. 通过执行以下操作确定每个相邻顶点的权重: `

重量 = exp(-(距离*距离)/(2.sigmasigma))

where distance is the 3D distance between thecurr_vertexand the neighbor andsigma= average length of attached edges ofcurr_vertex`

  1. 将所有权重相加,然后将每个邻居的权重除以该总和(归一化步骤)
  2. 将每个相邻顶点的位置乘以其相应的权重
  3. 将所有加权顶点相加并将结果添加到 curr_vertex 以生成新顶点。

当我这样做并运行我的算法时,实际发生的不是平滑而是缩放 - 我的网格只是被放大而没有任何明显的平滑。

对我做错了什么有什么想法吗?

编辑: 这是我的代码:

void R3Mesh::
Smooth(void)
{
  R3Mesh *new_mesh = new R3Mesh(*this);
  for(int i = 0; i < NVertices(); i++)
  {
    R3MeshVertex *v = Vertex(i);
    map<R3MeshVertex *, double> neighbors; // stores vertex-weight pairs 
    map<R3MeshVertex *, double>::iterator neighbors_iter;

    // store each vertex neighbor by going through
    // all adjacent edges and obtaining those edges' vertices
    R3MeshHalfEdge *tmp = v->half_edge;
    do
    {
      neighbors.insert(make_pair(tmp->opposite->vertex,0));
      tmp = tmp->opposite->next;
    }while(tmp != v->half_edge);

    // determine the sigma to use for Gaussian
    double sigma = v->AverageEdgeLength();
    double weight = 0, total_weight = 0;
    double distance;

    // determine and store the weight of each neighboring vertex
    for(neighbors_iter = neighbors.begin(); neighbors_iter != neighbors.end();
        neighbors_iter++)
    {
      distance = R3Distance(v->position, neighbors_iter->first->position);
      weight = (1./(sigma*sqrt(2.*3.14)))*exp(-(distance*distance)/(2.*sigma*sigma));
      total_weight += weight;
      neighbors_iter->second = weight;
    }

    // determine new position of current vertex
    R3Point new_pos = v->position;
    for(neighbors_iter = neighbors.begin(); neighbors_iter != neighbors.end();
        neighbors_iter++)
    {
      new_pos += (neighbors_iter->second/total_weight)*(neighbors_iter->first->position);
    }

    new_pos.Translate(new_pos - v->position);
    new_mesh->Vertex(i)->position.Reset(new_pos.X(), new_pos.Y(), new_pos.Z());

    neighbors.clear();
  }



  *this = *new_mesh;
}

【问题讨论】:

    标签: opengl mesh gaussian smoothing


    【解决方案1】:

    这有点令人头疼的拼写错误。您描述的算法对我来说看起来不错。

    首先清楚地验证权重的归一化。

    接下来检查您的代码,您将计算的顶点位置写回到新的平滑网格中。

    这些是我的猜测。如果这些不起作用,请随时发布代码 sn-p。

    【讨论】:

    • 请看一下我的函数
    • 尝试将 new_pos 初始化为原点,而不是 v->position。和你现在一样总结一下,然后删除这一行:new_pos.Translate(new_pos - v->position);那应该可以。
    猜你喜欢
    • 2011-02-15
    • 2013-02-01
    • 2011-05-10
    • 2015-05-07
    • 2015-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多