基础矩阵-Python

摘要:
基本矩阵-Python基本矩阵基本矩阵F可以由两个相机的参数矩阵表示。我们可以使用F来恢复相机参数,并且可以从相应的投影图像点计算F。它反映了两个视图几何的内部投影几何关系,即基本矩阵描述了两个图像平面中空间中点的坐标对应关系。8点算法8点算法是计算基本矩阵的最简单方法。它只涉及构造和求解线性方程组。如果你小心,它会表现得很好。
基础矩阵-Python

基础矩阵

  基础矩阵 F 可以由两照相机的参数矩阵(相对旋转 R 和平移 t)表示,我们可以借助 F 来恢复出照相机参数,而 F 可以从对应的投影图像点计算出来,它体现了两视图几何(对极几何)的内在射影几何关系即基础矩阵描述了空间中的点在两个像平面中的坐标对应关系。

 

对极几何

在上一篇相机模型里我们知道x=PX。通过小孔相机模型,可知从相机的中心C向点x投影一条射线Cx,则该射线必定经过对应像点的三维空间点X,但显然仅仅通过一个像点无法确定X的具体位置。那么如果两个相匹配的像点呢?
设x′是三维点X的另一个像点,其对应相机的中心为C′,那么从相机的中心C′向点也投影一条射线C′x′,并且该射线也必定经过X,也就是说从一对相匹配的像点反投影两条射线,必定相交于空间三维点X。那么一对匹配的像点之间存在这某种约束关系,这种约束被称为两视图的对极约束。
基础矩阵-Python第1张

 

 

8点算法

8点算法是计算基本矩阵(两幅图像之间的约束关系使用代数的方式表示出来即为基本矩阵)的最简单的方法,它仅涉及构造并(最小二乘)解一个线性方程组,如果小心的话,它可以执行得非常好。8点算法成功的关键是在构造解的方程之前应对输入的数据认真进行适当的归一化。在形成8点算法的线性方程组之前,图像点的一个简单变换(平移或变尺度)将使这个问题的条件极大的改善,从而提高结果的稳定性,而且进行这种变换所增加的计算复杂性并不显著。

 

像平面接近平行,极点位于无穷远

sift特征点匹配效果

基础矩阵-Python第2张

 基础矩阵-Python第3张

 

ransac算法优化

 基础矩阵-Python第4张

 

8点算法结果

基础矩阵-Python第5张

 基础矩阵:

基础矩阵-Python第6张

 

 

左右拍摄,极点位于图像平面上

sift特征点匹配效果

基础矩阵-Python第7张

 基础矩阵-Python第8张

 

ransac算法优化

 基础矩阵-Python第9张

 

8点算法结果

基础矩阵-Python第10张

 基础矩阵:

 基础矩阵-Python第11张

 

图像拍摄位置位于前后

sift特征点匹配效果

 基础矩阵-Python第12张

 基础矩阵-Python第13张

ransac算法优化

 基础矩阵-Python第14张

 

8点算法结果

 基础矩阵-Python第15张

 基础矩阵:

 基础矩阵-Python第16张

 

 

 

 

 

七点算法

像平面接近平行,极点位于无穷远

基础矩阵-Python第17张

 基础矩阵-Python第18张

 

左右拍摄,极点位于图像平面上

基础矩阵-Python第19张

 

基础矩阵-Python第20张

 

图像拍摄位置位于前后

基础矩阵-Python第21张

 基础矩阵-Python第22张

 

十点算法

像平面接近平行,极点位于无穷远

基础矩阵-Python第23张

 基础矩阵-Python第24张

左右拍摄,极点位于图像平面上

基础矩阵-Python第25张

 基础矩阵-Python第26张

图像拍摄位置位于前后

基础矩阵-Python第27张

 基础矩阵-Python第28张

 

 

总结

  • 照片的拍摄距离有些远,匹配的效果不是很好,有错误的匹配点较多,试着缩小拍摄距离会降低错误的匹配点,也可以提升图片的质量, 2-3M的图片匹配起来最好,但是相应的程序运行的时间成本就更大,优化后的特征点也更正确。
  • 有时候会因为匹配点附近太过相似而出现错误匹配,即使是经过优化后的结果仍存在错误的匹配点,图像拍摄的远近、明暗、质量都影响最终的结果
  • 8点算法是计算基本矩阵的最简单的方法,稳定性和精度都比7点、10点算法要好,而且运行速度也是较快的,7点算法反而最慢,不知道是不是我图片的质量影响了运行速度
  • 可能是我的图片边缘都不是很工整,较为平滑,导致特征点都没有匹配对,也有可能是背景墙面的花纹特征点更为明显,匹配的时候有限匹配了墙面的特征点。建议拍摄图片时选择墙面没有花纹的好一些。

 

 

报错

E:PyCharm 2018.2.5helperspycharmdocrunner.py:1: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses import imp

这是因为imp 从 Python 3.4 之后弃用了,建议使用 importlib 代替

解决方法一:

打开 Pycharm安装目录pycharmdocrunner.py 文件,做如下两步修改

  • 在第一行,注释掉 imp,导入 importlib
基础矩阵-Python第29张

 

  •  在第 230 行的 loadSource 函数中,注释 imp.load_source,使用 importlib.machinery.SourceFileLoader 加载模块
基础矩阵-Python第30张

 

解决方法二:

在导入包的位置,将imp改成importlib

基础矩阵-Python第31张

 -->

基础矩阵-Python第32张

 报错直接解除,不过我不知道对低版本的python有没有用,最好用方法一处理。

 

出现 ValueError: did not meet fit acceptance criteria 的错误,这是由于拍摄的图像水平落差比较大,可以重新拍摄一组图像。

基础矩阵-Python第33张

 

 

 代码:

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

# Read features
# 载入图像,并计算特征
im1 = array(Image.open('E:/test_pic/jichujuzhen/1.jpg'))
sift.process_image('E:/test_pic/jichujuzhen/1.jpg', 'E:/test_pic/jichujuzhen/im1.sift')
l1, d1 = sift.read_features_from_file('E:/test_pic/jichujuzhen/im1.sift')

im2 = array(Image.open('E:/test_pic/jichujuzhen/2.jpg'))
sift.process_image('E:/test_pic/jichujuzhen/2.jpg', 'E:/test_pic/jichujuzhen/im2.sift')
l2, d2 = sift.read_features_from_file('E:/test_pic/jichujuzhen/im2.sift')

# 匹配特征
matches = sift.match_twosided(d1, d2)
ndx = matches.nonzero()[0]

# 使用齐次坐标表示,并使用 inv(K) 归一化
x1 = homography.make_homog(l1[ndx, :2].T)
ndx2 = [int(matches[i]) for i in ndx]
x2 = homography.make_homog(l2[ndx2, :2].T)

x1n = x1.copy()
x2n = x2.copy()
print(len(ndx))

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

# Don't use K1, and K2

#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
    http://www.scipy.org/Cookbook/RANSAC).

    input: x1, x2 (3*n arrays) points in hom. coordinates. """

    from PCV.tools import ransac
    data = np.vstack((x1, x2))
    d = 20 # 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']

# find E through RANSAC
# 使用 RANSAC 方法估计 E
model = sfm.RansacModel()
F, inliers = F_from_ransac(x1n, x2n, model, maxiter=5000, match_threshold=1e-4)
print(len(x1n[0]))
print(len(inliers))

# 计算照相机矩阵(P2 是 4 个解的列表)
P1 = array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0]])
P2 = sfm.compute_P_from_fundamental(F)

# triangulate inliers and remove points not in front of both cameras
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()
imshow(im1)
gray()
plot(x1p[0], x1p[1], 'o')
#plot(x1[0], x1[1], 'r.')
axis('off')

figure()
imshow(im2)
gray()
plot(x2p[0], x2p[1], 'o')
#plot(x2[0], x2[1], 'r.')
axis('off')
show()

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

imshow(im3)

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()

print(F)

x1e = []
x2e = []
ers = []
for i,m in enumerate(matches):
    if m>0: #plot([locs1[i][0],locs2[m][0]+cols1],[locs1[i][1],locs2[m][1]],'c')
        x1=int(l1[i][0])
        y1=int(l1[i][1])
        x2=int(l2[int(m)][0])
        y2=int(l2[int(m)][1])
        # p1 = array([l1[i][0], l1[i][1], 1])
        # p2 = array([l2[m][0], l2[m][1], 1])
        p1 = array([x1, y1, 1])
        p2 = array([x2, y2, 1])
        # Use Sampson distance as error
        Fx1 = dot(F, p1)
        Fx2 = dot(F, p2)
        denom = Fx1[0]**2 + Fx1[1]**2 + Fx2[0]**2 + Fx2[1]**2
        e = (dot(p1.T, dot(F, p2)))**2 / denom
        x1e.append([p1[0], p1[1]])
        x2e.append([p2[0], p2[1]])
        ers.append(e)
x1e = array(x1e)
x2e = array(x2e)
ers = array(ers)

indices = np.argsort(ers)
x1s = x1e[indices]
x2s = x2e[indices]
ers = ers[indices]
x1s = x1s[:20]
x2s = x2s[:20]

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

imshow(im3)

cols1 = im1.shape[1]
rows1 = im1.shape[0]
for i in range(len(x1s)):
    if (0<= x1s[i][0]<cols1) and (0<= x2s[i][0]<cols1) and (0<=x1s[i][1]<rows1) and (0<=x2s[i][1]<rows1):
        plot([x1s[i][0], x2s[i][0]+cols1],[x1s[i][1], x2s[i][1]],'c')
axis('off')
show()

 

 

 

免责声明:文章转载自《基础矩阵-Python》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇yum提示Another app is currently holding the yum lock; waiting for it to exit...深入浅出计算机组成原理学习笔记:第三十一讲下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

OpenCV——常用函数查询

1、cvLoadImage:将图像文件加载至内存; 2、cvNamedWindow:在屏幕上创建一个窗口; 3、cvShowImage:在一个已创建好的窗口中显示图像; 4、cvWaitKey:使程序暂停,等待用户触发一个按键操作; 5、cvReleaseImage:释放图像文件所分配的内存; 6、cvDestroyWindow:销毁显示图像文件的窗口;...

【试题汇总】图像处理职位面试题汇总(1)

Matlab编程部分 1. Matlab 中读、写及显示一幅图像的命令各是什么? 解:第一、Matlab中读图像函数是imread( )。imread 函数用于读入各种图像文件,其一般的用法为:[X,MAP]=imread(‘filename’,‘fmt’) 其中,X,MAP分别为读出的图像数据和颜色表数据,fmt为图像的格式,filename为读取的...

ROS系统MoveIt玩转双臂机器人系列(五)--浅议机器人运动学与D-H建模

一、概述    机器人运动学研究的是机械臂各个连杆之间的位移关系、速度关系和加速度关系。比较经典的一本书推荐大家读读熊有伦的《机器人技术基础》下载网址在这。本篇博文将从刚体的位姿描述讲起,逐步过渡到D-H法运动学建模的方法与步骤,结合前几篇博客所树的Rob机器人的手臂建立D-H运动学模型,并编写一个逆运动学运动学求解的程序。   (1)位姿描述   我们知...

机器视觉之 ICP算法和RANSAC算法

临时研究了下机器视觉两个基本算法的算法原理 ,可能有理解错误的地方,希望发现了告诉我一下 主要是了解思想,就不写具体的计算公式之类的了 (一) ICP算法(Iterative Closest Point迭代最近点) ICP(Iterative Closest Point迭代最近点)算法是一种点集对点集配准方法,如下图1 如下图,假设PR(红色块)和RB(蓝...

图像风格迁移原理

所谓图像风格迁移,是指利用算法学习著名画作的风格,然后再把这种风格应用到另外一张图片上的技术。著名的图像处理应用Prisma是利用风格迁移技术,普通用户的照片自动变换为具有艺术家风格的图片。 一、图像风格迁移的原理 1、原始图像风格迁移的原理 在学习原始的图像风格迁移之前,可以在先看看ImageNet图像识别模型VGGNet(微调(Fine-tune)原理...

iOS,QRCord(矩阵二维码)

1.二维码及其原理介绍 2.二维码生成 3.二维码解析 二维码及其原理介绍 二维条码是指在一维条码的基础上扩展出另一维具有可读性的条码,使用黑白矩形图案表示二进制数据,被设备扫描后可获取其中所包含的信息。一维条码的宽度记载着数据,而其长度没有记载数据。二维条码的长度、宽度均记载着数据。二维条码有一维条码没有的“定位点”和“容错机制”。容错机制在即使没有辨识...