2013-02-13 56 views
0

我有一個算法,根據距離到最接近的像素的距離創建一個灰度漸變。我通過構建一個圓圈的半徑增大和採樣的所有像素的面具對圓的像素找到像素:基於到像素的距離的漸變

for (x = 0; x < width; x++){ 
    for (y = 0; y < height; y++) { 
     bool pixelFound = false; 
     for (radius = 0; radius < resolution, pixelFound == false; radius++) { 
     for (alpha = 0; alpha < 2 * PI; alpha += 1/radius) { 
      xx = x + cos(alpha)*radius; 
      yy = y + sin(alpha)*radius; 

      if (MaskHasPixel(xx, yy)) { 
       pixelFound = true; 
       gradient = 1 - Magnitude(xx-x, yy-y)/resolution; 
       WriteGradientForPixel(x,y, gradient); 
      } 
     } 
     } 
    } 
} 

目前的算法是非常緩慢的 - 爲512×512和口罩大小的圖像128x128它將不得不做512 * 512 * 384 * 41 = 4 127 195 136比較,這需要花費大量的時間在CPU上進行計算。其中一種選擇是在GPU上進行計算,但是可以優化該算法以使其運行速度更快嗎?我最終想要相對快速地獲得一個很好的平滑梯度。

謝謝!

+0

與你的問題沒有關係,但你可能想用'radius 2013-02-13 16:32:17

+0

使'罪'(alpha)&'cos(alpha)'表 - 這些功能緩慢。你也做錯了一切!不要掃描*所有*像素,而是根據您的遮罩製作漸變遮罩(標記具有要標記距離值的像素)。你可以用隨後的擴張來完成。 – 2013-02-13 16:35:00

+0

@Eddy_Em你應該充實你的漸變面具的建議,並將其作爲答案。 – 2013-02-13 17:35:00

回答

0

我找到了一種讓算法快3倍的方法: 1.計算我的邊界蒙版的幾何中心。 2.計算從當前像素到上述中心的方向:dir =(中心 - 像素)。標準化 3。檢查朝向中心的每個像素是否是邊框像素。 4.如果是,則搜索結束。 5.如果未找到朝向中心的邊框像素,請使用原先較慢的方法。

加快速度的另一種方法是縮小原始圖像的大小。這將有很大幫助。

1

那麼,至於後續擴張。他們可以用修改過的算法完成。假設你在零背景上有一些掩碼。把它放到你的圖像上(通過放大零背景,這個舞臺上的圖像可能是一個unsigned shortunsigned int的數組,這取決於它的大小 - 我們需要將它的像素值放入距離中)。

下一個操作是距離計算。爲了更快速地做到這一點,首先我們找到掩碼的邊界並將其保存到一個座標數組中。之後,我們通過該陣列並填充8個連接的非零像素,同時填充一個新的邊界陣列。

在第一次迭代結束時free()第一個邊界數組並運行新數組的第二次迭代,將2添加到鄰居並填充下一個邊界數組。

重複迭代,直到最後一個邊界數組將有0個成員。


另一個變種是直接的算法,像你這樣的。計算並存儲掩碼的邊框。好。現在開始掃描擴展到圖像大小掩碼的所有像素。

如果像素值== 0,我們會遍歷邊界的所有像素,計算與它們的距離並存儲最小距離。這將是漸變的價值。

該算法可以通過計算距離我們點的邊界像素的距離來改善。爲此,我們不僅應該存儲邊界像素的座標,而且還應該存儲來自掩模重心的角度。然後當掃描邊界時,我們可以丟棄與當前圖像點具有角度相等角度的像素,並掩蓋重心±某個值(π/2?)。

另一種快速計算的方法是將sinuses &的cosinuses製作得很小,以致相鄰成員之間的值可以忽略不計。這一步可能是從其中心成像的角度像素大小。甚至更大。


當然還有很多其他不同的優化方法可以解決這個問題,也許其中一些方法會更快。這是一個調查問題。