Python计算机视觉 第5章-多视图几何

Python计算机视觉 第5章-多视图几何

5.1 外极几何

在计算机视觉的多视图几何中,外极几何(Epipolar Geometry)描述了两个相机视角之间的几何关系,常用于立体匹配、图像配准和3D重建。以下是主要概念:

1. 外极几何

  • 描述两台摄像机之间的几何关系,与场景无关,只取决于摄像机的相对位置和内参。

2. 关键元素

  • 极点(Epipole):每个摄像机的光心在另一摄像机成像平面上的投影。
  • 极线(Epipolar Line):图像中的点在另一幅图像中的潜在匹配点所在的直线。

3. 基本矩阵(Fundamental Matrix)

  • 描述两个图像之间点和极线的映射关系,定义了外极几何的基本约束。

4. 本质矩阵(Essential Matrix)

  • 基本矩阵在已知相机内参时的特例,结合校准信息描述两相机之间的关系。

5. 应用场景

  • 立体匹配:确定同一三维点在两幅图像中的匹配位置。
  • 三维重建:使用极线约束来减少匹配搜索空间,重建场景的3D结构。
  • 图像校准:利用外极几何推导摄像机的相对位置和旋转。

外极几何是理解多视图关系的核心概念,特别是在多视角协同应用中。

5.1.1 一个简单的数据集

在接下来的几节中,我们需要一个带有图像点、三维点和照相机参数矩阵的数据集。我们这里使用一个牛津多视图数据集;从http://www.robots.ox.ac.uk/~vgg/data/datamview.html 可以下载Merton1 数据的压缩文件。

(点进网址发现已经404了,这边直接把参考资料的代码贴上来)

下面的脚本可以加载Merton1的数据:

import camera

# 载入一些图像
im1 = array(Image.open('images/001.jpg'))
im2 = array(Image.open('images/002.jpg'))

# 载入每个视图的二维点到列表中
points2D = [loadtxt('2D/00' + str(i + 1) + '.corners').T for i in range(3)]

# 载入三维点
points3D = loadtxt('3D/p3d').T

# 载入对应
corr = genfromtxt('2D/nview-corners', dtype='int', missing='*')

# 载入照相机矩阵到 Camera 对象列表中
P = [camera.Camera(loadtxt('2D/00' + str(i + 1) + '.P')) for i in range(3)]

下面来可视化这些数据。将三维的点投影到一个视图,然后和观测到的图像点比较:

# 将三维点转换成齐次坐标表示,并投影
X = vstack((points3D, ones(points3D.shape[1])))
x = P[0].project(X)

# 在视图1中绘制点
figure()
imshow(im1)
plot(points2D[0][0], points2D[0][1], '*')
axis('off')

figure()
imshow(im1)
plot(x[0], x[1], 'r.')
axis('off')

show()

实验结果如下所示:
在这里插入图片描述

图5-2 牛津multi-view数据集中的Merton1数据集:视图1与图像点(左);视图1与投影的三维点(右)

5.1.2 用Matplotlib绘制三维数据

为了可视化三维重建结果,我们需要绘制出三维图像。Matplotlib中的mplot3d工具包可以方便地绘制出三维点、线、等轮廓线、表面以及其他基本图形组件,还可以通过图像窗口控件实现三维旋转和缩放。

可以通过在axes对象中加上projection="3d"关键字实现三维绘图,如下:

from matplotlib.pyplot import figure, show
from mpl_toolkits.mplot3d import axes3d

fig = figure()
ax = fig.add_subplot(111, projection="3d") 

# 生成三维样本点
X, Y, Z = axes3d.get_test_data(0.25)

# 在三维中绘制点
ax.plot(X.flatten(), Y.flatten(), Z.flatten(), 'o')

show()

在这里插入图片描述

实验图1 绘图结果

get_test_data()函数在x, y空间按照设定的空间间隔参数来产生均匀的采样点。压平这些网格,会产生三列数据点,然后我们可以将其输入plot()函数。这样,我们就可以在立体表面上画出三维点。

现在通过画出Merton样本数据来观察三维点的效果:

# 绘制三维点
from matplotlib.pyplot import figure
from mpl_toolkits.mplot3d import axes3d

fig = figure()
ax = fig.gca(projection='3d')

ax.plot(points3D[0], points3D[1], points3D[2], 'k.')

图5-3是三个不同视图中的三维图像点。图像窗口和控制界面外观效果像加上三维旋转工具的标准画图窗口。

在这里插入图片描述

图5-3:使用Matplottib工具包绘制的,牛津multi-view数据库中Mertoln1数据集的三维点:从上面和侧边观测的视图(左);俯视的视图,展示了建筑墙体和屋顶上的点(中);侧视图,展示了一面墙的轮廓,以及另一面墙上点的主视图(右)

5.1.3 计算F:八点法

八点法是通过对应点来计算基础矩阵的算法。外极约束可以写成线性系统的形式:
[ x 2 1 x 1 1 x 2 1 y 1 1 x 2 1 w 1 1 ⋯ w 2 1 w 1 1 x 2 2 x 1 2 x 2 2 y 1 2 x 2 2 w 1 2 ⋯ w 2 2 w 1 2 ⋮ ⋮ ⋮ ⋱ ⋮ x 2 n x 1 n x 2 n y 1 n x 2 n w 1 n ⋯ w 2 n w 1 n ] [ F 11 F 12 F 13 ⋮ F 33 ] = A f = 0 \begin{bmatrix}x_2^1x_1^1&x_2^1y_1^1&x_2^1w_1^1&\cdots&w_2^1w_1^1\\x_2^2x_1^2&x_2^2y_1^2&x_2^2w_1^2&\cdots&w_2^2w_1^2\\\vdots&\vdots&\vdots&\ddots&\vdots\\x_2^nx_1^n&x_2^ny_1^n&x_2^nw_1^n&\cdots&w_2^nw_1^n\end{bmatrix}\begin{bmatrix}F_{11}\\F_{12}\\F_{13}\\\vdots\\F_{33}\end{bmatrix}=A\boldsymbol{f}=0 x21x11x22x12x2nx1nx21y11

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值