Created
July 30, 2020 05:34
-
-
Save Ajasra/f6990eda2d857ee96f94db985dddd82e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// BLUR | |
#define blur = mat3( | |
0.0, 0.2, 0.0, | |
0.2, 0.2, 0.2, | |
0.0, 0.2, 0.0 | |
) | |
#define factor 1.0; | |
#define bias 0.0; | |
// bigger blur | |
double filter[filterHeight][filterWidth] = | |
{ | |
0, 0, 1, 0, 0, | |
0, 1, 1, 1, 0, | |
1, 1, 1, 1, 1, | |
0, 1, 1, 1, 0, | |
0, 0, 1, 0, 0, | |
}; | |
double factor = 1.0 / 13.0; | |
double bias = 0.0; | |
// gaussian | |
double filter[filterHeight][filterWidth] = | |
{ | |
1, 2, 1, | |
2, 4, 2, | |
1, 2, 1, | |
}; | |
double factor = 1.0 / 16.0; | |
double bias = 0.0; | |
// Approximation to 5x5 kernel: | |
#define filterWidth 5 | |
#define filterHeight 5 | |
double filter[filterHeight][filterWidth] = | |
{ | |
1, 4, 6, 4, 1, | |
4, 16, 24, 16, 4, | |
6, 24, 36, 24, 6, | |
4, 16, 24, 16, 4, | |
1, 4, 6, 4, 1, | |
}; | |
double factor = 1.0 / 256.0; | |
double bias = 0.0; | |
// motion blur | |
#define filterWidth 9 | |
#define filterHeight 9 | |
double filter[filterHeight][filterWidth] = | |
{ | |
1, 0, 0, 0, 0, 0, 0, 0, 0, | |
0, 1, 0, 0, 0, 0, 0, 0, 0, | |
0, 0, 1, 0, 0, 0, 0, 0, 0, | |
0, 0, 0, 1, 0, 0, 0, 0, 0, | |
0, 0, 0, 0, 1, 0, 0, 0, 0, | |
0, 0, 0, 0, 0, 1, 0, 0, 0, | |
0, 0, 0, 0, 0, 0, 1, 0, 0, | |
0, 0, 0, 0, 0, 0, 0, 1, 0, | |
0, 0, 0, 0, 0, 0, 0, 0, 1, | |
}; | |
double factor = 1.0 / 9.0; | |
double bias = 0.0; | |
// find edges | |
#define filterWidth 5 | |
#define filterHeight 5 | |
double filter[filterHeight][filterWidth] = | |
{ | |
0, 0, -1, 0, 0, | |
0, 0, -1, 0, 0, | |
0, 0, 2, 0, 0, | |
0, 0, 0, 0, 0, | |
0, 0, 0, 0, 0, | |
}; | |
double factor = 1.0; | |
double bias = 0.0; | |
// vertical edges | |
#define filterWidth 5 | |
#define filterHeight 5 | |
double filter[filterHeight][filterWidth] = | |
{ | |
0, 0, -1, 0, 0, | |
0, 0, -1, 0, 0, | |
0, 0, 4, 0, 0, | |
0, 0, -1, 0, 0, | |
0, 0, -1, 0, 0, | |
}; | |
double factor = 1.0; | |
double bias = 0.0; | |
// 45degree edges | |
#define filterWidth 5 | |
#define filterHeight 5 | |
double filter[filterHeight][filterWidth] = | |
{ | |
-1, 0, 0, 0, 0, | |
0, -2, 0, 0, 0, | |
0, 0, 6, 0, 0, | |
0, 0, 0, -2, 0, | |
0, 0, 0, 0, -1, | |
}; | |
double factor = 1.0; | |
double bias = 0.0; | |
// all directions | |
#define filterWidth 3 | |
#define filterHeight 3 | |
double filter[filterHeight][filterWidth] = | |
{ | |
-1, -1, -1, | |
-1, 8, -1, | |
-1, -1, -1 | |
}; | |
double factor = 1.0; | |
double bias = 0.0; | |
//sharpen | |
#define filterWidth 3 | |
#define filterHeight 3 | |
double filter[filterHeight][filterWidth] = | |
{ | |
-1, -1, -1, | |
-1, 9, -1, | |
-1, -1, -1 | |
}; | |
double factor = 1.0; | |
double bias = 0.0; | |
#define filterWidth 5 | |
#define filterHeight 5 | |
// sharpen 2 | |
double filter[filterHeight][filterWidth] = | |
{ | |
-1, -1, -1, -1, -1, | |
-1, 2, 2, 2, -1, | |
-1, 2, 8, 2, -1, | |
-1, 2, 2, 2, -1, | |
-1, -1, -1, -1, -1, | |
}; | |
double factor = 1.0 / 8.0; | |
double bias = 0.0; | |
// emboss | |
#define filterWidth 3 | |
#define filterHeight 3 | |
double filter[filterHeight][filterWidth] = | |
{ | |
-1, -1, 0, | |
-1, 0, 1, | |
0, 1, 1 | |
}; | |
double factor = 1.0; | |
double bias = 128.0; | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// author : csblo | |
// Work made just by consulting : | |
// https://en.wikipedia.org/wiki/Kernel_(image_processing) | |
// Define kernels | |
#define identity mat3(0, 0, 0, 0, 1, 0, 0, 0, 0) | |
#define edge0 mat3(1, 0, -1, 0, 0, 0, -1, 0, 1) | |
#define edge1 mat3(0, 1, 0, 1, -4, 1, 0, 1, 0) | |
#define edge2 mat3(-1, -1, -1, -1, 8, -1, -1, -1, -1) | |
#define sharpen mat3(0, -1, 0, -1, 5, -1, 0, -1, 0) | |
#define box_blur mat3(1, 1, 1, 1, 1, 1, 1, 1, 1) * 0.1111 | |
#define gaussian_blur mat3(1, 2, 1, 2, 4, 2, 1, 2, 1) * 0.0625 | |
#define emboss mat3(-2, -1, 0, -1, 1, 1, 0, 1, 2) | |
#define factor 1 | |
#define bias 0 | |
// Find coordinate of matrix element from index | |
vec2 kpos(int index) | |
{ | |
return vec2[9] ( | |
vec2(-1, -1), vec2(0, -1), vec2(1, -1), | |
vec2(-1, 0), vec2(0, 0), vec2(1, 0), | |
vec2(-1, 1), vec2(0, 1), vec2(1, 1) | |
)[index] / iResolution.xy; | |
} | |
// Extract region of dimension 3x3 from sampler centered in uv | |
// sampler : texture sampler | |
// uv : current coordinates on sampler | |
// return : an array of mat3, each index corresponding with a color channel | |
mat3[3] region3x3(sampler2D sampler, vec2 uv) | |
{ | |
// Create each pixels for region | |
vec4[9] region; | |
for (int i = 0; i < 9; i++) | |
region[i] = texture(sampler, uv + kpos(i)); | |
// Create 3x3 region with 3 color channels (red, green, blue) | |
mat3[3] mRegion; | |
for (int i = 0; i < 3; i++) | |
mRegion[i] = mat3( | |
region[0][i], region[1][i], region[2][i], | |
region[3][i], region[4][i], region[5][i], | |
region[6][i], region[7][i], region[8][i] | |
); | |
return mRegion; | |
} | |
// Convolve a texture with kernel | |
// kernel : kernel used for convolution | |
// sampler : texture sampler | |
// uv : current coordinates on sampler | |
vec3 convolution(mat3 kernel, sampler2D sampler, vec2 uv) | |
{ | |
vec3 fragment; | |
// Extract a 3x3 region centered in uv | |
mat3[3] region = region3x3(sampler, uv); | |
// for each color channel of region | |
for (int i = 0; i < 3; i++) | |
{ | |
// get region channel | |
mat3 rc = region[i]; | |
// component wise multiplication of kernel by region channel | |
mat3 c = matrixCompMult(kernel, rc); | |
// add each component of matrix | |
float r = c[0][0] + c[1][0] + c[2][0] | |
+ c[0][1] + c[1][1] + c[2][1] | |
+ c[0][2] + c[1][2] + c[2][2]; | |
// for fragment at channel i, set result | |
fragment[i] = r * factor + bias; | |
} | |
return fragment; | |
} | |
void mainImage( out vec4 fragColor, in vec2 fragCoord ) | |
{ | |
// Normalized pixel coordinates (from 0 to 1) | |
vec2 uv = fragCoord/iResolution.xy; | |
// Convolve kernel with texture | |
vec3 col = convolution(emboss, iChannel0, uv); | |
// Output to screen | |
fragColor = vec4(col, 1.0); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define filterWidth 3 | |
#define filterHeight 3 | |
//color arrays | |
int red[filterWidth * filterHeight]; | |
int green[filterWidth * filterHeight]; | |
int blue[filterWidth * filterHeight]; | |
int selectKth(int* data, int s, int e, int k); | |
int main(int argc, char *argv[]) | |
{ | |
//load the image into the buffer | |
unsigned long w = 0, h = 0; | |
std::vector<ColorRGB> image; | |
loadImage(image, w, h, "pics/noise.png"); | |
std::vector<ColorRGB> result(image.size()); | |
//set up the screen | |
screen(w, h, 0, "Median Filter"); | |
ColorRGB color; //the color for the pixels | |
//apply the filter | |
for(int y = 0; y < h; y++) | |
for(int x = 0; x < w; x++) | |
{ | |
int n = 0; | |
//set the color values in the arrays | |
for(int filterY = 0; filterY < filterHeight; filterY++) | |
for(int filterX = 0; filterX < filterWidth; filterX++) | |
{ | |
int imageX = (x - filterWidth / 2 + filterX + w) % w; | |
int imageY = (y - filterHeight / 2 + filterY + h) % h; | |
red[n] = image[imageY * w + imageX].r; | |
green[n] = image[imageY * w + imageX].g; | |
blue[n] = image[imageY * w + imageX].b; | |
n++; | |
} | |
int filterSize = filterWidth * filterHeight; | |
result[y * w + x].r = red[selectKth(red, 0, filterSize, filterSize / 2)]; | |
result[y * w + x].g = green[selectKth(green, 0, filterSize, filterSize / 2)]; | |
result[y * w + x].b = blue[selectKth(blue, 0, filterSize, filterSize / 2)]; | |
} | |
//draw the result buffer to the screen | |
for(int y = 0; y < h; y++) | |
for(int x = 0; x < w; x++) | |
{ | |
pset(x, y, result[y * w + x]); | |
} | |
//redraw & sleep | |
redraw(); | |
sleep(); | |
} | |
// selects the k-th largest element from the data between start and end (end exclusive) | |
int selectKth(int* data, int s, int e, int k) // in practice, use C++'s nth_element, this is for demonstration only | |
{ | |
// 5 or less elements: do a small insertion sort | |
if(e - s <= 5) | |
{ | |
for(int i = s + 1; i < e; i++) | |
for(int j = i; j > 0 && data[j - 1] > data[j]; j--) std::swap(data[j], data[j - 1]); | |
return s + k; | |
} | |
int p = (s + e) / 2; // choose simply center element as pivot | |
// partition around pivot into smaller and larger elements | |
std::swap(data[p], data[e - 1]); // temporarily move pivot to the end | |
int j = s; // new pivot location to be calculated | |
for(int i = s; i + 1 < e; i++) | |
if(data[i] < data[e - 1]) std::swap(data[i], data[j++]); | |
std::swap(data[j], data[e - 1]); | |
// recurse into the applicable partition | |
if(k == j - s) return s + k; | |
else if(k < j - s) return selectKth(data, s, j, k); | |
else return selectKth(data, j + 1, e, k - j + s - 1); // subtract amount of smaller elements from k | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment