透视投影中3DMM系数的求解

今天总结代码, 想推导下透视投影下如何迭代求解3DMM的系数, 不经意间竟然发现如果给定Pose, 3DMM的系数竟然能够线性求解, 我很吃惊(透视投影不应该是非线性的吗?), 于是记录下来,经验证似乎没问题,验证代码如下:

在这里插入图片描述
在这里插入图片描述
带’的是乘上了R.

import numpy as np
import cv2 as cv

R = cv.Rodrigues(np.array([2, 1, 3.0]))[0].astype(np.float32)
t3d=np.array([3, 5, 100], dtype=np.float32)

nV = 30
dims = 20
E=np.random.rand(nV, 3, dims).astype(np.float32) 
V=np.random.rand(nV, 3).astype(np.float32)

def comp_x(x):
    S=V + E.dot(x)
    TS=S.dot(R.T) + t3d 
    dst = TS[:, :2] / TS[:, 2:] 
    return dst 

def solve_x(dst):
    V_ = V.dot(R.T) + t3d 
    E_ = (R.dot(E.transpose(1, 0, 2).reshape(3, -1)).reshape(3, nV, dims)).transpose(1, 0, 2).reshape(-1, dims)

    A=np.zeros((2*nV, dims), dtype=np.float32)
    b=np.zeros(2*nV, dtype=np.float32)

    for i in range(nV):

        A[i*2:i*2+2] = E_[i*3:i*3+2] - dst[i].reshape(2, 1).dot(E_[i*3+2].reshape(1, -1))
        b[i*2:i*2+2] = dst[i].reshape(-1)*V_[i, 2] - V_[i, :2] 

    AtA=A.T.dot(A)
    Atb=A.T.dot(b)

    x = np.linalg.inv(AtA).dot(Atb)
    return x

def pt_x(x): p(x.astype(np.int32))

x=(np.random.rand(dims)*10).astype(np.int32).astype(np.float32)
dst =  comp_x(x)

x_ = solve_x(dst)

dst_ = comp_x(x_)

pt_x(x)
pt_x(x_)

p( np.sum((dst_ - dst)**2))

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值