/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