Problem Statement and Background Image and Video filters Ascii art Photo Mosaic
This filters has the purpose of detect edges on the images, and are widely used on machine learning applications, because they help to extract important features of the images. Here we are going to test three different kernels in order to compare them.
Here you can see the filter applied to an image, and check how the edge detection extract only the shapes that could be related to edges on the image. The shaders applied to all the convolutional filters is the same, the only thing that changes is the definition of the convolutional matrix on the p5.js code, so we are only going to show the code for this filter.
1linklet convShader;
2linklet shaderTexture;
3linklet kernel = [];
4linklet size;
5linklet offset = [];
6linkfunction preload() {
7link img = loadImage('/vc/docs/sketches/lenna.png');
8link video = createVideo(['/vc/docs/sketches/fingers.mov', '/vc/docs/sketches/fingers.webm']);
9link kernelShader = loadShader('/vc/docs/sketches/kernel.vert', '/vc/docs/sketches/kernel.frag');
10link video.hide();
11link}
12link
13linkfunction setup() {
14link createCanvas(768, 393, WEBGL);
15link shaderTexture = createGraphics(393, 393, WEBGL);
16link shaderTexture.noStroke();
17link kernel = [1, 0, -1, 0, 0, 0, -1, 0, 1];
18link size = 3;
19link for (let i = 0; i < size; i++) {
20link for (let j = 0; j < size; j++) {
21link offset.push(float(-(size-1)/2.0+j)*1.0/height);
22link offset.push(float(-(size-1)/2.0+i)*1.0/width);
23link }
24link }
25link
26link for (let i = size*size; i < 49; i++) {
27link offset.push(0);
28link kernel.push(0);
29link }
30link video.loop();
31link noStroke();
32link}
33link
34linkfunction draw() {
35link shaderTexture.shader(kernelShader);
36link kernelShader.setUniform('tex0', img);
37link kernelShader.setUniform('kernel', kernel);
38link kernelShader.setUniform('n', size);
39link kernelShader.setUniform('size', 1);
40link kernelShader.setUniform('ofs', offset);
41link texture(shaderTexture);
42link shaderTexture.rect(0,0,393,393);
43link rect(-393,-393/2.0,393,393)
44link kernelShader.setUniform('tex0', video);
45link kernelShader.setUniform('kernel', kernel);
46link kernelShader.setUniform('n', size);
47link kernelShader.setUniform('size', 1);
48link kernelShader.setUniform('ofs', offset);
49link texture(shaderTexture);
50link shaderTexture.rect(0,0,393,393);
51link rect(0,-393/2.0,393,393)
52link}
53link
1link#ifdef GL_ES
2linkprecision mediump float;
3link#endif
4link
5linkattribute vec3 aPosition;
6linkattribute vec2 aTexCoord;
7link
8linkvarying vec2 vTexCoord;
9link
10linkvoid main() {
11link vTexCoord = aTexCoord;
12link
13link vec4 positionVec4 = vec4(aPosition, 1.0);
14link positionVec4.xy = positionVec4.xy * 2.0 - 1.0;
15link
16link gl_Position = positionVec4;
17link}
1link#ifdef GL_ES
2linkprecision mediump float;
3link#endif
4link
5linkvarying vec2 vTexCoord;
6linkuniform int n;
7linkuniform float kernel[49];
8linkuniform float size;
9linkuniform sampler2D tex0;
10linkuniform float ofs[98];
11link
12link
13linkvec4 conv = vec4(0.0);
14link
15linkvoid main(){
16link
17link vec2 uv = vTexCoord;
18link uv.y = 1.0 - uv.y;
19link
20link
21link for(int i = 0; i<49; i++){
22link if (i >= int(n*n)) break;
23link vec4 color = texture2D(tex0, uv + vec2(ofs[i*2], ofs[i*2+1])*size);
24link
25link conv += color*kernel[i] ;
26link }
27link
28link gl_FragColor = vec4(conv.rgb, 1.0);
29link}
Laplacian matrices has been used a lot for edge detection because of their incredible properties and results on these tasks.
Here you can find how the filter is applied.
As we can see the edge detection has improved a lot with this matrix on the image, but it stills a bit fuzzy on the video.
Here is the result of the filter.
This laplacian matrix has the best performance on the video, but on the image it takes many details of the textures as edges, which could affect the detection.
Problem Statement and Background Image and Video filters Ascii art Photo Mosaic