vondip
vondip

Reputation: 14039

GPUImage - How to specify filter size for GPUImageMedianFilter and GPUImageGaussianBlurFilter

Hi GPUImage community and Brad,

I would like to specify the filter size (radius) of the GPUImageMedianFilter and GPUImageGaussianBlurFilter.

Does that demand specifying GPU commends? Or can it be done through the GPUImage wrapper? If so, how can I do that?

Thanks

Upvotes: 1

Views: 1884

Answers (2)

James Bush
James Bush

Reputation: 1527

Here's how to calculate the median within the pixel-neighborhood radius of your choosing:

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)); 
}

A brief description of the steps 1. Calculate the mean of the values of the pixels surrounding the source pixel in a 3x3 neighborhood; 2. Find the maximum pixel value of all pixels in the same neighborhood that are less than the mean. 3. [OPTIONAL] Subtract the median pixel value from the source pixel value for edge detection.

If you're using the median value for edge detection, there are a couple of ways to modify the above code for better results, namely, hybrid median filtering and truncated media filtering (a substitute and a better 'mode' filtering). If you're interested, please ask.

Upvotes: 0

Brad Larson
Brad Larson

Reputation: 170319

This is probably not the place to ask a specific question about this framework, but I can answer you on this.

The GPUImageMedianFilter is a hardcoded 3x3 median filter based on the article "A Fast, Small-Radius GPU Median Filter" by Morgan McGuire in the ShaderX6 book. More on this can be found here, including larger-radius versions of this. Despite being the fastest implementation of this that I have found, it is still incredibly slow to run on all but the fastest iOS devices, so increasing the sampling area will only slow this down further.

The GPUImageGaussianBlurFilter does a 9-hit simple Gaussian blur in two separated passes. The blurSize property allows you to expand or contract the sampling area slightly, but if you go beyond a multiplier of 1.5, you'll start seeing fringe artifacts due to too few samples being used to blur over a large area. I'm working on a couple of ways of expanding the blur area in a performant manner, but that is the limitation of this particular filter.

Upvotes: 6

Related Questions