Commit 6733a12d authored by Andrey Filippov's avatar Andrey Filippov

Implemented LWIR grids calculation

parent 41b1b50e
......@@ -361,12 +361,15 @@ public class Aberration_Calibration extends PlugInFrame implements ActionListene
public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSimulatedPattern.DistortionParameters(
64, //32, // use 64 for less artifacts, // correlationSize
64, // Maximal correlation size
16, // int correlationSizeLwir,
128, // 64, // Maximal correlation size
16, // int maximalCorrelationSizeLwir,
0.75,// reduce to 0.5 when correlationSize==64 // correlationGaussWidth
false, // boolean absoluteCorrelationGaussWidth=false; // do not scale correlationGaussWidth when the FFT size is increased
0, //zeros - // leave this number of zeros on the margins of the window (toatal from both sides). If correlationGaussWidth>0 will
// additionally multiply by Hamming
128, // FFT size
256, // FFTSize (was 128)
32, // FFTSize_lwir
0.5, //fftGaussWidth
0.0, //phaseCorrelationFraction
1.5, // 2.5, //6.0, // 2.0, // 0.0, // correlationHighPassSigma, - pixels in frequency domain
......@@ -385,7 +388,8 @@ public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSi
0.1, // contrastSelectSigma, // Gaussian sigma to select correlation centers (fraction of UV period), 0.1
0.5, //contrastAverageSigma, // Gaussian sigma to average correlation variations (as contrast reference) 0.5
150, // minimalPatternCluster minimal pattern cluster size (0 - disable retries)
40, // 150, // minimalPatternCluster minimal pattern cluster size (0 - disable retries)
10, // 150, // minimalPatternClusterLwir minimal pattern cluster size (0 - disable retries)
2.0, // scaleMinimalInitialContrast increase/decrease minimal contrast if initial cluster is >0 but less than minimalPatternCluster
0.5, // when searching for grid, step this amount of the FFTSize
4, // public int patternSubdiv;
......@@ -1417,10 +1421,9 @@ if (MORE_BUTTONS) {
// matchSimulatedPattern.invalidateFlatFieldForGrid(); //It is already reset, no need to do it again
// matchSimulatedPattern.invalidateFocusMask();
matchSimulatedPattern.calculateDistortions(
null, // LwirReaderParameters lwirReaderParameters,
DISTORTION, //
PATTERN_DETECT,
PATTERN_DETECT.minGridPeriod/2,
PATTERN_DETECT.maxGridPeriod/2,
SIMUL,
COMPONENTS.equalizeGreens,
imp_sel,
......@@ -1815,10 +1818,9 @@ if (MORE_BUTTONS) {
// matchSimulatedPattern.invalidateFlatFieldForGrid(); //It is already reset, no need to do it again
// matchSimulatedPattern.invalidateFocusMask();
int numAbsolutePoints=matchSimulatedPattern.calculateDistortions(
null, // LwirReaderParameters lwirReaderParameters,
DISTORTION, //
PATTERN_DETECT,
PATTERN_DETECT.minGridPeriod/2,
PATTERN_DETECT.maxGridPeriod/2,
SIMUL,
COMPONENTS.equalizeGreens,
imp_sel,
......@@ -9416,10 +9418,6 @@ if (MORE_BUTTONS) {
}
/* ======================================================================== */
if (label.equals("LWIR grids")) {
// if ((LASER_POINTERS==null) || (LASER_POINTERS.laserUVMap.length==0)){
// IJ.showMessage("Laser pointer data needed for this function is not provided");
// return;
// }
calculateLwirGrids();
return;
}
......@@ -9449,23 +9447,20 @@ if (MORE_BUTTONS) {
matchSimulatedPattern.debugLevel=MASTER_DEBUG_LEVEL;
String [] sourceSetList = DISTORTION_PROCESS_CONFIGURATION.selectSourceSets();
LWIR_PARAMETERS.selectSourceChannels();
boolean [] sel_chn = LWIR_PARAMETERS.getSelectedVnir(); // start with regular cameras only
// boolean [] sel_chn = LWIR_PARAMETERS.getSelectedVnir(); // start with regular cameras only
boolean [] sel_chn = LWIR_PARAMETERS.getSelected();
int numFiles = LWIR_PARAMETERS.getSourceFilesFlat(sourceSetList, sel_chn).length; // just the number
String [][] sourceFilesList=LWIR_PARAMETERS.getSourceFiles(sourceSetList, sel_chn);
// String [] sourceFilesList=DISTORTION_PROCESS_CONFIGURATION.selectSourceFiles(); // select files - with/without dialog
boolean saveGrids=DISTORTION_PROCESS_CONFIGURATION.saveGridImages;
boolean overwriteGrids=DISTORTION_PROCESS_CONFIGURATION.overwriteResultFiles;
if (sourceSetList==null) return;
showPatternMinMaxPeriodDialog(PATTERN_DETECT, true);
int this_file = 0;
// if (DEBUG_LEVEL <100) return;
int saved_file = 0;
int in_file = 0;
String gridDir=DISTORTION_PROCESS_CONFIGURATION.selectGridFileDirectory(
true,DISTORTION_PROCESS_CONFIGURATION.gridDirectory,true);
if (gridDir == null) saveGrids=false; // do not ask about the next ones too
for (int nset = 0; nset < sourceFilesList.length; nset++){
String set_name = sourceSetList[nset];
int i = set_name.lastIndexOf(Prefs.getFileSeparator());
......@@ -9481,11 +9476,12 @@ if (MORE_BUTTONS) {
}
for (int nfile = 0; nfile < sourceFilesList[nset].length; nfile++) if (sourceFilesList[nset][nfile] != null){
in_file++;
long startFileTime=System.nanoTime();
if (DEBUG_LEVEL>0){
System.out.println(IJ.d2s(0.000000001*(System.nanoTime()-startTime),3)+"s: Processing set "+(nset+1) +" (of "+
sourceFilesList.length+"), channel # "+(nfile + 1)+
" (of "+ sourceFilesList[nset].length+"), file " +(this_file + 1)+" (of "+ numFiles+ ") - "+sourceFilesList[nset][nfile]);
" (of "+ sourceFilesList[nset].length+"), file "+in_file+" (of "+ numFiles+ ") success in "+saved_file+" - "+sourceFilesList[nset][nfile]);
}
String grid_path = null;
if (saveGrids && !overwriteGrids){ // check if result already exists
......@@ -9506,11 +9502,11 @@ if (MORE_BUTTONS) {
matchSimulatedPattern.invalidateFlatFieldForGrid(); //Reset Flat Field calibration - different image.
matchSimulatedPattern.invalidateFocusMask();
boolean is_lwir = LWIR_PARAMETERS.is_LWIR(imp_sel);
int numAbsolutePoints=matchSimulatedPattern.calculateDistortions(
LWIR_PARAMETERS, // LwirReaderParameters lwirReaderParameters,
DISTORTION, //
PATTERN_DETECT,
PATTERN_DETECT.minGridPeriod/2,
PATTERN_DETECT.maxGridPeriod/2,
SIMUL,
COMPONENTS.equalizeGreens,
imp_sel,
......@@ -9526,7 +9522,7 @@ if (MORE_BUTTONS) {
if (DEBUG_LEVEL>1) System.out.println("numAbsolutePoints="+numAbsolutePoints);
if ((numAbsolutePoints==DISTORTION.errPatternNotFound) || (numAbsolutePoints==DISTORTION.errTooFewCells)) {
if (DEBUG_LEVEL>0) System.out.println("Grid "+(this_file+1)+" not found or too small ("+numAbsolutePoints+"), wasted "+
if (DEBUG_LEVEL>0) System.out.println("Grid "+(in_file)+" not found or too small ("+numAbsolutePoints+"), wasted "+
IJ.d2s(0.000000001*(System.nanoTime()-startFileTime),3)+" seconds )\n");
if (this.SYNC_COMMAND.stopRequested.get()>0) {
System.out.println("User requested stop");
......@@ -9561,7 +9557,7 @@ if (MORE_BUTTONS) {
}
}
}
if (DEBUG_LEVEL>0) System.out.println("Grid "+(this_file+1)+" calculation done at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3)+" (in "+
if (DEBUG_LEVEL>0) System.out.println("Grid "+(saved_file+1)+" calculation done at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3)+" (in "+
IJ.d2s(0.000000001*(System.nanoTime()-startFileTime),3)+"s )\n");
//
......@@ -9569,7 +9565,7 @@ if (MORE_BUTTONS) {
System.out.println("User requested stop");
break;
}
this_file++;
saved_file++;
}
}
if (DEBUG_LEVEL>0) System.out.println(((this.SYNC_COMMAND.stopRequested.get()>0)?"Partial (interrupted by user) set of grids":"All")+ " grids calculation done at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
......@@ -9628,10 +9624,9 @@ if (MORE_BUTTONS) {
matchSimulatedPattern.invalidateFlatFieldForGrid(); //Reset Flat Field calibration - different image.
matchSimulatedPattern.invalidateFocusMask();
int numAbsolutePoints=matchSimulatedPattern.calculateDistortions(
LWIR_PARAMETERS, // LwirReaderParameters lwirReaderParameters,,
DISTORTION, //
PATTERN_DETECT,
PATTERN_DETECT.minGridPeriod/2,
PATTERN_DETECT.maxGridPeriod/2,
SIMUL,
COMPONENTS.equalizeGreens,
imp_sel,
......@@ -9733,12 +9728,10 @@ if (MORE_BUTTONS) {
imp_sel); // reuse the same image window
//Remove for old method?
matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize);
matchSimulatedPattern.calculateDistortions(
DISTORTION, //
PATTERN_DETECT,
PATTERN_DETECT.minGridPeriod/2,
PATTERN_DETECT.maxGridPeriod/2,
LWIR_PARAMETERS,
DISTORTION, //
PATTERN_DETECT,
SIMUL,
COMPONENTS.equalizeGreens,
imp_sel,
......@@ -17208,7 +17201,8 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) {
null, // no mesh distortion here
thisSimulParameters.subdiv,// SIMUL.subdiv, - do not need high quality here
size,
true); // center for greens
true, // center for greens
false);//boolean mono
sim_pix= simulationPattern.extractSimulPatterns (
thisSimulParameters,
1,
......@@ -17783,7 +17777,8 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) {
distortedPattern[2], //
simulParameters.subdiv,
fft_size,
simulParameters.center_for_g2);
simulParameters.center_for_g2,
false);//boolean mono
wVectors[0][0]=2.0*distortedPattern[0][0]/subpixel;
wVectors[0][1]=2.0*distortedPattern[0][1]/subpixel;
wVectors[1][0]=2.0*distortedPattern[1][0]/subpixel;
......@@ -17835,7 +17830,8 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) {
simCorr, //
simulParameters.subdiv,
fft_size,
simulParameters.center_for_g2);
simulParameters.center_for_g2,
false);//boolean mono
}
simul_pixels= simulationPattern.extractSimulPatterns (
simulParameters,
......@@ -20302,10 +20298,13 @@ use the result to create a rejectiobn mask - if the energy was high, (multiplica
public boolean showDistortionDialog(MatchSimulatedPattern.DistortionParameters distortionParameters) {
int i;
GenericDialog gd = new GenericDialog("Distrortion parameters");
gd.addNumericField("FFTSize (Initial pattern detection only):", distortionParameters.FFTSize, 0); // 128
gd.addNumericField("FFTSize (Initial pattern detection only):", distortionParameters.FFTSize, 0); // 256
gd.addNumericField("FFTSize for LWIR sensors):", distortionParameters.FFTSize_lwir, 0); // 32
gd.addNumericField("FFT Gaussian width (relative):", distortionParameters.fftGaussWidth, 3);
gd.addNumericField("Correlation size:", distortionParameters.correlationSize, 0); // 64
gd.addNumericField("Maximal correlation size:", distortionParameters.maximalCorrelationSize, 0); // 64
gd.addNumericField("Correlation size LWIR:", distortionParameters.correlationSizeLwir, 0); // 16
gd.addNumericField("Maximal correlation size:", distortionParameters.maximalCorrelationSize, 0); // 128
gd.addNumericField("Maximal correlation size LWIR:", distortionParameters.maximalCorrelationSizeLwir, 0); // 16
gd.addNumericField("Correlation Gauss width (relative):", distortionParameters.correlationGaussWidth, 3);
gd.addCheckbox("Keep Gaussian width absolute when increasing FFT size",distortionParameters.absoluteCorrelationGaussWidth);
......@@ -20330,20 +20329,21 @@ use the result to create a rejectiobn mask - if the energy was high, (multiplica
gd.addNumericField("Gaussian sigma to select correlation off-centers (fraction of UV period), 0.1", distortionParameters.contrastSelectSigma, 3);
gd.addNumericField("Gaussian sigma to average correlation variations (as contrast reference), 0.5", distortionParameters.contrastAverageSigma, 3);
gd.addNumericField("Minimal initial pattern cluster size (0 - disable retries)", distortionParameters.minimalPatternCluster, 0);
gd.addNumericField("Minimal initial pattern cluster size (0 - disable retries)", distortionParameters.minimalPatternCluster, 0); // 40
gd.addNumericField("Minimal initial LWIR pattern cluster size (0 - disable retries)", distortionParameters.minimalPatternClusterLwir, 0); // 10
gd.addNumericField("Scale minimal contrast if the initial cluster is nonzero but smaller", distortionParameters.scaleMinimalInitialContrast, 3);
gd.addNumericField("Overlap of FFT areas when searching for pattern", distortionParameters.searchOverlap, 3);
gd.addNumericField("Pattern subdivision:", distortionParameters.patternSubdiv, 0);
gd.addNumericField("Blur pattern bitmap (sigma): ", distortionParameters.bPatternSigma, 3,5,"pattern cell");
gd.addNumericField("Blur pattern (sigma): ", distortionParameters.barraySigma, 3,5,"sensor pix");
gd.addNumericField("Correlation weights (around maximum):", distortionParameters.correlationWeightSigma, 3,5,"nodes");
gd.addNumericField("Correlation radius scale (0 - sharp sigma)", distortionParameters.correlationRadiusScale, 1,3,"sigmas");
gd.addNumericField("Pattern subdivision:", distortionParameters.patternSubdiv, 0); // 4
gd.addNumericField("Blur pattern bitmap (sigma): ", distortionParameters.bPatternSigma, 3,5,"pattern cell"); // 0.02
gd.addNumericField("Blur pattern (sigma): ", distortionParameters.barraySigma, 3,5,"sensor pix"); // 0.5
gd.addNumericField("Correlation weights (around maximum):", distortionParameters.correlationWeightSigma, 3,5,"nodes"); // 2.5
gd.addNumericField("Correlation radius scale (0 - sharp sigma)", distortionParameters.correlationRadiusScale, 1,3,"sigmas"); //2.0
gd.addNumericField("Correlation maximal radius to use", distortionParameters.correlationRadius, 0,1,"pix");
gd.addNumericField("Correlation maximum calculation threshold", distortionParameters.correlationThreshold*100, 2,5,"%");
gd.addNumericField("Interpolate correlation (FFT*linear)", distortionParameters.correlationSubdiv, 0,1,"x");
gd.addNumericField("Interpolate correlation with FFT", distortionParameters.correlationFFTSubdiv, 0,1,"x");
gd.addNumericField("Correlation maximal radius to use", distortionParameters.correlationRadius, 0,1,"pix"); // 2.0
gd.addNumericField("Correlation maximum calculation threshold", distortionParameters.correlationThreshold*100, 2,5,"%"); // .8
gd.addNumericField("Interpolate correlation (FFT*linear)", distortionParameters.correlationSubdiv, 0,3,"x"); // 16
gd.addNumericField("Interpolate correlation with FFT", distortionParameters.correlationFFTSubdiv, 0,3,"x"); // 4
gd.addNumericField("Correlation dx (debug)", distortionParameters.correlationDx, 3);
gd.addNumericField("Correlation dy (debug)", distortionParameters.correlationDy, 3);
......@@ -20386,23 +20386,22 @@ use the result to create a rejectiobn mask - if the energy was high, (multiplica
WindowTools.addScrollBars(gd);
gd.showDialog();
if (gd.wasCanceled()) return false;
distortionParameters.FFTSize=1;
for (i=(int) gd.getNextNumber(); i >1; i>>=1) distortionParameters.FFTSize <<=1; /* make it to be power of 2 */
distortionParameters.fftGaussWidth= gd.getNextNumber();
distortionParameters.correlationSize=1;
for (i=(int) gd.getNextNumber(); i >1; i>>=1) distortionParameters.correlationSize <<=1; /* make it to be power of 2 */
distortionParameters.maximalCorrelationSize=1;
for (i=(int) gd.getNextNumber(); i >1; i>>=1) distortionParameters.maximalCorrelationSize <<=1; /* make it to be power of 2 */
distortionParameters.correlationGaussWidth= gd.getNextNumber();
distortionParameters.FFTSize = makePowerOfTwo((int) gd.getNextNumber());
distortionParameters.FFTSize_lwir = makePowerOfTwo((int) gd.getNextNumber());
distortionParameters.fftGaussWidth= gd.getNextNumber();
distortionParameters.correlationSize = makePowerOfTwo((int) gd.getNextNumber());
distortionParameters.correlationSizeLwir = makePowerOfTwo((int) gd.getNextNumber());
distortionParameters.maximalCorrelationSize = makePowerOfTwo((int) gd.getNextNumber());
distortionParameters.maximalCorrelationSizeLwir = makePowerOfTwo((int) gd.getNextNumber());
distortionParameters.correlationGaussWidth= gd.getNextNumber();
distortionParameters.absoluteCorrelationGaussWidth=gd.getNextBoolean();
distortionParameters.zeros= (int) gd.getNextNumber();
distortionParameters.phaseCorrelationFraction=gd.getNextNumber();
distortionParameters.correlationHighPassSigma=gd.getNextNumber();
distortionParameters.correlationLowPassSigma= gd.getNextNumber();
distortionParameters.correlationMaxOffset= gd.getNextNumber();
distortionParameters.correlationRingWidth= gd.getNextNumber();
distortionParameters.correlationMinContrast= gd.getNextNumber();
distortionParameters.zeros= (int) gd.getNextNumber();
distortionParameters.phaseCorrelationFraction= gd.getNextNumber();
distortionParameters.correlationHighPassSigma= gd.getNextNumber();
distortionParameters.correlationLowPassSigma= gd.getNextNumber();
distortionParameters.correlationMaxOffset= gd.getNextNumber();
distortionParameters.correlationRingWidth= gd.getNextNumber();
distortionParameters.correlationMinContrast= gd.getNextNumber();
distortionParameters.correlationMinInitialContrast= gd.getNextNumber();
distortionParameters.correlationMinAbsoluteContrast= gd.getNextNumber();
......@@ -20414,6 +20413,8 @@ use the result to create a rejectiobn mask - if the energy was high, (multiplica
distortionParameters.contrastAverageSigma= gd.getNextNumber();
distortionParameters.minimalPatternCluster=(int) gd.getNextNumber();
distortionParameters.minimalPatternClusterLwir=(int) gd.getNextNumber();
distortionParameters.scaleMinimalInitialContrast=gd.getNextNumber();
distortionParameters.searchOverlap= gd.getNextNumber();
......@@ -20460,6 +20461,12 @@ use the result to create a rejectiobn mask - if the energy was high, (multiplica
MASTER_DEBUG_LEVEL= (int) gd.getNextNumber();
return true;
}
private int makePowerOfTwo(int v) {
int v2 = 1;
for (int i=v; i > 1; i>>=1 ) v2 <<=1; /* make it to be power of 2 */
return v2;
}
/* ======================================================================== */
/* ======================================================================== */
public boolean showGaussianStackDialog(EyesisAberrations.InverseParameters inverseParameters) {
......@@ -1278,10 +1278,11 @@ public class EyesisAberrations {
}
int rslt=matchSimulatedPattern.calculateDistortions(
null, // LwirReaderParameters lwirReaderParameters, // null is OK
distortionParameters, //
patternDetectParameters,
patternDetectParameters.minGridPeriod/2,
patternDetectParameters.maxGridPeriod/2,
// patternDetectParameters.minGridPeriod/2,
// patternDetectParameters.maxGridPeriod/2,
simulParameters,
colorComponents.equalizeGreens,
imp,
......@@ -2709,7 +2710,8 @@ public class EyesisAberrations {
distortedPattern[2], //
simulParameters.subdiv,
fft_size,
simulParameters.center_for_g2);
simulParameters.center_for_g2,
false);//boolean mono
wVectors[0][0]=2.0*distortedPattern[0][0]/subpixel;
wVectors[0][1]=2.0*distortedPattern[0][1]/subpixel;
wVectors[1][0]=2.0*distortedPattern[1][0]/subpixel;
......@@ -2752,7 +2754,8 @@ public class EyesisAberrations {
simCorr, //
simulParameters.subdiv,
fft_size,
simulParameters.center_for_g2);
simulParameters.center_for_g2,
false);//boolean mono
}
// simul_pixels= simulationPattern.extractSimulPatterns (
simul_pixels= simulationPattern.extractSimulPatterns (
......
......@@ -665,11 +665,12 @@ horizontal axis:
boolean noMessageBoxes=true;
int numAbsolutePoints = matchSimulatedPattern.calculateDistortions(
null, // LwirReaderParameters lwirReaderParameters, // null is OK
// allow more of grid around pointers?
distortionParameters, //
this.patternDetectParameters,
this.patternDetectParameters.minGridPeriod/2,
this.patternDetectParameters.maxGridPeriod/2,
// this.patternDetectParameters.minGridPeriod/2,
// this.patternDetectParameters.maxGridPeriod/2,
simulParameters,
equalizeGreens, imp_eq,
this.laserPointers, // null, //LASER_POINTERS, //
......@@ -840,25 +841,26 @@ horizontal axis:
// matchSimulatedPatterns[numSensor].getChannel(images[numSensor])+" ");
int numAbsolutePoints = this.matchSimulatedPatterns[numSensor].calculateDistortions(
// allow more of grid around pointers?
distortionParameters, //
this.patternDetectParameters,
this.patternDetectParameters.minGridPeriod/2,
this.patternDetectParameters.maxGridPeriod/2,
simulParameters,
equalizeGreens, imp_eq,
this.laserPointers, // null, //LASER_POINTERS, //
// LaserPointer laserPointer, //
// LaserPointer object or null
true, // don't care -removeOutOfGridPointers
null, // double [][][] hintGrid, // predicted grid array (or null)
0, // double hintGridTolerance, // allowed mismatch (fraction of period) or 0 - orientation only
threadsMax,
updateStatus,
debug_level,
distortionParameters.loop_debug_level, // debug level
noMessageBoxes);
null, // LwirReaderParameters lwirReaderParameters, // null is OK
// allow more of grid around pointers?
distortionParameters, //
this.patternDetectParameters,
// this.patternDetectParameters.minGridPeriod/2,
// this.patternDetectParameters.maxGridPeriod/2,
simulParameters,
equalizeGreens, imp_eq,
this.laserPointers, // null, //LASER_POINTERS, //
// LaserPointer laserPointer, //
// LaserPointer object or null
true, // don't care -removeOutOfGridPointers
null, // double [][][] hintGrid, // predicted grid array (or null)
0, // double hintGridTolerance, // allowed mismatch (fraction of period) or 0 - orientation only
threadsMax,
updateStatus,
debug_level,
distortionParameters.loop_debug_level, // debug level
noMessageBoxes);
if (numAbsolutePoints <= 0) { // no pointers in this image
String msg = "*** No laser pointers matched for " + images[numSensor].getTitle() + " - they are needed for absolute grid positioning";
if (debug_level > 0) System.out.println("Warning: " + msg);
......
......@@ -99,6 +99,7 @@ public class LensAdjustment {
ImagePlus imp_eq=matchSimulatedPattern.applyFlatField (imp); // will throw if image size mismatch
if (updating) {
double maxActualCorr= matchSimulatedPattern.refineDistortionCorrelation (
null, // LwirReaderParameters lwirReaderParameters, // null is OK
distortionParameters, //
patternDetectParameters,
simulParameters,
......@@ -132,7 +133,8 @@ public class LensAdjustment {
System.out.println("updateFocusGrid(), number of already defined grid cells (before distortions()) = "+matchSimulatedPattern.numDefinedCells());
}
matchSimulatedPattern.distortions(
null, // is not used in update mode
null, //LwirReaderParameters lwirReaderParameters, // null is OK
null, // final boolean [] triedIndices, // is not used in update mode
distortionParameters, //
patternDetectParameters,
patternDetectParameters.minGridPeriod/2,
......@@ -157,10 +159,11 @@ public class LensAdjustment {
// matchSimulatedPattern.invalidateFlatFieldForGrid(); //Keep these!
// matchSimulatedPattern.invalidateFocusMask();
numAbsolutePoints=matchSimulatedPattern.calculateDistortions( // allow more of grid around pointers?
null, // LwirReaderParameters lwirReaderParameters, // null is OK
distortionParameters, //
patternDetectParameters,
patternDetectParameters.minGridPeriod/2,
patternDetectParameters.maxGridPeriod/2,
// patternDetectParameters.minGridPeriod/2,
// patternDetectParameters.maxGridPeriod/2,
simulParameters,
equalizeGreens,
imp_eq,
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -17,7 +17,7 @@ import ij.IJ;
** Copyright (C) 2010-2011 Elphel, Inc.
**
** -----------------------------------------------------------------------------**
**
**
** SimulationPattern.java is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
......@@ -35,11 +35,11 @@ import ij.IJ;
*/
public class SimulationPattern {
// private double [] bPattern; // pattern bitmap (does not change)
// private double[][] barray; // high resolution boolean pattern array (specific to distortions in each area)
// private double [] bPattern; // pattern bitmap (does not change)
// private double[][] barray; // high resolution boolean pattern array (specific to distortions in each area)
public double [] bPattern=null; // pattern bitmap (does not change)
public int bPatternSize=0;
/// public double[][] barray; // high resolution boolean pattern array (specific to distortions in each area)
/// public double[][] barray; // high resolution boolean pattern array (specific to distortions in each area)
public double[] barray; // high resolution boolean pattern array (specific to distortions in each area)
public double bPatternSigma=0.0;
public double barraySigma=0.0;
......@@ -55,15 +55,15 @@ public class SimulationPattern {
}
public SimulationPattern(
SimulParameters simulParameters ) {
this.bPatternSigma=simulParameters.bPatternSigma;
this.barraySigma=simulParameters.barraySigma;
patternGenerator(simulParameters);
this.bPatternSigma=simulParameters.bPatternSigma;
this.barraySigma=simulParameters.barraySigma;
patternGenerator(simulParameters);
}
public SimulationPattern(
int size,
int patternNumber,
double patternModifier) {
patternGenerator(size,patternNumber,patternModifier);
patternGenerator(size,patternNumber,patternModifier);
}
/* ======================================================================== */
public double [] patternGenerator(
......@@ -116,10 +116,10 @@ public class SimulationPattern {
break;
default: for (index=0;index<this.bPattern.length;index++) this.bPattern[index]=1.0;
}
// blur pattern
// blur pattern
if (this.bPatternSigma>0) {
if (this.bPatternSigma>0.25) this.bPatternSigma=0.25;
// 1 - add margins around the pattern
// 1 - add margins around the pattern
int i1,j1;
int margin= (int) Math.ceil(3*size*this.bPatternSigma);
int sizeM=size+2*margin;
......@@ -134,11 +134,11 @@ public class SimulationPattern {
bPatternM[i*sizeM+j]= (invertX ^ invertY)?(1.0-this.bPattern[i1*size+j1]):this.bPattern[i1*size+j1];
}
}
// apply blur
// apply blur
if (this.debugLevel>3) SDFA_INSTANCE.showArrays(bPatternM,sizeM,sizeM, "bPatternM");
this.gb.blurDouble(bPatternM,sizeM,sizeM,size*this.bPatternSigma,size*this.bPatternSigma, 0.01);
if (this.debugLevel>3) SDFA_INSTANCE.showArrays(bPatternM,sizeM,sizeM, "bPatternM-blured");
// remove margins
// remove margins
for (i=0;i<size;i++) for (j=0;j<size;j++) {
this.bPattern[i*size+j]= bPatternM[(i+margin)*sizeM+(j+margin)];
}
......@@ -146,7 +146,7 @@ public class SimulationPattern {
return this.bPattern;
}
/* ======================================================================== */
/* ======================================================================== */
public void simulatePatternFullPattern(
double freqX1,
double freqY1,
......@@ -157,7 +157,8 @@ public class SimulationPattern {
double [] corr,
int subdiv,
int size,
boolean center_for_g2) {
boolean center_for_g2,
boolean mono) {// takes precedence over center_for_g2, makes symmetrical around center of array (between pixels)
this.barray=simulatePatternFullPatternSafe(
freqX1,
freqY1,
......@@ -168,10 +169,12 @@ public class SimulationPattern {
corr,
subdiv,
size,
center_for_g2);
center_for_g2,
mono);
}
public double [] simulatePatternFullPatternSafe(
double freqX1,
double freqY1,
......@@ -182,7 +185,8 @@ public class SimulationPattern {
double [] corr,
int subdiv,
int size,
boolean center_for_g2) {
boolean center_for_g2,
boolean mono) {// takes precedence over center_for_g2, makes symmetrical around center of array (between pixels)
int patternSize= (this.bPattern!=null)?((int) Math.sqrt(this.bPattern.length)):0;
double twicePatternSize=2*patternSize;
int i,j;
......@@ -211,12 +215,16 @@ public class SimulationPattern {
double [] phases={phase1/(Math.PI*2)+0.25,phase2/(Math.PI*2)+0.25}; // period=1.0;
int iu,iv;
boolean invert;
for (i=0;i<fullSize;i++) {
yl=(i-0.5*fullSize)/subdiv-(center_for_g2?0.5:1.0); // center in the middle of Bayer
for (j=0;j<fullSize;j++) {
xl=(j-0.5*fullSize)/subdiv-(center_for_g2?0.5:1.0); // center in the middle of Bayer
/* apply second order polynomial correction to x,y
double offset = mono? 0.0: ((center_for_g2?0.5:1.0));
double center = 0.5*fullSize; // +(mono?-0.5: 0.0); // see if it is needed!
// in mono mode result barray is symmetrical around [fullSize/2,fullSize/2], but
// after extractSimulMono result will be symmetrical around [size/2-0.5, size/2 - 0.5]
for (i=0; i<fullSize; i++) {
yl=(i - center) / subdiv - offset; // center in the middle of Bayer
for (j=0; j<fullSize; j++) {
xl=(j - center) / subdiv - offset; // center in the middle of Bayer
/* apply second order polynomial correction to x,y
x=xl+Ax*xl^2+Bx*yl^2+2*Cx*xl*yl;
y=xl+Ay*xl^2+By*yl^2+2*Cy*xl*yl; */
if (corr==null) {
......@@ -256,31 +264,31 @@ public class SimulationPattern {
}
}
}
// Blur barray pattern if sigma >0
// Blur barray pattern if sigma >0
if (this.barraySigma>0) {
double sigma=this.barraySigma*subdiv; //*/ 2?
double sigma=this.barraySigma*subdiv; //*/ 2?
if (this.debugLevel>3) SDFA_INSTANCE.showArrays(localBarray, "localBarray");
this.gb.blurDouble(localBarray,fullSize,fullSize,sigma,sigma, 0.01);
if (this.debugLevel>3) SDFA_INSTANCE.showArrays(localBarray, "localBarray-blured");
}
return localBarray;
}
/* ======================================================================== */
public double [] recursiveFillPixels ( // invert pattern in the caller, return signed value (-1..1 - pattern is 0..1)
SimulParameters simulParameters,
double [] xy, // top-left corner
double [] dxy, // increments to other corners
double [][][] cornersXY, // xy pairs for the 4 corners of the square in UV (pattern) coordinates (u0v0,u1v0,u0v1,u1v1)
double [] uv, // UV value for the top-left corner (matching cornersXY[0][0])
double [] duv, // distances to the opposite corner in UV
// final boolean maskOnly, // just mark defined cells
int debug
){ //use this.bPattern, this.bPatternSize (side of the square)
/* ======================================================================== */
public double [] recursiveFillPixels ( // invert pattern in the caller, return signed value (-1..1 - pattern is 0..1)
SimulParameters simulParameters,
double [] xy, // top-left corner
double [] dxy, // increments to other corners
double [][][] cornersXY, // xy pairs for the 4 corners of the square in UV (pattern) coordinates (u0v0,u1v0,u0v1,u1v1)
double [] uv, // UV value for the top-left corner (matching cornersXY[0][0])
double [] duv, // distances to the opposite corner in UV
// final boolean maskOnly, // just mark defined cells
int debug
){ //use this.bPattern, this.bPatternSize (side of the square)
double [][][] cornersUV=new double [2][2][];
double [] xy4=new double[2];
double [] result ={0.0,0.0};
int numInside=0;
double [] xy4=new double[2];
double [] result ={0.0,0.0};
int numInside=0;
for (int i=0;i<2;i++) for (int j=0;j<2;j++) {
xy4[0]=xy[0]+j*dxy[0];
xy4[1]=xy[1]+i*dxy[1];
......@@ -289,7 +297,7 @@ public class SimulationPattern {
}
if (debug>21){
String dbgStr="";
// IJ.d2s(quarter_patterns[iq][0][0],4)
// IJ.d2s(quarter_patterns[iq][0][0],4)
dbgStr+="xy={"+IJ.d2s(xy[0],2)+","+IJ.d2s(xy[1],2)+"} ";
dbgStr+=" dxy={"+IJ.d2s(dxy[0],2)+","+IJ.d2s(dxy[1],2)+"} ";
dbgStr+=" uv={"+IJ.d2s(uv[0],2)+","+IJ.d2s(uv[1],2)+"} ";
......@@ -307,25 +315,25 @@ public class SimulationPattern {
}
if (numInside==0) return result; // all corners outside of the (sub)pattern cell
// if (maskOnly) {
if (simulParameters==null) {
// if (maskOnly) {
if (simulParameters==null) {
result[1]=dxy[0]*dxy[1];
result[0]=result[1];
return result;
result[0]=result[1];
return result;
}
// recalculate to the full uv
// recalculate to the full uv
boolean cornersInvert;
double [][] cornerValue=new double [2][2];
int [] iPat=new int [2];
double min=1.0,max=-1.0;
for (int i=0;i<2;i++) for (int j=0;j<2;j++) {
// cornersUV[i][j][0]=uv[0]+j*cornersUV[i][j][0]*duv[0];
// cornersUV[i][j][1]=uv[1]+i*cornersUV[i][j][1]*duv[1];
// cornersUV[i][j][0]=uv[0]+j*cornersUV[i][j][0]*duv[0];
// cornersUV[i][j][1]=uv[1]+i*cornersUV[i][j][1]*duv[1];
cornersUV[i][j][0]=uv[0]+cornersUV[i][j][0]*duv[0];
cornersUV[i][j][1]=uv[1]+cornersUV[i][j][1]*duv[1];
cornersInvert=false;
for (int k=0;k<2;k++) {
// iPat[k] = (int) Math.floor(cornersUV[i][j][k]*this.bPatternSize*2.0); // 0.5 ->bPatternSize
// iPat[k] = (int) Math.floor(cornersUV[i][j][k]*this.bPatternSize*2.0); // 0.5 ->bPatternSize
iPat[k] = (int) Math.floor(cornersUV[i][j][k]*this.bPatternSize); // 1.0 ->bPatternSize
if (iPat[k]<0){
iPat[k]+=this.bPatternSize;
......@@ -343,11 +351,11 @@ public class SimulationPattern {
if (max<cornerValue[i][j]) max=cornerValue[i][j];
if (min>cornerValue[i][j]) min=cornerValue[i][j];
}
if (((max-min)>simulParameters.bitmapNonuniforityThreshold) &&
if (((max-min)>simulParameters.bitmapNonuniforityThreshold) &&
(dxy[0]>simulParameters.smallestSubPix) &&
(dxy[1]>simulParameters.smallestSubPix)) {
// divide this square into 4 quadrants, return sum of the recursively called method on them
// divide this square into 4 quadrants, return sum of the recursively called method on them
double [][] quadrants={{0.0,0.0},{0.5,0.0},{0.0,0.5},{0.5,0.5}};
double [] subResult;
double [] subxy=new double [2];
......@@ -356,28 +364,28 @@ public class SimulationPattern {
System.out.println("---> Subdividing into "+subdxy[0]+"x"+subdxy[0]+" (max="+IJ.d2s(max,3)+" min="+IJ.d2s(min,3)+
" max-min="+IJ.d2s(max-min,3)+
" cornerValue: [0][0]="+IJ.d2s(cornerValue[0][0],3)+
" [0][1]="+IJ.d2s(cornerValue[0][1],3)+
" [1][0]="+IJ.d2s(cornerValue[1][0],3)+
" [1][1]="+IJ.d2s(cornerValue[1][1],3)+
" [0][1]="+IJ.d2s(cornerValue[0][1],3)+
" [1][0]="+IJ.d2s(cornerValue[1][0],3)+
" [1][1]="+IJ.d2s(cornerValue[1][1],3)+
" cornersUV={{{"+IJ.d2s(cornersUV[0][0][0],3)+","+IJ.d2s(cornersUV[0][0][1],3)+"},"+
"{"+IJ.d2s(cornersUV[0][1][0],3)+","+IJ.d2s(cornersUV[0][1][1],3)+"}},"+
"{{"+IJ.d2s(cornersUV[1][0][0],3)+","+IJ.d2s(cornersUV[1][0][1],3)+"},"+
"{"+IJ.d2s(cornersUV[1][1][0],3)+","+IJ.d2s(cornersUV[1][1][1],3)+"}}}");
"{"+IJ.d2s(cornersUV[0][1][0],3)+","+IJ.d2s(cornersUV[0][1][1],3)+"}},"+
"{{"+IJ.d2s(cornersUV[1][0][0],3)+","+IJ.d2s(cornersUV[1][0][1],3)+"},"+
"{"+IJ.d2s(cornersUV[1][1][0],3)+","+IJ.d2s(cornersUV[1][1][1],3)+"}}}");
}
for (int i=0;i<quadrants.length;i++) {
subxy[0]=xy[0]+dxy[0]*quadrants[i][0];
subxy[1]=xy[1]+dxy[1]*quadrants[i][1];
subResult= recursiveFillPixels ( // invert pattern in the caller, return signed value (-1..1 - pattern is 0..1)
subResult= recursiveFillPixels ( // invert pattern in the caller, return signed value (-1..1 - pattern is 0..1)
simulParameters,
subxy, // top-left corner
subxy, // top-left corner
subdxy, // increments to other corners
cornersXY, // xy pairs for the 4 corners of the square in UV (pattern) coordinates (u0v0,u1v0,u0v1,u1v1)
uv, // UV value for the top-left corner (matching cornersXY[0][0])
duv, // distances to the opposite corner in UV
// maskOnly, // just mark defined cells //always false - will never get here
// maskOnly, // just mark defined cells //always false - will never get here
debug
);
);
result[0]+=subResult[0];
result[1]+=subResult[1];
}
......@@ -391,7 +399,7 @@ public class SimulationPattern {
result[1]=dxy[0]*dxy[1];
result[0]*=result[1];
if (numInside <4) {
double f=((double) numInside)/4; // estimate fraction of the pixel - start with simple number of corners
double f=((double) numInside)/4; // estimate fraction of the pixel - start with simple number of corners
result[0]*=f;
result[1]*=f;
}
......@@ -402,7 +410,7 @@ public class SimulationPattern {
}
return result;
}
/* ======================================================================== */
/* ======================================================================== */
/**
* @param cornersXY first index V, second index U, third index:0 - x, 1-y
* @param xy 0-x,1-y of the point, for which UV should be generated
......@@ -411,7 +419,7 @@ public class SimulationPattern {
public double [] bilinearXY2UV(
double [][][] cornersXY, // first index V, second index U, third index:0 - x, 1-y
double [] xy, // 0-x,1-y of the point, for which
int debug
int debug
) {
return bilinearXY2UV(
cornersXY, // first index V, second index U, third index:0 - x, 1-y
......@@ -429,9 +437,9 @@ public class SimulationPattern {
double [][][] cornersXY, // first index V, second index U, third index:0 - x, 1-y
double [] xy, // 0-x,1-y of the point, for which
double quadThreshold, // if abs(4*a*c)/b^2 is less than this, use linear, not quadratic equations
int debug
int debug
) {
/*
/*
x,y -> u,v
(1) x= v*u*Ax + v*Bx + u*Cx + Dx
......@@ -460,8 +468,8 @@ Av=(By*Ax-Bx*Ay)
Bv=((-Bx*Cy-Ay*Dx+By*Cx+Ax*Dy)+Ay*x-Ax*y)
Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy)
*/
*/
double Ax=cornersXY[1][1][0]-cornersXY[1][0][0]-cornersXY[0][1][0]+cornersXY[0][0][0];
double Bx=cornersXY[1][0][0]-cornersXY[0][0][0];
double Cx=cornersXY[0][1][0]-cornersXY[0][0][0];
......@@ -479,26 +487,26 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy)
double Av=(By*Ax-Bx*Ay);
double Bv=((-Bx*Cy-Ay*Dx+By*Cx+Ax*Dy)+Ay*xy[0]-Ax*xy[1]);
double Cv=(Cy*xy[0]-Cx*xy[1])+(-Cy*Dx+Cx*Dy);
// double [] UV={-Cv/Bv,-Cu/Bu}; // linear solution - use for linear grid
// double [] UV={-Cv/Bv,-Cu/Bu}; // linear solution - use for linear grid
double [] UV={-Cu/Bu,-Cv/Bv}; // linear solution - use for linear grid
double au=0.0,bu=0.0,av=0.0,bv=0.0;
if (Math.abs(Au*Cu)/(Bu*Bu)>quadThreshold) { // use quadratic equation for U
au=-Bu/(2*Au);
bu=Math.sqrt(Bu*Bu-4*Au*Cu)/Math.abs(2*Au);
// Use solution that is closer to linear one
// Use solution that is closer to linear one
if (UV[0]>au) UV[0]=au+bu;
else UV[0]=au-bu;
}
if (Math.abs(Av*Cv)/(Bv*Bv)>quadThreshold) { // use quadratic equation for V
av=-Bv/(2*Av);
bv=Math.sqrt(Bv*Bv-4*Av*Cv)/Math.abs(2*Av);
// Use solution that is closer to linear one
// Use solution that is closer to linear one
if (UV[1]>av) UV[1]=av+bv;
else UV[1]=av-bv;
}
if (debug>2){
String dbgStr="";
// IJ.d2s(quarter_patterns[iq][0][0],4)
// IJ.d2s(quarter_patterns[iq][0][0],4)
dbgStr+=" Ax="+IJ.d2s(Ax,5)+", Bx="+IJ.d2s(Bx,5)+", Cx="+IJ.d2s(Cx,5)+", Dx="+IJ.d2s(Dx,5);
dbgStr+=" Ay="+IJ.d2s(Ay,5)+", By="+IJ.d2s(By,5)+", Cy="+IJ.d2s(Cy,5)+", Dy="+IJ.d2s(Dy,5);
dbgStr+=" Au="+IJ.d2s(Au,5)+", Bu="+IJ.d2s(Bu,5)+", Cu="+IJ.d2s(Cu,5);
......@@ -511,388 +519,390 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy)
return UV;
}
/* ======================================================================== */
private boolean isCellValid(
double [][][][] grid,
int [] uv){
if ((uv[1]>=0) && (uv[0]>=0) && (uv[1]<grid.length) && (uv[0]<grid[uv[1]].length)) {
double [][] cell = grid[uv[1]][uv[0]];
return ((cell!=null) && (cell.length>1));
}
return false;
}
/*
/* ======================================================================== */
private boolean isCellValid(
double [][][][] grid,
int [] uv){
if ((uv[1]>=0) && (uv[0]>=0) && (uv[1]<grid.length) && (uv[0]<grid[uv[1]].length)) {
double [][] cell = grid[uv[1]][uv[0]];
return ((cell!=null) && (cell.length>1));
}
return false;
}
/*
private boolean isCellDefined(
double [][][][] grid,
int [] uv){
return ((uv[1]>=0) && (uv[0]>=0) && (uv[1]<grid.length) && (uv[0]<grid[uv[1]].length) &&
(grid[uv[1]][uv[0]]!=null) && (grid[uv[1]][uv[0]][0]!=null));
(grid[uv[1]][uv[0]]!=null) && (grid[uv[1]][uv[0]][0]!=null));
}
*/
public float [] combineWithCanvas(
double canvasFill,
int width,
int height,
Rectangle woi,
float [] selection ){
float []canvas=new float[width*height];
for (int i=0;i<canvas.length;i++)canvas[i]= (float) canvasFill;
return combineWithCanvas(canvas, width, woi, selection );
}
public float [] combineWithCanvas(
float [] canvas,
int width,
Rectangle woi,
float [] selection ){
// debug
if (selection==null) System.out.println("combineWithCanvas(): selection==null");
if (woi==null) System.out.println("combineWithCanvas(): woi==null");
if (selection.length!=(woi.width*woi.height)) throw new IllegalArgumentException ("selection.length="+selection.length+", woi.width="+woi.width+", woi.height="+woi.height);
int i0=0;
int i1=width*woi.y+woi.x;
for (int y=0;y<woi.height;y++){
for (int x=0;x<woi.width;x++){
if ((i1>canvas.length) ||(i0>=selection.length)){
System.out.println("canvas.length="+canvas.length+" width="+width+" selection.length="+selection.length+" y="+y+" x="+x+" i0="+i0+" i1="+i1+
" woi.x="+woi.x+" woi.y="+woi.y+" woi.width="+woi.width+" woi.height="+woi.height);
}
canvas[i1++]=selection[i0++]; // OOB 18720
}
i1+=(width-woi.width);
}
return canvas;
}
public double [] combineWithCanvas(
double canvasFill,
int width,
int height,
Rectangle woi,
double [] selection ){
double []canvas=new double[width*height];
for (int i=0;i<canvas.length;i++)canvas[i]= canvasFill;
return combineWithCanvas(canvas, width, woi, selection );
}
public double [] combineWithCanvas(
double [] canvas,
int width,
Rectangle woi,
double [] selection ){
if (selection.length!=(woi.width*woi.height)) throw new IllegalArgumentException ("selection.length="+selection.length+", woi.width="+woi.width+", woi.height="+woi.height);
int i0=0;
int i1=width*woi.y+woi.x;
for (int y=0;y<woi.height;y++){
for (int x=0;x<woi.width;x++) canvas[i1++]=selection[i0++];
i1+=(width-woi.width);
}
return canvas;
}
//===================== Moved from Aberration_Calibration
public float[][] simulateGridAll (
int width, // extend to full image, width, height - original (not scaled) image size
int height,
MatchSimulatedPattern matchSimulatedPattern,
// double [][][][] patternGrid, // should be aligned to gridFrac
int gridFrac, // number of grid steps per pattern full period
SimulParameters simulParameters,
int threadsMax,
boolean updateStatus,
int globalDebugLevel,
int debug_level){// debug level used inside loops
// SimulationPattern simulationPattern=new SimulationPattern(simulParameters);
float [][] simArray0=simulateGridAll (
matchSimulatedPattern,
// patternGrid, // should be aligned to gridFrac
gridFrac, // number of grid steps per pattern full period
simulParameters,
// simulationPattern,
threadsMax,
updateStatus,
globalDebugLevel,
debug_level);
Rectangle woi=matchSimulatedPattern.getWOI();
if ((woi.x==0) && (woi.y==0) && (woi.width==width) && (woi.height==height)) return simArray0;
int k=simulParameters.subdiv/2;
Rectangle scaledWoi=new Rectangle(k*woi.x, k*woi.y, k*woi.width, k*woi.height);
float [][] simArray=new float [2][];
simArray[0]=(new SimulationPattern(simulParameters)).combineWithCanvas(0.0, k*width, k*height, scaledWoi,simArray0[0]);
simArray[1]=(new SimulationPattern(simulParameters)).combineWithCanvas(0.0, k*width, k*height, scaledWoi,simArray0[1]);
if (globalDebugLevel>1) SDFA_INSTANCE.showArrays(simArray,width*k,height*k,true, "full-simulation");
return simArray;
}
public float[][] simulateGridAll (
MatchSimulatedPattern matchSimulatedPattern,
// double [][][][] patternGrid, // should be aligned to gridFrac
int gridFrac, // number of grid steps per pattern full period
SimulationPattern.SimulParameters simulParameters,
// SimulationPattern simulationPattern, // or null
int threadsMax,
boolean updateStatus,
int globalDebugLevel,
int debug_level){// debug level used inside loops
long startTime=System.nanoTime();
double [][] xy0={{simulParameters.offsetX,simulParameters.offsetY},{simulParameters.offsetX-0.5,simulParameters.offsetY-0.5}} ;
// if (simulationPattern==null) simulationPattern=new SimulationPattern(simulParameters);
float[][] simArray=new float[2][];
simArray[0]= simulateGrid (
matchSimulatedPattern.getDArray(),
2, // gridFrac, // number of grid steps per pattern full period
simulParameters,
matchSimulatedPattern.getWOI(),
simulParameters.subdiv/2,
xy0[0], // add to patterGrid xy
threadsMax,
updateStatus,
debug_level); // debug level
simArray[1]= simulateGrid (
matchSimulatedPattern.getDArray(),
2, // gridFrac, // number of grid steps per pattern full period
simulParameters,
matchSimulatedPattern.getWOI(),
simulParameters.subdiv/2,
xy0[1], // add to patterGrid xy
threadsMax,
updateStatus,
debug_level); // debug level
if (globalDebugLevel>2) SDFA_INSTANCE.showArrays(simArray,matchSimulatedPattern.getWOI().width*simulParameters.subdiv/2,matchSimulatedPattern.getWOI().height*simulParameters.subdiv/2,true, "a-simulation");
if (globalDebugLevel>1) System.out.println("Grid simulation is finished at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
return simArray;
}
//========================
public float [] simulateGrid (
final double [][][][] patternGrid, // should be aligned to gridFrac
final int gridFrac, // number of grid steps per pattern full period: black+white
final SimulParameters simulParameters, // Try to use null here for maskOnly
final Rectangle woi,
final int subdiv, // subdivide output array from woi (normally 2)
double[] shift_xy, // add to patterGrid xy, null OK
// final boolean maskOnly, // just mark defined cells
final int threadsMax,
final boolean updateStatus,
final int debug_level){// debug level used inside loops
double []xy_zero={0.0,0.0};
if (patternGrid==null) return null;
final double [] xy0=(shift_xy==null)?xy_zero:shift_xy;
if ((simulParameters!=null) && (this.bPattern==null)){
System.out.println("simulateGrid(), running patternGenerator(simulParameters )");
patternGenerator(simulParameters ); // generate bPattern if it was not done yet
}
final Rectangle woiOut=new Rectangle(subdiv*woi.x,subdiv*woi.y,subdiv*woi.width,subdiv*woi.height);
final float [] pixels=new float[woiOut.width*woiOut.height];
final float [] pixelsDenom=new float[woiOut.width*woiOut.height];
for (int i=0;i<pixels.length;i++ ){
pixels[i]= 0.0F;
pixelsDenom[i]= 0.0F;
}
final Thread[] threads = newThreadArray(threadsMax);
final AtomicInteger cellNum = new AtomicInteger(0);
final int [] series = new int[1];
final int uvhwidth=(patternGrid[0].length+1)/2;
final int uvwidth= patternGrid[0].length;
final int uvhheight=(patternGrid.length+1)/2;
final int numInSeries=(uvhwidth-1)*(uvhheight-1);
final AtomicInteger debugCellNum = new AtomicInteger(0);
final AtomicInteger finishedAtomic = new AtomicInteger(1);
final int cellsToProcess=numInSeries*4;
final int debugCellNum0=0;
IJ.showStatus("Generating simulated pattern...");
for (series[0]=0;series[0]<4;series[0]++) { // split processing in 4 series (odd/even row/column to avoid races between threads
if (debug_level>2)System.out.println("**** series[0]="+series[0]);
cellNum.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
// String dbgStr="";
int [][][] iUV=new int [2][2][2];
double [][][] dUV=new double [2][2][2];
double [][][] xy=new double [2][2][2];
boolean invPattern;
double [] pixDXY={1.0,1.0};
for (int ncell=cellNum.getAndIncrement(); ncell<numInSeries;ncell=cellNum.getAndIncrement()){
iUV[0][0][0]=2*(ncell%(uvhwidth-1))+ (series[0] & 1);
iUV[0][0][1]=2*(ncell/(uvhwidth-1))+ ((series[0]>>1) & 1);
if ((updateStatus) && (debugLevel>1)) IJ.showStatus("Generating simulated pattern, series "+series[0]+" (of 4), row "+(iUV[0][0][1]/2+1)+"(of "+(uvhheight-1)+")");
if (debugLevel>2) System.out.println("Generating pattern, series "+series[0]+" (of 4), row "+(iUV[0][0][1]/2+1)+"(of "+(uvhheight-1)+")");
iUV[0][1][0]=iUV[0][0][0]+1;
iUV[0][1][1]=iUV[0][0][1];
iUV[1][0][0]=iUV[0][0][0];
iUV[1][0][1]=iUV[0][0][1]+1;
iUV[1][1][0]=iUV[0][0][0]+1;
iUV[1][1][1]=iUV[0][0][1]+1;
if ((isCellValid(patternGrid,iUV[0][0])) &&
(isCellValid(patternGrid,iUV[0][1])) &&
(isCellValid(patternGrid,iUV[1][0])) &&
(isCellValid(patternGrid,iUV[1][1]))){
// All 4 corners are valid
invPattern=((iUV[0][0][0]%gridFrac)>=(gridFrac/2))^((iUV[0][0][1]%gridFrac)>=(gridFrac/2));
if (debug_level>2)System.out.println("iUV[0][0][1]="+iUV[0][0][1]+" iUV[0][0][0]="+iUV[0][0][0]+" invert="+invPattern);
for (int i=0;i<2;i++) for (int j=0;j<2;j++) for (int k=0;k<2;k++) {
xy[i][j][k]=subdiv*patternGrid[iUV[i][j][1]][iUV[i][j][0]][0][k]+xy0[k];
}
for (int k=0;k<2;k++) {
dUV[0][0][k]=((double) (iUV[0][0][k]%(gridFrac/2)))/(gridFrac/2);
}
dUV[0][1][0]=dUV[0][0][0]+1.0/(gridFrac/2);
dUV[0][1][1]=dUV[0][0][1];
dUV[1][0][0]=dUV[0][0][0];
dUV[1][0][1]=dUV[0][0][1]+1.0/(gridFrac/2);
dUV[1][1][0]=dUV[0][1][0];
dUV[1][1][1]=dUV[1][0][1];
double [] minXY={xy[0][0][0],xy[0][0][1]};
double [] maxXY={xy[0][0][0],xy[0][0][1]};
for (int i=0;i<2;i++) for (int j=0;j<2;j++) for (int k=0;k<2;k++) {
if (minXY[k]>xy[i][j][k]) minXY[k]=xy[i][j][k];
if (maxXY[k]<xy[i][j][k]) maxXY[k]=xy[i][j][k];
}
Rectangle rcell=new Rectangle((int)minXY[0], // contains all pixels
(int)minXY[1],
((int) Math.ceil(maxXY[0]))-((int)minXY[0]) ,
((int) Math.ceil(maxXY[1]))-((int)minXY[1]));
double [] cornersDUV={1.0/(gridFrac/2),1.0/(gridFrac/2)};
boolean debugNow=debugCellNum.getAndIncrement()==debugCellNum0;
if (woiOut.intersects (rcell)) // do not bother if no
for (int iy=rcell.y;iy<(rcell.y+rcell.height);iy++) for (int ix=rcell.x;ix<(rcell.x+rcell.width);ix++)
if (woiOut.contains (ix,iy))
{
double [] pixXY={(double) ix,(double) iy};
double [] pixData=recursiveFillPixels ( // invert pattern in the caller, return signed value (-1..1 - pattern is 0..1)
simulParameters,
pixXY, // top-left corner
pixDXY, // increments to other corners
xy, // xy pairs for the 4 corners of the square in UV (pattern) coordinates (u0v0,u1v0,u0v1,u1v1)
dUV[0][0], // UV value for the top-left corner (matching cornersXY[0][0])
cornersDUV, // distances to the opposite corner in UV
// maskOnly, // just mark defined cells
debugNow?debug_level: debug_level-2
);
// int index=woiOut.width*iy+ix;
int index=woiOut.width*(iy-woiOut.y)+(ix-woiOut.x);
// pixels[index]+=((invPattern || maskOnly)?1.0:-1.0)*pixData[0];
if (index>pixels.length){
// final float [] pixels=new float[woiOut.width*woiOut.height];
System.out.println("simulateGrid(), pixels.length="+pixels.length+
" index="+index+
" iy="+iy+" ix="+ix+
" ncell="+ncell+
" subdiv="+subdiv+
" woiOut.x="+woiOut.x+
" woiOut.y="+woiOut.y+
" woiOut.width="+woiOut.width+
" woiOut.height="+woiOut.height+
" woi.x="+woi.x+
" woi.y="+woi.y+
" woi.width="+woi.width+
" woi.height="+woi.height+
" rcell.x="+rcell.x+
" rcell.y="+rcell.y+
" rcell.width="+rcell.width+
" rcell.height="+rcell.height);
}
// if (maskOnly) pixels[index]=patternGrid.length*iUV[0][0][1]+iUV[0][0][0]; // out of bounds
// OLD NASTY BUG!
// if (maskOnly) pixels[index]=uvwidth*iUV[0][0][1]+iUV[0][0][0]; // Should be width, not height!
if (simulParameters==null) pixels[index]=uvwidth*iUV[0][0][1]+iUV[0][0][0]; // Should be width, not height!
else pixels[index]+=(invPattern?1.0:-1.0)*pixData[0];
pixelsDenom[index]+=pixData[1];
}
}
final int numFinished=finishedAtomic.getAndIncrement();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
IJ.showProgress(numFinished,cellsToProcess);
}
});
}
}
};
}
startAndJoin(threads);
*/
public float [] combineWithCanvas(
double canvasFill,
int width,
int height,
Rectangle woi,
float [] selection ){
float []canvas=new float[width*height];
for (int i=0;i<canvas.length;i++)canvas[i]= (float) canvasFill;
return combineWithCanvas(canvas, width, woi, selection );
}
public float [] combineWithCanvas(
float [] canvas,
int width,
Rectangle woi,
float [] selection ){
// debug
if (selection==null) System.out.println("combineWithCanvas(): selection==null");
if (woi==null) System.out.println("combineWithCanvas(): woi==null");
if (selection.length!=(woi.width*woi.height)) throw new IllegalArgumentException ("selection.length="+selection.length+", woi.width="+woi.width+", woi.height="+woi.height);
int i0=0;
int i1=width*woi.y+woi.x;
for (int y=0;y<woi.height;y++){
for (int x=0;x<woi.width;x++){
if ((i1>canvas.length) ||(i0>=selection.length)){
System.out.println("canvas.length="+canvas.length+" width="+width+" selection.length="+selection.length+" y="+y+" x="+x+" i0="+i0+" i1="+i1+
" woi.x="+woi.x+" woi.y="+woi.y+" woi.width="+woi.width+" woi.height="+woi.height);
}
canvas[i1++]=selection[i0++]; // OOB 18720
}
for (int i=0;i<pixels.length;i++ ) {
// /(simulParameters!=null)
// if (maskOnly) {
if (simulParameters==null) {
if (pixelsDenom[i]==0.0F) pixels[i]=-1;
} else {
if (pixelsDenom[i]!=0.0F){
pixels[i]/= pixelsDenom[i];
pixels[i]=(float) ((pixels[i]+1.0)/2); // convert from -1..+1 to 0..1.0
i1+=(width-woi.width);
}
return canvas;
}
public double [] combineWithCanvas(
double canvasFill,
int width,
int height,
Rectangle woi,
double [] selection ){
double []canvas=new double[width*height];
for (int i=0;i<canvas.length;i++)canvas[i]= canvasFill;
return combineWithCanvas(canvas, width, woi, selection );
}
public double [] combineWithCanvas(
double [] canvas,
int width,
Rectangle woi,
double [] selection ){
if (selection.length!=(woi.width*woi.height)) throw new IllegalArgumentException ("selection.length="+selection.length+", woi.width="+woi.width+", woi.height="+woi.height);
int i0=0;
int i1=width*woi.y+woi.x;
for (int y=0;y<woi.height;y++){
for (int x=0;x<woi.width;x++) canvas[i1++]=selection[i0++];
i1+=(width-woi.width);
}
return canvas;
}
//===================== Moved from Aberration_Calibration
public float[][] simulateGridAll (
int width, // extend to full image, width, height - original (not scaled) image size
int height,
MatchSimulatedPattern matchSimulatedPattern,
// double [][][][] patternGrid, // should be aligned to gridFrac
int gridFrac, // number of grid steps per pattern full period
SimulParameters simulParameters,
int threadsMax,
boolean updateStatus,
int globalDebugLevel,
int debug_level){// debug level used inside loops
// SimulationPattern simulationPattern=new SimulationPattern(simulParameters);
float [][] simArray0=simulateGridAll (
matchSimulatedPattern,
// patternGrid, // should be aligned to gridFrac
gridFrac, // number of grid steps per pattern full period
simulParameters,
// simulationPattern,
threadsMax,
updateStatus,
globalDebugLevel,
debug_level);
Rectangle woi=matchSimulatedPattern.getWOI();
if ((woi.x==0) && (woi.y==0) && (woi.width==width) && (woi.height==height)) return simArray0;
int k=simulParameters.subdiv/2;
Rectangle scaledWoi=new Rectangle(k*woi.x, k*woi.y, k*woi.width, k*woi.height);
float [][] simArray=new float [2][];
simArray[0]=(new SimulationPattern(simulParameters)).combineWithCanvas(0.0, k*width, k*height, scaledWoi,simArray0[0]);
simArray[1]=(new SimulationPattern(simulParameters)).combineWithCanvas(0.0, k*width, k*height, scaledWoi,simArray0[1]);
if (globalDebugLevel>1) SDFA_INSTANCE.showArrays(simArray,width*k,height*k,true, "full-simulation");
return simArray;
}
public float[][] simulateGridAll (
MatchSimulatedPattern matchSimulatedPattern,
// double [][][][] patternGrid, // should be aligned to gridFrac
int gridFrac, // number of grid steps per pattern full period
SimulationPattern.SimulParameters simulParameters,
// SimulationPattern simulationPattern, // or null
int threadsMax,
boolean updateStatus,
int globalDebugLevel,
int debug_level){// debug level used inside loops
long startTime=System.nanoTime();
double [][] xy0={{simulParameters.offsetX,simulParameters.offsetY},{simulParameters.offsetX-0.5,simulParameters.offsetY-0.5}} ;
// if (simulationPattern==null) simulationPattern=new SimulationPattern(simulParameters);
float[][] simArray=new float[2][];
simArray[0]= simulateGrid (
matchSimulatedPattern.getDArray(),
2, // gridFrac, // number of grid steps per pattern full period
simulParameters,
matchSimulatedPattern.getWOI(),
simulParameters.subdiv/2,
xy0[0], // add to patterGrid xy
threadsMax,
updateStatus,
debug_level); // debug level
simArray[1]= simulateGrid (
matchSimulatedPattern.getDArray(),
2, // gridFrac, // number of grid steps per pattern full period
simulParameters,
matchSimulatedPattern.getWOI(),
simulParameters.subdiv/2,
xy0[1], // add to patterGrid xy
threadsMax,
updateStatus,
debug_level); // debug level
if (globalDebugLevel>2) SDFA_INSTANCE.showArrays(simArray,matchSimulatedPattern.getWOI().width*simulParameters.subdiv/2,matchSimulatedPattern.getWOI().height*simulParameters.subdiv/2,true, "a-simulation");
if (globalDebugLevel>1) System.out.println("Grid simulation is finished at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
return simArray;
}
//========================
public float [] simulateGrid (
final double [][][][] patternGrid, // should be aligned to gridFrac
final int gridFrac, // number of grid steps per pattern full period: black+white
final SimulParameters simulParameters, // Try to use null here for maskOnly
final Rectangle woi,
final int subdiv, // subdivide output array from woi (normally 2)
double[] shift_xy, // add to patterGrid xy, null OK
// final boolean maskOnly, // just mark defined cells
final int threadsMax,
final boolean updateStatus,
final int debug_level){// debug level used inside loops
double []xy_zero={0.0,0.0};
if (patternGrid==null) return null;
final double [] xy0=(shift_xy==null)?xy_zero:shift_xy;
if ((simulParameters!=null) && (this.bPattern==null)){
System.out.println("simulateGrid(), running patternGenerator(simulParameters )");
patternGenerator(simulParameters ); // generate bPattern if it was not done yet
}
final Rectangle woiOut=new Rectangle(subdiv*woi.x,subdiv*woi.y,subdiv*woi.width,subdiv*woi.height);
final float [] pixels=new float[woiOut.width*woiOut.height];
final float [] pixelsDenom=new float[woiOut.width*woiOut.height];
for (int i=0;i<pixels.length;i++ ){
pixels[i]= 0.0F;
pixelsDenom[i]= 0.0F;
}
final Thread[] threads = newThreadArray(threadsMax);
final AtomicInteger cellNum = new AtomicInteger(0);
final int [] series = new int[1];
final int uvhwidth=(patternGrid[0].length+1)/2;
final int uvwidth= patternGrid[0].length;
final int uvhheight=(patternGrid.length+1)/2;
final int numInSeries=(uvhwidth-1)*(uvhheight-1);
final AtomicInteger debugCellNum = new AtomicInteger(0);
final AtomicInteger finishedAtomic = new AtomicInteger(1);
final int cellsToProcess=numInSeries*4;
final int debugCellNum0=0;
IJ.showStatus("Generating simulated pattern...");
for (series[0]=0;series[0]<4;series[0]++) { // split processing in 4 series (odd/even row/column to avoid races between threads
if (debug_level>2)System.out.println("**** series[0]="+series[0]);
cellNum.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
// String dbgStr="";
int [][][] iUV=new int [2][2][2];
double [][][] dUV=new double [2][2][2];
double [][][] xy=new double [2][2][2];
boolean invPattern;
double [] pixDXY={1.0,1.0};
for (int ncell=cellNum.getAndIncrement(); ncell<numInSeries;ncell=cellNum.getAndIncrement()){
iUV[0][0][0]=2*(ncell%(uvhwidth-1))+ (series[0] & 1);
iUV[0][0][1]=2*(ncell/(uvhwidth-1))+ ((series[0]>>1) & 1);
if ((updateStatus) && (debugLevel>1)) IJ.showStatus("Generating simulated pattern, series "+series[0]+" (of 4), row "+(iUV[0][0][1]/2+1)+"(of "+(uvhheight-1)+")");
if (debugLevel>2) System.out.println("Generating pattern, series "+series[0]+" (of 4), row "+(iUV[0][0][1]/2+1)+"(of "+(uvhheight-1)+")");
iUV[0][1][0]=iUV[0][0][0]+1;
iUV[0][1][1]=iUV[0][0][1];
iUV[1][0][0]=iUV[0][0][0];
iUV[1][0][1]=iUV[0][0][1]+1;
iUV[1][1][0]=iUV[0][0][0]+1;
iUV[1][1][1]=iUV[0][0][1]+1;
if ((isCellValid(patternGrid,iUV[0][0])) &&
(isCellValid(patternGrid,iUV[0][1])) &&
(isCellValid(patternGrid,iUV[1][0])) &&
(isCellValid(patternGrid,iUV[1][1]))){
// All 4 corners are valid
invPattern=((iUV[0][0][0]%gridFrac)>=(gridFrac/2))^((iUV[0][0][1]%gridFrac)>=(gridFrac/2));
if (debug_level>2)System.out.println("iUV[0][0][1]="+iUV[0][0][1]+" iUV[0][0][0]="+iUV[0][0][0]+" invert="+invPattern);
for (int i=0;i<2;i++) for (int j=0;j<2;j++) for (int k=0;k<2;k++) {
xy[i][j][k]=subdiv*patternGrid[iUV[i][j][1]][iUV[i][j][0]][0][k]+xy0[k];
}
for (int k=0;k<2;k++) {
dUV[0][0][k]=((double) (iUV[0][0][k]%(gridFrac/2)))/(gridFrac/2);
}
dUV[0][1][0]=dUV[0][0][0]+1.0/(gridFrac/2);
dUV[0][1][1]=dUV[0][0][1];
dUV[1][0][0]=dUV[0][0][0];
dUV[1][0][1]=dUV[0][0][1]+1.0/(gridFrac/2);
dUV[1][1][0]=dUV[0][1][0];
dUV[1][1][1]=dUV[1][0][1];
double [] minXY={xy[0][0][0],xy[0][0][1]};
double [] maxXY={xy[0][0][0],xy[0][0][1]};
for (int i=0;i<2;i++) for (int j=0;j<2;j++) for (int k=0;k<2;k++) {
if (minXY[k]>xy[i][j][k]) minXY[k]=xy[i][j][k];
if (maxXY[k]<xy[i][j][k]) maxXY[k]=xy[i][j][k];
}
Rectangle rcell=new Rectangle((int)minXY[0], // contains all pixels
(int)minXY[1],
((int) Math.ceil(maxXY[0]))-((int)minXY[0]) ,
((int) Math.ceil(maxXY[1]))-((int)minXY[1]));
double [] cornersDUV={1.0/(gridFrac/2),1.0/(gridFrac/2)};
boolean debugNow=debugCellNum.getAndIncrement()==debugCellNum0;
if (woiOut.intersects (rcell)) // do not bother if no
for (int iy=rcell.y;iy<(rcell.y+rcell.height);iy++) for (int ix=rcell.x;ix<(rcell.x+rcell.width);ix++)
if (woiOut.contains (ix,iy))
{
double [] pixXY={ix,iy};
double [] pixData=recursiveFillPixels ( // invert pattern in the caller, return signed value (-1..1 - pattern is 0..1)
simulParameters,
pixXY, // top-left corner
pixDXY, // increments to other corners
xy, // xy pairs for the 4 corners of the square in UV (pattern) coordinates (u0v0,u1v0,u0v1,u1v1)
dUV[0][0], // UV value for the top-left corner (matching cornersXY[0][0])
cornersDUV, // distances to the opposite corner in UV
// maskOnly, // just mark defined cells
debugNow?debug_level: debug_level-2
);
// int index=woiOut.width*iy+ix;
int index=woiOut.width*(iy-woiOut.y)+(ix-woiOut.x);
// pixels[index]+=((invPattern || maskOnly)?1.0:-1.0)*pixData[0];
if (index>pixels.length){
// final float [] pixels=new float[woiOut.width*woiOut.height];
System.out.println("simulateGrid(), pixels.length="+pixels.length+
" index="+index+
" iy="+iy+" ix="+ix+
" ncell="+ncell+
" subdiv="+subdiv+
" woiOut.x="+woiOut.x+
" woiOut.y="+woiOut.y+
" woiOut.width="+woiOut.width+
" woiOut.height="+woiOut.height+
" woi.x="+woi.x+
" woi.y="+woi.y+
" woi.width="+woi.width+
" woi.height="+woi.height+
" rcell.x="+rcell.x+
" rcell.y="+rcell.y+
" rcell.width="+rcell.width+
" rcell.height="+rcell.height);
}
// if (maskOnly) pixels[index]=patternGrid.length*iUV[0][0][1]+iUV[0][0][0]; // out of bounds
// OLD NASTY BUG!
// if (maskOnly) pixels[index]=uvwidth*iUV[0][0][1]+iUV[0][0][0]; // Should be width, not height!
if (simulParameters==null) pixels[index]=uvwidth*iUV[0][0][1]+iUV[0][0][0]; // Should be width, not height!
else pixels[index]+=(invPattern?1.0:-1.0)*pixData[0];
pixelsDenom[index]+=pixData[1];
}
}
final int numFinished=finishedAtomic.getAndIncrement();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
IJ.showProgress(numFinished,cellsToProcess);
}
});
}
}
};
}
startAndJoin(threads);
}
for (int i=0;i<pixels.length;i++ ) {
// /(simulParameters!=null)
// if (maskOnly) {
if (simulParameters==null) {
if (pixelsDenom[i]==0.0F) pixels[i]=-1;
} else {
if (pixelsDenom[i]!=0.0F){
pixels[i]/= pixelsDenom[i];
pixels[i]=(float) ((pixels[i]+1.0)/2); // convert from -1..+1 to 0..1.0
}
}
return pixels;
}
/* Create a Thread[] array as large as the number of processors available.
* From Stephan Preibisch's Multithreading.java class. See:
* http://repo.or.cz/w/trakem2.git?a=blob;f=mpi/fruitfly/general/MultiThreading.java;hb=HEAD
*/
private Thread[] newThreadArray(int maxCPUs) {
int n_cpus = Runtime.getRuntime().availableProcessors();
if (n_cpus>maxCPUs)n_cpus=maxCPUs;
return new Thread[n_cpus];
}
return pixels;
}
/* Create a Thread[] array as large as the number of processors available.
* From Stephan Preibisch's Multithreading.java class. See:
* http://repo.or.cz/w/trakem2.git?a=blob;f=mpi/fruitfly/general/MultiThreading.java;hb=HEAD
*/
private Thread[] newThreadArray(int maxCPUs) {
int n_cpus = Runtime.getRuntime().availableProcessors();
if (n_cpus>maxCPUs)n_cpus=maxCPUs;
return new Thread[n_cpus];
}
/* Start all given threads and wait on each of them until all are done.
* From Stephan Preibisch's Multithreading.java class. See:
* http://repo.or.cz/w/trakem2.git?a=blob;f=mpi/fruitfly/general/MultiThreading.java;hb=HEAD
*/
private static void startAndJoin(Thread[] threads)
* From Stephan Preibisch's Multithreading.java class. See:
* http://repo.or.cz/w/trakem2.git?a=blob;f=mpi/fruitfly/general/MultiThreading.java;hb=HEAD
*/
private static void startAndJoin(Thread[] threads)
{
for (int ithread = 0; ithread < threads.length; ++ithread)
{
for (int ithread = 0; ithread < threads.length; ++ithread)
{
threads[ithread].setPriority(Thread.NORM_PRIORITY);
threads[ithread].start();
}
try
{
for (int ithread = 0; ithread < threads.length; ++ithread)
threads[ithread].join();
} catch (InterruptedException ie)
{
throw new RuntimeException(ie);
}
threads[ithread].setPriority(Thread.NORM_PRIORITY);
threads[ithread].start();
}
/* ======================================================================== */
/* make it faster when outSubdiv =2*n (usually so) */
/* TODO: cleanup shifts - they seem now to work correctly */
public double [][] extractSimulPatterns (
SimulParameters simulParameters,
int outSubdiv, // subdivide output pixels
int size, // number of Bayer cells in width of the square selection (half number of pixels)
double x0, // selection center, X (in pixels)
double y0) {
return extractSimulPatterns (
this.barray,
simulParameters,
outSubdiv, // subdivide output pixels
size, // number of Bayer cells in width of the square selection (half number of pixels)
x0, // selection center, X (in pixels)
y0);
try
{
for (int ithread = 0; ithread < threads.length; ++ithread)
threads[ithread].join();
} catch (InterruptedException ie)
{
throw new RuntimeException(ie);
}
public double [][] extractSimulPatterns (
double [] localbArray,
SimulParameters simulParameters,
int outSubdiv, // subdivide output pixels
int size, // number of Bayer cells in width of the square selection (half number of pixels)
double x0, // selection center, X (in pixels)
double y0) {
}
/* ======================================================================== */
/* make it faster when outSubdiv =2*n (usually so) */
/* TODO: cleanup shifts - they seem now to work correctly */
public double [][] extractSimulPatterns (
SimulParameters simulParameters,
int outSubdiv, // subdivide output pixels
int size, // number of Bayer cells in width of the square selection (half number of pixels)
double x0, // selection center, X (in pixels)
double y0) {
return extractSimulPatterns (
this.barray,
simulParameters,
outSubdiv, // subdivide output pixels
size, // number of Bayer cells in width of the square selection (half number of pixels)
x0, // selection center, X (in pixels)
y0);
}
public double [][] extractSimulPatterns (
double [] localbArray,
SimulParameters simulParameters,
int outSubdiv, // subdivide output pixels
int size, // number of Bayer cells in width of the square selection (half number of pixels)
double x0, // selection center, X (in pixels)
double y0) {
int sampleWidth=(int) (Math.sqrt(simulParameters.fill)*simulParameters.subdiv);
int sampleN=sampleWidth*sampleWidth;
if (sampleWidth<1) sampleWidth=1;
......@@ -949,7 +959,7 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy)
}
} else { // just reuse available greens
if (this.debugLevel>2)System.out.println("Generating combined greens pattern from individual greens");
/* now combine greens - same as in splitBayer() */
/* now combine greens - same as in splitBayer() */
int base, base_b;
base_b=0;
......@@ -984,6 +994,69 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy)
return simul_pixels;
}
public double [] extractSimulMono (
SimulParameters simulParameters,
int outSubdiv, // subdivide output pixels
int size, // number of Bayer cells in width of the square selection (half number of pixels)
double x0, // selection center, X (in pixels)
double y0) {
return extractSimulMono (
this.barray,
simulParameters,
outSubdiv, // subdivide output pixels
size, // number of Bayer cells in width of the square selection (half number of pixels)
x0, // selection center, X (in pixels)
y0);
}
public double [] extractSimulMono ( // TODO: can use twice smaller barray
double [] localbArray,
SimulParameters simulParameters,
int outSubdiv, // subdivide output pixels - now 4
int size, // number of Bayer cells in width of the square selection (half number of pixels)
double x0, // selection center, X (in pixels)
double y0) {
int sampleWidth=(int) (Math.sqrt(simulParameters.fill)*simulParameters.subdiv);
int sampleN=sampleWidth*sampleWidth;
if (sampleWidth<1) sampleWidth=1;
else if (sampleWidth>simulParameters.subdiv)sampleWidth=simulParameters.subdiv;
double sampleAverage=0.5*sampleN;
int fullSize=(int) Math.sqrt(localbArray.length);
double [] simul_pixels=new double [size*size];
int ix,iy, iy0,ix0,px,py;
double s;
double span=((double) size)/outSubdiv;
int sampLow=-sampleWidth/2;
int sampHigh=sampLow+sampleWidth;
for (iy=0;iy<size;iy++) {
iy0=(fullSize/2) + (int) (( -span/2 + y0 + 0.5 + 1.0 * iy / outSubdiv)*simulParameters.subdiv);
for (ix=0;ix<size;ix++) {
ix0=(fullSize/2) + (int) ((-span/2 + x0 + 0.5 + 1.0 * ix / outSubdiv)*simulParameters.subdiv);
s=0.0;
for (py=iy0+sampLow;py<iy0+sampHigh;py++) for (px=ix0+sampLow;px<ix0+sampHigh;px++) {
try {
s+=localbArray[py*fullSize+px];
} catch (Exception e){
System.out.println("Bug in extractSimulMono(): px="+px+" py="+py+" fullSize="+fullSize+" size="+size+" x0="+x0+" y0="+y0);
e.printStackTrace();
return null;
}
}
simul_pixels[iy*size+ix]= (s-sampleAverage)/sampleAverage;
}
}
if (this.debugLevel>2) {
System.out.println("extractSimulMono, x0="+x0+" y0="+y0+" fullSize="+fullSize+" size="+size+" subdiv="+simulParameters.subdiv+" outSubdiv="+outSubdiv);
System.out.println(" sampLow="+sampLow+" sampHigh="+sampHigh+" span="+span+" size="+size);
s=0.0;
for (int i=0;i<simul_pixels.length;i++) s+=simul_pixels[i];
System.out.println("sum of pixels="+s);
}
if (this.debugLevel>2) SDFA_INSTANCE.showArrays(simul_pixels,size,size, "SIMUL");
return simul_pixels;
}
private double [] matrix2x2_mul(double [][] a, double [] b ){
double [] rslt={a[0][0]*b[0]+a[0][1]*b[1],
a[1][0]*b[0]+a[1][1]*b[1]};
......@@ -1019,8 +1092,8 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy)
if (colorComp==4) { // checkerboard greens
r.y+=r.width/2; // now it is the "top left" corner of the diagonal greens
for (index=0;index<result.length;index++){
// int iy=r.y+(index / r.width);
// int ix=r.x+(index % r.width);
// int iy=r.y+(index / r.width);
// int ix=r.x+(index % r.width);
int iyi=index / r.width;
int ixi=index % r.width;
int iy=r.y+(iyi+ixi)/2 -ixi;
......@@ -1048,11 +1121,11 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy)
else if (ix>=full_width) iy=full_width-1;
result[index]=spixels[0][iy*full_width+ix];
}
}
return result;
}
return result;
}
//=====================
//=====================
public static class SimulParameters {
public int patternSize;
public int pattern_type;
......@@ -1072,7 +1145,7 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy)
public double bitmapNonuniforityThreshold; // subdivide pixels until difference between the corners is below this value
public double offsetX; // debug - add to X during simulation, in pixels
public double offsetY; // debug - add to Y during simulation, in pixels
public SimulParameters(
int patternSize,
......@@ -1093,7 +1166,7 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy)
double bitmapNonuniforityThreshold, // subdivide pixels until difference between the corners is below this value
double offsetX, // debug - add to X during simulation, in pixels
double offsetY // debug - add to Y during simulation, in pixels
) {
) {
this.patternSize= patternSize;
this.pattern_type= pattern_type;
......@@ -1115,6 +1188,7 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy)
this.offsetY= offsetY;
}
@Override
public SimulParameters clone() {
return new SimulParameters(
this.patternSize,
......@@ -1135,7 +1209,7 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy)
this.bitmapNonuniforityThreshold,
this.offsetX,
this.offsetY
);
);
}
public void setProperties(String prefix,Properties properties){
......@@ -1178,6 +1252,6 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy)
if (properties.getProperty(prefix+"offsetX")!=null) this.offsetX=Double.parseDouble(properties.getProperty(prefix+"offsetX"));
if (properties.getProperty(prefix+"offsetY")!=null) this.offsetY=Double.parseDouble(properties.getProperty(prefix+"offsetY"));
}
}
}
......@@ -32,6 +32,7 @@ import java.util.Properties;
import com.elphel.imagej.common.GenericJTabbedDialog;
import ij.ImagePlus;
import ij.Prefs;
public class LwirReaderParameters {
......@@ -54,6 +55,7 @@ public class LwirReaderParameters {
protected double vnir_gain_rg = 0.7705; // 1.116; halogen/fluorescent
protected double vnir_gain_bg = 2.401; // 1.476;
protected boolean [] selected_channels = {true, true, true, true, true, true, true, true};
protected int max_lwir_width = 1024; //
/*
protected double [] vnir_exp_corr = {1.0, 1.0, 1.0, 1.0};
......@@ -79,9 +81,18 @@ public class LwirReaderParameters {
protected boolean show_images = false;
// --- interface methods
public boolean is_LWIR(int width) {
return width <= max_lwir_width;
}
public boolean is_LWIR(ImagePlus imp){
return is_LWIR(imp.getWidth());
}
public int getDebugLevel() {
return this.debug_level;
}
public void setDebugLevel(int level) {
this.debug_level = level;
}
......
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