You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何均匀简化3D人脸表面网格且保留顶点双侧对称性

3D人脸网格简化时保留双侧对称性与顶点均匀分布的方案咨询

以下是3D人脸表面网格的示例,从下图1可见,特征点具备双侧对称性,我希望减少特征点的数量。

其中face为顶点坐标,triang为三角剖分文件,landPairs为包含顶点配对信息的两列文件,landPairs后续不会用于绘图,但若需要可直接使用。所有数据可从对应仓库获取。


原始网格绘制代码

library(rgl)
library(Rvcg)

# 自定义函数:将vb和it信息转换为3D网格
lm2mesh <- function(vb, it) {
    vb <- t(vb)
    vb <- rbind(vb, 1)
    rownames(vb) <- c("xpts", "ypts", "zpts", "")

    it_mat <- t(as.matrix(it))
    rownames(it_mat) <- NULL

    vertices <- c(vb)
    indices <- c(it_mat)

    tmesh3d(vertices = vertices, indices = indices, homogeneous = TRUE, 
            material = NULL, normals = NULL, texcoords = NULL)
}
# 加载`face`和`triang`文件   
face <- as.matrix(read.csv("<PATH>\\SampleFace.csv", header=F))
triang <- as.matrix(read.csv("<PATH>\\triangulation.csv", header=F))

facemesh <- lm2mesh(face,triang)

# 绘制未简化的网格
shade3d(facemesh, col="steelblue", specular = "#202020", alpha = 0.7)
plot3d(face, type = "s", col = "red", xlab = "x", ylab = "y", zlab = "z", 
       size = 0.2, aspect = FALSE, alpha = 0.8, add=T)

原始网格输出结果

原始3D人脸网格
顶点分布均匀且完全具备双侧对称性。


现有简化方案代码

# 绘制简化后的网格
open3d()
facemeshdecim <- vcgQEdecim(facemesh,percent=0.1)
shade3d(facemeshdecim, col="steelblue", specular = "#202020", alpha = 0.7)
plot3d(t(facemeshdecim$vb[-4, ]), type = "s", col = "red", xlab = "x", ylab = "y", zlab = "z", 
       size = 0.4, aspect = FALSE, alpha = 0.8, add=T)

简化后网格输出结果

简化后3D人脸网格
顶点分布不再均匀,且双侧对称性消失。


可行解决方案

有两种成熟的实现思路,都可以同时满足顶点分布均匀、保留双侧对称性的需求:

方案1:半侧镜像简化法(实现成本最低,适合当前数据集)

利用手头已有的landPairs对称配对信息,操作步骤如下:

  • 先对原始网格做坐标对齐,确保人脸对称轴与X=0平面完全重合(若数据集已经对齐可跳过这一步)
  • 提取X≥0的半侧人脸网格,单独对这半侧网格做简化,调整vcgQEdecim的参数开启均匀分布约束:
    # 半侧简化示例代码片段
    facemesh_half <- vcgClip(facemesh, "x", 0) # 截取x≥0的半侧网格
    # 开启preserveboundary参数保留边界,boundweight调大避免对称轴处被过度简化
    facemesh_half_decim <- vcgQEdecim(facemesh_half, percent=0.1, preserveboundary = T, boundweight = 10)
    
  • 将简化后的半侧网格沿X轴做镜像翻转,把对称的顶点、三角面拼接回完整网格,直接用landPairs做顶点匹配即可
  • 最后对拼接后的网格做一次简单的平滑处理消除接缝,即可得到完全对称、顶点分布均匀的简化网格

方案2:约束二次误差测度简化法(效果更可控,适合批量处理)

修改vcgQEdecim的误差计算逻辑,把对称约束加入到边折叠的代价计算中:

  • 每次计算边折叠代价时,同时计算其对称边的折叠代价,取两者的平均值作为最终代价
  • 只要触发任意一条边的折叠操作,就同时对其对称边执行完全相同的折叠操作
  • 额外添加顶点密度约束项,避免局部区域顶点过度稀疏/密集,即可同时满足两个需求

第一种方案不需要修改现有的简化工具底层逻辑,直接用现有数据和R包就能实现,推荐优先尝试。


内容的提问来源于stack exchange,提问作者Patrick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 16:27:03