三维人脸重建中光源部分的理解

球谐函数在光照估计中的应用

参考文献:https://blog.csdn.net/tinyzhao/article/details/62419220

光照估计就是从图片中获取光照信息,从而降低光照对纹理的影响。传统的光照估计依赖于光源方向和法线方向的估计,而光源方向和法线方向都是一种“估计”,本身就是不够精确的。使用不够精确的参数去估计目标值,就需要使用到一些高级的估计算法,这些算法一般都依赖于对象的统计特征。这样的光照模型过于复杂,其中的每一个过程都会影响最终的结果。

在2001年,Basri和Jacobs证明了曲面上的像素值可以使用9维的球谐基函数进行线性表示,这种光照模型只需要估计球谐基函数前面的权值,不需要光源的方向,大大简化了光照的估计。点p处的像素值等于p处的albedo乘以球谐基函数的线性组合,用数学公式表示一下就是:

请添加图片描述

ρ ( p ) ρ_(p) ρ(p)表示p处的albedo, l j l_j lj表示球谐基函数的系数, h j h_j hj表示9个球谐基函数。使用 n x n_x nx, n y n_y ny, n z n_z nz表示法线方向,这9个基分别为:
在这里插入图片描述
从式子中可以看到球谐函数基还是依赖于法线的方向的。Albedo的原意是反照率,我们可以看成是去除光照和阴影以后的纹理,在游戏图形工程上,更接近于基色的概念。

光照估计
对于一个有n个像素值的图片,n个像素对应着n个线性方程组,光照的估计就变成了n个方程求解n+9个未知数的问题,n+9表示n个albedo值和9个光照系数。一般的方法是使用最小二乘法进行估计。

  • 初始化albedo估计
    albedo的初始值 ρ 0 ρ^0 ρ0, ρ 0 ρ^0 ρ0可以使用图片像素平均值来估计。

  • 初始化光照参数
    有了 ρ 0 ρ^0 ρ0,就可以带入到 I = ρ 0 H L I=ρ^0HL I=ρ0HL中,使用最小二乘法获得初始的光照系数 L 0 L^0 L0

  • 更新albedo
    使用上一步中得到的L值,可以根据式子 I = ρ 0 H L I=ρ^0HL I=ρ0HL直接解得新的ρ。

  • 更新光照系数
    再次使用最小二乘法估计光照系数L。重复估计albedo和L,直到满足要求,一般5次就足够了。

def get_normal(vertices, triangles):
    ''' calculate normal direction in each vertex
    Args:
        vertices: [nver, 3]
        triangles: [ntri, 3]
    Returns:
        normal: [nver, 3]
    '''
    pt0 = vertices[triangles[:, 0], :] # [ntri, 3]
    pt1 = vertices[triangles[:, 1], :] # [ntri, 3]
    pt2 = vertices[triangles[:, 2], :] # [ntri, 3]
    tri_normal = np.cross(pt0 - pt1, pt0 - pt2) # [ntri, 3]. normal of each triangle     Vector的叉乘,可算出法线

    normal = np.zeros_like(vertices) # [nver, 3]
    #这里是将每个面的面法线都加到这个面的每一个顶点上
    for i in range(triangles.shape[0]):
        normal[triangles[i, 0], :] = normal[triangles[i, 0], :] + tri_normal[i, :]
        normal[triangles[i, 1], :] = normal[triangles[i, 1], :] + tri_normal[i, :]
        normal[triangles[i, 2], :] = normal[triangles[i, 2], :] + tri_normal[i, :]
    
    # normalize to unit length
    mag = np.sum(normal**2, 1) # [nver]
    zero_ind = (mag == 0)
    mag[zero_ind] = 1 #如果有法线为(0,0,0)的 将其变成1 
    normal[zero_ind, 0] = np.ones((np.sum(zero_ind))) 

    normal = normal/np.sqrt(mag[:,np.newaxis])

    return normal


def add_light_sh(vertices, triangles, colors, sh_coeff):
    ''' 
    In 3d face, usually assume:
    1. The surface of face is Lambertian(reflect only the low frequencies of lighting)
    2. Lighting can be an arbitrary combination of point sources
    --> can be expressed in terms of spherical harmonics(omit the lighting coefficients)
    I = albedo * (sh(n) x sh_coeff)
    
    albedo: n x 1
    sh_coeff: 9 x 1
    Y(n) = (1, n_x, n_y, n_z, n_xn_y, n_xn_z, n_yn_z, n_x^2 - n_y^2, 3n_z^2 - 1)': n x 9 
    # Y(n) = (1, n_x, n_y, n_z)': n x 4

    Args:
        vertices: [nver, 3]
        triangles: [ntri, 3]
        colors: [nver, 3] albedo   可以看到这是在顶点上着色啊
        sh_coeff: [9, 1] spherical harmonics coefficients

    Returns:
        lit_colors: [nver, 3]
    '''
    assert vertices.shape[0] == colors.shape[0]
    nver = vertices.shape[0]
    normal = get_normal(vertices, triangles) # [nver, 3]  get_normal -> calculate normal direction in each vertex
    sh = np.array((np.ones(nver), n[:,0], n[:,1], n[:,2], n[:,0]*n[:,1], n[:,0]*n[:,2], n[:,1]*n[:,2], n[:,0]**2 - n[:,1]**2, 3*(n[:,2]**2) - 1)) # [nver, 9]
    ref = sh.dot(sh_coeff) #[nver, 1]
    lit_colors = colors*ref
    return lit_colors

flat、Gouraud、Phong Shading的差別 (Comparison flat, Gouraud, Phong shading)

参考文献:https://cg2010studio.com/2011/11/01/flat%E3%80%81gouraud%E3%80%81phong-shading%E7%9A%84%E5%B7%AE%E5%88%A5-comparison-flat-gouraud-phong-shading/

现今多边形的着色方法基本的有这三种:flat、Gouraud、Phong Shading,它们之间有何差別呢?喜欢玩游戏的人一定要知道Gouraud Shading,这是PC最常使用的着色法,因为效能好、效果还不錯。而近年來,随着GPU快速的发展,Phong Shading逐渐使用在更真实的着色上。

从一张图可以看出他们的各自的特色:(a: Flat→b: Gouraud→c: Phong)
请添加图片描述
时间从古到今:Flat→Gouraud→Phong Shading。
从简单到复杂:Flat→Gouraud→Phong Shading。

观察三者所呈现的效果,可以归纳出以下结论:

flat shading: constant surface shading
Gouraud shading: color interpolation shading
Phong shading: vertex normal interpolation shading

用简单的中文来解释原理:

  • flat shading:三角形的顶点沒有法向量,三角形整个面才有法向量,打光时整个三角形只呈现一种颜色。
  • Gouraud shading:三角形的顶点都有各自的法向量,打光时三个顶点都有各自的颜色,接着做双线性内插(bilinear interpolation)来求得颜色,使整个三角形有逐渐的颜色变化。
  • Phong shading:三角形的顶点都有各自的法向量,先对三角形整个面作法向量的双线性内插,接着打光来求整个三角形的颜色。

在这里插入图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在国外,基于单图像的三维人脸重建是一个非常活跃的研究领域。许多研究人员致力于开发各种算法和模型,以从单个图像恢复出准确和逼真的三维人脸形状。 以下是一些国外的研究现状: 1. 3DMM方法:3D Morphable Model(3DMM)是一种经典的方法,通过对大量人脸数据进行建模,将人脸的形状和纹理表示为低维参数空间。这些参数可以用来重建人脸三维形状。一些研究通过改进3DMM模型的生成过程,提高了重建的准确性和逼真度。 2. 深度学习方法:近年来,深度学习技术在单图像三维人脸重建取得了显著进展。研究人员使用卷积神经网络(CNN)或生成对抗网络(GAN)等深度学习模型,通过从大规模数据集学习人脸的特征表示和形状变化,实现了更准确和细致的三维人脸重建。 3. 结合几何和纹理信息:一些研究将几何信息和纹理信息相结合,以提高重建的精度和真实感。这些方法通常利用纹理图像的细节信息来辅助形状重建,并使用几何约束来提高纹理贴图的对齐和一致性。 4. 多视角方法:除了单个图像,一些研究还利用多个视角的图像来进行三维人脸重建。这些方法通过结合多个视角的信息,可以更精确地恢复出人脸三维形状。 5. 实时重建:近年来,也有一些研究致力于实现实时的三维人脸重建。这些方法通常采用轻量级的网络结构和优化算法,以在实时性要求下实现准确的人脸重建。 总体而言,国外的研究者们在基于单图像的三维人脸重建领域取得了显著进展。不断涌现的新算法和技术为实现更准确、高质量的三维人脸重建提供了可能,为面部分析、虚拟现实、增强现实等领域带来了许多应用机会。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值