本發(fā)明涉及計算機視覺的技術(shù)領(lǐng)域,更具體地,涉及基于cuda實現(xiàn)的實時立體匹配及優(yōu)化的方法。
背景技術(shù):
立體視覺是計算機視覺中的一個重要課題,它可以使得人們獲取到物體和場景中的深度信息,是后期3d重建和內(nèi)容分析的基礎(chǔ)。立體匹配是立體視覺的關(guān)鍵技術(shù)之一,通過標(biāo)定好的雙目相機拍攝的左右圖片,經(jīng)過矯正對齊之后,立體匹配是直接獲取視差信息的關(guān)鍵性步驟。
立體匹配的直接目的是獲取精確的視差信息,而匹配的精確度和時效性是衡量匹配方法的標(biāo)準(zhǔn),如何平衡精準(zhǔn)度和時效性是一個重要的課題。目前主流的立體匹配方法分為局部匹配,半全局匹配和全局匹配三種,精準(zhǔn)度依次增加,同時消耗的時間也依次增加。
半全局匹配在精準(zhǔn)度和時效性平衡性較好,因此我們采用半全局匹配,并著力提高精準(zhǔn)度,降低運行時間。
在前景和后景的邊緣部分,精準(zhǔn)度難以把握,如何在前景膨脹和噪點中取舍得到好的效果是提高精確性的重要因素。
通過對圖像進行超像素平面分割,是前后景邊緣分割的重要手段,而分割方法也是計算機視覺領(lǐng)域的研究熱點之一,在圖像處理,對象識別中也有大量應(yīng)用。通過快速而準(zhǔn)確的超像素平面塊分割,擬合,顯著提高了視差的精確度。
gpgpu是gpu進行大規(guī)模計算的技術(shù),而cuda是nvida公司提供的gpgpu架構(gòu),gpu具有遠高于cpu的浮點運算能力和內(nèi)存帶寬,有高度的并行性,不同于cpu程序只能一個一個的順序執(zhí)行,gpu的硬件設(shè)計支持多任務(wù)共享,程序可以通過多個線程同時運行。
因此將程序通過cuda運行在gpu上,能極大縮短運行時間,提高時效性。
目前尚未發(fā)現(xiàn)在具備高精確度并且能輸出實時的視差圖的專利或者文獻。
技術(shù)實現(xiàn)要素:
本發(fā)明為克服上述現(xiàn)有技術(shù)所述的至少一種缺陷,提供基于cuda實現(xiàn)的實時立體匹配及優(yōu)化的方法,是兼顧精準(zhǔn)和實時的立體匹配方法,加入了超像素分割用以擬合視差平面提高精確性,降低誤匹配幾率,利用了cuda多線程并行化設(shè)計,將原本的算法程序計算時間由秒級別降低到毫米級別,能夠達到實時的密集匹配。
本發(fā)明的技術(shù)方案:基于cuda實現(xiàn)的實時立體匹配及優(yōu)化的方法,其中,包括以下步驟:
s1.選定一個框大小,對左右圖像除邊緣部分的每個像素都做census轉(zhuǎn)換為字符序列;
s2.在給定的視差范圍內(nèi),選定左圖像素點,遍歷右圖范圍內(nèi)各個字符序列,計算漢明碼距,得到初始的cost;
s3.路徑聚合,通過動態(tài)規(guī)劃找到每一個點的路徑聚合值最小,得到能量函數(shù);
s4.用wta選取能量函數(shù)最小所對應(yīng)的視差值;
s5.左右一致性檢查進行后期校驗,得到初始的密集視差圖;
s6.將左圖每個像素由rgb顏色空間轉(zhuǎn)換為cielab顏色空間;
s7.通過k-means聚合算法劃分出超像素平面塊,迭代幾次直至收斂,并融合超像素平面塊;
s8.對每個超像素平面多次采樣,計算平面參數(shù);
s9.用得到的平面參數(shù)計算得到新的視差值;
s10.對新的視差做插值運算,減小黑色塊,平滑視差圖。
基于cuda的編程算法都運用到以上步驟中。
與現(xiàn)有技術(shù)相比,有益效果是:在本發(fā)明中,多次使用cuda流,共享內(nèi)存塊,線程同步,多線程共享并行化設(shè)計,并且優(yōu)化了數(shù)據(jù)結(jié)構(gòu),都極大提高了運算效率。在對左右圖像進行census轉(zhuǎn)換,計算漢明碼距得出cost,用動態(tài)規(guī)劃法優(yōu)化路徑聚合的能量值,得到初始的密集視差圖,基于對超像素平面的理解,用k-means聚類收斂得到各個超像素塊,將每個超像素塊看成是一個平面,我們計算出平面參數(shù)用于擬合新的視差值。整個一套流程因為有超像素分割和平面擬合的加入,使得視差圖結(jié)果精確性得以提高,而選擇使用cuda并行化編程也使得實時性得到了保證,因此本發(fā)明在精確性和時效性方面做到了很好的平衡,這在目前來看并沒有別的文獻和專利做到過。
附圖說明
圖1表示整套算法的流程圖。
圖2表示路徑聚合使用8條cuda流并行時線程格的分配和計算方式。
圖3表示k-means聚合得到的分割圖。
圖4表示最終生成的視差圖渲染圖。
具體實施方式
附圖僅用于示例性說明,不能理解為對本專利的限制;為了更好說明本實施例,附圖某些部件會有省略、放大或縮小,并不代表實際產(chǎn)品的尺寸;對于本領(lǐng)域技術(shù)人員來說,附圖中某些公知結(jié)構(gòu)及其說明可能省略是可以理解的。附圖中描述位置關(guān)系僅用于示例性說明,不能理解為對本專利的限制。
cuda使用線程格管理線程,核函數(shù)的每個副本都可以通過內(nèi)置變量blockidx來確定線程塊的索引,griddim得到線程塊的數(shù)量,blockdim得到線程的數(shù)量,使用不同的griddim和blockdim是獲得不同并行化程度的關(guān)鍵。當(dāng)需要多個線程塊并且每個線程塊又包含多個線程時,索引計算方法為:inttid=threadidx.x+blockidx.x*blockdim.x;得到正確的索引tid才能定位到我們需要處理的線程,建立起映射關(guān)系,具體見圖2.
gpu的內(nèi)存結(jié)構(gòu)中可讀寫的有:寄存器、共享內(nèi)存和全局內(nèi)存。cuda上下文切換機制非常高效,幾乎是零開銷,訪問寄存器的速度是非??斓?,所以應(yīng)盡量優(yōu)先使用寄存器。cuda共享內(nèi)存緩沖區(qū)駐留在物理gpu上,所以訪問速度也很快,共享內(nèi)存的存在就可使運行線程塊中的多個線程之間相互通信。全局內(nèi)存因為gpu與cpu都可以對它進行寫操作,速度較慢。因此在cuda編程中,合理使用各種內(nèi)存方式能夠有效的提高效率和運行速度。
cuda可以使用線程同步機制__syncthreads();對線程塊中的線程進行同步。該函數(shù)可以確保同一線程塊中的所有線程在執(zhí)行完該語句之前的所有語句之后才會執(zhí)行其下一條語句,一般會和共享內(nèi)存搭配出現(xiàn)。
我們也采用了cuda流的方式,cuda流表示一個gpu操作隊列,并且該隊列中的操作以添加到隊列的先后順序執(zhí)行。使用cuda流可以實現(xiàn)任務(wù)級的并行,內(nèi)核函數(shù)之間可以并行處理,當(dāng)gpu在執(zhí)行核函數(shù)的同時,還可以在主機和設(shè)備之間交換數(shù)據(jù)。
步驟一中,我們選取的是n*m的塊大小進行census轉(zhuǎn)換。在cuda程序中,選取了16*16的線程塊,以方便后面用共享內(nèi)存提高效率,圖片的寬度是width,高度是height,選取的kernel大小分別是((width+15)/16,(height+15)/16)。共享內(nèi)存的大小是(n+16)*(m+16),先將數(shù)據(jù)從全局內(nèi)存復(fù)制到共享內(nèi)存,然后進行census轉(zhuǎn)換,轉(zhuǎn)換后同步線程,將字符串結(jié)果保存在gpu全局內(nèi)存中。census轉(zhuǎn)換的思想是將選中的像素點,假設(shè)為(x,y)點的灰度值與它鄰域塊大小的各個像素點的灰度值進行比較,比(x,y)大的設(shè)為0,小的為1。
步驟二中,我們選取的視差范圍是d,在cuda中選取32*8大小的線程塊,使用(32+d)*8大小的共享內(nèi)存,先將步驟一中得到每個像素點的字符序列從gpu全局內(nèi)存復(fù)制到共享內(nèi)存中,然后從右圖中找d個視差范圍內(nèi)對應(yīng)的字符序列,通過異或操作計算兩對字符序列的漢明碼距。漢明碼距表示兩個相同長度字對應(yīng)位不同的數(shù)量,我們以d(x,y)表示兩個字x,y之間的漢明距離。對兩個字符串進行異或運算,并統(tǒng)計結(jié)果為1的個數(shù),那么這個數(shù)就是漢明碼距。遍歷d個視差,選擇漢明碼距最小的視差存儲到全局內(nèi)存中,得到我們需要的初始的cost值。
步驟三中,路徑聚合是為了優(yōu)化能量函數(shù)從而查找到最小化的能量函數(shù)以確定視差值。
lr(p,d)=c(p,d)+min(lr(p-r,d),
lr(p-r,d-1)+p1,lr(p-r,d+1)+p1,
在上述公式中,c(p,d)就是上個步驟我們得到的在p點視差為d時對用的cost值。而lr(p,d)則表示在盤點在r路徑上視差為d的路徑cost和值,表述為每一個點的代價聚合值是“當(dāng)前代價+min(路徑相鄰點的當(dāng)前視差代價聚合值,路徑相鄰點的視差差值為1的代價聚合值+p1,路徑相鄰點的視差插值大于1的最小代價聚合值+p2)-路徑相鄰點的視差插值大于1的最小代價聚合值”,最后那一項是為了防止數(shù)字過大而設(shè)置。其中p1,p2分別是相鄰像素點視差值相差為1,和大于1的懲罰系數(shù),加入這兩個正則化項是為了保證視差圖平滑同時保持邊緣。p1是對物體不平整表面的適應(yīng),p2是對灰度不連續(xù)(可能是多個物體)的適應(yīng)。
想在2d的圖像找到使得cost聚合值最小的視差圖是個np-hard的問題,那么單獨在某方向r上(比如從左到右,從右到左等)選擇匹配點的路徑使得cost聚合值最小(即最終l最小),該問題就變成多項式時間內(nèi)可以解決的。我們采用具有全局性質(zhì)的動態(tài)規(guī)劃算法來優(yōu)化計算出最小值。若要使p的代價想要最小,那么前提必須是鄰域內(nèi)的點q的代價最小,q想要代價最小,那么必須保證q的鄰域點m的代價最小,如此傳遞下去分而治之得出最小值。
如果我們只沿著每一行求解,那么行間的約束完全考慮不到,q是p的鄰域的點其實這個時候被弱化到了q是p的左側(cè)點或者右側(cè)點,這樣的求優(yōu)效果差并且會出現(xiàn)長尾效應(yīng)。于是,我們選擇采用8個方向路徑進行優(yōu)化。也就是r=8,最后結(jié)果是8條路徑的聚合值,也就是我們要求的能量函數(shù)。
在我們實現(xiàn)的程序中,使用了8個cuda流,在kernel函數(shù)執(zhí)行的同時,還可以傳輸數(shù)據(jù),并且各個路徑能同時進行運算,以便提高效率,分別使用了4個32*8大小的block,(height/8,1)大小的grid來計算水平路徑和垂直路徑,使用了4個32*8大小block,((height+width)/8,1)大小的grid來計算斜向路徑,使用了32*8大小的共享內(nèi)存來存儲像素點的路徑聚合cost值,在求取最小值時采用并行規(guī)約和syncthreads線程同步的方法,極大減小了線程束的分化,并且在循環(huán)中多次用pragmaunroll指令使得循環(huán)充分展開并行操作,提高編譯器效率,圖2展示使用8個cuda流,內(nèi)核之間并行運行以及內(nèi)存空間分配的關(guān)系圖。
步驟四中,wta(winner-take-all)是一種競爭學(xué)習(xí)規(guī)則,用于無導(dǎo)師學(xué)習(xí),用在這里是指只有最小的能量值會激活使用,即選取能量值最小的視差值。在本程序里依然選用32*8大小的線程塊,128*8大小的共享內(nèi)存塊,先將上一步驟中得到的能量函數(shù)從全局內(nèi)存復(fù)制到共享內(nèi)存中,然后依次比較,將最小的結(jié)果進行并行規(guī)約以減少分支,再將視差值d保存在新的全局內(nèi)存中。
步驟五中,在視差圖中經(jīng)常會采用到后續(xù)的處理措施:左右一致性檢測。遮擋是只出現(xiàn)在一幅圖像,而在另一幅圖中看不到的那些點。遮擋點通常是一塊連續(xù)的區(qū)域,lrccheck的作用是實現(xiàn)遮擋檢測得到左圖對應(yīng)的遮擋圖像。對于左圖中的一個點p,求得的視差值是d1,那么p在右圖里的對應(yīng)點應(yīng)該是(p-d1),(p-d1)的視差值記作d2。若|d1-d2|>threshold,p標(biāo)記為遮擋點,在本程序中采用16*16的block和(width/16,height/16)大小的grid,對左右圖像遍歷,每個thread對應(yīng)一個像素點,若|d1-d2|>1,則將視差設(shè)置為0保存在全局內(nèi)存.
步驟六中,已經(jīng)進入了超像素分割平面的階段。在本發(fā)明中采用slic方法,即簡單的線性迭代聚類。分簇的依據(jù)是像素之間的顏色相似性與鄰近性,將彩色圖像轉(zhuǎn)化為cielab顏色空間和xy坐標(biāo)下的5維特征向量,然后對5維特征向量構(gòu)造距離度量標(biāo)準(zhǔn),對圖像像素進行局部聚類的過程。因此首先要將圖像從rgb色彩空間轉(zhuǎn)換到cielab色彩空間。首先rgb到xyz的轉(zhuǎn)換:
[x,y,z]=[m]*[r,g,b],其中m為一3x3矩陣:
xyz到lab的轉(zhuǎn)換:
l=116*f(y1)-16
a=500*(f(x1)-f(y1))
b=200*(f(y1)-f(z1))
其中f是一個類似gamma函數(shù)的校正函數(shù):
當(dāng)x>0.008856時,f(x)=x^(1/3);
當(dāng)x<=0.008856時,f(x)=(7.787*x)+(16/116)
x1、y1、z1分別是線性歸一化之后的xyz值。
在cuda程序中,使用16*16大小的線程塊,使得每一個像素都對應(yīng)一個thread線程,每個thread都進行上述函數(shù)變化,計算效率基本上達到理論峰值,之后再將得到的值保存在gpu的lab全局變量中。
步驟七中,k-means算法是一種簡單高效并且應(yīng)用廣泛的簇聚類方法其主要是來計算數(shù)據(jù)聚集的算法,主要通過不斷地取離種子點最近均值的算法。將圖片初始化分割n塊超像素,并將n個簇心點lab信息和xy坐標(biāo)保存在gpu全局內(nèi)存中,使用w*h大小的block,每個thread對應(yīng)一個像素點,都查找2w*2h區(qū)域類的簇心點信息,計算lab色彩信息和兩個點位置之間的歐氏距離,每個thread將最小的歐氏距離的簇心點更新復(fù)制到全局內(nèi)存,迭代多次直到收斂;
dlab=(plab.x-clab.x)2+(plab.y-clab.y)2+(plab.z-clab.z)2
dxy=(pxy.x-cxy.x)2+(pxy.y-cxy.y)2
d=dlab+w*dxy
以上公式dlab表示在lab色彩空間中p點與2w*2h區(qū)域內(nèi)c點即簇心點的歐式距離平方和,dxy表示在圖片中p點與簇心點c的坐標(biāo)的歐氏距離平方和,w是一個權(quán)重參數(shù),每個像素更新后的簇心點的信息即為平面標(biāo)簽。設(shè)置一個閾值,小于這個閾值的超像素平面會跟周圍的平面計算平均lab色彩距離,距離最小的進行平面融合。圖3是進行了k-means并且融合后的超像素分割圖。
步驟八中,在步驟七中已經(jīng)對圖像中每個像素都打了標(biāo)簽,表明每個像素都有對應(yīng)的超像素塊。已知三個點可以表示一個平面,所以在每個超像素塊隨機采樣3個視差值不為0且不同的點.由采樣到的三個點確定平面方程:
a=(x1×z2-x2×z1)×(y2×z3-y3×z2)-(x2×z3-x3×z2)×(y1×z2-y2×z1)
b=y(tǒng)1×z2-y2×z1;
p0=((z2×d1-z1×d2)×(y2×z3-y3×z2)-(z3×d2-z2×d3)×(y1×z2-y2×z1))/a;
p1=(z3×d2-z2×d3-p0×(x2×z3-x3×z2))/b;
p2=(d1-p0×xi-p1×yi)/zi;
以上公式表示的是計算平面參數(shù)的方程,若a<0,則平面參數(shù)p0=0,p1=0,p2=-1.若b<0,則
p1=(z3×d2-z2×d3-p0×(x2×z3-x3×z2))/b;
p2參數(shù)取決于zi的大小是否小于0,在初始化第一次求平面參數(shù)時,z均為1,(x,y,d)分別表示像素的x坐標(biāo),y坐標(biāo)和視差值。
在得到平面參數(shù)后,即可求得平面方程:s=p0×x+p1×y+p2;對剩下的平面點用方程進行擬合,找出一個平面中擬合點的個數(shù),循環(huán)多次,選取擬合點最多的平面參數(shù),保存到結(jié)果中。對所有的擬合點進行累加,得出新的參數(shù),進行新一輪的平面參數(shù)計算,并將最終結(jié)果保存在數(shù)據(jù)結(jié)構(gòu)中。
步驟九中,在步驟八中我們已經(jīng)得到了圖像中每個像素點的標(biāo)簽和平面參數(shù),因為超像素平面塊分割讓我們可以將一個平面塊認為視差值是變化很小的,因此我們用對應(yīng)的平面參數(shù)方程來代替初始的視差值,從而達到優(yōu)化的效果。新的視差方程就是:d=p0×x+p1×y+p2;如果d在[0,255]區(qū)間內(nèi)的話,就用這個新的d值代替原來初始的視差值。注意在超像素平面塊的邊緣線上,并不進行替換,依然采用初始視差值。
步驟十中,對視差圖進行插值。為了使視差圖更加平滑,我們對視差值為0的像素進行插值處理。首先找到視差值為0的區(qū)間,假設(shè)為[start,end],然后比較start-1和end+1點的視差值,將較小的那個視差值插入到[start,end]區(qū)間。經(jīng)過插值運算,在視差為0的地方過渡更加平滑,在前后景分割的邊緣因為前景膨脹而造成的黑邊也能比較好的平滑,提高了視插圖的準(zhǔn)確性。
在本發(fā)明中,我們多次使用cuda流,共享內(nèi)存塊,線程同步,多線程共享并行化設(shè)計,并且優(yōu)化了數(shù)據(jù)結(jié)構(gòu),都極大提高了運算效率。在對左右圖像進行census轉(zhuǎn)換,計算漢明碼距得出cost,用動態(tài)規(guī)劃法優(yōu)化路徑聚合的能量值,得到初始的密集視差圖,基于對超像素平面的理解,用k-means聚類收斂得到各個超像素塊,將每個超像素塊看成是一個平面,我們計算出平面參數(shù)用于擬合新的視差值。整個一套流程因為有超像素分割和平面擬合的加入,使得視差圖結(jié)果精確性得以提高,而選擇使用cuda并行化編程也使得實時性得到了保證,因此本發(fā)明在精確性和時效性方面做到了很好的平衡,這在目前來看并沒有別的文獻和專利做到過。
顯然,本發(fā)明的上述實施例僅僅是為清楚地說明本發(fā)明所作的舉例,而并非是對本發(fā)明的實施方式的限定。對于所屬領(lǐng)域的普通技術(shù)人員來說,在上述說明的基礎(chǔ)上還可以做出其它不同形式的變化或變動。這里無需也無法對所有的實施方式予以窮舉。凡在本發(fā)明的精神和原則之內(nèi)所作的任何修改、等同替換和改進等,均應(yīng)包含在本發(fā)明權(quán)利要求的保護范圍之內(nèi)。