2014年4月30日星期三
艳阳高照大晴天
今天一扫昨日的阴霾又是一个大晴天,心情稍好,动力充沛,希望效率也能有较大提升,今早六七点的时候感到右腹胀痛,应该是肝脾的位置,跟一月份那次隐痛位置差不多,医疗卡既然已经下来,我看下周还是去校医院看一下放心点,虽然我不认为有什么问题,有鉴于这五个月以来健康的生活方式以及干净的空气,我觉得多半是睡软床睡得。
Melancholy Invasion
气温日降,屋外的一切都提醒着南半球的冬天正悄然来临,穿短袖骑车上下班已经变得越来越不现实了,冬天带来的变化不仅仅是气候上的,更有人心情上的微妙变化,看着草木渐枯黄,感受着阴冷空气,还有每个人脸上都透着的冷漠,我眼中的整个城市都显得颓唐凋败,再想想自己的研究任务和目标,还有不断临近的归期,心里不禁泛起丝丝的忧愁,我期待着突破和压力释放的那一天,希望它就在不远。
2014年4月28日星期一
MPGC 1991 阅读摘录
ABSTRACT
1. For greater flexibility the geometric constraints are treated as weighted observation equations and not as strict conditions.
2. It is proposed to use a Wallis filter for a radiometric equalisation of the image before matching.
3. The Wallis filter has also been used to enhance contrast, high contrast being necessary for accurate matching.
4. A method to derive reasonable approximations by an image pyramid based (coarse-to-fine) approach is presented.
5. The pyramid approach increases the convergence radius (in practical tests parallaxes up to 70 pixels have been handled), convergence rate and computational speed, and can be exploited for a better quality control and self-adaptivity of the algorithm.
6. Without the image pyramid, convergence has been achieved, in some cases, for errors in the approximate values of up to 10-20 pixels, but optimally these approximate values should be 1 pixel accurate.
7. MPGC is a combination of area-based and feature-based, especially edge-based, matching.
8. The theoretical precision of the shifts, in the case of good targets, typically is 0.01-0.05 pixels. The achieved accuracy was for good planar targets 0.2-1 um, for signalised or good natural points 2-3 um, and for natural points on general points on general surfaces 10-15 um, whereby the pixel spacing was typically 10 um. In the performed tests, the matching accuracy was generally similar to the accuracy of manual measurements; in certain cases the matching accuracy was even higher than the manual one. The percentage of blunders automatically detected by MPGC varied from 5%-25% of the total number of points, depending on the image content and object surface. The percentage of undetected blunders was 1%-3% of the points accepted by MPGC as being correct, thus comparable to the error rate of a human operator.
1. For greater flexibility the geometric constraints are treated as weighted observation equations and not as strict conditions.
2. It is proposed to use a Wallis filter for a radiometric equalisation of the image before matching.
3. The Wallis filter has also been used to enhance contrast, high contrast being necessary for accurate matching.
4. A method to derive reasonable approximations by an image pyramid based (coarse-to-fine) approach is presented.
5. The pyramid approach increases the convergence radius (in practical tests parallaxes up to 70 pixels have been handled), convergence rate and computational speed, and can be exploited for a better quality control and self-adaptivity of the algorithm.
6. Without the image pyramid, convergence has been achieved, in some cases, for errors in the approximate values of up to 10-20 pixels, but optimally these approximate values should be 1 pixel accurate.
7. MPGC is a combination of area-based and feature-based, especially edge-based, matching.
8. The theoretical precision of the shifts, in the case of good targets, typically is 0.01-0.05 pixels. The achieved accuracy was for good planar targets 0.2-1 um, for signalised or good natural points 2-3 um, and for natural points on general points on general surfaces 10-15 um, whereby the pixel spacing was typically 10 um. In the performed tests, the matching accuracy was generally similar to the accuracy of manual measurements; in certain cases the matching accuracy was even higher than the manual one. The percentage of blunders automatically detected by MPGC varied from 5%-25% of the total number of points, depending on the image content and object surface. The percentage of undetected blunders was 1%-3% of the points accepted by MPGC as being correct, thus comparable to the error rate of a human operator.
一类室友
有一类室友,他们以弱势群体自居,没有公德心,不注意公共区域的卫生和公共资源的共享,洗澡往往能洗近一个小时从不管别人是否需要使用厕所,冰箱有空就可以往里塞,尽可能多的买东西储备,我不清楚另外几个室友的情况,反正大小两个冰箱我顶多能用上小冰箱的一小层,厨房用完很少精心收拾,水渍油渍以及菜渣满桌满台,只管往水槽里倒东西,水槽的过滤器却从不知清洗,卡在其中的面条,菜叶,肉丝坐等其他人来处理,也从未见其主动为厨房的大垃圾桶更换过垃圾袋,排好的轮值表对其形同虚设。
我真是受够了。
我真是受够了。
2014年4月25日星期五
ANZAC Day
4月25是澳新军团日(Australian and New Zealand Army Corps),city 里涌现出很多身着军装的大兵和军官,当然还有不少头发花白的估计是参加过越战甚至是二战的老兵,穿着正装,胸前佩着一排排勋章,依然神采奕奕,让人不由心生敬佩。
行至猫本的步行街,发现一对街头艺人周围围满了人,欢快的鼓点节奏还有艺人张扬的发型,以及卖力的表演让不少路人都停下来驻足观看。
在 Swanston St 的北边也有一个街头艺人在表演,一个年轻小伙,单独一人,一架电子琴,看小伙的容貌稍微感觉有点糙,有点凶,但指尖落下,琴声响起的时候真是被震住了,弹得又快又好,只可惜一首还没弹完城管就来了,通知小伙他的时间到了。。。听琴的人群里稍微能听到嘘声表示不满,但猫本城管的执法过程还算平和。
在 Flinders 火车站的东边有一个 Public Bar,里面聚集了很多水手大兵在畅饮啤酒庆祝节日。
下午两点半坐电车来到 South Wharf,驻足亚拉河上,远眺猫本 CBD 慨叹澳洲的空气质量真是好,真希望不久的将来国内也能有这样一片干净的蓝天。下午在 South Wharf 买了两条 Levi's 的牛仔裤,一条 32/32 skinny fit,一条 30/32 regular fit,挑了个把小时,试了有十几条裤子才最终选定这两条,本来看上一条 regular tapered fit,穿着特舒服,颜色也好看,可惜最小只剩下 32/32 的,估计能有 31/32 的就合身了,可惜了。价钱还不错,两条一起 98 刀,比国内 Levi's 的牛仔裤可是便宜太多了。
行至猫本的步行街,发现一对街头艺人周围围满了人,欢快的鼓点节奏还有艺人张扬的发型,以及卖力的表演让不少路人都停下来驻足观看。
在 Flinders 火车站的东边有一个 Public Bar,里面聚集了很多水手大兵在畅饮啤酒庆祝节日。
2014年4月18日星期五
舌尖上的中国 第二季 开播
昨天晚上北京时间9:10中央一套开播 舌尖上的中国第二季,我是到今天上午才看的视频。第二季的第一集名为 脚步,分好几个主线展开,包括采蜂蜜的人,养蜂人,还有渔民等,明显感觉第二季里面融入了更多的人物本身的故事,有更浓的人情味,有些情节和旁白更是催人泪下。看了舌尖上的中国最大的感受就是要珍惜食物,想想自己吃的美味从原食材到加工烹饪都是凝聚了很多人的辛勤劳动的汗水,至此对 谁知盘中餐粒粒皆辛苦 这句话有了更深的理解。很高兴舌尖二开播了,每周又多了一个可以看的节目了。
2014年4月17日星期四
Gabriel Garcia Marquez
早上醒来的时候,习惯性的拿起手机看新闻,一打开凤凰网就看到《百年孤独》的作者,文学巨匠加西亚马尔克斯去世了,尽管马尔克斯确实年事已高,又早就诊断患有癌症,而且早已封笔多年,但看到新闻的那一刻还是感到无比的惋惜,仿佛他的离去意味着一个时代的终结。
我看过的书并不多,屈指可数,马尔克斯的《百年孤独》和《霍乱时期的爱情》是其中的两本,马尔克斯的作品我也就看过这两本,但都看的很深很认真。
想起自己第一次尝试看《百》的时候还是在高中的时候,当时还没有真正喜欢上阅读,没有欣赏文字的能力,只是跟风看看文学作品,一上来我就从图书馆借了一本《百》,结果没坚持过两天就作罢了,被里面光怪陆离的情节,盘根错节的人物关系以及模糊不清的人物名称给彻底打败了,竟然爷孙好几代人都叫阿尔卡迪奥和奥雷里亚诺。。。打那以后近10年都没敢再尝试阅读《百》,一直到2010年的夏天,我发现亚马逊上有马尔克斯正式授权发布的《百》的中文版在热卖,当时想想一定要挑战一下自己,而且10年的人生历练让我相信自己慢慢的开始能读懂《百》了,于是毫不犹豫的下了单,并且在接下来两个月的时间里认认真真把它品尝了一遍。
在读完《百》合上书本的那一刻我真的有种像是被人从马孔多硬生生拉回到现实的感觉,恍如隔世,像是自己和书中的主角捆绑在一起在马孔多风雨飘摇的几百年里历经了几代人的生死轮回荣辱兴衰一样,沉醉了,这就是马尔克斯那有魔力般文字的力量,我热爱电影,但还没有哪部电影能带给我这样的感官冲击。
写着写着我决定找时间再重读一遍《百年孤独》,肯定还会读一读马尔克斯其它的作品吧,当然如果这些作品都是正版的话,我想这应该也就是缅怀马尔克斯最好的方式了吧,但愿马尔克斯在天国找到属于他的那个马孔多,一个能多些阳光少些阴雨的马孔多。
我看过的书并不多,屈指可数,马尔克斯的《百年孤独》和《霍乱时期的爱情》是其中的两本,马尔克斯的作品我也就看过这两本,但都看的很深很认真。
想起自己第一次尝试看《百》的时候还是在高中的时候,当时还没有真正喜欢上阅读,没有欣赏文字的能力,只是跟风看看文学作品,一上来我就从图书馆借了一本《百》,结果没坚持过两天就作罢了,被里面光怪陆离的情节,盘根错节的人物关系以及模糊不清的人物名称给彻底打败了,竟然爷孙好几代人都叫阿尔卡迪奥和奥雷里亚诺。。。打那以后近10年都没敢再尝试阅读《百》,一直到2010年的夏天,我发现亚马逊上有马尔克斯正式授权发布的《百》的中文版在热卖,当时想想一定要挑战一下自己,而且10年的人生历练让我相信自己慢慢的开始能读懂《百》了,于是毫不犹豫的下了单,并且在接下来两个月的时间里认认真真把它品尝了一遍。
在读完《百》合上书本的那一刻我真的有种像是被人从马孔多硬生生拉回到现实的感觉,恍如隔世,像是自己和书中的主角捆绑在一起在马孔多风雨飘摇的几百年里历经了几代人的生死轮回荣辱兴衰一样,沉醉了,这就是马尔克斯那有魔力般文字的力量,我热爱电影,但还没有哪部电影能带给我这样的感官冲击。
写着写着我决定找时间再重读一遍《百年孤独》,肯定还会读一读马尔克斯其它的作品吧,当然如果这些作品都是正版的话,我想这应该也就是缅怀马尔克斯最好的方式了吧,但愿马尔克斯在天国找到属于他的那个马孔多,一个能多些阳光少些阴雨的马孔多。
2014年4月15日星期二
Guangzhou Ever Grand vs Melbourne Victory at Etihad Stadium
第一次在猫本看亚冠的比赛,记得上一次在现场看球都是2011年时候的事情了,当时在贺龙体育场看的长沙金德对上海申花。
入场前料想会有很多中国球迷到场观战,但实在是没想到会有这么多,中国球迷的红色球衣在观众席的一边连成了红色的海洋,另外还有很多球迷散落在其它看台区域,我估计在场的中国球迷人数是要多过猫本当地球迷的,不可谓声势浩大,有种来到了广州天体的感觉。但是我想说的是,猫本球迷人数虽略少,但有好几个集中的球迷方阵,喊着统一的口号,踏着统一的节奏,非常团结,助威气势一点不弱于人数众多的中国球迷,其实我在现场的感觉是猫本球迷的气势很多时候都盖过了中国球迷,可能中国球迷还需要更为专业激情的组织一下吧。
下图是猫本球迷冲中国球迷竖中指对骂。。。
上图是几个光头本土球迷加油助威,下图是另一个本土球迷方阵。
最后来一张中国红色海洋,辛苦了大家。
入场前料想会有很多中国球迷到场观战,但实在是没想到会有这么多,中国球迷的红色球衣在观众席的一边连成了红色的海洋,另外还有很多球迷散落在其它看台区域,我估计在场的中国球迷人数是要多过猫本当地球迷的,不可谓声势浩大,有种来到了广州天体的感觉。但是我想说的是,猫本球迷人数虽略少,但有好几个集中的球迷方阵,喊着统一的口号,踏着统一的节奏,非常团结,助威气势一点不弱于人数众多的中国球迷,其实我在现场的感觉是猫本球迷的气势很多时候都盖过了中国球迷,可能中国球迷还需要更为专业激情的组织一下吧。
下图是猫本球迷冲中国球迷竖中指对骂。。。
上图是几个光头本土球迷加油助威,下图是另一个本土球迷方阵。
最后来一张中国红色海洋,辛苦了大家。
2014年4月14日星期一
留学期间阅读的文献汇总,二季度
1. Photo Tourism: Exploring Photo Collections in 3D, (completely read on 27th Mar 2014).
University of Washington 的 Noah Snavely 和 Steven M. Seitz 在 2006 年发表于 Association for Computing Machinery (ACM) 的一篇文章。看这篇文章主要的获得是吸纳了其中关于 Structure from Motion 流程的文字描述,其实这篇文章本身主要的内容还是关于如何利用互联网上的大数据(这里指海量图片数据)来对一些著名的自然和人文景点进行三维重建,并且提 出一整套关于某个景点的图像浏览导航的策略,让人们可以通过互联网的图片来进行虚拟的景点观光,并且可以通过重建出来的各图像拍摄的时间和位置,最后统计 总结出最佳的图像浏览顺序,我想 Google 地图的街景浏览技术应该就是用的这篇文章里描述的技术,包括你按下方向键,Google map 是通过一种渐变的方式过渡到下一幅图像的,但 Google 街景浏览应该还不是利用的三维重建出来的结果,而是实地拍摄的大量图片。这篇文章里主要涉及的还是基于特征的稀疏重建,并不是密集重建结果,而是利用稀疏 的重建点云去拟合各个平面,最后用平面去描述场景,这对于建筑一类的场景还是奏效的。
文中关于 SfM 的过程主要是进行的文字描述,我发现 SfM 跟我 3 月初的做法最大的不同就在于其在起始对每个图像对都首先进行了特征匹配,这样所有的图像间的关系就建立好了,各图像上匹配成 Tracks 的特征点也从此有了一个全局的对应关系,而不是像我的做法中的那样某个图像中的特征点必须通过和某个已经定向好的图像进行特征匹配才能建立其和全局点云的 对应关系,这样的做法确实更为合理和鲁棒。
2. Scene Reconstruction and Visualization From Community Photo Collections, (completely read on 30th Mar 2014).
这是上文作者 Noah Snavely 2010 年发表于 Proceedings of the IEEE 的一篇综述性的文章,主要是关于 Recent progress in digitizing and visualizing the world from data captured by people taking photos and uploading them to the web。
文章从基于特征的 Structure from Motion 场景稀疏重建讲起,接着讲到场景的密集重建,然后很大篇幅都是讲什么场景总结、图像聚类、寻找最优浏览路径等,也就是跟上文 Photo Tourism 相关的那些技术,跟我的研究相关度不高。文章中说到他们场景重建的目的不仅仅是通过 Multi-view stereo 来恢复场景的几何,还要恢复每个场景点的光照反射以及场景中的光照条件,这其实才是完整的三维重建要最终达到的效果,其实我一直认为考虑了光照条件和反射的同时也可以提高场景几何重建的精度,而不单单是先完成几何重建,完了之后再单独去进行光照和反射重建。
下面再摘录一些我认为文中对我的研究会有意义的信息:
M. Goesele 和 N. Snavely 于 2007 年发表于 ICCV 的 Multi-view stereo for community photo collections,里面有提出depth maps fusion 的方法,这篇文章我决定这两天好好看看。
文中提到其 SfM 后形成的 Image connectivity graph 是由 neato tool in the Graphviz graph visualization toolkit [25] 画出的,这个先记着,说不定后面可以用上。
文章将场景材料分为 diffuse, glossy and mirror 三种,即漫反射,有一定反射能力以及全镜面反射三种,然后还引用了 3 篇实验室内标定场景反射能力的文章,参考文中的 [13] [38] [46],还提到 3 篇室外估计光照和反射的文章,参考文中的 [12] [14] [78]。然后 本文作者一干人等在 2009 年文献 [27] 中使用 computer graphics 领域中的 inverse rendering 技术来从社区图像集中获得环境光照和反射。
3. Multi-View Stereo for Community Photo Collections, (completely read on 30th Mar 2014).
这就是上文中提到的 [22] 号参考文献,M. Goesele 和 N. Snavely 于 2007 年发表于 ICCV 的一篇文章。首先纠正一个说法,总结上文时我说该文里提到了新的 depth maps fusion 的算法,其实严格意义上来说本文并不是关于 depth maps fusion 的。
我就直接开始总结本文的核心思想吧,在 SfM 之后,在一堆网络图片中,首先文章先后通过全局选择准则 Global View Selection 和局部选择准则 Local View Selection 自动的选择适合进行后续 MVS 的各图像集,形成的每个图像集保证其各图像拍摄的场景内容 scene content,外形光照 appearance, 还有尺度 scale 都差不多一致,还有图像集中各图像对之间有一定的基线长度,而不至于基线太短,文中的 Global and Local View Selection 准则分别都有详细的式子描述,但这个不是我关心的重点。我关心的重点是后续在每个图像集上进行 MVS 的算法。
文中形成的每个图像集都有一个 reference image,最后要达到的效果是每个图像集都要形成一幅相对于其参考图像的 depth map,每个图像集的 depth map 是通过一种 seeds expansion 的策略去形成的:
一、相对于参考图像的 depth map 的形成过程中一直维护有一个优先级队列 Q,存放了接下来要进行评估考察的参考图像中的候选像素的位置,以及初始的深度值与法向值,这些 candidates 在 Q 中是按其期望置信度(即与其相邻的,将其引荐入 Q 的像素的置信度)大 小排列的,期望置信度高的候选者将被优先评估;通过了评估考察的候选者将被正式存入输出的 depth map, normal map and confidence map,并且将其 4 邻域内的 4 个像素作为新的候选者载入 Q,这 4 个候选者的期望置信度就是该通过评估考察的像素的置信度;
二、初始化优先级队列 Q,很显然在 SfM 过程中通过高精度配上的那些参考图中的稀疏 feature points 可以作为 seeds 推入 Q,并被优先考察,文中还指出可以把所有能在参考图上形成合理投影像点的已重建出来的稀疏场景点在参考图上做投影,并把投影像点作为 seeds 推入 Q,即使很多点在 SfM 过程中并没被裁定能在参考图中被观测到,如此一来初始 seeds set 就得到了拓展,反正那些确实在参考图中被遮挡的 feature points 在后续过程中很有可能因为通不过 photometric consistency check 而被否决掉。然后每个初始 seeds 的深度就设置为其重建出来的深度,法向为 fronto-parallel normal;
三、Stereo Matching as Optimization,基于优化的立体匹配,这一部分是文章的精髓所在。文章把场景的最小基元描述成一个带有法向的平面,当然这个法向是相对于参考图 而言的,以每个像素为中心的 N*N 的像素矩形框对应了场景中的一个有 N*N 个采样点的有法向的空间平面,如下图所示。
然后像素点 (s,t) 对应的场景点坐标就可以表示为:
而以 (s,t) 为中心的 N*N 的矩形框中的每个像素对应的场景点坐标就可以表示为:
其中 hs(s,t) 和 ht(s,t) 为平面深度在 s 和 t 方向上的线性增长因子,他们共同表示了平面法向 n。如此一来 N*N 个像素矩形框对应的 N*N 个空间平面点的坐标也就全都可以计算出来了,有了这些坐标,然后结合其它图像各自的参数就可以让这些平面点在其它图像上进行重投影,并对重投影像点的 color 进行插值,从而在每个其它每个图像上得到一个 N*N 的 image patch 来,利用这些 patches 和参考图上的 patch 来一一计算 SSD (Sum of Squared Differences),并考察相似性程度。
文中为了应对不同视角法向造成的灰度差,在考查相似性程度的时候,还为每个其它图像加入了一个线性尺度参数 ck,文中说 ck 因子很好的描述了在恒定光照条件下,漫反射空间平面在不同视角图像上的色彩变化,如此一来总的相似性描述方程应该为:
忽略 (s,t) 坐标上式就变成:
忽略 (s,t) 坐标上式就变成:
按照上述模型,如果有 m 幅其它图像的话,那么优化过程中就有 3+3m 个变量,h,hs,ht,以及 3m 个 ck,而如果是彩色图像,那么每个采样点有 3 个上述的观测方程,整个 patch 的话就是 3n*n 个,然后有 m 幅图像,因此总共有 3n*n*m 个观测方程,所以是超定的。文中采用摄影测量领域的 Multiphoto Gemetrically Constrained Least Squares Matching (MPGC) 来做这一优化。
下面摘录一段文中有关采用 SSD 还是 NCC 来做相似性度量的描述,讲的很好:
4. Accurate Multi-View Reconstruction Using Robust Binocular Stereo and Surface Meshing, (completely read on 3rd Apr 2014).
这是 University of British Columbia 的 Derek Brakley 在 2008 年发表于 CVPR 的一篇文章,当时被这篇文章吸引,是因为看到了其中几张枕头和衣服袖子的重建结果非常的好,心想要了解下到底用了什么方法,今天看完,一个总的感受就是这 篇文章之所以能有好的结果就在于他采用了很多道繁琐的工序来剔除 outliers,也就是说质量控制比较好,但我很怀疑他的整套算法的运行速度真的能像文中说的那么快。
直接切入重点,开始总结其中的一些关键点,首先总结下文中算法的整体流程:
一、需要提一下的是所有的图像都是事先标定好的,我看文中重建的物体都是放在一个贴满编码标志的平面板上用以标定图像外参数,然后文中上来就说物体 的轮廓已给定。。。也就是说 visual hull 已经有了,这样的条件一给定就已经能排除大量位于 visual hull 外的 outliers 了。。。回到正题,算法先选定几组靠的比较近的,适合进行 binocular stereo 的图像对,然后在每个图像对上去做 binocular stereo,并各自生成 depth maps,并整合 “merging” 成一个单一的大的 depth map,注意这里的 merging 没有 fusion 的意思,而只是单纯的把所有的 depth maps 整合成一大的,这一步得到的点云集为 Pn,其中文中还对每个点估计了其法向;
二、文中称这一步为 downsampling,降采样,意思就是上一步 merge 成的大 depth map 对于每个场景点都很多采样点,重复观测等,冗余度很大,这是很自然的,其实这一步就是 depth fusion,这一步输出的点云集为 Ps;
三、Cleaning,在完成 depth fusion 的 cloud points 中去进一步剔除 outliers 和小尺度的高频噪声点,这一步输出的点云集为 Pf;
四、Meshing,形成三角网络 mesh。
第一步中,文中的主要亮点在于所谓的 Scaled window matching,由于文中的密集匹配方法还是基于 NCC,所以避免不了要解决模板匹配中的 fronto-parallel 的问题,文中解决这一问题的方法就是在 epipolar resampling 也就是 stereo rectify 过程中生成多个不同水平矫正尺度(different horizontal scale factors)的匹配图像,然后用参考图的同一个模板在这不同矫正尺度的匹配图上沿极线去找最优匹配位置,文中花了1/4页的版面去证明这个尺度比例在 整幅图上是不变的,然后最后又说其实就选择了 3 个固定的水平尺度因子去进行矫正 1/sqrt(2), 1 以及 sqrt(2)。。。然后是亚像素视差的获得,我的理解好像是他要对图像进行拓展,比方说沿水平方向把图像尺寸进行插值拓展,然后用拓展的图去估计亚像素 视差。。。这个方法我不敢恭维啊。最后在视差图上还进行了一次中值滤波和 standard bilateral filter weighted by the NCC value 以剔除高频噪声视差点。
在所有的 depth maps 反投影到场景空间形成整合的大的点云之后,由于后续的处理需要用到点云中点的法向,因此还需要估计每个点的法向值,文中提到这可以使用 image-space gradient calculation 来估计每个 depth maps 中每个像素相对于该 depth map 的法向,这其实就是上文中的平面 patch 表示平面法向的方式,然后文中采用的方式是通过 kD-Tree 找到每个空间点的 k 个邻近点,然后去估计该点和 k 个邻近点张开的空间范围的最次的主方向,也就是对应了最小特征值的特征向量,文中描述这一过程是一 Principal Component Analysis (PCA) [20] 过程,这一术语用的真好,其实这一步出来的法向还不能确定正负号,然后就利用图像和观测场景点之间的相互关系来确定最终的法向方向,因为某观测到的场景点的法向肯定是冲着图像的,而不能是背着图像的。有了每个点的法向之后,这就形成了点云集 Pn。
到这一步就需要开始 fusion 点云了,他这里的做法简而言之,就是先对 Pn 进行聚类,聚为一类的空间点被认为是对应了同一个空间点,然后在每一类中选一个代表出来代表该类,这就完成了 fusion 了,他采用的聚类方法是所谓的 hierarchical vertex clustering,然后要支持该层次聚类还需要特别的数据结构 hierarchical partioning structure,文中选择了其中的 Volume-Surface Tree [5] 结构。最后每个聚类中的代表是怎么选举出来的呢?其实就是取的聚类中所有点的平均点位和平均法向作为该聚类代表。
文章在其摘要中就声称该算法主要是面向三维医学数据,像核磁共振成像扫描得到的人体三维图像切片等,这种医学数据就是典型的三维离散数据,里面的单元是一个一个 voxel,也就是三维像素,每个 voxel 也有一个强度值,也就是 intensity,原文中说成是 density。我记得以前张老师叫我处理过一组这样的脑部切片图像,它里面不同的人体组织有不同的灰度值,骨骼一般灰度值比较高,软组织灰度值就比较低,显得较暗,但同一组织在不同切片图像上的灰度响应是一致的,比方说我们想从这样的三维数据中提取出整个人体骨骼的 surface,已知骨骼外边缘的灰度值恒为 255,那么我们就只需把每个切片图像中灰度值为 255 的像素取出来就行了,但是简单的这样做只能是得到彼此不相关联的一个个封闭的 curves,不在相邻切片图像间建立联系的话就这些独立的 curves 是无法重构出骨骼 surface 的,那么文章的方法就是每次同时考虑相邻的两层切片图像,上下对应各取 2×2=4 个像素,共 8 个像素组成一个 cube,这 8 个像素每个像素都和骨骼的灰度 255 去比较,也就是说每个像素会有 0 和 1 两种状态,真正的 bone surface 会切过该 cube 中那些一端灰度比 255 小,一端比 255 大的边,这个还是比较好理解的。
文中对 surface 和 cube 相交的形式总结归纳出了一下 15 种:
其中第 0 种就是没有 surface,第 1 种里面 surface 可以用 1 个 triangle 表示,其它的形式中 surface 最多可以用 4 个 triangles 来表示,每个 triangle 的 vertices 的三维坐标可以利用所在边两端像素的灰度简单的线性插值出来,也就是说每个确定包含 bone surface 的 cube 可以最多输出 4 个 triangles,最终遍历所有 voxels 以后所有的 triangles 将自然连接成一个完整的 triangle mesh,也就是我们想要的 bone surface。
University of Washington 的 Noah Snavely 和 Steven M. Seitz 在 2006 年发表于 Association for Computing Machinery (ACM) 的一篇文章。看这篇文章主要的获得是吸纳了其中关于 Structure from Motion 流程的文字描述,其实这篇文章本身主要的内容还是关于如何利用互联网上的大数据(这里指海量图片数据)来对一些著名的自然和人文景点进行三维重建,并且提 出一整套关于某个景点的图像浏览导航的策略,让人们可以通过互联网的图片来进行虚拟的景点观光,并且可以通过重建出来的各图像拍摄的时间和位置,最后统计 总结出最佳的图像浏览顺序,我想 Google 地图的街景浏览技术应该就是用的这篇文章里描述的技术,包括你按下方向键,Google map 是通过一种渐变的方式过渡到下一幅图像的,但 Google 街景浏览应该还不是利用的三维重建出来的结果,而是实地拍摄的大量图片。这篇文章里主要涉及的还是基于特征的稀疏重建,并不是密集重建结果,而是利用稀疏 的重建点云去拟合各个平面,最后用平面去描述场景,这对于建筑一类的场景还是奏效的。
文中关于 SfM 的过程主要是进行的文字描述,我发现 SfM 跟我 3 月初的做法最大的不同就在于其在起始对每个图像对都首先进行了特征匹配,这样所有的图像间的关系就建立好了,各图像上匹配成 Tracks 的特征点也从此有了一个全局的对应关系,而不是像我的做法中的那样某个图像中的特征点必须通过和某个已经定向好的图像进行特征匹配才能建立其和全局点云的 对应关系,这样的做法确实更为合理和鲁棒。
2. Scene Reconstruction and Visualization From Community Photo Collections, (completely read on 30th Mar 2014).
这是上文作者 Noah Snavely 2010 年发表于 Proceedings of the IEEE 的一篇综述性的文章,主要是关于 Recent progress in digitizing and visualizing the world from data captured by people taking photos and uploading them to the web。
文章从基于特征的 Structure from Motion 场景稀疏重建讲起,接着讲到场景的密集重建,然后很大篇幅都是讲什么场景总结、图像聚类、寻找最优浏览路径等,也就是跟上文 Photo Tourism 相关的那些技术,跟我的研究相关度不高。文章中说到他们场景重建的目的不仅仅是通过 Multi-view stereo 来恢复场景的几何,还要恢复每个场景点的光照反射以及场景中的光照条件,这其实才是完整的三维重建要最终达到的效果,其实我一直认为考虑了光照条件和反射的同时也可以提高场景几何重建的精度,而不单单是先完成几何重建,完了之后再单独去进行光照和反射重建。
下面再摘录一些我认为文中对我的研究会有意义的信息:
M. Goesele 和 N. Snavely 于 2007 年发表于 ICCV 的 Multi-view stereo for community photo collections,里面有提出depth maps fusion 的方法,这篇文章我决定这两天好好看看。
文中提到其 SfM 后形成的 Image connectivity graph 是由 neato tool in the Graphviz graph visualization toolkit [25] 画出的,这个先记着,说不定后面可以用上。
文章将场景材料分为 diffuse, glossy and mirror 三种,即漫反射,有一定反射能力以及全镜面反射三种,然后还引用了 3 篇实验室内标定场景反射能力的文章,参考文中的 [13] [38] [46],还提到 3 篇室外估计光照和反射的文章,参考文中的 [12] [14] [78]。然后 本文作者一干人等在 2009 年文献 [27] 中使用 computer graphics 领域中的 inverse rendering 技术来从社区图像集中获得环境光照和反射。
3. Multi-View Stereo for Community Photo Collections, (completely read on 30th Mar 2014).
这就是上文中提到的 [22] 号参考文献,M. Goesele 和 N. Snavely 于 2007 年发表于 ICCV 的一篇文章。首先纠正一个说法,总结上文时我说该文里提到了新的 depth maps fusion 的算法,其实严格意义上来说本文并不是关于 depth maps fusion 的。
我就直接开始总结本文的核心思想吧,在 SfM 之后,在一堆网络图片中,首先文章先后通过全局选择准则 Global View Selection 和局部选择准则 Local View Selection 自动的选择适合进行后续 MVS 的各图像集,形成的每个图像集保证其各图像拍摄的场景内容 scene content,外形光照 appearance, 还有尺度 scale 都差不多一致,还有图像集中各图像对之间有一定的基线长度,而不至于基线太短,文中的 Global and Local View Selection 准则分别都有详细的式子描述,但这个不是我关心的重点。我关心的重点是后续在每个图像集上进行 MVS 的算法。
文中形成的每个图像集都有一个 reference image,最后要达到的效果是每个图像集都要形成一幅相对于其参考图像的 depth map,每个图像集的 depth map 是通过一种 seeds expansion 的策略去形成的:
一、相对于参考图像的 depth map 的形成过程中一直维护有一个优先级队列 Q,存放了接下来要进行评估考察的参考图像中的候选像素的位置,以及初始的深度值与法向值,这些 candidates 在 Q 中是按其期望置信度(即与其相邻的,将其引荐入 Q 的像素的置信度)大 小排列的,期望置信度高的候选者将被优先评估;通过了评估考察的候选者将被正式存入输出的 depth map, normal map and confidence map,并且将其 4 邻域内的 4 个像素作为新的候选者载入 Q,这 4 个候选者的期望置信度就是该通过评估考察的像素的置信度;
二、初始化优先级队列 Q,很显然在 SfM 过程中通过高精度配上的那些参考图中的稀疏 feature points 可以作为 seeds 推入 Q,并被优先考察,文中还指出可以把所有能在参考图上形成合理投影像点的已重建出来的稀疏场景点在参考图上做投影,并把投影像点作为 seeds 推入 Q,即使很多点在 SfM 过程中并没被裁定能在参考图中被观测到,如此一来初始 seeds set 就得到了拓展,反正那些确实在参考图中被遮挡的 feature points 在后续过程中很有可能因为通不过 photometric consistency check 而被否决掉。然后每个初始 seeds 的深度就设置为其重建出来的深度,法向为 fronto-parallel normal;
三、Stereo Matching as Optimization,基于优化的立体匹配,这一部分是文章的精髓所在。文章把场景的最小基元描述成一个带有法向的平面,当然这个法向是相对于参考图 而言的,以每个像素为中心的 N*N 的像素矩形框对应了场景中的一个有 N*N 个采样点的有法向的空间平面,如下图所示。
然后像素点 (s,t) 对应的场景点坐标就可以表示为:
而以 (s,t) 为中心的 N*N 的矩形框中的每个像素对应的场景点坐标就可以表示为:
其中 hs(s,t) 和 ht(s,t) 为平面深度在 s 和 t 方向上的线性增长因子,他们共同表示了平面法向 n。如此一来 N*N 个像素矩形框对应的 N*N 个空间平面点的坐标也就全都可以计算出来了,有了这些坐标,然后结合其它图像各自的参数就可以让这些平面点在其它图像上进行重投影,并对重投影像点的 color 进行插值,从而在每个其它每个图像上得到一个 N*N 的 image patch 来,利用这些 patches 和参考图上的 patch 来一一计算 SSD (Sum of Squared Differences),并考察相似性程度。
文中为了应对不同视角法向造成的灰度差,在考查相似性程度的时候,还为每个其它图像加入了一个线性尺度参数 ck,文中说 ck 因子很好的描述了在恒定光照条件下,漫反射空间平面在不同视角图像上的色彩变化,如此一来总的相似性描述方程应该为:
忽略 (s,t) 坐标上式就变成:
忽略 (s,t) 坐标上式就变成:
按照上述模型,如果有 m 幅其它图像的话,那么优化过程中就有 3+3m 个变量,h,hs,ht,以及 3m 个 ck,而如果是彩色图像,那么每个采样点有 3 个上述的观测方程,整个 patch 的话就是 3n*n 个,然后有 m 幅图像,因此总共有 3n*n*m 个观测方程,所以是超定的。文中采用摄影测量领域的 Multiphoto Gemetrically Constrained Least Squares Matching (MPGC) 来做这一优化。
下面摘录一段文中有关采用 SSD 还是 NCC 来做相似性度量的描述,讲的很好:
文中还花了较多篇幅描述采用怎么的优化机制去避免 MPGC 发生震荡,看着还挺繁琐的。
这是 University of British Columbia 的 Derek Brakley 在 2008 年发表于 CVPR 的一篇文章,当时被这篇文章吸引,是因为看到了其中几张枕头和衣服袖子的重建结果非常的好,心想要了解下到底用了什么方法,今天看完,一个总的感受就是这 篇文章之所以能有好的结果就在于他采用了很多道繁琐的工序来剔除 outliers,也就是说质量控制比较好,但我很怀疑他的整套算法的运行速度真的能像文中说的那么快。
直接切入重点,开始总结其中的一些关键点,首先总结下文中算法的整体流程:
一、需要提一下的是所有的图像都是事先标定好的,我看文中重建的物体都是放在一个贴满编码标志的平面板上用以标定图像外参数,然后文中上来就说物体 的轮廓已给定。。。也就是说 visual hull 已经有了,这样的条件一给定就已经能排除大量位于 visual hull 外的 outliers 了。。。回到正题,算法先选定几组靠的比较近的,适合进行 binocular stereo 的图像对,然后在每个图像对上去做 binocular stereo,并各自生成 depth maps,并整合 “merging” 成一个单一的大的 depth map,注意这里的 merging 没有 fusion 的意思,而只是单纯的把所有的 depth maps 整合成一大的,这一步得到的点云集为 Pn,其中文中还对每个点估计了其法向;
二、文中称这一步为 downsampling,降采样,意思就是上一步 merge 成的大 depth map 对于每个场景点都很多采样点,重复观测等,冗余度很大,这是很自然的,其实这一步就是 depth fusion,这一步输出的点云集为 Ps;
三、Cleaning,在完成 depth fusion 的 cloud points 中去进一步剔除 outliers 和小尺度的高频噪声点,这一步输出的点云集为 Pf;
四、Meshing,形成三角网络 mesh。
第一步中,文中的主要亮点在于所谓的 Scaled window matching,由于文中的密集匹配方法还是基于 NCC,所以避免不了要解决模板匹配中的 fronto-parallel 的问题,文中解决这一问题的方法就是在 epipolar resampling 也就是 stereo rectify 过程中生成多个不同水平矫正尺度(different horizontal scale factors)的匹配图像,然后用参考图的同一个模板在这不同矫正尺度的匹配图上沿极线去找最优匹配位置,文中花了1/4页的版面去证明这个尺度比例在 整幅图上是不变的,然后最后又说其实就选择了 3 个固定的水平尺度因子去进行矫正 1/sqrt(2), 1 以及 sqrt(2)。。。然后是亚像素视差的获得,我的理解好像是他要对图像进行拓展,比方说沿水平方向把图像尺寸进行插值拓展,然后用拓展的图去估计亚像素 视差。。。这个方法我不敢恭维啊。最后在视差图上还进行了一次中值滤波和 standard bilateral filter weighted by the NCC value 以剔除高频噪声视差点。
在所有的 depth maps 反投影到场景空间形成整合的大的点云之后,由于后续的处理需要用到点云中点的法向,因此还需要估计每个点的法向值,文中提到这可以使用 image-space gradient calculation 来估计每个 depth maps 中每个像素相对于该 depth map 的法向,这其实就是上文中的平面 patch 表示平面法向的方式,然后文中采用的方式是通过 kD-Tree 找到每个空间点的 k 个邻近点,然后去估计该点和 k 个邻近点张开的空间范围的最次的主方向,也就是对应了最小特征值的特征向量,文中描述这一过程是一 Principal Component Analysis (PCA) [20] 过程,这一术语用的真好,其实这一步出来的法向还不能确定正负号,然后就利用图像和观测场景点之间的相互关系来确定最终的法向方向,因为某观测到的场景点的法向肯定是冲着图像的,而不能是背着图像的。有了每个点的法向之后,这就形成了点云集 Pn。
到这一步就需要开始 fusion 点云了,他这里的做法简而言之,就是先对 Pn 进行聚类,聚为一类的空间点被认为是对应了同一个空间点,然后在每一类中选一个代表出来代表该类,这就完成了 fusion 了,他采用的聚类方法是所谓的 hierarchical vertex clustering,然后要支持该层次聚类还需要特别的数据结构 hierarchical partioning structure,文中选择了其中的 Volume-Surface Tree [5] 结构。最后每个聚类中的代表是怎么选举出来的呢?其实就是取的聚类中所有点的平均点位和平均法向作为该聚类代表。
上一步得到 Ps 之后,其中还有很多 outliers 和 small scale high frequency noise,这一部分文章怎么做的我没看太明白,也没有看太细,就是看到处理前者是采用的迭代分类的方式,然后算了一个 Plane Fit Criterion [42],就可以检测到 outliers 了。滤除高频噪声文中采用一种 point-normal filtering inspired by Amenta and Kil [3] and is basically a simplification of the Moving Least Square Projection [1] using the per-sample normal estimate,我大概的理解是利用邻近点进行加权拟合得到一个平面,然后让点在该平面上做投影,并用投影点代替该点。
最后关于 Mesh,我涉及的不多,所以也没怎么看懂,大概的意思就是要做到两点吧,先是把传统的 delaunay triangulation
改了下,改成局部的 triangulation
了,之前是全局形式的,现在改成局部的话,不会牵一发而动全身了,提高了速度,另一个就是争取降维,做 2D 的 delaunay
triangulation 简化算法。在 meshing 过程中文章也有剔除的操作。
5. Accurate, Dense, and Robust Multiview Stereopsis, (completely read on 1st May 2014).
我崇拜的大牛 Y. Furukawa 在 2010 年发表在 PAMI 的一篇文章,详细介绍了他的 PMVS 的整套方法原理
6. SURE: Photogrammetric Surface Reconstruction from Imagery, (completely read on 6th May 2014).
这是来自 Institute for Photogrammetry, University of Stuttgart 的 Mathias Rothermel, K. Wenzel, D. Fritsch 和 N. Haala 的一篇文章,说是一篇学术文章哈,其实主要是介绍他们的 SURE 三维重建软件的原理。
前言部分总结说虽然已经有很多的 MVS 算法提出,但是真正公开让大家可以用到的 MVS 软件却还很少,里面提到了 Furukawa 的 PMVS 还有 CMVS,这两个都是可以在 Furukawa 网站上下到的,还有就是基于最大流/最小割全局方法的 MicMac 软件。文章的前言还是很丰富的,有一页半的量,总结了很多相关的文章,后面自己写文章值得参考。
文章的 SURE 软件的核心算法其实就是 Hirschmuller 的 Semi global matching,然后作为对软件的介绍,文章把软件的四大功能模块及相应的输入输出接口通过下面的流图表示出来了。
这个流程现在看还是比较清楚的,需要说明的是 SURE 并不是为每幅图像都生成一幅视差图并最终融合到一起,而是基于一定的机制,比方说按 EO 连通性对图像进行聚类,每一类选出一个 reference image,这就是 module 1 的工作;然后每一个聚类里其它图像都和参考图像组成一个 binocular stereo model 去做 tSGM,得到很多幅相对于该参考图像的视差图,当然这些视差图肯定是通过了 left/right consistency check 的视差图,这就是 module 2 和 3 的工作;最后就是通过这多个相对于参考图像的视差图基于 multi-view geometrical consistency check 来进行进一步的粗差剔除,深度融合以及最终非线性优化形式的 triangulation 的操作得到最终的相对于该聚类中参考图像的完整深度图,这就是 module 4 的工作。当所有聚类中相对于其参考图的深度图都得到之后,把这些深度图综合到一起就是最终的密集重建结果了。下面就开始摘录一些有用的信息。
SURE 的 Image rectification 功能用到了两个算法:
文中提到图像矫正并不会改变图像光心的位置,只是改变了像面的朝向,可以想象成在同样的空间内用一块虚拟的像面截取了新的图像,所以原始图像中的像点和矫正图像的对应位置应该是可以用一个平面单应来表示的,另外就是空间点和图像光心的连线方向以及长度应该都是不发生改变的,这也是后面在做 check 的时候利用到的一点。
如下图所示,SURE 用到的 matching cost 有一下三种,一是 Census cost,一是 Mutual infomation,另外还有 DAISY 描述子(居然还有这个),其中 Census cost 是对参数最不敏感的。
SURE 的核心 tSGM 算法相对于原 SGM 算法最大的改进就于内存占用量的减少,和运算时间的缩短,tSGM 是怎么做的呢,它是基于金字塔 coarse to fine 的思想,通过高层金字塔提供的 disparity range 信息来 propagate 到低层金字塔并限制了底层金字塔的 disparity searching range,这样就极大的减少了对内存的需要,进而缩短了运算时间,并且文章声称这样还屏蔽了一些 outlier。
下面就详细描述描述 tSGM 是怎么做的,首先在金字塔的最高层,这时图像尺寸和分辨率比较小,为了达到文中声称的完全不需要视差的任何先验信息的特性,显然金字塔最高层的视差图的视差范围是整个图像的尺寸,这时存储 matching cost 和 aggregated cost 的结构是原来的那种长方体 cube 结构,也就是每个像素的可能视差范围是完全一样的。
最高层往后的层存储 cost 的结构就不再是这种简单的但很占内存的长方体结构了,见下图,假使第 l 层生成的经过了 left/right check 的视差图为 D(l),这个信息如何影响下一层,也就是 l-1 层每个像素的 disparity searching range 的呢?tSGM 是这样做的,对于 D(l) 中每个有效视差像素,取以其为中心的 7×7 的窗口内的最大视差值为 dmax,最小视差值为 dmin,并各自存入一个新的二维矩阵 Dmax(l) 和 Dmin(l),还要把该像素的视差值更新为该窗口内的中值,对于 D(l) 中每个无效视差像素,也就是被判为遮挡的那些像素同样是进行上述操作,只不过这时候的窗口变成一个 31×31 的窗口,要说明的是文中说 l 层中针对有效视差和无效视差像素的 disparity searching range 分别被限制为了 16 和 32 个像素,也就是说对于一个有效视差像素如果 dmax - dmin <= 16,那么 searching range 就是 dmin 到 dmax,否则的话会有一个截断以保证 range 为 16 个像素,我在想这个截断操作可就不是只有唯一的方式了,是从上截,还是从下截,亦或是以中值为中心上下各 8 像素,更或是以没更新为中值前的视差值为中心上下各 8 像素?这里还是个疑问,至少从这篇文章里还找不到明确的答案,各让人不解的是文中说拓展到 l-1 层时,D(l),Dmax(l) 和 Dmin(l) 被 upscaled 了,l-1 层中每个像素的视差搜索范围居然是 [2(xb+d-dmin) 2(xb+d+dmax)],我觉得应该是 [2(xb+dmin) 2(xb+dmax)],因为经过截断后得到的 dmin 和 dmax 已经定义了 l 层中视差范围的两个边界,到 l-1 层时只需要简单的拓展一下就行了啊,但是这样做的话中值化的 D(l) 貌似又没起到什么作用,反正关于这个问题 SURE 到底是怎么做的我是还没有搞的很明白,尽管从下图来看他们的意图很明显。
然后再截一张文中有关基于其提出的新的 cost 存储结构的 cost aggregation 策略:
好吧,我承认上面的式子我又没有完全理解,感觉有点矛盾,Lr 难道只跟 Cr 有关系吗?不是 像原 SGM 中那样是 Lr-1 吗?而且是当 d>dmax 和 d<dmin 时才加 P2,其它情况则是 Lr=Lr-1,WTF?还是按原 SGM 那样的策略来做不就行了吗?
再截一段文字描述了 tSGM 中的 left/right check,以及如何整合灰度边缘信息,还有如何排除大面积的无效非场景区域。
下面就来描述如何通过多个相对于参考图像的视差图基于 multi-view geometrical consistency check 来进行进一步的粗差剔除,深度融合以及最终非线性优化形式的 triangulation 的操作得到最终的相对于该聚类中参考图像的完整深度图。
每个相对于参考图的视差图其实都是经过了不同的图像矫正操作的,直接在这些不同视差图上去进行比较肯定是没意义的,因为这个视差图上的 i,j 像素实际并不同样对应其它视差图上的 i,j 像素,因此比较都是相对于没有任何矫正的原参考图像来做的。
原参考图上的每个像素 xb 依据各视差图 Dn 还有图像矫正参数 Tn 能计算得到一个物点光心连线长度,如下图所示,依据的就是上面描述的空间点和图像光心的连线方向以及长度不随图像矫正发生改变。
原参考图中的每个像素在每个视差图上都可以计算得到一个这样的长度,其实也就代表了沿像素光心射线方向上的不同物点位置,这些物点位置肯定有些是 outliers,即使不是 outliers 肯定所有的物点位置也不是完全重合的,SURE 是怎么剔除这些 outliers 和融合 inliers 的呢?它就是通过聚类,它认为每个视差的提取沿极线方向上是有一定不确定度的,该不确定度投射到像素射线方向上就是一个一维的区间,当多个物点的该区间有重合时,这多个物点就被聚为一类,认为是同一个物点,见下图示意。
这样的聚类准则下可能会出现多个聚类,这时就选择拥有物点数目最多的那个聚类当做最终的物点,当然 SURE 也强加了一个最小聚类数目的参数,也就是说当最大聚类的物点数目少于该参数时,该像素依然会被判为是个无效的像素,因为多图间的一致性不够高。而当最多数目的聚类有多个的时候,则选择平均交会角最小的那个聚类,如下所示。
上面说的 image space accuracies are correctly propagated 我的理解是指就是上述的视差不确定度是跟交会角度有关的,交会角大时对应的视差不确定度会大些。
然后就是交会,也就是说上述的聚类中会有多个物点,这些物点到底要融合到哪一个共同的物点位置呢?SURE 有两种交会策略可供选择,一个是在物方做的,也就是直接取这些物点的平均深度位置,如下式
另一种方法则是更合理的考虑到每个观测像点的方式,也就是迭代优化使得在所有 rectified match images 上的综合重投影残差最小化:
式子写是这么写,但是仔细想一想上面的式子实际上意味着什么呢?其实就是意味着该以一维深度诱导的在各视差图上的视差值应该与各视差图上原本通过 tSGM 得到的视差值差的平方和最小化,依据式子 (10) 上式其实可以写成如下形式
其中的 D 就是要迭代优化的一维深度变量,准确说是点心连线长度,而 (xr,yr) 坐标是原始未矫正的参考图像中的考察像素 xb 对应其在 m 个矫正参考图中的坐标,该坐标与 D 无关,该深度 D 诱导的在 (xr,yr) 处的视差值就是前面的除法部分,后面的 dm 则是通过 tSGM 得到的在 (xr,yr) 处的视差值,这个目标函数对 D 求导还是比较简单的,因为就分母那项跟 D 有关。很容易迭代优化得到最终的 D,而且 Design matrix ATA 是一个标量,都不用求矩阵逆,只需要求倒数就行了。
最后文中就是列了一堆实验结果,并进行了结果分析。
7. Non-parametric Local Transforms for Computing Visual Correspondence, (completely read on 7th May 2014).
Ramin Zabih from Cornell University 1994 年的一篇 ECCV 文章,介绍了两种 non-parametric local transforms,一个是 rank transform,一个是 census transform,这两个变换的定义非常的简单,总之都是基于邻域内像素灰度和中心像素灰度间的比较,只不过 rank transform 只是记录了满足要求的邻域像素的个数,而 census transform 则还按顺序完整记录了各比较结果,因此也就包含了局部的结构信息,这两种变化可以说都属于 binary feature。这两种变换提出的初衷就是对抗局部窗口内不满足统一统计特性的少数 outliers,尤其是遇到 depth discontinuity 时,如果使用通常的 SAD, SSD 或者 NCC 相似性度量时,会造成较大的误差,尤其是 NCC,因为这些度量是基于灰度信息,outliers 的灰度会产生较大的影响,如果是像这里提出的 transform 一样只基于相对灰度值大小比较的话,outliers 的影响就会减小很多,能获得更好的 depth discontinuity 精度,其实这种方式后来在 Hirschmuller 09 年的 PAMI 综述文章里还被拿来进行测试,在对抗 radiometric differences 方面也获得最高的评价。
8. The Complete Rank Transform: A Tool for Accurate and Morphologically Invariant Matching of Structures, (completely read on 8th May 2014).
Oliver Demetz 在 2013 年发表的一篇文章,作者不是很熟悉。文章中提出了所谓的 Complete Rank Transform (CRT),跟原 rank transform 和 census transform 相比的不同就在于其为邻域内每个像素就统计了灰度比较特性,并依然以 string 形式存储,就下面一张图就可以看出它的创新点在哪里,CRT 需要的存储空间无疑是会多很多,因为不能以 bit string 的方式存储了,严格上说不是一种 local binary pattern LBP。
9. A Census-Based Stereo Vision Algorithm Using Modified Semi-Global Matching and Plane Fitting to Improve Matching Quality, (completely read on 8th May 2014).
奥地利 M. Humenberger 2010 年的一篇 CVPR 文章,我觉得有点侧重于高效视觉系统算法的实现,核心思想就是采用了 census transform 作为 matching cost,然后在 SGM 框架下做全局优化,之后再对纹理不丰富也就是匹配不可靠(其实也就意味着纹理不丰富)进行平面拟合得到最终的 disparity map,为了减小原 SGM 方法对内存的使用率,他这里提出不在全图做 SGM,而是在一定像素宽的条带图像区域做 SGM,以较少内存占用,我觉得没什么太多意义,可能对 FPGA 实现确实有意义吧。
10. Performance Evaluation of a Census-Based Stereo Matching Algorithm on Embedded and Multi-Core Hardware, (completely read on 8th May 2014).
还是上文作者 M. Humenberger 2009 年的一篇文章,关于这篇文章没什么太多好提的,他里面都是把 09 年那时候出现的嵌入式的 real-time stereo matching systems 给列了一下。
然后值得一提的就是他里面提了一种评判视差置信度的标准:
11. Evaluation of Stereo Matching Costs on Images with Radiometric Differences, (completely read on 9th May 2014).
SGM 算法的作者德国大神 Heiko Hirschmuller 在 2009 年的一篇 PAMI 文章,好吧,这篇文章毫无争议的当选我心目中的二季度最佳文章,这里我的总结不再摘录其中的有用信息了,因为怕篇幅不够,其中的有价值的信息实在是太多了,扎扎实实看完这篇文章我感觉心情很愉悦,很充实。文章总共测试比较了 15 种 matching costs 结合 3 种 stereo methods 的效果,这 15 种 matching costs 被他分为 parametric, nonparametric 和 Mutual infomation 三大类,3 种 stereo methods 则分别是基于矩形窗的 WTA Local method,SGM 以及 Graph cut。测试集 Images without
Radiometric Changes, Simulated Radiometric Changes 和 Real Exposure and Light Source Changes 三大类。文章还测试了不同 costs 对不同测试集的稳定性,以及各 costs 的 Discriminability,还分析了采用 color 信息对匹配的意义,这里我就仅仅摘录下文章的结论吧。面对这样的好文章我只能是一直膜拜了。。。总结完毕。
12. Bilateral Filtering for Gray and Color Images, (completely read on 11th May 2014).
来自 Stanford University 和 S. Birchfield 一起提出 sampling insensible matching cost 的 Carlo Tomasi 在 1998 年的一篇 ICCV 文章。
文中提出了一种新的图像滤波方法 —— Bilateral Filtering,相比于传统的高斯滤波等只能利用 spatial offset 信息来进行滤波,也就是文中所谓的 domain filtering,BF 还结合了 photometric difference 信息,即文中所谓的 range filtering,BF 同时考虑了空域和灰度(或色彩)域的偏移量,所以作者称其为 bilateral filtering。也就是说在原来传统的例如高斯滤波中,参与滤波的邻域元素的权重随其与中心元素的 spatial distance 非线性下降的基础上,其权重还同时随其灰度或色彩与中心元素灰度或色彩之间的差非线性下降,就这么个意思。
Bilateral filtering 在能达到传统滤波效果的基础上同时还能非常好的保持图像边缘的锐度,这也正是其后来被应用于 stereo 前段滤波去除 stereo images 之间 photometric distortion 的原因。关于 BF 的详细表达式可以参考原文,其边缘保持的效果确实非常的好。另外文中介绍了一种 CIE-Lab 的色彩空间表达方式,据其称该色彩空间表示是最符合人眼认知的一种表达方式。
13. Enhanced Real-time Stereo Using Bilateral Filtering, (completely read on 11th May 2014).
该文来自 Jet Propulsion Laboratory, California Institution of Technology 的 Adnan Ansar,作于 2004 年。该文据上面文献 11 中所描述是第一次将 bilateral filtering 应用于 stereo vision。
stereo vision 中在做 SAD 之前通常需要通过某些手段去补偿 stereo images 之间的整体亮度差或色彩差,常用的方法是 background subtraction,也就是用原始图像减去通过高斯滤波以后的图像,通过高斯滤波的图像被认为主要是图像背景,左右两幅图像都做了这一操作之后它们之间的亮度或者色彩差就被补偿了。但是传统的高斯等滤波方法都会使得图像边缘出现泛化,因此该文利用 bilateral filtering 取代高斯滤波去做 background subtraction,进而在不损失边缘锐度的情况下去补偿左右图像间的灰度或色彩差,然后再去做 stereo,这就是该文最大的贡献,另外一个贡献就是文中提出二维 bilateral filtering 可以拆分成两次一维滤波去做,一次沿行方向,一次沿列方向,被称这样可以提高运行速度。
14. Adaptive Support-Weight Approach for Correspondence Search, (completely read on 13th May 2014).
这是韩国人 Kuk-Jin Yoon 2006 年在 PAMI 上发表的一篇文章,像很多其他学者一样,该文里的内容事先已经于 2005 年发表在了 CVPR 上面,现在感觉 CVPR 已经成了 PAMI 和 IJCV 的试金石,中了 CVPR 接下来就是中 PAMI 和 IJCV 了。
文章前言里提到匹配问题的歧义性随着相似性度量分辨力的提高而下降,而后文章将 local stereo methods 中跟 support window 相关的方法分成了 4 大类:
1. Adaptive-window methods,窗口个数还是只有一个,但会有选择机制来选择一个最优的支持窗口;
2. Multiple-window methods,预先设定好若干固定的窗口,然后每个窗口去计算一次相似度,最终选择相似度最高的作为最终的相似度;
3. Segmentation-based methods, 先通过灰度或颜色信息对图像进行分割,然后利用分割信息形成 support window;
4. Adaptive support-weight methods,单一窗口,窗口形状可以就是简单的矩形窗,但是其中每个像素的 support-weights 却是自适应各不相同的,该文方法就属于这一范畴。
其 adaptive support-weight 的思想和上面文献 [12] 中提出的 bilateral filtering 很相似,同样是同时利用了 spatial proximity 和 photometric similarity 信息,如果 spatial proximity 加权函数 wp(p,q) 是 p 和 q 欧式空间距离 △p(p,q) 的函数(一般可以是一个高斯核),而 photometric similarity 加权函数 ws(p,q) 是 p 和 q 色彩空间欧式距离(例如CIE-Lab空间)△s(p,q) 的函数(一般也是高斯核)的话,那么联合加权函数就是 w(p,q)=wp(p,q)*ws(p,q),按照 bilateral filtering 的用法的话就是 h(p) = ∑w(p,q)f(q)/∑w(p,q),其中 q∈N(p) 即在 p 的邻域内,f(q) 是 q 的灰度或者色彩。而按照 ASW 的用法,数学上就成了 cost(p,d) = ∑w(p,q)w(pd,qd)e(q,qd)/∑w(p,q)w(pd,qd),其中 pd, qd 分别是 p 和 q 在视差 d 的支持下在匹配视图中的对应像素,w(pd,qd) 是在联合加权情况下对 qd 点的加权值,e(q,qd) 则是参考图中 q 像素和匹配视图中对应 qd 像素之间的灰度差或者色彩差,可以是 AD、SD 或者该文中的 truncated AD,详细定义见原文。
对比 BF,可以发现 BF 仅仅是利用邻域对灰度进行滤波,所以就在原图上去做就行了,只涉及到一幅图;而 ASW 的目的则是要计算像素 p 在视差 d 时的 matching cost,牵扯到了两幅视图,因此出于对称性的考虑,参与 ASW matching cost 计算的在参考图和匹配图中的两个窗口内的元素都有各自的加权,即 w(p,q) 和 w(pd,qd),并且很显然 ASW 是对灰度差或色彩差即 AD、SD 或者 truncated AD 进行滤波,而不是像 BF 原文中那样仅仅对灰度或色彩进行滤波,说白了 ASW 本质上就是对 AD、SD or truncated AD 进行了 bilateral filtering,是对简单的 SAD、SSD or STAD matching costs 的一种改进。
该文中在计算得到 ASW matching cost 以后采用的是 WTA 的 local 机制来生成 disparity map,但是这种 matching cost 显然也可以加入 global optimization 机制。
15. Marching Cubes: A High Resolution 3D Surface Construction Algorithm, (completely read on 25th May 2014).
这是一篇 1987 年 ACM Siggraph Computer Graphics 的文章,作者是 William E. Lorensen 和 Harvey E. Cline,这篇文章现在的引用次数是 10486 次。。。我查了查 Lowe 的 SIFT IJCV 从 2004 年发表到现在的引用次数是 24000 多次,该文还是不及伟大的 Lowe 哈。
回归正题,别看该文名字里有 3D surface construction,其实它跟我们现在理解的三维表面重建还是不一样的,准确来说该文提出是一种从原始 3D original data or volume 中提取 三维等值面 isosurface 的方法,也就是说在一个三维数据中,把等于用户指定值的 surface 给提取出来,输出的是连通的 triangulated meshes。文章在其摘要中就声称该算法主要是面向三维医学数据,像核磁共振成像扫描得到的人体三维图像切片等,这种医学数据就是典型的三维离散数据,里面的单元是一个一个 voxel,也就是三维像素,每个 voxel 也有一个强度值,也就是 intensity,原文中说成是 density。我记得以前张老师叫我处理过一组这样的脑部切片图像,它里面不同的人体组织有不同的灰度值,骨骼一般灰度值比较高,软组织灰度值就比较低,显得较暗,但同一组织在不同切片图像上的灰度响应是一致的,比方说我们想从这样的三维数据中提取出整个人体骨骼的 surface,已知骨骼外边缘的灰度值恒为 255,那么我们就只需把每个切片图像中灰度值为 255 的像素取出来就行了,但是简单的这样做只能是得到彼此不相关联的一个个封闭的 curves,不在相邻切片图像间建立联系的话就这些独立的 curves 是无法重构出骨骼 surface 的,那么文章的方法就是每次同时考虑相邻的两层切片图像,上下对应各取 2×2=4 个像素,共 8 个像素组成一个 cube,这 8 个像素每个像素都和骨骼的灰度 255 去比较,也就是说每个像素会有 0 和 1 两种状态,真正的 bone surface 会切过该 cube 中那些一端灰度比 255 小,一端比 255 大的边,这个还是比较好理解的。
文中对 surface 和 cube 相交的形式总结归纳出了一下 15 种:
文中还提到要估计 triangle 每个 vertices 的法向值,我得说明一下的是,它这里的法向值其实是指的灰度法向值,而不是三维坐标法向值,其实想一想都已经得到 triangle 每个点的三维坐标了还有必要再显式的算一遍该 triangle 的表面法向吗?貌似没这个必要了。Anyway,文中算 vertex 灰度法向的方法是跟算其三维坐标的方法一样的,即先通过简单的中心差分得到 vertex 所在边两端像素的灰度梯度,然后再通过线性插值出该 vertex 的灰度梯度。等值面的法向其实可以用灰度梯度方向代替,这很好理解,等值面本身是灰度等值的面,灰度变化的主方向应该是和灰度等值面的法向方向一致的,这在二维图像上就能容易理解,二维图像上提取的等值曲线在某点的法向正是该点处灰度梯度的方向。
我还下了两篇有关等值面提取的文章 Octree-Based Decimation of Marching Cubes Surfaces 和 A Modified Look-Up Table for Implicit Disambiguation of Marching Cubes 都是对 Marching Cubes 方法进行了拓展或者改进,后面有空了可以再看一看。
16. A Volumetric Method for Building Complex Models from Range Images, (completely read on 26th May 2014).
该文是 M. Goesele 的 Multi-View Stereo Revisited 一文中使用的 depth fusion 方法的出处,作者是当时还就读于 Stanford University 的 Brian Curless 和 Marc Levoy,B. Curless 现在在 University of Washington 任教授。
总的来说该文的方法是一种对多个 depth maps 进行融合的方法,基本方式就是先利用所有 depth maps 的 depth 信息及其对应的不确定度来 render 一个 3D discrete volume,该 volume 表示了一个 cumulative weighted signed distance function,每一个单独的 depth map 可以用其对应的 signed distance function render 一次该 volume 中的每一个 voxel,所有的 signed distance function 按权重加权累加起来就得到该 cumulative weighted signed distance function,文章最终要提取的 surface 就是该 CWSDF volume 中的等于 0 的等值面,提取该等值面的方法正是文献【15】中的 Marching Cubes,还有 A Modified Look-Up Table for Implicit Disambiguation of Marching Cubes 一文的改进方法。要注意的是用 Marching cubes 方法提取的等值面就已经是 trianglated meshes surface 了。下面摘录一下文章的摘要,注意其称本文方法在最小二乘意义上是最优的。
文章的前言部分把 surface reconstruction from dense range data 方法分成两大类,一类是 reconstruction from unorganized points 一类则是 reconstruction that exploits the underlying structure of the acquired data。前者指的是对这些 unorganized points 之间的连通性没有任何的先验信息,而后者则是利用了数据本身的一些结构信息,比方说我的数据本身是一个 range image 的话,那么我每一个深度点属于一个像素,它和其 8-邻域 中的各像素间自然就存在连通性了,这就是可以加以利用的重要信息。这两大类方法按照其是构建 parametric surfaces 还是 implicit function 各自又可以分为两个子类,宇翔介绍的 Hoppe 1992 的方法属于 unorganized points/implicit function 方法,而本文的方法则是 structured data/implicit function 方法,因为其要处理的工作是融合多个 range images 并提取出一个统一的 surface。下面我开始详细复述一遍上述的 cumulative weighted signed distance function or volume 是如何建立的。
拿来第一张 range image or depth map 及其每个像素对应的权重值 weight map,如何渲染其对应的 signed distance volume 和 weight volume 呢?首先利用 depth map 每个像素和其 8-邻域 连通性可以自然的将 depth map 在空间中生成一个 triangulated mesh,不过当然要避免为 depth discontinuity 分配 edge,也就是要删除那些包含 edge length 长于一定阈值的 triangles;然后采用遍历两个 volume 中每个 voxel 的方式,每个 voxel 中心和光心连接成的射线将和上面形成的 mesh 交某个 triangle 于某一个点,voxel 中心与该交点的相对矢量就是该 voxel 对应的 signed distance value,然后该 voxel 对应的 weight 就是通过空间三角线性插值出来的。我在想实际中做的话应该不用再显式的生成一个 mesh,然后算空间交点什么的,而是直接把 voxel 重投影过来得到一个亚像素坐标,该亚像素坐标的深度值可以直接利用其所属 2D triangle 的三个像素的深度值给按二维三角线性插值出来,有了深度其实也就相当于有了三维坐标了,同样也就可以得到该 voxel 的 signed distance value,其 weight value 也可以通过二维三角线性插值出来,我这想的二维三角形去插值做应该是和三维三角形插值去做是完全一样的,但其实严格来说可能不一样,因为完全一样的前提条件得是 2D triangle 中的每个像点的深度随着像素边长线性变化,之前我推过,要是深度真是随像素边长线性变化的话,其对应的空间表面将不是一个平面,而是一个凹面,所以基于这样的前提,2D triangle 在空间中将不对应一个 3D triangle,那么插值出来的深度和 weight 将会有出入,但这个出入我认为还是会很小的,毕竟一个 2D triangle 的边长也就是一整像素,这样的近似带来的误差到底有多大还得仿真看看。
上面遍历每个 voxel 之后就有了第一个 signed distance volume Di(x) 和 weight volume Wi(x),它和新来的 depth map 的 di+1(x) 及 wi+1(x) 按下式来融合得到新的 Di+1(x) 和 Wi+1(x):
第 i 个 cumulative weighted signed distance function or volume Di(x) 中的 surface 就通过 marching cubes 算法提取出 0 等值面得到。
文章后面还讲了如何做 hole filling 和 smoothing,还有预先通过 resampling depth map 让其行方向和 volume scanline 方向对齐以做快速同步扫描等,总结部分还列出了一些方法的局限性等,我只是稍作了解。看懂本文方法之后我觉得还真有可能把它给用上。
17. Surface Reconstruction from Unorganized Points, (completely read on 27th May 2014).
这就是宇翔向我推荐的 surface reconstruction 的文章,作者是 University of Washington 的 Hugues Hoppe。该文章方法面向的问题是从几乎没有任何先验信息的一堆 unorganized points 中去重建 surface,如此一来该方法从表面上看貌似适用于所有测量手段得到的点云,但也因此说明该方法应该不是针对哪种测量数据是最优的,实际上该方法也不是完全不需要先验信息的,他的算法需要知道点云的整体密度以及精度。
好,开始复述方法流程:
1、首先为所有的测量空间点找到其 knn 最邻近点,然后算其和这 k 个邻近构成的点集的 centroid O,并利用主成分分析方法算得该点集张开空间的最小特征向量,也就是对应了该点集空间的法向 n,当然由于所有数据点没有任何方位信息,因此该法向的方向还是未定的,我在想我做的空间 patch 的法向也可以这样来求得,当然要借助其与观测图像的相对关系来消除法向歧义性。文中声称该平面 (O, n) 是对真实 surface 在 O 处切平面的线性估计,还称直接用这些估计的切平面去作为最终的 surface 效果并不好,呈现出非常复杂的非流型结构 non-manifold structure,因此文中的做法是利用这些估计的切平面去构造 signed distance volume,并用 marching cubes 方法去提取其中的 zero set 等值面作为最终的 surface。
2、上面说的为每个测量点 x 都算了一个平面 (O, n),但其实其法向的方向是未定的,需要为每个切平面赋上一致的法向,否则 signed distance volume 就会是乱的,文中采用的做法是由某个法向按照邻域连接性 propagate 到其它的切平面去,首先要做的就是确定连通性,即哪些切平面之间是相连的,文中采用的是 Euclidean Minimum Spanning Tree (EMST) 结合 knn 邻域的方法建立了一种所谓的 Riemannian Graph 来表示各切平面的连通性。
3、然后开始从某个切平面传递法向到邻域切平面,文中声称法向传递的顺序有很重要的影响,他的做法是当前的切平面法向只传递给邻域中与之最平行的切平面,即 1-|ni*nj| 最小的切平面,也就是 traversing the minimal spanning tree (MST) of the graph in depth-first order。
4、接着就生成包裹了所有切平面的离散 volume 空间,对于其中的每个 voxel 都找到与其最邻近的切平面 (O, n),并在其上做投影点,如果该投影点离所有原始测量点集的距离太大,超过了先验已知的整体点密度和精度之和,说明该 voxel 应该是在 surface boundary 之外了,那么该 voxel 就被定为 undefined,后续找等值面不予考虑了,要是没超过,那么其与其投影点之间的矢量距离就被当作 signed distance value 赋给了该 voxel,遍历完该 volume 之后,signed distance volume 就生成了。
5、接下来就是利用 marching cubes 方法来做 zero set 等值面提取了,输出的就是 triangulated mesh。
和宇翔讨论的时候我们都在想一个问题,在估计完切平面之后为什么不拿原始测量点在对应的切平面上去进行投影,然后在所有投影点上去做三角化得到 mesh 作为最终的 surface?现在想想可以这么理解吧,如果这样去做的话那么跟直接拿估计的切平面当作 surface 就没区别了,而文中说过直接拿切平面做 surface 得到的是一个 non-manifold structure,效果很差,因此建立离散 signed distance volume 去找等值面,可能 marching cubes 方法可以保证形成 manifold 吧,隐性的代入了更多的平滑作用。
另外关于文献【16】方法和本文方法的不同,假设原始数据就只有一张 depth map,那么利用【16】的方法得到的结果将是就是基于该原始 depth map 生成的 triangulated mesh,因为没有多余观测,就一张 depth map,没有其它的,当然由于 marching cubes 本身对空间进行了离散,其实 marching cubes 也有些许平滑的效果,但 marching cubes 输入数据本身就是该 depth map 没有利用邻域深度数据对其进行平滑,而本文方法即使是单张 depth map,也会利用 knn 邻域点估计切平面,也就是进行了平滑,【16】中的方法主要依靠的是重复观测,没有强加邻域平滑项,且每单个测量点有自己的不确定度,从测量理论的角度来说【16】中的方法显然更符合测量原理,精度也会更高。
我还下了两篇有关等值面提取的文章 Octree-Based Decimation of Marching Cubes Surfaces 和 A Modified Look-Up Table for Implicit Disambiguation of Marching Cubes 都是对 Marching Cubes 方法进行了拓展或者改进,后面有空了可以再看一看。
16. A Volumetric Method for Building Complex Models from Range Images, (completely read on 26th May 2014).
该文是 M. Goesele 的 Multi-View Stereo Revisited 一文中使用的 depth fusion 方法的出处,作者是当时还就读于 Stanford University 的 Brian Curless 和 Marc Levoy,B. Curless 现在在 University of Washington 任教授。
总的来说该文的方法是一种对多个 depth maps 进行融合的方法,基本方式就是先利用所有 depth maps 的 depth 信息及其对应的不确定度来 render 一个 3D discrete volume,该 volume 表示了一个 cumulative weighted signed distance function,每一个单独的 depth map 可以用其对应的 signed distance function render 一次该 volume 中的每一个 voxel,所有的 signed distance function 按权重加权累加起来就得到该 cumulative weighted signed distance function,文章最终要提取的 surface 就是该 CWSDF volume 中的等于 0 的等值面,提取该等值面的方法正是文献【15】中的 Marching Cubes,还有 A Modified Look-Up Table for Implicit Disambiguation of Marching Cubes 一文的改进方法。要注意的是用 Marching cubes 方法提取的等值面就已经是 trianglated meshes surface 了。下面摘录一下文章的摘要,注意其称本文方法在最小二乘意义上是最优的。
文章的前言部分把 surface reconstruction from dense range data 方法分成两大类,一类是 reconstruction from unorganized points 一类则是 reconstruction that exploits the underlying structure of the acquired data。前者指的是对这些 unorganized points 之间的连通性没有任何的先验信息,而后者则是利用了数据本身的一些结构信息,比方说我的数据本身是一个 range image 的话,那么我每一个深度点属于一个像素,它和其 8-邻域 中的各像素间自然就存在连通性了,这就是可以加以利用的重要信息。这两大类方法按照其是构建 parametric surfaces 还是 implicit function 各自又可以分为两个子类,宇翔介绍的 Hoppe 1992 的方法属于 unorganized points/implicit function 方法,而本文的方法则是 structured data/implicit function 方法,因为其要处理的工作是融合多个 range images 并提取出一个统一的 surface。下面我开始详细复述一遍上述的 cumulative weighted signed distance function or volume 是如何建立的。
拿来第一张 range image or depth map 及其每个像素对应的权重值 weight map,如何渲染其对应的 signed distance volume 和 weight volume 呢?首先利用 depth map 每个像素和其 8-邻域 连通性可以自然的将 depth map 在空间中生成一个 triangulated mesh,不过当然要避免为 depth discontinuity 分配 edge,也就是要删除那些包含 edge length 长于一定阈值的 triangles;然后采用遍历两个 volume 中每个 voxel 的方式,每个 voxel 中心和光心连接成的射线将和上面形成的 mesh 交某个 triangle 于某一个点,voxel 中心与该交点的相对矢量就是该 voxel 对应的 signed distance value,然后该 voxel 对应的 weight 就是通过空间三角线性插值出来的。我在想实际中做的话应该不用再显式的生成一个 mesh,然后算空间交点什么的,而是直接把 voxel 重投影过来得到一个亚像素坐标,该亚像素坐标的深度值可以直接利用其所属 2D triangle 的三个像素的深度值给按二维三角线性插值出来,有了深度其实也就相当于有了三维坐标了,同样也就可以得到该 voxel 的 signed distance value,其 weight value 也可以通过二维三角线性插值出来,我这想的二维三角形去插值做应该是和三维三角形插值去做是完全一样的,但其实严格来说可能不一样,因为完全一样的前提条件得是 2D triangle 中的每个像点的深度随着像素边长线性变化,之前我推过,要是深度真是随像素边长线性变化的话,其对应的空间表面将不是一个平面,而是一个凹面,所以基于这样的前提,2D triangle 在空间中将不对应一个 3D triangle,那么插值出来的深度和 weight 将会有出入,但这个出入我认为还是会很小的,毕竟一个 2D triangle 的边长也就是一整像素,这样的近似带来的误差到底有多大还得仿真看看。
上面遍历每个 voxel 之后就有了第一个 signed distance volume Di(x) 和 weight volume Wi(x),它和新来的 depth map 的 di+1(x) 及 wi+1(x) 按下式来融合得到新的 Di+1(x) 和 Wi+1(x):
第 i 个 cumulative weighted signed distance function or volume Di(x) 中的 surface 就通过 marching cubes 算法提取出 0 等值面得到。
文章后面还讲了如何做 hole filling 和 smoothing,还有预先通过 resampling depth map 让其行方向和 volume scanline 方向对齐以做快速同步扫描等,总结部分还列出了一些方法的局限性等,我只是稍作了解。看懂本文方法之后我觉得还真有可能把它给用上。
17. Surface Reconstruction from Unorganized Points, (completely read on 27th May 2014).
这就是宇翔向我推荐的 surface reconstruction 的文章,作者是 University of Washington 的 Hugues Hoppe。该文章方法面向的问题是从几乎没有任何先验信息的一堆 unorganized points 中去重建 surface,如此一来该方法从表面上看貌似适用于所有测量手段得到的点云,但也因此说明该方法应该不是针对哪种测量数据是最优的,实际上该方法也不是完全不需要先验信息的,他的算法需要知道点云的整体密度以及精度。
好,开始复述方法流程:
1、首先为所有的测量空间点找到其 knn 最邻近点,然后算其和这 k 个邻近构成的点集的 centroid O,并利用主成分分析方法算得该点集张开空间的最小特征向量,也就是对应了该点集空间的法向 n,当然由于所有数据点没有任何方位信息,因此该法向的方向还是未定的,我在想我做的空间 patch 的法向也可以这样来求得,当然要借助其与观测图像的相对关系来消除法向歧义性。文中声称该平面 (O, n) 是对真实 surface 在 O 处切平面的线性估计,还称直接用这些估计的切平面去作为最终的 surface 效果并不好,呈现出非常复杂的非流型结构 non-manifold structure,因此文中的做法是利用这些估计的切平面去构造 signed distance volume,并用 marching cubes 方法去提取其中的 zero set 等值面作为最终的 surface。
2、上面说的为每个测量点 x 都算了一个平面 (O, n),但其实其法向的方向是未定的,需要为每个切平面赋上一致的法向,否则 signed distance volume 就会是乱的,文中采用的做法是由某个法向按照邻域连接性 propagate 到其它的切平面去,首先要做的就是确定连通性,即哪些切平面之间是相连的,文中采用的是 Euclidean Minimum Spanning Tree (EMST) 结合 knn 邻域的方法建立了一种所谓的 Riemannian Graph 来表示各切平面的连通性。
3、然后开始从某个切平面传递法向到邻域切平面,文中声称法向传递的顺序有很重要的影响,他的做法是当前的切平面法向只传递给邻域中与之最平行的切平面,即 1-|ni*nj| 最小的切平面,也就是 traversing the minimal spanning tree (MST) of the graph in depth-first order。
4、接着就生成包裹了所有切平面的离散 volume 空间,对于其中的每个 voxel 都找到与其最邻近的切平面 (O, n),并在其上做投影点,如果该投影点离所有原始测量点集的距离太大,超过了先验已知的整体点密度和精度之和,说明该 voxel 应该是在 surface boundary 之外了,那么该 voxel 就被定为 undefined,后续找等值面不予考虑了,要是没超过,那么其与其投影点之间的矢量距离就被当作 signed distance value 赋给了该 voxel,遍历完该 volume 之后,signed distance volume 就生成了。
5、接下来就是利用 marching cubes 方法来做 zero set 等值面提取了,输出的就是 triangulated mesh。
和宇翔讨论的时候我们都在想一个问题,在估计完切平面之后为什么不拿原始测量点在对应的切平面上去进行投影,然后在所有投影点上去做三角化得到 mesh 作为最终的 surface?现在想想可以这么理解吧,如果这样去做的话那么跟直接拿估计的切平面当作 surface 就没区别了,而文中说过直接拿切平面做 surface 得到的是一个 non-manifold structure,效果很差,因此建立离散 signed distance volume 去找等值面,可能 marching cubes 方法可以保证形成 manifold 吧,隐性的代入了更多的平滑作用。
另外关于文献【16】方法和本文方法的不同,假设原始数据就只有一张 depth map,那么利用【16】的方法得到的结果将是就是基于该原始 depth map 生成的 triangulated mesh,因为没有多余观测,就一张 depth map,没有其它的,当然由于 marching cubes 本身对空间进行了离散,其实 marching cubes 也有些许平滑的效果,但 marching cubes 输入数据本身就是该 depth map 没有利用邻域深度数据对其进行平滑,而本文方法即使是单张 depth map,也会利用 knn 邻域点估计切平面,也就是进行了平滑,【16】中的方法主要依靠的是重复观测,没有强加邻域平滑项,且每单个测量点有自己的不确定度,从测量理论的角度来说【16】中的方法显然更符合测量原理,精度也会更高。
2014年4月13日星期日
关于后期工作的开展
正所谓七分研究三分总结,现严格日常时间的安排为:
09:30-17:30 算法研究和代码编写;
18:30-21:30 文字总结。
这一周的任务是把脚步停下来,回头总结这一段时间的工作,形成类似于 technical report的详细文字描述,并把疑问和自己设想的解决方案列出来,目标就是要通过文字描述把 Clive, Christos and Chunsun 拉入到我的思维轨道上来,这样后面的讨论我想会轻松很多很多。
09:30-17:30 算法研究和代码编写;
18:30-21:30 文字总结。
这一周的任务是把脚步停下来,回头总结这一段时间的工作,形成类似于 technical report的详细文字描述,并把疑问和自己设想的解决方案列出来,目标就是要通过文字描述把 Clive, Christos and Chunsun 拉入到我的思维轨道上来,这样后面的讨论我想会轻松很多很多。
Captain America 2 at IMAX Melbourne Museum
午饭后,和得糠、宇翔一行三人散步至 Melbourne Museum,正好聊起近来热映的大片 Captain America 2,心想干脆去这个全球第三大的 IMAX 电影院看下有没有票,结果心头一热直接和得糠一人买了一张,宇翔晚上还有事就没买票,买的下午三点场,有点早,有点困。电影还没开始,我就已经被片头的各种电影预告片给彻底征服了,这3D效果,万达的 IMAX 貌似还真赶不上了,刺激,对美国队长这部电影我不做过多的评价,肯定又是一部会被很快遗忘的电影。。。再加上没有字幕,只恨自己英语听力还是不过关啊,真真是枉看了这么多美国片了。。。
2014年4月12日星期六
关于 visual studio 2010 intellisense cannot open source file "stdafx.h" 的解决方法
下午将近要离开实验室的时候,我尝试着使用 namespace
来把我自己的代码纳入统一的命名空间,以免和其它同名的全局函数产生冲突,另外还新建了一个 calib3d 的 .cpp,新建完之后发现自己新建立的
.h 和 .cpp 都在工程目录下,包括之前新建的 typedef 的
.cpp,于是想当然的在系统目录下新建了个新的专属自己代码库的文件夹,并把所有自己的 .cpp 和 .h
都挪了进去,这一挪可就出问题了,自己代码所有的 .cpp 文件中 #include "stdafx.h" 都被 IDE 的
IntelliSense 提示说 cannot open source file "stdafx.h",.cpp 里要是真不能 include
stdafx.h 也就意味着基本上工程中定义的所有的 struct class 等都不能识别了,都是 undefined 的,但是令人困惑的是
compile 能顺利通过,仅仅是 IntelliSense
的各种提示功能不能正常工作,不能识别各种结构,本来想这样的话,干脆别深究,就将就着算去,但是后来看看那一道道提示 error
的红线感觉实在闹心,就决心一定要查个明白,google 了老半天才终于在下面这个 msdn 的 blog 中找到了答案:
http://blogs.msdn.com/b/vcblog/archive/2010/02/19/improving-c-intellisense-performance-with-pch.aspx?PageIndex=2
其中 Windows C++ Team 的 Ulzii Luvsanbat 这样解释道:
The reason why build compiler succeeded when intellisense failed on #include "stdafx.h" is because you were still using PCH for the project and the new file inherited that property. So, when build compiler sees #include "stdafx.h" it automatically loads the .pch file without doing any look-up for the actual header file. Once PCH is loaded, all symbols resolve and build succeeds. If you turn-off PCH for the project and do a Re-Build, you will see a compiler error in the output that's same as the Intellisense squiggle error.
When you add #include "stdafx.h" to any file the compiler or intellisense parser will follow the lookup heuristic of searching current directory and then searching INCLUDE path. In both cases stdafx.h will not found because it's in the $(ProjectDir) folder and your source is in a different folder. One easy way fix this in your project would be to add $(ProjectDir) to your Include Directories under "VC++ Directories" property.
他的意思简单点说就是,当 .cpp 文件不在工程目录中时,IntelliSense Parser 就会在 .cpp 当前的文件夹中去找 .cpp 中所包含的 stdafx.h,结果发现找不到,然后接着又在 INCLUDE path 里面去找,发现也找不到,因为 stdafx.h 是在工程目录下的,当 .cpp 和 stdafx.h 同在工程目录中时,这就没有问题,但一旦不在一个目录 IntelliSense Parser 就会找不到 stdafx.h 了,所以当我把之前在工程目录中的 typedef.cpp 挪过来的时候会出现这样的问题,而之前都没有,解决方法就是在 "VC++ Directories" 的 Include Directories 中添加 $(ProjectDir),这个路径应该就是工程自己的路径了。经过自己一试发现问题果然没了,problem solved。
(这其实是我在Blogbus上于14年3月3号发布的一篇博文,现在转移到这里来)
http://blogs.msdn.com/b/vcblog/archive/2010/02/19/improving-c-intellisense-performance-with-pch.aspx?PageIndex=2
其中 Windows C++ Team 的 Ulzii Luvsanbat 这样解释道:
The reason why build compiler succeeded when intellisense failed on #include "stdafx.h" is because you were still using PCH for the project and the new file inherited that property. So, when build compiler sees #include "stdafx.h" it automatically loads the .pch file without doing any look-up for the actual header file. Once PCH is loaded, all symbols resolve and build succeeds. If you turn-off PCH for the project and do a Re-Build, you will see a compiler error in the output that's same as the Intellisense squiggle error.
When you add #include "stdafx.h" to any file the compiler or intellisense parser will follow the lookup heuristic of searching current directory and then searching INCLUDE path. In both cases stdafx.h will not found because it's in the $(ProjectDir) folder and your source is in a different folder. One easy way fix this in your project would be to add $(ProjectDir) to your Include Directories under "VC++ Directories" property.
他的意思简单点说就是,当 .cpp 文件不在工程目录中时,IntelliSense Parser 就会在 .cpp 当前的文件夹中去找 .cpp 中所包含的 stdafx.h,结果发现找不到,然后接着又在 INCLUDE path 里面去找,发现也找不到,因为 stdafx.h 是在工程目录下的,当 .cpp 和 stdafx.h 同在工程目录中时,这就没有问题,但一旦不在一个目录 IntelliSense Parser 就会找不到 stdafx.h 了,所以当我把之前在工程目录中的 typedef.cpp 挪过来的时候会出现这样的问题,而之前都没有,解决方法就是在 "VC++ Directories" 的 Include Directories 中添加 $(ProjectDir),这个路径应该就是工程自己的路径了。经过自己一试发现问题果然没了,problem solved。
(这其实是我在Blogbus上于14年3月3号发布的一篇博文,现在转移到这里来)
关于C语言如何确定不比输入int值小的能被16整除的数
通过位操作最为方便快捷:
int x;
int y = (x+15) & ~15;
y 就是不比 x 小的离 x 最近的能被 16 整除的数
15 的二进制位为 0000 0000 0000 1111,因此 ~15 为 1111 1111 1111 0000,进行与操作可以保证 16 的倍数全被保留下来,+15 是为了保证 y 不比 x 小。
int x;
int y = (x+15) & ~15;
y 就是不比 x 小的离 x 最近的能被 16 整除的数
15 的二进制位为 0000 0000 0000 1111,因此 ~15 为 1111 1111 1111 0000,进行与操作可以保证 16 的倍数全被保留下来,+15 是为了保证 y 不比 x 小。
放弃Blogbus,转战Blogger
来到猫本后一直保有记博客的习惯,主要是记录自己的科技文献读后感还有一些程序编写上小技巧。Blogbus貌似有一套严格的文字审查制度,有很多的文字组合都被其视为敏感词汇,其实很多都是虚警,但一旦被其发现存在敏感词汇你的博客就必须提交审核通过后才能正式发布,而且在审核通过前就连用户自己都查看不了被锁定的博客,我对此表示很无语,甚至于前两天发现自己有超过一半的博客都被锁定,直至联系客服才给最终解锁,无奈只得是从中脱身而另觅根据地了。。。
So, Blogger, here I am.
So, Blogger, here I am.
订阅:
博文 (Atom)