基础矩阵

本文详细介绍了基础矩阵在计算机视觉中的作用,包括其定义、推导过程以及在立体像对中的应用。通过实验,对比分析了七点法、八点法和十点法估算基础矩阵的性能,并探讨了不同拍摄角度对结果的影响。此外,文章还讨论了在实际操作中遇到的问题及解决方案。
摘要由CSDN通过智能技术生成

1. 基础矩阵简介

在计算机视觉中,基础矩阵F是一个3×3的矩阵,表达了立体像对的像点之间的对应关系。在对极几何中,对于立体像对中的一对同名点,它们的齐次化图像坐标分别为p与 p’,Fp表示一条必定经过p’的直线(极线)。这意味着立体像对的所有同名点对都满足:
在这里插入图片描述
F矩阵中蕴含了立体像对的两幅图像在拍摄时相互之间的空间几何关系(外参数)以及相机检校参数(内参数),包括旋转、位移、像主点坐标和焦距。因为F矩阵的秩为2,并且可以自由缩放(尺度化),所以只需7对同名点即可估算出F的值。本质矩阵与基础矩阵之间的关系可由下式表达:
在这里插入图片描述
其中K和K’分别为两个相机的内参数矩阵。

2. 基础矩阵推导

在双相机的拍摄场景中建立一个空间直角坐标系,称为世界坐标系(如图1中蓝色坐标系)。物点就是场景中物体表面上的点,比如说点P在世界坐标系中的坐标为 :
在这里插入图片描述
在这里插入图片描述
相机的光心从物理上讲就是相机镜头组的光学中心。以光心为原点,主光轴为Z轴建立空间直角坐标系,称为相机坐标系(如图1中绿色和红色坐标系)。像平面在相机坐标系中的方程即为z=f,像点就是在物点在像平面上的投影,这个投影关系是透视投影。

用一句话来概括相机的拍摄模型,就是物点、像点、光心三点一线,此模型称为针孔相机模型。在此模型中,世界坐标系到左右相机坐标系的变换是刚性变换,即只包含旋转和平移,因此我们分别用增广矩阵[R|t]和[R’|t’]表示,其中R和R’是3x3的旋转矩阵,t和t’为平移向量。
在这里插入图片描述为P的齐次化坐标,那么物点P在左右相机坐标系下的坐标分别为
在这里插入图片描述
以一台相机为例,如图2所示,C为相机光心,Z轴为主轴。物点在相机坐标系下的坐标和以相片左下角为原点的像点坐标p有如下关系:
在这里插入图片描述
在这里插入图片描述
式中(x0,y0,f)为像主点在相机坐标系下的坐标。
设两相机内参数矩阵同为:
在这里插入图片描述
那么物点与像点之间的关系为:
在这里插入图片描述
又因为:
在这里插入图片描述
并令下式得:
在这里插入图片描述
在这里插入图片描述
由于物点、像点、光心三点一线,那么物点、一对同名点和2个光心这5个点一定处于同一个平面上,我们将这个平面称为𝜋平面。𝜋平面和像平面的交线称为极线l’。显然,左片上的每一个像点p对应于右片上的一条极线l’,且p’一定在l’上。两个相机光心的连线与右片像平面的交点称为极点,用e’表示。

在右片像平面内,极线 l’的方程可以表示为Ax+By+C=0。这个平面直线方程的一般式可以视为:
在这里插入图片描述
因此,我们可以用一个三维向量 (A,B,C)来表示极线l’,并且 l’的方程可以简单的由e’坐标向量与 p’坐标向量做向量积得到,即
在这里插入图片描述
其中:
在这里插入图片描述
令[e’]x表示向量积的矩阵形式,那么再将同名点之间的变换关系代入,得到极线的方程为:
在这里插入图片描述
因为p’在 l’上,所以显然有:
在这里插入图片描述

在这里插入图片描述
即得到:
在这里插入图片描述

3. 实验代码

3.1 七点法

from PIL import Image
from numpy import *
from pylab import *
from PCV.geometry import camera
from PCV.geometry import homography
from PCV.geometry import sfm
from PCV.localdescriptors import sift
from PCV.tools import ransac
import numpy as np


# Read features
im1 = array(Image.open('C:/picture/3.jpg'))
sift.process_image('C:/picture/3.jpg', 'img1.sift')

im2 = array(Image.open('C:/picture/4.jpg'))
sift.process_image('C:/picture/4.jpg', 'img2.sift')


l1, d1 = sift.read_features_from_file('img1.sift')
l2, d2 = sift.read_features_from_file('img2.sift')


matches = sift.match_twosided(d1, d2)

ndx = matches.nonzero()[0]
x1 = homography.make_homog(l1[ndx, :2].T)
ndx2 = [int(matches[i]) for i in ndx]
x2 = homography.make_homog(l2[ndx2, :2].T)

d1n = d1[ndx]
d2n = d2[ndx2]
x1n = x1.copy()
x2n = x2.copy()


#figure(figsize=(16,16))
sift.plot_matches(im1, im2, l1, l2, matches, True)
show()



#def F_from_ransac(x1, x2, model, maxiter=5000, match_threshold=1e-6):
def F_from_ransac(x1, x2, model, maxiter=5000, match_threshold=1e-6):

    data = np.vstack((x1, x2))
    d = 10 # 20 is the original
    # compute F and return with inlier index
    F, ransac_data = ransac.ransac(data.T, model,
                                   7, maxiter, match_threshold, d, return_all=True)
    return F, ransac_data['inliers']

# find F through RANSAC
model = sfm.RansacModel()
F, inliers = F_from_ransac(x1n, x2n, model, maxiter=5000, match_threshold=1e-5)
print (F)


P1 = array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0]])
P2 = sfm.compute_P_from_fundamental(F)


X = sfm.triangulate(x1n[:, inliers], x2n[:, inliers], P1, P2)
# plot the projection of X
cam1 = camera.Camera(P1)
cam2 = camera.Camera(P2)
x1p = cam1.project(X)
x2p = cam2.project(X)

# figure(figsize=(16, 16))
imj = sift.appendimages(im1, im2)
imj = vstack((imj, imj))

imshow(imj)

cols1 = im1.shape[1]
rows1 = im1.shape[0]
for i in range(len(x1p[0])):
    if (0<= x1p[0][i]<cols1) and (0<= x2p[0][i]<cols1) and (0<=x1p[1][i]<rows1) and (0<=x2p[1][i]<rows1):
        plot([x1p[0][i], x2p[0][i]+cols1],[x1p[
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值