001 package util.wavelet;
002 import java.util.List;
003 import static java.lang.Math.*;
004
005 /** A simple wavelet space contains a simple signal and its wavelet transform.
006 * <ol>
007 * <li>The original SimpleSignal
008 * <li>An ordered list of instances of SimpleSignal representing scales</li>
009 * <li>An instance of smoothed signal</li>
010 * </ol>
011 *
012 * @author John Talbot
013 */
014 public class SimpleWaveletSpace {
015
016 /** Reference to original signal. */
017 public SimpleSignal signal;
018
019 /** List of scales containing wavelet coefficients. */
020 public java.util.List<SimpleSignal> scales;
021
022 /** Last smoothed array as computed by the atrous wavelet transform. */
023 SimpleSignal smoothedSignal;
024
025 /**
026 * Construct a discrete wavelet transform using the 1D A-Trous method with a b3-spline
027 * smoothing function. (Starck 2002 p.29). Boundary conditions are handled by the simple signal object.
028 * @param signal the simple signal to be wavelet transformed
029 */
030 public SimpleWaveletSpace(SimpleSignal signal) {
031 this.signal = signal;
032 int maximumScale = signal.estimateNumberOfScales();
033 scales = new java.util.ArrayList<SimpleSignal>(maximumScale);
034 smoothedSignal = new SimpleSignal(signal);
035 int n = signal.size();
036 for (int scaleNumber = 0; scaleNumber < maximumScale; scaleNumber++) {
037 SimpleSignal scale = new SimpleSignal(smoothedSignal);
038 int step = (int)(pow(2.0d, (double) scaleNumber) + 0.5d);
039 int step2= step * 2;
040 for (int i = 0; i < n; i++) { // smooth with kernel (1/16, 1/4, 3/8, 1/4, 1/16)
041 smoothedSignal.setValue(i, 0.375f * scale.getValue(i)
042 + 0.25f * ( scale.getValue(i-step) + scale.getValue(i+step))
043 + 0.0625f * ( scale.getValue(i-step2) + scale.getValue(i-step2)));
044 }
045 scale.subtract(smoothedSignal);
046 scales.add(scale);
047 }
048 }
049
050 /** The maximum number of iterations used to obtain the continuum. */
051 static int MAX_ITERATIONS = 5;
052
053 /**
054 * Get the continuum of a signal. The continuum is computed by iteratively substracting
055 * the smoothed signal from the signal; the iteration is required due to border problems.
056 * (see Starck 1998 p.127).
057 * @return the continuum of the signal
058 */
059 public SimpleSignal getContinuum() {
060 int n = signal.size();
061 SimpleSignal continuum = new SimpleSignal(getSmoothedSignal());
062 SimpleSignal flattenedSignal = new SimpleSignal(n);
063 for (int iteration = 0; iteration < MAX_ITERATIONS; iteration++) {
064 SimpleSignal.subtract(signal, continuum, flattenedSignal);
065 SimpleWaveletSpace simpleWaveletSpace = new SimpleWaveletSpace(flattenedSignal);
066 continuum.add(simpleWaveletSpace.getSmoothedSignal());
067 }
068 return continuum;
069 }
070
071 /**
072 * Get the last smoothed array as computed by the atrous wavelet transform.
073 * @return the last smoothed array as a simple signal
074 */
075 public SimpleSignal getSmoothedSignal() {
076 return smoothedSignal;
077 }
078
079 /**
080 * Get the specified scale as computed by the atrous wavelet transform.
081 * @param scaleNumber the scale number
082 * @return the specified scale as an instance of simple signal
083 */
084 public SimpleSignal getScale(int scaleNumber) {
085 return scales.get(scaleNumber);
086 }
087
088 /**
089 * Set the scale at the specified scale number.
090 * @param scaleNumber the scale number
091 * @param scale the specified scale
092 */
093 public void setScale(int scaleNumber, SimpleSignal scale) {
094 scales.set(scaleNumber, scale);
095 }
096
097 /**
098 * Get the number of scales as computed by the atrous wavelet transform.
099 * @return the number of scales
100 */
101 public int getNumberOfScales() {
102 return scales.size();
103 }
104
105 /** Use the WObject as a mask to eliminate wavelet coefficients not in the object. */
106 public void mask(WObject wObject) {
107 // TODO:
108 }
109
110 /**
111 * Discrete wavelet transform reconstruction using the 1D A-Trous method with a b3-spline smoothing function.
112 * Reconstruction is computed by summing up all the scales plus the last smoothed array.
113 * (see Starck 1998 p.21-26).
114 * @return the reconstructed signal as an instance of simple signal
115 */
116 public SimpleSignal getReconstruction() {
117 SimpleSignal reconstruction = new SimpleSignal(signal.size());
118 for (SimpleSignal scale : scales) reconstruction.add(scale);
119 reconstruction.add(smoothedSignal);
120 return reconstruction;
121 }
122
123 /**
124 * Discrete wavelet transform reconstruction using the 1D A-Trous method with a b3-spline smoothing function.
125 * Reconstruction is computed by summing up all the structures belonging to the WObject plus the last smoothed array.
126 * (see Starck 1998 p.21-26).
127 * @return the reconstructed signal as an instance of simple signal
128 */
129 public SimpleSignal getReconstruction(WObject wObject) {
130 // TODO:
131 //for (int scale = 0; scale < scales.size(); scale++) {
132 // SimpleSignal coefficients = wObject.getStructures(scale);
133 //}
134 return getReconstruction();
135 }
136
137 }