2011-04-30 64 views
5

我正在尋找一個快速,骯髒,非常有效的邊緣檢測着色器或邊緣網格的視頻應用程序。由於這將在移動設備上完成,因此我需要一些能夠提高精度的性能。無論如何,我將模糊輸出,而我所見過的所有邊緣檢測算法都傾向於通過將原始圖像與模糊圖像進行比較來完成。我認爲這是造成大多數性能問題的模糊因素。GLSL邊緣檢測着色器最有效的方法

我有這樣的工作的函數:

vec4 edge() 
{ 

    float K00 = -1.0; 
    float K01 = -2.0; 
    float K02 = -1.0; 
    float K10 = 0.0; 
    float K11 = 0.0; 
    float K12 = 0.0; 
    float K20 = 1.0; 
    float K21 = 2.0; 
    float K22 = 1.0; 

    vec2 ox = vec2 (0.0,0.0); 
    ox[0] = width; 
    vec2 oy = vec2 (0.0,0.0); 
    oy[1] = height; 

    float g00, g01, g02; 
    float g10, g11, g12; 
    float g20, g21, g22; 
    vec4 CC; 

    vec2 PP = TextureCoord - oy; 
    CC = texture2D(blurredFrame, vec2(PP-ox)); 
    g00 = getGrey(CC); 
    CC = texture2D(blurredFrame, vec2(PP)); 
    g01 = getGrey(CC); 
    CC = texture2D(blurredFrame, vec2(PP+ox)); 
    g02 = getGrey(CC); 


    PP = TextureCoord; 
    CC = texture2D(blurredFrame, vec2(PP-ox)); 
    g10 = getGrey(CC); 
    CC = texture2D(blurredFrame, vec2(PP)); 
    g11 = getGrey(CC); 
    CC = texture2D(blurredFrame, vec2(PP+ox)); 
    g12 = getGrey(CC); 

    PP = TextureCoord + oy; 
    CC = texture2D(blurredFrame, vec2(PP-ox)); 
    g20 = getGrey(CC); 
    CC = texture2D(blurredFrame, vec2(PP)); 
    g21 = getGrey(CC); 
    CC = texture2D(blurredFrame, vec2(PP+ox)); 
    g22 = getGrey(CC); 

    float sx = 0.0, sy = 0.0; 
    sx = sx + g00 * K00; 
    sx = sx + g01 * K01; 
    sx = sx + g02 * K02; 
    sx = sx + g10 * K10; 
    sx = sx + g11 * K11; 
    sx = sx + g12 * K12; 
    sx = sx + g20 * K20; 
    sx = sx + g21 * K21; 
    sx = sx + g22 * K22; 
    sy = sy + g00 * K00; 
    sy = sy + g01 * K10; 
    sy = sy + g02 * K20; 
    sy = sy + g10 * K01; 
    sy = sy + g11 * K11; 
    sy = sy + g12 * K21; 
    sy = sy + g20 * K02; 
    sy = sy + g21 * K12; 
    sy = sy + g22 * K22; 

    float dist = sqrt(sx * sx + sy * sy); 

    return dist > threshold ? vec4 (0,0,0,1) : vec4 (1,1,1,1); 
} 

我見過的所有例子都是這樣,似乎專注於桌面平臺 - 也參與和昂貴獲得在iPhone或一個體面的幀率Android設備。這隻適用於2d應用程序,速度是關鍵。

任何想法,使這個更有效率,或者更好的選擇?感謝大家。

回答

4

不知道我是否知道不同的算法。

但是,一些建議浮現在腦海:

  1. 做比較DIST之前,不要採取的sqrt(),而不是比較DIST^2
  2. 看看你能不能優化訪問模式的紋理負載。紋理內存訪問模式可能會對性能產生重大影響。你想盡可能保持你的內存訪問(即0,1,2,3,...),而不是隨機的。
  3. 關閉mip貼圖,或在您手動指定mip貼圖級別的地方使用texture2DLod。
+0

謝謝。我唯一想到的其他事情就是從中刪除「模糊」代碼,並在縮小版本的圖像上執行模糊處理,然後將該紋理傳遞到此代碼的邊緣檢測部分。我認爲這會加速模糊,但我會通過使用多次傳球失去一些收益。 – akaru 2011-05-01 17:13:52

1

我有一個關於優化紋理樣本夫婦的想法:

  1. 無需採樣,而相應的係數爲零 (K1 *)。
  2. 使用texture2DOffset代替texture2D。它接受恆定整數 偏移量,允許驅動程序 有效地預測您的訪問模式更多 。
  3. 您正在對樣本進行加權。您可以使用內置的線性過濾器來實現這一點。例如,對於 獲取兩個鄰域 texels中的採樣總和,可以在它們之間線性採樣(僅 一次),並將 結果乘以2.此變體排除 先前的建議。
+1

謝謝。好的建議。我不認爲texture2DOffset在opengles上可用,除非我只是實現了錯誤。 – akaru 2011-05-01 18:29:46

+0

@akaru。看起來你是正確的 - 在GL ES中沒有'texture * Offset'功能。 – kvark 2011-05-01 18:53:55