package dwttest; import java.util.Arrays; import math.transform.jwave.Transform; import math.transform.jwave.handlers.DiscreteWaveletTransform; import math.transform.jwave.handlers.TransformInterface; import math.transform.jwave.handlers.wavelets.Daub04; import processing.core.PApplet; import processing.core.PImage; @SuppressWarnings("serial") public class DWTTest extends PApplet { int threshold = 5, depth = 1; Transform t = new Transform( (TransformInterface) new DiscreteWaveletTransform(new Daub04(), threshold)); double[][] matHilb; boolean[] keys = new boolean[526]; public void setup() { PImage img = loadImage("data/duc_006_2005_00_1024x768_ducati-monster-620.jpg"); // PImage img = loadImage("data/2007_MV_Brutale_910_1r.jpg"); size(512, 512, JAVA2D); background(0); img.resize(this.width, this.height); // img = getImage(getData(img)); matHilb = getData(img); for (int i = 0; i < depth; i++) matHilb = t.forward(matHilb); // 2-D FWT Haar forward getMinMax(matHilb, 0,0,512,512); image(getImage(matHilb), 0, 0); } public void keyPressed() { double[][] data = dup(matHilb); boolean inverse = true, cumulative = true; keys[keyCode] = true; cumulative = !checkKey(CONTROL); switch (key) { case 'z': inverse = false; break; default: if (key > '0' && key <= '9') discard(data, key - '0', cumulative); } if (inverse) for (int i = 0; i < depth; i++) data = t.reverse(data); // 2-D FWT Haar reverse image(getImage(data), 0, 0); } public void keyReleased() { keys[keyCode] = false; } public void draw() { } double[][] getData(PImage img) { int wid = img.width, hei = img.height, i, j; double[][] ret = new double[hei][wid]; double val; img.loadPixels(); for (j = 0; j < hei; j++) for (i = 0; i < wid; i++) { // Extract luminance (the Y of YUV) from RBG val = 0.299 * red(img.pixels[j * wid + i]) + 0.587 * green(img.pixels[j * wid + i]) + 0.114 * blue(img.pixels[j * wid + i]); val /= 255.0; ret[j][i] = val; } return ret; } PImage getImage(double[][] data) { int hei = data.length, wid = data[0].length, i, j; PImage ret = createImage(wid, hei, RGB); ret.loadPixels(); for (j = 0; j < hei; j++) for (i = 0; i < wid; i++) { ret.pixels[j * wid + i] = color(constrain( (int) (255 * Math.abs(data[j][i])), 0, 255)); } ret.updatePixels(); return ret; } PImage getImage(double[][] data, boolean scale) { int hei = data.length, wid = data[0].length, i, j, val; PImage ret = createImage(wid, hei, RGB); double max = 1, min = 0; ret.loadPixels(); if (scale) { min = max = data[0][0]; for (j = 0; j < hei; j++) for (i = 0; i < wid; i++) { min = (data[i][j] < min) ? data[i][j] : min; max = (data[i][j] > max) ? data[i][j] : max; } } for (j = 0; j < hei; j++) for (i = 0; i < wid; i++) { val = map(data[j][i], min, max, 0, 255); ret.pixels[j * wid + i] = color(val); } ret.updatePixels(); return ret; } private int map(double d, double min, double max, int i, int j) { return (int) (i + (d - min) * (j - i) / (max - min)); } private void discard(double[][] data, int level, boolean cumulative) { if (level > threshold || level < 1) return; int wid = (int) (this.width / Math.pow(2, level)), hei = (int) (this.height / Math .pow(2, level)); if (cumulative) { nullify(data, wid, 0, this.width - wid, this.height); nullify(data, 0, hei, wid, this.height - hei); } else { nullify(data, wid, 0, wid, hei * 2); nullify(data, 0, hei, wid, hei); } } private void nullify(double[][] data, int x, int y, int wid, int hei) { int j, xx = x + wid; for (j = y + hei - 1; j >= y; j--) { Arrays.fill(data[j], x, xx, 0.0); } } @SuppressWarnings("unused") private void round(double[][] array) { int a = array.length, b = array[0].length, i, j; for (j = 0; j < a; j++) for (i = 0; i < b; i++) { array[i][j] = (int) Math.round(array[i][j]); } } private void getMinMax(double[][] array, int x, int y, int wid, int hei) { int i, j, xx = x + wid; double max, min; min = max = array[x][y]; for (j = y + hei - 1; j >= y; j--) for (i = x + wid - 1; i >= x; i--) { min = (array[i][j] < min) ? array[i][j] : min; max = (array[i][j] > max) ? array[i][j] : max; } println("(min, max) = ( " + min + ", " + max + " )"); } // private double[] getSD(double[][] array) { // int i, j, xx = x + wid; // double max, min, mean; // min = max = array[x][y]; // // for (j = y + hei - 1; j >= y; j--) // for (i = x + wid - 1; i >= x; i--) { // min = (array[i][j] < min) ? array[i][j] : min; // max = (array[i][j] > max) ? array[i][j] : max; // } // // println("(min, max) = ( " + min + ", " + max + " )"); // // } private double[][] dup(double[][] array) { int a = array.length, b = array[0].length, i; double[][] ret = new double[a][b]; for (i = 0; i < a; i++) { System.arraycopy(array[i], 0, ret[i], 0, b); } return ret; } boolean checkKey(int k) { if (keys.length >= k) { return keys[k]; } return false; } public static void main(String _args[]) { PApplet.main(new String[] { dwttest.DWTTest.class.getName() }); } }