hi,你好!欢迎访问本站!登录
本站由网站地图腾讯云宝塔系统阿里云强势驱动
当前位置:首页 - 教程 - 杂谈 - 正文 君子好学,自强不息!

BFM模子引见及可视化完成(C++)

2019-11-18杂谈搜奇网21°c
A+ A-

BFM模子引见及可视化完成(C++)

BFM模子基础引见

Basel Face Model是一个开源的人脸数据库,其基础原理是3DMM,因而其就是在PCA的基础上举行存储的。
现在有两个版本的数据库(2009和2017)。
官方网站:2009,2017

数据内容(以2009版本为例)

文件内容

01_MorphableModel.mat(数据主体)

BFM模子由53490个极点组成,其shape/texture的数据长度为160470(53490*3),由于其分列体式格局以下:

shape: x_1, y_1, z_1, x_2, y_2, z_2, ..., x_{53490}, y_{53490}, z_{53490}
texture: r_1, g_1, b_1, r_2, g_2, b_2, ..., r_{53490}, g_{53490}, b_{53490}

.h5文件与.mat文件对应关联

[注] .h5文件中的tl数目与.mat数目差别,主身分方差的值也差别,且shape的值是.mat中shape值的0.001倍(见/shape/representer/length-unit)。

Matlab剧本

发起浏览script_gen_random_head.m文件,该剧本完成了怎样生成随机脸,从中我们可以进修到BFM模子的运用要领。

2009与2017版本区分

2009年版本数据集:

  • 供应数据花样:mat(01_MorphableModel.mat)和h5(model2009-publicmm1-bfm.h5);
  • 供应一系列Matlab剧本,有生成随机脸等功用;
  • 供应多种特性点(PublicMM1/11_feature_points);
  • 供应segment的mask(PublicMM1/09_mask);
  • 供应对称点的对应关联(PublicMM1/13_symmetry_indices);
  • 供应属性(PublicMM1/04_attributes.mat
  • 不供应脸色;

2017年版本数据集:

  • 供应数据花样:h5(原版(model2017-1_bfm_nomouth.h5)和裁剪过的版本(model2017-1_face12_nomouth.h5));
  • 不供应Matlab剧本(自身也无mat花样数据);
  • 供应单种特性点(metadata/landmarks/text);
  • 不供应segment、对称点的对应关联和属性;
  • 供应脸色(expression);

基础原理

目的shape或许texture都可以经由历程以下式子获得:

obj = average + pc * (coeficient .* pcVariance)

个中系数(coeficient)是变量,其他均是数据库里的常量,其是一个199维(对应199个PC)的向量。

C++完成BFM模子可视东西

数据读取

我们可以读取.mat文件或许.h文件,由于读取.mat文件须要运用Matlab的库文件,我们暂时不斟酌。

读取.h5花样文件

.h5文件没法直接经由历程文本东西翻开,须要下载特地的可视东西,此处我运用了HDFView。

经由历程该文件我们可以相识到HDF5文件的内部花样。
在C++中运用HDF5读写须要下载官方的库:
HDF5库下载地点
官网右上角注册后下载,随后挑选对应版本下载。
[注] 在Windows的Visual Studio运用shared库须要编译历程定义H5_BUILT_AS_DYNAMIC_LIB。(若涌现LINK2001毛病可以增添这个来处理)
[注] static库定名前面以lib开首,比方hdf5.lib是shared库,libhdf5.lib是static库。
在VS的包括目次和库目次中增添对应的inlcude和lib目次。
在链接器的输入中增添szip.lib;zlib.lib;hdf5.lib;hdf5_cpp.lib;,并将对应的.dll文件安排到Windows/System32Windows/SysWOW64

我们只须要用到HDF5中的读取功用,步骤是翻开文件->翻开数据库->读取数据->封闭数据库->封闭文件。我们以shape均匀值为例:

float *shape_mu_raw = new float[N_VERTICE * 3];
H5File file(bfm_h5_path, H5F_ACC_RDONLY);
DataSet shape_mu_data = file.openDataSet("/shape/model/mean"); 
shape_mu_data.read(shape_mu_raw, PredType::NATIVE_FLOAT); 
raw2vector(shape_mu, shape_mu_raw);   // 自即将数组转换成想要寄存的花样
shape_mu_data.close(); 
file.close();

shape均匀值读取后须要再乘以1000才等同于.mat花样的读取。
须要注重的是数据的读取范例一定要根数据库中的范例一致。shape/tex的范例均为float,对应PredType::NATIVE_FLOAT,tl的范例为unsigned int,对应PredType::NATIVE_UINT32
[注] 由于缺乏pdb文件,HDF5中的代码假如报错可以没法举行调试,须要逐行举行毛病的消除,罕见毛病就是范例不婚配或许长度不婚配。

其他读取体式格局

在最最先不相识.h5花样的时刻,我便运用一些笨要领举行读取,比方先将.mat花样数据转换成二进制文件/文本文件再举行读取。
比方如许一个matlab剧本:

function mat2binary(filename, mat, type)
    fid=fopen(filename, 'wb');
    matrix = mat;                        
    [m,n]=size(matrix);
     for i=1:1:m
       for j=1:1:n
            fwrite(fid, matrix(i,j), type);
       end
    end
    fclose(fid);
end

这些剧本可以简朴地将mat花样举行转换,成为轻易被C++举行读取的花样。然则弊病也很明显,在C++中的读写速率异常慢。.h5花样读写1s摆布完成,二进制文件读写1分钟摆布完成,文本文件读写5分钟摆布完成。且在存储大小上,.h5文件(249MB)≈ 二进制文件 < 文本文件(凌驾710M)。

生成人脸

即按照上述基础原理中的式子举行完成。

OpenGL举行显现

这里运用了Qt5内置的OpenGL模块,经由历程最简朴的glBegin()glEnd()即可绘出人脸。

double sint = sin(theta), cost = cos(theta);
for (auto t = tl.begin(); t != tl.end(); t++) {
       glBegin(GL_TRIANGLES);
       vec3 tmp = *t;
       glColor3f(tex[tmp.x].x / 255.0, tex[tmp.x].y / 255.0, tex[tmp.x].z / 255.0);
       glVertex3f(shape[tmp.x].x * scale * cost - shape[tmp.x].z * scale * sint, shape[tmp.x].y * scale, shape[tmp.x].x * scale * sint + shape[tmp.x].z * scale * cost);
       glColor3f(tex[tmp.y].x / 255.0, tex[tmp.y].y / 255.0, tex[tmp.y].z / 255.0);
       glVertex3f(shape[tmp.y].x * scale * cost - shape[tmp.y].z * scale * sint, shape[tmp.y].y * scale, shape[tmp.y].x * scale * sint + shape[tmp.y].z * scale * cost);
       glColor3f(tex[tmp.z].x / 255.0, tex[tmp.z].y / 255.0, tex[tmp.z].z / 255.0);
       glVertex3f(shape[tmp.z].x * scale * cost - shape[tmp.z].z * scale * sint, shape[tmp.z].y * scale, shape[tmp.z].x * scale * sint + shape[tmp.z].z * scale * cost);
       glEnd();
}

运用thetascale参数用于完成鼠标和键盘对模子方向的掌握。
依据模子大小,我们设置响应的视角:

void OpenGLWidget::resizeGL(int width, int height) {
        glViewport(0, 0, width, height);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluPerspective(60.0, (GLfloat)width / (GLfloat)height, 1.0, 600000.0);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        gluLookAt(0, 0, 300000.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}

效果展现

初始界面(左边显现一个彩色三角形):

当随机性设置为0(即coeficient设为[0, ..., 0]),生成均匀脸:

随机生成人脸,或随机设置PC值:

源代码

GitHub:https://github.com/Great-Keith/bfm-visual-tool

  选择打赏方式
微信赞助

打赏

QQ钱包

打赏

支付宝赞助

打赏

  移步手机端
BFM模子引见及可视化完成(C++)

1、打开你手机的二维码扫描APP
2、扫描左则的二维码
3、点击扫描获得的网址
4、可以在手机端阅读此文章
未定义标签

本文来源:搜奇网

本文地址:https://www.sou7.cn/282198.html

关注我们:微信搜索“搜奇网”添加我为好友

版权声明: 本文仅代表作者个人观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。请记住本站网址https://www.sou7.cn/搜奇网。

发表评论

选填

必填

必填

选填

请拖动滑块解锁
>>