python Deformation Transfer for Triangle Meshes
这个主要是给自己看的,这个脚本是自己第一次思考如何构建如此复杂稀疏矩阵的方法,并进行加速,里面有一些思考的要素,值得以后记住。
@20-5-20
补充之前缺少的代码 【在最后】
算法要点: 稀疏矩阵是 ( n F ∗ 3 ∗ 3 ) × ( 3 ∗ ( n V + N F ) ) (nF*3*3)\times(3*(nV+NF)) (nF∗3∗3)×(3∗(nV+NF))
构造的时候把握每个面片的构造,应该是 A ( 3 ∗ 3 ) = B ( 3 ∗ 4 ) × C ( 4 ∗ 3 ) A(3*3)=B(3*4)\times C(4*3) A(3∗3)=B(3∗4)×C(4∗3). 其中B是个稀疏矩阵,本意就是构造 A = ( ( v 2 − v 1 ) T , ( v 3 − v 1 ) T , ( v 4 − v 1 ) T ) A=((v2-v1)^T, (v3-v1)^T, (v4-v1)^T) A=((v2−v1)T,(v3−v1)T,(v4−v1)T), 也可以看出来其实对于每个面片其实最后组成的系数矩阵每行也只有四个元素起作用。 C = ( v 1 T , v 2 T , v 3 T , v 4 T ) C=(v1^T, v2^T, v3^T, v4^T) C=(v1T,v2T,v3T,v4T) 。
B = [ − 1 1 − 1 1 − 1 1 ] B=\begin{bmatrix} -1 & 1 & & \\ -1 & & 1 & \\ -1 & & & 1 \end{bmatrix} B=⎣⎡−1−1−1111⎦⎤
注意 v4是每个面有一个,共nF 个,因此 优化的顶点数为 nV+nF 个。
然后就需要构造最终的大矩阵,设法把B提前乘进去,这样变量 x 就只包括顶点位置了。然后求解类似 Ax=b 这种的方程就行(和上面那个A不一样)。
事后感觉, 这里似乎就是为了避免求法向量, 直接把v4 当作变量优化出来.
S: V1->V2
T: V3->V4
def run():fobjs=["../tempdir/scans_hd_smooth2/36/1.obj", "../tempdir/scans_hd_smooth2/36/15.obj","../tempdir/scans_hd_smooth/36/1.obj"]#nV*3, nF*3v1, F = get_obj_v_f(fobjs[0])v2 = get_obj_v(fobjs[1])v3 = get_obj_v(fobjs[2])f, v1, v2, v3 = [ np2th(e) for e in [F.astype(np.int64), v1, v2, v3] ] tm_bg= time.time()V1 = get_init_V_(v1, f)V2 = get_init_V_(v2, f)V3 = get_init_V_(v3, f)# V1->V2# 可能出现奇异值的情况Q=V1.pinverse().bmm( V2 ) # 果然不能死抄公式,要与自己的分析一致# 注意 待求解的是 3*(nV+nF)V3_inv = V3.pinverse()nF = f.size(0)nV = v1.size(0)tri=[]s_h = nF*9s_w = (nF+nV) * 3sparse_info=get_sparse_info( nF*3*3*4 )cM=torch.zeros((3, 4))if nptype==np.float64: cM=cM.double()cM[:, 0] = -1cM[:, 1:] = torch.eye(3)# A_full : (nF*9) * ((nV+nF)*3)_As = V3_inv.bmm(cM.unsqueeze(0).expand( nF, 3, 4 ).clone()).numpy() # 其实这个可以用einsum sparse_info.i[:] = np.arange(nF*3*3).repeat(4)sparse_info.d[:] = _As.reshape(nF, 3, 1, 4).repeat(3, axis=2).reshape(-1)# 上面的比下面的快 100倍多, 简直不敢想象# 每行有4个, 作用nF, 9 行#j1 = F.reshape(nF,3, 1 ).repeat(1, 1, 9).transpose(0, 2, 1).reshape(nF, 3, 3, 3) * 3j1 = F.reshape(nF, 1, 3 ).repeat(9, axis=1).reshape(nF, 3, 3, 3) * 3j1[:, :, 1] += 1j1[:, :, 2] += 2j1 = j1.reshape(-1, 3)j2 = (np.arange(nF).astype(np.int32) + nV).repeat(9).reshape(nF, 3, 3) *3j2[:, :, 1] += 1j2[:, :, 2] += 2j2 = j2.reshape(-1, 1)sparse_info.j[:] = np.hstack( (j1, j2) ).reshape(-1)# 写的时候主要看下面到底是哪一列需要重复, 然后就 repeat#for i in range(nF):# A = _As[i]# for j in range(3):# for k in range(3):# bid = i*9+j*3+k# for kk in range(4):# sparse_info.i[bid*4+kk]=bid# sparse_info.d[bid*4+kk]=A[j, kk]# if kk<3:# sparse_info.j[bid*4+kk]=f[i, kk]*3+k# else:# sparse_info.j[bid*4+kk]=(nV+i)*3+kp("time use:", time.time()-tm_bg)s = sparse_infoA = scipy.sparse.coo_matrix(( s.d, (s.i, s.j)), shape=(s_h, s_w)).tocsr()b = Q.view(-1).numpy()AtA=A.T.dot(A)Atb=A.T.dot(b)x = spsolve(AtA, Atb)p("time use:", time.time()-tm_bg)v =x.reshape(-1, 3)[:nV]save_obj("../tempdir/ck.obj", v, F)def get_sparse_info(n):class info:i=np.zeros(n , dtype=np.int32)j=np.zeros(n , dtype=np.int32)d=np.zeros(n, dtype=nptype)return info# 论文中需要的V
def get_init_V_(v, f, isnp=True):if nptype==np.float64: v= v.double()vs = v[f.view(-1)].view(-1, 3, 3)a = vs[:, 0]b = vs[:, 1]c = vs[:, 2]v2_1 = b-av3_1 = c-av4_1 = thF.normalize(v2_1.cross(v3_1), eps=1e-20, dim=1)V = torch.cat( (v2_1, v3_1, v4_1), 1 )# 注意这里 我是按照行的和论文中不一样,但是这样求解就免去转置了return V.view(-1, 3, 3) def kronecker(A, B):return torch.einsum("ab,cd->acbd", A, B).view(A.size(0)*B.size(0), A.size(1)*B.size(1))
之前缺少的代码
读取obj 有关的在下面找到
https://github.com/changhongjian/SimRender/blob/master/lib/comm/geometry.py
其他的
def np2th(e): return torch.from_numpy(e)
def np2th_gpu(e): return torch.from_numpy(e).cuda()
def th2np(e): return e.detach().cpu().numpy()# 其他就是Import了,缺什么自己补吧
import torch
import numpy as np
import time
import scipy
import torch.nn.functional as thF
from scipy.sparse.linalg import spsolve
python Deformation Transfer for Triangle Meshes相关推荐
- Deformation Transfer for Triangle Meshes
1.where S refers to the set of triangle indices for the source mesh. 这里S是指source三角形的个数 2.M集合里面的pair个 ...
- Polygon Mesh Processing读书笔记——1三角网格Triangle Meshes
最近看论文深感基础知识的匮乏,所以补充一些图形几何方面的知识,首先是这本书的封面. 主要章节介绍 本书讨论了基于多边形网格的几何处理管道的主要组件,如下图所示. 为了本书的指导目的,主题的描述顺序与图 ...
- Q95:纹理映射(Texture Mapping)(3)——Triangle Meshes
首先,声明一下: 个人感觉这一章节有点鸡肋,因为通过"纹理映射"的方式给Triangle Meshes图形添加纹理貌似不太常用. 1,理论分析 能够通过"纹理映射&quo ...
- Hierarchical deformation of Locally Rigid Meshes
这篇文章的主要思想是, 先通过 edge collapse 将 mesh 简化, 然后呢通过变形简化的模型 , 重建出复杂的模型, 行为有点类似于embedding deformation那篇 2.1 ...
- Q91:真实地模拟透明材质(Realistic Transparency)(2)——Triangle Meshes
这一章节是在"Q91:真实地模拟透明材质(Realistic Transparency)"的基础上测试一下Triangle Mesh图形. 之前章节的链接:http://blog. ...
- 变形迁移(Deformation Transfer)DT
DT一般用于人脸表情基迁移,人体运动迁移等等. 直接上干货:上个比 开源代码效果还差的效果 从左边到右边就是表情迁移,一般完成这个工作分两步: 1. 将上面模型与表情基模型做非刚性配准 上述三 ...
- 卡通角色表情驱动系列二
前言 之前介绍了使用传统算法求解BS系数的表情驱动方法,其中提到过的三种方法之一是基于网格形变迁移做的,那么这篇文章就是对<Deformation Transfer for Triangle M ...
- 卡通角色表情驱动系列一
前言 分析完ThreeDPoseTracker来做卡通角色的身体驱动,接下来在卡通驱动领域还有一个是表情驱动.对这个真的是一窍不通啊,只能慢慢看论文了. 国际惯例,参考博客/论文: <Landm ...
- 3D Human Body Reshaping with Anthropometric Modeling 阅读翻译
3D Human Body Reshaping with Anthropometric Modeling 阅读翻译 最近着手做3D人体编辑相关内容,先从文章开始学习 一下文章github地址:http ...
最新文章
- Android-广播接收者简介
- linux驱动(七)gpiolib库详解
- C# Color颜色对照表
- 安装SQL Sever2017时出现“Polybase要求安装Oracle JRE 7更新51(64位)或更高版本规则失效”的解决办法
- 使用视频追踪算法研究物体运动轨迹
- SwiftUI学习笔记-【列表】
- 洛谷刷题笔记 鸡尾酒疗法
- 电脑和手机好用的播放器
- 有关VScode 配置MinGW32_9.2.0+OpenGL+GLFW+GLAD
- c语言程序表达语句,《C语言程序设计》讲稿.doc
- 数据泄露的类型以及如何防止它们
- 计算机无法共享的原因,不能共享的原因
- 本地JSON格式化工具下载
- 控制别人计算机鼠标点了无反应,Win10电脑qq远程协助时为什么无法控制对方电脑或则点了对方电脑没反应...
- 【网络安全】LemonDuck木马进化,危害性增强
- 一篇生物学博士的自白,写的很不错,博士生的真实写照
- 右键管家MenuMgr-1.2单文件
- Pytorch 多层感知机
- matlab 如何输出gif,MATLAB生成GIF动画,PhotoShop制作GIF动画
- 南京邮电大学智慧云校园,业务上线速度提升60%
热门文章
- 电子书下载:CRM Fundamentals
- 人脸识别与美颜算法实战-图像特效
- 【2018.12.14】python3.7 一个低级趣味的爬虫(requests+pyquery)妹纸的图哇咔咔
- 正在载入中......loading页面的几种方法
- PPIO数据碎片化分散存储
- 3.2 电话号码对应英语单词
- 谷歌浏览器Console不显示error信息
- idea怎样创建jsp文件
- 「计算机日常」笔吧测评室笔记本测评科普视频笔记
- 2020德勤面试开始了吗_四大2020年春招时间曝光!