立體視覺(jué)是計(jì)算機(jī)視覺(jué)領(lǐng)域的一個(gè)重要課題,它的目的在于重構(gòu)場(chǎng)景的三維幾何信息。立體視覺(jué)的研究具有重要的應(yīng)用價(jià)值,其應(yīng)用包括移動(dòng)機(jī)器人的自主導(dǎo)航系統(tǒng),航空及遙感測(cè)量,工業(yè)自動(dòng)化系統(tǒng)等。
1. 引言
立體視覺(jué)是計(jì)算機(jī)視覺(jué)領(lǐng)域的一個(gè)重要課題,它的目的在于重構(gòu)場(chǎng)景的三維幾何信息。立體視覺(jué)的研究具有重要的應(yīng)用價(jià)值,其應(yīng)用包括移動(dòng)機(jī)器人的自主導(dǎo)航系統(tǒng),航空及遙感測(cè)量,工業(yè)自動(dòng)化系統(tǒng)等。
一般而言,立體視覺(jué)的研究有如下三類(lèi)方法:
(1) 直接利用測(cè)距器(如激光測(cè)距儀)獲得程距(range data)信息,建立三維描述的方法;
(2) 僅利用一幅圖象所提供的信息推斷三維形狀的方法;
(3) 利用不同視點(diǎn)上的,也許是不同時(shí)間拍攝的,兩幅或更多幅圖象提供的信息重構(gòu)三維結(jié)構(gòu)的方法。
第一類(lèi)方法,也就是程距法 (range data method),根據(jù)已知的深度圖,用數(shù)值逼近的方法重建表面信息,根據(jù)模型建立場(chǎng)景中的物體描述,實(shí)現(xiàn)圖象理解功能。這是一種主動(dòng)方式的立體視覺(jué)方法,其深度圖是由測(cè)距器(range finders)獲得的,如結(jié)構(gòu)光(structured light)、激光測(cè)距器(laser range finders) 等其他主動(dòng)傳感技術(shù) (active sensing techniques)。這類(lèi)方法適用于嚴(yán)格控制下的環(huán)境(tightly controlled domains),如工業(yè)自動(dòng)化的應(yīng)用方面。
第二類(lèi)方法,依據(jù)光學(xué)成象的透視原理及統(tǒng)計(jì)假設(shè),根據(jù)場(chǎng)景中灰度變化導(dǎo)出物體輪廓及表面,由影到形(shape from shading),從而推斷場(chǎng)景中的物體。線條圖的理解就是這樣的一個(gè)典型問(wèn)題,曾經(jīng)引起了普遍的重視而成為計(jì)算機(jī)視覺(jué)研究領(lǐng)域的一個(gè)焦點(diǎn),由此產(chǎn)生了各種各樣的線條標(biāo)注法。這種方法的結(jié)果是定性的,不能確定位置等定量信息,該方法由于受到單一圖象所能提供信息的局限性,存在難以克服的困難。
第三類(lèi)方法,利用多幅圖象來(lái)恢復(fù)三維信息的方法,它是被動(dòng)方式的。根據(jù)圖象獲取方式的區(qū)別又可以劃分成普通立體視覺(jué)和通常所稱(chēng)的光流(optical flow)兩大類(lèi)。普通立體視覺(jué)研究的是由兩攝像機(jī)同時(shí)拍攝下的兩幅圖象,而光流法中研究的是單個(gè)攝像機(jī)沿任一軌道運(yùn)動(dòng)時(shí)順序拍下的兩幅或更多幅圖象。前者可以看作后者的一個(gè)特例,它們具有相同的幾何構(gòu)形,研究方法具有共同點(diǎn)。雙目立體視覺(jué)是它的一個(gè)特例。
立體視覺(jué)的研究由如下幾部分組成:
(1) 圖象獲取 (image acquisition),
用作立體視覺(jué)研究的圖象的獲取方法是多種多樣的,在時(shí)間、視點(diǎn)、方向上有很大的變動(dòng)范圍,直接受所應(yīng)用領(lǐng)域的影響。立體視覺(jué)的研究主要集中在三個(gè)應(yīng)用領(lǐng)域中,即自動(dòng)測(cè)繪中的航空?qǐng)D片的解釋?zhuān)灾鬈?chē)的導(dǎo)引及避障,人類(lèi)立體視覺(jué)的功能模擬。不同的應(yīng)用領(lǐng)域涉及不同類(lèi)的景物,就場(chǎng)景特征的區(qū)別來(lái)分,可以劃分成兩大類(lèi),一類(lèi)是含有文明特征(cultural features)的景物,如建筑、道路等; 另一類(lèi)是含有自然特征的景物和表面(natural objects and surfaces), 如山、水、平原及樹(shù)木等。不同類(lèi)的景物的圖象處理方法大不相同,各有其特殊性。
總之,與圖象獲取相關(guān)的主要因素可歸納如下:
(a) 場(chǎng)景領(lǐng)域 (scene domain),
(b) 計(jì)時(shí) (timing),
(c) 時(shí)間(照明和陰影)(time of day (lighting and presence ofshadows)),
(d) 成像形態(tài)(包括特殊的遮蓋)(photometry (including special coverage)),
(e) 分辨率 (resolution),
(f) 視野 (field of view),
(g) 攝像機(jī)的相對(duì)位置 (relative camera positioning).
場(chǎng)景的復(fù)雜程度受如下因素的影響:
(a) 遮掩 (occlusion),
(b) 人工物體(直的邊界,平的表面) (man-made objects (straight edge, flat surfaces)),
(c) 均勻的紋理區(qū)域 (smoothly textured areas),
(d) 含有重復(fù)結(jié)構(gòu)的區(qū)域 (areas containing repetitive structure)。
(2) 攝像機(jī)模型 (camera modeling),
攝像機(jī)模型就是對(duì)立體攝像機(jī)組的重要的幾何與物理特征的表示形式,它作為一個(gè)計(jì)算模型,根據(jù)對(duì)應(yīng)點(diǎn)的視差信息,用于計(jì)算對(duì)應(yīng)點(diǎn)所代表的空間點(diǎn)的位置。攝像機(jī)模型除了提供圖象上對(duì)應(yīng)點(diǎn)空間與實(shí)際場(chǎng)景空間之間的映射關(guān)系外,還可以用于約束尋找對(duì)應(yīng)點(diǎn)時(shí)的搜索空間,從而降低匹配算法的復(fù)雜性,減小誤匹配率。
(3) 特征抽取 (feature acquisition),
幾乎是同一灰度的沒(méi)有特征的區(qū)域是難以找到可靠匹配的,因而,絕大部分計(jì)算機(jī)視覺(jué)中的工作都包括某種形式的特征抽取過(guò)程,而且特征抽取的具體形式與匹配策略緊密相關(guān)。在立體視覺(jué)的研究中,特征抽取過(guò)程就是提取匹配基元的過(guò)程。
(4) 圖象匹配 (image matching),
圖象匹配是立體視覺(jué)系統(tǒng)的核心,是建立圖象間的對(duì)應(yīng)從而計(jì)算視差的過(guò)程,是極為重要的。
(5) 深度計(jì)算 (distance(depth) determination),
立體視覺(jué)的關(guān)鍵在于圖象匹配,一旦精確的對(duì)應(yīng)點(diǎn)建立起來(lái),距離的計(jì)算相對(duì)而言只是一個(gè)簡(jiǎn)單的三角計(jì)算而已。然而,深度計(jì)算過(guò)程也遇到了顯著的困難,尤其是當(dāng)對(duì)應(yīng)點(diǎn)具有某種程度的非精確性或不可靠性時(shí)。粗略地說(shuō),距離計(jì)算的誤差與匹配的偏差成正比,而與攝像機(jī)組的基線長(zhǎng)成反比。加大基線長(zhǎng)可以減少誤差,但是這又增大了視差范圍和待匹配特征間的差別,從而使匹配問(wèn)題復(fù)雜化了。為了解決這一問(wèn)題出現(xiàn)了各種匹配策略,如由粗到精策略,松馳法等。
在很多情況下,匹配精度通常是一個(gè)象素。但是,實(shí)際上區(qū)域相關(guān)法和特征匹配法都可以獲得更好的精度。區(qū)域相關(guān)法要達(dá)到半個(gè)象素的精度需要對(duì)相關(guān)面進(jìn)行內(nèi)插。盡管有些特征抽取方法可以得到比一個(gè)象素精度更好的特征,但這直接依賴(lài)于所使用的算子類(lèi)型,不存在普遍可用的方法。
另一種提高精度的方法是采用一個(gè)象素精度的算法,但是利用多幅圖象的匹配,通過(guò)多組匹配的統(tǒng)計(jì)平均結(jié)果獲得較高精度的估計(jì)。每組匹配結(jié)果對(duì)于最后深度估計(jì)的貢獻(xiàn)可以根據(jù)該匹配結(jié)果的可靠性或精度加權(quán)處理。
總之,提高深度計(jì)算精度的途徑有三條,各自涉及了一些附加的計(jì)算量:
(a) 半象素精度估計(jì) (subpixel estimation),
(b) 加長(zhǎng)基線長(zhǎng) (increased stereo baseline),
(c) 幾幅圖的統(tǒng)計(jì)平均 (statistical averaging over several views)。
(6) 內(nèi)插 (interpolation).
在立體視覺(jué)的應(yīng)用領(lǐng)域中,一般都需要一個(gè)稠密的深度圖。基于特征匹配的算法得到的僅是一個(gè)稀疏而且分布并不均勻的深度圖。在這種意義下,基于區(qū)域相關(guān)匹配的算法更適合于獲得稠密的深度圖,但是該方法在那些幾乎沒(méi)有信息(灰度均勻)的區(qū)域上的匹配往往不可靠。因此,兩類(lèi)方法都離不開(kāi)某種意義的內(nèi)插過(guò)程。最為直接的將稀疏深度圖內(nèi)插成稠密的深度圖的方法是將稀疏深度圖看作為連續(xù)深度圖的一個(gè)采樣,用一般的內(nèi)插方法(如樣條逼近)來(lái)近似該連續(xù)深度圖。當(dāng)稀疏深度圖足以反映深度的重要變化時(shí),該方法可能是合適的。如起伏地貌的航空立體照片的處理中用這種方式的內(nèi)插也許是比較合適的。但是這種方法在許多應(yīng)用領(lǐng)域中,尤其是在有遮掩邊界的圖象的領(lǐng)域中,就不適用了。
Grimson 指出可匹配特征的遺漏程度反映了待內(nèi)插表面變化程度的相應(yīng)限度,在這種基礎(chǔ)上,他提出了一個(gè)內(nèi)插過(guò)程[2]。換一角度來(lái)看,根據(jù)單幅圖象的“由影到形”的技術(shù),用已經(jīng)匹配上的特征來(lái)建立輪廓條件和光滑的交接表面可以確保內(nèi)插的有效性。這些方法結(jié)合起來(lái),可以使內(nèi)插過(guò)程達(dá)到合乎要求的目標(biāo)。內(nèi)插的另一種途徑是在已有的幾何模型與稀疏深度圖之間建立映射關(guān)系,這是模型匹配過(guò)程。一般而言,要進(jìn)行模型匹配,預(yù)先應(yīng)將稀疏深度圖進(jìn)行聚類(lèi),形成若干子集,各自相應(yīng)于一種特殊結(jié)構(gòu)。然后找每一類(lèi)的最佳對(duì)應(yīng)模型,該模型為這種特殊結(jié)構(gòu)(物體)提供參數(shù)和內(nèi)插函數(shù)。如 Gennery用這種方法來(lái)發(fā)現(xiàn)立體對(duì)圖片中的橢園結(jié)構(gòu),Moravec 用于為自主車(chē)探測(cè)地面。
2. 雙目立體視覺(jué)(Binocular Stereo Vision)
2.1 雙目立體視覺(jué)模型
雙目立體視覺(jué)理論建立在對(duì)人類(lèi)視覺(jué)系統(tǒng)研究的基礎(chǔ)上,通過(guò)雙目立體圖象的處理,獲取場(chǎng)景的三維信息,其結(jié)果表現(xiàn)為深度圖,再經(jīng)過(guò)進(jìn)一步處理就可得到三維空間中的景物,實(shí)現(xiàn)二維圖象到三維空間的重構(gòu)。Marr-Poggio-Grimson [1] 最早提出并實(shí)現(xiàn)了一種基于人類(lèi)視覺(jué)系統(tǒng)的計(jì)算視覺(jué)模型及算法。雙目立體視覺(jué)系統(tǒng)中,獲取深度信息的方法比其它方式(如由影到形方法)較為直接,它是被動(dòng)方式的,因而較主動(dòng)方式(如程距法)適用面寬,這是它的突出特點(diǎn)。
雙目立體視覺(jué)系統(tǒng)中,深度信息的獲得是分如下兩步進(jìn)行的:
(1) 在雙目立體圖象間建立點(diǎn)點(diǎn)對(duì)應(yīng),
(2) 根據(jù)對(duì)應(yīng)點(diǎn)的視差計(jì)算出深度。
第一部分,也就是對(duì)應(yīng)點(diǎn)問(wèn)題,是雙目立體視覺(jué)的關(guān)鍵; 第二部分是攝像機(jī)模型問(wèn)題。雙目立體視覺(jué)模型中,雙攝像機(jī)彼此參數(shù)一致,光軸平行且垂直于基線,構(gòu)成一共極性 (epipolar) 結(jié)構(gòu),這樣做是為了縮小對(duì)應(yīng)的搜索空間,只有水平方向的視差,簡(jiǎn)化了對(duì)應(yīng)過(guò)程,如下圖所示。
如上圖所示,設(shè)空間一點(diǎn)P(X,Y,Z)在兩個(gè)平行放置的完全相同的攝象機(jī)中像點(diǎn)分別是(x1,y1).(x2,y2),則在知道基線長(zhǎng)B和焦距f的情況下,可以計(jì)算出深度
這是雙目立體視覺(jué)的基本原理,即根據(jù)視差來(lái)恢復(fù)立體信息。
2.2 匹配基元
匹配基元是指匹配算法的最小匹配對(duì)象,它是由特征抽取算法產(chǎn)生的。在建立立體視覺(jué)系統(tǒng)時(shí),必須根據(jù)環(huán)境的特點(diǎn)和應(yīng)用的領(lǐng)域選擇適當(dāng)?shù)钠ヅ浠Fヅ浠梢允牵?br />
(1) 過(guò)零點(diǎn) (zero-crossings),
(2) 邊界與線片段 (edge and line fragments),
(3) 線性特征 (linear features),
(4) 邊緣輪廓 (object boundaries),
(5) 興趣算子抽取的特征點(diǎn)(如角點(diǎn)等)
基元作為匹配算法處理的基本單位,是局部特征,應(yīng)包含以下一些信息:
(1) 維量(點(diǎn)、線、邊界等) (dimensionality),
(2) 尺度(空間頻度,長(zhǎng)短、大小、方向等)(size (spatial frequency)),
(3) 亮度(對(duì)比度) (contrast),
(4) 語(yǔ)義量 (semantic content),
(5) 稠密度 (density of occurrence),
(6) 簡(jiǎn)單可量度的分布特征 (easily measurable attributes),
(7) 唯一性/突出性 (uniqueness/distinguishability)
2.3 匹配算法
匹配算法就是在兩幅圖象的匹配基元之間建立對(duì)應(yīng)關(guān)系的過(guò)程,它是雙目立體視覺(jué)系統(tǒng)的關(guān)鍵。實(shí)際上,任何計(jì)算機(jī)視覺(jué)系統(tǒng)中都包含一個(gè)作為其核心的匹配算法,因而對(duì)于匹配算法的研究是極為重要的。
為了比較全面地考察匹配算法,這里不妨將雙目立體視覺(jué)的匹配算法擴(kuò)展到更一般的情況來(lái)分析:假設(shè)給定兩幅同一環(huán)境的圖象,這兩幅圖象可能由于攝取的時(shí)間、方位或方式的不同而有差別,如雙目立體視覺(jué)系統(tǒng)所攝取的兩幅圖象、地圖與遙感或航測(cè)圖象等,如何找到彼此對(duì)應(yīng)的部分? 對(duì)于這個(gè)問(wèn)題,一般有兩種考慮途徑:
(1) 灰度分布的相關(guān)性,
(2) 特征分布的相似性。
因而就有兩類(lèi)算法:
(1) 基于灰度的算法 (intensity based),
(2) 基于特征的算法 (feature based)。
如果按照控制策略分,有如下幾種:
(1) 粗到精多層次結(jié)構(gòu) (coarse-to-fine,hierarchical),
(2) 引入約束條件的松馳法 (constraints, relaxation),
(3) 多級(jí)表示的決策結(jié)構(gòu) (multilevel representation)。
2.3.1 基于灰度的匹配算法
基于灰度的算法是指圖象處理中所稱(chēng)的區(qū)域相關(guān)方法 (area-correlation technique),它是解決對(duì)應(yīng)問(wèn)題的一個(gè)最直觀最簡(jiǎn)單的方法。在一幅圖象中以一點(diǎn)為中心選定一區(qū)域(窗口),在另一幅圖象中尋找與該區(qū)域相關(guān)系數(shù)最大的區(qū)域,把該找到的區(qū)域的中心認(rèn)為是原來(lái)那區(qū)域中心的對(duì)應(yīng)點(diǎn)。這里所說(shuō)的圖象包括經(jīng)過(guò)某種特殊處理如Gauss濾波后的圖象。
這種算法計(jì)算量大,但可以得到整幅圖象的視差圖。該算法對(duì)噪音很敏感,考慮到計(jì)算量,窗口不宜開(kāi)得過(guò)大,因而可能匹配的選擇較大,誤對(duì)應(yīng)可能性大,不適于灰度分布均勻的圖象,較適于灰度分布很復(fù)雜的圖象,如自然景物等。采用該方法的關(guān)鍵在于排除或減輕噪音的影響。通常采用多層次相關(guān)對(duì)應(yīng)及多幅圖象的統(tǒng)計(jì)平均處理方式來(lái)實(shí)現(xiàn)。如 D. B. Gennery [2]采用九幅圖象多級(jí)處理方式來(lái)實(shí)現(xiàn)對(duì)應(yīng)求解。
2.3.2 基于特征的匹配算法
鑒于灰度區(qū)域相關(guān)方法的局限性,現(xiàn)在大部分研究集中在這方面。在許多環(huán)境(如有線條輪廓特征可尋的人工環(huán)境 (man-made structured world))中,圖象的特征是很有規(guī)律地分布的,反映了場(chǎng)景的核心,數(shù)量少,處理方便。基于特征的匹配算法特別適用于特殊的比較簡(jiǎn)單的環(huán)境如室內(nèi)環(huán)境,具有速度快、精度高的特點(diǎn),但對(duì)于自然環(huán)境,由于缺少顯著的主導(dǎo)特征,該方法也遇到了很大困難。
基于特征的雙目立體視覺(jué)的對(duì)應(yīng)算法,通過(guò)建立所選基元的對(duì)應(yīng)關(guān)系,旨在獲取一稀疏深度圖,如果需要再經(jīng)過(guò)內(nèi)插等方法可以得到整幅深度圖。這一類(lèi)算法因各自采用的匹配基元不同而相異。概括而言,該類(lèi)匹配算法都是建立在匹配基元之間的相似性度量基礎(chǔ)上的。這種相似性度量被稱(chēng)為親合性 (affinity)[2], 它是以匹配基元的各項(xiàng)參數(shù)信息為依據(jù)的局部特征相似程度的度量。這種度量方法與攝像機(jī)模型相結(jié)合,可以大大減小匹配時(shí)的搜索空間。
由于僅利用親合性建立匹配是模糊的,可能匹配的空間仍舊很大(多對(duì)一的),因此有必要引入其它約束條件及控制策略來(lái)限制搜索空間,減小模糊程度。匹配算法中常引入的兩種約束條件及控制策略是:
(1) 共極性 (epipolar) (雙目立體視覺(jué)模型特點(diǎn)),
(2) 連續(xù)性 (continuity),
(3) 分層次的匹配策略(即由粗到精策略)(hierarchical (e.g.,coarse-fine) matching strategy)。
這種引入約束的方法實(shí)際上是將有關(guān)環(huán)境模型的知識(shí)融于算法之中。
這種算法的具體實(shí)現(xiàn),可以采用概率度量、松馳法迭代或者聚類(lèi)等模式識(shí)別算法來(lái)實(shí)現(xiàn)。作為最后結(jié)果的1-1 對(duì)應(yīng),可以利用啟發(fā)式搜索方法從已經(jīng)大大減小了的搜索空間中獲得。這部分可望能利用現(xiàn)代 AI 研究的許多手段如專(zhuān)家系統(tǒng)等研究方法,作為承上啟下,建立更高層次描述的先導(dǎo)。
可以從以下幾個(gè)角度來(lái)比較各種匹配算法,
(1) 精度 (accuracy),
(2) 可靠性(排除總體分類(lèi)誤差的程度)(reliability),
(3) 通用性(適于不同場(chǎng)景的能力)(available of performance models),
(4) 預(yù)見(jiàn)性 (predictability),
(5) 復(fù)雜性(設(shè)備及計(jì)算量的代價(jià))(complexity (cost implementation, computational requirements))。
立體視覺(jué)的匹配算法有:
(1) Marr-Poggio-Grimson算法,以過(guò)零點(diǎn)為基元,采用由粗到精的控制策略,用精度較低層次的匹配來(lái)限定精度較高層次匹配的搜索空間,最后利用連續(xù)性約束通過(guò)迭代方式實(shí)現(xiàn)匹配過(guò)程。處理對(duì)象是自然景物的雙目立體圖象。
(2) R. Nevatia-G.Medioni算法,以線片段 (segments) 為基元,以最小差別視差 (minimum differential disparity) 為基準(zhǔn),建立匹配過(guò)程。該基準(zhǔn)實(shí)際上是連續(xù)性約束的一種表現(xiàn)形式,在對(duì)應(yīng)線片段各自鄰域內(nèi)存在的對(duì)應(yīng)線片段的視差與其視差相近。處理對(duì)象是人工環(huán)境的雙目立體圖象。
(3) R. Y. Wong算法,旨在建立兩類(lèi)圖象的對(duì)應(yīng)關(guān)系,如航空照片、遙感圖象與灰度圖象之間的對(duì)應(yīng)關(guān)系。以邊界特征(edge feature)為依據(jù)采用順序的 (sequential)、多層次結(jié)構(gòu) (hierarchical structure)的搜索策略實(shí)現(xiàn)匹配過(guò)程。
(4) K. Price-R. Reddy算法,依據(jù)場(chǎng)景的線條特征模型,將自頂向下(人工智能)(top-down (artificial intelligence))與自底向上(模式識(shí)別)(bottom-up (pattern recognition)) 兩種控制策略有效地結(jié)合起來(lái),采用廣義的相關(guān)方法進(jìn)行匹配,旨在建立形態(tài)差別較大的兩幅圖象(一幅是參照?qǐng)D或參考模型,另一幅是待對(duì)應(yīng)的圖象)的對(duì)應(yīng)關(guān)系。如機(jī)場(chǎng)模型與機(jī)場(chǎng)的航空照片之間的對(duì)應(yīng)關(guān)系。
(5) C. S. Clark-A. L. Luck-C. A. McNary算法,抽取線條輪廓特征建立模型,在模型間建立對(duì)應(yīng)。適于存在較大差別的圖象的匹配。
(6) K. E. Price算法,用于在圖象間建立區(qū)域?qū)?yīng)。該算法利用區(qū)域間的相互關(guān)系,以松馳法為基本思想實(shí)現(xiàn)了多層次表示結(jié)構(gòu)下的匹配過(guò)程。突出特點(diǎn)是匹配算法考慮了圖象本身區(qū)域間的相互關(guān)系(如包含、子部分等)的匹配,具有類(lèi)似于某種語(yǔ)義網(wǎng)絡(luò)式的啟發(fā)性。
(7) R. Horaud-T. Skorads算法,以線條特征為匹配基元,每個(gè)線條特征不僅含有其本身的端點(diǎn)坐標(biāo)及方向矢量信息,而且含有它同那些與其相鄰的線條特征之間存在的相對(duì)位置及結(jié)構(gòu)關(guān)系的信息。這些特征將每幅圖象表示成為一個(gè)關(guān)系圖,根據(jù)該關(guān)系圖對(duì)于每個(gè)線條特征確定它在另一幅圖象中的可能對(duì)應(yīng)集合,以每組對(duì)應(yīng)為一結(jié)點(diǎn)構(gòu)造對(duì)應(yīng)圖,依據(jù)關(guān)系圖的相容性通過(guò)利益函數(shù)(benefit function)確定最佳對(duì)應(yīng)。它處理的對(duì)象是室內(nèi)環(huán)境的雙目立體圖象。
(8) W. Hoff-N. Ahuja算法,以過(guò)零點(diǎn)為最小特征,將特征匹配、輪廓檢測(cè)以及表面內(nèi)插這三個(gè)過(guò)程結(jié)合在一起,采用基于多層表示的由粗到精的控制策略,根據(jù)對(duì)于表面的光滑性約束重構(gòu)三維表面。這是一種與傳統(tǒng)方法大不相同的算法,適合于有紋理特征的環(huán)境如工作臺(tái)上的物品,不適合于稀疏特征環(huán)境如室內(nèi)環(huán)境。另外 S. I. Olsen提出的算法與此相似,它將表面的重構(gòu)過(guò)程(reconstruction process)結(jié)合在對(duì)應(yīng)匹配過(guò)程中,基于多重屬性用松弛法進(jìn)行匹配,逐步提高重構(gòu)的視差表面與實(shí)際的視差數(shù)據(jù)的一致性。
2.4 雙目立體視覺(jué)系統(tǒng)
雙目立體視覺(jué)經(jīng)過(guò)幾十年的研究已經(jīng)取得了顯著了成果,出現(xiàn)了各種專(zhuān)門(mén)的硬件設(shè)計(jì)和視頻速率(實(shí)時(shí))的立體視覺(jué)系統(tǒng),在理論和技術(shù)方面都比較成熟了。但是,從普遍的意義來(lái)講,由于很難徹底地解決對(duì)應(yīng)點(diǎn)問(wèn)題,具體的立體視覺(jué)系統(tǒng)一般都是有針對(duì)性的、不是普遍適用的,還無(wú)法與人類(lèi)的雙目視覺(jué)系統(tǒng)相媲美。
下圖是SRI的集成在電路板上的雙目立體視覺(jué)系統(tǒng)。CMU設(shè)計(jì)了Stereo Machine, 可以實(shí)時(shí)地獲取深度信息。
立體攝象機(jī)校準(zhǔn) Stereo Camera Calibration
三維視覺(jué)
Milan Sonka, 3D Vision
集成在電路板上的立體攝象機(jī)對(duì)SRI Stereo Engine, Stereo head onboard
立體幾何模型 SRI Stereo Geometry
雙目立體視覺(jué)Introduction to Stereo Imaging -- Theory
3. 結(jié)構(gòu)光方法(Structured Light)
將平面光束照射在物體上可以形成光帶,光帶的偏轉(zhuǎn)數(shù)據(jù)反映了物體表面的三維形狀信息,用這種方法可以精確地獲取物體的三維信息。借助于一組平行的平面光,或?qū)⑽矬w置于專(zhuān)門(mén)的旋轉(zhuǎn)工作臺(tái)上通過(guò)一束平面光,都可以利用偏轉(zhuǎn)數(shù)據(jù)直接地計(jì)算出深度信息,稱(chēng)這種方法為結(jié)構(gòu)光方法。結(jié)構(gòu)光方法適合于限制條件下,局部范圍內(nèi)需要精確測(cè)量的情況,用于不規(guī)則表面的三維建模。
結(jié)構(gòu)光方法在工業(yè)上有重要的應(yīng)用,例如從傳送帶上檢測(cè)工件,工件的逆工程(Reverse engineering);在圖形建模方面也有重要的應(yīng)用,如人體建模,包括頭部等軀體模型,雕塑造型的數(shù)字化。實(shí)際上它是三維掃描儀的基本原理。
如下圖所示的裝置,就是結(jié)構(gòu)光方法的典型事例。
詳細(xì)可見(jiàn):Our Active Stereo Vision System
4. 激光雷達(dá)與程距數(shù)據(jù)(Range Data)處理
激光雷達(dá)(Laser range finder)與結(jié)構(gòu)光方法不同,它直接利用激光光速掃描物體,通過(guò)測(cè)量光束從發(fā)出到反射回來(lái)的時(shí)間差來(lái)計(jì)算深度信息。它提供的數(shù)據(jù)是深度圖,稱(chēng)為程距數(shù)據(jù)(Range data)。激光雷達(dá)可以用于比較大范圍的測(cè)量,如移動(dòng)機(jī)器人可以用激光雷達(dá)信息來(lái)建立環(huán)境內(nèi)模型,以實(shí)現(xiàn)自主導(dǎo)航、躲避障礙等功能。
程距數(shù)據(jù)實(shí)際上就是深度圖象,結(jié)構(gòu)光方法和激光雷達(dá)得到的數(shù)據(jù)最后都是深度信息。程距數(shù)據(jù)處理主要是表面擬合,恢復(fù)物體的表面結(jié)構(gòu)。
5. 視覺(jué)臨場(chǎng)感系統(tǒng)
臨場(chǎng)感(Telepresence)技術(shù)是新一代遙操作(Teleoperation)系統(tǒng)的重要組成部分。顧名思義,它的目的就是使人從遠(yuǎn)地遙控操作時(shí)具有在現(xiàn)場(chǎng)處實(shí)地操作式的身臨其境的感覺(jué)。在理想情況下,這些感覺(jué)應(yīng)該包括人的各種感官所能感受到的感覺(jué),如視覺(jué)、聽(tīng)覺(jué)、觸覺(jué)、味覺(jué)、體位覺(jué)、力感等。
臨場(chǎng)感系統(tǒng)因其面對(duì)的任務(wù)不同,所需的現(xiàn)場(chǎng)信息有所區(qū)別,其中,視覺(jué)通常是最重要的信息之一,其次才是聽(tīng)覺(jué)、觸覺(jué)等。目前,臨場(chǎng)感技術(shù)主要涉及視覺(jué)和聽(tīng)覺(jué)。
臨場(chǎng)感遙操作系統(tǒng)的主要優(yōu)點(diǎn)是:將人與機(jī)器人有機(jī)地結(jié)合起來(lái),能夠恰到好處地發(fā)揮出各自的特長(zhǎng)。機(jī)器代替人去危險(xiǎn)或人不可能到達(dá)的區(qū)域去工作,而人的判斷能力和決策水平又明顯地提高了系統(tǒng)的整體智能水平。
如下圖所示,室外車(chē)輛上的立體攝象機(jī)將視頻信號(hào)傳回基地端,操作員通過(guò)立體眼睛觀察環(huán)行屏幕,仿佛他親自在車(chē)上一樣能夠具有身臨其境的感覺(jué)。
(參見(jiàn):艾海舟、張朋飛、何克忠、江濰、張軍宇,室外移動(dòng)機(jī)器人的視覺(jué)臨場(chǎng)感系統(tǒng),機(jī)器人,22(1):28-32,2000。)
有關(guān)立體視覺(jué)的前沿工作請(qǐng)參見(jiàn)微軟研究院張正友博士的網(wǎng)頁(yè),他是這方面的著名學(xué)者:~zhang/
參考文獻(xiàn)
1.馬松德、張正友,計(jì)算機(jī)視覺(jué)計(jì)算理論與算法基礎(chǔ),科學(xué)出版社,1998。
2.艾海舟,關(guān)于雙目立體視覺(jué)的研究,碩士論文,121頁(yè),1988.4.
3.艾海舟, 關(guān)于移動(dòng)機(jī)器人自主式系統(tǒng)的研究, 博士論文, 153頁(yè), 1991.3.
最近一直學(xué)習(xí)立體視覺(jué),寫(xiě)了很多的代碼,但是還沒(méi)整理具體的算法。使用左右兩張圖片,計(jì)算深度圖
左圖如下:
?
右圖如下:
?
//SAD算法
#include
#include
#include
using namespace std;
int GetHammingWeight(unsigned int value);
int main(){
/*Half of the window size for the census transform*/
int hWin = 11;
int compareLength = (2*hWin+1)*(2*hWin+1);
cout<<"hWin: "<
cvShowImage("Census",SADImage);
cvShowImage("MatchLevel",MatchLevelImage);
cvSaveImage("depth.jpg",SADImage);
cvSaveImage("matchLevel.jpg",MatchLevelImage);
cvWaitKey(0);
cvDestroyAllWindows();
cvReleaseImage(&leftImage);
cvReleaseImage(&rightImage);
return 0;
}
效果:
?
//SSD:
#include
#include
#include
using namespace std;
int GetHammingWeight(unsigned int value);
int main(){
/*Half of the window size for the census transform*/
int hWin = 11;
int compareLength = (2*hWin+1)*(2*hWin+1);
cout<<"hWin: "<
cvShowImage("Census",SADImage);
cvShowImage("MatchLevel",MatchLevelImage);
cvSaveImage("depth.jpg",SADImage);
cvSaveImage("matchLevel.jpg",MatchLevelImage);
cvWaitKey(0);
cvDestroyAllWindows();
cvReleaseImage(&leftImage);
cvReleaseImage(&rightImage);
return 0;
}
?
//ZSSD
#include
#include
#include
using namespace std;
int GetHammingWeight(unsigned int value);
int main(){
/*Half of the window size for the census transform*/
int hWin = 11;
int compareLength = (2*hWin+1)*(2*hWin+1);
cout<<"hWin: "<
cvShowImage("Census",SADImage);
cvShowImage("MatchLevel",MatchLevelImage);
cvSaveImage("depth.jpg",SADImage);
cvSaveImage("matchLevel.jpg",MatchLevelImage);
cout<
IplImage * leftImage = cvLoadImage("left.bmp",0);
IplImage * rightImage = cvLoadImage("right.bmp",0);
int imageWidth = leftImage->width;
int imageHeight =leftImage->height;
IplImage * NCCImage = cvCreateImage(cvGetSize(leftImage),leftImage->depth,1);
IplImage * MatchLevelImage = cvCreateImage(cvGetSize(leftImage),leftImage->depth,1);
int minDBounds = 0;
int maxDBounds = 31;
cvNamedWindow("Left",1);
cvNamedWindow("Right",1);
cvNamedWindow("Census",1);
cvNamedWindow("MatchLevel",1);
cvShowImage("Left",leftImage);
cvShowImage("Right",rightImage);
/*Census Transform */
int i,j ,m,n,k;
unsigned char centerPixel = 0;
unsigned char neighborPixel = 0;
int bitCount = 0;
unsigned int bigger = 0;
unsigned int sum =0;
unsigned int leftSquareSum = 0;
unsigned int rightSquareSum = 0;
double *matchLevel = new double[maxDBounds - minDBounds + 1];
double tempMax = 0;
int tempIndex = 0;
unsigned char* dst;
unsigned char* leftSrc = NULL;
unsigned char* rightSrc = NULL;
unsigned char leftPixel = 0;
unsigned char rightPixel =0;
unsigned char subPixel = 0;
unsigned char meanLeftPixel = 0;
unsigned char meanRightPixel = 0;
for(i = 0 ; i < leftImage->height;i++){
for(j = 0; j< leftImage->width;j++){
/*均值計(jì)算 */
for (k = minDBounds;k <= maxDBounds;k++)
{
sum = 0;
leftSquareSum = 0;
rightSquareSum = 0;
for (m = i-hWin; m <= i + hWin;m++)
{
for (n = j - hWin; n <= j + hWin;n++)
{
if (m < 0 || m >= imageHeight || n <0 || n >= imageWidth )
{
leftPixel = 0;
}else {
leftSrc = (unsigned char*)leftImage->imageData
+ m*leftImage->widthStep + n + k;
leftPixel = *leftSrc;
}
if (m < 0 || m >= imageHeight || n + k <0 || n +k >= imageWidth)
{
rightPixel = 0;
}else
{
rightSrc = (unsigned char*)rightImage->imageData
+ m*rightImage->widthStep + n;
rightPixel = *rightSrc;
}
sum += leftPixel*rightPixel;
leftSquareSum += leftPixel*leftPixel;
rightSquareSum += rightPixel*rightPixel;
}
}
matchLevel[k] = (double)sum/(sqrt(double(leftSquareSum))*sqrt((double)rightSquareSum));
}
tempMax = 0;
tempIndex = 0;
for ( m = 1;m < maxDBounds - minDBounds + 1;m++)
{
if (matchLevel[m] > matchLevel[tempIndex])
{
tempMax = matchLevel[m];
tempIndex = m;
}
}
dst = (unsigned char *)NCCImage->imageData + i*NCCImage->widthStep + j;
*dst = tempIndex*8;
dst = (unsigned char *)MatchLevelImage->imageData + i*MatchLevelImage->widthStep + j;
*dst = (unsigned char)(tempMax*255);
}
}
cvShowImage("Census",NCCImage);
cvShowImage("MatchLevel",MatchLevelImage);
cvSaveImage("depth.jpg",NCCImage);
cvSaveImage("matchLevel.jpg",MatchLevelImage);
cout
leftPixel = *pLeftPixel;
rightPixel = *pRightPixel;
if (abs(leftPixel - rightPixel) <= max12Diff)
{
Ddynamic[j + 1][k + 1] = Ddynamic[j][k] +1;
}else if (Ddynamic[j][k+1] > Ddynamic[j+1][k])
{
Ddynamic[j + 1][k + 1] = Ddynamic[j][k+1];
}else{
Ddynamic[j+1][k+1] = Ddynamic[j+1][k];
}
//cout<0 )
{
if (Ddynamic[m][n] == Ddynamic[m-1][n])
m--;
else if (Ddynamic[m][n] == Ddynamic[m][n-1])
n--;
else
{
//s[--l]=a[i-1];
pPixel = (unsigned char *)DPImage->imageData + i*DPImage->widthStep + m;
*pPixel = (n-m)*8;
l--;
m--;
n--;
}
}
//cvWaitKey(0);
}
cvShowImage("Depth",DPImage);
cvSaveImage("depth.jpg",DPImage);
cvWaitKey(0);
return 0;
}
?
//貼一張清楚的
//DP5
//引入概率公式
//
#include
#include
#include
#include
#include
#include
using namespace std;
const int Width = 1024;
const int Height = 1024;
int Ddynamic[Width][Width];
//使用鐘形曲線作為匹配概率,差值越小則匹配的概率越大,最終的要求是使匹配的概率最大,概率曲線使用matlab生成
int Probability[256] = {
255, 255, 254, 252, 250, 247, 244, 240, 235, 230, 225, 219, 213, 206, 200, 192, 185, 178, 170, 162,
155, 147, 139, 132, 124, 117, 110, 103, 96, 89, 83, 77, 71, 65, 60, 55, 50, 46, 42, 38, 35, 31, 28,
25, 23, 20, 18, 16, 14, 13, 11, 10, 9, 8, 7, 6, 5, 4, 4, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
int main()
{
IplImage * leftImage = cvLoadImage("l2.jpg",0);
IplImage * rightImage = cvLoadImage("r2.jpg",0);
//IplImage * leftImage = cvLoadImage("left.bmp",0);
//IplImage * rightImage = cvLoadImage("right.bmp",0);
int imageWidth = leftImage->width;
int imageHeight =leftImage->height;
IplImage * DPImage = cvCreateImage(cvGetSize(leftImage),leftImage->depth,1);
IplImage * effectiveImage = cvCreateImage(cvGetSize(leftImage),leftImage->depth,1);
IplImage * FilterImage = cvCreateImage(cvGetSize(leftImage),leftImage->depth,1);
unsigned char * pPixel = NULL;
unsigned char pixel;
unsigned char * pPixel2 = NULL;
unsigned char pixel2;
for (int i = 0; i< imageHeight;i++)
{
for (int j =0; j < imageWidth;j++ )
{
pPixel = (unsigned char *)DPImage->imageData + i*DPImage->widthStep + j;
*pPixel = 0;
pPixel = (unsigned char *)effectiveImage->imageData + i*effectiveImage->widthStep + j;
*pPixel = 0;
}
}
cvNamedWindow("Left",1);
cvNamedWindow("Right",1);
cvNamedWindow("Depth",1);
cvNamedWindow("effectiveImage",1);
cvShowImage("Left",leftImage);
cvShowImage("Right",rightImage);
int minD = 0;
int maxD = 31;
//假設(shè)圖像是經(jīng)過(guò)矯正的,那么每次都只是需要搜搜同一行的內(nèi)容
int max12Diff = 5;
for (int i = 0;i < imageWidth;i++)
{
Ddynamic[0][i] = 0;
Ddynamic[i][0] = 0;
}
unsigned char * pLeftPixel = NULL;
unsigned char * pRightPixel = NULL;
unsigned char leftPixel = 0;
unsigned char rightPixel =0;
int m,n,l;
int t1 = clock();
for (int i = 0 ; i < imageHeight;i++)
{
for (int j = 0; j= imageWidth)
{imageData + i*leftImage->widthStep + k;
pRightPixel= (unsigned char*)rightImage->imageData+i*rightImage->widthStep + j;
leftPixel = *pLeftPixel;
rightPixel = *pRightPixel;
//之前概率最大的點(diǎn)加上當(dāng)前的概率
Ddynamic[j + 1][k + 1] = max(Ddynamic[j][k],max(Ddynamic[j][k+1],Ddynamic[j+1][k]))
+ Probability[abs(leftPixel - rightPixel)];
/* if (abs(leftPixel - rightPixel) <= max12Diff)
{
Ddynamic[j + 1][k + 1] = Ddynamic[j][k] +1;
}else if (Ddynamic[j][k+1] > Ddynamic[j+1][k])
{
Ddynamic[j + 1][k + 1] = Ddynamic[j][k+1];
}else{
Ddynamic[j+1][k+1] = Ddynamic[j+1][k];
}*/
//cout<= 1 && n >= 1)
{
pPixel = (unsigned char *)DPImage->imageData + i*DPImage->widthStep + m;
*pPixel = (n-m)*8;
//標(biāo)記有效匹配點(diǎn)
pPixel = (unsigned char *)effectiveImage->imageData + i*effectiveImage->widthStep + m;
*pPixel = 255;
if (Ddynamic[m-1][n] >= Ddynamic[m][n -1] && Ddynamic[m-1][n] >= Ddynamic[m-1][n -1])
m--;
else if (Ddynamic[m][n-1] >= Ddynamic[m-1][n] && Ddynamic[m][n -1] >= Ddynamic[m-1][n -1])
n--;
else
{
//s[--l]=a[i-1];
// l -= Ddynamic[m][n];
m--;
n--;
}
}
//cvWaitKey(0);
}
//refine the depth image 7*7中值濾波
//統(tǒng)計(jì)未能匹配點(diǎn)的個(gè)數(shù)
int count = 0;
for (int i = 0 ;i< imageHeight;i++)
{
for (int j= 0; j< imageWidth;j++)
{
pPixel = (unsigned char *)effectiveImage->imageData + i*effectiveImage->widthStep + j;
pixel = *pPixel;
if (pixel == 0)
{
count++;
}
}
}
int t2 = clock();
cout<<"dt: "<
評(píng)論