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

2024-02-25 04:20

本文主要是介绍归一化八点算法及图像之间基础矩阵求解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

文章目录

    • 归一化8点算法及图像之间基础矩阵求解
      • 归一化8点算法介绍
      • 归一化8点算法步骤
      • 归一化8点算法总结
      • 对极几何与基础矩阵
      • 实验详细需求
      • 实验过程及代码
        • (1)左右拍摄,极点位于图像平面上。
        • (2)像平面接近平行,极点位于无穷远,如图所示
        • (3)图像拍摄位置位于前后,如图所示

多视图几何时利用在不同视点所拍摄图像间的关系,来研究照相机之间或者特征之间关系的一门科学。多视图几何中最重要的内容是双视图几何。如果有一个场景的两个视图以及视图中的对应图像点,那么根据照相机的空间相对位置关系、照相机的性质以及三维场景点的位置,可以得到对这些图像点的一些几何关系约束。

归一化8点算法介绍

基本矩阵是由下述方程定义:
在这里插入图片描述
其中x↔x’x↔x′是两幅图像的任意一对匹配点。由于每一组点的匹配提供了计算F系数的一个线性方程,当给定至少7个点(3×3)的齐次矩阵减去一个尺度,以及一个秩为2的约束),方程就可以计算出未知的FF。我们记点的坐标为x=(x,y,1)T,x’=(x’,y’,1)Tx=(x,y,1) T,x′=(x′,y′,1) T,则对应的方程为:
在这里插入图片描述
展开后有:
在这里插入图片描述
把矩阵F写成列向量的形式,则有:
在这里插入图片描述
给定n组点的集合,我们有如下方程:
在这里插入图片描述
如果存在确定(非零)解,则系数矩阵AA的秩最多是8。由于F是齐次矩阵,所以如果矩阵A的秩为8,则在差一个尺度因子的情况下解是唯一的。可以直接用线性算法解得。

如果由于点坐标存在噪声则矩阵A的秩可能大8(也就是等于9,由于A是n×9的矩阵)。这时候就需要求最小二乘解,这里就可以用SVD来求解,ff的解就是系数矩阵A最小奇异值对应的奇异向量,也就是A奇异值分解后A=UDVT

中矩阵V的最后一列矢量,这是在解矢量ff在约束‖f‖下取‖Af‖最小的解。以上算法是解基本矩阵的基本方法,称为8点算法。

归一化8点算法步骤

由于基本矩阵有一个重要的特点就是奇异性,F矩阵的秩是2。如果基本矩阵是非奇异的,那么所计算的对极线将不重合。所以在上述算法解得基本矩阵后,会增加一个奇异性约束。最简便的方法就是修正上述算法中求得的矩阵F。设最终的解为F′ ,令detF′=0下求得Frobenius范数(二范数)‖F−F ′‖最小的F′F′ 。这种方法的实现还是使用了SVD分解,若F=UDV ,此时的对角矩阵D=diag(r,s,t),满足r≥s≥t,则F′=Udiag(r,s,0)VT 最小化范数‖F−F′‖,也就是最终的解。

所以8点算法由下面两个步骤组成:
1.求线性解 由系数矩阵AA最小奇异值对应的奇异矢量ff求的FF。
2.奇异性约束 是最小化Frobenius范数∥F−F′∥‖F−F′‖的F′F′代替FF。

归一化8点算法总结

8点算法是计算基本矩阵的最简单的方法。为了提高解的稳定性和精度,往往会对输入点集的坐标先进行归一化处理。在MVG的估计一章中推荐各向同性归一化,OpenCV的8点算法也是使用了各向同性,也就是使得各个点做平移缩放之后到坐标原点的均方根距离等于2–√ 2 。

对于归一化八点算法的总结如下:
给定n≥8n≥8组对应点xi↔x′i ,确定基本矩阵FF使得x’TiFxi=0x
算法:
1.归一化:根据xˆi=Txi,xˆ′i=T′x′i ,变换图像坐标。其中T和T′ 是有平移和缩放组成的归一化变换。
2.求解对应匹配的基本矩阵F’。
1.求线性解:用由对应点集xˆi↔xˆ′i 确定的系数矩阵Aˆ 的最小奇异值的奇异矢量确定Fˆ。
2.奇异性约束:用SVD对Fˆ 进行分解,令其最小奇异值为0,得到Fˆ′ 使得detF’=0。
3.解除归一化:令F=T’TFˆ′T。矩阵F就是数据xi↔x′i 对应的基本矩阵。

通常SVD算法来计算最小二乘法,由于上面的算法得出的解可能秩不为2(基础矩阵的秩小于等于2),所以需要通过最后一个奇异值置0来得到秩最接近2的基础矩阵。上面的函数忽略了一个重要的步骤:对图像坐标进行归一化,这可能会带来数值问题。

八点算法的优点:
线性求解,容易实现,运行速度快 。
八点算法的缺点:
对噪声敏感。

对极几何与基础矩阵

基本矩阵体现了两视图几何(对极几何,epipolar geometry)的内在射影几何(projective geometry)关系,基本矩阵只依赖于摄像机的内部参数K和外部参数R、t

对极平面 = 包含基线的平面
对极线 = 对极平面与像平面的交线
对极点= 基线与像平面相交点= 光心在另一幅图像中的投影

基础矩阵是对极几何的代数表达方式
基础矩阵描述了图像中任意对应点 x↔x’ 之间的约束关系
在这里插入图片描述
F 为 3x3 矩阵,秩为2,对任意匹配点对 x↔x’ 均满足xTFx’=0

  1. 转置: 如果 F 是表述点对 (x, x’)之间的基础矩阵, 则 FT 表述点对 (x’,x)之间的基础矩阵;
  2. 对极线: F 可以将点 x 映射到对应像平面上一条线 l=Fx’,同理可得 l’=FTx
  3. 对极点: 对于所有对极线, 有 eTFx’=0, 全x’ →eTF=0, 同理有 Fe’=0
  4. F 自由度为 7 , i.e. 3x3-1(homogeneous)-1(rank2)

实验详细需求

分别用七点、八点、十点(匹配点),计算基础矩阵
图片包含三种情况,即:
(1)左右拍摄,极点位于图像平面上,如图所示
在这里插入图片描述
(2)像平面接近平行,极点位于无穷远,如图所示
在这里插入图片描述
(3)图像拍摄位置位于前后,如图所示
在这里插入图片描述
针对上述情况,画出极点和极线,其中点坐标要均匀分布于各行

实验过程及代码

我是用了SIFT对两个图像进行特征提取以及匹配,然后使用归一化8点算法进行基本矩阵的求解。

代码实现:

# 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 siftcamera = reload(camera)
homography = reload(homography)
sfm = reload(sfm)
sift = reload(sift)# 提取特征
im1 = array(Image.open('D:/test/test5/7.jpg'))
sift.process_image('D:/test/test5/7.jpg', 'im1.sift')im2 = array(Image.open('D:/test/test5/8.jpg'))
sift.process_image('D:/test/test5/8.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

这篇关于归一化八点算法及图像之间基础矩阵求解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/744379

相关文章

python panda库从基础到高级操作分析

《pythonpanda库从基础到高级操作分析》本文介绍了Pandas库的核心功能,包括处理结构化数据的Series和DataFrame数据结构,数据读取、清洗、分组聚合、合并、时间序列分析及大数据... 目录1. Pandas 概述2. 基本操作:数据读取与查看3. 索引操作:精准定位数据4. Group

基于Python开发一个图像水印批量添加工具

《基于Python开发一个图像水印批量添加工具》在当今数字化内容爆炸式增长的时代,图像版权保护已成为创作者和企业的核心需求,本方案将详细介绍一个基于PythonPIL库的工业级图像水印解决方案,有需要... 目录一、系统架构设计1.1 整体处理流程1.2 类结构设计(扩展版本)二、核心算法深入解析2.1 自

Javaee多线程之进程和线程之间的区别和联系(最新整理)

《Javaee多线程之进程和线程之间的区别和联系(最新整理)》进程是资源分配单位,线程是调度执行单位,共享资源更高效,创建线程五种方式:继承Thread、Runnable接口、匿名类、lambda,r... 目录进程和线程进程线程进程和线程的区别创建线程的五种写法继承Thread,重写run实现Runnab

C# 比较两个list 之间元素差异的常用方法

《C#比较两个list之间元素差异的常用方法》:本文主要介绍C#比较两个list之间元素差异,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. 使用Except方法2. 使用Except的逆操作3. 使用LINQ的Join,GroupJoin

深度解析Java项目中包和包之间的联系

《深度解析Java项目中包和包之间的联系》文章浏览阅读850次,点赞13次,收藏8次。本文详细介绍了Java分层架构中的几个关键包:DTO、Controller、Service和Mapper。_jav... 目录前言一、各大包1.DTO1.1、DTO的核心用途1.2. DTO与实体类(Entity)的区别1

Java中的雪花算法Snowflake解析与实践技巧

《Java中的雪花算法Snowflake解析与实践技巧》本文解析了雪花算法的原理、Java实现及生产实践,涵盖ID结构、位运算技巧、时钟回拨处理、WorkerId分配等关键点,并探讨了百度UidGen... 目录一、雪花算法核心原理1.1 算法起源1.2 ID结构详解1.3 核心特性二、Java实现解析2.

java Long 与long之间的转换流程

《javaLong与long之间的转换流程》Long类提供了一些方法,用于在long和其他数据类型(如String)之间进行转换,本文将详细介绍如何在Java中实现Long和long之间的转换,感... 目录概述流程步骤1:将long转换为Long对象步骤2:将Longhttp://www.cppcns.c

从基础到进阶详解Pandas时间数据处理指南

《从基础到进阶详解Pandas时间数据处理指南》Pandas构建了完整的时间数据处理生态,核心由四个基础类构成,Timestamp,DatetimeIndex,Period和Timedelta,下面我... 目录1. 时间数据类型与基础操作1.1 核心时间对象体系1.2 时间数据生成技巧2. 时间索引与数据

安装centos8设置基础软件仓库时出错的解决方案

《安装centos8设置基础软件仓库时出错的解决方案》:本文主要介绍安装centos8设置基础软件仓库时出错的解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录安装Centos8设置基础软件仓库时出错版本 8版本 8.2.200android4版本 javas

Linux基础命令@grep、wc、管道符的使用详解

《Linux基础命令@grep、wc、管道符的使用详解》:本文主要介绍Linux基础命令@grep、wc、管道符的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录grep概念语法作用演示一演示二演示三,带选项 -nwc概念语法作用wc,不带选项-c,统计字节数-