日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

深度图的实时平滑

發(fā)布時(shí)間:2025/7/25 52 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深度图的实时平滑 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

from: http://blog.csdn.net/jiaojialulu/article/details/53192887?locationNum=12&fps=1

深度圖的實(shí)時(shí)平滑

一、背景

英文原文,使用的是第一代kinect
youtube上的演示效果

二、深度數(shù)據(jù)存在的問題

下圖是我簡單處理后的深度圖:

藍(lán)色表示采到深度值為0的點(diǎn),而其他點(diǎn)用顏色來標(biāo)識,顏色越深表示離相機(jī)越近。數(shù)據(jù)中的噪聲表現(xiàn)為藍(lán)色斑點(diǎn)在畫面上不斷出現(xiàn)和消失。一些噪點(diǎn)是由于紅外在遇到物體表面時(shí)發(fā)生散射造成的,另一些是由于離得kinect較近的物體的遮擋。
另一個(gè)限制深度數(shù)據(jù)的地方在于kinect的工作范圍(0.8m-4m)。在這個(gè)范圍之外的物體就會表現(xiàn)為無數(shù)據(jù),即深度值為0。

三、解決辦法

作者提出了像素濾波器加權(quán)移動平均兩種方法,并且能在實(shí)時(shí)的要求下達(dá)到深度圖平滑的效果。

3.1 像素濾波器

3.1.1 原理及步驟

第一步是將深度數(shù)據(jù)幀轉(zhuǎn)換為我們方便處理的形式,比如UINT16[]。

UINT16 *depthData = new UINT16[424 * 512]; m_pDepthFrame->CopyFrameDataToArray(nDepthBufferSize,reinterpret_cast<UINT16*>(depthData));
  • 1
  • 2

下面就是對一幀上的每個(gè)像素搜索,找到深度值為0的位置,我們希望除去這樣的像素,但是又不會影響精度和數(shù)據(jù)的其他特性。那么應(yīng)該如何去做呢?
我們先把深度值為0的像素定為候選濾波對象,然后看看它究竟是否符合我們?yōu)V去它的標(biāo)準(zhǔn)。我們利用它周圍的一些像素對應(yīng)的深度值來定義這個(gè)標(biāo)準(zhǔn)。我們以候選濾波像素為中心定義一個(gè)一個(gè)兩“層”的濾波器,同時(shí)用它來尋找這個(gè)濾波器框內(nèi)其他深度值非零的像素。濾波器將這些深度值做一個(gè)分布,并關(guān)注每層框內(nèi)這種像素的數(shù)量。然后將每層內(nèi)非零像素個(gè)數(shù)與一個(gè)閾值比較,進(jìn)而決定這個(gè)候選像素是否應(yīng)該被濾波。如果任意層內(nèi)非零像素的數(shù)目超過了閾值,就要將所有非零像素深度值對應(yīng)的統(tǒng)計(jì)眾數(shù)(數(shù)目最多一個(gè)深度值)應(yīng)用到候選濾波像素上,使其深度值不為0。濾波器如下圖所示:

下圖主要表明了采用眾數(shù),即濾波器框內(nèi)頻數(shù)最高的一個(gè)深度值來作為候選像素的深度值,要比直接采用框內(nèi)所有深度值的平均要更加符合實(shí)際(我覺得如果改成內(nèi)層的眾數(shù)更好)。

原文使用的是C#,我這里改為C++:

// 濾波后深度圖的緩存unsigned short* smoothDepthArray = (unsigned short*)i_result.data;// 我們用這兩個(gè)值來確定索引在正確的范圍內(nèi)int widthBound = 512 - 1;int heightBound = 424 - 1;// 內(nèi)(8個(gè)像素)外(16個(gè)像素)層閾值int innerBandThreshold = 3;int outerBandThreshold = 7;// 處理每行像素for (int depthArrayRowIndex = 0; depthArrayRowIndex<424;depthArrayRowIndex++){// 處理一行像素中的每個(gè)像素for (int depthArrayColumnIndex = 0; depthArrayColumnIndex < 512; depthArrayColumnIndex++){int depthIndex = depthArrayColumnIndex + (depthArrayRowIndex * 512);// 我們認(rèn)為深度值為0的像素即為候選像素if (depthArray[depthIndex] == 0){// 通過像素索引,我們可以計(jì)算得到像素的橫縱坐標(biāo)int x = depthIndex % 512;int y = (depthIndex - x) / 512;// filter collection 用來計(jì)算濾波器內(nèi)每個(gè)深度值對應(yīng)的頻度,在后面// 我們將通過這個(gè)數(shù)值來確定給候選像素一個(gè)什么深度值。unsigned short filterCollection[24][2] = {0};// 內(nèi)外層框內(nèi)非零像素?cái)?shù)量計(jì)數(shù)器,在后面用來確定候選像素是否濾波int innerBandCount = 0;int outerBandCount = 0;// 下面的循環(huán)將會對以候選像素為中心的5 X 5的像素陣列進(jìn)行遍歷。這里定義了兩個(gè)邊界。如果在// 這個(gè)陣列內(nèi)的像素為非零,那么我們將記錄這個(gè)深度值,并將其所在邊界的計(jì)數(shù)器加一,如果計(jì)數(shù)器// 高過設(shè)定的閾值,那么我們將取濾波器內(nèi)統(tǒng)計(jì)的深度值的眾數(shù)(頻度最高的那個(gè)深度值)應(yīng)用于候選// 像素上for (int yi = -2; yi < 3; yi++){for (int xi = -2; xi < 3; xi++){// yi和xi為操作像素相對于候選像素的平移量// 我們不要xi = 0&&yi = 0的情況,因?yàn)榇藭r(shí)操作的就是候選像素if (xi != 0 || yi != 0){// 確定操作像素在深度圖中的位置int xSearch = x + xi;int ySearch = y + yi;// 檢查操作像素的位置是否超過了圖像的邊界(候選像素在圖像的邊緣)if (xSearch >= 0 && xSearch <= widthBound &&ySearch >= 0 && ySearch <= heightBound){int index = xSearch + (ySearch * 512);// 我們只要非零量if (depthArray[index] != 0){// 計(jì)算每個(gè)深度值的頻度for (int i = 0; i < 24; i++){if (filterCollection[i][0] == depthArray[index]){// 如果在 filter collection中已經(jīng)記錄過了這個(gè)深度// 將這個(gè)深度對應(yīng)的頻度加一filterCollection[i][1]++;break;}else if (filterCollection[i][0] == 0){// 如果filter collection中沒有記錄這個(gè)深度// 那么記錄filterCollection[i][0] = depthArray[index];filterCollection[i][1]++;break;}}// 確定是內(nèi)外哪個(gè)邊界內(nèi)的像素不為零,對相應(yīng)計(jì)數(shù)器加一if (yi != 2 && yi != -2 && xi != 2 && xi != -2)innerBandCount++;elseouterBandCount++;}}}}}// 判斷計(jì)數(shù)器是否超過閾值,如果任意層內(nèi)非零像素的數(shù)目超過了閾值,// 就要將所有非零像素深度值對應(yīng)的統(tǒng)計(jì)眾數(shù)if (innerBandCount >= innerBandThreshold || outerBandCount >= outerBandThreshold){short frequency = 0;short depth = 0;// 這個(gè)循環(huán)將統(tǒng)計(jì)所有非零像素深度值對應(yīng)的眾數(shù)for (int i = 0; i < 24; i++){// 當(dāng)沒有記錄深度值時(shí)(無非零深度值的像素)if (filterCollection[i][0] == 0)break;if (filterCollection[i][1] > frequency){depth = filterCollection[i][0];frequency = filterCollection[i][1];}}smoothDepthArray[depthIndex] = depth;}else{smoothDepthArray[depthIndex] = 0;}}else{// 如果像素的深度值不為零,保持原深度值smoothDepthArray[depthIndex] = depthArray[depthIndex];}}}

3.1.2 濾波效果

我這里再次把原圖貼上,左圖是濾波后的效果圖:可以看到物體邊緣散亂的深度值為0的點(diǎn)已經(jīng)減少了不少。

3.1.3 代碼

因?yàn)橹皇菫榱死碚撋狭私庀袼貫V波器平滑的機(jī)制,因此我選擇靜態(tài)的讀取kinect采集的原始圖片,然后進(jìn)行平滑。
代碼下載鏈接

請自行配制環(huán)境–kinect 2.0SDK和OpenCV。
下一節(jié)將繼續(xù)講解平滑中的加權(quán)移動機(jī)制

《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

以上是生活随笔為你收集整理的深度图的实时平滑的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。