• BFM使用


    使用版本:2009
    数据说明网址:https://faces.dmi.unibas.ch/bfm/index.php?nav=1-1-0&id=details
    数据下载网址:https://faces.dmi.unibas.ch/bfm/index.php?nav=1-2&id=downloads

    使用Matlab导入01_MorphableModel.mat

    load('解压目录1_MorphableModel.mat')
    


    160470=53490*3,即形状(Shape)(S=(x_1, y_1, z_1, ..., x_n, y_n, z_n))
    包含内容:

    • segbin:猜是segment binary,用热点法标注属于面部哪一部分。
    • shapeEV:形状方差;
    • shapeMU(160470*1):平均形状;
    • shapePC:形状的主成分;
    • texEV:纹理方差;
    • texMU:平均纹理
    • texPC:纹理的主成分;

    新建一个Matlab脚本,输入如下代码:

    shape = reshape(shapeMU, 3, 53490)
    shape = shape.'
    x = shape(:, 1)
    y = shape(:, 2)
    z = shape(:, 3)
    scatter3(x,y,z, 1, 'filled');
    

    该代码将原本一行的形状向量转换为n*3的矩阵,然后将其在三维坐标系下画出来,我们可以看到显示如图人脸。

    官方提供的landmark对应关系格式如下(Farkas_face05.fp):

    # Feature Points
    # Filename: /net/faces/projects/model200/fps/new_farkas/face05_farkas.fp
    # Format: (vertex_nr) (x y z) (x y) (name)
    19963 -88262.2 36394.8 -4947.64 0 0 sa
    20205 -71257.4 -20598.4 13258.3 0 0 sba
    21629 -77516 30127.9 12058.9 0 0 pra
    ...
    

    因此我们通过一个python脚本读取其中的三维点信息并保存到mat矩阵当中:

    import scipy.io as scio
    file = open("Farkas_face05.fp")
    landmarks = []
    while True:
        line = file.readline()
            if not line:
                break
            if line[0] < '0' or line[0] > '9':
                continue
            args = line.split()
            coord = [float(args[1]), float(args[2]), float(args[3])]    
            landmarks.append(coord)
    scio.savemat('landmarks.mat', {'landmarks': landmarks})
    

    随后从Matlab中读取这个mat文件,并进行打印:

    scatter3(x,y,z,2, 'filled');
    hold on;
    for i = 1:70
        scatter3(landmarks(i,1), landmarks(i,2), landmarks(i,3),10, 'r');
    end
    

    显示效果图如下

    因为我们最终想通过与dlib提供的68个点进行拟合,因此不能使用这种方法得到的特征点。
    这边找到了Github上有人提供的68个特征点在BFM上的对应关系:https://github.com/anilbas/BFMLandmarks
    我们将其中的Landmarks68_BFM.anl文件内的68个下标导入Matlab然后更新代码:

    % tmp存储了Landmarks68_BFM.anl中的68个下标
    scatter3(x,y,z,2, 'filled');
    hold on;
    for i = 1:68
        scatter3(x(tmp(i)), y(tmp(i)), z(tmp(i)),10, 'r');
    end
    

    显示结果如下:

    这便是我们想要得到的68个点,最后我们把这68个点的坐标导出到本地:

    landmarks = zeros(68,3);
    for i = 1:68
        landmarks(i, :) = [x(tmp(i)), y(tmp(i)), z(tmp(i))];
    end
    save landmarks landmarks
    

    这样我们就可以在后续的代码中通过导入landmarks.mat来获取标准脸的68位特征点坐标了。

  • 相关阅读:
    用react重构个人网站 3-23
    用react重构个人网站 3-22
    React官方文档笔记之快速入门
    .Net多线程编程—同步机制
    .Net多线程编程—Parallel LINQ、线程池
    .Net多线程编程—并发集合
    .Net多线程编程—任务Task
    【翻译】MongoDB指南/聚合——聚合管道
    【翻译】MongoDB指南/CRUD操作(四)
    【翻译】MongoDB指南/CRUD操作(三)
  • 原文地址:https://www.cnblogs.com/bemfoo/p/11215643.html
Copyright © 2020-2023  润新知