Commit 288a87a6 authored by Andrey Filippov's avatar Andrey Filippov
Browse files

debugging initial pattern detection

parent 0414c82c
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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 (
+625 −381
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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();
@@ -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;
@@ -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;
@@ -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){
@@ -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,
@@ -3129,6 +3141,7 @@ public class MatchSimulatedPattern {
						   );
						   debugLevel=was_debug_level;
						   if ((node!=null) && (node[0]!=null)) {
							   nodeQueue.add(new GridNode(node));
							   break;
						   }
					   }
@@ -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,
@@ -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");
@@ -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 
@@ -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
@@ -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
@@ -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
@@ -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;
@@ -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);
@@ -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,
@@ -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){
@@ -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){
@@ -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){