/Users/lyon/j4p/src/ip/transforms/ConvolutionUtils.java

1    package ip.transforms; 
2     
3    import j2d.ImageUtils; 
4    import j2d.ShortImageBean; 
5    import j2d.ImagePanel; 
6    import math.Mat2; 
7    import math.MathUtils; 
8     
9    import java.awt.*; 
10   import java.awt.image.ImageObserver; 
11   import java.io.File; 
12    
13   import graphics.NumImage; 
14   import gui.ClosableJFrame; 
15    
16    
17   public class ConvolutionUtils { 
18       static double t0 = 0; 
19       static double t1 = 0; 
20       static double t2 = 0; 
21       static double t3 = 0; 
22       static double t4 = 0; 
23       static double t5 = 0; 
24       static double t6 = 0; 
25       static double t7 = 0; 
26       static double t8 = 0; 
27       static double t9 = 0; 
28       static double t10 = 0; 
29       static double t11 = 0; 
30       static double t12 = 0; 
31       static double t13 = 0; 
32       static double t14 = 0; 
33       static double t15 = 0; 
34       static double t16 = 0; 
35       static double t17 = 0; 
36       static double t18 = 0; 
37       static double t19 = 0; 
38       static double t20 = 0; 
39       static double t21 = 0; 
40       static double t22 = 0; 
41       static double t23 = 0; 
42       static double t24 = 0; 
43       static double t25 = 0; 
44       static double t26 = 0; 
45       static double t27 = 0; 
46       static double t28 = 0; 
47       static double t29 = 0; 
48       static double t30 = 0; 
49       static double t31 = 0; 
50       static double t32 = 0; 
51       static double t33 = 0; 
52       static double t34 = 0; 
53       static double t35 = 0; 
54       static double t36 = 0; 
55       static double t37 = 0; 
56       static double t38 = 0; 
57       static double t39 = 0; 
58       static double t40 = 0; 
59       static double t41 = 0; 
60       static double t42 = 0; 
61       static double t43 = 0; 
62    
63       public static void drawPel(Graphics g, int x, int y) { 
64           int dGrid = 10; 
65           int x1 = x * dGrid; 
66           int y1 = y * dGrid; 
67           int h = dGrid / 2; 
68           g.drawOval(x1 - h, y1 - h, dGrid, dGrid); 
69       } 
70    
71       public static void drawPel(Graphics g, Point p) { 
72           drawPel(g, p.x, p.y); 
73       } 
74    
75       public static void testConvolution(String args[]) { 
76           File f = new File("Users/lyon/current/java/j4p/dataFiles/images/orl_faces/assortment/jpg/s6_11.jpg"); 
77           System.out.println(f); 
78           Image img = ImageUtils.getGifJpgPngImage(f); 
79           ImageUtils.convolution(img, Kernels.getLaplacian9()); 
80    
81       } 
82    
83       private static void oddTest() { 
84           System.out.println("24 is odd:" + MathUtils.odd(24) + 
85                   " 13 is odd:" + MathUtils.odd(13)); 
86       } 
87    
88       public static Image convolution(Image img, float k[][], ImageObserver io) { 
89           short orig[][] = ImageUtils.getGreenFromImage(img, io); 
90           orig = Mat2.clip(ConvolutionUtils.convolve(orig, k)); 
91           return ImageUtils.getImage(orig); 
92       } 
93    
94       public static void main(String[] args) { 
95           testGrowTile(); 
96           //testCxCy(); 
97       } 
98    
99       public static void testGrowTile() { 
100          Image img = NumImage.getImage(); 
101          ImagePanel ip = new ImagePanel(img); 
102          ClosableJFrame cf = new ClosableJFrame(); 
103          Container c = cf.getContentPane(); 
104          c.setLayout(new FlowLayout()); 
105          c.add(ip); 
106          c.add(new ImagePanel(growTile(img, 70, 70))); 
107          cf.setSize(200, 200); 
108          cf.show(); 
109      } 
110   
111      public static Image growTile(Image img, int growX, int growY) { 
112          ShortImageBean sib = new ShortImageBean(img); 
113          short r [][] = sib.getR(); 
114          short g [][] = sib.getG(); 
115          short b [][] = sib.getB(); 
116          int oldWidth = sib.getWidth(); 
117          int oldHeight = sib.getHeight(); 
118          int newWidth = oldWidth + growX; 
119          int newHeight = oldHeight + growY; 
120          System.out.println("new Width=" + newWidth); 
121          System.out.println("new Height=" + newHeight); 
122          ShortImageBean sibNew = new ShortImageBean(newWidth, newHeight); 
123          short nr [][] = sibNew.getR(); 
124          short ng [][] = sibNew.getG(); 
125          short nb [][] = sibNew.getB(); 
126          for (int x = 0; x < newWidth; x++) { 
127              for (int y = 0; y < newHeight; y++) { 
128                  int otx = cx(x-growX/2, oldWidth); 
129                  int oty = cy(y-growY/2, oldHeight); 
130                  nr[x][y] = r[otx][oty]; 
131                  ng[x][y] = g[otx][oty]; 
132                  nb[x][y] = b[otx][oty]; 
133              } 
134          } 
135          return sibNew.getImage(); 
136      } 
137   
138      public static void testCxCy() { 
139          int width = 3; 
140          int height = 3; 
141          int gx = 6; 
142          int gy = 6; 
143          for (int x = -gx; x < width + gx; x++) { 
144              for (int y = -gy; y < height + gy; y++) { 
145                  int tx = cx(x, width); 
146                  int ty = cy(y, height); 
147                  System.out.print(tx + "," + ty + " "); 
148              } 
149              System.out.println(); 
150          } 
151      } 
152   
153      public static int cx(int x, int width) { 
154          if (x >= width ) 
155              return x % width; 
156          if (x < 0) 
157              return  (width  + x % width)%width; 
158          return x; 
159      } 
160   
161      public static int cy(int y, int height) { 
162          if (y >= height) 
163              return y % height; 
164          if (y < 0) 
165              return (height +  y % height)%height; 
166          return y; 
167      } 
168   
169      public static short[][] convolveBruteForce(short f[][], float k[][]) { 
170          int uc = k.length / 2; 
171          int vc = k[0].length / 2; 
172          int width = f.length; 
173          int height = f[0].length; 
174   
175          short h[][] = new short[width][height]; 
176          double sum = 0; 
177   
178          for (int y = 0; y < height; y++) { 
179              for (int x = 0; x < width; x++) { 
180                  convolvePixel(x, y, uc, vc, width, height, k, f, h); 
181              } 
182          } 
183          return h; 
184      } 
185   
186      private static void convolvePixel(int x, int y, 
187                                        int uc, int vc, 
188                                        int imageWidth, int imageHeight, 
189                                        float[][] kernel, 
190                                        short[][] inputImage, short[][] outputImage) { 
191          double sum; 
192          sum = 0.0; 
193          for (int v = -vc; v <= vc; v++) 
194              for (int u = -uc; u <= uc; u++) 
195                  sum += inputImage[cx(x - u, imageWidth)][cy(y - v, imageHeight)] * kernel[u + uc][v + vc]; 
196          //if (sum < 0) sum = 0; 
197          //if (sum > 255) sum = 255; 
198          outputImage[x][y] = (short) sum; 
199      } 
200   
201  // Convolution, optimze the edges 
202      public static short[][] convolve(short f[][], float k[][]) { 
203          if (k == null) return null; 
204          if (f == null) return null; 
205          if (!(MathUtils.odd(k.length) && MathUtils.odd(k[0].length))) { 
206              System.out.println("Error:kernel passed to convolution is not odd!"); 
207   
208          } 
209          int uc = k.length / 2; 
210          int vc = k[0].length / 2; 
211   
212          short h[][] = convolveNoEdge(f, k); 
213          double sum = 0; 
214          int width = f.length; 
215          int height = f[0].length; 
216          //convolve bottom 
217          for (int x = 0; x < width - 1; x++) 
218              for (int y = 0; y < vc; y++) { 
219                  sum = 0.0; 
220                  for (int v = -vc; v <= vc; v++) 
221                      for (int u = -uc; u <= uc; u++) 
222                          sum += f[cx(x - u, width)][cy(y - v, height)] * k[u + uc][v + vc]; 
223                  //if (sum < 0) sum = 0; 
224                  //if (sum > 255) sum = 255; 
225                  h[x][y] = (short) sum; 
226              } 
227          //convolve left 
228          for (int x = 0; x < uc; x++) 
229              for (int y = vc; y < height - vc; y++) { 
230   
231                  sum = 0.0; 
232                  for (int v = -vc; v <= vc; v++) 
233                      for (int u = -uc; u <= uc; u++) 
234                          sum += f[cx(x - u, height)][cy(y - v, height)] * k[u + uc][v + vc]; 
235                  //if (sum < 0) sum = 0; 
236                  //if (sum > 255) sum = 255; 
237                  h[x][y] = (short) sum; 
238              } 
239          //convolve right 
240          for (int x = width - uc; x < width - 1; x++) 
241              for (int y = vc; y < height - vc; y++) { 
242   
243                  sum = 0.0; 
244                  for (int v = -vc; v <= vc; v++) 
245                      for (int u = -uc; u <= uc; u++) 
246                          sum += f[cx(x - u, width)][y - v] * k[u + uc][v + vc]; 
247                  //if (sum < 0) sum = 0; 
248                  //if (sum > 255) sum = 255; 
249                  h[x][y] = (short) sum; 
250              } 
251   
252          //convolve top 
253          try { 
254              for (int x = 0; x < width - 1; x++) { 
255                  for (int y = height - vc; y < height - 1; y++) { 
256                      sum = 0.0; 
257                      for (int v = -vc; v <= vc; v++) 
258                          for (int u = -uc; u <= uc; u++) 
259                              sum += f[cx(x - u, f.length)][cy(y - v, f[0].length)] 
260                                      * k[u + uc][v + vc]; 
261                      //if (sum < 0) sum = 0; 
262                      //if (sum > 255) sum = 255; 
263                      h[x][y] = (short) sum; 
264                  } 
265              } 
266          } catch (Exception e) { 
267              e.printStackTrace(); 
268          } 
269          return h; 
270      } 
271  // Convolution, ignoring the edges 
272      public static short[][] convolveNoEdge(short f[][], float k[][]) { 
273          int uc = k.length / 2; 
274          int vc = k[0].length / 2; 
275          int width = f.length; 
276          int height = f[0].length; 
277          short h[][] = new short[width][height]; 
278          double sum = 0; 
279   
280          for (int x = uc; x < width - uc; x++) { 
281              for (int y = vc; y < height - vc; y++) { 
282   
283                  sum = 0.0; 
284                  for (int v = -vc; v <= vc; v++) 
285                      for (int u = -uc; u <= uc; u++) 
286                          sum += f[x - u][y - v] * k[u + uc][v + vc]; 
287                  //if (sum < 0) sum = 0; 
288                  //if (sum > 255) sum = 255; 
289                  h[x][y] = (short) sum; 
290              } 
291          } 
292          return h; 
293      } 
294   
295   
296      public static short[][] convolveBrute2(short f[][], float k[][]) { 
297          return convolveBruteForce(f, k); 
298      } 
299   
300      public static short[][] convolve2(short f[][], float k[][]) { 
301          //return convolveNoEdge2(f, k); 
302          return convolveBruteForce(f, k); 
303      } 
304   
305      public static short[][] convolveNoEdge2(short f[][], float k[][]) { 
306          return convolveNoEdge(f, k); 
307   
308      } 
309   
310   
311  } 
312   
313