/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  }