00:14
咱们就开始吧。嗯,大家好,嗯,非常开心能够在这里和大家一起分享一起匹立体匹配相关的知识,嗯,很感谢3D视觉工坊能够给我们提供这样的一个相互交流的机会,我觉得他们在做一个非常棒的事情。希望我今天的分享能够给大家一点有用的信息。呃,首先做一个自我介绍,呃,我叫李迎松,嗯,博士毕业于武汉大学摄影测量与遥感专业,我的主方向是立体匹配和影像的三维重建。那这里我先用一个简短的时间来介绍一下我最近这段时间在做的一个我觉得比较有意义的工作。首先是最近我在CSDN和知乎上面都在同步的写一些关于立体匹配相关的一些理论和实战的一些文章,嗯。
01:11
另外一件呢,我觉得特别有意义的事情是,我在给上面也在开源一些关于立体匹配相关的算法,嗯,可以给大家,可以让大家免费的下载和那个参考。这个是我的知乎和CSDN的主页,里面有一些关于立体匹配视觉相关的文章,如果大家感兴趣的话,可以在这两个平台去搜索我的名字就可以了。呃,这是我的那个get HUB的主页,我目前开源了两个立体匹配的经典的算法,一个是新global match s GM的算法,另一个是是我今年上半年开始做了一个,嗯,一个工作我觉得还是蛮有意义的,到目前为止也是有100多个,嗯,100多个,嗯,人觉得这个工作做的还不错,我也会持续的更新下去。
02:06
后面会写更多的关于立体匹配相关的算法在里面。如果大家感兴趣的话,可以进我的主页看一看。嗯,今天的报告的话,我主要是从两个部分去呃去讲述,其一是立体匹配的理论概述,其二是立体匹配的实战入门,整体来说的话可能会偏实战入门一些。首先理论它是实战的基础,所以说我们一定是在实战的前面去讲理论,理论先于实战而行。我们知道立体匹配,它是立体视觉从图像生成三维点云的一个常规手段,立体视觉呢,它的应用是非常广泛的,我这里列举了五个比较经典的应用,其一是深度相机。这个大家都可能不是特别陌生,因为现在英特尔还有国内的一些厂商都在呃研发它属于自己的深度相机,深度相机在实际的应用中也是呃非常的广泛的。
03:10
其二是三维重建,呃,我这其实三维重建它是一个非常大的方向,我这里特指基于那个无像无序的影像及生成三维模型的一个方向。其三是自动驾驶。自动驾驶大家肯定更熟悉了,它是当前应该说非常热门的一个一个领域,因为自动驾驶它要感感知周遭的周围的一个三维的信息,而这个三维信息的获取手段之一就是立体视觉。其次人脸识别,人脸识别发展到现在已经成为了三已经,嗯,大多数都采用了一种三维的,三维的人脸识别的方案和三维信息的获取。获取手段之一就是立体视觉。其五,智能机器人。智能机器人其实和自动驾驶是比较类似的,它也需要感知周围的三维三维信息,而这个三维信息的获取的手段之一就是立体视觉。
04:07
在空间中的同一个点,它在两两个视图上面同时成像,那么它就形成一个双目立体,而这个而它在在两张视图上同时成像了那个像素点,他们叫做一个同名点,对,从右边我们可以看右边这个图,我们可以嗯比较直观的看到什么是同名点,对这个。实际上一一个同名点对,它代表的是空间当中的同一个点,而我们立体匹配它要所解它,它要解决的问题就是要去寻找。要去在图像中寻找,寻找一那些同名点对,寻找那些同名点对。根据同名点的数量的多少,其实我们是可以分为稀疏的立体匹配和稠密的立体匹配。稀疏的立体匹配它是寻找有限的同名点,而稠密的立体匹配它是尽可能把图像中所有像素的同名点对都要寻找出来,而我们我们今天的那个报告主要就是针对于稠密的立体匹配。
05:11
呃,如何去,如何去解决这个同名点的搜索问题呢?我们首先想到的就是一个暴力便利法。我们可以看这个上图,我们可以看这个上图,嗯,对于左图当中的一个点,我们在右图上去一个一个在右一个一个一个像素点的便利,然后计算它们两个之间的相关性,选择相关性最大的那个点作为左图这个像素的同名点对同名点,那么这样的搜索会带来带来什么问题呢?有两个,其一是我这个这种暴力搜索法,它的效率是非常低的,可以想象我的图像如果宽是W。然后高是H,那么那么我我对于左图上面的每一个像素点,我在右图上都要去遍历所有的像素,就是W乘以H,是因为右图也是WHH,那么总共需要遍历的次数是多少呢?是W乘以H。
06:12
再乘以W乘以H。这个时间复杂度是非常高的,这是一,第一点它的效率非常低,第二点它的出错的概率会增大,因为我们是没法去提出一种完美的相关性的度量函数,使得相关性最大的那个点一定就是真实的同一点对,往往是往往出现一种情况是相关性最大的那个点可能不是真实的同名点对。而当我们搜索的像素对越多,那么这个出错的可能性就会越大,所以说这两点是暴力搜索法所带来的问题,那么我们有没有方法去解决这个问题呢?这就要感谢有一个非常经典的约束,叫做极限约束。极限约束它所描述的是什么样的关系呢?它所描述的是我在左视图和右视图当中。
07:06
都存在,分别存在一条直线。都分别存在一条直线,左视图有条直线,然后右视图有条直线,这两条直线它直线它称为一个极限对,然后任意一条直线上的像素,它的同名点对都必定必定是存在于另外一个视图另外一条直线上的直线上的这个这样的一个特性就可以把这个搜索范围大大减少,那么我针对于左视图的一个像素点,那么我一定是可以去计算它在右视图上面的那个极限的。它搜索只需要沿着这个极限去搜索,对对摄影测量里面极限也叫做和线。然后它它,那么它的搜索空间就从一个全图的二维直接降成了一维,这样降维了,降维了之后,它的搜索效率就大大提高了,而且它的出错的几率也大大减少,这个就是极限约束所带来的一个好处。
08:05
我们看一看左上角这个图,这个是原始的一个双目,双目立体,像双目立体的一个一个系统。然后P点大P点是那个空间点的坐标or是左视图的一个,嗯,摄影中心。OT是右视图的这个摄影中心,这个这三个点,它会形成一个一个平面,它叫极平面。这个极平面呢,嗯,它是通过P点和P和OT这三个点的这个平面,它和左视图和右视图分别相交于一条直线。左视图相交的这个直线是条黑线,然后右视图相交的这条绿色的线,这条线叫做极线,这个就是我刚才所说的上上一篇可所说的极限对这条极限对左边的这条极限上面的像素点,它的同名点是一定位于它对应的这条在右视图上面的这条极线的。
09:07
大家可以可以自己改看一下这个,因为这个大P点在左边的这个这个像素点,它的同名点是一定位于这个这条那条绿线上面,这个QQ点在这个在这个视图上的那个像素点,它的同名点也一定位于这条直线上面。就像左下角这个图所表现的一样,这个红叉点是同一点对这个左边的,左边的那个红叉点一定它的同一点一定位于右边的这条那个直线上。那么我们还有一个叫极限纠正的,它是什么东西呢?极限纠正它是进一步去把这去去让这个极限进一步的去让这个极限更更方便的运用。因为像左边这种方式,极限它是它的分布不是按照按照这个图像的排列来的,按照图像排列,那么我们用的时候必须去计算这个极限的一个方程,然后算这个极限和这个像素的相交的一呃,和这个影像的相交的这些像素到底在哪个位置,这个比较麻烦,那么我们做了极限纠正之后呢,就变成了右下角这种方式。
10:15
右下走这种方式的话,极限就和这个图像的那个行平行了,平行了。而且同那个对应的极限对它的横坐标Y值,它的坐标是相等的。这个Y值是相等的。这个就是一个非常好的特性,我们直接通过遍历这个图像,我就可以确定这个极限,极限对了,就是每一行就是一条极限,每一行就是一条极限,而且左右,左右对应的极限对在于同一行,这个这个特性就非常清晰了,因在算法设计的时候就很好的运用了,那极限向极限纠正,实际上就是把这个图像进行一个旋转。进行一个旋转之后呢,这个图像它的橡皮面是和这个基线是平行的,你看这个橡皮面和这个基线是平是平行的,而且而且还有一个特性是它的橡平面和那个。
11:13
两个两个视图的那个主光轴是垂直的,这个光轴是这样的,之前光轴是是那个斜的嘛,纠正之后这个光轴是和橡平面垂直的是直的。是这样的。这样,就这样,其实就是为了让我们更好的用算法设计,让那个算法的时间复杂度进一步的降低。在极限纠正之后,它的同名点就位于同一行之内,它们的横坐标是相同的,只存在列坐标的偏差,这个列坐标的偏差呢就叫做视差,实际上广义的视差,它是广义的视差,它是有行视差和列视差的。那个,但是因为我们极限纠正之后,它是同一行之内,那么我就只有列坐标的时差,就叫做,所以说我们在立即匹配里面说到四差,实际上单子列坐标的视差,列坐标的偏差。
12:09
一般来说,我们说视差就是用这个公式XR减XT,这个嗯,这个R和T实际上就是左视图和右视图,呃,也就是说D就其实等于左视图的X坐标减去右视图的X坐标,我们一般是这样用的,嗯,所以其实你用右视图剪左视图也倒是没什么问题,但是国大家都是用这种左视图剪右视图,所以说你嗯,还是大家都用同一种用法,还是比较比较方便一些。嗯,通过任意一个视图的像素坐标以及视差,就可以计算它的另一个视图的同名点,这个比较好理解,因为我们只有列坐标的是偏差嘛,那么如果说我的左左像素是左,左视图上面一个像素是XY。
13:00
然后呢,它的视差是D,那么它的右视图的同名点呢,就是X减D和Y是吧,因为它的横坐标相同嘛,然后列坐标只只存在一个一个时差的偏差嘛,而且时差是等于左视图的像数减去右视图的那个X,左视图X减去右视度X嘛,所以说实际上我们最后表示表示这个,嗯。嗯,匹配结果的时候,我们就用这个XY去表示。我们不用,我们不用这样表示,有可能大家可能想象有这样一种表示方式,就是XLY。XR这样一种表示方式,这样也可以,因为他们两个是一个同名点对嘛,一个同名点对是这样表示。但是我显然我用XYD就可以这样表,可以表示两个同点了,那么我们用XYD可能就少一个少一个那个少一少一点那个字节嘛,就是在内存的时候,我用三个数据表示比四个数据表示占用的内存更少嘛,所以XYD现在是通用的表示方法。
14:07
然后存储每一个像素视差值的图像,叫做视差图。这个大家都不太陌生吧,视差图它是像素为单位,就是这一个第第三个,第三个这个就是一个视差图,它其实是和这个影像是等大小的,它的宽度和这个影像的宽度是相同的,它的高度也是和原始影像的高度是相同的,只不过不同的是在于它们的元素的意义是不一样的,视差图所存储的存储的这个元素的意义啊,它是视差值,而这个原始影像呢,它所存储的是图像的亮度或者色彩值,这是不一样的地方。然后四杀图,它是以像素为单位的。第四点,视差图,它可以结合基线和相机内参计算深度图,深度图又是一个概念深度图,然后深度图它也是和图像等大的,它的尺寸也是和图像一样的,而不一样的是深度图它所存储的元素呢,它就和视差图也不一样的,它所存储的是空间中的一个一一个度量单位。
15:14
它是空间单位,比如说米,毫米这种单位,它叫深度图,深度,深度的含义我后面一篇,我后面那个会会讲什么是深度图,后面会讲我这里你只要记住四插图是可以转换成深度图的。时差它和深度它是一一对应的关系,一一对应就是一个时差对应一个深度,一个深度对应一个时差,不可能存在两个时差对应一个深度,或者两个深度对应一个时差,这种情况是不可能的。视差公式我前面也说了,视差公式就是左边的左视图的嗯,那个同名点对在左视图的X坐标减去在右视图的X坐标。这个。
16:00
这是视差的公式,非常简单,那么深度公式呢?深度公式前面我说了,深度公式是通过视差,还有基线,还有焦,还有焦距计算出来的,那么这个公式就是图中这个这两个公式一和二。21的一个特殊的特殊形式就是当X0L等于X0R的时候,这个X0L和X0R是什么意思呢?X0L是向主点在向主点在左视图上的。这个X坐标,然后X0R呢是向主点,是右视图的向主点在右视图上的X坐标。嗯,这个这个公式其实非常好推的,非常好推导,不知道大家推导过没有。如果大家没有,如果大家大家没有关注这部分的话,我可以给大家讲一讲到底是怎么推导出这个公式的。这个公司其实其实是呃,非常简非常简单的。
17:01
它是通过一个三角形的那个相似,相似匹配来来得到的相似性来得到的,就是因为我们先先说一下这个图,我们先做一下这个图,这个图是什么什么,这个什么含义呢。这一段这个其实是向主点,这个点是向主点。这个点是向主点,向主点是那个光轴和这个向平面的交点。向左点,那么我们我们来看一下啊,这个公司怎么推导的。这个这个是焦距F。这个是焦距F。然后这个深度,深度它实际上是向那个和线纠正之后的相机坐标系下的J值,J值就是这个深度。这个是深度。我们在这里画一条线,在这里画一条线。那么我们用的相似性关系是这个三角形。和这个三角形。是相似的。
18:01
然后这个三角形。和这个三角形是相似的。这个应该应该大家都都都能理解,这两个相似的关系是比较很好理解的,然后我这个这个的X坐标是X0R,因为这个向左点嘛,是吧,这个向点的X坐标是X0L,这个向左点的X坐标是X0L。然后这个P点的坐标是X。L,所以我们只说了X坐标,因为Y坐标都是已知的,Y坐标都是相同的,我们就不讨论Y了,这个是P撇的,P1撇的X坐标是XR。我们先把它定义清楚,然后呢,这一段我们给它定义一个B1。这一段我们给他定一个B2。好。那我们来推导一下,可以看啊相似性的相似三角形的话,相似三角形可以有一个定有一个有一个定理叫做这一这条边,这条这个腰,腰上这条边比上这个底边,然后等于这个这个高等于这条高比上这条高。
19:12
这边也是一样,这个比这个。等于这条边比上这条边。这两边其实上就是Z嘛,就是D。就深度地,深度地。所以,所以就是这样,然后F比D实际上是等于这个,这个腰是XL减去X0。X0 LXL减去X0。L,然后比上这个底边叫B。等于X。等于这边的哈,这边的是X0 R减去XR。X0 R减去XR,再比上B2。然后这个就等于呢,这个相加,这个这两个相分子相加,分母相加,分子相加是B1加B2。
20:06
B1加B2。然后分母相加是X0。不是XL。减去。X0L加上X0R。减去X。减去XR是吧。然后呢,B1加B2是等于B的,就是极限。这这个这个这个这个这个加这个B1加B2是等于下面这个比底边嘛,等于等于这个基线。然后等于这个,我们把这个改一下XL加。减去X,我们换一个顺序,XL减去X,然后加上括号。X0L减去X0L这样一个关系等于B分之。
21:01
XL减XR其实就是这个时差,就是这个时差就等于D。加上X0R减X0L。OK。最后就是。最后就是这一个等于这一个。这样这个这个等于这个就可以推出这个公司了。是吧?这个F比D等于这个D加上X0减去X0 L比B,这样就可以推出这个这个这个深度公式就等于。这个可以推出。推出D就等于BF。除以D加上X0R减去X0L对吧。
22:01
这个没问题。OK,那我们就就下下一张。嗯,我们可以看左边这个图,左边这个图它是一个离散化的视差与深度的平面,实际上是一个一个是一个深度的一个深度的平面,每一个深度呢,呃,四差之间的间隔是一个像素,它就是嗯,通过通过这个这个公式去算出,算出每一个四差,每一个整数四差下的那个深度值是多少。是一个离散的。比如说我的时差值是一的时候,是这个平面是二的时候,就是这个平面是三的啊,应该是。是深度值越大于差值越小,所以说应该是这样的,我给大家写一下,应该这是这是四差一的时候,这是四差二的时候,这是四差三的时候,这是四差四的时候。所以。其实通过这个公式啊,通过通过视差转深度这个公式啊,我们可以得出两个两个那个结论,一个是深度值越大,视差值越小。
23:09
深度就是说离相机越远,它的视差值是越小的。第二点是,呃,这个可以,这个第一个其实是显而易见的,因为你们他们视差和深度是反比例关系嘛,反比例关系,所以说四差值越大,视差深度值越大,视差值越小,这个离散的实际上是为了大家那个那个可视化的一个比较清晰的可视化的肯定实际上实际的结果肯定肯定不是离散的,它是一个实际的肯定是一个连续的嘛。然后第二点是深度值越大,同样的视差范围对应的深度范围就越大,这个是从这个图上一个直观的看出来的,深度值越大的时候,因为我这个间隔是一个时差嘛,你发现同样是间隔一个时差,但是这个相机越远,这个深度间隔就越来越大了。是吧,其实大家可以去用公式去推一下的,推一下的就是同一个时差下面深度,它的它的深度间隔是多少,这个其实揭示的一个道理就是深度越大的时候,我同样一个像素,我同样一个像素,它对应的差范围,我的深度范围越来越大,这样呢,我如果说我的算法的精度是一个像素,我稍微偏了一个像素,那么我离相机越远,深度偏的就越就就就会越远,这样我同样一个算法,你离相机越远,那么你的精度就你的那个空间精度就会越差,因为我如果说稍微偏一点点,那么你你的空间上面偏的值可就大了。
24:38
所以说它揭示的是你把你离相机越远的话,精度会越差。所以说你通过这个公式,你能不能推导出你的视差范围了?因为我们做立即匹配的时候,视差范围是一个非常重要的概念,我们总是会拿到一个算法,算法的一个输入参数差的范围,这个你可能会纳闷,我为什么要输入一个时差范围呢?我应该定一个什么样的时差范围比较合理呢?
25:04
一般来说啊,一般来说当有同学问我的时候,我不知道他到底是什么场景,所以我会跟他说,你就直接在图像上面去量,你在图像上看哪一个点离你的,你离你的那个虚拟的相机啊,你你那个,因为你拿到图像之后,你可以虚拟,你在脑海中可以虚拟出这个图像的相机在哪个位置。你就去,你想你就去图像上去看哪一个点是离相机最近的,然后去量出这个这个点的时差值,然后你再去看哪个点是离相机最远的,然后你再去量这个时差值,这两个时差值的范围,它就是它就是算法应该输入了视差范围,你稍微往外扩一点就可以了。嗯。另一种方式呢,是我知道你的你的那个基线和焦距这两个,我知道你这两个,那么我就可以直接通过你的场景的那个空间的范围,比如说你的相机要测量的是多大的那个深度啊,你想测量300~500毫米的那个,做做两三百到500毫米的测量,还是想做十米到20米的测量呢?就通过你这个,你这个应用的需求,你可以去推算我,我应该给算法输入一个什么样的时差范围,范围之外的我就不管了,我只管十米到20米这个范围之内的时差范围是是正确的就OK了,就输给算法就行了。
26:29
这是两种方式,一种方式是我嗯不知道B和F的情况下,我让他我推荐去直接去去图像上,图像相对上面去量就好了,然后呢,第二种是我知道B和F,那么我就直接这个通过这个公式去推一下,那就行了。好了,理论我们就介绍到这里,这因为嗯,时间关系哈,我们今这次的重点还是在实战这一方面,所以说我们理论就不说太多了,提到实战呢,大家都都会比较可能都会比较怵一些,相对于理论来说。
27:09
那么实战到底该如何去手呢?如何去开始那个那个那个呢?嗯,首先我觉得第一点哈,我们要用理论夯实基础,我们首先要用理论首我们首先脑海中要对一个理论非常的清晰,我才能去用一个代码去把它实现,这个其实是一个非常正确的顺序,你要是理论都没搞清楚,这个写代码,那你写出来的肯定不是正确的结果,所以说。那么我们怎么去获取这些这些理论呢?就是通过查文献,然后找文档这些这些方式。我这里呢,只是把自己的一些经验分享给大家,比如说这个文献我们该怎么去寻找,怎么去搜索呢?我平时是怎么去搜索文献的。呃,首先我会去,嗯,去我们的图书馆,我们的图书馆里面有各种各样的数据库,我们的那个大学的那个。
28:05
还是非常良心的,他们其实买了特别多别多的数据库放在我们图书馆里面,电电子数据库放在我们的图书馆里面,比如说万方啊,知网呀,维普呀,还有说还有web of science啊这些,你还有那个博士硕士论文库啊,这些在图书馆里面都可以找到,你如果说是在学校的话,你可以直接用你的账号登录图书馆里面去搜索论文,学得非常非常的方便。这是其一,其二我也会用用网上的,我也会在网上去找,就是第一点,第一个是百度百百度学术,百度学术其实也也嗯收集了特别多的论文,有一有很多论文都是可以直接下载的,你直接通过关键词去搜索,然后看一下这个论文的呃影影响影响那个引用次数,因为引用次数多,代表这个论文是经典的概率就大。引用次数,还有他的期刊的那个影响力,当然其实最直观的就是引用的次数,因为期刊的影响力可能你你并不是特别的直感直观,也不是特别的敏感,你不知道哪个期刊到底影响力如何,所以你就看他的影,呃那个呃那个背影量,背影量多了你下来啊,大大概率情况下是没什么问题的。
29:18
还有他他一般都会提供一个免费下载的链接,如果说没有这个链接,那么你再寻找其他的方式,有这个链接你就直接下载就好了,没有这个链接,你再找找其他的那个那个搜索的测那个呃途径。第三就是谷歌,呃,谷歌的话其实获取的难度稍微大一些,因为你不搞这个VPN的话,你是你是用不了谷歌的,如果说你有幸可以有有V编的话,那么你可以直接在谷歌上面去,嗯,这个搜索栏去以关键词去搜索,那么他优先会把这个学,把这个论文呈现给你,你就直接后面也可以看他的背景次数,你就直接点进去看有没有下载链接就好了,一般来说是可以下载到的。
30:01
然后第四个是一个我比较推荐的一个,我经常常用的一个网上的一个神器,搜索神器叫SCIHUB,这个确实是一个神器啊,因为这个这个它是可以可供下载一些,不管是它是开源的,开源就是open access嘛,不管它是OA的还是非OA的,你都可以直接把文献的文章啊,把文献的名字,还有doi这个进去,呃,输进去,然后直接去搜索就好了,它的命中率还是挺高的,就是大部分的文你都可以在里面去找到,可以直接下载这个这个神器确实是非常好用,推荐给大家。嗯。然后就是文档啊,文档其实没有什么固定的去固定的那个搜索方式,就大家就是有缘就可以有缘见到,就是就就把它下下来用吧,我这里推荐一个。一个叫的一个文档,这个文档特别的特别的好,这个文档讲立体匹配特别的好,里面它是从那个立体匹配的原理啊,到最后好多他列了好多种,讲了好多种,从局部全局然后到半全局,这种好多种方法他都,然后他的效果图啊,都在里面有有讲这个文档特别特别好。
31:13
特别好,这个是有微信,我这里有链接哈,我这里链接这个可以点,到时候大家如果说大家那个直播后可以要这个这个PPT的,我这个PPT会开放,可以会公会那个给大家的,所以说你给直接点这个链接就好了。这个链接我这里面有超链接的。呃,第二点,要用一门语言去武装自己,我们在前面我们掌握的理论,那么我们要实现它,必须去必须去掌握一门语言嘛,掌握一门语言的话。我这里呢,就是以自己的经验去告诉大家,我们去去给大家一个参考,就说就说什么语言是比较适合的,我个人觉得哈,我个人觉得在一级匹配这个领域最适合的领呃语言大概就是C和C加加,还有Python,这这这C和C加加我就归为一类成C语言嘛,然后就是Python这两这两个语言应该是用的最多最多的。
32:11
传统的几何算法的话,我是首推C和C加加的,因为你在get上面,无论是在上面,还是在哪个什么渠道去下载的关于立体匹配的算法,可能有90%都是C和C加加的。而C和C加加最大的优点就是它的效率特别快,当然它的是它的难度可能性是最大的,不过呢,这个C和C加加在你的后面的,在你后面的工作当中,它是非常有用的,因为可能很多公司都是会推用C和C加加去实现的,因为他们要注重效率,所以说C和C加加它是效率开发的首选。第二,关于深度学习算法的话,如果说你做研究的话,那么我就推荐你用Python,有一句话说的好像人生苦短,人生苦短我用Python嘛,Python它就是你用起来特别的方便,我在C加加里面100行代码,那么你Python可能十行代码就给我搞定了,这个就是特别适合你们做研究嘛,因为研究了你可能会花大量的时间去在理论上面来,在理论的那个那个研究上面,而在实现方面,你们可能没有那么多时间去实现,所以说用passion可能是比较适合的。
33:22
而在工程实践的时候,当在深度学习这方面的算法方面,工程实践我想应该是拍摄和大家结合吧,到只嗯,因为真正在落地的时候,我们还是要以效率优先,我们还是以效率优先,要去用C加加,还要去做一些优化。我赞我我赞同的一句话是语言它只是工具,但是如果没有这个工具的话,你怎么去建造你自己的大厦呢?除非你有别有其他的工程师可以愿意为你服务,去为你写代码,但是一般情况下,我想大家都没有这个这个这个这个环,这个条件,所以说的话,大家还是要重视一下语言的学习。
34:02
第三点要会用资源,避免重复造轮子,这个其实老生常谈的,大家嗯,对于轮子的话,大家都可能都到轮子,大家都不是特别陌生,我们我们现在现在这个这个信息信息时代啊,其实各种资源都是都是铺天盖地的,怎么去用好这个资源地比较比较关键。我平时呢,就是用用的两个,两个比较多的,一个是嗯,我们有嗯一个是全球最大的开源社区get HUB,这个的话大家确实要要要那个尊重一下,因为这github确实是现在目前为止,我觉得在那个开源上面做的最好的一个社区,你可以在里面找到很多关于关于立体视觉啊,关于呃,稍微重建啊这些的一些一些那个开源的仓库,免费给你下载,给你用,给你参考,给你学习,我觉得这是非常非常好的,非常好的。
35:01
第二个呢,就是全球用户最多的CV库了,就是open CV,这个可能大家都都知道都了解了,因为它太有名了,Open CV,嗯,其实我们那个时候我们我们09年09年10年那个时候,因为OCV的都都没有现在这么多,那个时候嗯,我们用影像库的话,我那个时候用的影像库是一个叫cx image的。不知道大家有没有用,有知不知道这个库现在是一米几这个库,它它我们就用它来读影像啊,然后纯影像啊,所以它有一些哎呀,图像方面的,图像处理方面的一些一些功能,嗯,但是呢,做三维方面基本上是没有的,所以现在有那个open CV,其实有很多三维的3D的一些部分,3D微型的部分,我觉得非常好,大家可以去。嗯,大家可以去,嗯,去研究一下这个open CV,我觉得它是非常好的一个东西。第四,有数据才能干活,当你掌握你掌握了理论,你也掌握了那个语言,你也知道怎么去用轮子,那么剩下的还还剩什么呢?就是数据了,你没有数据你也干不了活呀。
36:13
嗯,数据呢,它就分为两个部分,一个是公开数据集,一个是项目数据,那个公开数据集呢,就适合于那些它其实没有特定的项目的那个同学,因为我们我们现在其实公开数据它也是一个轮吧,一种轮子,一种非常好的一个资源,公开的资源,大家可以下来我这里列举几个比较经典的。一个是这个这个这个数据,这个数据集,这个数据集特别好,这个数据集有现在有有五年的,总共有五套数据集,它是专门针对于内的。从从零一年到现在一四年,零一年,零三年,零五年,零六年,还有一四年这五年分别分别发表发布了一套数据,嗯,它的分辨率是逐年上升的这个分辨率,然后。到现在一四年都是非常高的分辨率的,3000乘以2000多这样子,然后前面前面的都是一些比较低分辨率的,第二个是k Di,这个是一个室外,室外的驾驶的一个室外驾驶的一个一个数据集,他们是把把那个双目摄像头放到那个汽车上面去采集的,然后用那个莱达去采,采集那个针针值。
37:23
这个数据适合于大家做室外的,就可以用这个数据集,再就是floor,这个是一个你合成的数据集,它不是真实世界,它是一个,嗯,实际上它的那个图像都是合成的,也就是不是不是真实世界,是虚拟的世界,而且有很多大量庞大的关于那个训练的数据集,所以说你如果是要研究学基于学习的你比例算法的话,那么你可以看一下这个数据集。再一个是SP,这个可能大家不是特别的那个,嗯,熟悉这个是那个航空航天的,我们搞摄影测量的一个数据集,这个这个我我之前做博士的时候用过这个数据集,这个数据集是特别好,这个是他是拍了一个非常大的非常大的场景,在空中拍了一个非常大的场景,嗯。
38:08
大概有一个有一个1亿像素的几千万像素,这个你可以截取其中一部分,也可以全图去做,立即匹配这个这个数据集。然后如果说项目数据的话,就没什么好说的,项目数据就是你给什么项数项给什么数据,那你就用什么数据嘛,你项目什么特点,那就是不同的项目具有不同的特点的数据。嗯,我们接下来我们作为说一下这个实战的步骤,实战的步骤我我个人的话,总结一下我个人的经验,实战的我个人把实战分为四步。其一是画算法架构图和流程图,我们从那个一张一篇文章里面,把一个算法的架构完全都搞清楚了,那么我们把它画出来,这又是一个那个算法,它复习的过程只要很简单,只要把这个算法那个步骤按照流程图就把它画出来就好了,有的是有的是一步一步来的,有的是多步并行的,那么你只要把它画出来,你画一步画一下的话,你的脑海又又去,呃,对他那个的理解会深刻一些。
39:13
这个架构图的还有一个作用就是为你的带编码是提供一个,嗯,总指导的。第二步去画代码的构架图,呃,架构图,框架图,我的代码的框架图,因为我的代码是用什么语言去写的,那么就它会有不同的框架方式,我这里举一个例子,就是我我们用C语言去写,那么它是一种类的方式去组织的,它一个类,它它有的还有成员函数,有那个成员变量,你就把这个类的架构图去给画出来,我画其实就是两个图而已,你把这两个画出来之后,你后面写代码的话,都根据这个两个图去写,一步一步写就好了,这样就很清晰,逻辑上就很清晰。第三步,我们要去,我们就开始去编写,还有调试我们代码,编写代码的时候,我们就根据我们前面的架构图和这个代码的框架图,一步一步的去,去把我们的代码,把我们的想法去实现就好了,实现就好了,这个实现的时候呢,你就不要嗯,一次把所有东西都实现,然后再去调试,再去看结果,这样去不合理的,你去实现某一个大的步骤,比如说我的我的SGM,它有四步。
40:19
一个是初始代价的计算。一个是代价聚合,一个是视差计算,一个是后处理,那么我不妨实现一步之后,实现一步之后我就调试一下,我这个这一步是不是对的,然后再实现一步之后呢,我再调试一下,这样一步一步来,一步一步一步迭代的来,这样的话,我在我最后写完之后,写完之后再去调试的时候,可能结果就结果出错的几率就会大大减少了,而且即使结果出错了,我已经把前面前面几步都已经调试OK了,那么问题极大可能就是出现在最后一步,那就好定位定位问题,这是一个我的一个经验。就不要大家就是一直埋埋头去去实写代码,一直写完之后再去运行,再去再去看结果,这样是是不合理的,不理智的,嗯。
41:07
第四就是实验呢,这个是一个非常重要的这个部分呢,你代码写完之后,你要跑一下你的那个前面的公开数据集,跑一下结果,看一下结果怎么样,然后把这个结果和这个真值去对比一下,看一个那个看一下符不符合自己的预期。你自己去提提的,提出的一个优化的一个,呃,提出的一个优化的思路,它有没有生效,它有没有生效,它到底能不能达到自己优化的这个预期,这个通过实验来完成,实验是非常关键的,没有实验的话,那你这个算法也写的是,嗯,也不知道你这个算法对不对。还有要实验去验证,这是实战的一个事故。当你把一个算法写完之后。你只是你是把它实现了,但是这个算法能不能能不能实际的用在用在实际的那个生产之中呢,就你在工作之后,你会面临就是一个问题,我在学校里面的开发和在工作上面的开发是不一样的,那我在工作的开发一定要注重这个算法的实际落地表现它的它的一个非常关键的因素,那个点在于它的效率。
42:11
实际的那个实际的那个算法是必须要注重效率的,这个是一个非常非常关键的点,当然效果也是一个非常关键的点,我我这里呢,我就只先以这个效率为为例,去去去讲一下这个实战的升级。一个高效的算法和一个低效的算法,它的它的实用性是完全不一样的,我跑我一个跑100帧的算法和一个跑十帧的算法,你想想它的它所它的应用面和它的实用性是完全不在一个一个level的,不是一个层级的。而提高效率呢,它有四个途径,四个方法,四个方式,一个是多线程的优化,我们知道我们现在现在的CPU都是多核多线程的,一一个CPU它有多个核,那么你只用单个一个核去跑,那么肯定就肯定是没法。
43:00
最大化的去发挥出你这个算你这个硬件的那个实例的,那么我们去把它设计成一个多线程的算法,我比如说我一张图,比如说我我一张图我画成。四块。那么我一块放进一个CPU,那个CCPU1。然后一块放在CPU2,一块放在CPU3,对吧。我这样去跑的话,那我就快了四倍嘛,理论上但实际上可能是快不了四倍的嘛,因为它受限于其他的方,其他的一些一些一些东西,比如说内存的一个竞争啊,这些这些这些方面,所以说。所以说但是理论上它是可以达到三二到四倍的,一个提加速比的,肯定是可以加速的,这是一个大家经常采用的一个方式,就是多线程优化,多样优化呢,其实是这里面最简单的一种方式了,就是大家编码的时候就是比较简单的。
44:00
第二就是SMD指令集,指令集呢是一个可能大家比较陌生的一个,嗯。陌生的概念,纯洁是一个比较陌生的概念。我们在我们电脑中有一个寄存器,有一个有一个一定大小的寄存器,比如说128位的寄存器,那么它它有一个非常好的特性是什么呢?它可以嗯同时载入,嗯载入128位的数据,比如说你有你的图像一个像素是占八位,是一个字节嘛,一般来说我们用灰度零到255去代表一个像素,它是一个字节,它代表它是八位一个字节。那么我同一百28位的寄存器,我可以同时读多少个像素?可以算一下,128除以八等于十,16是吧?可以同时把16个像素去呃读到一个寄存器里面去,这个读这个读取操作是一是一次完成的,是一次完成的,然后读取之后,它可以同时去执行一个指令,比如说我让他同时加一个数,那么我就可以同时对这个呃16个像素同时加一个数。
45:14
就一个使用周期,我就可以做16次运算,如果说我不用这个指令集,我肯定是一个像素一个像素的加满。或者说我用多线程,我放到呃,16个CPU里面去,16个线程里面去,嗯,一个一个的加也可以,但是我的令集呢,我我的指令集是在现成的基础上,我我另外又可以搞一种方式,就是又可以用这个指令集,我这两个是可以相加的。我这两个家长会两个都一起用的,这样就进一步的加快了这个速度,这个指令级的用处就是这样。然后。再再一步就是再第三个就是GPU优化,GPU优化因为我们GPU设计的时候是跟CPU的逻辑是不一样的,CPU设计的时候是重逻辑,重逻辑控制,那么它实际上它核心数是有限的,我只能设计六个核,十个核,顶多20个核,或者说但是嫌随着核心数的增加,我的成本大大增加嘛,但我的GPU不一样,我不用那么注重去那个逻辑控制,我直接就搞一个呃搞一个呃几千个,像线成的那个几千个,几千个核心的GP,那么就这跟多一样的多一样思,我搞个几千个核心的话,那我把几千个都放进去一起跑,那就快了,呃几十倍都有,都都是非常非常常见的。
46:35
嗯,第四个就是FPGA优化FGA其实和GPU是类似的道理,FP里面也是,FPGA里面也可以,也是非常多的核心可以一起跑。我放我这里放一个视频,我这个视频是我从YouTube下的,YouTube下它是作者呢,是用一个fpg实现了一个SGM算法,可以看一下它的表现,你看一下他拿着这个相机在野外去去表去去测试它的性能。
47:15
The next video um this is actually the same sequence and just visualize differently now as a three d point cloud so and every pixel from the de map of the video before is now here projected as a d point and we can again see how dense these d measurements are。So there'is another example from automotive use case and here again we can see how dense these measurements are and we can see both of the road very close to the vehicle as well as the road very of a far ahead,可以看到它这个效率还是非常,Here on the left hand side there's a bicyccl coming in and this yeah would be a typical application that you would want to detect hear the bicycclist driver with a three d camera sensor so that the vehicle can react accordingly。
48:03
然后words,那他他自己也说了,他这个是用一个FPARA的一个优化的SM算法做的f spga,它的优势呢,就是它是可以做嵌入式的,就嵌入式你可以用嵌入式版的话,嵌入式版去你可以做这个FP优化,不用占用那个PC端的资源,Image each other and这个这个链接我也放在这里,大家可以去直接用这个链接去点这个链,用这个链点这个链接去那个看我这个我这个PPT啊,它我这个其实视频我也下下来了,我签在你这个视频PPT里面了,如果说大家到时候获得这个CP之后,我这个视频可能就直接在你就不用去下了。呃,这个也又是一个,那个又是一个G于GPU的,这个是一个GPGPU的结构光的单帧结构光的一个STEM and today I going to talk about just so that estimation and be study our community at least for thirty years and many of you would tell me that it'is a solve problem however if you want to sensor cap running a high frame rate and To Be a very accurate and maybe running on a mobile platform we realize where we are far to,他这个这个算法它是一个散班结光的,他那个投了,他是主动是他往这个他物理上投影的一个一帧散白的结光,然后用双目系统去去做匹配,它的思路实际上是做一个是基于那个pass ma去做的,做了一个优化了一个化论文里面可以达到500。
49:51
S whichs multiple shots in order to produce a single data map and again it suffers from motion artifacts。
50:06
Here demonstrate。对,然后呢,其实我自己呢,也也实现过一个基于GPU的一个STM算法,我在这个哔哩哔哩上面也也开放过一个,可以给大家看一下。嗯,我这个是在那个GTX107上跑的。就是一个基于那个库达,库达写的库大写的一个CGPU,它总共是它帧率是130帧,视差范围是零到128。效果上面我倒是没有去怎么去做优化,只是在效率上面去去做了一个优化。啊,我是基于下面这篇文章去实现的,这个这个文章我在这里大家可以切下来去看一下,这个文章还是写的非常好的,我这篇文章我仔细阅读过,这里面有些步骤都都是非常合理的。
51:09
那我自己也会做,也做了一些优化,不只是完全是按照这个文章写的。嗯,我们在装匹配的时候会遇到一些一些问题,一些固有的问题,也就是说在立体匹配嗯过程当中,我们会这些问题都是都是每个算法都会遇到的,都会存在的。首先呢,第一个是亮度不一致,从这个图上可以看到两边的图像,它的明暗是不一致的,一边左边的比较亮,左边的比较亮,右边的比较暗一些。第二个是表面过曝,表面过爆。嗯,可以看到这个红圈绿圈里面,一个是这边过报,一个是那边过报,但他信息完全丢失了,这样就很难去匹配了。这个是角度,一个角,第三个是角度变化,角度变化可以看到这个左视图这个角度哈,右视图这个角度完全它是不一样的嘛,是吧,这个角度变化实际上很常见,现在很多算法处理表角度变化应该来说都算都还是可以的。
52:09
第四个是若纹理和甚至无纹理,你看这个白色的区域,这个基本上嗯,都没有什么纹理,它就就懵了,就不知道到底哪一个是他的同名点啊,你懵我也懵了。然后是透明,透明呢存在两个问题,一个是那个纹理是没有,是比较少的这个纹理哈,纹理是比较少,第二个是它这个折射,光的折射,你不同的角角度看过去,光的折射它不一样,所以说同名点它表现的并不一样,这样它这个是困难的地方。第六个是遮挡,遮挡的话就更加的难以难以处理了,遮挡这些这个。我都看不到,你还让我去去搜索同名点,这简直是一个非常嗯蛋疼的事情,我你看我这个左视图这个这个位置哈,左视图是可以看到右图你给我遮住了,你连你的你连那个相机都没拍到,你还要我去找他的同名点,这个是很难的。
53:08
然后呢,我们做例题匹配方法都会,呃,一般的例题匹方法他都会那个啥,提出一些经典的假设,就是今年假设是是嗯,他们形成自己的论文的一个非常的一个基础。我这里列举几条,一个是窗口内的相像素的视差相同,这个假设可能所有的所有基本上90%的一比算法,他都会用这个假设,基于只要是基于窗口的哈,它都会用于这个,用这个假设就是窗口里的时差像素时差是相同的,嗯,可以看到左边这个右右图这个它的时差是就是相同的,但是呢,这个假设往往它是它是会失效的,一般情况下这个假设都会失效。我们从前面的那个公式啊,深度公式,比如说D等于深度公式BF除以除以时差嘛,你看势差相同的话,如果这个D相同,那么它的深度肯定是相同的,这就是理解,你你理解一下就是。
54:08
窗口内的视差相同,那么这个这个窗口内的所有表面点到你相机的距离都是一模一样的,你可以想象这种情况实际上比较难嘛。你看下面这种情况,这个窗口内的点,肯定你相机又不是同一个距离嘛。所以说这种这个假设往啊经常会失效,但是呢,它不影响这个假设为他们,为他们那个算法提供一个非常好的切入点,他们就以这个这个假设为切入点,去设计我的基于窗口的一个算法,我可以通过这个假设去计算初始代价嘛,后面我虽然我还会,我因为我后面还会经过很多的代价聚合呀,还有一些嗯,全局的那个全局的一个那个聚合方式啊,去把这个结果再优化一下,嗯,得到最终的时差。所以它这个实际上是提供一个很好的切入点的。
55:02
第二个呢,是像素P的视差,只和其领域的像素有关,这个实际是来自于一个马尔科夫的性质,马尔科夫随机场大家可能,嗯,有的可能听过,有的可能没听过,马科夫随机场它描述一种什么样性质呢?就是一个顶点,它的它的它在状态,在某一个状态的概率呢,它只和它周围的顶点的,只和它都周围的顶点的状态有关。就是在图中这个黑点,这个黑点的是在某一个状态的概率,只和这四个灰点有关,和其他点都没有任何关系。这样在像素上面反映到像素上面就是这样一个关系,就是像素P的时差只和它邻居像素像素有关,那么它是这个就给大家做聚合的时候提供一个假设了,提供一个很好的切入点啊,做聚合的时候,我只用管我淋浴的像素怎么给我做贡献就好了,我不用管我淋浴之外的像素怎么给我做贡献,嗯,我我在中间的像素,我不用管脚上那个像素给我怎么怎么给我贡献,我只用管我旁边的这个像素,我上面这个像素和我下面这个像素,还有我右边这个像素怎么给我共中间就好了,这样就其实就简化了这个这个这个聚合的问聚合的问题,简化了这个问题。
56:18
或只用管周围的像素就好了,周围的像素状态就好了,就像那个我们说嗯,SGM,它是一种聚合嘛,它是一种那个动态规划嘛,他要前面一个像素的像素视差值的那个代价去聚合到这个像素上来嘛,我只管前面这个像素嘛,我不用管前面的前面的前面。实际上这个这个性质,这个假设第三个呢,就是相近的颜色像素具有相近的时差,这个呢,就是其实是其实是为那些经常这个假设会被用来做那些弱纹理的优化,嗯,弱纹理的,因为因为弱纹理经常会出现这种情况。
57:00
就是我这个一个一块区域,我可能只有零散的几个点,比如说这几个点,这个点这个点零散的几个点,我计算出了正确的时差,其他的全部都错了,全部都错了,那么我怎么去算出,最后怎么去优,通过优化来得到这整个整一块的时差值呢?那我就通过这几个零散的点去拟合一个平面,拟合一个平面,然后这个平拟合的平面,再通过这个像素值去算拟合的平像数值,去算每一个点的时差,就把这个填满,就是我整一块用一个平面,用一个时差平面。因为我基于这个假设嘛,相近的原则相就具有具有相近的时差嘛,就基于这个假设。这是第三个假设,第四个假设就是像素的非连续边界具有色差或者亮度差。嗯,这个假设实际上往往是是成立的,往往是会成立的,因为嗯四杀非连续,那四杀非连续的区域一般是背景和前景的交界区,背景和连前前景的交界区呢,景因为离相机和前景离相机的距离是不一样的,距离不一样,那么光光源打过去,反射过来的强度是不一样的,这个强度不一样直接就反映到图像上,就是它的设值不一样,颜色的话就是它的呃颜色的那个。
58:21
颜色的那个明亮度不一样,然后亮度的话也是亮度的那个呃值不一样,一个是比较暗,一个是比较亮,还有一种情况是呃,背后这个背景就跟前景完全是不一样的东西,这个它的颜色也可也其他可能是不一样的,这个这个假设也是经常成立的,但是也会有失效。比如说我前背景就是都是都是一个白色的,白色的东西,前背景是一道墙,前面是一个白色的盒子,那么两个就相近了嘛,这个就处就好处理了嘛。嗯,所所以说这四个假设呢。其实。都是弱假设,都不是完全严密的假设,但是这四个假设都为现在的算法提供了一个非常好的切入点,虽然它不严密,但是我可以处理很多,绝大部分情况嘛,因为现在没有人能够提出一种算法能够解决所有问题,所以说我的问,我的算法能够解决一部分问题就OK了,可以了。
59:15
我不用提出一种大而全的把所有的问题的所有的场景都解决掉的一个算法。这个难度是特别大的,所以说现在的都是现在的算法,算法都是以这样的一个思路去去做,就是我能够提升某一个场景下的那个表现,那么我这个算法就算合格了,就可以达到我的预期了。嗯,不同的匹配算法,它的效果差别是特别大的,我们可以看到这个右边这个图,上面是传统的一个一个算法,下面呢是2011年的时候的一个so sota的算法就是最好的效果的一个算法,可以看它们两个是差别特别大的。我们一般立体算法一地平算法的话,我们会把它分为四,分为啊四种,四种如果是传统的几何算法的话,那就是三种局部,局部算法,全局算法,半全局算法,还有如果说到现在的话,因为深度学习非常流行的嘛,那么我们把深度学习加进来,那就是四种算法加上一种基于学习的方法。
60:21
立体匹配呢,它它的步骤分为有四步,第一步是代价计算。代价计算呢,它实际上是是衡量也两个同名点它的不相关性,不相关性那代价嗯,两个同名点的两个两个像素点呢,它越不相关,那么它的代价就越大。它越相关,它代价就越小,我们代价计算的目的就是要找到最小的那个代价所对应的同名点,对。嗯,代价计算一般都会提出一些跟亮度,亮度的那个相亮度的那个相互的比较所相关的一些一些一些函数,比如说这个ad哈,这个ad,我们来举一个例子,这个ad。
61:14
Ad是什么呢?Ad是。IB减去I'这个B就是左视图的亮度值,就是I'就是右视图的亮度值,它就是表达的是左视图一个像素和右视图一个像素,它的它的亮度差,这个其实非常简单的嘛,这个就是非常简单的一个公式嘛,就亮度差嘛,它就是假设,他提出了一个它的基于的一个假设,就是我的同名点,如果说我是同名点的话,那么我的亮度差应该是很小的,应该是很小的。嗯,这个假设当然是一个非常非常弱的假设,但是他因为代价计算,因为我们知道他有四部嘛,代价计算只是为了计算一个初始代价的,我不需要它很准,我现在只需要它能反映一定的,反映一定的相相关性就好了。
62:07
嗯,说到代价计算,我们要提到一个东西叫做DSI叫就是视差空间影像,在右边这个视差空间影像它是一个三维的数组,它保存了嗯,像素点,每一个像素点在后选视差下的每一个,每一个视差的那个代价。就是所以说它是一个三维的嘛,叫矮叫它的它的空间,它的尺寸。它的尺寸是。W乘以H乘以D。W是宽,H是高,D是那个时差的范围,我们是是那个算法输入嘛,比如说我输入零到64,那么W,那么D就是64时差的范围,它是这么大一个一个空间,它里面的元素,每一个元素就是CXYD,它代表的是像素XY,当时差为D的时候的代价值。
63:03
其实就是你可以想象我CXYD,用这个公式怎么去算CXYD呢?它就是CXYD等于。等于,嗯。等于他,等于爱。XY。减去二。X减DY是吧。因为我通过XY和D就可以算出在右视图上面的坐标嘛,因为这个XY是左视图上的坐标嘛,这个X减D是右视图上的坐标,我直接就这个这个这个I减去这个I,就可以得到这个这个这个这个ad代价了这个C。Ad。等于这个啊,非常简单,这个大家计算,这是其中一种呢,就大家这个其他种方法也是类似的,只是公式不一样,只是后面这个公式不一样,其实你知道这个公式之后,你就直接把这个公式代进去算一下就好了,大致原理都是这样,都是这样,嗯。
64:13
匹配我们知道啊,匹配代价它是衡量两个像素的不相关性,那两个像素越相关呢,它的匹配代价就越小,所以说我们就最小的匹配代价对应的时差值就是最优的时差值,我们在经过代价计算之后,我们就其实就能够去定位最小代价值了。能够去进入最小时代,有人就问,那我直接结束就好了嘛?但这样是是不行的,我直接结束就会,这是一个什么样的结果呢?就是这个结果,这个结果。就这个结果就麻麻点点的,这就只能看到一个大概,就是很多值就是错的,就因为你这个代价计算啊,这个太简单了,就是比如说这个ad,这个代价计算多简单了,就只是两个像素的亮度值之差,我的同名点,我的同名点很可能就不满足这个条件,有可能就一个错误的同名点满足这个条件了。
65:06
所以说嗯,初始代价出来的结果就是这样的,就是比较比较烂的,那么我们后面还要做什么,就是代价聚合,代价聚合它是要干什么事情呢?代价聚合它是要去在一个他是要去嗯把领域像素的代价。把邻域像素的代价,嗯。做一个考考虑,做一个考虑,然后比如说我给你画一个啊,画一个我我中间一个像素,我淋域,淋域有有八个像素,那八个像素有C1 C2 C3CCCC,每一个像素有一个代价值叫C嘛,那么我需要做的聚合,就要做的是把它所有的大价值都有一种方式聚合到中间去。就是给中间做一个贡献,最后计算出中间的像素的那个聚合的价值。所以他现在就是不单单考虑我单个像素的那个亮度差,我还要考虑周围的像素亮度差,我要去把这个嗯,代价,代价变得更加的鲁放,我把这个代价更加变得更加的准确。
66:10
我通过大家大家聚合方式,我大家聚合有很多种方方法,比如说box,比如说multiple Windows,比如双边滤波,比如说自信全值,还有十字交叉域,还有扫描线方法,这些方法都是为了做代价聚合,只不过他们聚合的方式不一样,但是他们都是按这种方,按这种方式来做的,都是按这种方式来做的,可能这个窗口也不是一个正方形的,可能这个窗口是一个是一个非非矩形的。都是有可能,但是他的他们所给予的一个思路都是一致的。具体什么方法,采用的是什么方式,大家就得去看一下这个论文了,得去看一下这个论文到底他们是什么方式了。然后时差估计呢,就是我的代价聚合之后,这个时候呢,我的代价,我的最小匹配代价就就很就极大的就。
67:02
嗯嗯,就更能反映那个我真实的相关性了,就是说我现在用最小匹配代价对应的视差值,把它当做最优视差,这个时候的准确性就会大大提高,那么我最后再做一步,再做的一步就是时差估计,我就要把最小匹配代价值给计算出来,就比如说我的第一个算的是赢家通吃,赢价通知是什么呢?就是我统计一个最小匹配单价值,然后把这个最小匹配代价值所对应的那个时差值给当做增值输出来就行了,这个就就这么简单。聚合之后就是这样的结果,就是中间这个结果,这个结果还是。这个结果就比第一个结果好多了嘛,就这个基本上就是已经接近我的预期了,就是接近接近最后最最最后最终的结果了。我这里还写了其他的BP啊,GC呀,DP呀,那个什么Co啊,其实这个。它不一样的地方在于。
68:00
这些都是全局的方法,全局的方法,全局的方法是没有第二步的,全局的方法是没有第二步的,有了第二步之后才有这个聚合代价吗?有了聚合代价,实际上我直接通过赢家通吃就可以把那个真实施加值给定价定位出来了,我不用通过这个BP啊,GC啊,DP和GC都是一个图优化算法,比如说自信度传播,还有图哥,它都是图优化算法,是比较复杂的,这个图优化算法是直接直接直接做了第一步之后就跳到这一步。所以说我们说全局算法它只有三步,大家计算差估计,还有时差优化。这就是为什么我们说全局算法只有三步,因为全局算法没有这个聚合这一步,我直接把大家计算的结果直接做一个全全图的图优化。全球优化是比较慢的,比较慢的,然后呢,最后一步视差优化,视差优化就是前面三步都做完了哈,不管是全局还是半全局,他们全局就把前面两步做完了,半全局就把前面三步都做完了,然后前面三步都做完之后,再做一个时差优化,你可以看到我这个中间这个结果是没有优化的,看到左边这部分还有什么麻麻点点嘛,然后这个嗯,这个这个这个中间也是有一些。
69:17
啊,发散的不是特别边界不是特别清晰的,结果这个这个。特别是遮挡区,遮挡区也有一些像素,其实这些像素是错的,这些遮挡区根本都没看到这个点,怎么它还出来一个值呢?这个值肯定是不可靠的。那么。我就做一步时差优化,时差优化,时差优化的话就有很多种很多种那个步骤了,像这个第一步子像素计算,那么我前面算出来都是整整像素时差,我最后实际我要想很高的精度的话,我必须得用子像素,子像素时差,因为子像素时差是高精度的,嗯是高精度的那个,嗯基本保障,我如果是整项说是谈不上精度了,不要不要谈精度。
70:02
子像素才能才才才才有弹精度的资格,子像素优化就是像SGM的话,就做一个那个二次拟合嘛,其实不同算法是不一样的。第二,左右一次性检查,左右一次性检查呢,它实际上是右他左,它实际上是是这样操作的,是左视图它匹配一个视差图之后,右视图它也匹配一个视差图,这两个视差图它它一一对应的时候,嗯,比如说我左视图的像素P,它找到了右视图的像素Q为同名点,那么我在右视图上面的时候,Q能不能找到P为同名点呢?如果说Q没有也找到了P为同名点,那么你们两个就对上了,那就OK,我就通过了,但是如果说P我找到了另外一个P为同名点,都就是两个找到同名点队都不一致,那么你你就通过不了我的一次性检查,你就把被我pass掉了,我就被我无效掉了。所以这就是一次性检查,一次性检查可以去除特别多的那个那个错误点,错误点。
71:05
一般来说,一次性检查都在实际应用中是必须要做的一个步骤,因为你不做一次性检查的话,你的结果是其实上是是很难是很难看的,嗯,再就是小小联通欲去除小灵通与剔除呢,它是基于一个一个一个假设是那种,嗯,是那种。嗯。也就是说在在图像上一种一直一些散落的一些一些小小白块,小白块散落的一些小白块,像这个这个这个白块散落的一些小白块,这些小白块很有可能它是错误的时差值,像这个小白块错误的时差值,那么我把它给你跟踪出来,用区域跟踪嘛,我把一把把图像中的那个嗯联通的一块去跟踪出来,然后计算这个联通区的一个大小,大小很小的,大小很小的,我就把它剔除掉,这个小联小联通去除。第四是视差填充,视差填充是前面的步骤,做了之后左右一次性检查和联动浴去除之后。
72:06
你就会产生很多无效的区域,产生无效的区域呢,你用你要不就你要不就不管它,你要不就不管它,把它就直接拿去用,能保证我用的都是可靠的,我用的都是对的,但是呢,有有一种情,有的时候别人又要求你,你的视差图必须要得完整,你的摄像图必得完整,那么你就得做一个把那个无像素给无限,那个无效的像素给填上。填上让让那个视差图成为一个就没有洞的一个视差图,就没有那个那个那个黑洞的一个视差图,所有的所有的点都有视差值,呃填充呢,填充方法各的各个的那个论文里面都不一样,有的呢采用是嗯把把它周围的八个有效像素去去取一个中值,有的呢去把就是把在左右分别搜索一个有效像素,然后取它的最小值,这个这个是两种方式,就很多种方式,反正你看不同的论文,它有不同的方式,这个这个部分其实视差优化部分都是就相较前面的步骤都是最好理解的一个步骤,我想大家看一下论文就明白它到底是怎么怎么一回事。
73:11
然后弱纹理优化呢,若纹理优化就是那些前面说的那个一大片纹理,它它都没有出来正确的值,这个其实如果说你拿一个弱纹理的数据,你可很有可能会遇到这种情况,就是一大片他们都是空白,就是没有没有值,或者只是错的,只是错的,那么我怎么去优化它,让这个整一块都会能达到正确的市场值呢?这个也有很多方法去研究,我说我这里说一种方法,就是SGM的那种方法,就是在这一块里面去找,去找那个因因为它,因为它一一整块一整块都完全一整块全部错了的那个还是比较少的,一般来说,呃,一块里面还有还是有零散的一些正确的值的,我用这个正确的值再去拟合一个平面,去拟合一个平面,然后把这个用这个平面去算出这一整块的一个所有像素的时差值,这样就是就通过里面的少数正确的时差值去去去传播到整个整一块这样一种方式。
74:12
那还有其他很多的方式,我也我也没有,嗯,做非常多的研究在这一块。最后呢,就做一个平滑滤波,因为平滑滤波就是出了去噪声的嘛,你出来的结果可能就会有一些异常的噪声,比如说飘在空中的一个一个孤立点啊,这种可以通过平滑滤波去给它给滤掉,平滑滤波呢,平滑滤波的话有三种,一种是中值滤波,中值滤波大家都比较了解了,中值滤波嗯,在一个窗口内的所有的那个时杀值取一个终止。这是中止滤波,第二个是加权的中植滤波,这个是那个派星曼里面用的一种方式,加权的中植滤波。加权中值滤波是给窗口内每一个值都一个全值,然后再按照这个全值去排个序,然后再再那个再加,再把这个全那个排序后的全值进行累加值一一直到加到那个累加的值等于总全值的一半的时候,那个时差值值等于它的最终时差值,这个是加权中止滤波,会稍微麻烦一些。
75:17
第三个是那个嗯,双边滤波,双面滤波它因为我们前面的中值滤波,它只考虑了一个空间域的一个关系,双子滤波上那个双边滤波,它还考虑了一个颜色域的关系,它会把中呃空间关空间关系和颜与空呃空间关系和那个颜色关系都会去考虑进来,算一个全职,然后去嗯。去做一个滤波,大家可以看一下,查找相关的一个资料啊,去去了解一下,当然可能还有其他的滤波,这三种滤波是我看到最常见的。那这个这个就是我最终的最终的那个做了视差优化的一个结果,我们我也做了视差填充啊,也也做了那个子像素计算,也做了那个左右一次性检查,也做了小联通预的剔除,还有时差填充啊,没有做若理优化,还做了平滑滤波,这五步我除了若理优化没有做,其他四部都做了啊,这六步我除了论文你优化没有做,其他五部我都做了,得到右边这个结果,这个结果啊,看上去还不错,当然还有一些细节的地方没有处理,处理的不是太好,最后可以再再想,再想一想如何去优化这个这个视察图。
76:34
那么立体匹配方法的话,嗯,大家可能就是拿到去拿到一个课题之后,我不知道怎么去怎么,不知道怎么去开始,不知道怎一开始老师让我做立体匹配研究,但是我不知道怎么去开始,我这里的建议的话,就是从经典文章去入局,经典文章去入局。因为这些经典文章,因为后面可能有成百上千篇文章,都是基于这个经典文章去去做的优化,所以说你搞清楚这个经典文章之后,那么你看其他论文可能就突然间茅塞顿开,你就看上去就没有什么难度了,所以这个是我推荐的一个就从经典文章录取,我这里就举四个经典的文章,第一个是group match,这个STM,这个STM可能是我见过的最经典,应用最广泛的算法了。
77:21
我自己做,我自己做那个,我自己现在做工业上的一个一个算法的研发,也SM也是一个我非常呃经常会考虑的考量的一个算法,这个算法它的它的数据适应性啊,还有它的效率啊,都是都是非常好的,都是非常好的,它可以它的可变性度非常高,它可以用GPU,还有还有多线程,还有SMD,还有GPU,还有FPGA都可以在这个算法上面去优化,所以它,嗯很多商业软件也都会用它,比如说我们摄影测量里面的一个photo sc,还有那个。那个什么3D。
78:02
打什么3D我不知道啊,就是photo sc,还有那个开一个非常开源的叫欧MVS都会用这个,呃,米去做,嗯。第二个是AC,是AC实际上是后面我我我我们嗯。中国的一个学者提出来的一个算法,它的效果是是比较好的,应该是比S加要更好的,而且它的速度也很快,他当时提出的时候就是就是拿来做那个GPU优化的速度是是可以保证的,现在的英特尔那个四也是采用了这这个这个。这个方法。我是从那个英特的那个,呃,这篇文章来。啊,英特尔这个这个有一篇有有一个文档,有一个文档,他说的他他用的这个ADS也是一个升级版嘛,它有个第四第二第二版还有个第400,第200就是用了一个比较简单的系数匹配,第四版就是用的一个ADC,说明ADC还是还是蛮可靠的,得到他们认可的一个算法,嗯,我我也读读过他那个文献,还是说的那个文献的理论还是非常嗯,非常合理的。第三个是match起,这个拍match起呢,就是它是倾倾斜窗口模型的一个一个经典经典之作派清麦起他所提出来这个理论啊,就是倾斜窗口模型啊,它是嗯。
79:28
非常值得学习的。我们知道,而且很多算法它是它是一种叫嗯,Front叫fpw front这个这个平行我都不知道怎么读了,读了就是前端平行窗口,前端平行窗口它讲的是什么呢?就这个窗口,它是和你的那个那个和你的那个光轴是垂直的。和你的光头是和垂直的,和你的那个什么,嗯,橡平面是是平行的,和橡皮面是平行的,这个窗口,这样的窗口就是它它一个好处是这个窗口类的,它想这个窗口类的一个一个这个窗口类的视差值它是相同的,这是前端平行窗口的一个一个优势,嗯,所以可比较那个基于窗口式的一些一些算法就都用这个FPW,就是前端平行窗口去做,像SGM啊都是基于这个窗口去做的,但是他带了一个问题,就是如果说我这个这个表面是跟这个相机是倾斜的表这个。
80:33
嗯,这个啥,这个这个表面的那个,呃,这空间的这个表面和我这个橡皮面,它的夹角特别的大,甚至是垂直的,这种情况下,我这个FPW这个窗口模式就不适用了,出来的点可能就很稀疏,或者干脆就不出点,然后这个拍它用一个倾斜的窗口,你空间中的是它的法线是怎样的,那我的窗口我的法线就就是就是怎样的,这样就就非常好的那个契合这个空间的那个表现那个那个呈现嘛。
81:03
你空间的是斜的,那我的窗口就是斜的,这样就更合理一些,所以拍行卖卖,拍行卖起的效果也是特别好,最后证明他这个理论还是比还是合理的,当然它的问题是它的算法效率太慢了,我也我写了一个我开源的,我开源的那个S和嘛,就发现写的算法的效率大概是SM的那个啥,嗯,100倍是有了吧,所以说后面后面人们去用那个呢,都会用一个用一个把这个拍慢给退化成这个FFPW去用,然后去用,然后GPU去优化,退化成这个FW去用。像那个前面我说的那个,它就是用这个派,然后把它,然后把它退化了用用那个FPW去用,嗯嗯,最后效果也蛮好,这个拍它像那个啥,Open m Vs最开,嗯他他提供open m m Vs,它的匹配部分是提供两个接口的嘛,其实最早的就是用派慢写,嗯,SM只是一个,嗯,最近几年才才加进去的,他用用的最早,用的最早,也是用的最多的就是这个派奇曼奇也。
82:15
他进进一步是说明这个帕西曼实际上是可靠的,他的点名非成靠非成靠,所以他们才才会用这个算法。你你要去用的话,你可能会做一些优化,也有很多学者去针对他去做优化,你你可以参考一下他们的那个优化的思路,嗯,第四个呢,就是MCNMCCN呢,其实基于学习的一个生是开山之作,这个算法提出来是非常有名的MCCNN,它其实还是没有脱离那个那个传统的匹配的框架,它是基于SGM的那个框架去做的,只是把SGM的那个计算初始的家那个部分去替换成,替换成的M那个CNN的一种方法去做。但效果也是特别好,效果嗯比SM要好很多很多,所以说嗯,MCCN也是一个非常非常经典的,大家去也可可以去研究一下的算法,当然现在很多的深度学习都是端对端的,就是不拘泥于这种传统的一个架一个一个架构去做的,就直接是从嗯从点,从那个是像素值,直接就直接就到那个视差值,中间就没有什么,嗯前面所说的代价计算呀,加聚合呀,还有说视差计算呀,视差优化呀,这些这些操作,那就是端对端的,这个就就另外一种了。
83:34
我研究也我我研究的也不是特别多。嗯。好了,今天的今天的就到这里吧,我这个也讲的挺多的,嗯,我没有没有讲特别的那个比较难理解的一些东西,比如说算法的细节方面的东西啊,因为给人讲的话,可能今天就讲的特别时间特别长了,嗯。所以今天这个这个论文的话,我的我的初衷的话,我的目的的话,主要是嗯,给大家一个开始的交流,然后做一个抛砖引玉,希望后面能够有更多的嗯,更多的同僚去分享更多的经验和和那个和知识,所以我今天的嗯目标并不是特别的目。
84:21
目标并不是特别的那个那个啥。反正就是,呃,质量可能不是不是特别的高,我觉得。好,今天就今天就到这里吧。
我来说两句