基础矩阵与对极几何
基础矩阵与对极几何
简介
在计算机视觉中,基础矩阵(Fundamental matrix)F是一个3×3的矩阵,表达了立体像对的像点之间的对应关系。在对极几何中,对于立体像对中的一对同名点,它们的齐次化图像坐标分别为p与 p’,表示一条必定经过p’的直线(极线)。这意味着立体像对的所有同名点对都满足:
F矩阵中蕴含了立体像对的两幅图像在拍摄时相互之间的空间几何关系(外参数)以及相机检校参数(内参数),包括旋转、位移、像主点坐标和焦距。因为F矩阵的秩为2,并且可以自由缩放(尺度化),所以只需7对同名点即可估算出F的值。
基础矩阵这一概念由Q. T. Luong在他那篇很有影响力的博士毕业论文中提出。 Faugeras则是在1992年发表的著作中以上面的关系式给出了F矩阵的定义。尽管Longuet-Higgins提出的本质矩阵也满足类似的关系式,但本质矩阵中并不蕴含相机检校参数。本质矩阵与基础矩阵之间的关系可由下式表达:
其中K和K’分别为两个相机的内参数矩阵。
基本概念
对极几何
如果有一个场景的两个视图以及视图中的对应图像点,那么根据照相机间的空间相对位置关系、照相机的性质以及三维场景点的位置,可以得到对这些图像点的一些几何关系约束。我们通过对极几何来描述这些几何关系。
通俗的说,对极几何实际上是“两幅图像之间的对极几何”,它是图像平面与以基线为轴的平面束的交的几何(这里的基线是指连接摄像机中心的直线)。如下图,对极几何描述的是左右两幅图像(点x和x’对应的图像)与以C1C2为轴的平面束的交的几何
外极几何的几个相关概念
对极平面(epipolar plane):任何包含基线的平面都称为对极平面,或者说是对极平面束中的平面;例如,下图中的平面π就是一个对极平面
对极点(epipole):摄像机的基线与每幅图像的交点;对于所有对极线, 有 eTFx’=0, 对任意的x’有eTF=0, 同理 有 Fe’=0。即下图中的点e和e’(红色圈出的点)
对极线(epipolar line):对极平面与图像的交线;:F 可以将点 x 映射到对应像平面上一条线 l=Fx’ ,同理可得 l’=FTx。例如,下图中的直线l和l’
基础矩阵
基础矩阵(Fundamental matrix)F是一个3×3的矩阵,表达了立体像对的像点之间的对应关系。在对极几何中,对于立体像对中的一对同名点,它们的齐次化图像坐标分别为p与 p’,Fp表示一条必定经过p’的直线(极线)。这意味着立体像对的所有同名点对都满足:
F矩阵中蕴含了立体像对的两幅图像在拍摄时相互之间的空间几何关系(外参数)以及相机检校参数(内参数),包括旋转、位移、像主点坐标和焦距。因为F矩阵的秩为2,并且可以自由缩放(尺度化),所以只需7对同名点即可估算出F的值。
通俗的说,就是,基本矩阵提供了三维点到二维的一个约束条件。举个例子,现在假设我们不知道空间点X的位置,只知道X在左边图上的投影x的坐标位置,也知道基本矩阵,首先我们知道的是X一定在射线Cx上,到底在哪一点是没法知道的,也就是X可能是Cx上的任意一点(也就是轨迹的意思),那么X在右图上的投影肯定也是一条直线。也就是说,如果我们知道一幅图像中的某一点和两幅图的基本矩阵,那么就能知道其对应的右图上的点一定是在一条直线上,这样就约束了两视角下的图像中的空间位置一定是有约束的,不是任意的。
实验步骤:
1、导入两幅图像,并使用sift算法提取特征;
2、使用函数match_twosided连接两幅图的特征;
3、RANSAC去除错误点匹配;
4、归一化8点算法估计基础矩阵。这是通过对应点来计算基础矩阵的算法。
实验
实验代码
七点
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:/Users/Artor/PycharmProjects/PCV_1/data1/1.jpg'))
sift.process_image('C:/Users/Artor/PycharmProjects/PCV_1/data1/1.jpg', 'img1.sift')
im2 = array(Image.open('C:/Users/Artor/PycharmProjects/PCV_1/data1/2.jpg'))
sift.process_image('C:/Users/Artor/PycharmProjects/PCV_1/data1/2.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]