/Users/lyon/j4p/src/ip/gui/frames/WaveletFrame.java
|
1 package ip.gui.frames;
2
3 // to run use:
4 // ip.gui.WaveletFrame
5
6 import ip.transforms.Lifting;
7 import utils.Print;
8
9 import java.awt.*;
10 import java.awt.event.ActionEvent;
11
12 public class WaveletFrame extends FFTFrame {
13
14 private Menu waveletMenu = getMenu("Wavelet");
15 private MenuItem forwardHaar_mi = addMenuItem(waveletMenu, "Forward Haar");
16 private MenuItem backwardHaar_mi = addMenuItem(waveletMenu, "Backward Haar");
17 private MenuItem liftingForwardHaar_mi = addMenuItem(waveletMenu, "LiftingForward Haar");
18 private MenuItem liftingBackwardHaar_mi = addMenuItem(waveletMenu, "LiftingBackward Haar");
19 private MenuItem demo1d_mi = addMenuItem(waveletMenu, "demo 1d");
20 private MenuItem demo2d_mi = addMenuItem(waveletMenu, "demo 2d");
21
22 private MenuItem haarCompress_mi = addMenuItem(waveletMenu, "[E-c]haarCompress");
23 private MenuItem stripimage_mi = addMenuItem(waveletMenu, "stripimage");
24
25 private MenuItem ulawEncode_mi = addMenuItem(waveletMenu, "ulaw encode");
26 private MenuItem ulawDecode_mi = addMenuItem(waveletMenu, "ulaw decode");
27 private MenuItem clip_mi = addMenuItem(waveletMenu, "clip");
28 private MenuItem clearQuad1_mi = addMenuItem(waveletMenu, "clear quad1");
29 private MenuItem clearQuad2_mi = addMenuItem(waveletMenu, "clear quad2");
30 private MenuItem clearQuad3_mi = addMenuItem(waveletMenu, "clear quad3");
31 private MenuItem clearLowerHalf_mi = addMenuItem(waveletMenu, "clear lower half");
32 private MenuItem clearLower34_mi = addMenuItem(waveletMenu, "clear lower 3/4");
33
34 private MenuItem stats_mi = addMenuItem(getFileMenu(), "compute stats");
35
36
37 public void actionPerformed(ActionEvent e) {
38
39 if (match(e, clearLowerHalf_mi)) {
40 clearLowerHalf();
41 return;
42 }
43 if (match(e, clearLower34_mi)) {
44 clearLower34();
45 return;
46 }
47 if (match(e, clearQuad3_mi)) {
48 clearQuad3();
49 return;
50 }
51 if (match(e, clearQuad1_mi)) {
52 clearQuad1();
53 return;
54 }
55 if (match(e, clearQuad2_mi)) {
56 clearQuad2();
57 return;
58 }
59 if (match(e, stripimage_mi)) {
60 stripimage();
61 return;
62 }
63 if (match(e, haarCompress_mi)) {
64 haarCompress();
65 return;
66 }
67 if (match(e, clip_mi)) {
68 clip();
69 return;
70 }
71 if (match(e, ulawDecode_mi)) {
72 ulawDecode();
73 return;
74 }
75 if (match(e, ulawEncode_mi)) {
76 ulawEncode();
77 return;
78 }
79 if (match(e, stats_mi)) {
80 stats();
81 return;
82 }
83
84 if (match(e, liftingForwardHaar_mi)) {
85 liftingForwardHaar();
86 return;
87 }
88 if (match(e, liftingBackwardHaar_mi)) {
89 liftingBackwardHaar();
90 return;
91 }
92 if (match(e, backwardHaar_mi)) {
93 backwardHaar();
94 return;
95 }
96 if (match(e, forwardHaar_mi)) {
97 forwardHaar();
98 return;
99 }
100
101 if (match(e, demo2d_mi)) {
102 demo2d();
103 return;
104 }
105 if (match(e, demo1d_mi)) {
106 demo1d();
107 return;
108 }
109 super.actionPerformed(e);
110 }
111
112 public void demo2d() {
113 int[][] i =
114 {
115 {9, 7, 5, 3},
116 {3, 5, 7, 9},
117 {2, 4, 6, 8},
118 {4, 6, 8, 10}
119 };
120 short x[][] = getShort(i);
121 print(x);
122 forwardHaar(x);
123 print(x);
124 }
125 public final static short[][] getShort(int a[][]){
126 short s[][] = new short[a.length][a[0].length];
127 for (int i=0; i < a.length; i++)
128 for (int j=0; j < a[0].length; j++)
129 s[i][j] = (short)a[i][j];
130 return s;
131 }
132
133 public void demo1d() {
134 int s[][] =
135 {
136 {9, 7, 5, 3},
137 {3, 5, 7, 9},
138 {2, 4, 6, 8},
139 {4, 6, 8, 10}
140 };
141 short x[][] = getShort(s);
142 print(x);
143 for (int i = 0; i < x.length; i++)
144 forwardHaar2(x[i]);
145 print(x);
146 }
147
148 public void print(short in[][]) {
149 for (int i = 0; i < in.length; i++) {
150 for (int j = 0; j < in[0].length; j++)
151 Print.print(in[i][j] + "\t");
152 Print.println("");
153 }
154 Print.println("-------------------");
155 }
156
157 public void forwardHaar() {
158 fh(shortImageBean.getR());
159 fh(shortImageBean.getG());
160 fh(shortImageBean.getB());
161 short2Image();
162 }
163
164 public void liftingForwardHaar() {
165 Lifting.forwardHaar(shortImageBean.getR());
166 Lifting.forwardHaar(shortImageBean.getG());
167 Lifting.forwardHaar(shortImageBean.getB());
168 short2Image();
169 }
170
171 public void liftingBackwardHaar() {
172 Lifting.backwardHaar(shortImageBean.getR());
173 Lifting.backwardHaar(shortImageBean.getG());
174 Lifting.backwardHaar(shortImageBean.getB());
175 short2Image();
176 }
177
178 public void fh(short in[][]) {
179 forwardHaar(in);
180 }
181
182 public void backwardHaar() {
183 backwardHaar(shortImageBean.getR());
184 backwardHaar(shortImageBean.getG());
185 backwardHaar(shortImageBean.getB());
186 clip();
187 }
188
189 private static void forwardHaar(short in[][]) {
190 int width = in.length;
191 int height = in[0].length;
192 short temp[] = new short[width];
193 for (int i = 0; i < width; i++)
194 forwardHaar2(in[i]);
195 for (int j = 0; j < height; j++) {
196 for (int i = 0; i < width; i++)
197 temp[i] = in[i][j];
198 forwardHaar2(temp);
199 for (int i = 0; i < width; i++)
200 in[i][j] = temp[i];
201 }
202 }
203
204
205 private void backwardHaar(short in[][]) {
206 int width = in.length;
207 int height = in[0].length;
208 short out[] = new short[width];
209 for (int i = 0; i < width; i++)
210 backwardHaar2(in[i]);
211 for (int j = 0; j < height; j++) {
212 for (int i = 0; i < width; i++)
213 out[i] = in[i][j];
214 backwardHaar2(out);
215 for (int i = 0; i < width; i++)
216 in[i][j] = out[i];
217 }
218 }
219
220 private static void forwardHaar2(short in[]) {
221 int n = in.length;
222 int nOn2 = n / 2;
223 if (n < 2) return;
224 for (int i = 0; i < n; i += 2) {
225 in[i + 1] -= in[i];
226 in[i] += in[i + 1] / 2;
227 }
228 short averages[] = new short[n / 2];
229 for (int i = nOn2 - 1; i >= 0; i--) {
230 averages[i] = in[2 * i];
231 in[i + nOn2] = in[2 * i + 1];
232 }
233 forwardHaar2(averages);
234 for (int i = 0; i < nOn2; i++)
235 in[i] = averages[i];
236 }
237
238 private void backwardHaar2(short in[]) {
239 int n = in.length;
240 if (n < 2) return;
241 int nOn2 = n / 2;
242
243 short averages[] = new short[nOn2];
244 for (int i = 0; i < nOn2; i++)
245 averages[i] = in[i];
246 backwardHaar2(averages);
247 for (int i = 0; i < nOn2; i++) {
248 in[2 * i] = averages[i];
249 in[2 * i + 1] = in[i + nOn2];
250 }
251 for (int i = 0; i < n; i += 2) {
252 in[i] -= in[i + 1] / 2;
253 in[i + 1] += in[i];
254 }
255 }
256
257 public int[][] short2Int(short s[][]) {
258 int a[][] = new int[getImageWidth()][getImageHeight()];
259 for (int x = 0; x < getImageWidth(); x++)
260 for (int y = 0; y < getImageHeight(); y++)
261 a[x][y] = s[x][y];
262 return a;
263 }
264
265 public short[][] int2Short(int s[][]) {
266 short a[][] = new short[getImageWidth()][getImageHeight()];
267 for (int x = 0; x < getImageWidth(); x++)
268 for (int y = 0; y < getImageHeight(); y++)
269 a[x][y] = (short) s[x][y];
270 return a;
271 }
272
273 public WaveletFrame(String title) {
274 super(title);
275 getXformMenu().add(waveletMenu);
276 }
277
278
279 /**
280 print statistics on the image
281 */
282 public void stats() {
283 int max[] = {-10000, -1000, -1000};
284 int min[] = {10000, 1000, 1000};
285 double average[] = new double[3];
286 for (int x = 0; x < getImageWidth(); x++)
287 for (int y = 0; y < getImageHeight(); y++) {
288 if (shortImageBean.getR()[x][y] > max[0]) max[0] = shortImageBean.getR()[x][y];
289 if (shortImageBean.getG()[x][y] > max[1]) max[1] = shortImageBean.getR()[x][y];
290 if (shortImageBean.getB()[x][y] > max[2]) max[2] = shortImageBean.getR()[x][y];
291 if (shortImageBean.getR()[x][y] < min[0]) min[0] = shortImageBean.getR()[x][y];
292 if (shortImageBean.getG()[x][y] < min[1]) min[1] = shortImageBean.getR()[x][y];
293 if (shortImageBean.getB()[x][y] < min[2]) min[2] = shortImageBean.getR()[x][y];
294 average[0] += shortImageBean.getR()[x][y];
295 average[1] += shortImageBean.getG()[x][y];
296 average[2] += shortImageBean.getB()[x][y];
297 }
298 int n = getImageWidth() * getImageHeight();
299 average[0] = average[0] / n;
300 average[1] = average[1] / n;
301 average[2] = average[2] / n;
302 Print.println("------ Statistics -----");
303 Print.println("\tR\tG\tB\t");
304 Print.println("min:" + min[0] + "\t" + min[1] + "\t" + min[2]);
305 Print.println("max:" + max[0] + "\t" + max[1] + "\t" + max[2]);
306 Print.println("avg:" + average[0] + "\t" + average[1] + "\t" + average[2]);
307 }
308
309 public static void main(String args[]) {
310 WaveletFrame wf = new WaveletFrame("wavelet frame");
311 wf.show();
312 }
313
314 public void ulawEncode() {
315 for (int x = 0; x < getImageWidth(); x++) {
316 shortImageBean.getR()[x] = UlawCodec.encode(shortImageBean.getR()[x]);
317 shortImageBean.getG()[x] = UlawCodec.encode(shortImageBean.getG()[x]);
318 shortImageBean.getB()[x] = UlawCodec.encode(shortImageBean.getB()[x]);
319 }
320 //add(128);
321 short2Image();
322 }
323
324 public void ulawDecode() {
325 for (int x = 0; x < getImageWidth(); x++) {
326 shortImageBean.getR()[x] = UlawCodec.decode(shortImageBean.getR()[x]);
327 shortImageBean.getG()[x] = UlawCodec.decode(shortImageBean.getG()[x]);
328 shortImageBean.getB()[x] = UlawCodec.decode(shortImageBean.getB()[x]);
329 }
330 //add(-128);
331 short2Image();
332 }
333
334
335 short eps = 0;
336
337 public void haarCompress() {
338 forwardHaar();
339 stripimage();
340 backwardHaar();
341 }
342
343 public void stripimage() {
344 eps += 5;
345 Print.println("Haar compress factor=" + eps);
346 for (int x = 0; x < getImageWidth(); x++)
347 for (int y = 0; y < getImageHeight(); y++) {
348 shortImageBean.getR()[x][y] = strip(shortImageBean.getR()[x][y], eps);
349 shortImageBean.getG()[x][y] = strip(shortImageBean.getG()[x][y], eps);
350 shortImageBean.getB()[x][y] = strip(shortImageBean.getB()[x][y], eps);
351 }
352 }
353
354 public void clearQuad1() {
355 clearQuad(getImageWidth() / 2, getImageHeight() / 2, getImageWidth(), getImageHeight());
356 short2Image();
357 }
358
359 public void clearQuad2() {
360 clearQuad(getImageWidth() / 2, 0, getImageWidth(), getImageHeight());
361 clearQuad(0, getImageHeight() / 2, getImageWidth(), getImageHeight());
362 short2Image();
363 }
364
365 public void clearQuad3() {
366 clearQuad(getImageWidth() / 4, 0, getImageWidth(), getImageHeight());
367 clearQuad(0, getImageHeight() / 4, getImageWidth(), getImageHeight());
368 short2Image();
369 }
370
371 public void clearLowerHalf() {
372 clearQuad(0, getImageHeight() / 2, getImageWidth(), getImageHeight());
373 short2Image();
374 }
375
376 public void clearLower34() {
377 clearQuad(0, getImageHeight() / 4, getImageWidth(), getImageHeight());
378 short2Image();
379 }
380
381 public void clearQuad(int x1, int y1, int x2, int y2) {
382 for (int x = x1; x < x2; x++)
383 for (int y = y1; y < y2; y++) {
384 shortImageBean.getR()[x][y] = 0;
385 shortImageBean.getG()[x][y] = 0;
386 shortImageBean.getB()[x][y] = 0;
387 }
388 }
389
390 public short strip(short i, short eps) {
391 if (Math.abs(i) < eps) return 0;
392 return i;
393 }
394
395 public void clip() {
396 for (int x = 0; x < getImageWidth(); x++)
397 for (int y = 0; y < getImageHeight(); y++) {
398 shortImageBean.getR()[x][y] = clip(shortImageBean.getR()[x][y]);
399 shortImageBean.getG()[x][y] = clip(shortImageBean.getG()[x][y]);
400 shortImageBean.getB()[x][y] = clip(shortImageBean.getB()[x][y]);
401 }
402 short2Image();
403 }
404
405 private short clip(short i) {
406 if (i < 0) return 0;
407 if (i > 255) return 255;
408 return i;
409 }
410
411 }
412
413 class UlawCodec {
414 public static double mu = 255.0;
415 public static double vmax = 255;
416 public static double offset = vmax / 2 + 2;
417 private static double factor = 22;
418 private static double muOnVmax = mu / vmax;
419
420 public static short[] encode(short a[]) {
421 for (int i = 0; i < a.length; i++)
422 a[i] = encode(a[i]);
423 return a;
424 }
425
426 public static short decode(short x) {
427 double a = (x - offset) / factor;
428 a = Math.exp(a) - 1;
429 a = a / muOnVmax;
430 return (short) a;
431 }
432
433 public static short encode(short x) {
434 return
435 (short) (offset + sign(x) * factor * Math.log(1 + Math.abs(x) * muOnVmax));
436 }
437
438 public static short sign(short x) {
439 if (x < 0) return -1;
440 return 1;
441 }
442
443 public static short[] decode(short a[]) {
444 for (int i = 0; i < a.length; i++)
445 a[i] = decode(a[i]);
446 return a;
447 }
448
449
450 }