001: import java.awt.*;
002: import java.awt.image.*;
003: import java.awt.event.*;
004: import java.applet.*;
005: import java.io.*;
006: import JSci.maths.wavelet.symmlet8.*;
007:
008: /**
009: * This applet is meant to illustrate the FWT classes in JSci.
010: * It is both speedy and convenient for some
011: * intensive applications such as image processing.
012: *
013: * @author Daniel Lemire
014: */
015: public final class ImageTransform extends Applet {
016: final int W = 256;
017: final FastSymmlet8 fwt = new FastSymmlet8();
018: final float[][] mY = new float[W][W];
019: final float[][] mI = new float[W][W];
020: final float[][] mQ = new float[W][W];
021: Image lena;
022: Image lenaTransformed;
023:
024: public void init() {
025: System.err.println("(C) 1999 Daniel Lemire, Ph.D.");
026: setSize(2 * W, W);
027: System.err.println("Loading image...");
028: MediaTracker mt = new MediaTracker(this );
029: Class this class = this .getClass();
030: InputStream is = this class.getResourceAsStream("lena.gif");
031: if (is != null)
032: System.err.println("Image found...");
033: else
034: System.err.println("Image cannot be found!");
035: int b;
036: ByteArrayOutputStream bais = new ByteArrayOutputStream();
037: try {
038: while ((b = is.read()) != -1) {
039: bais.write(b);
040: }
041: } catch (IOException ioe) {
042: ioe.printStackTrace();
043: }
044: System.err.println("Image read...");
045: lena = Toolkit.getDefaultToolkit().createImage(
046: bais.toByteArray());
047: mt.addImage(lena, 0, W, W);
048: try {
049: mt.waitForAll();
050: } catch (InterruptedException ie) {
051: ie.printStackTrace();
052: }
053: System.err.println("Image loaded...");
054: int[] pixels = new int[W * W];
055: PixelGrabber pg = new PixelGrabber(lena, 0, 0, W, W, pixels, 0,
056: W);
057: try {
058: pg.grabPixels();
059: } catch (InterruptedException ie) {
060: ie.printStackTrace();
061: }
062: byte red, green, blue;
063: for (int k = 0; k < W; k++) {
064: for (int l = 0; l < W; l++) {
065: red = (byte) (((pixels[k * W + l] >> 16) & 0xFF) - 128);
066: green = (byte) (((pixels[k * W + l] >> 8) & 0xFF) - 128);
067: blue = (byte) ((pixels[k * W + l] & 0xFF) - 128);
068: mY[k][l] = (red * .299f + green * .587f + blue * .114f);
069: }
070: }
071: transform();
072: quantize();
073: final int two24 = twoPower(24);
074: final int two16 = twoPower(16);
075: final int two8 = twoPower(8);
076: for (int k = 0; k < W; k++) {
077: for (int l = 0; l < W; l++) {
078: pixels[k * W + l] = (int) mY[k][l] * two16
079: + (int) mY[k][l] * two8 + (int) mY[k][l]
080: - two24;
081: }
082: }
083: MemoryImageSource topmis = new MemoryImageSource(W, W, pixels,
084: 0, W);
085: lenaTransformed = createImage(topmis);
086: mt.addImage(lenaTransformed, 1, W, W);
087: try {
088: mt.waitForAll();
089: } catch (InterruptedException ie) {
090: ie.printStackTrace();
091: }
092: this .setFont(new Font("Default", Font.BOLD, 12));
093: }
094:
095: private static int twoPower(int exp) {
096: int result = 1;
097: for (int k = 0; k < exp; ++k)
098: result = 2 * result;
099: return result;
100: }
101:
102: public String getAppletInfo() {
103: return "This applet is meant to illustrate the FWT classes in JSci";
104: }
105:
106: private void transform() {
107: transformColumns();
108: transformRows();
109: }
110:
111: private void transformColumns() {
112: float[] ColumnVector = new float[W];
113: for (int col = 0; col < W; ++col) {
114: for (int row = 0; row < W; ++row)
115: ColumnVector[row] = mY[row][col];
116: fwt.transform(ColumnVector);
117: for (int row = 0; row < W; ++row)
118: mY[row][col] = ColumnVector[row];
119: }
120: }
121:
122: private void transformRows() {
123: for (int row = 0; row < W; ++row) {
124: fwt.transform(mY[row]);
125: }
126: }
127:
128: private void quantize() {
129: float max = mY[0][0];
130: float min = mY[0][0];
131: for (int k = 0; k < W; k++) {
132: for (int l = 0; l < W; l++) {
133: max = Math.max(mY[k][l], max);
134: min = Math.min(mY[k][l], min);
135: }
136: }
137: for (int k = 0; k < W; k++) {
138: for (int l = 0; l < W; l++) {
139: mY[k][l] = Math.round((mY[k][l] - min) / (max - min)
140: * 255.0);
141: }
142: }
143: }
144:
145: public void paint(Graphics g) {
146: FontMetrics fm = this .getFontMetrics(this .getFont());
147: int fontheight = fm.getHeight();
148: g.setColor(Color.white);
149: g.drawImage(lena, 0, 0, this );
150: g.drawImage(lenaTransformed, 256, 0, this );
151: g
152: .drawString(
153: "Real time computation of the Fast Wavelet Transform in Java",
154: 10, W - 4 * fontheight);
155: g.drawString("using " + (int) (Math.log(W) / Math.log(2) - 3)
156: + " iterations and Symmlet8 wavelets.", 10, W - 3
157: * fontheight);
158: g.drawString("(Only the Y channel is shown.)", 10, W - 2
159: * fontheight);
160: g.drawString(
161: "Notice how economical the FWT representation is!", 10,
162: W - fontheight);
163: }
164: }
|