机器视觉 增强现实分享 http://blog.sciencenet.cn/u/wanglin193 把算法当成业余爱好......

博文

固定边界的三维人脸网格参数化

已有 858 次阅读 2018-9-16 15:06 |个人分类:3D|系统分类:科研笔记| 网格参数化

三维曲面离散化为三维网格后,为了进行纹理贴图,有时还要展开到二维的uv坐标平面上。虽然大部分空间曲面都不是可展的,但是在曲面的局部区域观察是可以表示成f(u,v)的形式的,这个过程在数字图形处理中的术语叫参数化(Parameterization)。从三角网格的角度,每个三角和它的uv平面上的对应都是仿射变换的关系,根据不同的应用,通常要给这种局部映射加约束,比如要求角度或者面积的变形最小等,在曲面不撕裂的情况下,这种假设只能近似满足。

常用的纹理映射方法是把和平面圆盘拓扑等价的曲面,映射到平面上。曲面的边界分别有固定边界和不固定边界两种。对于后者多数求解方法都是非线性的。而固定边界方法则用线性方程就能求解,即给定凸边界,不在边界上的点看成是边界点的某种线性加权(参见上一篇)。其中Tutte mapping堪称是最简单的uv映射方法,每个点是邻近点的重心位置。

下面针对Basel人脸模型做参数化。预先对于原网站上提供的10个模型作平均,得到一个平均模型,保存在Basel_color_meanface.mat中,三角形序号表示的‘面表’保存在face_tri.txt中。

    clear all
    close all
    path = 'data\';
    % load mesh data, Vertex, Color and Facets
    load([path,'Basel_color_meanface.mat']);
    facetri = 1 + load([path,'face_tri.txt']);
    % load IBUG 68 lmk for basel model
    idlmk = 1 + load([path,'lmk_id68_in53490.txt']);
    
    meanshape = meanface.shape;
    meantex = meanface.tex;
    numv = size(meanshape,1);
    % Calculate laplacian matrix
    L = cal_mesh_laplacian(double(meanshape),facetri,'conformal');
    % Find contour: edges has only one half edge in edgelist
    [idcon,idseg] = find_mesh_contour( meanshape, facetri );

    因为模型只有一条边界,idseg=1,即没有孔洞,拓扑结构和圆盘等价。68个蓝色点表示的是IBUG二维人脸特征点(ASM/AAM等face alignment方法常用的landmark配置)的对应位置:

    把曲面x/z坐标归一化到一个半径r的圆柱面上(早年3DMM人脸模型经常做这样的操作):

    sum2 = meanshape(:, 3).^2 + meanshape(:, 1).^2;
    sum2 = sqrt(sum2);
    r = mean(sum2);
    
    meanshape(:, 3) = r*meanshape(:, 3)./sum2;
    meanshape(:, 1) = r*meanshape(:, 1)./sum2;
    
    trimesh( facetri, meanshape(:, 1), meanshape(:, 2), meanshape(:, 3), ...
        'EdgeColor', 'none', ...
        'FaceVertexCData', meantex/255, 'FaceColor', 'interp', ...
        'FaceLighting', 'phong'  );
    zlabel('Z');hold onview(-35,60);
    plot3( meanshape(idcon,1),meanshape(idcon,2),meanshape(idcon,3),'r.' );
    axis equal

    然后展开到Z=0平面上:

    ang = atan2(meanshape(:, 1), meanshape(:, 3));
    shx = ang*r;
    shy = meanshape(:, 2);
    shz = zeros(numv,1);

    图中鼻孔和嘴部的瑕疵是鼻腔口腔内部三角网格映射形成的,也就是说网格点映射时产生了一对多的问题。这当然可以通过检查网格投影先后顺序来解决。但是参数化的要求是一对一的bijection,网格不能有折叠。

    固定边界(红色的点)求内部点V的位置,保证每个三角网格的法线一致:都朝纸外。

    %hard constaint
    idx = ones(numv,1);
    idx(idcon)=0;
    id_unkown = find(idx);
    % remove known vertex lines from L
    L(idcon,:)=[];
    % move column of boundary vertex in LV=0 to right
    V = [shx,shy];
    vh = sparse(double(V(idcon,:)));
    Rhs = -L(:,idcon) * (vh);
    % Unknow vertex on left
    Lhs = L(:,id_unkown);
    Vp = Lhs\Rhs;
    % copy back to vertex
    V(id_unkown,:) = full(Vp);
    
    figure
    trimesh( facetri, V(:,1), V(:,2), shz, 'EdgeColor', 'none', ...
        'FaceVertexCData', meantex/255, 'FaceColor', 'interp', ...
        'FaceLighting', 'phong'  );
    zlabel('Z');view(2);axis equal;hold on,
    shx = V(:,1); shy = V(:,2);
    plot3( shx(idcon),shy(idcon), zeros(length(idcon),1),'r.' );
    plot3( shx(idlmk),shy(idlmk), zeros(length(idlmk),1),'b.' );

    仍然用trimesh函数画出网格和颜色,以及边界和68个landmark的位置:

    固定边界也可以按照edge的长度比例固定在圆形(长度按比例对应2PI角)或者正方形上,比如映射到正方形上是这样(“好吓人!”):


    UV.png


    如果只固定少量边界点会怎样?比如只用8个点:

    idcon = idcon(1:round(end/8):end);


    如果在边界约束中加入部分face landmark会怎样?

    idcon = [idcon;idlmk(9);idlmk(18:end-20)];

    内部约束点会导致附近的三角形方向发生翻折,法线朝向纸内:

    用 triplot()函数叠加网格,在下巴点处放大观察:

    fix some 2.png


    参考:

    [1].计算稀疏矩阵L和W的函数cal_mesh_laplacian()参考自:

    http://www.numerical-tours.com/matlab




    http://blog.sciencenet.cn/blog-465130-1135112.html

    上一篇:三角剖分网格的邻接矩阵和Laplacian矩阵实验
    下一篇:三维网格在参数化uv图上进行网格重采样做Remesh

    0

    该博文允许注册用户评论 请点击登录 评论 (0 个评论)

    数据加载中...

    Archiver|手机版|科学网 ( 京ICP备14006957 )

    GMT+8, 2018-12-15 04:21

    Powered by ScienceNet.cn

    Copyright © 2007- 中国科学报社

    返回顶部