2011-09-22 84 views
3

我正試圖在JavaScript中實現一個簡單的雙邊過濾器。這是我到目前爲止:雙邊濾波算法

// For each pixel 
for (var y = kernelSize; y < height-kernelSize; y++) { 
    for (var x = kernelSize; x < width-kernelSize; x++) { 
     var pixel = (y*width + x)*4; 
     var sumWeight = 0; 
     outputData[pixel] = 0; 
     outputData[pixel+1] = 0; 
     outputData[pixel+2] = 0; 
     outputData[pixel+3] = inputData[pixel+3]; 

     // For each neighbouring pixel 
     for(var i=-kernelSize; i<=kernelSize; i++) { 
      for(var j=-kernelSize; j<=kernelSize; j++) { 
       var kernel = ((y+i)*width+x+j)*4; 
       var dist = Math.sqrt(i*i+j*j); 
       var colourDist = Math.sqrt((inputData[kernel]-inputData[pixel])*(inputData[kernel]-inputData[pixel])+ 
         (inputData[kernel+1]-inputData[pixel+1])*(inputData[kernel+1]-inputData[pixel+1])+ 
         (inputData[kernel+2]-inputData[pixel+2])*(inputData[kernel+2]-inputData[pixel+2])); 
       var curWeight = 1/(Math.exp(dist*dist/72)*Math.exp(colourDist*colourDist*8)); 
       sumWeight += curWeight; 
       outputData[pixel] += curWeight*inputData[pixel]; 
       outputData[pixel+1] += curWeight*inputData[pixel+1]; 
       outputData[pixel+2] += curWeight*inputData[pixel+2]; 
      } 
     } 

     outputData[pixel] /= sumWeight; 
     outputData[pixel+1] /= sumWeight; 
     outputData[pixel+2] /= sumWeight; 
    } 
} 

inputData來自html5畫布對象,格式爲rgba。 我的圖片或者想出任何更改或黑色斑塊周圍邊緣取決於我如何改變這種公式:

var curWeight = 1/(Math.exp(dist*dist/72)*Math.exp(colourDist*colourDist*8)); 

不幸的是我還是新來的HTML/JavaScript和圖像視覺算法和我的搜索有拿出沒有答案。我的猜測是,計算curWeight的方式有些問題。我在這裏做錯了什麼?我應該先將輸入圖像轉換爲CIElab/hsv嗎?

+0

這是一個大量記錄的雙邊過濾器matlab代碼,我寫了,它適用於rgba圖像(包括邊緣)。 http://pastebin.com/pLu4v1dC這只是前面的參考資料,稍後會查看你的代碼 –

回答

1

首先,由於您不過濾邊緣,因此您的圖像在邊緣會變黑/怪異。簡單看一下你的代碼將會顯示你從(kernelSize,kernelSize)開始並且在(width-kernelSize,height-kernelSize)處結束 - 這意味着你只在圖像中過濾一個更小的矩形每一邊都是未經過濾的。在不知道javscript/html5的情況下,我會假設你的outputData數組是初始化爲零(這意味着黑色),然後不觸及它們會使它們變黑。查看我的鏈接評論到您的文章處理邊緣的代碼。

除此之外,請按照@ nikie的回答 - 您可能想要確保將色距限制在[0,1]的範圍內 - 您可以通過將colourDist = colourDist/(MAX_COMP * Math,sqrt(3))(直接在第一行之後計算它)。其中MAX_COMP是圖像中顏色分量的最大值(通常爲255)

+0

我很難理解matlab代碼。什麼是顏色exp函數的輸入值的域? – Skul

+2

@Skul:我的代碼在灰色圖像上工作(所以只有一個顏色分量)。我已經在這裏上傳了RGB圖像的新代碼:http://pastebin.com/UsBBBkeK 基本上,exp接收一個2d矩陣的值(我們的情況不同)並計算每個值的指數。然後它返回結果矩陣。所以結果(i,j)= e^src(i,j) –

+0

感謝您的幫助。我認爲我現在更瞭解阿爾戈=) – Skul

2

我不是Javasript專家:是RGB值0..255?如果是這樣,Math.exp(colourDist*colourDist*8)將產生非常大的值 - 您可能想要將colourDist縮放到範圍[0..1]。

順便說一句:如果你以後只需要平方距離,爲什麼要計算和colourDistsqrt

+0

現在我覺得自己很愚蠢......我已經編輯了代碼,將顏色dist分配到[0,1]刪除了sqrt函數 – Skul

0

我在代碼中發現了錯誤。問題是我將每個像素添加到自身而不是周圍的鄰居。如果有人需要雙邊濾波算法,我會在這裏保留更正的代碼。

outputData[pixel] += curWeight*inputData[kernel]; 
outputData[pixel+1] += curWeight*inputData[kernel+1]; 
outputData[pixel+2] += curWeight*inputData[kernel+2];