New image processing filter; (simplified) opening morphological operator

(aka denoising).
This commit is contained in:
brunoherbelin
2020-04-28 13:41:27 +02:00
parent 7f371fe5c9
commit 203ee4bea9
3 changed files with 52 additions and 10 deletions

View File

@@ -206,7 +206,7 @@ void ImGuiVisitor::visit(ImageProcessingShader &n)
if (ImGuiToolkit::ButtonIcon(1, 7)) n.filterid = 0;
ImGui::SameLine(0, 10);
ImGui::SetNextItemWidth(RIGHT_ALIGN);
ImGui::Combo("Filter", &n.filterid, "None\0Blur\0Sharpen\0Edge\0Emboss\0Erode 3x3\0Erode 5x5\0Erode 7x7\0Dilate 3x3\0Dilate 5x5\0Dilate 7x7\0");
ImGui::Combo("Filter", &n.filterid, "None\0Blur\0Sharpen\0Edge\0Emboss\0Denoising\0Erode 3x3\0Erode 5x5\0Erode 7x7\0Dilate 3x3\0Dilate 5x5\0Dilate 7x7\0");
if (ImGuiToolkit::ButtonIcon(7, 1)) n.invert = 0;
ImGui::SameLine(0, 10);

View File

@@ -38,7 +38,8 @@ public:
// filter identifyer
// [0] No filter
// [1 4] 4 x kernel operations; Blur, Sharpen, Edge, Emboss
// [5 10] 6 x convolutions: erosion 3, 5, 7, dilation 3, 5, 7
// [5] 1 x convolution opening (denoising)
// [6 11] 6 x convolutions: erosion 3x3, 5x5, 7x7, dilation 3x3, 5x5, 7x7
int filterid;
};

View File

@@ -79,7 +79,7 @@ vec3 erosion(int N, vec2 filter_step)
minValue = min(texture(iChannel0, vertexUV + vec2 (-1.0, 0.0) * filter_step ).rgb, minValue);
minValue = min(texture(iChannel0, vertexUV + vec2 (1.0, 0.0) * filter_step ).rgb, minValue);
minValue = min(texture(iChannel0, vertexUV + vec2 (0.0, 1.0) * filter_step ).rgb, minValue);
if (N == 3)
if (N < 1)
return minValue;
minValue = min(texture(iChannel0, vertexUV + vec2 (-1.0, -2.0) * filter_step ).rgb, minValue);
minValue = min(texture(iChannel0, vertexUV + vec2 (0.0,-2.0) * filter_step ).rgb, minValue);
@@ -97,7 +97,7 @@ vec3 erosion(int N, vec2 filter_step)
minValue = min(texture(iChannel0, vertexUV + vec2 ( 2.0, -1.0) * filter_step ).rgb, minValue);
minValue = min(texture(iChannel0, vertexUV + vec2 (-2.0, 0.0) * filter_step ).rgb, minValue);
minValue = min(texture(iChannel0, vertexUV + vec2 ( 2.0, 0.0) * filter_step ).rgb, minValue);
if (N == 5)
if (N < 2)
return minValue;
minValue = min(texture(iChannel0, vertexUV + vec2 (-1.0, -3.0) * filter_step ).rgb, minValue);
minValue = min(texture(iChannel0, vertexUV + vec2 (0.0,-3.0) * filter_step ).rgb, minValue);
@@ -128,7 +128,7 @@ vec3 dilation(int N, vec2 filter_step)
maxValue = max(texture(iChannel0, vertexUV + vec2 (-1.0, 0.0) * filter_step ).rgb, maxValue);
maxValue = max(texture(iChannel0, vertexUV + vec2 (1.0, 0.0) * filter_step ).rgb, maxValue);
maxValue = max(texture(iChannel0, vertexUV + vec2 (0.0, 1.0) * filter_step ).rgb, maxValue);
if (N == 3)
if (N < 1)
return maxValue;
maxValue = max(texture(iChannel0, vertexUV + vec2 (-1.0, -2.0) * filter_step ).rgb, maxValue);
maxValue = max(texture(iChannel0, vertexUV + vec2 (0.0,-2.0) * filter_step ).rgb, maxValue);
@@ -146,7 +146,7 @@ vec3 dilation(int N, vec2 filter_step)
maxValue = max(texture(iChannel0, vertexUV + vec2 ( 2.0, -1.0) * filter_step ).rgb, maxValue);
maxValue = max(texture(iChannel0, vertexUV + vec2 (-2.0, 0.0) * filter_step ).rgb, maxValue);
maxValue = max(texture(iChannel0, vertexUV + vec2 ( 2.0, 0.0) * filter_step ).rgb, maxValue);
if (N == 5)
if (N < 2)
return maxValue;
maxValue = max(texture(iChannel0, vertexUV + vec2 (-1.0, -3.0) * filter_step ).rgb, maxValue);
maxValue = max(texture(iChannel0, vertexUV + vec2 (0.0,-3.0) * filter_step ).rgb, maxValue);
@@ -168,6 +168,45 @@ vec3 dilation(int N, vec2 filter_step)
return maxValue;
}
vec3 opening(vec2 filter_step)
{
// 1) erosion
vec3 minValue1 = vec3(1.0);
minValue1 = min(texture(iChannel0, vertexUV + vec2 (0.0, 0.0) * filter_step ).rgb, minValue1);
minValue1 = min(texture(iChannel0, vertexUV + vec2 (0.0, 1.0) * filter_step ).rgb, minValue1);
minValue1 = min(texture(iChannel0, vertexUV + vec2 (0.0, 2.0) * filter_step ).rgb, minValue1);
minValue1 = min(texture(iChannel0, vertexUV + vec2 (1.0, 1.0) * filter_step ).rgb, minValue1);
minValue1 = min(texture(iChannel0, vertexUV + vec2 (1.0, -1.0) * filter_step ).rgb, minValue1);
vec3 minValue2 = vec3(1.0);
minValue2 = min(texture(iChannel0, vertexUV + vec2 (0.0, 0.0) * filter_step ).rgb, minValue2);
minValue2 = min(texture(iChannel0, vertexUV + vec2 (-1.0, 0.0) * filter_step ).rgb, minValue2);
minValue2 = min(texture(iChannel0, vertexUV + vec2 (-2.0, 0.0) * filter_step ).rgb, minValue2);
minValue2 = min(texture(iChannel0, vertexUV + vec2 (1.0, -1.0) * filter_step ).rgb, minValue2);
minValue2 = min(texture(iChannel0, vertexUV + vec2 (-1.0, -1.0) * filter_step ).rgb, minValue2);
vec3 minValue3 = vec3(1.0);
minValue3 = min(texture(iChannel0, vertexUV + vec2 (0.0, 0.0) * filter_step ).rgb, minValue3);
minValue3 = min(texture(iChannel0, vertexUV + vec2 (0.0, -1.0) * filter_step ).rgb, minValue3);
minValue3 = min(texture(iChannel0, vertexUV + vec2 (0.0, -2.0) * filter_step ).rgb, minValue3);
minValue3 = min(texture(iChannel0, vertexUV + vec2 (-1.0, -1.0) * filter_step ).rgb, minValue3);
minValue3 = min(texture(iChannel0, vertexUV + vec2 (-1.0, 1.0) * filter_step ).rgb, minValue3);
vec3 minValue4 = vec3(1.0);
minValue4 = min(texture(iChannel0, vertexUV + vec2 (0.0, 0.0) * filter_step ).rgb, minValue4);
minValue4 = min(texture(iChannel0, vertexUV + vec2 (1.0, 0.0) * filter_step ).rgb, minValue4);
minValue4 = min(texture(iChannel0, vertexUV + vec2 (2.0, 0.0) * filter_step ).rgb, minValue4);
minValue4 = min(texture(iChannel0, vertexUV + vec2 (1.0, 1.0) * filter_step ).rgb, minValue4);
minValue4 = min(texture(iChannel0, vertexUV + vec2 (-1.0, 1.0) * filter_step ).rgb, minValue4);
// 2) dilation
vec3 maxValue = vec3(0.0);
maxValue = max(minValue1, maxValue);
maxValue = max(minValue2, maxValue);
maxValue = max(minValue3, maxValue);
maxValue = max(minValue4, maxValue);
return maxValue;
}
vec3 convolution(mat3 kernel, vec2 filter_step)
{
int i = 0, j = 0;
@@ -184,14 +223,16 @@ vec3 apply_filter() {
vec2 filter_step = 1.f / textureSize(iChannel0, 0);
if (filterid < 1 || filterid > 10)
if (filterid < 1 || filterid > 11)
return texture(iChannel0, vertexUV).rgb;
else if (filterid < 5)
return convolution( KERNEL[filterid], filter_step);
else if (filterid < 8)
return erosion( 3 + (filterid -5) * 2, filter_step);
else if (filterid < 6)
return opening(filter_step);
else if (filterid < 9)
return erosion( filterid - 6 , filter_step);
else
return dilation( 3 + (filterid -8) * 2, filter_step);
return dilation( filterid - 9, filter_step);
}
/*