/Users/lyon/j4p/src/j2d/ShortImageBean.java
|
1 package j2d;
2
3 import gui.Clipper;
4 import ip.transforms.Kernels;
5 import math.MathUtils;
6
7 import java.awt.*;
8 import java.io.Serializable;
9
10 /**
11 * GPL code by DocJava, Inc. User: lyon Date: Mar 5, 2003 Time: 5:44:03 PM
12 */
13 public class ShortImageBean implements Serializable {
14 private short r[][];
15 private short g[][];
16 private short b[][];
17 private Clipper clipper = new Clipper();
18
19 public ShortImageBean() {
20 }
21
22 public void swapGreenAndBlue() {
23 short temp[][] = getG();
24 setG(getB());
25 setB(temp);
26 }
27
28 public float getTotalNoisePower(ShortImageBean sib) {
29 float sum = 0;
30 float error = 0;
31 for (int x = 0; x < getWidth(); x++)
32 for (int y = 0; y < getHeight(); y++) {
33 final int dr = r[x][y] - sib.getR()[x][y];
34 final int dg = g[x][y] - sib.getG()[x][y];
35 final int db = b[x][y] - sib.getB()[x][y];
36 error = Math.abs(dr) + Math.abs(dg) + Math.abs(db);
37 sum = sum + error;
38 }
39 return sum;
40 }
41
42 public float getTotalSignalPower() {
43 float sum = 0;
44 float signal = 0;
45 for (int x = 0; x < getWidth(); x++)
46 for (int y = 0; y < getHeight(); y++) {
47 signal = r[x][y] +
48 g[x][y] +
49 b[x][y];
50 sum = sum + signal * signal;
51 }
52 return sum;
53 }
54
55 public ShortImageBean getImageFlowBean() {
56 float ns[][] = Kernels.getRobinson1();
57 float ew[][] = Kernels.getRobinson3();
58 Image maxImage = getImage();
59 ShortImageBean nsb =
60 new ShortImageBean(ImageUtils.convolution(maxImage, ns));
61 ShortImageBean ewb =
62 new ShortImageBean(ImageUtils.convolution(maxImage, ew));
63 short imaginaryPart[][] = nsb.getR();
64 short realPart[][] = ewb.getR();
65 int w = realPart.length;
66 int h = realPart[0].length;
67 ShortImageBean ifb = new ShortImageBean(w, h);
68 short rIfb[][] = ifb.getR();
69 int length = 1;
70 for (int x = 0; x < w; x++)
71 for (int y = 0; y < h; y++) {
72 double dy = imaginaryPart[x][y];
73 double dx = realPart[x][y];
74 // y = mx+b,b=y-m*x
75 //double b = y - x* dy/dx ;
76 //double x1=x+5;
77 //double y1=dy/dx * (x+5) + b;
78 dy = dy / dx;
79 if ((x % length) != 0) continue;
80 if ((y % length) != 0) continue;
81 if (x + length >= w) continue;
82 if (y + length * dy >= h) continue;
83 // use DDA to draw a short line segment
84 for (int i = 0; i < length; i++)
85 rIfb[x + i][(int) (y + i * dy)] = 255;
86 }
87 ifb.copyRedToGreenAndBlue();
88 return ifb;
89 }
90
91 /**
92 * average averages the input short image bean with the given short
93 * image bean <code> ShortImageBean sib, sib2; sib.average(sib2); This
94 * is like: a = avg(a,b); </code>
95 *
96 * @param sib
97 */
98 public void average(ShortImageBean sib) {
99 for (int x = 0; x < getWidth(); x++)
100 for (int y = 0; y < getHeight(); y++) {
101 r[x][y] =
102 (short) ((r[x][y] + sib.getR()[x][y]) / 2);
103 g[x][y] =
104 (short) ((g[x][y] + sib.getG()[x][y]) / 2);
105 b[x][y] =
106 (short) ((b[x][y] + sib.getB()[x][y]) / 2);
107 }
108 }
109
110 public ShortImageBean(int w, int h) {
111 r = new short[w][h];
112 g = new short[w][h];
113 b = new short[w][h];
114 }
115
116 public static ShortImageBean
117 getShortImageBean(ShortImageBean sib) {
118 int w = sib.getWidth();
119 int h = sib.getHeight();
120 ShortImageBean nsib = new ShortImageBean(w, h);
121 short _r[][] = nsib.getR();
122 short _g[][] = nsib.getG();
123 short _b[][] = nsib.getB();
124 for (int x = 0; x < w; x++)
125 for (int y = 0; y < h; y++) {
126 _r[x][y] = sib.getR()[x][y];
127 _g[x][y] = sib.getG()[x][y];
128 _b[x][y] = sib.getB()[x][y];
129 }
130 return nsib;
131 }
132
133 public Clipper getClipper() {
134 return clipper;
135 }
136
137 public int getWidth() {
138 return r.length;
139 }
140
141 public int getHeight() {
142 return r[0].length;
143 }
144
145 public ShortImageBean(Image img) {
146 setImage(img);
147 }
148
149 public Image getImage() {
150 return ImageUtils.getImage(r, g, b);
151 }
152
153 public void setImage(Image img) {
154 int w = img.getWidth(null);
155 int h = img.getHeight(null);
156 short[][] r1 = new short[w][h];
157 r = r1;
158 short[][] g1 = new short[w][h];
159 g = g1;
160 short[][] b1 = new short[w][h];
161 b = b1;
162 ImageUtils.pelsToShort(r, g, b,
163 ImageUtils.getPels(img,
164 w,
165 h),
166 w, h);
167 }
168
169 /**
170 * convert the image to gray scale by taking the average of the red,
171 * green and blue colors. It is silly, but fast.
172 */
173 public void gray() {
174 for (int x = 0; x < getWidth(); x++)
175 for (int y = 0; y < getHeight(); y++) {
176 r[x][y] = (short)
177 ((r[x][y] + g[x][y] + b[x][y]) / 3);
178 g[x][y] = r[x][y];
179 b[x][y] = r[x][y];
180 }
181 }
182
183 /*
184 public void colorToRed2() {
185 for (int x = 0; x < getImageWidth(); x++)
186 for (int y = 0; y < getImageHeight(); y++)
187 getR()[x][y] = (short)
188 ((getR()[x][y] + getG()[x][y] + getB()[x][y]) / 3);
189 }
190 */
191 /**
192 * Copy all colors to red plane, using an average operation. <code>
193 * ShortImageBean.colorToRed(sib); r = (r+g+b)/3;
194 * <p/>
195 * </code>
196 *
197 * @param sib
198 */
199 public static void colorToRed(ShortImageBean sib) {
200 for (int x = 0; x < sib.getWidth(); x++)
201 for (int y = 0; y < sib.getHeight(); y++)
202 sib.r[x][y] = (short)
203 ((sib.r[x][y] +
204 sib.g[x][y] +
205 sib.b[x][y]) / 3);
206 }
207
208 public static void clip(ShortImageBean sib) {
209 int w = sib.getWidth();
210 int h = sib.getHeight();
211 for (int x = 0; x < w; x++)
212 for (int y = 0; y < h; y++) {
213 if (sib.r[x][y] > 255) sib.r[x][y] = 255;
214 if (sib.g[x][y] > 255) sib.g[x][y] = 255;
215 if (sib.b[x][y] > 255) sib.b[x][y] = 255;
216 if (sib.r[x][y] < 0) sib.r[x][y] = 0;
217 if (sib.g[x][y] < 0) sib.g[x][y] = 0;
218 if (sib.b[x][y] < 0) sib.b[x][y] = 0;
219 }
220 }
221
222 public void saltAndPepper(int n) {
223 for (int i = 0; i < n; i++) {
224 int rx = MathUtils.rand(0, getWidth() - 1);
225 int ry = MathUtils.rand(0, getHeight() - 1);
226 r[rx][ry] = 255;
227 g[rx][ry] = 255;
228 b[rx][ry] = 255;
229 rx = MathUtils.rand(0, getWidth() - 1);
230 ry = MathUtils.rand(0, getHeight() - 1);
231 r[rx][ry] = 0;
232 g[rx][ry] = 0;
233 b[rx][ry] = 0;
234 }
235 }
236
237 public void add(int n) {
238 for (int x = 0; x < getWidth(); x++)
239 for (int y = 0; y < getHeight(); y++) {
240 r[x][y] = (short) (r[x][y] + n);
241 g[x][y] = (short) (g[x][y] + n);
242 b[x][y] = (short) (b[x][y] + n);
243 }
244 }
245
246 public void negate() {
247 for (int x = 0; x < getWidth(); x++)
248 for (int y = 0; y < getHeight(); y++) {
249 r[x][y] = (short) (255 - r[x][y]);
250 g[x][y] = (short) (255 - g[x][y]);
251 b[x][y] = (short) (255 - b[x][y]);
252 }
253 clip(this);
254 }
255
256 public void copyRedToGreenAndBlue() {
257 g = new short[getWidth()][getHeight()];
258 b = new short[getWidth()][getHeight()];
259 for (int x = 0; x < getWidth(); x++)
260 for (int y = 0; y < getHeight(); y++) {
261 g[x][y] = r[x][y];
262 b[x][y] = r[x][y];
263 }
264 }
265
266 public static void subtract(ShortImageBean sibA, ShortImageBean sibB) {
267 for (int i = 0; i < sibB.getWidth(); i++)
268 for (int j = 0; j < sibB.getHeight(); j++) {
269 sibA.r[i][j] = (short) (sibA.r[i][j]
270 - sibB.r[i][j]);
271 sibA.g[i][j] = (short) (sibA.g[i][j]
272 - sibB.g[i][j]);
273 sibA.b[i][j] = (short) (sibA.b[i][j]
274 - sibB.b[i][j]);
275 }
276 }
277
278 public int getAverage(int x, int y) {
279 return (r[x][y] + g[x][y] + b[x][y]) / 3;
280 }
281
282 public short[][] getR() {
283 return r;
284 }
285
286 public void setR(short[][] r) {
287 this.r = r;
288 }
289
290 public short[][] getG() {
291 return g;
292 }
293
294 public void setG(short[][] g) {
295 this.g = g;
296 }
297
298 public short[][] getB() {
299 return b;
300 }
301
302 public void setB(short[][] b) {
303 this.b = b;
304 }
305
306 public int[] getPels() {
307 final int w = getWidth();
308 final int h = getHeight();
309 int pels[] = new int[w * h];
310
311 for (int x = 0; x < w; x++) {
312
313 for (int y = 0; y < h; y++) {
314 pels[x + y * w] =
315 0xff000000
316 |
317 (getR()[x][y] << 16)
318 |
319 (getG()[x][y] << 8)
320 | getB()[x][y];
321 }
322 }
323 return pels;
324 }
325 public double getSNRinDb(ShortImageBean sib) {
326 if (sib == null) {
327 System.out.println("sib=null!");
328 return 0;
329 }
330 // Math.log is a natural log
331 // but want a common log.
332 // To Convert to a base 10 log divide by the ln(10).
333 final float totalSignalPower = getTotalSignalPower();
334 final float totalNoisePower = getTotalNoisePower(sib);
335 return 10 * Math.log(totalSignalPower /totalNoisePower)/Math.log(10);
336 }
337 public static void linearCut(short a[][], int numberOfBitsToCut) {
338 int mask = 255 << numberOfBitsToCut;
339 int w = a.length;
340 int h = a[0].length;
341 for (int x = 0; x < w; x++)
342 for (int y = 0; y < h; y++)
343 a[x][y] = (short) (a[x][y] & mask);
344 }
345
346 public void scale(int scale) {
347 final int width = getWidth();
348 int nw = width * scale;
349 final int height = getHeight();
350 int nh = height * scale;
351 short sr[][] = new short[nw][nh];
352 short sg[][] = new short[nw][nh];
353 short sb[][] = new short[nw][nh];
354 for (int y = 0; y < height; y++)
355 for (int j = 0; j < nw; j++)
356 for (int x = 0; x < width; x++)
357 for (int i = 0; i < nh; i++) {
358 sr[i][j] = getR()[x][y];
359 sg[i][j] = getG()[x][y];
360 sb[i][j] = getB()[x][y];
361 }
362 setR(sr);
363 setG(sg);
364 setB(sb);
365 }
366 }