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

debugging initial pattern detection

parent 0414c82c
......@@ -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 (
......
......@@ -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
......@@ -3286,8 +3311,8 @@ public class MatchSimulatedPattern {
(iUV[0]>=distortionParameters.gridSize) || (iUV[1]>=distortionParameters.gridSize)) continue; // don't fit into UV grid
if (!isCellNew(PATTERN_GRID,iUV)) continue; // already processed
// add uv and dir to the list
// public boolean [] focusMask=null; // array matching image pixels, used with focusing (false outside sample areas)
// New: if it is updating the grid and focusMask is defined - do not go more than 1 step away from the needed image area
// public boolean [] focusMask=null; // array matching image pixels, used with focusing (false outside sample areas)
// New: if it is updating the grid and focusMask is defined - do not go more than 1 step away from the needed image area
if (hasNeededNeighbor) {
putInWaveList (waveFrontList, iUV, (dir+(directionsUV.length/2))%directionsUV.length); // opposite direction
initPatternGridCell(PATTERN_GRID, iUV);
......@@ -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
......@@ -3545,7 +3570,7 @@ public class MatchSimulatedPattern {
}
if (debugLevel>1) System.out.println("***** Starting cleanup, wave length="+waveFrontList.size());
}
// end of layer
// end of layer
if (initialWave!=null){ // just after the first layer (usually one cell) - delete it and add next time - otherwise first one needs large correction
if (debugLevel>0) System.out.println("Removing "+initialWave.size()+" initial wave cells");
while (initialWave.size()>0){
......@@ -3558,16 +3583,16 @@ public class MatchSimulatedPattern {
}//while (waveFrontList.size()>0)
debugLevel=was_debug_level;
/*
/*
if (updating){
return PATTERN_GRID; // no need to crop the array, it should not change
}
*/
*/
umax=0;
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){
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment