求解基础矩阵

基础矩阵 文章目录一、 基础矩阵1、简介2、F的几何推导3、F的代数推导![在这里插入图片描述](https://img-blog.csdnimg.cn/2020042115321268.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xwMjAxN... 阅读详情

一、对极几何

1.1概念

对极几何(Epipolar Geometry)是Structure from Motion问题中,在两个相机位置产生的两幅图像的之间存在的一种特殊几何关系,是sfm问题中2D-2D求解两帧间相机姿态的基本模型。

1.2基本模型

在这里插入图片描述
其中c0、c1为两个相机中心,p为空间中一点,p在c0、c1对应像平面上的投影分别为x0、x1。c0、c1连线与像平面的交点e0、e1称为极点(Epipoles),l0、l1称为极线(Epipolar Lines),c0、c1、p三点组成的平面称为极平面(Epipolar Plane)。

二、基础矩阵

通过对极几何一副图像上的点可以确定另外一幅图像上的一条直线,这种情况用基础矩阵来表示。通过一种映射,一幅图像上的点可以确定另外一副图像上的一个点,这种情况用单应矩阵。
本质矩阵是基础矩阵的一种特殊情况,是在归一化图像坐标下的基础矩阵。
本质矩阵
存在一个不经过两个相机光心的的平面π,光心C与x的射线与平面π相交与一点X。该点X又投影到第二幅图像平面上的点x′。这个称为点x通过平面π的转移。点x,x′是平面ππ上的3D点X在两个相机平面上的像。对应每一个3D点X都存在一个2D的单应R把每一个x映射到x′。
在这里插入图片描述
如上图所示,给定一个目标点P,以左摄像头光心Ol为原点。点P相对于光心Ol的观察位置为Pl,相对于光心Or的观察位置为Pr。点P在左摄像头成像平面上的位置为pl,在右摄像头成像平面上的位置为pr。
现在我们要寻找由点P、Ol和Or确定的对极平面的表达式。注意到平面上任意一点x与点a的连线垂直于平面法向量n,即向量 (x-a) 与向量 n 的点积为0:(x-a)·n = 0。在Ol坐标系中,光心Or的位置为T,则P、Ol和Or确定的对极平面可由下式表示:
在这里插入图片描述
由Pr = R(Pl-T) 得在这里插入图片描述
另一方面,向量的叉积又可表示为矩阵与向量的乘积,记向量T的矩阵表示为S,得:
在这里插入图片描述
在这里插入图片描述
也就可以得到在这里插入图片描述
就可以得到本质矩阵E=RS。
通过矩阵E我们知道Pl和Pr的关系满足:
在这里插入图片描述
根据相似三角形定理,pl = flPl/Zl 和 pr = frPr/Zr 我们可以得到点P在左右两个摄像机坐标系中的观察点 pl 和 pr 应满足的极线约束关系为:
在这里插入图片描述
注意到 E 是不满秩的,它的秩为2,那么
在这里插入图片描述
表示的是一条直线,也就是对极线。

2.1基本矩阵原理

为了描述对极几何,引入基础矩阵F。对于一幅图像上的点x(图上p1),在另一幅图像上存在对极线l’,并且在第二幅图像上,与x匹配的点x’(点p2)必然在l’上。为了表示x与l’关系,我们令基础矩阵F定义为: l′=Fx。

假设第一幅图到第二幅图之间存在单应性变换H,则 x′=Hx。

又因为l’是表示过对极点e2和图像点x’的直线,可以表示为: l′=e2×x′=[e2]xx′=[e2]xHx。

所以可得 F=[e2]xH。
其中e′=[a1,a2,a3]Te′=[a1,a2,a3]T,则它的反对称阵定义为:在这里插入图片描述
在已知两个摄像机的射影矩阵P和P’时,对于图像上的一点x,可以得到其反投影射线方程为: X(λ)=P+ x+λC

其中P+ 是P的伪逆,即PP+ = I,C为摄像机中心。射线上的两点:P+ x(当λ=0)、C(当λ=∞)在第二个摄像机P’拍摄下,在第二幅视图上的点分别为P′P+ 和P′C,这两点过对极线l’,即 l′=(P′C)×(P′P+ x)=[e′]x(P′P+ )x

可以推得 F=[e′]xP′P+

2.2八点估算法

基本矩阵是由该方程定义的: x′TFx=0

其中x↔x′是两幅图像的任意一对匹配点。由于每一组点的匹配提供了计算F系数的一个线性方程,当给定至少7个点(3×3的齐次矩阵减去一个尺度,以及一个秩为2的约束),方程就可以计算出未知的F。我们记点的坐标为x=(x,y,1)T,x′=(x′,y′,1)T

又因为F为:
在这里插入图片描述
所以可得到方程:
在这里插入图片描述
即相应方程式为
在这里插入图片描述
给定n组点的集合,我们有如下方程:
在这里插入图片描述
如果存在确定(非零)解,则系数矩阵A的秩最多是8。由于F是齐次矩阵,所以如果矩阵A的秩为8,则在差一个尺度因子的情况下解是唯一的。可以直接用线性算法解得。

如果由于点坐标存在噪声则矩阵AA的秩可能大于8(也就是等于9,由于A是n×9的矩阵)。这时候就需要求最小二乘解,这里就可以用SVD来求解,f的解就是系数矩阵A最小奇异值对应的奇异向量,也就是A奇异值分解后A=UDVT中矩阵V的最后一列矢量,这是在解矢量f在约束∥f∥下取∥Af∥最小的解。以上算法是解基本矩阵的基本方法,称为8点算法。

上述求解后的F不一定能满足秩为2的约束,因此还要在F的基础上加以约束。通过SVD分解可以解决,令F=UΣVT,则
在这里插入图片描述
因为要秩为2,所以取最后一个元素设置为0,则
在这里插入图片描述
最终的解
在这里插入图片描述

三、实验内容

3.1实验图片

在这里插入图片描述

3.2实验结果

前后拍摄场景

特征匹配
在这里插入图片描述
极点极线
在这里插入图片描述
基础矩阵
在这里插入图片描述

平行

特征匹配
在这里插入图片描述
极点极线
在这里插入图片描述
基础矩阵
在这里插入图片描述

图片左右拍摄

匹配
在这里插入图片描述
极点极线

在这里插入图片描述
基础矩阵
在这里插入图片描述

3.3实验代码

特征匹配

# coding: utf-8
from PIL import Image
from numpy import *
from pylab import *
import numpy as np
from PCV.geometry import homography, camera, sfm
from PCV.localdescriptors import sift

camera = reload(camera)
homography = reload(homography)
sfm = reload(sfm)
sift = reload(sift)

# 提取特征
im1 = array(Image.open(‘C:/Users/jxtx/计算机视觉/5/1.jpg’))
sift.process_image('C:/Users/jxtx/计算机视觉/5/1.jpg', 'im1.sift')

im2 = array(Image.open('C:/Users/jxtx/计算机视觉/5/2.jpg'))
sift.process_image('C:/Users/jxtx/计算机视觉/5/2.jpg', 'im2.sift')

l1, d1 = sift.read_features_from_file('im1.sift')
l2, d2 = sift.read_features_from_file('im2.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):
    """
    使用RANSAC从点对应中稳健估计基本矩阵F.
  (来自http://www.scipy.org/Cookbook/RANSAC的ransac.py)。
    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
    # 计算F并返回inlier索引
    F, ransac_data = ransac.ransac(data.T, model,
                                   8, maxiter, match_threshold, d, return_all=True)
    return F, ransac_data['inliers']


# 通过RANSAC找到F.
model = sfm.RansacModel()
F, inliers = F_from_ransac(x1n, x2n, model, maxiter=5000, match_threshold=1e-3)

P1 = array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0]])
P2 = sfm.compute_P_from_fundamental(F)  # 计算第二个相机矩阵

# print P2
print 'F is'
print F

X = sfm.triangulate(x1n[:, inliers], x2n[:, inliers], P1, P2)

# 绘制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[1][i], x2p[1][i]], 'c')
axis('off')
show()

d1p = d1n[inliers]
d2p = d2n[inliers]

绘制极点极线

# coding: utf-8
from PIL import Image
from numpy import *
from pylab import *
import numpy as np
from PCV.geometry import homography, camera, sfm
from PCV.localdescriptors import sift

camera = reload(camera)
homography = reload(homography)
sfm = reload(sfm)
sift = reload(sift)

# 提取特征
im1 = array(Image.open('C:/Users/jxtx/计算机视觉/5/1.jpg'))
sift.process_image('C:/Users/jxtx/计算机视觉/5/1.jpg', 'im1.sift')

im2 = array(Image.open('C:/Users/jxtx/计算机视觉/5/2.jpg'))
sift.process_image('C:/Users/jxtx/计算机视觉/5/2.jpg', 'im2.sift')

l1, d1 = sift.read_features_from_file('im1.sift')
l2, d2 = sift.read_features_from_file('im2.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()

#import sfm111
### 计算 F
#F = sfm111.compute_fundamental(x1n,x2n)
#print(F)


def F_from_ransac(x1, x2, model, maxiter=5000, match_threshold=1e-6):
    """
    使用RANSAC从点对应中稳健估计基本矩阵F.
  (来自http://www.scipy.org/Cookbook/RANSAC的ransac.py)。
    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
    # 计算F并返回inlier索引
    F, ransac_data = ransac.ransac(data.T, model,
                                   8, maxiter, match_threshold, d, return_all=True)
    return F, ransac_data['inliers']


# 通过RANSAC找到F.
model = sfm.RansacModel()
F, inliers = F_from_ransac(x1n, x2n, model, maxiter=5000, match_threshold=1e-3)

P1 = array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0]])
P2 = sfm.compute_P_from_fundamental(F)  # 计算第二个相机矩阵

# print P2
print 'F is'
print F

X = sfm.triangulate(x1n[:, inliers], x2n[:, inliers], P1, P2)

# 绘制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]

def compute_epipole(F):
 """ 从基础矩阵 F 中计算右极点(可以使用 F.T 获得左极点)"""
 # 返回 F 的零空间(Fx=0)
 U,S,V = linalg.svd(F)
 e = V[-1]
 return e/e[2]



def plot_epipolar_line(im,F,x,epipole=None,show_epipole=True):
 """ 在图像中,绘制外极点和外极线 F×x=0。F 是基础矩阵,x 是另一幅图像中的点 """
 m,n = im.shape[:2]
 line = dot(F,x)
 # 外极线参数和值
 t = linspace(0,n,100)
 lt = array([(line[2]+line[0]*tt)/(-line[1]) for tt in t])
 # 仅仅处理位于图像内部的点和线
 ndx = (lt>=0) & (lt<m)
 plot(t[ndx],lt[ndx],linewidth=2)
 if show_epipole:
     if epipole is None:
         epipole = compute_epipole(F)
     plot(epipole[0]/epipole[2],epipole[1]/epipole[2],'r*')

e = compute_epipole(F)
for i in range(5):
    plot_epipolar_line(im1,F,x2[:,i],e,False)
axis('off')
figure()
imshow(im2)
# 分别绘制每个点,这样会绘制出和线同样的颜色
for i in range(5):
    plot(x2[0,i],x2[1,i],'o')
axis('off')
show()

d1p = d1n[inliers]
d2p = d2n[inliers]

四、总结

sift特征匹配精确度不高,还会有很多错误的匹配结果,基础矩阵可以用于简化匹配和去除错配特征。在本次实验中我们主要是利用RANSAC方法估计基础矩阵,然后再通过基础矩阵计算相机矩阵。得出最后的匹配结果。
一开始由于图片的像素导致出现了问题,把图片像素改小且统一就可以解决问题了。

基础矩阵、本质矩阵、单应矩阵 基础矩阵是一个 3×3 的秩为2的矩阵,用于描述两个不同视图(或称为图像)之间对应点的几何约束。更具体地说,如果你有两幅图像,分别从两个不同的相机或者相机位置拍摄,那么基础矩阵可以用于找到一个图像中的点在另一个图像中的对应点。本质矩阵也是一个 3×3 的秩为2的矩阵,与基础矩阵非常类似。当两个视图(图像)之间的场景是一个平面或者两个视图之间仅有旋转和平移时,可以使用单应矩阵来关联这两个视图。这三个矩阵都是在计算机视觉中广泛应用的基础工具,但它们适用于不同类型的视图和场景。给定两个图像中的一对对应点。 阅读详情

相关推荐

基础矩阵求解之RANSAC、8点算法(python)

前言 sift提取特征 估计基础矩阵 RANSAC去除错误点匹配 归一化8点算法

qq_42399848的博客 1万+

OpenCV基础矩阵求解解析笔记

OpenCV基础矩阵求解解析笔记

会飞的鱼的博客 1875

归一化八点算法及图像之间基础矩阵求解

归一化8点算法及图像之间基础矩阵求解 文章目录归一化8点算法及图像之间基础矩阵求解归一化8点算法介绍归一化8点算法步骤归一化8点算法总结对极几何与基础矩阵实验详细需求实验过程及代码(1)左右拍摄,极点位于图像平面上。(2)像平面接近平行,极点位于无穷远,如图所示(3)图像拍摄位置位于前后,如图所示 多视图几何时利用在不同视点所拍摄图像间的关系,来研究照相机之间或者特征之间关系的一门科学。多视图几何...

WeskerXR的博客 9111

对极几何以及基础矩阵原理求解(一)

文章目录一、P在不同坐标系中的表示二、本质矩阵基础矩阵对极几何本质矩阵(Essential Matrix)基础矩阵(Fundamen...

gaocui883的博客 691

求解图像基础矩阵

一、基础矩阵 1.1 对极几何 对极几何是描述两视射影几何的基本工具,当我们使用两个相机在不同位置对同一场景进行拍摄时,为了描述两幅图像之间的关系,引入对极几何。对极几何是两幅图像之间,两幅图像上的匹配点与以基线(连接两摄像机中心的直线)为轴的平面束的交的几何。 已知两个摄像头的光心和,为空间中的一点,和是点在两个摄像头成的像中的投影。平面称为外极平面,显然和是和上...

ziyi_mi的博客 1560

ORB中的基础矩阵求解

本文介绍ORB中基础矩阵F中归一化的原因及具体实现.

qq_20604231的博客 1378

對極幾何基礎矩陣求解 - 七點法

一個三維點xx在兩個相機中的投影分別為x1,x2,這兩個投影點座標需滿足"對極約束",即x2^TFx1 = 0。其中的F即為基礎矩陣,本篇著重於推導基礎矩陣求解方式之一的七點法。

keineahnung2345的博客 827

【VSLAM面试】必备基础知识2-最小二乘问题求解基础矩阵、本质矩阵和单应矩阵矩阵分解(求解Ax = b)

VSLAM面试常用基础知识,最小二乘问题求解基础矩阵,本质矩阵和单应矩阵矩阵分解

dulu_301的博客 1179

求解图像之间的基础矩阵

文章目录1.原理1.11.2基本矩阵 1.原理 1.1 对极平面:任何包含基线的平面都称为对极平面,或者说是对极平面束中的平面,如上图中的π 对极点:摄像机的基线与每幅图像的交点;即上图中的点e和e’ 对极线:对极平面与图像的交线;例如,上图中的直线l和l’ 基本矩阵F:对应点对之间的约束 所有的极线都通过其极点 1.2基本矩阵 观测点P在相机1坐标系的坐标就可以通过转换变成相机2坐标系下 ...

yuyaoshiniba的博客 1193

多视图几何总结——基础矩阵、本质矩阵和单应矩阵求解过程

MVG总结——基础矩阵、本质矩阵和单应矩阵求解过程MVG总结——基础矩阵、本质矩阵和单应矩阵求解过程(1)说明——其实求解过程大同小异(2)基础矩阵求解过程(3)本质矩阵求解过程(4)单应矩阵求解过程 MVG总结——基础矩阵、本质矩阵和单应矩阵求解过程 在《视觉SLAM十四讲》中,仅仅给出了基础矩阵、本质矩阵和单应矩阵的推导过程,并没有详细给出其求解过程,再看过《计算机视觉中的多视图几何》之...

weixin_44580210的博客 7527

ORB_SLAM2原理及代码解析:单应矩阵H、基础矩阵F求解

用于评估给定单应矩阵 H21(Frame1 → Frame2)是否正确,通过检查匹配点的重投影误差,计算一个评分,并标记每个匹配点是否为内点。vPn1, vPn2(归一化后匹配点集合) ← Normalize() → T1, T2。└─ 若得分更高 → 更新 H21, vbMatchesInliers, score。├─ 从 mvSets[it] 抽取 8 对匹配点。mvKeys1, mvKeys2 (去畸变关键点)mvMatches12 (匹配点索引集合)

weixin_45728280的博客 705

计算机视觉——求解基础矩阵和对极几何

基础矩阵和对极几何一、对极几何1、概念2、外极线、外极点二、基础矩阵1、描述2、实现步骤3、八点法求基础矩阵三、计算基础矩阵1、八点法求基础矩阵2、对比实验 一、对极几何 1、概念 如果有一个场景的两个视图以及视图中的对应图像点,那么根据照相机间的空间相对位置关系、照相机的性质以及三维场景点的位置,可以得到对这些图像点的一些几何关系约束。我们通过外极几何来描述这些几何关系。 对极几何描述的是两幅...

weixin_42646077的博客 1621

计算机视觉——求解图像之间的基础矩阵

文章目录1. 外极几何1.1 基础矩阵1.2 基础矩阵估算方法1.2.1 八点估算法2. 实验部分2.1 代码2.2 实验结果2.2.1 左右小结2.2.2 前后小结2.2.3 平移小结2.3 实验总结 1. 外极几何 1.1 基础矩阵 概述: 1)两幅图像之间的约束关系使用代数的方式表示出来即为基本矩阵。    2)基础矩阵F满足: 3)基础矩阵可以用于简化匹配和去除错配特征。 原理 基...

xxxcci的博客 3417

基础矩阵求解本质矩阵,得到相机的参数(三维重建task1-5)

基础矩阵求解本质矩阵,得到相机的参数(三维重建task1-5) 代码呈上 #include <math/matrix.h> #include <math/matrix_svd.h> typedef math::Matrix<double, 3, 3> FundamentalMatrix; typedef math::Matrix<double, 3, 3> EssentialMatrix; //用于测试相机姿态的正确性 math::Vec2d p1={

weixin_46877907的博客 1841

常微分方程求解全解析:从基础矩阵方法深度实践

常微分方程的阶数指方程中未知函数导数的最高阶数。通解是包含任意常数且常数个数与方程阶数相同的解,特解则是通解中任意常数取特定值得到的解。以自由落体运动为例,根据牛顿第二定律(F=ma)(F = ma)(F=ma),可得(mg=md2ydt2)(mg = m\frac{d^{2}y}{dt^{2}})(mg=mdt2d2y​),这是二阶常微分方程。方程分类标准可依据未知函数及其导数是否为一次幂,若为一次幂则是线性方程,否则为非线性方程。初值问题是给定自变量某一值时未知函数及其各阶导数的值;边值问题是给定自变量

GeekDongHuang的博客 1855

从对极约束到三维重建:深入解析基础矩阵与本质矩阵求解与应用

本文深入解析了双目视觉中的基础矩阵与本质矩阵求解与应用,详细介绍了八点法、RANSAC算法等关键技术,以及从基础矩阵到本质矩阵的转换与分解方法。通过实际工程案例,展示了如何应对特征匹配噪声、矩阵分解稳定性等挑战,并提供了三维重建的完整链路与性能优化技巧。

weixin_29053577的博客 229
上一篇: 棋盘格标定
下一篇: 计算视差图
Yep_Ying
博客等级 码龄7年 18粉丝 15原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值