喜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