New morphological operators

This commit is contained in:
Bruno Herbelin
2022-05-07 23:01:17 +02:00
parent cf020d06c6
commit f7da3a347d
6 changed files with 131 additions and 0 deletions

View File

@@ -583,6 +583,10 @@ set(VMIX_RSC_FILES
./rsc/shaders/filters/grain.glsl ./rsc/shaders/filters/grain.glsl
./rsc/shaders/filters/stippling.glsl ./rsc/shaders/filters/stippling.glsl
./rsc/shaders/filters/dithering.glsl ./rsc/shaders/filters/dithering.glsl
./rsc/shaders/filters/erosion.glsl
./rsc/shaders/filters/dilation.glsl
./rsc/shaders/filters/tophat.glsl
./rsc/shaders/filters/blackhat.glsl
) )
# Include the CMake RC module # Include the CMake RC module

View File

@@ -99,6 +99,11 @@ std::list< ImageFilter > ImageFilter::presets = {
ImageFilter("Pixelate", "shaders/filters/pixelate.glsl", "", { { "Size", 0.5}, { "Sharpen", 0.5} }), ImageFilter("Pixelate", "shaders/filters/pixelate.glsl", "", { { "Size", 0.5}, { "Sharpen", 0.5} }),
ImageFilter("Chromakey","shaders/filters/chromakey.glsl", "", { { "Red", 0.05}, { "Green", 0.63}, { "Blue", 0.14}, { "Tolerance", 0.54} }), ImageFilter("Chromakey","shaders/filters/chromakey.glsl", "", { { "Red", 0.05}, { "Green", 0.63}, { "Blue", 0.14}, { "Tolerance", 0.54} }),
ImageFilter("Fisheye", "shaders/filters/fisheye.glsl", "", { { "Factor", 0.5} }), ImageFilter("Fisheye", "shaders/filters/fisheye.glsl", "", { { "Factor", 0.5} }),
ImageFilter("Openning", "shaders/filters/erosion.glsl", "shaders/filters/dilation.glsl", { { "Radius", 0.5} }),
ImageFilter("Closing", "shaders/filters/dilation.glsl", "shaders/filters/erosion.glsl", { { "Radius", 0.5} }),
ImageFilter("TopHat", "shaders/filters/erosion.glsl", "shaders/filters/tophat.glsl", { { "Radius", 0.5} }),
ImageFilter("BlackHat", "shaders/filters/dilation.glsl", "shaders/filters/blackhat.glsl", { { "Radius", 0.5} })
}; };

View File

@@ -0,0 +1,36 @@
uniform float Radius;
#define MAX_SIZE 5
vec3 erosion (sampler2D source, vec2 uv, vec2 uv_step, float R)
{
vec3 minValue = vec3(1.0);
float D = length(vec2( R / 2.));
for (float i=-R; i <= R; ++i)
{
for (float j=-R; j <= R; ++j)
{
vec2 delta = vec2(i, j);
minValue = min(texture(source, uv + delta * smoothstep(R, D, length(delta)) * uv_step ).rgb, minValue);
}
}
return minValue;
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord.xy / iResolution.xy;
// blackhat is the difference between the Closing of the input image and the image
// Closing is Dilation (first pass) followed by Erosion (second pass)tion.xy;
// get original image
vec3 c = texture(iChannel1, uv).rgb;
// get result of Closing
vec3 e = erosion(iChannel0, uv, 1.0 / iResolution.xy, mix(1., MAX_SIZE, Radius));
// composition
fragColor = vec4( c + (c-e), 1.0);
}

View File

@@ -0,0 +1,25 @@
uniform float Radius;
#define MAX_SIZE 5
vec3 dilation (sampler2D source, vec2 uv, vec2 uv_step, float R) {
vec3 maxValue = vec3(0.0);
float D = length(vec2( R / 2.));
for (float i=-R; i <= R; ++i)
{
for (float j=-R; j <= R; ++j)
{
vec2 delta = vec2(i, j);
maxValue = max(texture(source, uv + delta * smoothstep(R, D, length(delta)) * uv_step ).rgb, maxValue);
}
}
return maxValue;
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord.xy / iResolution.xy;
fragColor = vec4( dilation(iChannel0, uv, 1.0 / iResolution.xy, mix(1., MAX_SIZE, Radius)), 1.0);
}

View File

@@ -0,0 +1,25 @@
uniform float Radius;
#define MAX_SIZE 5
vec3 erosion (sampler2D source, vec2 uv, vec2 uv_step, float R)
{
vec3 minValue = vec3(1.0);
float D = length(vec2( R / 2.));
for (float i=-R; i <= R; ++i)
{
for (float j=-R; j <= R; ++j)
{
vec2 delta = vec2(i, j);
minValue = min(texture(source, uv + delta * smoothstep(R, D, length(delta)) * uv_step ).rgb, minValue);
}
}
return minValue;
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord.xy / iResolution.xy;
fragColor = vec4( erosion(iChannel0, uv, 1.0 / iResolution.xy, mix(1., MAX_SIZE, Radius)), 1.0);
}

View File

@@ -0,0 +1,36 @@
uniform float Radius;
#define MAX_SIZE 5
vec3 dilation (sampler2D source, vec2 uv, vec2 uv_step, float R) {
vec3 maxValue = vec3(0.0);
float D = length(vec2( R / 2.));
for (float i=-R; i <= R; ++i)
{
for (float j=-R; j <= R; ++j)
{
vec2 delta = vec2(i, j);
maxValue = max(texture(source, uv + delta * smoothstep(R, D, length(delta)) * uv_step ).rgb, maxValue);
}
}
return maxValue;
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord.xy / iResolution.xy;
// tophat is the difference between input image and Opening of the input image
// Opening is Erosion (first pass) followed by Dilation (second pass)
// get original image
vec3 c = texture(iChannel1, uv).rgb;
// get result of Opening
vec3 d = dilation(iChannel0, uv, 1.0 / iResolution.xy, mix(1., MAX_SIZE, Radius));
// composition
fragColor = vec4( c + (c-d), 1.0);
}