summaryrefslogtreecommitdiff
path: root/opencl/bilateral-filter.cl
blob: 0205b985576217e707c10473815d4c7736d23923 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#define POW2(a) ((a) * (a))
kernel void bilateral_filter(global float4 *in,
                             global float4 *out,
                             const  float radius,
                             const  float preserve)
{
    int gidx       = get_global_id(0);
    int gidy       = get_global_id(1);
    int n_radius   = ceil(radius);
    int dst_width  = get_global_size(0);
    int src_width  = dst_width + n_radius * 2;

    int u, v, i, j;
    float4 center_pix =
        in[(gidy + n_radius) * src_width + gidx + n_radius];
    float4 accumulated = 0.0f;
    float4 tempf       = 0.0f;
    float  count       = 0.0f;
    float  diff_map, gaussian_weight, weight;

    for (v = -n_radius;v <= n_radius; ++v)
    {
        for (u = -n_radius;u <= n_radius; ++u)
        {
            i = gidx + n_radius + u;
            j = gidy + n_radius + v;

            int gid1d = i + j * src_width;
            tempf = in[gid1d];

            diff_map = exp (
                - (   POW2(center_pix.x - tempf.x)
                    + POW2(center_pix.y - tempf.y)
                    + POW2(center_pix.z - tempf.z))
                * preserve);

            gaussian_weight =
                exp( - 0.5f * (POW2(u) + POW2(v)) / radius);

            weight = diff_map * gaussian_weight;

            accumulated += tempf * weight;
            count += weight;
        }
    }
    out[gidx + gidy * dst_width] = accumulated / count;
}