1 //package mpi.fruitfly.registration;
3 import mpi
.fruitfly
.general
.*;
4 import mpi
.fruitfly
.math
.datastructures
.*;
5 import mpi
.fruitfly
.math
.*;
6 import mpi
.fruitfly
.registration
.FloatArray2DSIFT
;
7 import mpi
.fruitfly
.registration
.FloatArray2DScaleOctave
;
8 import mpi
.fruitfly
.registration
.FloatArray2DScaleOctaveDoGDetector
;
9 import mpi
.fruitfly
.registration
.ImageFilter
;
10 import mpi
.fruitfly
.registration
.Feature
;
17 import java
.util
.Collections
;
18 import java
.util
.Vector
;
19 import java
.awt
.Color
;
20 import java
.awt
.Polygon
;
21 import java
.awt
.TextField
;
22 import java
.awt
.event
.KeyEvent
;
23 import java
.awt
.event
.KeyListener
;
26 public class SIFT_Movie
implements PlugIn
, KeyListener
29 private static int steps
= 3;
31 private static float initial_sigma
= 1.6f
;
32 // feature descriptor size
33 private static int fdsize
= 8;
34 // feature descriptor orientation bins
35 private static int fdbins
= 8;
36 // size restrictions for scale octaves, use octaves < max_size and > min_size only
37 private static int min_size
= 64;
38 private static int max_size
= 1024;
41 * Set true to double the size of the image by linear interpolation to
42 * ( with * 2 + 1 ) * ( height * 2 + 1 ). Thus we can start identifying
43 * DoG extrema with $\sigma = INITIAL_SIGMA / 2$ like proposed by
46 * This is useful for images scmaller than 1000px per side only.
48 private static boolean upscale
= false;
49 private static float scale
= 1.0f
;
53 * draws a rotated square with center point center, having size and orientation
55 static void drawSquare( ImageProcessor ip
, double[] o
, double scale
, double orient
)
59 double sin
= Math
.sin( orient
);
60 double cos
= Math
.cos( orient
);
62 int[] x
= new int[ 6 ];
63 int[] y
= new int[ 6 ];
66 x
[ 0 ] = ( int )( o
[ 0 ] + ( sin
- cos
) * scale
);
67 y
[ 0 ] = ( int )( o
[ 1 ] - ( sin
+ cos
) * scale
);
69 x
[ 1 ] = ( int )o
[ 0 ];
70 y
[ 1 ] = ( int )o
[ 1 ];
72 x
[ 2 ] = ( int )( o
[ 0 ] + ( sin
+ cos
) * scale
);
73 y
[ 2 ] = ( int )( o
[ 1 ] + ( sin
- cos
) * scale
);
74 x
[ 3 ] = ( int )( o
[ 0 ] - ( sin
- cos
) * scale
);
75 y
[ 3 ] = ( int )( o
[ 1 ] + ( sin
+ cos
) * scale
);
76 x
[ 4 ] = ( int )( o
[ 0 ] - ( sin
+ cos
) * scale
);
77 y
[ 4 ] = ( int )( o
[ 1 ] - ( sin
- cos
) * scale
);
81 ip
.drawPolygon( new Polygon( x
, y
, x
.length
) );
85 public void run( String args
)
87 if ( IJ
.versionLessThan( "1.37i" ) ) return;
89 final ImagePlus imp
= WindowManager
.getCurrentImage();
90 if ( imp
== null ) { System
.err
.println( "There are no images open" ); return; }
92 final GenericDialog gd
= new GenericDialog( "Test SIFT" );
94 gd
.addNumericField( "steps_per_scale_octave :", steps
, 0 );
95 gd
.addNumericField( "initial_gaussian_blur :", initial_sigma
, 2 );
96 gd
.addNumericField( "feature_descriptor_size :", fdsize
, 0 );
97 gd
.addNumericField( "feature_descriptor_orientation_bins :", fdbins
, 0 );
98 gd
.addNumericField( "minimum_image_size :", min_size
, 0 );
99 gd
.addNumericField( "maximum_image_size :", max_size
, 0 );
100 gd
.addCheckbox( "upscale_image_first", upscale
);
102 if ( gd
.wasCanceled() ) return;
103 steps
= ( int )gd
.getNextNumber();
104 initial_sigma
= ( float )gd
.getNextNumber();
105 fdsize
= ( int )gd
.getNextNumber();
106 fdbins
= ( int )gd
.getNextNumber();
107 min_size
= ( int )gd
.getNextNumber();
108 max_size
= ( int )gd
.getNextNumber();
109 upscale
= gd
.getNextBoolean();
110 if ( upscale
) scale
= 2.0f
;
113 ImageProcessor ip1
= imp
.getProcessor().convertToFloat();
114 ImageProcessor ip2
= imp
.getProcessor().duplicate().convertToRGB();
116 Vector
< Feature
> fs1
;
118 FloatArray2DSIFT sift
= new FloatArray2DSIFT( fdsize
, fdbins
);
120 FloatArray2D fa
= ImageArrayConverter
.ImageToFloatArray2D( ip1
);
121 ImageFilter
.enhance( fa
, 1.0f
);
125 FloatArray2D fat
= new FloatArray2D( fa
.width
* 2 - 1, fa
.height
* 2 - 1 );
126 FloatArray2DScaleOctave
.upsample( fa
, fat
);
128 fa
= ImageFilter
.computeGaussianFastMirror( fa
, ( float )Math
.sqrt( initial_sigma
* initial_sigma
- 1.0 ) );
131 fa
= ImageFilter
.computeGaussianFastMirror( fa
, ( float )Math
.sqrt( initial_sigma
* initial_sigma
- 0.25 ) );
133 long start_time
= System
.currentTimeMillis();
134 System
.out
.print( "processing SIFT ..." );
135 sift
.init( fa
, steps
, initial_sigma
, min_size
, max_size
);
136 fs1
= sift
.run( max_size
);
137 Collections
.sort( fs1
);
138 System
.out
.println( " took " + ( System
.currentTimeMillis() - start_time
) + "ms" );
140 System
.out
.println( fs1
.size() + " features identified and processed" );
142 //#############################################################################
144 FloatArray2DScaleOctave
[] sos
= sift
.getOctaves();
145 for ( int o
= 0; o
< sos
.length
; ++o
)
147 FloatArray2DScaleOctave so
= sos
[ o
];
149 FloatArray2D
[] l
= so
.getL();
150 FloatArray2D
[] d
= so
.getD();
152 for ( int i
= 0; i
< steps
; ++i
)
154 FloatArray2D ls
= l
[ i
];
155 FloatArray2D ds
= d
[ i
];
157 for ( int oi
= o
; oi
> 0; --oi
)
159 os
= ( int )Math
.pow( 2, oi
- 1 );
160 int w
= imp
.getWidth();
161 int h
= imp
.getHeight();
162 for ( os
= oi
; os
> 1; --os
)
167 //System.out.println( "o: " + o + ", w: " + w + ", h: " + h );
168 FloatArray2D ld
= new FloatArray2D( w
, h
);
169 FloatArray2D dd
= new FloatArray2D( w
, h
);
170 FloatArray2DScaleOctave
.upsample( ls
, ld
);
171 FloatArray2DScaleOctave
.upsample( ds
, dd
);
175 os
= ( int )Math
.pow( 2, o
);
177 System
.out
.println( os
* so
.SIGMA
[ i
] );
179 FloatProcessor fp
= new FloatProcessor( ls
.width
, ls
.height
);
180 ImageArrayConverter
.FloatArrayToFloatProcessor( fp
, ls
);
181 fp
.setMinAndMax( 0.0, 1.0 );
182 // FloatProcessor fp = new FloatProcessor( ds.width, ds.height );
183 // ImageArrayConverter.FloatArrayToFloatProcessor( fp, ds );
184 // fp.setMinAndMax( -0.25, 0.25 );
185 ImageProcessor ip
= fp
.convertToRGB();
187 // draw DoG detections
189 // ip.setLineWidth( 2 );
190 // ip.setColor( Color.red );
191 // for ( FloatArray2DSIFT.Feature f : fs1 )
193 // int ot = ( int )( f.scale / initial_sigma );
200 // //int ol = General.ldu( ( int )( f.scale / initial_sigma ) ) - 1;
201 // int sl = ( int )Math.round( steps * ( Math.log( f.scale / Math.pow( 2.0, ol ) / initial_sigma ) ) / Math.log( 2.0 ) );
202 // if ( sl >= steps )
208 // //if ( ol < o || ( ol == o && sl <= i ) )
209 // if ( ol == o && sl == i )
210 // drawSquare( ip, new double[]{ f.location[ 0 ] / scale, f.location[ 1 ] / scale }, fdsize * ( double )f.scale / scale, ( double )f.orientation );
213 imp
.setProcessor( null, ip
);
216 new ij
.io
.FileSaver( imp
).saveAsTiff(
217 "D:/Benutzer/Stephan/Eigene Dateien/diploma/gauss-0" + ( steps
* o
+ i
) + ".tif" );
220 FloatArray2D[] gradients = so.getL1( i );
221 ImageArrayConverter.FloatArrayToFloatProcessor( fp, gradients[ 0 ] );
222 stackGradientAmplitude.addSlice( null, fp );
223 ImageArrayConverter.FloatArrayToFloatProcessor( fp, gradients[ 1 ] );
224 stackGradientOrientation.addSlice( null, fp );
229 for ( int i = 0; i < d.length; ++i )
231 FloatProcessor fp = new FloatProcessor( d[ i ].width, d[ i ].height );
232 ImageArrayConverter.FloatArrayToFloatProcessor( fp, d[ i ] );
233 fp.setMinAndMax( -255.0, 255.0 );
234 ImageProcessor ipl = fp.convertToRGB();
236 // draw DoG detections
237 ipl.setLineWidth( 2 );
238 ipl.setColor( Color.green );
240 Vector< float[] > candidates = dog.getCandidates();
241 for ( float[] c : candidates )
243 if ( i == ( int )Math.round( c[ 2 ] ) )
244 ipl.drawDot( ( int )Math.round( c[ 0 ] ), ( int )Math.round( c[ 1 ] ) );
247 stackDoG.addSlice( null, ipl );
250 //stackDoG.addSlice( null, fp );
255 //#############################################################################
258 ip2
.setLineWidth( 2 );
259 ip2
.setColor( Color
.red
);
260 for ( Feature f
: fs1
)
262 //System.out.println( f.location[ 0 ] + " " + f.location[ 1 ] + " " + f.scale + " " + f.orientation );
263 drawSquare( ip2
, new double[]{ f
.location
[ 0 ] / scale
, f
.location
[ 1 ] / scale
}, fdsize
* ( double )f
.scale
/ scale
, ( double )f
.orientation
);
266 ImagePlus imp1
= new ImagePlus( imp
.getTitle() + " Features ", ip2
);
270 public void keyPressed(KeyEvent e
)
273 ( e
.getKeyCode() == KeyEvent
.VK_F1
) &&
274 ( e
.getSource() instanceof TextField
) )
279 public void keyReleased(KeyEvent e
) { }
281 public void keyTyped(KeyEvent e
) { }