视觉定位系统原理——基础矩阵

发布时间:2024-05-10
一、视觉定位系统基础矩阵的原理介绍基础矩阵我们先说一下对积几和
对极几何一定是对二幅图像而言,对极几何实际上是“两幅图像之间的对极几何”,它是图像平面与以基线为轴的平面束的交的几何(这里的基线是指连接摄像机中心的直线),以下图为例:对极几何描述的是左右两幅图像(点x和x’对应的图像)与以cc’为轴的平面束的交的几何!
直线cc’为基线,以该基线为轴存在一个平面束,该平面束与两幅图像平面相交,下图给出了该平面束的直观形象,可以看到,该平面束中不同平面与两幅图像相交于不同直线;
上图中的灰色平面π,只是过基线的平面束中的一个平面(当然,该平面才是平面束中最重要的、也是我们要研究的平面);
epipolarpoints极点
每一个相机的透镜中心是不同的,会投射到另一个相机像面的不同点上。这两个像点用el和er表示,被称为epipolarpoints极点。两个极点el、er分别与透镜中心ol、or在空间中位于一条直线上。
epipolarplane极面
将x、ol和or三点形成的面称为epipolarplane极面。
epipolarline极线
直线ol-x被左相机看做一个点,因为它和透镜中心位于一条线上。然而,从右相机看直线ol-x,则是像面上的一条线直线er-xr,被称为epipolarline极线。从另一个角度看,极面x-ol-or与相机像面相交形成极线。
极线是3d空间中点x的位置函数,随x变化,两幅图像会生成一组极线。直线ol-x通过透镜中心ol,右像面中对应的极线必然通过极点er。一幅图像中的所有极线包含了该图像的所有极点。实际上,任意一条包含极点的线都是由空间中某一点x推导出的一条极线。
如果两个相机位置已知,则:
1.如果投影点xl已知,则极线er-xr已知,点x必定投影到右像面极线上的xr处。这就意味着,在一个图像中观察到的每个点,在已知的极线上观察到该点的其他图像。这就是epipolarconstraint极线约束:x在右像面上的投影xr必然被约束在er-xr极线上。对于ol-xl上的x,x1,x2,x3都受该约束。极线约束可以用于测试两点是否对应同一3d点。极线约束也可以用两相机间的基本矩阵来描述。
2.如果xl和xr已知,他们的投影线已知。如果两幅图像上的点对应同一点x,则投影线必然交于x。这就意味着x可以用两个像点的坐标计算得到。
二、视觉定位系统基础矩阵如果已知基础矩阵f,以及一个3d点在一个像面上的像素坐标p,则可以求得在另一个像面上的像素坐标p‘。这个是基础矩阵的作用,可以表征两个相机的相对位置及相机内参数。
面具体介绍基础矩阵与像素坐标p和p’的关系。
以o1为原点,光轴方向为z轴,另外两个方向为x,y轴可以得到一个坐标系,在这个坐标系下,可以对p,p1(即图中所标p),p2(即图中所标p‘)得到三维坐标,同理,对o2也可以得到一个三维坐标,这两个坐标之间的转换矩阵为[rt],即通过旋转r和平移t可以将o1坐标系下的点p1(x1,y1,z1),转换成o2坐标系下的p2(x2,y2,z2)。
则可知,p2=r(p1-t)(1)
采用简单的立体几何知识,可以知道
其中,p,p‘分别为p点的像点在两个坐标系下分别得到的坐标(非二维像素坐标)。rp’为极面上一矢量,t为极面上一矢量,则两矢量一叉乘为极面的法向量,这个法向量与极面上一矢量p一定是垂直的,所以上式一定成立。(这里采用转置是因为p会表示为列向量的形式,此处需要为行向量)
采用一个常用的叉乘转矩阵的方法,
将我们的叉乘采用上面的转换,会变成
红框中所标即为本征矩阵e,他描述了三维像点p和p‘之间的关系
有了本征矩阵,我们的基础矩阵也就容易推导了,
注意到将p和p‘换成p1和p2式(4)也是成立的,且有
q1=k1p1(6)
q2=k2p2(7)
上式中,k1k2为相机的校准矩阵,描述相机的内参数q1q2为相机的像素坐标代入式(4)中,得
上式中p->q1,p‘->q2
这样我们就得到了两个相机上的像素坐标和基础矩阵f之间的关系了
二、不同图像对的基础矩阵
代码
# coding: utf-8
# in[1]:
from pil import image
from numpy import *
from pylab import *
import numpy as np
# in[2]:
from pcv.geometry import homography, camera, sfm
from pcv.localdescriptors import sift
# in[5]:
# read features
im1 = array(image.open('im1.jpg'))
sift.process_image('im1.jpg', 'im1.sift')
im2 = array(image.open('im2.jpg'))
sift.process_image('im2.jpg.', 'im2.sift')
# in[6]:
l1, d1 = sift.read_features_from_file('im1.sift')
l2, d2 = sift.read_features_from_file('im2.sift')
# in[7]:
matches = sift.match_twosided(d1, d2)
# in[8]:
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()
# in[9]:
figure(figsize=(16,16))
sift.plot_matches(im1, im2, l1, l2, matches, true)
show()
# in[10]:
#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):
robust estimation of a fundamental matrix f from point
correspondences using ransac (ransac.py from
/cookbook/ransac).
input: x1, x2 (3*n arrays) points in hom. coordinates.
from pcv.tools import ransac
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,
8, maxiter, match_threshold, d, return_all=true)
return f, ransac_data['inliers']
# in[11]:
# find f through ransac
model = sfm.ransacmodel()
f, inliers = f_from_ransac(x1n, x2n, model, maxiter=5000, match_threshold=1e-3)
print(f)
# in[12]:
p1 = array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0]])
p2 = pute_p_from_fundamental(f)
# in[13]:
print(p2)
print(f)
# in[14]:
# p2, f (1e-4, d=20)
# [[ -1.e+00 1.e+01 5.e+02 4.e+03]
# [ 1.e+01 -9.e+01 -4.e+03 5.e+02]
# [ 2.e-02 3.e-03 -1.e+02 1.e+00]]
# [[ -1.e-07 4.e-06 -2.e-03]
# [ -1.e-06 6.e-07 2.e-02]
# [ 1.e-03 -2.e-02 1.e+00]]
# in[15]:
# triangulate inliers and remove points not in front of both cameras
x = sfm.triangulate(x1n[:, inliers], x2n[:, inliers], p1, p2)
# in[16]:
# plot the projection of x
cam1 = camera.camera(p1)
cam2 = camera.camera(p2)
x1p = cam1.project(x)
x2p = cam2.project(x)
# in[17]:
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]
plot([x1p[0][i], x2p[0][i]+cols1],[x1p[1][i], x2p[1][i]],'c')
axis('off')
show()
# in[18]:
d1p = d1n[inliers]
d2p = d2n[inliers]
# in[19]:
# read features
im3 = array(image.open('im3.jpg'))
sift.process_image('im3.jpg', 'im3.sift')
l3, d3 = sift.read_features_from_file('im3.sift')
# in[20]:
matches13 = sift.match_twosided(d1p, d3)
# in[21]:
ndx_13 = matches13.nonzero()[0]
x1_13 = homography.make_homog(x1p[:, ndx_13])
ndx2_13 = [int(matches13[i]) for i in ndx_13]
x3_13 = homography.make_homog(l3[ndx2_13, :2].t)
# in[22]:
figure(figsize=(16, 16))
imj = sift.appendimages(im1, im3)
imj = vstack((imj, imj))
imshow(imj)
cols1 = im1.shape[1]
rows1 = im1.shape[0]
for i in range(len(x1_13[0])):
if (0<= x1_13[0][i]
plot([x1_13[0][i], x3_13[0][i]+cols1],[x1_13[1][i], x3_13[1][i]],'c')
axis('off')
show()
# in[23]:
p3 = pute_p(x3_13, x[:, ndx_13])
# in[24]:
print(p3)
# in[25]:
print(p1)
print(p2)
print(p3)
# in[26]:
# can't tell the camera position because there's no calibration matrix (k)
得到视觉对位系统基础矩阵如下
室外
得到基础矩阵如下
上一个:直埋预制聚氨酯保温管安装工艺
下一个:硬盘怎样分区好,硬盘如何分区好

米王m1怎么样,漫步者m1怎么样
承试四级设施许可证应该如何办理?
弄清工程中各种梁的区别
固态硬盘怎样分区c盘
关于水上船只锚系警戒助航塑料浮标参数
双网带式压滤机淀粉酿酒污泥处理设备
VOCs、脱硫除尘、SCR脱硝 湖南拟推荐88个项目申报中央大气污染防治资金
木屑养花全死的原因
加味三红茶防治老年斑
香蕉枯萎病有何危害?症状如何?如何防治?