2012-06-18 45 views

回答

6

這可能不是問這個框架內具體問題的地方,但我可以回答你這個。

GPUImageMedianFilter是一個硬編碼的3x3中值濾波器,基於ShaderX6書中由Morgan McGuire撰寫的文章「A Fast,Small-Radius GPU Median Filter」。更多的信息可以在here找到,包括更大的半徑版本。儘管這是我發現的最快的實現,但它運行在除最快的iOS設備之外的所有設備上運行速度仍然非常慢,因此增加採樣面積只會進一步降低速度。

GPUImageGaussianBlurFilter在兩個分離的遍中執行9命中的簡單高斯模糊。 blurSize屬性允許您略微擴大或縮小採樣區域,但如果超出1.5的倍數,則由於在大面積上使用太少的樣本進行模糊,您將開始看到邊緣僞影。我正在努力以一種高性能的方式擴展模糊區域,但這是該特定濾鏡的限制。

+2

很好,非常感謝布拉德爲答案和真棒圖書館! – vondip

0

以下爲您所選擇的像素鄰域範圍內計算位數:

kernel vec4 medianUnsharpKernel(sampler u) { 
vec4 pixel = unpremultiply(sample(u, samplerCoord(u))); 
vec2 xy = destCoord(); 
int radius = 3; 
int bounds = (radius - 1)/2; 
vec4 sum = vec4(0.0); 
for (int i = (0 - bounds); i <= bounds; i++) 
{ 
    for (int j = (0 - bounds); j <= bounds; j++) 
    { 
     sum += unpremultiply(sample(u, samplerTransform(u, vec2(xy + vec2(i, j))))); 
    } 
} 
vec4 mean = vec4(sum/vec4(pow(float(radius), 2.0))); 
float mean_avg = float(mean); 
float comp_avg = 0.0; 
vec4 comp = vec4(0.0); 
vec4 median = mean; 
for (int i = (0 - bounds); i <= bounds; i++) 
{ 
    for (int j = (0 - bounds); j <= bounds; j++) 
    { 
     comp = unpremultiply(sample(u, samplerTransform(u, vec2(xy + vec2(i, j))))); 
     comp_avg = float(comp); 
     median = (comp_avg < mean_avg) ? max(median, comp) : median; 
    } 
} 

return premultiply(vec4(vec3(abs(pixel.rgb - median.rgb)), 1.0)); 
} 

的步驟 1.計算周圍的源像素的像素值的平均值的簡要說明一個3x3的街區; 2.找到相同鄰域內小於平均值的所有像素的最大像素值。 3. [可選]從源像素值中減去邊緣檢測的中值像素值。

如果您使用邊緣檢測的中值,有幾種方法可以修改上述代碼以獲得更好的結果,即混合中值濾波和截斷媒體濾波(替代和更好的「模式」濾波)。如果您有興趣,請詢問。