Loading src/main/java/LensAdjustment.java +2 −1 Original line number Diff line number Diff line Loading @@ -131,7 +131,8 @@ public class LensAdjustment { imp_eq, // image to process threadsMax, updateStatus, debug_level);// debug level used inside loops debug_level,// debug level used inside loops debug_level); // global debug level ? if (debug_level>1) System.out.println("distortions() finished at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3)); matchSimulatedPattern.recalculateWaveVectors ( Loading src/main/java/MatchSimulatedPattern.java +625 −381 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ import java.awt.Rectangle; import java.util.ArrayList; import java.util.List; import java.util.Properties; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; Loading @@ -34,7 +36,6 @@ import javax.swing.SwingUtilities; import Jama.LUDecomposition; import Jama.Matrix; // Download here: http://math.nist.gov/javanumerics/jama/ import ij.IJ; import ij.ImagePlus; import ij.ImageStack; Loading Loading @@ -2976,7 +2977,8 @@ public class MatchSimulatedPattern { final ImagePlus imp, // image to process final int threadsMax, final boolean updateStatus, final int debug_level){// debug level used inside loops final int debug_level, // debug level used inside loops final int global_debug_level){ // moved to caller // this.PATTERN_GRID=null; // invalidateCalibration(); Loading Loading @@ -3050,6 +3052,13 @@ public class MatchSimulatedPattern { int [] iUV= new int [2]; final boolean updating=(PATTERN_GRID!=null); final boolean useFocusMask=updating && (focusMask!=null); // do not expand wave beyound 1 grid step from needed image regions // double [][][] nodes=null; Queue<GridNode> nodeQueue = new ConcurrentLinkedQueue<GridNode>(); boolean fromVeryBeginning=true; for (int i=3;i<triedIndices.length;i++) if (triedIndices[i]){ // do not count forst three fromVeryBeginning=false; break; } if (!updating) { double [] point = new double[2]; int tryHor=0,tryVert=0; Loading @@ -3067,7 +3076,8 @@ public class MatchSimulatedPattern { int nbv,nbh,nh,nv,nb; if (debugLevel>1) System.out.println("selection.x="+selection.x+" selection.y="+selection.y+" selection.width="+selection.width+" selection.height="+selection.height); if (debugLevel>1) System.out.println("numTries="+numTries+" tryHor="+tryHor+" tryVert="+tryVert); double [][] node=null; // double [][] node=null; // double [][][] nodes=null; boolean oldMode=false; //true; // false; /* if (startScanIndex[0]==0) startScanIndex[0]=3; Loading @@ -3080,6 +3090,8 @@ public class MatchSimulatedPattern { if (oldMode) { // old (single-threaded) mode // for (int n=startScanIndex[0];n<numTries;n++) { // final boolean [] triedIndices, // nodes = new double [1][][]; // nodes[0]=null; for (int startScanIndex=3;startScanIndex<=numTries;startScanIndex++) if (!triedIndices[startScanIndex]){ if (startScanIndex==numTries){ Loading Loading @@ -3110,7 +3122,7 @@ public class MatchSimulatedPattern { if (debugLevel>2) System.out.println("trying xc="+point[0]+", yc="+point[1]+"(nv="+nv+", nh="+nh+")"); // System.out.println("### trying xc="+point[0]+", yc="+point[1]+"(nv="+nv+", nh="+nh+")"); if ((debugLevel>2) && (startScanIndex==3)) debugLevel=3; // show debug images for the first point only node=tryPattern ( double [][] node=tryPattern ( point, // xy to try thisDistortionParameters, //no control of the displacement patternDetectParameters, Loading @@ -3129,6 +3141,7 @@ public class MatchSimulatedPattern { ); debugLevel=was_debug_level; if ((node!=null) && (node[0]!=null)) { nodeQueue.add(new GridNode(node)); break; } } Loading @@ -3140,7 +3153,7 @@ public class MatchSimulatedPattern { if (debugLevel>1) System.out.println("distortions(): startScanIndex="+startScanIndex); if (startScanIndex<numTries) { node = findPatternCandidate( nodeQueue = findPatternCandidates( triedIndices, startScanIndex, // [0] will be updated tryHor, Loading @@ -3165,9 +3178,12 @@ public class MatchSimulatedPattern { updateStatus, this.debugLevel ); if (node==null){ if (nodeQueue.isEmpty()) { // nodes==null){ if (debugLevel>1) System.out.println("All start points tried"); triedIndices[numTries]=true; // all tried } else { // if (debugLevel>1) System.out.println("Found "+nodes.length+" candidates"); if (debugLevel>1) System.out.println("Found "+nodeQueue.size()+" candidates"); } } else { if (debugLevel>1) System.out.println("All start points tried before - should not get here"); Loading @@ -3175,29 +3191,18 @@ public class MatchSimulatedPattern { } } // if (startScanIndex[0]>=numTries) startScanIndex[0]=-1; // all indices used if ((node==null) || (node[0]==null)) { // if ((nodes==null) || (nodes[0]==null) || (nodes[0][0]==null)) { if ((nodeQueue.isEmpty()) || (nodeQueue.peek().getNode()[0]==null)) { if (debugLevel>1) System.out.println("*** Pattern not found"); this.PATTERN_GRID=null; return 0; } double [] centerXY=node[0]; /* TODO null pointrer in next line - DONE?*/ if (debugLevel>1) System.out.println("*** distortions: Center x="+IJ.d2s(centerXY[0],3)+" y="+ IJ.d2s(centerXY[1],3)); if (debugLevel>1) { System.out.println("*** distortions: got "+nodeQueue.size()+" candidates"); // System.out.println("*** distortions: Center x="+IJ.d2s(centerXY[0],3)+" y="+ IJ.d2s(centerXY[1],3)); } debugLevel=debug_level; // Reset pattern grid this.PATTERN_GRID=setPatternGridArray(distortionParameters.gridSize); // global to be used with threads? setPatternGridCell( this.PATTERN_GRID, centerUV, centerXY, // contrast OK? node[1], node[2]); putInWaveList(waveFrontList, centerUV, 0); // Mark initial point as debug one (seems to be largest correction later // patternDetectParameters.debugX=centerXY[0]; // patternDetectParameters.debugY=centerXY[1]; // System.out.println(">>>>>> Set debugX="+patternDetectParameters.debugX + " debugY="+patternDetectParameters.debugY); debugLevel=debug_level; // ???? } else { // create initial wave from the border nodes of existent grid // start with clearing all invalid nodes Loading @@ -3222,7 +3227,28 @@ public class MatchSimulatedPattern { putInWaveList(waveFrontList, iUV, 0); } } double [][] node={null}; nodeQueue.add(new GridNode(node)); // will not be used, any element } int numDefinedCells=0; for (GridNode gn:nodeQueue){ if (!updating){ double [][] node=gn.getNode(); double [] centerXY=node[0]; if (debugLevel>1) { System.out.println("*** distortions: Center x="+IJ.d2s(centerXY[0],3)+" y="+ IJ.d2s(centerXY[1],3)); } debugLevel=debug_level; // Reset pattern grid this.PATTERN_GRID=setPatternGridArray(distortionParameters.gridSize); // global to be used with threads? setPatternGridCell( this.PATTERN_GRID, centerUV, centerXY, // contrast OK? node[1], node[2]); waveFrontList.clear(); putInWaveList(waveFrontList, centerUV, 0); } // Each layer processing may be multi-threaded, they join before going to the next layer Loading Loading @@ -3253,7 +3279,6 @@ public class MatchSimulatedPattern { // special case (most common, actually) when initial wave has 1 node. Remove it after processing ArrayList<Integer> initialWave=new ArrayList<Integer>(); for (Integer I:waveFrontList) initialWave.add(I); while (waveFrontList.size()>0) { // process current list, add new wave layer (moving in one of the 4 directions) // proceed until the entry is undefined on the grid (or list is empty Loading Loading @@ -3322,7 +3347,7 @@ public class MatchSimulatedPattern { double [][] refCell=PATTERN_GRID[iUVRef[1]][iUVRef[0]]; // should never be null as it is an old one if (refCell==null){ System.out.println("refCell==null"); System.out.println("**** refCell==null - what does it mean?****"); continue; } //found reference cell, calculate x/y, make sure it is inside the selection w/o borders Loading Loading @@ -3567,7 +3592,7 @@ public class MatchSimulatedPattern { vmax=0; vmin=PATTERN_GRID.length; umin=PATTERN_GRID[0].length; int numDefinedCells=0; numDefinedCells=0; for (int i=0;i<PATTERN_GRID.length;i++) for (int j=0;j<PATTERN_GRID[i].length;j++) { if ((PATTERN_GRID[i][j]!=null) && (PATTERN_GRID[i][j][0]!=null)) { if (vmin > i) vmin = i; Loading @@ -3578,13 +3603,14 @@ public class MatchSimulatedPattern { } } if (updating){ return numDefinedCells; // no need to crop the array, it should not change } // if (updating){ // return numDefinedCells; // no need to crop the array, it should not change // } if (!updating){ if (vmin>vmax){ this.PATTERN_GRID=null; return 0; // null; // nothing found continue; // try next in queue if available // return 0; // null; // nothing found } // Add extra margins for future extrapolation int extra=distortionParameters.numberExtrapolated -((distortionParameters.removeLast)?1:0); Loading Loading @@ -3616,10 +3642,78 @@ public class MatchSimulatedPattern { if (debugLevel>1) System.out.println("Total number of defined cells="+numDefinedCells); this.PATTERN_GRID=result; return numDefinedCells; //result; } // more tests here (moved from the caller) that result is good double averageGridPeriod=Double.NaN; if (this.PATTERN_GRID!=null) averageGridPeriod=averageGridPeriod(this.PATTERN_GRID); if (debugLevel>0){ System.out.println("Pattern period="+averageGridPeriod+ " limits are set to :"+patternDetectParameters.minGridPeriod+","+patternDetectParameters.maxGridPeriod); } if (!Double.isNaN(averageGridPeriod)) { if (!Double.isNaN(patternDetectParameters.minGridPeriod) && (patternDetectParameters.minGridPeriod>0.0) && (averageGridPeriod<patternDetectParameters.minGridPeriod)){ if (debugLevel>0){ System.out.println("Pattern is too small, period="+averageGridPeriod+ " minimal="+patternDetectParameters.minGridPeriod); } continue; // bad grid } if (!Double.isNaN(patternDetectParameters.maxGridPeriod) && (patternDetectParameters.maxGridPeriod>0.0) && (averageGridPeriod>patternDetectParameters.maxGridPeriod)){ if (debugLevel>0){ System.out.println("Pattern is too large, period="+averageGridPeriod+ " maximal="+patternDetectParameters.maxGridPeriod); } continue; // bad grid } } if ( (distortionParameters.minimalPatternCluster<=0) || // minimal cluster size is disabled (distortionParameters.scaleMinimalInitialContrast<=0) || // minimal cluster size is disabled ((numDefinedCells==0) && fromVeryBeginning)|| // no cells detected at all, starting from the very beginning (numDefinedCells>=distortionParameters.minimalPatternCluster) // detected enough cells ) { return numDefinedCells; } if (roi!=null){ // don't use this feature with ROI as it can be small if (global_debug_level>0) System.out.println("Initial pattern cluster is small ("+numDefinedCells+"), but ROI is set - no retries"); { return numDefinedCells; } } } // next node in queue // failed to find - deal in the caller /* boolean someLeft=false; int startScanIndex=0; for (startScanIndex=3;startScanIndex<triedIndices.length;startScanIndex++) if (!triedIndices[startScanIndex]){ someLeft=true; break; } private double [][] findPatternCandidate( if (someLeft) { if (global_debug_level>0){ System.out.println("Initial pattern cluster is too small ("+numDefinedCells+ "), continuing scanning from index "+startScanIndex); } } else { // startScanIndex[0]=0; System.out.println("Last pattern cluster was too small, adjusting the minimal contrast from "+ IJ.d2s(distortionParameters.correlationMinInitialContrast,3)+ " to "+IJ.d2s(distortionParameters.correlationMinInitialContrast*distortionParameters.scaleMinimalInitialContrast,3)); distortionParameters.correlationMinInitialContrast*=distortionParameters.scaleMinimalInitialContrast; for (int i=0;i<triedIndices.length;i++) triedIndices[i]=(i<3); // mark first 3 as if they are already used fromVeryBeginning=true; } */ return 0; // none } public double [][] findPatternCandidate_old( // final int [] startScanIndex, // [0] will be updated final boolean [] triedIndices, // which indices are already tried final int startScanIndex, Loading Loading @@ -3731,6 +3825,117 @@ public class MatchSimulatedPattern { return nodeRef[0]; } class GridNode { double [][] node; public GridNode(double [][] node){ this.node=node; } public double [][] getNode(){ return this.node; } } // private double [][][] findPatternCandidates( private Queue<GridNode> findPatternCandidates( // final int [] startScanIndex, // [0] will be updated final boolean [] triedIndices, // which indices are already tried final int startScanIndex, final int tryHor, final int tryVert, // final int numTries, final Rectangle selection, final DistortionParameters distortionParameters, // final MatchSimulatedPattern.PatternDetectParameters patternDetectParameters, final SimulationPattern.SimulParameters thisSimulParameters, final MatchSimulatedPattern matchSimulatedPattern, final MatchSimulatedPattern matchSimulatedPatternCorr, final SimulationPattern simulationPattern, final boolean equalizeGreens, final ImagePlus imp, // image to process final double [] bPattern, final double [] windowFunction, final double [] windowFunctionCorr, final double [] windowFunctionCorr2, final double [] windowFunctionCorr4, final double[][] locsNeib, // which neibors to try (here - just the center) final int threadsMax, final boolean updateStatus, final int debugLevel ){ final Thread[] threads = newThreadArray(threadsMax); final AtomicInteger seqNumber = new AtomicInteger(startScanIndex); // final AtomicBoolean nodeSet=new AtomicBoolean(false); // final double [][][] nodeRef= new double[1][][]; // nodeRef[0]=null; final Queue<GridNode> nodeQueue = new ConcurrentLinkedQueue<GridNode>(); for (int ithread = 0; ithread < threads.length; ithread++) { threads[ithread] = new Thread() { public void run() { int nbh, nbv, nh, nv, nb; double [] point = new double[2]; for (int n=seqNumber.getAndIncrement(); n<(triedIndices.length-1); n=seqNumber.getAndIncrement()) if (!triedIndices[n]){ if (!nodeQueue.isEmpty()) break; // already set at least one element nbh=tryHor-1; nbv=tryVert-1; nh=0; nv=0; nb=0; while (nb<(tryHor+tryVert)) { if (nbh>=0) { if ((n & (1<<nb))!=0) nh |= 1<<nbh; nbh--; nb++; } if (nbv>=0) { if ((n & (1<<nb))!=0) nv |= 1<<nbv; nbv--; nb++; } } if (debugLevel>2) System.out.println("Searching, n="+n+", nv="+nv+", nh="+nh+", nb="+nb ); if ((nv>0) && (nh>0)) { point[0]=(selection.x+nh*selection.width/(1<<tryHor)) & ~1; point[1]=(selection.y+nv*selection.height/(1<<tryVert)) & ~1; if (debugLevel>2) System.out.println("trying xc="+point[0]+", yc="+point[1]+"(nv="+nv+", nh="+nh+")"); // if ((debugLevel>2) && (n==3)) debugLevel=3; // show debug images for the first point double [][] node=tryPattern ( point, // xy to try distortionParameters, //no control of the displacement patternDetectParameters, thisSimulParameters, matchSimulatedPattern, matchSimulatedPatternCorr, simulationPattern, equalizeGreens, imp, // image to process bPattern, windowFunction, windowFunctionCorr, windowFunctionCorr2, windowFunctionCorr4, locsNeib // which neibors to try (here - just the center) ); if ((node!=null) && (node[0]!=null)) { nodeQueue.add(new GridNode(node)); if (debugLevel>1) System.out.println("probing "+n); } } triedIndices[n]=true; // regardless - good or bad } } }; } startAndJoin(threads); // if (nodeQueue.isEmpty()) return null; return nodeQueue; // never null, may be empty // double [][][] nodes = new double [nodeQueue.size()][][]; // for (int i=0;i<nodes.length;i++) nodes[i]=nodeQueue.poll().getNode(); // return nodes; } /* ================================================================*/ public void scaleContrast(double scale){ for (double [][][] patternRow:this.PATTERN_GRID){ Loading Loading @@ -5270,8 +5475,18 @@ public class MatchSimulatedPattern { imp, threadsMax, updateStatus, debug_level); // debug level debug_level, global_debug_level); // debug level if (global_debug_level>1) System.out.println("Pattern correlation done at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3)); if (patternCells>0) { foundGoodCluster=true; break; // new distortions() code - returns non-zero only if passed other tests } if (fromVeryBeginning){ if (global_debug_level>1) System.out.println("--- Nothing found at all ---"); break; // or maybe - still try to adjust threshold? } /* double averageGridPeriod=Double.NaN; if (this.PATTERN_GRID!=null) averageGridPeriod=averageGridPeriod(this.PATTERN_GRID); if (global_debug_level>0){ Loading Loading @@ -5337,7 +5552,36 @@ public class MatchSimulatedPattern { } // distortionParameters.correlationMinInitialContrast*=distortionParameters.scaleMinimalInitialContrast; // } */ boolean someLeft=false; int startScanIndex=0; for (startScanIndex=3;startScanIndex<triedIndices.length;startScanIndex++) if (!triedIndices[startScanIndex]){ someLeft=true; break; } if (someLeft) { // if (!triedIndices[triedIndices.length-1]) { if (global_debug_level>0){ // int startScanIndex=3; // for (;(startScanIndex<triedIndices.length) && triedIndices[startScanIndex];startScanIndex++); // skip tried indices System.out.println("Initial pattern cluster is too small ("+patternCells+ "), continuing scanning from index "+startScanIndex); } } else { // startScanIndex[0]=0; System.out.println("Last pattern cluster was too small, adjusting the minimal contrast from "+ IJ.d2s(distortionParameters.correlationMinInitialContrast,3)+ " to "+IJ.d2s(distortionParameters.correlationMinInitialContrast*distortionParameters.scaleMinimalInitialContrast,3)); distortionParameters.correlationMinInitialContrast*=distortionParameters.scaleMinimalInitialContrast; for (int i=0;i<triedIndices.length;i++) triedIndices[i]=(i<3); // mark first 3 as if they are already used fromVeryBeginning=true; } } // restore initial distortionParameters.correlationMinInitialContrast distortionParameters.correlationMinInitialContrast=savedCorrelationMinInitialContrast; if (!foundGoodCluster){ Loading Loading
src/main/java/LensAdjustment.java +2 −1 Original line number Diff line number Diff line Loading @@ -131,7 +131,8 @@ public class LensAdjustment { imp_eq, // image to process threadsMax, updateStatus, debug_level);// debug level used inside loops debug_level,// debug level used inside loops debug_level); // global debug level ? if (debug_level>1) System.out.println("distortions() finished at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3)); matchSimulatedPattern.recalculateWaveVectors ( Loading
src/main/java/MatchSimulatedPattern.java +625 −381 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ import java.awt.Rectangle; import java.util.ArrayList; import java.util.List; import java.util.Properties; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; Loading @@ -34,7 +36,6 @@ import javax.swing.SwingUtilities; import Jama.LUDecomposition; import Jama.Matrix; // Download here: http://math.nist.gov/javanumerics/jama/ import ij.IJ; import ij.ImagePlus; import ij.ImageStack; Loading Loading @@ -2976,7 +2977,8 @@ public class MatchSimulatedPattern { final ImagePlus imp, // image to process final int threadsMax, final boolean updateStatus, final int debug_level){// debug level used inside loops final int debug_level, // debug level used inside loops final int global_debug_level){ // moved to caller // this.PATTERN_GRID=null; // invalidateCalibration(); Loading Loading @@ -3050,6 +3052,13 @@ public class MatchSimulatedPattern { int [] iUV= new int [2]; final boolean updating=(PATTERN_GRID!=null); final boolean useFocusMask=updating && (focusMask!=null); // do not expand wave beyound 1 grid step from needed image regions // double [][][] nodes=null; Queue<GridNode> nodeQueue = new ConcurrentLinkedQueue<GridNode>(); boolean fromVeryBeginning=true; for (int i=3;i<triedIndices.length;i++) if (triedIndices[i]){ // do not count forst three fromVeryBeginning=false; break; } if (!updating) { double [] point = new double[2]; int tryHor=0,tryVert=0; Loading @@ -3067,7 +3076,8 @@ public class MatchSimulatedPattern { int nbv,nbh,nh,nv,nb; if (debugLevel>1) System.out.println("selection.x="+selection.x+" selection.y="+selection.y+" selection.width="+selection.width+" selection.height="+selection.height); if (debugLevel>1) System.out.println("numTries="+numTries+" tryHor="+tryHor+" tryVert="+tryVert); double [][] node=null; // double [][] node=null; // double [][][] nodes=null; boolean oldMode=false; //true; // false; /* if (startScanIndex[0]==0) startScanIndex[0]=3; Loading @@ -3080,6 +3090,8 @@ public class MatchSimulatedPattern { if (oldMode) { // old (single-threaded) mode // for (int n=startScanIndex[0];n<numTries;n++) { // final boolean [] triedIndices, // nodes = new double [1][][]; // nodes[0]=null; for (int startScanIndex=3;startScanIndex<=numTries;startScanIndex++) if (!triedIndices[startScanIndex]){ if (startScanIndex==numTries){ Loading Loading @@ -3110,7 +3122,7 @@ public class MatchSimulatedPattern { if (debugLevel>2) System.out.println("trying xc="+point[0]+", yc="+point[1]+"(nv="+nv+", nh="+nh+")"); // System.out.println("### trying xc="+point[0]+", yc="+point[1]+"(nv="+nv+", nh="+nh+")"); if ((debugLevel>2) && (startScanIndex==3)) debugLevel=3; // show debug images for the first point only node=tryPattern ( double [][] node=tryPattern ( point, // xy to try thisDistortionParameters, //no control of the displacement patternDetectParameters, Loading @@ -3129,6 +3141,7 @@ public class MatchSimulatedPattern { ); debugLevel=was_debug_level; if ((node!=null) && (node[0]!=null)) { nodeQueue.add(new GridNode(node)); break; } } Loading @@ -3140,7 +3153,7 @@ public class MatchSimulatedPattern { if (debugLevel>1) System.out.println("distortions(): startScanIndex="+startScanIndex); if (startScanIndex<numTries) { node = findPatternCandidate( nodeQueue = findPatternCandidates( triedIndices, startScanIndex, // [0] will be updated tryHor, Loading @@ -3165,9 +3178,12 @@ public class MatchSimulatedPattern { updateStatus, this.debugLevel ); if (node==null){ if (nodeQueue.isEmpty()) { // nodes==null){ if (debugLevel>1) System.out.println("All start points tried"); triedIndices[numTries]=true; // all tried } else { // if (debugLevel>1) System.out.println("Found "+nodes.length+" candidates"); if (debugLevel>1) System.out.println("Found "+nodeQueue.size()+" candidates"); } } else { if (debugLevel>1) System.out.println("All start points tried before - should not get here"); Loading @@ -3175,29 +3191,18 @@ public class MatchSimulatedPattern { } } // if (startScanIndex[0]>=numTries) startScanIndex[0]=-1; // all indices used if ((node==null) || (node[0]==null)) { // if ((nodes==null) || (nodes[0]==null) || (nodes[0][0]==null)) { if ((nodeQueue.isEmpty()) || (nodeQueue.peek().getNode()[0]==null)) { if (debugLevel>1) System.out.println("*** Pattern not found"); this.PATTERN_GRID=null; return 0; } double [] centerXY=node[0]; /* TODO null pointrer in next line - DONE?*/ if (debugLevel>1) System.out.println("*** distortions: Center x="+IJ.d2s(centerXY[0],3)+" y="+ IJ.d2s(centerXY[1],3)); if (debugLevel>1) { System.out.println("*** distortions: got "+nodeQueue.size()+" candidates"); // System.out.println("*** distortions: Center x="+IJ.d2s(centerXY[0],3)+" y="+ IJ.d2s(centerXY[1],3)); } debugLevel=debug_level; // Reset pattern grid this.PATTERN_GRID=setPatternGridArray(distortionParameters.gridSize); // global to be used with threads? setPatternGridCell( this.PATTERN_GRID, centerUV, centerXY, // contrast OK? node[1], node[2]); putInWaveList(waveFrontList, centerUV, 0); // Mark initial point as debug one (seems to be largest correction later // patternDetectParameters.debugX=centerXY[0]; // patternDetectParameters.debugY=centerXY[1]; // System.out.println(">>>>>> Set debugX="+patternDetectParameters.debugX + " debugY="+patternDetectParameters.debugY); debugLevel=debug_level; // ???? } else { // create initial wave from the border nodes of existent grid // start with clearing all invalid nodes Loading @@ -3222,7 +3227,28 @@ public class MatchSimulatedPattern { putInWaveList(waveFrontList, iUV, 0); } } double [][] node={null}; nodeQueue.add(new GridNode(node)); // will not be used, any element } int numDefinedCells=0; for (GridNode gn:nodeQueue){ if (!updating){ double [][] node=gn.getNode(); double [] centerXY=node[0]; if (debugLevel>1) { System.out.println("*** distortions: Center x="+IJ.d2s(centerXY[0],3)+" y="+ IJ.d2s(centerXY[1],3)); } debugLevel=debug_level; // Reset pattern grid this.PATTERN_GRID=setPatternGridArray(distortionParameters.gridSize); // global to be used with threads? setPatternGridCell( this.PATTERN_GRID, centerUV, centerXY, // contrast OK? node[1], node[2]); waveFrontList.clear(); putInWaveList(waveFrontList, centerUV, 0); } // Each layer processing may be multi-threaded, they join before going to the next layer Loading Loading @@ -3253,7 +3279,6 @@ public class MatchSimulatedPattern { // special case (most common, actually) when initial wave has 1 node. Remove it after processing ArrayList<Integer> initialWave=new ArrayList<Integer>(); for (Integer I:waveFrontList) initialWave.add(I); while (waveFrontList.size()>0) { // process current list, add new wave layer (moving in one of the 4 directions) // proceed until the entry is undefined on the grid (or list is empty Loading Loading @@ -3322,7 +3347,7 @@ public class MatchSimulatedPattern { double [][] refCell=PATTERN_GRID[iUVRef[1]][iUVRef[0]]; // should never be null as it is an old one if (refCell==null){ System.out.println("refCell==null"); System.out.println("**** refCell==null - what does it mean?****"); continue; } //found reference cell, calculate x/y, make sure it is inside the selection w/o borders Loading Loading @@ -3567,7 +3592,7 @@ public class MatchSimulatedPattern { vmax=0; vmin=PATTERN_GRID.length; umin=PATTERN_GRID[0].length; int numDefinedCells=0; numDefinedCells=0; for (int i=0;i<PATTERN_GRID.length;i++) for (int j=0;j<PATTERN_GRID[i].length;j++) { if ((PATTERN_GRID[i][j]!=null) && (PATTERN_GRID[i][j][0]!=null)) { if (vmin > i) vmin = i; Loading @@ -3578,13 +3603,14 @@ public class MatchSimulatedPattern { } } if (updating){ return numDefinedCells; // no need to crop the array, it should not change } // if (updating){ // return numDefinedCells; // no need to crop the array, it should not change // } if (!updating){ if (vmin>vmax){ this.PATTERN_GRID=null; return 0; // null; // nothing found continue; // try next in queue if available // return 0; // null; // nothing found } // Add extra margins for future extrapolation int extra=distortionParameters.numberExtrapolated -((distortionParameters.removeLast)?1:0); Loading Loading @@ -3616,10 +3642,78 @@ public class MatchSimulatedPattern { if (debugLevel>1) System.out.println("Total number of defined cells="+numDefinedCells); this.PATTERN_GRID=result; return numDefinedCells; //result; } // more tests here (moved from the caller) that result is good double averageGridPeriod=Double.NaN; if (this.PATTERN_GRID!=null) averageGridPeriod=averageGridPeriod(this.PATTERN_GRID); if (debugLevel>0){ System.out.println("Pattern period="+averageGridPeriod+ " limits are set to :"+patternDetectParameters.minGridPeriod+","+patternDetectParameters.maxGridPeriod); } if (!Double.isNaN(averageGridPeriod)) { if (!Double.isNaN(patternDetectParameters.minGridPeriod) && (patternDetectParameters.minGridPeriod>0.0) && (averageGridPeriod<patternDetectParameters.minGridPeriod)){ if (debugLevel>0){ System.out.println("Pattern is too small, period="+averageGridPeriod+ " minimal="+patternDetectParameters.minGridPeriod); } continue; // bad grid } if (!Double.isNaN(patternDetectParameters.maxGridPeriod) && (patternDetectParameters.maxGridPeriod>0.0) && (averageGridPeriod>patternDetectParameters.maxGridPeriod)){ if (debugLevel>0){ System.out.println("Pattern is too large, period="+averageGridPeriod+ " maximal="+patternDetectParameters.maxGridPeriod); } continue; // bad grid } } if ( (distortionParameters.minimalPatternCluster<=0) || // minimal cluster size is disabled (distortionParameters.scaleMinimalInitialContrast<=0) || // minimal cluster size is disabled ((numDefinedCells==0) && fromVeryBeginning)|| // no cells detected at all, starting from the very beginning (numDefinedCells>=distortionParameters.minimalPatternCluster) // detected enough cells ) { return numDefinedCells; } if (roi!=null){ // don't use this feature with ROI as it can be small if (global_debug_level>0) System.out.println("Initial pattern cluster is small ("+numDefinedCells+"), but ROI is set - no retries"); { return numDefinedCells; } } } // next node in queue // failed to find - deal in the caller /* boolean someLeft=false; int startScanIndex=0; for (startScanIndex=3;startScanIndex<triedIndices.length;startScanIndex++) if (!triedIndices[startScanIndex]){ someLeft=true; break; } private double [][] findPatternCandidate( if (someLeft) { if (global_debug_level>0){ System.out.println("Initial pattern cluster is too small ("+numDefinedCells+ "), continuing scanning from index "+startScanIndex); } } else { // startScanIndex[0]=0; System.out.println("Last pattern cluster was too small, adjusting the minimal contrast from "+ IJ.d2s(distortionParameters.correlationMinInitialContrast,3)+ " to "+IJ.d2s(distortionParameters.correlationMinInitialContrast*distortionParameters.scaleMinimalInitialContrast,3)); distortionParameters.correlationMinInitialContrast*=distortionParameters.scaleMinimalInitialContrast; for (int i=0;i<triedIndices.length;i++) triedIndices[i]=(i<3); // mark first 3 as if they are already used fromVeryBeginning=true; } */ return 0; // none } public double [][] findPatternCandidate_old( // final int [] startScanIndex, // [0] will be updated final boolean [] triedIndices, // which indices are already tried final int startScanIndex, Loading Loading @@ -3731,6 +3825,117 @@ public class MatchSimulatedPattern { return nodeRef[0]; } class GridNode { double [][] node; public GridNode(double [][] node){ this.node=node; } public double [][] getNode(){ return this.node; } } // private double [][][] findPatternCandidates( private Queue<GridNode> findPatternCandidates( // final int [] startScanIndex, // [0] will be updated final boolean [] triedIndices, // which indices are already tried final int startScanIndex, final int tryHor, final int tryVert, // final int numTries, final Rectangle selection, final DistortionParameters distortionParameters, // final MatchSimulatedPattern.PatternDetectParameters patternDetectParameters, final SimulationPattern.SimulParameters thisSimulParameters, final MatchSimulatedPattern matchSimulatedPattern, final MatchSimulatedPattern matchSimulatedPatternCorr, final SimulationPattern simulationPattern, final boolean equalizeGreens, final ImagePlus imp, // image to process final double [] bPattern, final double [] windowFunction, final double [] windowFunctionCorr, final double [] windowFunctionCorr2, final double [] windowFunctionCorr4, final double[][] locsNeib, // which neibors to try (here - just the center) final int threadsMax, final boolean updateStatus, final int debugLevel ){ final Thread[] threads = newThreadArray(threadsMax); final AtomicInteger seqNumber = new AtomicInteger(startScanIndex); // final AtomicBoolean nodeSet=new AtomicBoolean(false); // final double [][][] nodeRef= new double[1][][]; // nodeRef[0]=null; final Queue<GridNode> nodeQueue = new ConcurrentLinkedQueue<GridNode>(); for (int ithread = 0; ithread < threads.length; ithread++) { threads[ithread] = new Thread() { public void run() { int nbh, nbv, nh, nv, nb; double [] point = new double[2]; for (int n=seqNumber.getAndIncrement(); n<(triedIndices.length-1); n=seqNumber.getAndIncrement()) if (!triedIndices[n]){ if (!nodeQueue.isEmpty()) break; // already set at least one element nbh=tryHor-1; nbv=tryVert-1; nh=0; nv=0; nb=0; while (nb<(tryHor+tryVert)) { if (nbh>=0) { if ((n & (1<<nb))!=0) nh |= 1<<nbh; nbh--; nb++; } if (nbv>=0) { if ((n & (1<<nb))!=0) nv |= 1<<nbv; nbv--; nb++; } } if (debugLevel>2) System.out.println("Searching, n="+n+", nv="+nv+", nh="+nh+", nb="+nb ); if ((nv>0) && (nh>0)) { point[0]=(selection.x+nh*selection.width/(1<<tryHor)) & ~1; point[1]=(selection.y+nv*selection.height/(1<<tryVert)) & ~1; if (debugLevel>2) System.out.println("trying xc="+point[0]+", yc="+point[1]+"(nv="+nv+", nh="+nh+")"); // if ((debugLevel>2) && (n==3)) debugLevel=3; // show debug images for the first point double [][] node=tryPattern ( point, // xy to try distortionParameters, //no control of the displacement patternDetectParameters, thisSimulParameters, matchSimulatedPattern, matchSimulatedPatternCorr, simulationPattern, equalizeGreens, imp, // image to process bPattern, windowFunction, windowFunctionCorr, windowFunctionCorr2, windowFunctionCorr4, locsNeib // which neibors to try (here - just the center) ); if ((node!=null) && (node[0]!=null)) { nodeQueue.add(new GridNode(node)); if (debugLevel>1) System.out.println("probing "+n); } } triedIndices[n]=true; // regardless - good or bad } } }; } startAndJoin(threads); // if (nodeQueue.isEmpty()) return null; return nodeQueue; // never null, may be empty // double [][][] nodes = new double [nodeQueue.size()][][]; // for (int i=0;i<nodes.length;i++) nodes[i]=nodeQueue.poll().getNode(); // return nodes; } /* ================================================================*/ public void scaleContrast(double scale){ for (double [][][] patternRow:this.PATTERN_GRID){ Loading Loading @@ -5270,8 +5475,18 @@ public class MatchSimulatedPattern { imp, threadsMax, updateStatus, debug_level); // debug level debug_level, global_debug_level); // debug level if (global_debug_level>1) System.out.println("Pattern correlation done at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3)); if (patternCells>0) { foundGoodCluster=true; break; // new distortions() code - returns non-zero only if passed other tests } if (fromVeryBeginning){ if (global_debug_level>1) System.out.println("--- Nothing found at all ---"); break; // or maybe - still try to adjust threshold? } /* double averageGridPeriod=Double.NaN; if (this.PATTERN_GRID!=null) averageGridPeriod=averageGridPeriod(this.PATTERN_GRID); if (global_debug_level>0){ Loading Loading @@ -5337,7 +5552,36 @@ public class MatchSimulatedPattern { } // distortionParameters.correlationMinInitialContrast*=distortionParameters.scaleMinimalInitialContrast; // } */ boolean someLeft=false; int startScanIndex=0; for (startScanIndex=3;startScanIndex<triedIndices.length;startScanIndex++) if (!triedIndices[startScanIndex]){ someLeft=true; break; } if (someLeft) { // if (!triedIndices[triedIndices.length-1]) { if (global_debug_level>0){ // int startScanIndex=3; // for (;(startScanIndex<triedIndices.length) && triedIndices[startScanIndex];startScanIndex++); // skip tried indices System.out.println("Initial pattern cluster is too small ("+patternCells+ "), continuing scanning from index "+startScanIndex); } } else { // startScanIndex[0]=0; System.out.println("Last pattern cluster was too small, adjusting the minimal contrast from "+ IJ.d2s(distortionParameters.correlationMinInitialContrast,3)+ " to "+IJ.d2s(distortionParameters.correlationMinInitialContrast*distortionParameters.scaleMinimalInitialContrast,3)); distortionParameters.correlationMinInitialContrast*=distortionParameters.scaleMinimalInitialContrast; for (int i=0;i<triedIndices.length;i++) triedIndices[i]=(i<3); // mark first 3 as if they are already used fromVeryBeginning=true; } } // restore initial distortionParameters.correlationMinInitialContrast distortionParameters.correlationMinInitialContrast=savedCorrelationMinInitialContrast; if (!foundGoodCluster){ Loading