mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-11 18:34:58 +01:00
New image processing filter; (simplified) opening morphological operator
(aka denoising).
This commit is contained in:
@@ -206,7 +206,7 @@ void ImGuiVisitor::visit(ImageProcessingShader &n)
|
|||||||
if (ImGuiToolkit::ButtonIcon(1, 7)) n.filterid = 0;
|
if (ImGuiToolkit::ButtonIcon(1, 7)) n.filterid = 0;
|
||||||
ImGui::SameLine(0, 10);
|
ImGui::SameLine(0, 10);
|
||||||
ImGui::SetNextItemWidth(RIGHT_ALIGN);
|
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;
|
if (ImGuiToolkit::ButtonIcon(7, 1)) n.invert = 0;
|
||||||
ImGui::SameLine(0, 10);
|
ImGui::SameLine(0, 10);
|
||||||
|
|||||||
@@ -38,7 +38,8 @@ public:
|
|||||||
// filter identifyer
|
// filter identifyer
|
||||||
// [0] No filter
|
// [0] No filter
|
||||||
// [1 4] 4 x kernel operations; Blur, Sharpen, Edge, Emboss
|
// [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;
|
int filterid;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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 (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);
|
minValue = min(texture(iChannel0, vertexUV + vec2 (0.0, 1.0) * filter_step ).rgb, minValue);
|
||||||
if (N == 3)
|
if (N < 1)
|
||||||
return minValue;
|
return minValue;
|
||||||
minValue = min(texture(iChannel0, vertexUV + vec2 (-1.0, -2.0) * filter_step ).rgb, 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);
|
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, -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);
|
||||||
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;
|
return minValue;
|
||||||
minValue = min(texture(iChannel0, vertexUV + vec2 (-1.0, -3.0) * filter_step ).rgb, 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);
|
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 (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);
|
maxValue = max(texture(iChannel0, vertexUV + vec2 (0.0, 1.0) * filter_step ).rgb, maxValue);
|
||||||
if (N == 3)
|
if (N < 1)
|
||||||
return maxValue;
|
return maxValue;
|
||||||
maxValue = max(texture(iChannel0, vertexUV + vec2 (-1.0, -2.0) * filter_step ).rgb, 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);
|
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, -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);
|
||||||
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;
|
return maxValue;
|
||||||
maxValue = max(texture(iChannel0, vertexUV + vec2 (-1.0, -3.0) * filter_step ).rgb, 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);
|
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;
|
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)
|
vec3 convolution(mat3 kernel, vec2 filter_step)
|
||||||
{
|
{
|
||||||
int i = 0, j = 0;
|
int i = 0, j = 0;
|
||||||
@@ -184,14 +223,16 @@ vec3 apply_filter() {
|
|||||||
|
|
||||||
vec2 filter_step = 1.f / textureSize(iChannel0, 0);
|
vec2 filter_step = 1.f / textureSize(iChannel0, 0);
|
||||||
|
|
||||||
if (filterid < 1 || filterid > 10)
|
if (filterid < 1 || filterid > 11)
|
||||||
return texture(iChannel0, vertexUV).rgb;
|
return texture(iChannel0, vertexUV).rgb;
|
||||||
else if (filterid < 5)
|
else if (filterid < 5)
|
||||||
return convolution( KERNEL[filterid], filter_step);
|
return convolution( KERNEL[filterid], filter_step);
|
||||||
else if (filterid < 8)
|
else if (filterid < 6)
|
||||||
return erosion( 3 + (filterid -5) * 2, filter_step);
|
return opening(filter_step);
|
||||||
|
else if (filterid < 9)
|
||||||
|
return erosion( filterid - 6 , filter_step);
|
||||||
else
|
else
|
||||||
return dilation( 3 + (filterid -8) * 2, filter_step);
|
return dilation( filterid - 9, filter_step);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Reference in New Issue
Block a user