-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathkernel.cl
135 lines (108 loc) · 4.65 KB
/
kernel.cl
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
__constant sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;
__kernel void gaussian_filter(__read_only image2d_t srcImage, __write_only image2d_t dstImage, __constant float *g_kernel, int kernelSize) {
int2 pos = (int2)(get_global_id(0), get_global_id(1));
int width = get_image_width(srcImage);
int height = get_image_height(srcImage);
float4 color = (float4)(0.0f, 0.0f, 0.0f, 0.0f);
int halfSize = kernelSize / 2;
for (int i = -halfSize; i <= halfSize; i++) {
for (int j = -halfSize; j <= halfSize; j++) {
int2 neighborPos = (int2)(clamp(pos.x + i, 0, width - 1), clamp(pos.y + j, 0, height - 1));
float4 neighborColor = read_imagef(srcImage, sampler, neighborPos);
color += neighborColor * g_kernel[(i + halfSize) * kernelSize + (j + halfSize)];
}
}
write_imagef(dstImage, pos, color);
}
__kernel void bilateral_filter(__read_only image2d_t srcImage,
__write_only image2d_t dstImage,
const float sigma_s, // spatial
const float sigma_r) { // range
int2 coords = (int2)(get_global_id(0), get_global_id(1));
float4 centerPixel = read_imagef(srcImage, sampler, coords);
float4 sum = (float4)(0.0f);
float weightSum = 0.0f;
for (int i = -2; i <= 2; i++) {
for (int j = -2; j <= 2; j++) {
int2 neighborCoords = coords + (int2)(i, j);
float4 neighborPixel = read_imagef(srcImage, sampler, neighborCoords);
float spatialDist = (float)(i*i + j*j);
float rangeDist = length(centerPixel - neighborPixel);
float weight = exp(-spatialDist / (2 * sigma_s * sigma_s) - rangeDist / (2 * sigma_r * sigma_r));
sum += neighborPixel * weight;
weightSum += weight;
}
}
write_imagef(dstImage, coords, sum / weightSum);
}
__kernel void sharpen_filter(__read_only image2d_t srcImage,
__write_only image2d_t dstImage) {
int2 coords = (int2)(get_global_id(0), get_global_id(1));
float weight[3][3] = {
{ 0, -1, 0},
{-1, 5, -1},
{ 0, -1, 0}
};
float4 sum = (float4)(0.0f);
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
float4 pixel = read_imagef(srcImage, sampler, coords + (int2)(i, j));
sum += pixel * weight[i + 1][j + 1];
}
}
write_imagef(dstImage, coords, clamp(sum, 0.0f, 1.0f)); // Clamping to valid range
}
__kernel void mean_filter(__read_only image2d_t srcImage,
__write_only image2d_t dstImage,
const int kernelSize) {
int2 coords = (int2)(get_global_id(0), get_global_id(1));
int halfSize = kernelSize / 2;
// Initialize sum
float4 sum = (float4)(0.0f);
// Iterate over the kernel
for (int i = -halfSize; i <= halfSize; i++) {
for (int j = -halfSize; j <= halfSize; j++) {
// Read the pixel value from the image
float4 pixel = read_imagef(srcImage, sampler, coords + (int2)(i, j));
// Sum up the pixel values
sum += pixel;
}
}
// Compute the average
float4 average = sum / (float)(kernelSize * kernelSize);
// Write the result to the destination image
write_imagef(dstImage, coords, average);
}
__kernel void median_filter(__read_only image2d_t srcImage,
__write_only image2d_t dstImage,
const int kernelSize) {
int2 coords = (int2)(get_global_id(0), get_global_id(1));
int halfSize = kernelSize / 2;
// Initialize the array to store the pixel values
float4 pixels[25]; // 5x5 kernel is the maximum size
// Iterate over the kernel
int index = 0;
for (int i = -halfSize; i <= halfSize; i++) {
for (int j = -halfSize; j <= halfSize; j++) {
// Read the pixel value from the image
float4 pixel = read_imagef(srcImage, sampler, coords + (int2)(i, j));
// Store the pixel value in the array
pixels[index] = pixel;
index++;
}
}
// Sort the array
for (int i = 0; i < kernelSize * kernelSize; i++) {
for (int j = i + 1; j < kernelSize * kernelSize; j++) {
if (pixels[i].x > pixels[j].x) {
float4 temp = pixels[i];
pixels[i] = pixels[j];
pixels[j] = temp;
}
}
}
// Get the median value
float4 median = pixels[kernelSize * kernelSize / 2];
// Write the result to the destination image
write_imagef(dstImage, coords, median);
}