1 package mpi
.fruitfly
.registration
;
4 import ini
.trakem2
.display
.Patch
;
5 import ini
.trakem2
.display
.Layer
;
6 import ini
.trakem2
.display
.Display
;
7 import mpi
.fruitfly
.analysis
.FitLine
;
9 public class Optimize
{
12 * minimize the overall displacement of a set of tiles, propagate the
13 * estimated models to a corresponding set of patches and redraw
17 * @param fixed_tiles do not touch these tiles
20 * TODO revise convergence check
21 * particularly for unguided minimization, it is hard to identify
22 * convergence due to presence of local minima
24 * Johannes Schindelin suggested to start from a good guess, which is
25 * e.g. the propagated unoptimized pose of a tile relative to its
26 * connected tile that was already identified during RANSAC
27 * correpondence check. Thank you, Johannes, great hint!
29 static public void minimizeAll(
31 List
< Patch
> patches
,
32 List
< Tile
> fixed_tiles
,
35 int num_patches
= patches
.size();
37 double od
= Double
.MAX_VALUE
;
38 double dd
= Double
.MAX_VALUE
;
39 double min_d
= Double
.MAX_VALUE
;
40 double max_d
= Double
.MIN_VALUE
;
43 double[] dall
= new double[100];
47 final Observer observer
= new Observer();
49 final Layer layer
= patches
.get(0).getLayer();
51 while ( next
< 100000 ) // safety check
52 // while ( next < 10000 ) // safety check
54 for ( int i
= 0; i
< num_patches
; ++i
)
56 Tile tile
= tiles
.get( i
);
57 if ( fixed_tiles
.contains( tile
) ) continue;
61 patches
.get( i
).getAffineTransform().setTransform( tile
.getModel().getAffine() );
62 //IJ.showStatus( "displacement: overall => " + od + ", current => " + tile.getDistance() );
65 min_d
= Double
.MAX_VALUE
;
66 max_d
= Double
.MIN_VALUE
;
67 for ( Tile t
: tiles
)
70 double d
= t
.getDistance();
71 if ( d
< min_d
) min_d
= d
;
72 if ( d
> max_d
) max_d
= d
;
76 dd
= Math
.abs( od
- cd
);
78 //IJ.showStatus( "displacement: " + od + " [" + min_d + "; " + max_d + "] after " + iteration + " iterations");
82 //cc = d < 0.00025 ? cc + 1 : 0;
83 cc
= dd
< 0.001 ? cc
+ 1 : 0;
85 if (dall
.length
== next
) {
86 double[] dall2
= new double[dall
.length
+ 100];
87 System
.arraycopy(dall
, 0, dall2
, 0, dall
.length
);
93 if (next
> 100) { // wait until completing at least 'n' iterations
94 double[] dn
= new double[100];
95 System
.arraycopy(dall
, dall
.length
- 100, dn
, 0, 100);
97 double[] ft
= FitLine
.fitLine(dn
);
100 //if ( Math.abs( ft[ 1 ] ) < 0.001 )
102 // TODO revise convergence check or start from better guesses
103 if ( od
< max_error
&& ft
[ 2 ] >= 0.0 )
105 System
.out
.println( "Exiting at iteration " + next
+ " with slope " + ft
[ 2 ] );
113 if (0 == iteration
/ 1000) Display
.repaint(layer
, null, 0, false); // do the entire canvas, and do not update the navigator
117 System
.out
.println( "Successfully optimized configuration of " + tiles
.size() + " tiles:" );
118 System
.out
.println( " average displacement: " + od
+ "px" );
119 System
.out
.println( " minimal displacement: " + min_d
+ "px" );
120 System
.out
.println( " maximal displacement: " + max_d
+ "px" );
123 static private class Observer
125 public int i
; // iteration
126 public double v
; // value
127 public double d
; // first derivative
128 public double m
; // mean
129 public double var
; // variance
130 public double std
; // standard-deviation
132 public void add( double new_value
)
147 m
= ( v
+ m
* ( double )i
++ ) / ( double )i
;
149 var
+= tmp
* tmp
/ ( double )i
;
150 std
= Math
.sqrt( var
);