日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Face3D学习笔记(4)3DMM示例源码解析【中上】3DMM模型

發(fā)布時間:2023/12/20 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Face3D学习笔记(4)3DMM示例源码解析【中上】3DMM模型 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

寫在前面

  • 為了保證整個示例項目更加直觀,方便理解,在展示一些函數(shù)的源碼時會使用numpy版本進行展示,而在示例程序中并未使用numpy版本的庫,在Cython版本與numpy版本出現(xiàn)差異的原碼前會有標注,希望讀者留意。

  • 3DMM實例程序的jupyter版本后續(xù)會更新,完全免費,歡迎大家下載

預備

上一篇文章在MATLAB里面對BFM模型執(zhí)行了Face3D提供的程序生成了新的模型數(shù)據(jù)BFM.mat、BFM_info.mat、BFM_UV.mat。這三個文件的格式分別如下:

  • BFM.mat
  • BFM_info.mat
  • BFM_UV.mat 就是一個53215*2的矩陣
  • MATLAB里面的程序到底干了些啥,下面從原理進行一些分析:

    首先要知道3DMM的公式為

    其中, S ̄\overline{S}S代表平均人臉形狀,SiS_iSi?表示形狀PCA主成分,αi\alpha_iαi?是形狀系數(shù), EiE_iEi?是人臉表情PCA主成分,βi\beta_iβi?是人臉表情系數(shù)。
    BFM模型不直接提供原始人臉數(shù)據(jù)或參數(shù)化后的人臉,只提供了形狀和紋理信息
    PS:在BMF模型經(jīng)過去中心化后的數(shù)據(jù)所對應式中的m、n均為199。
    01_MorphableModel.mat中具體包含數(shù)據(jù)如下

    如表所示:

    名稱含義維度
    shapeMU平均人臉形狀(160470,1)
    shapePC形狀主成分(160470,199)
    shapeEV形狀主成分方差(199,1)
    texMU平均人臉紋理(160470,1)
    texPC紋理主成分(160470,199)
    texEV紋理主成分方差(199,1)
    tl三角面片(106466,3)
    segbin區(qū)域分割信息(53490,4)

    在經(jīng)過MATLAB運算輸出的BFM.mat從3DDFA那里獲取了表情數(shù)據(jù),這樣來看face3d里面的3dmm例程:

    bfm = MorphabelModel('Data/BFM/Out/BFM.mat') print('init bfm model success')

    其中MorphabelModel所對應的源碼為

    class MorphabelModel(object):"""docstring for MorphabelModelmodel: nver: number of vertices. ntri: number of triangles. *: must have. ~: can generate ones array for place holder.'shapeMU': [3*nver, 1]. *'shapePC': [3*nver, n_shape_para]. *'shapeEV': [n_shape_para, 1]. ~'expMU': [3*nver, 1]. ~ 'expPC': [3*nver, n_exp_para]. ~'expEV': [n_exp_para, 1]. ~'texMU': [3*nver, 1]. ~'texPC': [3*nver, n_tex_para]. ~'texEV': [n_tex_para, 1]. ~'tri': [ntri, 3] (start from 1, should sub 1 in python and c++). *'tri_mouth': [114, 3] (start from 1, as a supplement to mouth triangles). ~'kpt_ind': [68,] (start from 1). ~"""def __init__(self, model_path, model_type = 'BFM'):super( MorphabelModel, self).__init__()if model_type=='BFM':self.model = load.load_BFM(model_path)else:print('sorry, not support other 3DMM model now')exit()# fixed attributesself.nver = self.model['shapePC'].shape[0]/3self.ntri = self.model['tri'].shape[0]self.n_shape_para = self.model['shapePC'].shape[1]self.n_exp_para = self.model['expPC'].shape[1]self.n_tex_para = self.model['texPC'].shape[1]self.kpt_ind = self.model['kpt_ind']self.triangles = self.model ['tri']self.full_triangles = np.vstack((self.model['tri'], self.model['tri_mouth']))

    就可以理解self.model = load.load_BFM(model_path)所讀取的model里面所包含的元素都是什么了,下面以表格的形式列出來。

    名稱含義格式
    shapeMU平均人臉形狀(159645,1)
    shapePC形狀主成分(159645,199)
    shapeEV形狀主成分方差(199,1)
    expMU平均人臉表情(159645,1)
    expPC表情主成分(159645,29)
    expEV表情主成分方差(29,1)
    texMU平均人臉紋理(159645,1)
    texPC紋理主成分(159645,199)
    texEV紋理主成分方差(199,1)
    tri三角格坐標(105840,3)
    tri_mouth嘴部三角格坐標(114, 3)
    kpt_ind特征點(68,)

    源碼解讀

    1.讀取模型&&生成面部網(wǎng)格

    讀取處理過的BFM模型

    bfm = MorphabelModel('Data/BFM/Out/BFM.mat') print('init bfm model success')

    用隨機的形狀系數(shù)和表情系數(shù)生成面部網(wǎng)格

    sp = bfm.get_shape_para('random') ep = bfm.get_exp_para('random') vertices = bfm.generate_vertices(sp, ep)tp = bfm.get_tex_para('random') colors = bfm.generate_colors(tp) colors = np.minimum(np.maximum(colors, 0), 1)

    sp對應形狀系數(shù)α\alphaα,ep對應表情系數(shù)β\betaβ,tp對應的是紋理系數(shù)。這些系數(shù)均隨機產(chǎn)生。
    這部分對應的源碼如下:

    def get_shape_para(self, type = 'random'):if type == 'zero':sp = np.zeros((self.n_shape_para, 1))elif type == 'random':sp = np.random.rand(self.n_shape_para, 1)*1e04return spdef get_exp_para(self, type = 'random'):if type == 'zero':ep = np.zeros((self.n_exp_para, 1))elif type == 'random':ep = -1.5 + 3*np.random.random([self.n_exp_para, 1])ep[6:, 0] = 0return ep def generate_vertices(self, shape_para, exp_para):'''Args:shape_para: (n_shape_para, 1)exp_para: (n_exp_para, 1) Returns:vertices: (nver, 3)'''vertices = self.model['shapeMU'] + \self.model['shapePC'].dot(shape_para) + \self.model['expPC'].dot(exp_para)vertices = np.reshape(vertices, [int(3), int(len(vertices)/3)], 'F').Treturn vertices# -------------------------------------- texture: here represented with rgb value(colors) in vertices.def get_tex_para(self, type = 'random'):if type == 'zero':tp = np.zeros((self.n_tex_para, 1))elif type == 'random':tp = np.random.rand(self.n_tex_para, 1)return tpdef generate_colors(self, tex_para):'''Args:tex_para: (n_tex_para, 1)Returns:colors: (nver, 3)'''colors = self.model['texMU'] + self.model['texPC'].dot(tex_para)colors = np.reshape(colors, [int(3), int(len(colors)/3)], 'F').T/255. return colors

    形狀和表情部分進行了下式的矩陣運算:

    紋理部分也進行了類似運算,這里不贅述。
    到這里產(chǎn)生了新的人臉模型。

    2. 網(wǎng)格位置變換

    變換網(wǎng)格頂點位置到合適處。

    s = 8e-04 angles = [10, 30, 20] t = [0, 0, 0] transformed_vertices = bfm.transform(vertices, s, angles, t) projected_vertices = transformed_vertices.copy() # using stantard camera & orth projection def transform(self, vertices, s, angles, t3d):R = mesh.transform.angle2matrix(angles)return mesh.transform.similarity_transform(vertices, s, R, t3d)

    對應的源碼:

    def similarity_transform(vertices, s, R, t3d):''' similarity transform. dof = 7.3D: s*R.dot(X) + tHomo: M = [[sR, t],[0^T, 1]]. M.dot(X)Args:(float32)vertices: [nver, 3]. s: [1,]. scale factor.R: [3,3]. rotation matrix.t3d: [3,]. 3d translation vector.Returns:transformed vertices: [nver, 3]'''t3d = np.squeeze(np.array(t3d, dtype = np.float32))transformed_vertices = s * vertices.dot(R.T) + t3d[np.newaxis, :]return transformed_vertices

    這部分和之前pipeline源碼分析中的頂點位置變換部分相同,輸入為網(wǎng)格頂點vertices、縮放比例s、旋轉(zhuǎn)矩陣R和平移向量t3d執(zhí)行空間坐標變換s*R.dot(X) + t后輸出變換后的頂點位置

    3.轉(zhuǎn)化為二維圖像

    這部分同樣與pipeline例程相同,放出來代碼:

    h = w = 256; c = 3 image_vertices = mesh.transform.to_image(projected_vertices, h, w) image = mesh.render.render_colors(image_vertices, bfm.triangles, colors, h, w) plt.imshow(image) plt.show()

    得到新生成的三維人臉模型圖片如下圖:

    后續(xù)將繼續(xù)更新代碼后半部分的解讀,敬請關注

    總結(jié)

    以上是生活随笔為你收集整理的Face3D学习笔记(4)3DMM示例源码解析【中上】3DMM模型的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。