1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
package bjc.imgchain.pipeline.stages;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import javax.swing.JComponent;
import javax.swing.JPanel;
import bjc.imgchain.pipeline.StageType;
import bjc.imgchain.utils.LabeledInputPanel;
/**
* Stage which runs a gaussian blur over an image.
* @author Ben Culkin
*
*/
public class GaussStage extends AbstractPipelineStage {
private int m;
private double sig, k;
/**
* Create a new gaussian blur stage.
*/
public GaussStage() {
super(StageType.IMGTRANS);
}
@Override
public Image process(Image inp) {
BufferedImage buf = (BufferedImage) inp;
ConvolveOp cop = new ConvolveOp(genKern());
BufferedImage ret = cop.createCompatibleDestImage(buf, null);
cop.filter(buf, ret);
return ret;
}
/* @TODO 5 Oct, 2020 - Ben Culkin - :GaussianDoc
*
* Should document this better, when I get a chance to relookup the applicable math.
*/
private Kernel genKern() {
float[][] w = new float[m][m];
float sum = 0.0f;
for (int i = 0; i < m - 1; i++) {
for (int j = 0; j < m - 1; j++) {
double s = i - (m / 2.0);
double t = j - (m / 2.0);
double r2 = (s * s) + (t * t);
double frac = r2 / (2.0 * sig * sig);
double val = k * Math.exp(-frac);
int idx1 = m - i;
int idx2 = m - j;
float fval = (float) val;
w[idx1 - 1][idx2 - 1] = fval;
sum += fval;
}
}
// Shouldn't we be doing something with this?
@SuppressWarnings("unused")
float invsum = 1 / sum;
float[] dat = new float[m * m];
for (int i = 0; i < m; i++) {
for (int j = 0; j < m; j++) {
dat[(i * m) + j] = w[i][j] * sum;
}
}
return new Kernel(m, m, dat);
}
@Override
public String name() {
return "Gaussian";
}
@Override
public String description() {
return "Perform a gaussian blur";
}
@Override
public JComponent getEditor() {
JPanel holder = new JPanel();
holder.setLayout(new GridLayout(3, 1));
LabeledInputPanel mField = new LabeledInputPanel("Size of kernel", 3);
mField.field.addPropertyChangeListener("value", (ev) -> {
m = (Integer) mField.field.getValue();
});
LabeledInputPanel sigField = new LabeledInputPanel("Value for sigma", 3.0);
sigField.field.addPropertyChangeListener("value", (ev) -> {
sig = (Double) sigField.field.getValue();
});
LabeledInputPanel kField = new LabeledInputPanel("Value for k", 1.0);
kField.field.addPropertyChangeListener("value", (ev) -> {
k = (Double) kField.field.getValue();
});
holder.add(mField);
holder.add(sigField);
holder.add(kField);
return holder;
}
}
|