喜GPUImage社區和布拉德濾波器的尺寸,GPUImage - 如何指定GPUImageMedianFilter和GPUImageGaussianBlurFilter
我想指定GPUImageMedianFilter 和GPUImageGaussianBlurFilter的過濾器尺寸(半徑)。
請求指定GPU是否表示讚賞?或者可以通過GPUImage包裝來完成? 如果是這樣,我該怎麼做?
感謝
喜GPUImage社區和布拉德濾波器的尺寸,GPUImage - 如何指定GPUImageMedianFilter和GPUImageGaussianBlurFilter
我想指定GPUImageMedianFilter 和GPUImageGaussianBlurFilter的過濾器尺寸(半徑)。
請求指定GPU是否表示讚賞?或者可以通過GPUImage包裝來完成? 如果是這樣,我該怎麼做?
感謝
這可能不是問這個框架內具體問題的地方,但我可以回答你這個。
GPUImageMedianFilter是一個硬編碼的3x3中值濾波器,基於ShaderX6書中由Morgan McGuire撰寫的文章「A Fast,Small-Radius GPU Median Filter」。更多的信息可以在here找到,包括更大的半徑版本。儘管這是我發現的最快的實現,但它運行在除最快的iOS設備之外的所有設備上運行速度仍然非常慢,因此增加採樣面積只會進一步降低速度。
GPUImageGaussianBlurFilter在兩個分離的遍中執行9命中的簡單高斯模糊。 blurSize屬性允許您略微擴大或縮小採樣區域,但如果超出1.5的倍數,則由於在大面積上使用太少的樣本進行模糊,您將開始看到邊緣僞影。我正在努力以一種高性能的方式擴展模糊區域,但這是該特定濾鏡的限制。
以下爲您所選擇的像素鄰域範圍內計算位數:
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. [可選]從源像素值中減去邊緣檢測的中值像素值。
如果您使用邊緣檢測的中值,有幾種方法可以修改上述代碼以獲得更好的結果,即混合中值濾波和截斷媒體濾波(替代和更好的「模式」濾波)。如果您有興趣,請詢問。
很好,非常感謝布拉德爲答案和真棒圖書館! – vondip