从UV位置图获得3D人脸
1. 这部分主要写从UV位置图获得3D人脸,并不包括如何产生UV位置图。
我已经获取一张图片的UV位置图,如下图:
(a. 裁剪后的人脸区域) (b. UV位置图 (仅用来展示的)) (c. UV纹理图)
a, b, c 三张图片shape都是(255, 255, 3) , UV位置图 b 并不是真正的 UV位置图, 只是将UV位置图转化成图像显示出来。
接下来, 利用a, b 获取 a中人脸对应的3D模型。
2. 主要代码
"""
如何 从 Position Map 产生 3D Face
"""
import numpy as np
import os
from skimage.io import imread, imsave# 类似 超参数
uv_kpt_ind = np.loadtxt("datas/uv-data/uv_kpt_ind.txt").astype(np.int32) # 2 x 68 get kpt
face_ind = np.loadtxt("datas/uv-data/face_ind.txt").astype(np.int32) # get valid vertices in the pos map
triangles = np.loadtxt("datas/uv-data/triangles.txt").astype(np.int32) # ntri x 3# 测试一个例子
face_url = "datas/image00050.jpg"
face_texture_url = "datas/image00050_tex.jpg"
# Label 是 npy 数据, 可不是 position map图像(只是用来显示看的)
face_posmap_url = "datas/image00050.npy" # 真正的 UV Position Mapglobal resolution_op
resolution_op = 256
# 设置参数
uv_h = uv_w = 256
image_h = image_w = 256image_posmap = np.load(face_posmap_url)
print(image_posmap.shape)
print(np.max(image_posmap))# 从 Position Map 获取 顶点
def get_vertices(pos):'''Args:pos: the 3D position map. shape = (256, 256, 3).Returns:vertices: the vertices(point cloud). shape = (num of points, 3). n is about 40K here.'''all_vertices = np.reshape(pos, [resolution_op ** 2, -1])vertices = all_vertices[face_ind, :] # face_ind 是什么呢?return verticesdef get_landmarks(pos):"""Args:pos: the 3D position map. shape = (256, 256, 3).Returns:kpt: 68 3D landmarks. shape = (68, 3).:param pos::return:"""kpt = pos[uv_kpt_ind[1, :], uv_kpt_ind[0, :], :]return kptkpt = get_landmarks(image_posmap)
print(kpt.shape) # (68, 3) 68个关键点vertices = get_vertices(image_posmap)
print(vertices.shape) # (43867, 3) PRNet 人脸是 43867 个顶点# 保存顶点 不保存纹理
def dump_to_ply(vertex, tri, wfp):header = """plyformat ascii 1.0element vertex {}property float xproperty float yproperty float zelement face {}property list uchar int vertex_indicesend_header"""n_vertex = vertex.shape[1] # ((3, 43867))n_face = tri.shape[1] # ((3, 86906))header = header.format(n_vertex, n_face)with open(wfp, 'w') as f:f.write(header + '\n')for i in range(n_vertex): # 顶点x, y, z = vertex[:, i]f.write('{:.4f} {:.4f} {:.4f}\n'.format(x, y, z))for i in range(n_face): # 三角形idx1, idx2, idx3 = tri[:, i]f.write('3 {} {} {}\n'.format(idx1 - 1, idx2 - 1, idx3 - 1))print('Dump tp {}'.format(wfp))save_prefix = "results/"
name = face_url.split("/")[-1].split(".")[0] + ".ply"
print(name)
face_ply = os.path.join(save_prefix, name)# 保存 顶点信息 shape 成功
dump_to_ply(vertices.T, triangles.T, face_ply) # 切记 tri 是 /Data/uv-data/triangles.txt 中的三角# 保存 带上 color/texture 信息
def get_colors(image, vertices):"""Args:pos: the 3D position map. shape = (256, 256, 3).Returns:colors: the corresponding colors of vertices. shape = (num of points, 3). n is 45128 here."""[h, w, _] = image.shapevertices[:, 0] = np.minimum(np.maximum(vertices[:, 0], 0), w - 1) # xvertices[:, 1] = np.minimum(np.maximum(vertices[:, 1], 0), h - 1) # yind = np.round(vertices).astype(np.int32)colors = image[ind[:, 1], ind[:, 0], :] # n x 3return colorsimage_face = imread(face_url) # face_url 是 剪切后为(256, 256, 3)的人脸图像
[h, w, c] = image_face.shape
print(h, w, c)
image_face = image_face / 255.
colors = get_colors(image_face, vertices) # 从人脸 和 顶点 中获取 color (43867, 3)
print(colors.shape)# 写入 .obj文件,具有colors (texture)
def write_obj_with_colors(obj_name, vertices, triangles, colors):''' Save 3D face model with texture represented by colors.Args:obj_name: strvertices: shape = (nver, 3)colors: shape = (nver, 3)triangles: shape = (ntri, 3)'''triangles = triangles.copy()triangles += 1 # meshlab start with 1if obj_name.split('.')[-1] != 'obj':obj_name = obj_name + '.obj'# write objwith open(obj_name, 'w') as f:# write vertices & colorsfor i in range(vertices.shape[0]):# s = 'v {} {} {} \n'.format(vertices[0,i], vertices[1,i], vertices[2,i])s = 'v {} {} {} {} {} {}\n'.format(vertices[i, 0], vertices[i, 1], vertices[i, 2], colors[i, 0],colors[i, 1], colors[i, 2])f.write(s)# write f: ver ind/ uv ind[k, ntri] = triangles.shapefor i in range(triangles.shape[0]):# s = 'f {} {} {}\n'.format(triangles[i, 0], triangles[i, 1], triangles[i, 2])s = 'f {} {} {}\n'.format(triangles[i, 2], triangles[i, 1], triangles[i, 0])f.write(s)
name = face_url.split("/")[-1].split(".")[0] + ".obj"
save_vertices = vertices.copy()
save_vertices[:, 1] = h - 1 - save_vertices[:, 1] # 这一步 不可缺少; (43867, 3)
write_obj_with_colors(os.path.join(save_prefix, name), save_vertices, triangles, colors) # save 3d face(can open with meshlab)
3. obj, ply 文件 用 MeshLab 打开后的效果:
.ply 文件效果:
.obj 文件效果:
从原始UV位置图产生3D人脸,条纹现象不是特别严重, PRNet 预测的效果,条纹效果严重。
代码和文件链接
https://github.com/DongPoLI/Face-3D-Study/tree/master/generate_position_map
————————————————
版权声明:本文为CSDN博主「挡不住三千问的BlueCat」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_23944915/article/details/105046742
从UV位置图获得3D人脸相关推荐
- 一文为你详解2D与3D人脸识别有什么区别?
最近业界内刮起了一股"人脸识别安全"的大讨论,小到个人大到超市以及银行,都在使用这个刷脸认证或支付,说它好吧,确实解决了无接触,快速高效等问题,你说它不好吧,也是有原因的,比如最明 ...
- 3D人脸重建——PRNet网络输出的理解
前言 之前有款换脸软件不是叫ZAO么,分析了一下,它的实现原理绝对是3D人脸重建,而非deepfake方法,找了一篇3D重建的论文和源码看看.这里对源码中的部分函数做了自己的理解和改写. 国际惯例,参 ...
- 七点人脸姿态估计_Github开源库简单配置即可上线的3D人脸检测工具箱
[导读]人脸识别/检测是计算机视觉方向的一个基础的任务.小编在Github中找到了一个轻松配置即可上线使用的3D人脸检测工具箱,该工具箱包括多种特性:2D稀疏点.稠密点.3D.深度图.PNCC.UV纹 ...
- DECA:基于单张静态图像,进行 3D 人脸建模
作者|神经三羊 来源|HyperAI超神经 By 超神经 内容概要:本文罗列了 3D 人脸建模常用的 3 大方法,以及基于静态图像进行人脸建模的 3 个方法.文末分享了一个 DECA 教程. 关键词: ...
- 最新3D人脸技术综述
点击我爱计算机视觉标星,更快获取CVML新技术 目录 导语 3D人脸基础知识 初识3D人脸 相机模型 3D相机 3D人脸数据 3D人脸相关任务 常见Pipeline 3D人脸识别 3D人脸重建 总结 ...
- 一分钟详解3D人脸技术
点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 目录 导语 3D人脸基础知识 初识3D人脸 相机模型 3D相机 3D人脸数据 3D人脸相关任务 常见P ...
- 2D与3D人脸识别有什么本质上的区别?
https://www.zhihu.com/question/324123433/answer/681365180 https://www.zhihu.com/question/324123433/a ...
- 3D人脸技术漫游指南
目录 导语 3D人脸基础知识 初识3D人脸 相机模型 3D相机 3D人脸数据 3D人脸相关任务 常见Pipeline 3D人脸识别 3D人脸重建 总结 导语 随着深度学习技术的推进,人脸相关任务研究也 ...
- 3D人脸重建硕博论文阅读
基于人脸单视图的3D人脸重建方法研究(华南理工) 摘要 基于人脸正视图来开展 3D 人脸重建.在选择人脸正面图像后,采用主动形状模型(Active Shape Model,ASM)算法进行人脸对齐,从 ...
最新文章
- 精确监听AbsListView滚动至底部
- 文件操作工具类FileUtil
- 阿里云mysql5.7 窗口函数_关于阿里云centos版本,mysql5.7的一些注意事项
- 30 个提高Web 程序执行效率的好经验[转]
- Java番外篇4——BigInteger与BigDecimal
- 制作首页的显示列表(2017.11.29)
- c语言10怎么打开文件,Lecture 10 C语言文件操作
- CSS布局中应用BFC的例子
- 《大话操作系统——扎实project实践派》(8.2)(除了指令集.完)
- AKOJ-2021-逆序对(归并,二分)
- html如何转换成中文,html中文乱码怎么解决怎么造成如何避免中文乱码
- 香蕉树上第一根芭蕉——关于C语言中链表(动态链表静态链表)使用说明
- RecorderManager安卓仿微信自定义音视频录制第三方库
- python之html网页转PDF
- 我的奋斗之黑马第一天
- 【7】win10 病毒和威胁防护服务停止,立即重启报错
- More Effective C++之 Item M35:让自己习惯使用标准C++语言
- 云计算基础技术及解决方案介绍 - ZCCT考试
- OllyDBG 破解入门教程
- MATLAB与STK互联46:在场景中加入某个国家作为Area Target对象(GIS命令使用)
热门文章
- Windows10 + Visual Studio 2017 + CMake +OpenCV编译、开发环境配置及测试
- linux fcntl 函数 文件描述符选项控制
- windbg拦截驱动
- Linux 下查看文件的命令介绍
- 字符编码总结(UTF-8,UNICODE)
- 高级语言的编译:链接及装载过程介绍
- Linux内核子系统
- java string s_Java字符串:“String s=新字符串(”愚蠢“);
- 安装bigsur卡在12分钟_Big Sur为什么安装不了?macOS Big Sur无法完成安装的解决办法!...
- java maven清理打包运行