Almost there, need to fix an rgb bug and add layer remove/add awareness hooks.
[trakem2.git] / Scale_Space.java
blobb8affda48aeaf0c070f9da65abdf45ac61899fea
1 import static mpi.fruitfly.math.General.*;
3 import mpi.fruitfly.general.*;
4 import mpi.fruitfly.math.datastructures.*;
5 import mpi.fruitfly.registration.*;
7 import imagescience.transform.*;
8 import imagescience.image.Image;
10 import ij.plugin.*;
11 import ij.gui.*;
12 import ij.*;
13 import ij.process.*;
15 import java.util.Iterator;
16 import java.util.Vector;
17 import java.awt.Color;
18 import java.awt.Polygon;
19 import java.awt.geom.AffineTransform;
20 import java.awt.GridBagConstraints;
21 import java.awt.Insets;
22 import java.awt.Panel;
23 import java.awt.TextField;
24 import java.awt.event.KeyEvent;
25 import java.awt.event.KeyListener;
26 import java.io.*;
28 import ini.trakem2.imaging.FloatProcessorT2;
31 public class Scale_Space implements PlugIn, KeyListener
33 // steps
34 private static String steps_str = "3";
35 private static int steps = 3;
37 // initial sigma
38 private static String initial_sigma_str = "1.6";
39 private static float initial_sigma = 1.6f;
41 public void run( String args )
43 if ( IJ.versionLessThan( "1.37i" ) ) return;
45 final ImagePlus imp = WindowManager.getCurrentImage();
46 if ( imp == null ) { System.out.println( "There are no images open" ); return; }
48 GenericDialog gd = new GenericDialog( "Scale space" );
49 gd.addStringField( "Steps per gaussian octave:", steps_str, 2 );
50 gd.addStringField( "Initial gaussian blur (Sigma):", initial_sigma_str, 2 );
51 final Vector< TextField > tfs = gd.getStringFields();
52 tfs.get( 0 ).addKeyListener( this );
53 gd.showDialog();
55 if (gd.wasCanceled()) return;
57 steps_str = gd.getNextString();
58 initial_sigma_str = gd.getNextString();
60 Affine a = new Affine();
62 try
64 steps = Integer.parseInt( steps_str );
66 catch ( Exception e )
68 throw new IllegalArgumentException( "Invalid steps value." );
71 try
73 initial_sigma = Float.parseFloat( initial_sigma_str );
75 catch ( Exception e )
77 throw new IllegalArgumentException( "Invalid Sigma value." );
79 if ( initial_sigma < 0.5 )
80 throw new IllegalArgumentException( "Invalid Sigma value, must not be smaller than 0.5)." );
82 ImageProcessor ip;
84 ip = imp.getProcessor().convertToFloat();
85 FloatArray2D fa = ImageArrayConverter.ImageToFloatArray2D( ip );
86 ImageFilter.enhance( fa, 1.0f );
88 fa = ImageFilter.computeGaussianFastMirror( fa, ( float )Math.sqrt( initial_sigma * initial_sigma - 0.25 ) );
91 FloatArray2DScaleOctave so = new FloatArray2DScaleOctave(
92 fa,
93 steps,
94 initial_sigma );
96 FloatArray2DSIFT sift = new FloatArray2DSIFT(
98 8 );
100 long start_time = System.currentTimeMillis();
101 System.out.print( "initializing scale space ..." );
102 sift.init( fa, steps, initial_sigma, 32, Math.max( fa.width, fa.height ) );
103 System.out.println( " took " + ( System.currentTimeMillis() - start_time ) + "ms" );
105 ImageStack stackScaleSpace = new ImageStack( imp.getWidth(), imp.getHeight() );
106 ImageStack stackDoG = new ImageStack( imp.getWidth(), imp.getHeight() );
107 //ImageStack stackGradientAmplitude = new ImageStack( imp.getWidth(), imp.getHeight() );
108 //ImageStack stackGradientOrientation = new ImageStack( imp.getWidth(), imp.getHeight() );
110 FloatArray2DScaleOctave[] sos = sift.getOctaves();
111 for ( int o = 0; o < sos.length; ++o )
113 FloatArray2DScaleOctave so = sos[ o ];
114 start_time = System.currentTimeMillis();
115 System.out.print( "building scale octave ..." );
116 so.build();
117 System.out.println( " took " + ( System.currentTimeMillis() - start_time ) + "ms" );
119 FloatArray2DScaleOctaveDoGDetector dog = new FloatArray2DScaleOctaveDoGDetector();
121 start_time = System.currentTimeMillis();
122 System.out.print( "identifying difference of gaussian extrema ..." );
123 dog.run( so );
124 System.out.println( " took " + ( System.currentTimeMillis() - start_time ) + "ms" );
126 FloatArray2D[] l = so.getL();
127 FloatArray2D[] d = so.getD();
129 for ( int i = 0; i < steps; ++i )
131 FloatArray2D ls = l[ i ];
132 FloatArray2D ds = d[ i ];
133 int os;
134 for ( int oi = o; oi > 0; --oi )
136 os = ( int )Math.pow( 2, oi - 1 );
137 int w = imp.getWidth();
138 int h = imp.getHeight();
139 for ( os = oi; os > 1; --os )
141 w = w / 2 + w % 2;
142 h = h / 2 + h % 2;
144 //System.out.println( "o: " + o + ", w: " + w + ", h: " + h );
145 FloatArray2D ld = new FloatArray2D( w, h );
146 FloatArray2D dd = new FloatArray2D( w, h );
147 FloatArray2DScaleOctave.upsample( ls, ld );
148 FloatArray2DScaleOctave.upsample( ds, dd );
149 ls = ld;
150 ds = dd;
152 os = ( int )Math.pow( 2, o );
153 FloatProcessor fp = new FloatProcessorT2( ls.width, ls.height );
154 ImageArrayConverter.FloatArrayToFloatProcessor( fp, ls );
155 fp.setMinAndMax( 0.0, 1.0 );
156 //ImageProcessor ipl = fp.convertToRGB();
157 ImageProcessor ipl = fp.duplicate();
158 ImageArrayConverter.FloatArrayToFloatProcessor( fp, ds );
159 fp.setMinAndMax( -1.0, 1.0 );
160 ImageProcessor ipd = fp.convertToRGB();
162 // draw DoG detections
163 ipl.setLineWidth( ( int )( initial_sigma * ( 1 + ( float )i / steps ) * os ) );
164 ipl.setColor( Color.green );
165 ipd.setLineWidth( ( int )( initial_sigma * ( 1 + ( float )i / steps ) * os ) );
166 ipd.setColor( Color.green );
168 Vector< float[] > candidates = dog.getCandidates();
169 for ( float[] c : candidates )
171 if ( i == ( int )Math.round( c[ 2 ] ) )
173 ipl.drawDot(
174 ( int )Math.round( ( float )os * c[ 0 ] ),
175 ( int )Math.round( ( float )os * c[ 1 ] ) );
176 ipd.drawDot(
177 ( int )Math.round( ( float )os * c[ 0 ] ),
178 ( int )Math.round( ( float )os * c[ 1 ] ) );
182 stackScaleSpace.addSlice( null, ipl );
183 stackDoG.addSlice( null, ipd );
186 FloatArray2D[] gradients = so.getL1( i );
187 ImageArrayConverter.FloatArrayToFloatProcessor( fp, gradients[ 0 ] );
188 stackGradientAmplitude.addSlice( null, fp );
189 ImageArrayConverter.FloatArrayToFloatProcessor( fp, gradients[ 1 ] );
190 stackGradientOrientation.addSlice( null, fp );
195 for ( int i = 0; i < d.length; ++i )
197 FloatProcessor fp = new FloatProcessorT2( d[ i ].width, d[ i ].height , 0, 0);
198 ImageArrayConverter.FloatArrayToFloatProcessor( fp, d[ i ] );
199 fp.setMinAndMax( -255.0, 255.0 );
200 ImageProcessor ipl = fp.convertToRGB();
202 // draw DoG detections
203 ipl.setLineWidth( 2 );
204 ipl.setColor( Color.green );
206 Vector< float[] > candidates = dog.getCandidates();
207 for ( float[] c : candidates )
209 if ( i == ( int )Math.round( c[ 2 ] ) )
210 ipl.drawDot( ( int )Math.round( c[ 0 ] ), ( int )Math.round( c[ 1 ] ) );
213 stackDoG.addSlice( null, ipl );
216 //stackDoG.addSlice( null, fp );
220 ImagePlus impScaleSpace = new ImagePlus( "Scales", stackScaleSpace );
221 ImagePlus impDoG = new ImagePlus( "Differences of Scales", stackDoG );
222 //ImagePlus impGradientAmplitude = new ImagePlus( "Gradient amplitudes of Scales", stackGradientAmplitude );
223 //ImagePlus impGradientOrientation = new ImagePlus( "Gradient orientations of Scales", stackGradientOrientation );
224 impScaleSpace.show();
225 impDoG.show();
226 //impGradientAmplitude.show();
227 //impGradientOrientation.show();
231 public void keyPressed(KeyEvent e)
233 if (
234 ( e.getKeyCode() == KeyEvent.VK_F1 ) &&
235 ( e.getSource() instanceof TextField) )
240 public void keyReleased(KeyEvent e) { }
242 public void keyTyped(KeyEvent e) { }