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 package org.openimaj.image.analysis.algorithm;
31
32 import org.openimaj.image.FImage;
33 import org.openimaj.image.analyser.ImageAnalyser;
34 import org.openimaj.math.util.Interpolation;
35
36
37
38
39
40
41
42
43 public class ImageInterpolation implements ImageAnalyser<FImage> {
44
45
46
47
48
49
50 public static interface Interpolator {
51
52
53
54
55
56
57
58
59
60
61
62
63
64 public float interpolate(float x, float y, FImage image, Object workingSpace);
65
66
67
68
69
70
71 public Object createWorkingSpace();
72 }
73
74
75
76
77
78
79
80 public static enum InterpolationType implements Interpolator {
81
82
83
84 NEAREST_NEIGHBOUR {
85 @Override
86 public float interpolate(float x, float y, FImage image, Object workingSpace) {
87 x = Math.round(x);
88 y = Math.round(y);
89
90 if (x < 0 || x >= image.width || y < 0 || y >= image.height)
91 return 0;
92
93 return image.pixels[(int) y][(int) x];
94 }
95
96 @Override
97 public Object createWorkingSpace() {
98 return null;
99 }
100 },
101
102
103
104 BILINEAR {
105 @Override
106 public float interpolate(float x, float y, FImage image, Object workingSpace) {
107 return image.getPixelInterpNative(x, y, 0);
108 }
109
110 @Override
111 public Object createWorkingSpace() {
112 return null;
113 }
114 },
115
116
117
118 BICUBIC {
119 @Override
120 public float interpolate(float x, float y, FImage image, Object workingSpace) {
121 final float[][] working = (float[][]) workingSpace;
122
123 final int sx = (int) Math.floor(x) - 1;
124 final int sy = (int) Math.floor(y) - 1;
125 final int ex = sx + 3;
126 final int ey = sy + 3;
127
128 for (int yy = sy, i = 0; yy <= ey; yy++, i++) {
129 for (int xx = sx, j = 0; xx <= ex; xx++, j++) {
130 final int px = xx < 0 ? 0 : xx >= image.width ? image.width - 1 : xx;
131 final int py = yy < 0 ? 0 : yy >= image.height ? image.height - 1 : yy;
132
133 working[i][j] = image.pixels[py][px];
134 }
135 }
136
137 final float dx = (float) (x - Math.floor(x));
138 final float dy = (float) (y - Math.floor(y));
139 return Interpolation.bicubicInterp(dx, dy, working);
140 }
141
142 @Override
143 public Object createWorkingSpace() {
144 return new float[4][4];
145 }
146 };
147 }
148
149 protected Interpolator interpolator;
150 protected Object workingSpace;
151 protected FImage image;
152
153
154
155
156
157
158
159 public ImageInterpolation(Interpolator interpolator) {
160 this.interpolator = interpolator;
161 this.workingSpace = interpolator.createWorkingSpace();
162 }
163
164 @Override
165 public void analyseImage(FImage image) {
166 this.image = image;
167 }
168
169
170
171
172
173
174
175
176
177
178 public float getPixelInterpolated(float x, float y) {
179 return interpolator.interpolate(x, y, image, workingSpace);
180 }
181 }