Skip to content

Commit bcbea79

Browse files
authored
Merge pull request BradLarson#30 from Hyun-je/master
Add Median Filter
2 parents 70e1092 + e1dcd83 commit bcbea79

File tree

3 files changed

+126
-0
lines changed

3 files changed

+126
-0
lines changed

framework/GPUImage.xcodeproj/project.pbxproj

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,10 @@
268268
7B72DB292103CEB900A91156 /* AddBlend.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B72DB272103CEB900A91156 /* AddBlend.swift */; };
269269
7B72DB2B2103CED000A91156 /* AddBlend.metal in Sources */ = {isa = PBXBuildFile; fileRef = 7B72DB2A2103CED000A91156 /* AddBlend.metal */; };
270270
7B72DB2C2103CED000A91156 /* AddBlend.metal in Sources */ = {isa = PBXBuildFile; fileRef = 7B72DB2A2103CED000A91156 /* AddBlend.metal */; };
271+
96F24FEF22007D6D0042E78D /* MedianFilter.metal in Sources */ = {isa = PBXBuildFile; fileRef = 96F24FED22007D6C0042E78D /* MedianFilter.metal */; };
272+
96F24FF022007D6D0042E78D /* MedianFilter.metal in Sources */ = {isa = PBXBuildFile; fileRef = 96F24FED22007D6C0042E78D /* MedianFilter.metal */; };
273+
96F24FF122007D6D0042E78D /* MedianFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96F24FEE22007D6C0042E78D /* MedianFilter.swift */; };
274+
96F24FF222007D6D0042E78D /* MedianFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96F24FEE22007D6C0042E78D /* MedianFilter.swift */; };
271275
BC67D91820F815B60046D2C4 /* RenderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79E30E7320F11DD9005FA13C /* RenderView.swift */; };
272276
BC7BA27420F2BD1E006B5F4B /* ShaderUniformSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC7BA27320F2BD1E006B5F4B /* ShaderUniformSettings.swift */; };
273277
BC7BA27720F2C269006B5F4B /* BrightnessAdjustment.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC7BA27620F2C269006B5F4B /* BrightnessAdjustment.swift */; };
@@ -461,6 +465,8 @@
461465
7B25C0EB2103D5E9000EC621 /* ColorBlend.metal */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.metal; name = ColorBlend.metal; path = Source/Operations/ColorBlend.metal; sourceTree = "<group>"; };
462466
7B72DB272103CEB900A91156 /* AddBlend.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AddBlend.swift; path = Source/Operations/AddBlend.swift; sourceTree = "<group>"; };
463467
7B72DB2A2103CED000A91156 /* AddBlend.metal */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.metal; name = AddBlend.metal; path = Source/Operations/AddBlend.metal; sourceTree = "<group>"; };
468+
96F24FED22007D6C0042E78D /* MedianFilter.metal */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.metal; name = MedianFilter.metal; path = Source/Operations/MedianFilter.metal; sourceTree = "<group>"; };
469+
96F24FEE22007D6C0042E78D /* MedianFilter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MedianFilter.swift; path = Source/Operations/MedianFilter.swift; sourceTree = "<group>"; };
464470
BC7BA27320F2BD1E006B5F4B /* ShaderUniformSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ShaderUniformSettings.swift; path = Source/ShaderUniformSettings.swift; sourceTree = "<group>"; };
465471
BC7BA27620F2C269006B5F4B /* BrightnessAdjustment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = BrightnessAdjustment.swift; path = Source/Operations/BrightnessAdjustment.swift; sourceTree = "<group>"; };
466472
BC7BA27820F2C2CF006B5F4B /* BrightnessAdjustment.metal */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.metal; name = BrightnessAdjustment.metal; path = Source/Operations/BrightnessAdjustment.metal; sourceTree = "<group>"; };
@@ -646,6 +652,8 @@
646652
795ECAC221EF961F000EF927 /* LocalBinaryPattern.metal */,
647653
795ECAC521EF97F8000EF927 /* ColorLocalBinaryPattern.swift */,
648654
795ECAC821EF9806000EF927 /* ColorLocalBinaryPattern.metal */,
655+
96F24FED22007D6C0042E78D /* MedianFilter.metal */,
656+
96F24FEE22007D6C0042E78D /* MedianFilter.swift */,
649657
);
650658
name = "Image processing";
651659
sourceTree = "<group>";
@@ -924,6 +932,7 @@
924932
79CB6E0821092E330042F87B /* LuminosityBlend.swift in Sources */,
925933
7957438D20FE790E001EAE0A /* LuminanceRangeReduction.swift in Sources */,
926934
79A81C882100E1B700A3B43A /* LevelsAdjustment.swift in Sources */,
935+
96F24FF122007D6D0042E78D /* MedianFilter.swift in Sources */,
927936
795ECABD21EF920B000EF927 /* Laplacian.metal in Sources */,
928937
79DD50C7213450CB004EF308 /* SwirlDistortion.metal in Sources */,
929938
79E30E6620F10F72005FA13C /* BasicOperation.swift in Sources */,
@@ -1013,6 +1022,7 @@
10131022
79CB6DD22108B3F00042F87B /* ColorDodgeBlend.swift in Sources */,
10141023
79EB1B6E2125C7670049135E /* LookupFilter.metal in Sources */,
10151024
795ECA7D21E9095A000EF927 /* ZoomBlur.metal in Sources */,
1025+
96F24FEF22007D6D0042E78D /* MedianFilter.metal in Sources */,
10161026
BC7BA28F20F5A275006B5F4B /* PictureInput.swift in Sources */,
10171027
79CB6DDE2108C9160042F87B /* DifferenceBlend.swift in Sources */,
10181028
BC9294A421051346006C8E93 /* ColorMatrixFilter.metal in Sources */,
@@ -1083,6 +1093,7 @@
10831093
79CB6E0921092E330042F87B /* LuminosityBlend.swift in Sources */,
10841094
7957438E20FE790E001EAE0A /* LuminanceRangeReduction.swift in Sources */,
10851095
79A81C892100E1B700A3B43A /* LevelsAdjustment.swift in Sources */,
1096+
96F24FF222007D6D0042E78D /* MedianFilter.swift in Sources */,
10861097
795ECABE21EF920B000EF927 /* Laplacian.metal in Sources */,
10871098
79DD50C8213450CB004EF308 /* SwirlDistortion.metal in Sources */,
10881099
793D932620F66303008A7A6E /* Luminance.metal in Sources */,
@@ -1172,6 +1183,7 @@
11721183
79CB6DD32108B3F00042F87B /* ColorDodgeBlend.swift in Sources */,
11731184
79EB1B6F2125C7670049135E /* LookupFilter.metal in Sources */,
11741185
795ECA7E21E9095A000EF927 /* ZoomBlur.metal in Sources */,
1186+
96F24FF022007D6D0042E78D /* MedianFilter.metal in Sources */,
11751187
795B05D920F270FF00D1E759 /* MetalRendering.swift in Sources */,
11761188
79CB6DDF2108C9160042F87B /* DifferenceBlend.swift in Sources */,
11771189
BC9294A521051347006C8E93 /* ColorMatrixFilter.metal in Sources */,
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
#include <metal_stdlib>
2+
#include "TexelSamplingTypes.h"
3+
4+
using namespace metal;
5+
6+
#define s2(a, b) temp = a; a = min(a, b); b = max(temp, b);
7+
#define mn3(a, b, c) s2(a, b); s2(a, c);
8+
#define mx3(a, b, c) s2(b, c); s2(a, c);
9+
10+
#define mnmx3(a, b, c) mx3(a, b, c); s2(a, b); // 3 exchanges
11+
#define mnmx4(a, b, c, d) s2(a, b); s2(c, d); s2(a, c); s2(b, d); // 4 exchanges
12+
#define mnmx5(a, b, c, d, e) s2(a, b); s2(c, d); mn3(a, c, e); mx3(b, d, e); // 6 exchanges
13+
#define mnmx6(a, b, c, d, e, f) s2(a, d); s2(b, e); s2(c, f); mn3(a, b, c); mx3(d, e, f); // 7 exchanges
14+
15+
16+
17+
fragment half4 medianFilter(NearbyTexelVertexIO fragmentInput [[stage_in]],
18+
texture2d<half> inputTexture [[texture(0)]]) {
19+
20+
constexpr sampler quadSampler(coord::pixel);
21+
22+
half3 v[6];
23+
24+
v[0] = inputTexture.sample(quadSampler, fragmentInput.bottomLeftTextureCoordinate).rgb;
25+
v[1] = inputTexture.sample(quadSampler, fragmentInput.topRightTextureCoordinate).rgb;
26+
v[2] = inputTexture.sample(quadSampler, fragmentInput.topLeftTextureCoordinate).rgb;
27+
v[3] = inputTexture.sample(quadSampler, fragmentInput.bottomRightTextureCoordinate).rgb;
28+
v[4] = inputTexture.sample(quadSampler, fragmentInput.leftTextureCoordinate).rgb;
29+
v[5] = inputTexture.sample(quadSampler, fragmentInput.rightTextureCoordinate).rgb;
30+
31+
32+
half3 temp;
33+
34+
mnmx6(v[0], v[1], v[2], v[3], v[4], v[5]);
35+
36+
v[5] = inputTexture.sample(quadSampler, fragmentInput.bottomTextureCoordinate).rgb;
37+
38+
mnmx5(v[1], v[2], v[3], v[4], v[5]);
39+
40+
v[5] = inputTexture.sample(quadSampler, fragmentInput.topTextureCoordinate).rgb;
41+
42+
mnmx4(v[2], v[3], v[4], v[5]);
43+
44+
v[5] = inputTexture.sample(quadSampler, fragmentInput.textureCoordinate).rgb;
45+
46+
mnmx3(v[3], v[4], v[5]);
47+
48+
return half4(v[4], 1.0);
49+
50+
}
51+
52+
53+
/*
54+
55+
varying vec2 textureCoordinate;
56+
varying vec2 leftTextureCoordinate;
57+
varying vec2 rightTextureCoordinate;
58+
59+
varying vec2 topTextureCoordinate;
60+
varying vec2 topLeftTextureCoordinate;
61+
varying vec2 topRightTextureCoordinate;
62+
63+
varying vec2 bottomTextureCoordinate;
64+
varying vec2 bottomLeftTextureCoordinate;
65+
varying vec2 bottomRightTextureCoordinate;
66+
67+
uniform sampler2D inputImageTexture;
68+
69+
#define s2(a, b) temp = a; a = min(a, b); b = max(temp, b);
70+
#define mn3(a, b, c) s2(a, b); s2(a, c);
71+
#define mx3(a, b, c) s2(b, c); s2(a, c);
72+
73+
#define mnmx3(a, b, c) mx3(a, b, c); s2(a, b); // 3 exchanges
74+
#define mnmx4(a, b, c, d) s2(a, b); s2(c, d); s2(a, c); s2(b, d); // 4 exchanges
75+
#define mnmx5(a, b, c, d, e) s2(a, b); s2(c, d); mn3(a, c, e); mx3(b, d, e); // 6 exchanges
76+
#define mnmx6(a, b, c, d, e, f) s2(a, d); s2(b, e); s2(c, f); mn3(a, b, c); mx3(d, e, f); // 7 exchanges
77+
78+
void main()
79+
{
80+
vec3 v[6];
81+
82+
v[0] = texture2D(inputImageTexture, bottomLeftTextureCoordinate).rgb;
83+
v[1] = texture2D(inputImageTexture, topRightTextureCoordinate).rgb;
84+
v[2] = texture2D(inputImageTexture, topLeftTextureCoordinate).rgb;
85+
v[3] = texture2D(inputImageTexture, bottomRightTextureCoordinate).rgb;
86+
v[4] = texture2D(inputImageTexture, leftTextureCoordinate).rgb;
87+
v[5] = texture2D(inputImageTexture, rightTextureCoordinate).rgb;
88+
// v[6] = texture2D(inputImageTexture, bottomTextureCoordinate).rgb;
89+
// v[7] = texture2D(inputImageTexture, topTextureCoordinate).rgb;
90+
vec3 temp;
91+
92+
mnmx6(v[0], v[1], v[2], v[3], v[4], v[5]);
93+
94+
v[5] = texture2D(inputImageTexture, bottomTextureCoordinate).rgb;
95+
96+
mnmx5(v[1], v[2], v[3], v[4], v[5]);
97+
98+
v[5] = texture2D(inputImageTexture, topTextureCoordinate).rgb;
99+
100+
mnmx4(v[2], v[3], v[4], v[5]);
101+
102+
v[5] = texture2D(inputImageTexture, textureCoordinate).rgb;
103+
104+
mnmx3(v[3], v[4], v[5]);
105+
106+
gl_FragColor = vec4(v[4], 1.0);
107+
}
108+
109+
*/
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
public class MedianFilter: TextureSamplingOperation {
2+
public init() {
3+
super.init(fragmentFunctionName:"medianFilter")
4+
}
5+
}

0 commit comments

Comments
 (0)