opencv的极线几何

news2025/7/27 12:20:56

一、理论介绍

当我们使用针孔相机拍摄图像时,我们会丢失一个重要的信息,即图像的深度。一个解决方案如我们的眼睛的方式使用两个相机(两只眼睛),这就是所谓的立体视觉。 

PO1O2为极平面,l1和l2为极线,e1和e2为极点。

原因:左边的摄像机,我们无法找到与图像中的点x相对应的3D点,因为线OX上的每个点都投影到图像平面上的相同点(没有一一对应),即图O中的一个点因为深度不确定。但是考虑右边的摄像机得到的图像。现在OX线上的不同点投射到右侧的不同点(xx')。 所以对于这两幅图像,我们可以对正确的三维点进行三角测量。

极线以及极线约束:OX上不同点的投影在右平面上形成一条线(I')。 我们称之为对应于点x的极线。 这意味着,要找到右侧图像上的点x,只需沿着这个极线搜索。它应该在这一条线上的某个地方(可以不用全图找,只需沿着极线搜索,增加效率准确性),这被称为极线约束,同样,所有的点在其他图像中都会有相应的极线。

极点:O和O'是相机中心,看到右侧相机O' 的投影在左侧图像上的点e处出现。 它被称为极点。 极点是通过相机中心和图像平面的交叉点。 类似地,e' 是左侧相机的圆心。在某些情况下,您将无法找到图像中的圆点,它们可能在图像之外(也就是说,一个相机看不到另一个)。

所有的极线都穿过它的极点。所以要找到极点的位置,我们可以找到许多极线并找到它们的交点。

Fundamental矩阵(F)和Essential矩阵:寻找极线和极点。但要找到它们,我们还需要两个东西:Fundamental矩阵(F)和Essential矩阵(E)。Essential矩阵包含有关平移和旋转的信息,这些信息描述了第二个摄像机相对于全局坐标中第一个摄像机的位置。图如下所示:

我们更喜欢在像素坐标系中进行测量Fundamental矩阵包含与Essential矩阵相同的信息,另外再加上两个相机的内在信息,以便我们可以将两个相机的像素坐标关联起来。简而言之,Fundamental矩阵F将一个图像中的一个点映射到另一个图像中的一条线(极线)。

就是左视图上一点x1到右视图上极线L2的关系,如下公式: L2=Fx1

对极原理来说,左视图上一点x1在右视图上的匹配点 x2 一定在极线L2上,也就是:x2TL2= x2TFx1=0

F从两个图像的匹配点计算出来的。找到基本矩阵(使用8点算法时)至少需要8个这样的点。

二、代码实现步骤如下:

一、找到两个图像之间尽可能多的匹配点来找到Fundamental矩阵,用SIFT来进行特征提取,然后用FLANN进行匹配并筛选好的匹配点。

先讲解一下,有关以下代码的一些知识点以及函数:

1、关键点和描述子:特征点包含了关键点和描述子,关键点指的特征点在图像中的位置,而描述子是指的是关键点的朝向和周围像素信息。相同特征点他们的描述子相似。

2、FlannBasedMatcher():从字面意思可知它是一种近似法,算法更快但是找到的是最近邻近似匹配,所以当我们需要找到一个相对好的匹配但是不需要最佳匹配的时候往往使用FlannBasedMatcher。当然也可以通过调整FlannBasedMatcher的参数来提高匹配的精度或者提高算法速度,但是相应地算法速度或者算法精度会受到影响。

参数:

index_params:采用的什么算法(值为1就是计算机自行采用),随机kd树,平行搜索。默认trees=4。

search_params:迭代的次数

3、knnMatch()

参数:描述子1,描述子2,查找最优的几个匹配点

返回值参数:匹配点,DMatch数据类型

4、DMatch数据类型:

queryIdx query描述子的索引,即特征点在训练图像中检测出的特征点集中的下标号

trainIdx train描述子的索引,即特征点在匹配图像中检测出的特征点集中的下标号

imgIdx  进行匹配图像的索引,如已知一幅图像的sift描述子,与其他十幅图像的描述子进行匹配,找最相似的图像,则imgIdx此时就有用了。      
distance 对应特征点之间的欧氏距离,越小表明匹配度越高

5、KeyPoint 数据结构:

angle 关键点的方向,值为0~360,负值表示不使用。如SIFT算法中为了保证方向不变形,
          通过对关键点周围邻域进行梯度运算,求得该点方向。(初值为-1)
         
octave 表示的是关键点所在的图像金字塔的层组

pt 关键点的坐标。pt.x为横坐标,pt.y为纵坐标。

reponse 响应程度,代表了该点是特征点的稳健度,可以用于后续处理中特征点排序

class_id 用于聚类的id,即当要对图片进行分类时,我们可以用class_id对每个关键点进行区分,默认为-1,也可自己设定
            
size 关键点邻域直径  

import cv2
import numpy as np
from matplotlib import pyplot as plt
 
img1 = cv2.imread('left.png', 0)  # queryimage # 左侧图片
img2 = cv2.imread('right.png', 0)  # trainimage # 右侧图片
 
sift = cv2.xfeatures2d.SIFT_create()
 
# 用SIFT查找关键点和描述子
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)
 
# FLANN参数
FLANN_INDEX_KDTREE = 1
index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
search_params = dict(checks=50)
 
flann = cv2.FlannBasedMatcher(index_params,search_params)
matches = flann.knnMatch(des1, des2, k=2)
 
good = []
pts1 = []
pts2 = []
 
# 按照Lowe的论文进行比率测试
for i, (m, n) in enumerate(matches):
    if m.distance < 0.8*n.distance:
        good.append(m)
        pts2.append(kp2[m.trainIdx].pt)
        pts1.append(kp1[m.queryIdx].pt)

 二、现在我们有两张图片的最佳匹配点的列表。让我们找到Fundamental矩阵。

FlannBasedMatcher():从两个图像中的对应点计算基本矩阵。

参数:

points1  包含第一张图像的 N 个点的数组(匹配点);
points2  与 points1 具有相同大小和格式的第二个图像点的数组;
method  计算基本矩阵的方法;

输出:

基本矩阵;

mask:输出包含N个元素的数组,其中的每个元素对于异常值都设置为 0,对于其他点设置为1。 该数组仅在 RANSAC 和 LMedS 方法中计算.对于其他方法,它设置为全1;

pts1 = np.int32(pts1)
pts2 = np.int32(pts2)
F, mask = cv2.findFundamentalMat(pts1, pts2, cv2.FM_LMEDS)
 
# 我们只使用inlier点
pts1 = pts1[mask.ravel() == 1]
pts2 = pts2[mask.ravel() == 1]

三、我们定义一个新的函数来在图像上绘制极线,第一图像中的点对应的极线的线条会在第二图像上绘制。

def drawlines(img1, img2, lines, pts1, pts2):
    ''' img1 - 我们要绘制到的图像
        lines - 相应的极线 '''
    r, c = img1.shape
    img1 = cv2.cvtColor(img1, cv2.COLOR_GRAY2BGR)
    img2 = cv2.cvtColor(img2, cv2.COLOR_GRAY2BGR)
    for r, pt1, pt2 in zip(lines, pts1, pts2):
        color = tuple(np.random.randint(0, 255, 3).tolist())
        x0, y0 = map(int, [0, -r[2]/r[1]])
        x1, y1 = map(int, [c, -(r[2]+r[0]*c)/r[1]])
        img1 = cv2.line(img1, (x0, y0), (x1, y1), color, 1)
        img1 = cv2.circle(img1,tuple(pt1), 5, color, -1)
        img2 = cv2.circle(img2,tuple(pt2), 5, color, -1)
    return img1, img2

 四、这两个图像中找到这些极线,调用函数画出来

computeCorrespondEpilines:找出极线的方法

参数:

     points :输入点,类型为CV_32FC2N × 1或1 × N矩阵。

     whichImage :包含点的图像(1或2)的索引。

      F :基本矩阵

     输出:对应于另一幅幅图像中点的极线的输出矢量( a , b , c )表示直线ax + by + c = 0 。 

# 找到右边图像(第二张图像)中的点对应的极线,在左边图像上画出来
lines1 = cv2.computeCorrespondEpilines(pts2.reshape(-1, 1, 2), 2, F)
lines1 = lines1.reshape(-1, 3)
img5, img6 = drawlines(img1, img2, lines1, pts1, pts2)
 
# 找到左边图像(第一张图像)中的点对应的极线
# 在右边图像上画出来
lines2 = cv2.computeCorrespondEpilines(pts1.reshape(-1, 1, 2), 1, F)
lines2 = lines2.reshape(-1, 3)
img3, img4 = drawlines(img2, img1, lines2, pts2, pts1)
 
plt.subplot(121), plt.imshow(img5)
plt.subplot(122), plt.imshow(img3)
plt.savefig('sift_left_right.png')
plt.show()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/35315.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于webrtc的数据传输研究总结

什么是webrtc WebRTC (Web Real-Time Communications) 是一项实时通讯技术&#xff0c;它允许网络应用或者站点&#xff0c;在不借助中间媒介的情况下&#xff0c;建立浏览器之间点对点&#xff08;Peer-to-Peer&#xff09;的连接&#xff0c;实现视频流和&#xff08;或&…

最新阿里云ECS服务器S6/C6/G6/N4/R6/sn2ne/sn1ne/se1ne处理器CPU性能详解

阿里云ECS服务器S6/C6/G6/N4/R6/sn2ne/sn1ne/se1ne处理器CPU性能怎么样&#xff1f;阿里云服务器优惠活动机型有云服务器S6、计算型C6、通用型G6、内存型R6、云服务器N4、云服务器sn2ne、云服务器sn1ne、云服务器se1ne处理器CPU性能详解及使用场景说明。 1、阿里云服务器活动机…

全局唯一ID

文章目录前言MongoDB ObjectIdTwitter SnowflakeUUID前言 基于数据库设置其实初始值&#xff0c;以及增量步长。基于ZK,Redis,改良雪花集中式服务生成&#xff0c;远程调用获取id。基于并行空间划分&#xff0c;Snowflake&#xff08;8Byte字节64bit位&#xff09;&#xff0c…

供应化学试剂mPEG-Azide,mPEG-N3,甲氧基-聚乙二醇-叠氮,CAS:89485-61-0

1、名称 英文&#xff1a;mPEG-Azide&#xff0c;mPEG-N3 中文&#xff1a;甲氧基-聚乙二醇-叠氮 2、CAS编号&#xff1a;89485-61-0 3、所属分类&#xff1a;Azide PEG Methoxy PEG 4、分子量&#xff1a;可定制&#xff0c;甲氧基-聚乙二醇-叠氮 5k、甲氧基-PEG-叠氮 10…

Higress 实战: 30行代码写一个 Wasm Go 插件

前言 在11月15号的直播 《Higress 开源背后的发展历程和上手 Demo 演示》中&#xff0c;为大家演示了 Higress 的 Wasm 插件如何面向 Ingress 资源进行配置生效&#xff0c;本文对当天的 Demo 进行一个回顾&#xff0c;并说明背后的原理机制。 本文中 Demo 运行的前提&#x…

PPOCR车牌定位模型推理后处理优化研究

综述 最近在研究基于PPOCR算法的车牌识别&#xff08;LPR&#xff09;&#xff0c;部署模型后发现之前关于OCR文本定位的后处理策略在车牌识别中存在定位精度不够高&#xff0c;文本框偏移的问题&#xff0c;如&#xff1a; 经分析发现是之前的OCR后处理策略存在一定局限&am…

java刷题day 03

选择题&#xff1a; 解析&#xff1a; 父类private的成员变量&#xff0c;根据权限修饰符的访问控制范围&#xff0c;只有在类内部才能被访问&#xff0c;就算是他的子类&#xff0c;也不能访问。这里如果将Person p new Child();改成 Person p new Person();代码依然无法通过…

乐趣国学—品读《弟子规》中的“余力学文”之道

文章目录余力学文不力行 但学文 长浮华 成何人但力行 不学文 任己见 昧理真读书法 有三到 心眼口 信皆要方读此 勿慕彼 此未终 彼勿起宽为限 紧用功 工夫到 滞塞通心有疑 随札记 就人问 求确义房室清 墙壁净 几案洁 笔砚正墨磨偏 心不端 字不敬 心先病列典籍 有定处 读看毕 还原…

信号完整性测试,关于SMA装配的细节,很多人都忽视了

作者 | 萧隐君&#xff0c;仿真秀专栏作者 SMA转接头是射频微波、天线和高速电路测试经常用到的一种连接器&#xff0c;应用非常广泛&#xff0c;种类也很多。在信号完整性的测试夹具中&#xff0c;2.92mm的SMA用的较多&#xff0c;它的带宽可以到40GHz&#xff0c;对于25Gbps…

【全网独家,收藏吧】10年全部《信息资源管理》真题整理,第2章 信息化规划与组织

文章目录&#x1f525; 11 年 4 月《信息资源管理》真卷选择题名词解释综合分析题&#x1f525; 11 年 7 月《信息资源管理》真卷选择题名词解释题简答题⭐ 12 年 4 月《信息资源管理》真卷选择题简答题⭐ 12 年 7 月《信息资源管理》真卷选择题简答题⭐ 13 年 4 月《信息资源管…

计算机网络--- 电子邮件

&#xff08;一&#xff09;电子邮件系统的组成 电子邮件是一种异步通信方式&#xff0c;通信时不需要双方同时在场。电子邮件把邮件发送到收件人使用的邮件服务器&#xff0c;并放在其中的收件人邮箱中&#xff0c;收件人可以随时上网到自己使用的邮件服务器进行读取。 一…

补盲激光雷达大爆发,各路产品谁领风骚?

11月伊始车载激光雷达赛道上演了冰火两重天的景象。国外Ouster与Velodyne LiDAR宣布合并以抱团取暖&#xff0c;主打OPA技术的Quanergy甚至股市停牌&#xff0c;一时风声鹤唳&#xff0c;寒意阵阵&#xff1b;而反观国内&#xff0c;禾赛、速腾、亮道相继发布纯固态补盲激光雷达…

龙格-库塔法(Runge-Kutta methods)

非线性的常微分方程通常是难以求出解析解的&#xff0c;只能通过多次迭代求近似的数值解。 龙格&#xff0d;库塔法&#xff08;Runge-Kutta methods&#xff09;是用于非线性常微分方程的解的重要的一类隐式或显式迭代法。简写做RK法。 对于任意的Yf(X),假设某点(Xi,Yi)的斜…

固定资产管理系统能帮助企业解决哪些问题?

固定资产管理系统是企业信息化转型中重要的工具之一。固定资产在企业整体资金和运营管理中的占比非同一般&#xff0c;因此企业管理者对固定资产的重视程度也逐渐提升。随着企业固定资产数量和种类的增多、人员的增多&#xff0c;以及分支机构和部门的增多&#xff0c;单纯依靠…

数据安全治理白皮书4.0(附下载link)

数据安全治理白皮书是国内最早的数据安全治理白皮书系列&#xff0c;围绕数据安全治理&#xff0c;“新理论、新技术、新实践”&#xff0c;一次系统汇总、梳理分析与集中呈现&#xff0c;2018年-2021年&#xff0c;已发布1.0/2.0/3.0三个版本&#xff0c;2022年&#xff0c;已…

LeetCode | 循环队列的爱情【恋爱法则——环游世界】

兜兜转转⚪还是你❤✒前言环形队列的概念拓展&#xff1a;生产者与消费者一、题目描述二、思路分析&#x1f351;初次遇见她♀【是心动的感觉】&#x1f351;阻碍一&#xff1a;队空还是队满不好区分【性格互异】&#x1f351;解决方案&#x1f351;阻碍二&#xff1a;很难获取…

Git之借助Commitizen规范化提交代码

文章目录一、约定式提交规范1.1 概述1.2 规范1.3 好处二、Commitizen2.1 安装2.2 安装并配置cz-customizable依赖2.2.1 安装依赖2.2.2 配置package.json2.2.3 添加cz-config配置文件2.3 使用2.4 问题一、约定式提交规范 1.1 概述 约定式提交规范是一种基于提交信息的轻量级约…

ES6 入门教程 26 编程风格 26.4 对象 26.5 数组 26.6 函数

ES6 入门教程 ECMAScript 6 入门 作者&#xff1a;阮一峰 本文仅用于学习记录&#xff0c;不存在任何商业用途&#xff0c;如侵删 文章目录ES6 入门教程26 编程风格26.4 对象26.5 数组26.6 函数26 编程风格 26.4 对象 单行定义的对象&#xff0c;最后一个成员不以逗号结尾。多…

流媒体传输 - RTSP 协议

概述 协议简介 RTSP RTSP (Real-Time Stream Protocol) 实时流传输协议是一种基于文本的应用层协议&#xff0c;常被用于 建立的控制媒体流的传输&#xff0c;该协议用于 C/S 模型 , 是一个 基于文本 的协议&#xff0c;用于在客户端和服务器端建立和协商实时流会话。 RTP …

JS语句完全攻略

JavaScript 语言定义了 20 套&#xff08;或个&#xff09;语句命令&#xff0c;分别执行不同的操作。 以用途划分&#xff0c;JavaScript 语句可以分为&#xff1a;声明、分支控制、循环控制、流程控制异常处理和其他。 以结构划分&#xff0c;JavaScript 语句又可以分为单句…