当前位置: 首页 > news >正文

莱州相亲网站在婚纱店做网站优化

莱州相亲网站,在婚纱店做网站优化,网络软件开发专业是做什么的,太原网站建设方案优化前言 之前出过三篇换脸的博文#xff0c;遇到一个问题是表情那一块不好处理#xff0c;可行方法是直接基于2D人脸关键点做网格变形#xff0c;强行将表情矫正到目标人脸#xff0c;还有就是使用PRNet的思想#xff0c;使用目标人脸的顶点模型配合源人脸的纹理#xff0c…前言 之前出过三篇换脸的博文遇到一个问题是表情那一块不好处理可行方法是直接基于2D人脸关键点做网格变形强行将表情矫正到目标人脸还有就是使用PRNet的思想使用目标人脸的顶点模型配合源人脸的纹理可以让表情迁移过来但是这个表情是很僵硬的。比如笑脸的3D顶点模型结合不笑人脸的纹理图生成的笑脸是非常奇怪的。有兴趣可以翻csdn前面的文章或者关注公众号检索人脸相关文章。 这里针对表情采用另一种方案——blendshape。这个理论在表情动画中经常使用到目的就是驱动人脸表情无论是动画人脸还是真人的人脸只要你这个人脸具有对应的顶点模型、纹理还有很多标准的blendshape模型分别对应不同的表情。 我们这里采用eos库实现表情变换一来是很多blendshape数据集获取难度比较大二来是这个库还是蛮好用的有C/python/matlab的接口而且与之前研究的PRNet有很多相似的的。 国际惯例参考博客 基于PRNet的3D人脸重建与替换 eos官方文档 eos源码 eos作者提供的model的可视化工具包括blendshape控制 算法流程 分为四步 人脸关键点提取3D人脸拟合表情驱动渲染 注意一般来说人脸重建是基于人脸关键点不断去调整3D标准人脸的使其变换到目标人脸的关键点形状这一点可以去知乎上看看3DMM人脸重建相关文章拟合过程一般涉及到两类参数形状、表情 预备 先安装一些必备的环境直接用pip安装eos-py、opencv-python、opencv-contrib-python 导入必要的库 import eos import numpy as np import cv2 from matplotlib import pyplot as plt然后把eos的源码下载保存在一个文件夹中我们写的代码都在eos源码文件夹并列的代码中写不要进到eos文件夹里面写代码面得污染了环境。 人脸关键点提取 之前人脸替换系列的博客都用的opencv人脸关键点检测方法这里也就不再说了直接贴代码 #初始化检测器 cas cv2.CascadeClassifier(./facemodel/haarcascade_frontalface_alt2.xml) obj cv2.face.createFacemarkLBF() obj.loadModel(./facemodel/lbfmodel.yaml)# 检测人脸关键点 def detect_facepoint(img):img_gray cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)faces cas.detectMultiScale(img_gray,2,3,0,(30,30))landmarks obj.fit(img_gray,faces)assert landmarks[0],no face detectedif(len(landmarks[1])1):print(multi face detected,use the first)return faces[0],np.squeeze(landmarks[1][0])#可视化图片 def vis_img(img):plt.imshow(cv2.cvtColor(img.copy(),cv2.COLOR_BGR2RGB))测试看看 img_file ./images/zly.jpg img cv2.imread(img_file) face_box,coords detect_facepoint(img)# 转换为eos库所需要的关键点输入格式 landmarks [] ibug_index 1 # count from 1 to 68 for all ibug landmarks for l in range(coords.shape[0]):landmarks.append(eos.core.Landmark(str(ibug_index), [float(coords[ibug_index-1][0]), float(coords[ibug_index-1][1])]))ibug_index ibug_index 1#可视化关键点 img_show img.copy() for kps in landmarks:face_kps kps.coordinatescv2.circle(img_show,(face_kps[0],face_kps[1]),5,(0,255,0),-1) vis_img(img_show) plt.axis(off)使用eos 重建人脸 因为是要用标准人脸和blendshape去拟合图片人脸关键点所以需要先初始化一堆内容这个是固定套路 # 初始化eos model eos.morphablemodel.load_model(./eos/share/sfm_shape_3448.bin) blendshapes eos.morphablemodel.load_blendshapes(./eos/share/expression_blendshapes_3448.bin) # Create a MorphableModel with expressions from the loaded neutral model and blendshapes: morphablemodel_with_expressions eos.morphablemodel.MorphableModel(model.get_shape_model(), blendshapes,color_modeleos.morphablemodel.PcaModel(), vertex_definitionsNone, texture_coordinatesmodel.get_texture_coordinates()) landmark_mapper eos.core.LandmarkMapper(./eos/share/ibug_to_sfm.txt) edge_topology eos.morphablemodel.load_edge_topology(./eos/share/sfm_3448_edge_topology.json) contour_landmarks eos.fitting.ContourLandmarks.load(./eos/share/ibug_to_sfm.txt) model_contour eos.fitting.ModelContour.load(./eos/share/sfm_model_contours.json)这个操作不用管只要使用这个eos库重建人脸只需把这一串代码复制下来用就行了把模型路径改改就行这些路径对应文件都在官方源码上有。 稍微解释一下作者为什么不把这一串操作封到一个对象里面我们使用的时候直接一句话初始一个对象就行了原因在于这个库是可以支持三种人脸模型(Surrey Face Model (SFM), 4D Face Model (4DFM), Basel Face Model (BFM))而且对应的blendshape表情数也可以增加还有很多其他的映射关系表也根据不同的模型而变化所以还不如全部暴露出来用户自行设置修改。 【注】上述初始化使用的人脸模型是SFM作者提供的这个模型对应的blendshapes只有六种表情anger, disgust, fear, happiness, sadness, surprise所以重建或者驱动效果其实不是特别理想但是能看出来有驱动。如果读者其它两种模型比如4DFM的人脸模型精细度(网格数目)就比较高而且多达36种表情就建议使用高精度模型尝试一波 初始化完毕就可以针对关键点进行拟合 # 重建人脸 (mesh, pose, shape_coeffs, blendshape_coeffs) eos.fitting.fit_shape_and_pose(morphablemodel_with_expressions,landmarks, landmark_mapper, image_width, image_height, edge_topology, contour_landmarks, model_contour)注意上面的返回值shape_coeffs和blenshape_coeffs就是3DMM人脸重建中经常说的形状系数和表情系数了前者拟合脸型后者拟合表情。待会表情驱动就是利用表情系数来做的。 如果还记得之前写的PRNet人脸重建文章里面有几个信息比较重要3D顶点、人脸纹理图、网格顶点索引在eos库中可以直接通过下面这句话获取纹理信息 # 提取纹理 isomap eos.render.extract_texture(mesh,pose,img).swapaxes(0,1)因为后面使用meshlab打开重建的人脸需要这个纹理文件所以提前保存一下顺便可视化一波 cv2.imwrite(result.isomap.png,isomap) vis_img(isomap)接下来就是需要根据得到的形状参数和表情系数将标准人脸变换成咱赵丽颖的人脸这里需要注意在issuee 35有人提到过C中使用这句话 auto merged_shape morphable_model.get_shape_model().draw_sample(fitted_coeffs) to_matrix(blendshapes) * Mat(blendshape_coefficients);但是在python中并未提供表情系数乘法对应的函数那么直接写一个 def blendshape_add(bss,bc):bs_array []for bs in bss:bs_array.append(bs.deformation)bs_array np.array(bs_array).transpose()bc np.array(bc)return np.dot(bs_array,bc)再仿照C代码写重建方法 merge_shape morphablemodel_with_expressions.get_shape_model().draw_sample(shape_coeffs) blendshape_add(blendshapes,blendshape_coeffs);表情驱动 如果要驱动表情那么仅仅改改表情系数就可以了比如 # 改变表情 anger, disgust, fear, happiness, sadness, surprise blendshape_coeffs [0,1,0,0,0,0]这只是获取了形状我们最终需要渲染的是mesh所以还需要做一个转换记录一下颜色信息顶点信息什么的 merged_mesh eos.morphablemodel.sample_to_mesh(merge_shape,morphablemodel_with_expressions.get_color_model().get_mean(),morphablemodel_with_expressions.get_shape_model().get_triangle_list(),morphablemodel_with_expressions.get_color_model().get_triangle_list(),morphablemodel_with_expressions.get_texture_coordinates());渲染 接下来介绍两种可视化方法 使用meshlab可视化因为上面我们保存过纹理文件所以这里只需要把mesh保存一下 outputfile result.obj eos.core.write_textured_obj(merged_mesh,outputfile);这时候我们就有了result.obj、result.mtl、result.isomap.png三个文件直接双击obj用meshlab打开 使用代码可视化按照之前学习PRNet中得到的知识需要分别获取到人脸模型的3D顶点坐标每个人脸网格顶点索引每个顶点的颜色信息这些在eos求取的mesh中都有分别取出来 triangles np.array(merged_mesh.tvi) # 人脸网格对应的顶点索引 # 人脸顶点 vertices [] for v in merged_mesh.vertices:vertices.append(np.array([v[0],-v[1],v[2]])) vertices np.array(vertices) vertices vertices-np.min(vertices) # 纹理坐标 texcoords [] for tc in merged_mesh.texcoords:texcoords.append(tc) texcoords np.array(texcoords) # 根据纹理坐标获取每个顶点的颜色 colors [] for i in range(texcoords.shape[0]):colors.append(isomap[int(texcoords[i][1]*(isomap.shape[0]-1)),int(texcoords[i][0]*(isomap.shape[1]-1)),0:3]) colors np.array(colors,np.float32)然后利用顶点的颜色求平均得到网格的颜色 #获取三角形每个顶点的color平均值作为三角形颜色 tri_tex (colors[triangles[:,0] ,:] colors[triangles[:,1],:] colors[triangles[:,2],:])/3.对每个网格上色 img_3D np.zeros_like(img,dtypenp.uint8) for i in range(triangles.shape[0]):cnt np.array([(vertices[triangles[i,0],0],vertices[triangles[i,0],1]),(vertices[triangles[i,1],0],vertices[triangles[i,1],1]),(vertices[triangles[i,2],0],vertices[triangles[i,2],1])],dtypenp.int32)img_3D cv2.drawContours(img_3D,[cnt],0,(int(tri_tex[i][0]), int(tri_tex[i][1]), int(tri_tex[i][2])),-1)可视化 plt.figure(figsize(8,8)) vis_img(img_3D)有人奇怪我上传的图片讲道理没张嘴啊为什么张嘴了因为我们驱动了表情 # 改变表情 anger, disgust, fear, happiness, sadness, surprise blendshape_coeffs [0,1,0,0,0,0]所以现在看起来是disgust这个表情为啥看起来不自然当然是因为丽颖的照片本来就在笑导致默认纹理在笑然后再加上blendshape比较粗糙看起来就有点怪怪的。 生成表情驱动的gif 通过上面的一系列操作我们可以基于eos自带的6种表情blendshape改变大颖妹子的面部表情那么来搞个gif玩玩思路就是对blendshape_coeffs做一个线性过渡即可 buff [] frame_num 20 for i in range(frame_num): #一个gif 10帧# 改变表情 anger, disgust, fear, happiness, sadness, surpriseblendshape_coeffs [1.0 - i/frame_num,0,0,0,0,i/frame_num]merge_shape morphablemodel_with_expressions.get_shape_model().draw_sample(shape_coeffs) blendshape_add(blendshapes,blendshape_coeffs);merged_mesh eos.morphablemodel.sample_to_mesh(merge_shape,morphablemodel_with_expressions.get_color_model().get_mean(),morphablemodel_with_expressions.get_shape_model().get_triangle_list(),morphablemodel_with_expressions.get_color_model().get_triangle_list(),morphablemodel_with_expressions.get_texture_coordinates());triangles np.array(merged_mesh.tvi) # 人脸网格对应的顶点索引# 人脸顶点vertices []for v in merged_mesh.vertices:vertices.append(np.array([v[0],-v[1],v[2]]))vertices np.array(vertices)vertices vertices-np.min(vertices)# 纹理坐标texcoords []for tc in merged_mesh.texcoords:texcoords.append(tc)texcoords np.array(texcoords)# 根据纹理坐标获取每个顶点的颜色colors []for i in range(texcoords.shape[0]):colors.append(isomap[int(texcoords[i][1]*(isomap.shape[0]-1)),int(texcoords[i][0]*(isomap.shape[1]-1)),0:3])colors np.array(colors,np.float32)#获取三角形每个顶点的color平均值作为三角形颜色tri_tex (colors[triangles[:,0] ,:] colors[triangles[:,1],:] colors[triangles[:,2],:])/3.img_3D np.zeros_like(img,dtypenp.uint8)for i in range(triangles.shape[0]):cnt np.array([(vertices[triangles[i,0],0],vertices[triangles[i,0],1]),(vertices[triangles[i,1],0],vertices[triangles[i,1],1]),(vertices[triangles[i,2],0],vertices[triangles[i,2],1])],dtypenp.int32)img_3D cv2.drawContours(img_3D,[cnt],0,(int(tri_tex[i][0]), int(tri_tex[i][1]), int(tri_tex[i][2])),-1)buff.append(cv2.cvtColor(img_3D,cv2.COLOR_BGR2RGB)) gifimageio.mimsave(expression.gif,buff,GIF,duration0.1)从愤怒到惊讶的效果图 后记 当前只是针对之前人脸替换的表情问题按照blendshape驱动的方法做了一个实验至于还有其它问题比如为啥这个人脸上有黑洞洞啊、怎么把人脸拼接到原图上这个后续有机会再去折腾了这个eos库的python接口文档不是特别详细而且没C那么完善。建议真有兴趣的老铁多看看issues里面有很多有趣的问题。 代码上面都放出来了如果想要我实验的代码直接关注微信公众号在公众号简介中的github中获取同时本博文也同步更新到微信公众号中
http://wiki.neutronadmin.com/news/173150/

相关文章:

  • 网站优化的主要内容品牌设计公司排行榜
  • 如何建立竞价网站烟台网站优化公司
  • 响应式网站什么意思小程序店铺怎么弄
  • 动态手机网站wordpress 电话
  • 个人网站建设第一步专业北京网站建设公司哪家好
  • 微信端微网站怎么做wordpress the 7
  • 旅游网站建设注册网页设计及制作方法
  • 网站维护中模版高端网站制作建设
  • 建网站服务器用什么个人介绍网页模板免费下载
  • 班级网站怎么做ppt企业网络推广分析
  • 17zwd一起做网站广州新塘旅游网站建设规划报告怎么写
  • 自己做的产品在哪个网站上可从卖深圳企业登记注册
  • 网站建设亿玛酷技术动漫制作软件
  • 单位网站等级保护必须做吗从零开始做电影网站
  • 网站建设丷金手指专业十五个人域名怎么做社交网站
  • 知知网站推荐wordpress主题市场
  • 辽宁高端网站建设土建找工作去哪个网站
  • 葫芦岛网站建设找思路建设银行通控件网站
  • 查询网站是否过期星子网今天最新新闻
  • 网站开发培训设计企业数字化管理
  • 博客推广那个网站列好做优秀企业网站
  • 资讯类网站源码wordpress 配置ftp
  • 自学网站建设要看什么书农资网络销售平台
  • 玉溪市网站建设如何学习wordpress
  • 微信网站开发用什么语言怎样建设企业网站 用于宣传
  • 网站开发技术岗位职责wordpress 忘记用户名密码破解
  • 咨询网站公司建设计划书如何做某网站的移动客户端开发
  • 信息可视化网站提供免费建网站的网
  • 网站建设的功能特点有哪些网站开发学什么数据库
  • 灵璧做网站的公司安徽省建设安全协会网站