三维重建(四)PMVS算法 the patch-based MVS algorithm

通过前面的介绍,已经获得了相机的参数,我们可以利用这些参数使用基于面片的三维多视角立体视觉算法(PMVS)重建出稠密的点云。下面详细介绍一下PMVS算法。

一、基本概念介绍

1、面片(patch)

面片p是一个近似的正切与重建物体表面的一个小矩形,他的一边平行于参考相机的x轴。对于一个面片p,他的几何特征如下:

中心点:c(p);

单位法向:n(p),该向量指向相机的光心;

面片p对应一个参考图像R(p),在R(p)中p是可见的。针对p有扩展矩形,p在R(p)中的投影是μ×μ大小的,在原论文中μ=5 or 7

2、灰度一致性函数(Photometric Discrepancy Function)

首先,我们另图像集合V(p)是所有在自身图像中可见面片p的图像集合(显然这里有R(p)∈V(p),将在后面介绍V(p)的获得已经R(p)的确定)那么,灰度一致性函数定义如下:

g(p)=1|V(p)?R(p)|∑I∈(V(p)?R(p))h(p,I,R(p)

在这里,V(p)?R(p)是指出去R(p)的V(p)的其他元素;h(p,I1,I2)是指I和R(p)的灰度一致性函数,计算过程如下:

1. 首先把面片p划分为μ×μ的小格;

2. 通过双线性差值的方法,对p在Ii的图像上的投影进行差值,得到像素灰度q(p,Ii);

3. 用1减去q(p,I1)和q(p,I1)的NCC(normalized cross correlation)值。

过程如下图所示:

由于g(p)对于图像中出现高光或者有障碍物的情况下的效果不好,因此在实际情况下,我们需要保证图像I和图像R(p)的灰度一致性函数大于一定的值α(后面将会介绍如何选择这个阈值)。因此有:

V?(p)=I|I∈V(p),h(p,I,R(p)≤α)

g?(p)=1|V?(p)?R(p)|∑I∈(V?(p)?R(p))h(p,I,R(p)

3、面片的优化

面片优化的目的就是恢复那些g?(p)较小的面片,每个面片的重建过程分为以下两步:

4. 初始化面片的相关参数c(p),n(p),V?(p)和R(p);

5. 优化c(p)和n(p)

这里的第一步初始化的过程在后面用到,这里先讲以下c(p)和n(p)的优化。几何参数c(p)和n(p)的优化是通过最小化g?(p)而得到的。为了简化计算,将c(p)约束在某一条光线上,这样p在其对应的可视图集V?(p)中某个图像的投影位置就不会变,因此降低了p的自由度。n(p)是由欧拉角(yaw and pitch)决定的,可以用共轭梯度法求解这个优化问题。(这一段我没有懂这些方法)

4、图像模型

基于面片的物体表面的表示的优势是他的灵活性,然而却不容易找到面片的连续性。为了解决这个问题进行了如下的操作,把图像Ii分成了许多β1×β1像素的的小块Ci(x,y),这里x,y表示图像块的下标,i表示这是第i张图像的。给定一个面片p和对应的V(p),把p投影到V(p)的图像中,以得到面片p对应的图像块,每个图像块Ci(x,y)用一个集合Qi(x,y)记录了所有投影到这个图像块的面片。同理,我们用Q?i(x,y)来表示用V?(p)得到的结果。如下图所示:

二、面片的重构

基于面片的多视角三维立体视觉算法的目的就是保证在每个图像块Ci(x,y)上至少有一个面片的的投影。主要分为以下三步:

1. 初始化特征匹配(initial feature matching);

2. 面片生成(patch expansion);

3. 面片筛选(patch filtering);

初始化特征匹配的目的就是生成一系列稀疏的面片,面片的生成和筛选都要执行n次使得面片足够稠密,同时去除不好的面片。下面依次进行介绍。

1、初始化特征匹配

首先用DOG和Harris来提取图像的角点特征,即为每幅图像的特征点。对于图像Ii,以及其对应的光心O(Ii),该图像中的特征点f,通过允许有两个像素误差的极线约束找到它在其他图像中的同种类型的特征点f′,构成匹配点对(f,f′)。然后用这些匹配点对使用三角化的方法生成一系列三维空间点,然后将这些点按照距离O(Ii)从小到大顺序进行排列,然后依次尝试生成面片,直到成功。

尝试生成面片的方法如下所示:首先初始化候选面片的c(p),n(p)和R(p),如下所示:

由于生成的面片可能有很多错误的情况,因此我们认为在图像Ii中可见的面片是面片的法向量与面片中心到相机光心的连线夹角小于一定角度α的图像,即满足:

同样V?(p)的获得与前面所讲的方法相同。这样面片的信息都已经初始化过了,然后根据前面所讲的对c(p)和n(p)进行优化,并将优化过后的c(p)和n(p)带入

V?(p)=I|I∈V(p),h(p,I,R(p)≤α)

中对V(p)和V?(p)进行更新。如果|V?(p)|≥r,集认为面片p的可视图像至少为r幅,即接受面片p,重建成功。并将面片p存储到对应的可视图像的图像块中(即更新Qi(x,y)和Q?i(x,y))。

具体的算法描述和图示如下图所示,过程就是我上面说的过程,懒得翻译了,很好理解。

2、面片生成(patch expansion)

面片生成的目的就是保证每个图像块至少对应一个面片。通过上面生成的面片,重复的生成新的面片,具体来说就是给定一个面片p,首先获得一个满足一定条件的邻域图像块集合C(p),然后进行面片生成的过程。

下面是面片p的两个相关概念:

图像块邻域C(p):

面片p和p′的临近关系:

|(c(p)?c(p′))?n(p)|+|(c(p)?c(p′))?n(p′)|<2ρ1

即当面片p和p′满足上式时,即判定两者为临近关系,上式中的ρ1由R(p)在c(p)和c(p′)中的深度决定。

当存在一个面片p′其所属的图像块Ci(x′,y′)满足Ci(x′,y′)∈C(p),同时p和p′属于近邻关系时,此时将Ci(x′,y′)从C(p)中删除,不对他进行面片生成。同时,即使这个条件没有满足,只要Qi(x′,y′)不为空,也不需要再此图像块上执行生成操作。

对于C(p)中其余的图像块,将会执行面片生成的操作流程以生成新的面片p′。首先用p的相应变量初始化p′的n(p′)、R(p′)和V(p′),对于c(p’)的初始值为穿过Ci(x,y)的可视光线与面片p所在平面的交点。使用

V?(p)=I|I∈V(p),h(p,I,R(p)≤α)

由V(p)得到V?(p′),再由上面提到的方法对c(p′)和n(p′)进行优化。在优化的过程中,将c(p′)约束在一条直线上,使得p′在图像Ii上的位置不会改变,始终对应的是Ci(x,y)。优化完成后,给V(p′)加上一组图像,这些图像块些根据深度测试判断为p′对其应该是可见的,并根据此更新V?(p′)。

最终如果|V?(p′)|≥r,则判定p′是可接受的,即生成成功,同时更新Qi(x,y)和Q?i(x,y)。具体的参数设置参见原论文。

面片生成的算法流程如图所示:

3、面片过滤(patch filtering)

在面片的重建过程中,可能会生成一些误差较大的面片,因此需要过滤来确保面片的准确性。

第一个过滤器是通过可视一致性进行过滤,另U(p)表示与当前可视信息不连续的面片集合,所谓的不连续就是p和p′两个面片不属于近邻关系,但是却存在于同一个Qi(x,y)中。对于U(p)中的面片p,如果满足下列条件,则将其过滤掉。

|V?(p)|(1?g?(p))<∑pi∈U(p)1?g?(p)

直观上来讲,如果p是一个异常值,那么1?g?(p)和|V?(p)|都会比较小,这样p一般都会被过滤掉。

第二个过滤器同样也是考虑可视一致性,不过会更加严格,对于每个面片p,我们计算他通过深度测试得到的可视图像的总数,如果数目小于r,那么则认为p是异常值,从而过滤掉。

第三个过滤器,对于每个面片p,在V(p)中,收集这样的一组面片,他们的映射到面片p自己所在的图像块以及所有相邻的图像块,如果p的八邻域内的面片数量占收集所得面片数量的比例小于0.25,则任务p是异常值,将其过滤掉。

时间: 2024-10-13 13:50:05

三维重建(四)PMVS算法 the patch-based MVS algorithm的相关文章

支持向量机原理(四)SMO算法原理

支持向量机原理(一) 线性支持向量机 支持向量机原理(二) 线性支持向量机的软间隔最大化模型 支持向量机原理(三)线性不可分支持向量机与核函数 支持向量机原理(四)SMO算法原理 支持向量机原理(五)线性支持回归(待填坑) 在SVM的前三篇里,我们优化的目标函数最终都是一个关于\alpha向量的函数.而怎么极小化这个函数,求出对应的\alpha向量,进而求出分离超平面我们没有讲.本篇就对优化这个关于\alpha向量的函数的SMO算法做一个总结. 1. 回顾SVM优化目标函数 我们首先回顾下我们的

在一个字符串中,统计大写字母个数,小写字母个数,其他字符个数的四种算法

题目描述:编写程序,输出字符串中的大写字母.小写小母和其他的个数.如有一个字符串"Helle, This is A test textfile.123456, tannk you!!",则其大写字母个数:3,小写字母个数:29,其他字符个数:18. 这里提供了四种算法,第一种是我们比较好理解的,也属于硬编码问题,其他三种方法要借助JAVA语言的jdk提供的api. 方法一: <!DOCTYPE html> <html lang="en"> &

求逆元的四种算法(拓欧费马小线性推欧拉)

求逆元的四种算法 拓展欧几里得算法求逆元 上一篇博客中已经讲过拓展欧几里得算法,并且讲解了求逆元的原理.这里只列出代码 在要求逆元的数与p互质时使用 代码 //扩展欧几里得定理 int ex_gcd(int a,int b,int& x,int& y) { if(b==0) { x=1; y=0; return a; } int ans = ex_gcd(b,a%b,x,y); int tmp = x; x = y; y = tmp-a/b*y; return ans; } int cal

求解最短路的四个算法及其优化

目录 求解最短路的四个算法及其优化 1.Dijkstra算法 <1.朴素Dijkstra算法: <2:堆优化的Dijkstra算法 2.Floyd算法 3.Bellman-Ford算法 4.SPFA算法 求解最短路的四个算法及其优化 1.Dijkstra算法 Dijkstra很好的运用了贪心算法,其思想是一直找离已加入顶点集合的最短边,更新邻点,下面是实现代码: <1.朴素Dijkstra算法: [题意]:给定一个n个点m条边的有向图,图中可能存在重边和自环,所有边权均为正值.请你求出1

全排列算法(字典序法、SJT Algorithm 、Heap&#39;s Algorithm)

一.字典序法 1) 从序列P的右端开始向左扫描,直至找到第一个比其右边数字小的数字,即. 2) 从右边找出所有比大的数中最小的数字,即. 3) 交换与. 4) 将右边的序列翻转,即可得到字典序的下一个排列. 5) 重复上面的步骤,直至得到字典序最大的排列,即左边数字比右边的大的降序排列. 二.SJT Algorithm 初始状态为. 1) 找到最大的可移动数m(当一个数指向一个比它小的数是,该数就是可移动数) 2) 交换m和m所指向的数 3) 改变所有比m大的数的方向 4) 重复上面的步骤,直至

机器学习(四) 机器学习(四) 分类算法--K近邻算法 KNN (下)

六.网格搜索与 K 邻近算法中更多的超参数 七.数据归一化 Feature Scaling 解决方案:将所有的数据映射到同一尺度 八.scikit-learn 中的 Scaler preprocessing.py import numpy as np class StandardScaler: def __init__(self): self.mean_ = None self.scale_ = None def fit(self, X): """根据训练数据集X获得数据的均

SPFA,dijskra,prime,topu四种算法的模板

1 ////#include<stdio.h> 2 ////#include<string.h> 3 ////#include<queue> 4 ////#include<algorithm> 5 ////using namespace std; 6 ////const int INF=0x3f3f3f3f; 7 ////const int MAXN=110; 8 ////const int MAXM=20010; 9 ////int top,vis[MAX

AP聚类算法(Affinity propagation Clustering Algorithm )

AP聚类算法是基于数据点间的"信息传递"的一种聚类算法.与k-均值算法或k中心点算法不同,AP算法不需要在运行算法之前确定聚类的个数.AP算法寻找的"examplars"即聚类中心点是数据集合中实际存在的点,作为每类的代表. 算法描述: 假设$\{ {x_1},{x_2}, \cdots ,{x_n}\} $数据样本集,数据间没有内在结构的假设.令是一个刻画点之间相似度的矩阵,使得$s(i,j) > s(i,k)$当且仅当$x_i$与$x_j$的相似性程度要大

Shank的大步小步算法(Shank‘s Baby-Step-Giant-Step Algorithm)

1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <map> 5 typedef long long LL; 6 int mul_mod(int a,int b,int n){ // a.b都小于n 7 return a * b % n; 8 } 9 int pow_mod(int a,int p,int n){ 10 if(p == 0) return 1; 11