计算机视觉——两视图几何求解投影矩阵

上文我提到了通过图像匹配得到基本矩阵,接下来我们要接着求解投影矩阵。

计算投影矩阵思路

假设两个投影矩阵为规范化相机,因此采用基本矩阵进行恢复。在规范化相机下, P = [ I ∣ 0 ] P=[I|0] P=[I∣0], P ′ = [ M ∣ m ] P'=[M|m] P=[Mm]
我们知道一对 ( P , P ′ ) (P,P') (P,P)可以唯一确定基本矩阵 F = [ m ] x M F=[m]_xM F=[m]xM,而基本矩阵则在相差一个射影变换的意义下才能唯一对应一组 ( P , P ′ ) (P,P') (P,P)
P = [ I ∣ 0 ] P=[I|0] P=[I∣0], P ′ = [ [ e ′ ] x F ∣ e ′ ] P'=[[e']_xF|e'] P=[[e]xFe],其中 e ′ e' e e ′ T F = 0 e'^TF=0 eTF=0的对极点。因此我们需要求解对极点。而对极点是极线聚焦的点:
l 1 × l 2 = e l_1 ×l_2=e l1×l2=e
同时我们可以通过两点确定一条直线:
p 1 × p 2 = l p_1 × p_2 = l p1×p2=l

这种点叉积为线,线叉积为点叫做对偶

def drawlines(img1,img2,lines,pts1,pts2):

    r,c,_ = img1.shape
    for r,pt1,pt2 in zip(lines,pts1,pts2):
        color = tuple(np.random.randint(0,255,3).tolist())
        x0,y0 = map(int, [0, -r[2]/r[1] ])
        x1,y1 = map(int, [c, -(r[2]+r[0]*c)/r[1] ])
        img1 = cv2.line(img1, (x0,y0), (x1,y1), color,1)
        img1 = cv2.circle(img1,tuple(pt1),5,color,-1)
        img2 = cv2.circle(img2,tuple(pt2),5,color,-1)
    return img1,img2

pts1 = np.int32(src_points)
pts2 = np.int32(dst_points)
lines1 = cv2.computeCorrespondEpilines(pts2.reshape(-1,1,2), 2,F)
lines1 = lines1.reshape(-1,3)
img_line1,_ = drawlines(left_img,right_img,lines1,pts1,pts2)

lines2 = cv2.computeCorrespondEpilines(pts1.reshape(-1,1,2), 1,F)
lines2 = lines2.reshape(-1,3)
img_line2,_ = drawlines(right_img,left_img,lines2,pts2,pts1)

在这里插入图片描述
然后我们统计一下对极点,还是采用SVD分解。因为两条直线相交能够唯一确定一个点,而我们这里有数十条直线,它们不一定能确保相交于一个点。因此我们需要找到一个点 e e e,使得 e e e到每一条直线的距离和最小,也就是:
a r g m i n e ∑ i N d i s t ( l i , e ) \underset{e}{argmin}\sum_{i}^{N} dist(l_i,e) eargminiNdist(li,e)
然后根据我上面写的公式 P = [ I ∣ 0 ] P=[I|0] P=[I∣0], P ′ = [ [ e ′ ] x F ∣ e ′ ] P'=[[e']_xF|e'] P=[[e]xFe]即可算出P矩阵

Ⅰ. [ a ] x [a]_x [a]x表示a×b中a的矩阵写法。当我们计算两个向量的叉积时,可以将向量写成一个反对称矩阵 [ a ] x [a]_x [a]x的形式。
Ⅱ. 设 a ⃗ = ( a 1 , a 2 , a 3 ) , [ a ] x = [ 0 − a 3 a 2 a 3 0 − a 1 − a 2 a 1 0 ] 设\vec{a}=(a_1,a_2,a_3),[a]_x=\begin{bmatrix} 0 & -a_3 &a_2 \\ a_3 & 0 & -a_1 \\ -a_2 & a_1 & 0 \end{bmatrix} a =(a1,a2,a3)[a]x= 0a3a2a30a1a2a10
Ⅲ. np.array格式的矩阵可以用@进行相乘,当然还有np.dot(),np.multiply(),np.matmul(),可以查一下区别。

def getEpiPoint(A):
    U,sigma,VT = np.linalg.svd(A)
    pts = VT.T[:,-1]
    pts  = pts / pts[2]
    return pts
Epts1 = getEpiPoint(lines1) 
Epts2 = getEpiPoint(lines2)
e2x = np.array([[0,-Epts2[2],Epts2[1]],[Epts2[2],0,-Epts2[0]],[-Epts2[1],Epts2[0],0]])
P1 = np.array([[1,0,0,0],
      [0,1,0,0],
      [0,0,1,0]])
P2 = np.column_stack((e2x @ F,np.array(Epts2).T))

对投影矩阵分解得到内参

我们知道 P = K [ R ∣ t ] = [ K R ∣ K t ] P=K[R|t]=[KR|Kt] P=K[Rt]=[KRKt],设 P P P前三列为 P ^ \hat P P^,那么我们对 P ^ \hat P P^进行QR分解可以得到两矩阵。在QR分解中,左Q矩阵为正交矩阵,右R矩阵为上三角矩阵,而 P ^ = K R \hat{P}=KR P^=KR中K为上三角矩阵,R为正交矩阵,与QR分解得到的矩阵并不能对应上。因此我们应该先对 P ^ \hat{P} P^进行求逆, P ^ − 1 = R − 1 K − 1 \hat{P}^{-1}=R^{-1}K^{-1} P^1=R1K1,而正交矩阵和上三角矩阵的逆仍保持自身的性质,因此我们对 P ^ \hat{P} P^进行QR分解,得到矩阵再求一遍逆即可。

def decompose_projection_matrix(projection_matrix):

    R_inv, K_inv = np.linalg.qr(np.linalg.inv(projection_matrix[:, :3])) 
    K_inv_tmp = K_inv
    K_inv /= K_inv[2, 2]  # 归一化

    K = np.linalg.inv(K_inv)
    R = np.linalg.inv(R_inv)
    # if np.linalg.det(K) < 0:
    #     K *= -1
    extrinsic_matrix = np.matmul(K_inv_tmp, projection_matrix)

    return K, R, extrinsic_matrix

线性三角测量

投影矩阵是将世界三维点投影到图像二维点,因此我们想通过图像二位点和投影矩阵恢复出三维点,从而恢复出图像中物体三维结构,这个过程叫做三维重建。想要恢复出较好的三维图,需要大量的多角度图片进行拍摄和计算。而两张图片只能用于简单的三维坐标计算。
λ [ x y 1 ] = P [ X Y Z 1 ] \lambda \begin{bmatrix} x\\ y\\ 1 \end{bmatrix}=P\begin{bmatrix} X \\ Y \\ Z \\ 1 \end{bmatrix} λ xy1 =P XYZ1
想要使用SVD分解就需要构造 A X = 0 AX=0 AX=0的形式。我们发现xPX是成比例的的,因此x × PX=0,从而得到:
x ( p 3 T X ) − ( p 1 T X ) = 0 y ( p 3 T X ) − ( p 2 T X ) = 0 x ( p 2 T X ) − y ( p 1 T X ) = 0 \begin{align*} x(p^{3T}X)-(p^{1T}X) & = 0 \\ y(p^{3T}X)-(p^{2T}X) & =0\\ x(p^{2T}X)-y(p^{1T}X) & = 0 \end{align*} x(p3TX)(p1TX)y(p3TX)(p2TX)x(p2TX)y(p1TX)=0=0=0
其中 p i T p^{iT} piT P P P的行的转置,这三个方程的系数的秩为2。
然后结合x × PX=0x’ × P’X=0得到:
A = [ x p 3 T − p 1 T y p 3 T − p 2 T x ′ p ′ 3 T − p ′ 1 T y ′ p ′ 3 T − p ′ 2 T ] , A X = 0 A = \begin{bmatrix} xp^{3T}-p^{1T} \\ yp^{3T}-p^{2T} \\ x'p'^{3T}-p'^{1T} \\ y'p'^{3T}-p'^{2T} \end{bmatrix},AX=0 A= xp3Tp1Typ3Tp2Txp3Tp1Typ3Tp2T ,AX=0
从而能够解出X的坐标。

def triangulate(P1, P2, x1, x2):
    A = np.vstack((x1[0] * P1[2] - P1[0],
                   x1[1] * P1[2] - P1[1],
                   x2[0] * P2[2] - P2[0],
                   x2[1] * P2[2] - P2[1]))
    _, _, VT = np.linalg.svd(A)
    X_homogeneous = VT.T[:,-1]
    
    X_homogeneous /= X_homogeneous[3] 
    X = X_homogeneous[:3] 
    
    return X

之后会给大家更新黄金标准标定算法和由基本矩阵诱导的单应性。今天看到课程成绩出来了,并没有达到我的预期,哎就这样吧。

  • 29
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 计算机视觉中多视图几何是指在图像处理和计算机视觉过程中,利用多个视角或摄像机位置对目标进行观察和分析的技术。在三维对象的重建、姿态估计、目标跟踪等领域中,多视图几何具有重要的应用价值。 多视图几何涉及到三维坐标系、相机内参、相机外参、相机姿态、图像对极约束等概念和知识点。其中,相机内参是指相机本身的属性参数,包括焦距、畸变系数等;相机外参则表示相机在某一位姿态下的位置和方向。 在计算机视觉领域,多视图几何研究的目的主要是将不同角度、不同分辨率的图像进行匹配,实现目标物体的准确重建和位姿估计。 针对多视图几何的研究,已经有大量的论文和教材可以参考。其中,多视图几何一书是该领域较为经典的著作之一,可以在网上找到该书的PDF下载。 总之,多视图几何计算机视觉领域中的重要技术之一,掌握该技术对于进行三维重建与位姿估计等任务有着重要的意义。 ### 回答2: 计算机视觉中多视图几何的PDF下载是指下载介绍计算机视觉中多视图几何的相关PDF文档,以帮助人们更好地了解和学习这一领域的知识。多视图几何计算机视觉基本理论之一,它研究如何从多个视角拍摄的图像中恢复出三维场景信息。这项技术的主要应用包括机器人视觉、三维重建、立体测量、运动分析等。多视图几何的研究领域涉及相机模型、相机标定、立体匹配和三维重建等方面。 在计算机视觉中,多视图几何的研究和应用非常重要。因此,有很多学者和研究机构在这一领域开展了大量的研究工作,并出版了丰富的学术论文和研究报告。这些文献对于想要深入学习多视图几何的人来说非常有帮助。通过下载相关的PDF文档,可以更加全面地了解多视图几何的概念、原理和应用。掌握多视图几何的知识对于从事计算机视觉相关工作的人来说非常重要,可以帮助他们解决实际问题,提高研究成果的质量和效率。 总之,对于想要在计算机视觉中深入学习多视图几何的人来说,下载相关的PDF文档是非常必要的。通过多视图几何的学习,可以更好地理解计算机视觉基本理论,提高在实际工作中解决问题的能力和水平。 ### 回答3: 计算机视觉中的多视图几何指的是将多个视角或相机的信息融合在一起来重建三维场景的数学模型。从理论上讲,通过多视角信息,我们可以准确地推导出三维场景中的各种深度、尺寸和方向等几何属性。在实际应用中,多视图几何被广泛用于目标跟踪、立体视觉、3D扫描等领域。 关于多视图几何的理论掌握,可以通过阅读PDF下载资料来掌握。PDF下载中通常包括多视图几何基本理论、数学模型、算法流程等内容,帮助我们系统地学习理解多视图几何应用的原理和方法。同时,在学习过程中,我们还需结合实际应用情况进行实践,不断积累经验。 总之,计算机视觉中多视图几何是一个重要的研究领域,对于深度学习和人工智能技术的发展有着重要的推动作用。希望广大科技工作者能够加强学习研究,把握未来科技发展趋势。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值