...
 
Commits (16)
......@@ -208,13 +208,22 @@ public class Aberration_Calibration extends PlugInFrame implements ActionListene
public static EyesisAberrations.OTFFilterParameters OTF_FILTER = new EyesisAberrations.OTFFilterParameters(
0.008, // deconvInvert - when FFT component is less than this fraction of the maximal value, replace 1/z with Z
2.0, // zerofreqSize - used for filtering oversampling artifacts - size of zero freq maximum (if absent on simulated model PS)
2.5, // smoothPS - smooth model PS for rejecting aliases (0 - no smooth, >0 additional Gauss before FFT smaller than normal by this ratio)
0.002, // deconvInvert - when FFT component is less than this fraction of the maximal value, replace 1/z with Z
1.0, // zerofreqSize - used for filtering oversampling artifacts - size of zero freq maximum (if absent on simulated model PS)
1.25, // smoothPS - smooth model PS for rejecting aliases (0 - no smooth, >0 additional Gauss before FFT smaller than normal by this ratio)
0.02, // thresholdHigh -used for filtering oversampling artifacts - relative to max PS value to make filter completely rejecting
0.002 // thresholdLow - used for filtering oversampling artifacts - relative to max PS to make filter completely transmissive
);
public static EyesisAberrations.OTFFilterParameters OTF_FILTER_LWIR = new EyesisAberrations.OTFFilterParameters(
0.01, // deconvInvert - when FFT component is less than this fraction of the maximal value, replace 1/z with Z
1.0, // zerofreqSize - used for filtering oversampling artifacts - size of zero freq maximum (if absent on simulated model PS)
1.25, // smoothPS - smooth model PS for rejecting aliases (0 - no smooth, >0 additional Gauss before FFT smaller than normal by this ratio)
0.2, // thresholdHigh -used for filtering oversampling artifacts - relative to max PS value to make filter completely rejecting
0.05 // thresholdLow - used for filtering oversampling artifacts - relative to max PS to make filter completely transmissive
);
public static MatchSimulatedPattern.PatternDetectParameters PATTERN_DETECT = new MatchSimulatedPattern.PatternDetectParameters (
0.4, // GAUSS_WIDTH= 0.4; //0 - use Hamming window - initWindowFunction()
0.2, // corrGamma - pattern detection: gamma applied to PS
......@@ -375,6 +384,8 @@ public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSi
// additionally multiply by Hamming
256, // FFTSize (was 128)
32, // FFTSize_lwir
32, // FFTOverlap (was 32)
4, // FFTOverlap_lwir
0.5, //fftGaussWidth
0.0, //phaseCorrelationFraction
1.5, // 2.5, //6.0, // 2.0, // 0.0, // correlationHighPassSigma, - pixels in frequency domain
......@@ -1183,7 +1194,7 @@ if (MORE_BUTTONS) {
return;
/* ======================================================================== */
} else if (label.equals("Conf. OTF Filter")) {
showOTFFilterParametersDialog(OTF_FILTER);
showOTFFilterParametersDialog(OTF_FILTER, OTF_FILTER_LWIR); // second may be null
return;
/* ======================================================================== */
} else if (label.equals("Conf. Interpolation")) {
......@@ -9161,11 +9172,13 @@ if (MORE_BUTTONS) {
EYESIS_ABERRATIONS.createPartialKernels(
this.SYNC_COMMAND.stopRequested,
MAP_FFT_SIZE, // scanImageForPatterns:FFT size //int mapFFTsize, // scanImageForPatterns:FFT size
FFT_OVERLAP, ////int fft_overlap,
FFT_SIZE, //int fft_size,
LWIR_PARAMETERS, // LwirReaderParameters lwirReaderParameters,
// MAP_FFT_SIZE, // scanImageForPatterns:FFT size //int mapFFTsize, // scanImageForPatterns:FFT size
// FFT_OVERLAP, ////int fft_overlap,
// FFT_SIZE, //int fft_size,
PSF_SUBPIXEL, // //int PSF_subpixel,
OTF_FILTER, // //OTFFilterParameters otfFilterParameters,
OTF_FILTER, // OTFFilterParameters otfFilterParameters,
OTF_FILTER_LWIR, //OTFFilterParameters otfFilterParameters_lwir,
PSF_PARS, //PSFParameters psfParameters,
INVERSE.dSize, //int PSFKernelSize, // size of square used in the new map (should be multiple of map step)
......@@ -15513,6 +15526,7 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) {
boolean select_INVERSE=!select;
boolean select_PSF_PARS=!select;
boolean select_OTF_FILTER=!select;
boolean select_OTF_FILTER_LWIR=!select;
boolean select_PATTERN_DETECT=!select;
boolean select_COMPONENTS=!select;
boolean select_SHOW_RESULTS=!select;
......@@ -15554,6 +15568,7 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) {
gd.addCheckbox("INVERSE",select_INVERSE);
gd.addCheckbox("PSF_PARS",select_PSF_PARS);
gd.addCheckbox("OTF_FILTER",select_OTF_FILTER);
gd.addCheckbox("OTF_FILTER_LWIR",select_OTF_FILTER_LWIR);
gd.addCheckbox("PATTERN_DETECT",select_PATTERN_DETECT);
gd.addCheckbox("COMPONENTS",select_COMPONENTS);
gd.addCheckbox("SHOW_RESULTS",select_SHOW_RESULTS);
......@@ -15596,6 +15611,7 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) {
select_INVERSE=gd.getNextBoolean();
select_PSF_PARS=gd.getNextBoolean();
select_OTF_FILTER=gd.getNextBoolean();
select_OTF_FILTER_LWIR=gd.getNextBoolean();
select_PATTERN_DETECT=gd.getNextBoolean();
select_COMPONENTS=gd.getNextBoolean();
select_SHOW_RESULTS=gd.getNextBoolean();
......@@ -15635,7 +15651,8 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) {
if (select_INTERPOLATE) INTERPOLATE.setProperties( "INTERPOLATE.", properties);
if (select_INVERSE) INVERSE.setProperties( "INVERSE.", properties);
if (select_PSF_PARS) PSF_PARS.setProperties( "PSF_PARS.", properties);
if (select_OTF_FILTER) OTF_FILTER.setProperties( "OTF_FILTER.", properties);
if (select_OTF_FILTER) OTF_FILTER.setProperties( "OTF_FILTER.", properties);
if (select_OTF_FILTER) OTF_FILTER_LWIR.setProperties( "OTF_FILTER_LWIR.", properties);
if (select_PATTERN_DETECT) PATTERN_DETECT.setProperties( "PATTERN_DETECT.", properties);
if (select_COMPONENTS) COMPONENTS.setProperties( "COMPONENTS.", properties);
if (select_SHOW_RESULTS) SHOW_RESULTS.setProperties( "SHOW_RESULTS.", properties);
......@@ -15679,6 +15696,7 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) {
INVERSE.getProperties("INVERSE.", properties);
PSF_PARS.getProperties("PSF_PARS.", properties);
OTF_FILTER.getProperties("OTF_FILTER.", properties);
OTF_FILTER_LWIR.getProperties("OTF_FILTER_LWIR.", properties);
PATTERN_DETECT.getProperties("PATTERN_DETECT.", properties);
COMPONENTS.getProperties("COMPONENTS.", properties);
SHOW_RESULTS.getProperties("SHOW_RESULTS.", properties);
......@@ -20388,13 +20406,29 @@ use the result to create a rejectiobn mask - if the energy was high, (multiplica
/* ======================================================================== */
/* ======================================================================== */
/**TODO: add variable gaussian filter to direct psf */
public boolean showOTFFilterParametersDialog(EyesisAberrations.OTFFilterParameters otfFilterParameters) {
public boolean showOTFFilterParametersDialog(
EyesisAberrations.OTFFilterParameters otfFilterParameters,
EyesisAberrations.OTFFilterParameters otfFilterParameters_lwir) {
GenericDialog gd = new GenericDialog("OTF Filter parameters");
if (otfFilterParameters_lwir!=null) {
gd.addMessage("EO (high-res color) sensors:");
}
gd.addNumericField("Invert deconvolution if less than", otfFilterParameters.deconvInvert, 3);
gd.addNumericField("OTF zero frequency size on power spectrum ", otfFilterParameters.zerofreqSize, 3); //2.0;
gd.addNumericField("OTF smouth PS to generate alias rejection mask (0 - none)", otfFilterParameters.smoothPS, 3); //2.5 - smooth model PS for rejecting aliases (0 - no smouth, >0 additional Gauss )
gd.addNumericField("OTF relative high value of PS for rejection mask ", otfFilterParameters.thresholdHigh, 3); //0.1
gd.addNumericField("OTF relative low value of PS for rejection mask ", otfFilterParameters.thresholdLow, 3); //0.01; // when FFT component is less than this fraction of the maximal value, replace 1/z with Z
if (otfFilterParameters_lwir!=null) {
gd.addMessage("LWIR (low-res mono) sensors:");
gd.addNumericField("Invert deconvolution if less than", otfFilterParameters_lwir.deconvInvert, 3);
gd.addNumericField("OTF zero frequency size on power spectrum ", otfFilterParameters_lwir.zerofreqSize, 3); //2.0;
gd.addNumericField("OTF smouth PS to generate alias rejection mask (0 - none)", otfFilterParameters_lwir.smoothPS, 3); //2.5 - smooth model PS for rejecting aliases (0 - no smouth, >0 additional Gauss )
gd.addNumericField("OTF relative high value of PS for rejection mask ", otfFilterParameters_lwir.thresholdHigh, 3); //0.1
gd.addNumericField("OTF relative low value of PS for rejection mask ", otfFilterParameters_lwir.thresholdLow, 3); //0.01; // when FFT component is less than this fraction of the maximal value, replace 1/z with Z
}
gd.showDialog();
if (gd.wasCanceled()) return false;
otfFilterParameters.deconvInvert= gd.getNextNumber();
......@@ -20402,6 +20436,13 @@ use the result to create a rejectiobn mask - if the energy was high, (multiplica
otfFilterParameters.smoothPS= gd.getNextNumber();
otfFilterParameters.thresholdHigh= gd.getNextNumber();
otfFilterParameters.thresholdLow= gd.getNextNumber();
if (otfFilterParameters_lwir!=null) {
otfFilterParameters_lwir.deconvInvert= gd.getNextNumber();
otfFilterParameters_lwir.zerofreqSize= gd.getNextNumber();
otfFilterParameters_lwir.smoothPS= gd.getNextNumber();
otfFilterParameters_lwir.thresholdHigh= gd.getNextNumber();
otfFilterParameters_lwir.thresholdLow= gd.getNextNumber();
}
return true;
}
/* ======================================================================== */
......@@ -20696,8 +20737,10 @@ 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); // 256
gd.addNumericField("FFTSize (Initial pattern and aberraton kernels):", distortionParameters.FFTSize, 0); // 256
gd.addNumericField("FFTSize for LWIR sensors):", distortionParameters.FFTSize_lwir, 0); // 32
gd.addNumericField("FFTOverlap (aberration kernels):", distortionParameters.FFTOverlap, 0); // 32
gd.addNumericField("FFTOverlap for LWIR sensors):", distortionParameters.FFTOverlap_lwir, 0); // 4
gd.addNumericField("FFT Gaussian width (relative):", distortionParameters.fftGaussWidth, 3);
gd.addNumericField("Correlation size:", distortionParameters.correlationSize, 0); // 64
gd.addNumericField("Correlation size LWIR:", distortionParameters.correlationSizeLwir, 0); // 16
......@@ -20786,6 +20829,8 @@ use the result to create a rejectiobn mask - if the energy was high, (multiplica
if (gd.wasCanceled()) return false;
distortionParameters.FFTSize = makePowerOfTwo((int) gd.getNextNumber());
distortionParameters.FFTSize_lwir = makePowerOfTwo((int) gd.getNextNumber());
distortionParameters.FFTOverlap = makePowerOfTwo((int) gd.getNextNumber());
distortionParameters.FFTOverlap_lwir = makePowerOfTwo((int) gd.getNextNumber());
distortionParameters.fftGaussWidth= gd.getNextNumber();
distortionParameters.correlationSize = makePowerOfTwo((int) gd.getNextNumber());
distortionParameters.correlationSizeLwir = makePowerOfTwo((int) gd.getNextNumber());
......@@ -4276,7 +4276,7 @@ List calibration
}
public boolean removeOutLierSets(int numOutLiers){
boolean removeEmptySets=false;
boolean removeEmptySets=true; // false;
if (numOutLiers<0) {
GenericDialog gd = new GenericDialog("Select sets to process");
gd.addNumericField("Series number (<0 - all images)", -1, 0);
......
......@@ -14,6 +14,7 @@ import com.elphel.imagej.common.DoubleGaussianBlur;
import com.elphel.imagej.common.ShowDoubleFloatArrays;
import com.elphel.imagej.common.WindowTools;
import com.elphel.imagej.jp4.JP46_Reader_camera;
import com.elphel.imagej.lwir.LwirReaderParameters;
import ij.IJ;
import ij.ImagePlus;
......@@ -1056,17 +1057,15 @@ public class EyesisAberrations {
}
return fileList;
}
/*
int numChannels=this.fittingStrategy.distortionCalibrationData.getNumChannels(); // number of used channels
*/
public boolean createPartialKernels(
public boolean createPartialKernels(
AtomicInteger stopRequested, // 1 - stop now, 2 - when convenient
int mapFFTsize, // scanImageForPatterns:FFT size
int fft_overlap,
int fft_size,
LwirReaderParameters lwirReaderParameters, // null is OK
// int fft_overlap,
// int fft_size,
int PSF_subpixel,
OTFFilterParameters otfFilterParameters,
OTFFilterParameters otfFilterParameters_lwir,
PSFParameters psfParameters,
int PSFKernelSize, // size of square used in the new map (should be multiple of map step)
double gaussWidth, // ** NEW
......@@ -1245,6 +1244,10 @@ public class EyesisAberrations {
if (debugLevel>0) System.out.println("Processing file #"+(imgNum+1)+ " ( of "+files.length+") :"+files[imgNum][0]);
ImagePlus imp=new ImagePlus(files[imgNum][0]); // read source file
JP4_INSTANCE.decodeProperiesFromInfo(imp);
boolean is_lwir = lwirReaderParameters.is_LWIR(imp);
int fft_size = is_lwir ? distortionParameters.FFTSize_lwir : distortionParameters.FFTSize;
int fft_overlap = is_lwir ? distortionParameters.FFTOverlap_lwir : distortionParameters.FFTOverlap;
imp.setProperty("MONOCHROME",""+is_lwir);
// pad image to full sensor size
int numGridImage=fileIndices[imgNum];
int chn = distortions.fittingStrategy.distortionCalibrationData.gIP[numGridImage].getChannel();
......@@ -1289,7 +1292,7 @@ public class EyesisAberrations {
}
int rslt=matchSimulatedPattern.calculateDistortions(
null, // LwirReaderParameters lwirReaderParameters, // null is OK
lwirReaderParameters, // LwirReaderParameters lwirReaderParameters, // null is OK
distortionParameters, //
patternDetectParameters,
// patternDetectParameters.minGridPeriod/2,
......@@ -1332,16 +1335,17 @@ public class EyesisAberrations {
createPSFMap(
matchSimulatedPattern,
matchSimulatedPattern.applyFlatField (imp), // if grid is flat-field calibrated, apply it (may throw here)
lwirReaderParameters, //final LwirReaderParameters lwirReaderParameters, // null is OK
null, // int [][][] sampleList, // optional (or null) 2-d array: list of coordinate pairs (2d - to match existent PSF_KERNEL_MAP structure)
multiFilePSF.overexposedMaxFraction, //MULTIFILE_PSF.overexposedMaxFraction,
simulParameters, //SIMUL, //simulation parameters
mapFFTsize, // MAP_FFT_SIZE, // scanImageForPatterns:FFT size int mapFFTsize, // scanImageForPatterns:FFT size
patternDetectParameters, //PATTERN_DETECT, //MatchSimulatedPattern.PatternDetectParameters patternDetectParameters,
fft_overlap, //FFT_OVERLAP, // int fft_overlap,
fft_size, // FFT_SIZE, // int fft_size,
colorComponents, //COMPONENTS, // ColorComponents colorComponents,
PSF_subpixel, //PSF_SUBPIXEL, // int PSF_subpixel,
otfFilterParameters, // OTF_FILTER, // OTFFilterParameters otfFilterParameters,
(is_lwir?otfFilterParameters_lwir:otfFilterParameters),
// otfFilterParameters, // OTF_FILTER, // OTFFilterParameters otfFilterParameters,
psfParameters, //PSF_PARS, // final PSFParameters psfParameters
psfParameters.minDefinedArea , //PSF_PARS.minDefinedArea, // final double minDefinedArea,
PSFKernelSize, //// int PSFKernelSize, // size of square used in the new map (should be multiple of map step)
......@@ -2161,7 +2165,8 @@ public class EyesisAberrations {
jp4_instance.encodeProperiesToInfo(impPsf);
FileSaver fs=new FileSaver(impPsf);
fs.saveAsTiffStack(path);
// fs.saveAsTiffStack(path);
fs.saveAsTiff(path);
}
......@@ -2174,15 +2179,24 @@ public class EyesisAberrations {
if (kernels==null) return null;
int tilesY=kernels.length;
int tilesX=kernels[0].length;
int i,j,k,nChn, chn,x,y,index;
int i=0,j=0,k,nChn, chn,x,y,index;
double [][]kernel=null;
for (i=0;(i<tilesY) && (kernel==null);i++) for (j=0;(j<tilesX) && (kernel==null);j++) kernel=kernels[i][j];
if (kernel==null) return null;
int length=0;
for (i=0;i<kernel.length;i++) if (kernel[i]!=null){
length=kernel[i].length;
break;
for (i=0;(i<tilesY) && (kernel==null);i++) {
for (j=0;(j<tilesX) && (kernel==null);j++) {
kernel=kernels[i][j];
}
}
System.out.println("Got non-empty kernel at "+i+":"+j);
if (kernel==null) return null;
/// int length=0;
/// for (i=0;i<kernel.length;i++) if (kernel[i]!=null){
/// length=kernel[i].length;
/// break;
/// }
int length = kernel.length; // number of color channels
if (length==0){
System.out.println("mergeKernelsToStack(): no non-null kernels");
return null;
......@@ -2192,7 +2206,7 @@ public class EyesisAberrations {
for (i=0;i<tilesY ;i++) for (j=0;j<tilesX;j++) if (kernels[i][j]!=null) {
for (k=0;(k<kernel.length)&& (k<channelsMask.length);k++) if (kernels[i][j][k]!=null) {
channelsMask[k]=1;
if (kernels[i][j][k].length>length) length=kernels[i][j][k].length;
if (kernels[i][j][k].length > length) length=kernels[i][j][k].length;
}
}
......@@ -2237,11 +2251,11 @@ public class EyesisAberrations {
public double [][][][] createPSFMap(
final MatchSimulatedPattern commonMatchSimulatedPattern, // to be cloned in threads, using common data
final ImagePlus imp_sel, // linearized Bayer mosaic image from the camera, GR/BG
final ImagePlus imp_sel, // linearized Bayer mosaic image from the camera, GR/BG
final LwirReaderParameters lwirReaderParameters, // null is OK
final int [][][] sampleList, // optional (or null) 2-d array: list of coordinate pairs (2d - to match existent pdfKernelMap structure)
final double overexposedAllowed, // fraction of pixels OK to be overexposed
final SimulationPattern.SimulParameters simulParameters,
final int mapFFTsize, // scanImageForPatterns:FFT size
final MatchSimulatedPattern.PatternDetectParameters patternDetectParameters,
final int fft_overlap,
final int fft_size,
......@@ -2258,6 +2272,17 @@ public class EyesisAberrations {
final int masterDebugLevel, // get rid of it? // ** NEW
final int globalDebugLevel,// ** NEW
final int debug_level){// debug level used inside loops
boolean is_lwir = ((lwirReaderParameters != null) && lwirReaderParameters.is_LWIR(imp_sel));
boolean is_mono = false;
try {
is_mono = Boolean.parseBoolean((String) imp_sel.getProperty("MONOCHROME"));
} catch (Exception e) {
}
is_mono |= is_lwir;
final int full_fft_size = fft_size * PSF_subpixel / (is_mono? 2: 1); // for LWIR - 64, 5MPix: 1024. fft_size = 32/256
final boolean debugLateralShifts=(globalDebugLevel>1);
System.out.println("createPSFMap(): masterDebugLevel="+masterDebugLevel+" globalDebugLevel="+globalDebugLevel+" debug_level="+debug_level); // 2 2 0
final long startTime = System.nanoTime();
......@@ -2273,20 +2298,30 @@ public class EyesisAberrations {
int numPatternCells=0;
/* Filter results based on correlation with the actual pattern */
boolean [][] PSFBooleanMap; // map of 2*fft_size x 2*fft_size squares with 2*fft_overlap step, true means that that tile can be used for PSF
final int mapWidth=imp_sel.getWidth();
final int tile_size = (is_mono? 1 : 2) * fft_size;
final int tile_overlap = (is_mono? 1 : 2) * fft_overlap;
if (sampleList==null){
// tiles are twice smaller for monochrome
PSFBooleanMap= mapFromPatternMask ( // count number of defined cells
commonMatchSimulatedPattern,
imp_sel.getWidth(), // image (mask) width
fft_size*2,
fft_overlap*2,
fft_size, // backward compatibility margin==tileSize/2
mapWidth, // imp_sel.getWidth(), // image (mask) width
tile_size, // fft_size*2,
tile_overlap, // fft_overlap*2,
fft_size, // backward compatibility margin==tileSize/2
gaussWidth,
// psfParameters.minDefinedArea);
minDefinedArea,
globalDebugLevel);
} else {
PSFBooleanMap= new boolean[sampleList.length][sampleList[0].length];
for (int i=0;i<sampleList.length;i++) for (int j=0;j<sampleList[0].length;j++) PSFBooleanMap[i][j]=(sampleList[i][j][0]>=0); // all with positive X
for (int i=0;i<sampleList.length;i++) {
for (int j=0;j<sampleList[0].length;j++) {
PSFBooleanMap[i][j]=(sampleList[i][j][0]>=0); // all with positive X
}
}
}
if (PSFBooleanMap==null) return null;
numPatternCells=0;
......@@ -2307,9 +2342,14 @@ public class EyesisAberrations {
if (PSFBooleanMap[nTileY][nTileX]) {
tilesToProcessXY[ncell ][0]=nTileX;
tilesToProcessXY[ncell ][1]=nTileY;
tilesToProcessXY[ncell ][2]=(sampleList==null)?(fft_overlap*2*nTileX):sampleList[nTileY][nTileX][0];
tilesToProcessXY[ncell++][3]=(sampleList==null)?(fft_overlap*2*nTileY):sampleList[nTileY][nTileX][1];
pdfKernelMap[nTileY][nTileX]=new double[colorComponents.colorsToCorrect.length][];
tilesToProcessXY[ncell ][2]=(sampleList==null)?(tile_overlap * nTileX) : sampleList[nTileY][nTileX][0];
tilesToProcessXY[ncell++][3]=(sampleList==null)?(tile_overlap * nTileY) : sampleList[nTileY][nTileX][1];
if (is_mono) {
pdfKernelMap[nTileY][nTileX]=new double[1][];
} else {
pdfKernelMap[nTileY][nTileX]=new double[colorComponents.colorsToCorrect.length][];
}
} else pdfKernelMap[nTileY][nTileX]=null;
}
final double [][][][] debugLateral=new double [PSFBooleanMap.length][PSFBooleanMap[0].length][][];
......@@ -2322,10 +2362,9 @@ public class EyesisAberrations {
final int patternCells=numPatternCells;
// final double [] overexposedMap, // map of overexposed pixels in the image (may be null)
final double [] overexposed=(overexposedAllowed>0)?JP4_INSTANCE.overexposedMap (imp_sel):null;
final int mapWidth=imp_sel.getWidth();
final AtomicInteger tilesFinishedAtomic = new AtomicInteger(1); // first finished will be 1
final int debugNumColors=6;
final int dbgTile0 = -1; // 245; //
final int debugNumColors = is_mono? 1 : colorComponents.colorsToCorrect.length;
// final int dbgTile0 = 217; // -1; // 245; //
for (int ithread = 0; ithread < threads.length; ithread++) {
// Concurrently run in as many threads as CPUs
threads[ithread] = new Thread() {
......@@ -2350,7 +2389,9 @@ public class EyesisAberrations {
SimulationPattern simulationPattern= new SimulationPattern(bitmaskPattern);
simulationPattern.debugLevel=globalDebugLevel;
double [] windowFFTSize= matchSimulatedPattern.initWindowFunction(fft_size,gaussWidth); //=initHamming( fft_size) calculate once
double [] windowFullFFTSize=matchSimulatedPattern.initWindowFunction(fft_size*PSF_subpixel,gaussWidth); //=initHamming( fft_size*subpixel);
// same width - different size?
/// double [] windowFullFFTSize = matchSimulatedPattern.initWindowFunction(fft_size*PSF_subpixel,gaussWidth); //=initHamming( fft_size*subpixel);
double [] windowFullFFTSize = matchSimulatedPattern.initWindowFunction(full_fft_size,gaussWidth); //=initHamming( fft_size*subpixel);
DoubleFHT fht_instance =new DoubleFHT(); // provide DoubleFHT instance to save on initializations (or null)
double over;
// individual per-thread - will be needed when converted to doubleFHT
......@@ -2360,19 +2401,20 @@ public class EyesisAberrations {
nTY=tilesToProcessXY[nTile][1];
y0=tilesToProcessXY[nTile][3];
x0=tilesToProcessXY[nTile][2];
if (nTile == dbgTile0) {
boolean debugThis = false; // (y0==48) && (x0==80);
if (debugThis) {
System.out.println("#!# "+x0+":"+y0+" Processing tile["+nTY+"]["+nTX+"] ("+(nTile+1)+" of "+patternCells+") : "+IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
}
if (updateStatus) IJ.showStatus("Processing tile["+nTY+"]["+nTX+"] ("+(nTile+1)+" of "+patternCells+")");
if (masterDebugLevel>1) System.out.println("#!# "+x0+":"+y0+" Processing tile["+nTY+"]["+nTX+"] ("+(nTile+1)+" of "+patternCells+") : "+IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
if (overexposed!=null){
over=JP4_INSTANCE.fracOverExposed(overexposed, // map of overexposed pixels 0.0 - 0K, >0 (==1.0) - overexposed
over=JP4_INSTANCE.fracOverExposed(
overexposed, // map of overexposed pixels 0.0 - 0K, >0 (==1.0) - overexposed
mapWidth, // width of the map
x0, // X of the top left corner of the selection
y0, // Y of the top left corner of the selection
2*fft_size, // selection width
2*fft_size); // selection height
// if ((globalDebugLevel>0) && (over>0.0)) System.out.println("Overexposed fraction of "+over+" at x0="+x0+" y0="+y0+" width"+(2*fft_size));
tile_size, // selection width
tile_size); // selection height
} else over=-1.0;
if ( over > overexposedAllowed) {
pdfKernelMap[nTY][nTX]=null;
......@@ -2381,12 +2423,14 @@ public class EyesisAberrations {
if (debugLateralShifts) {
debugLateral[nTY][nTX]= new double [debugNumColors][]; // X/Y shift of the PSF array, in Bayer component pixel coordinates (same as PSF arrays)
}
kernels=getPSFKernels(imp_sel,
kernels=getPSFKernels(
imp_sel,
lwirReaderParameters, //LwirReaderParameters lwirReaderParameters, // null is OK
simArray, //simulation image, scaled PSF_subpixel/2
2*fft_size, // size in pixels (twice fft_size)
tile_size, // 2*fft_size, // size in pixels (twice fft_size for Bayer only?)
x0, // top left corner X (pixels)
y0, // top left corner Y (pixels)
simulationPattern,
simulationPattern, // should be individual for each sensor type? Probably not, it is just a high res bitmap
matchSimulatedPattern,
patternDetectParameters,
windowFFTSize, //=initHamming( fft_size) calculate once
......@@ -2399,14 +2443,18 @@ public class EyesisAberrations {
psfParameters,
fht_instance, // provide DoubleFHT instance to save on initializations (or null)
debug_level,// ((x0<512)&& (y0<512))?3:debug_level DEBUG during "focusing"
masterDebugLevel, // get rid of it? // ** NEW
globalDebugLevel + ((nTile == dbgTile0)? 3:0),// ** NEW
debugLateralShifts?debugLateral[nTY][nTX]:null
masterDebugLevel+ (debugThis? 3:0), // get rid of it? // ** NEW
globalDebugLevel + (debugThis? 3:0),// ** NEW
debugLateralShifts?debugLateral[nTY][nTX] : null
);
if (kernels!=null) {
if (kernelLength(kernels)>(PSFKernelSize*PSFKernelSize)) kernels=resizeForFFT(kernels,PSFKernelSize); // shrink before normalizing
if (kernelLength(kernels)>(PSFKernelSize*PSFKernelSize)) {
kernels=resizeForFFT(kernels,PSFKernelSize); // shrink before normalizing
}
normalizeKernel(kernels); // in-place
if (kernelLength(kernels)<(PSFKernelSize*PSFKernelSize)) kernels=resizeForFFT(kernels,PSFKernelSize); // expand after normalizing
if (kernelLength(kernels)<(PSFKernelSize*PSFKernelSize)) {
kernels=resizeForFFT(kernels,PSFKernelSize); // expand after normalizing
}
for (nChn=0;nChn<kernels.length;nChn++) if (kernels[nChn]!=null){
pdfKernelMap[nTY][nTX][nChn]=kernels[nChn]; // not .clone()?
}
......@@ -2650,41 +2698,75 @@ public class EyesisAberrations {
return 0;
}
public double [][] getPSFKernels ( ImagePlus imp,
float [][] simArray, //simulation image, scaled PSF_subpixel/2 (or null), [0] - main pixels, [1] - shifted diagonally by 0.5 pixels (for checker greens)
int size, // size in pixels (twice FFT_SIZE)
int x0, // top left corner X (pixels)
int y0, // top left corner Y (pixels)
// should return [1] for mono
public double [][] getPSFKernels (
ImagePlus imp,
LwirReaderParameters lwirReaderParameters, // null is OK
float [][] simArray, //simulation image, scaled PSF_subpixel/2 (or null), [0] - main pixels, [1] - shifted diagonally by 0.5 pixels (for checker greens)
int tile_size, // size in pixels (twice FFT_SIZE for Bayer, equals FFT size for mono)
int x0, // top left corner X (pixels)
int y0, // top left corner Y (pixels)
SimulationPattern simulationPattern,
MatchSimulatedPattern matchSimulatedPattern,
MatchSimulatedPattern.PatternDetectParameters patternDetectParameters,
double [] Hamming, //=initHamming( fft_size) calculate once
double [] fullHamming, //=initHamming( fft_size*subpixel);
int subpixel, // use finer grid than actual pixels
double [] Hamming, //=initHamming( fft_size) calculate once
double [] fullHamming, //=initHamming( fft_size*subpixel); for mono - twice smaller !
int subpixel, // use finer grid than actual pixels
SimulationPattern.SimulParameters simulParameters,
EyesisAberrations.ColorComponents colorComponents,
EyesisAberrations.OTFFilterParameters otfFilterParameters,
int referenceComp, // number of color component to reference lateral chromatic aberration to (now 4 - checkerboard greens)
int referenceComp, // number of color component to reference lateral chromatic aberration to (now 4 - checkerboard greens)
EyesisAberrations.PSFParameters psfParameters,
DoubleFHT fht_instance, // provide DoubleFHT instance to save on initializations (or null)
int masterDebugLevel, // get rid of it? // ** NEW
int globalDebugLevel,// ** NEW
int debug,
double [][] debugLateralTile
int masterDebugLevel, // get rid of it? // ** NEW
int globalDebugLevel,// ** NEW
int debug,
double [][] debugLateralTile
){
boolean debugThis=false; //(y0==384) && ((x0==448) || (x0==512));
boolean debugThis= false; // (y0==48) && (x0==80); //(y0==384) && ((x0==448) || (x0==512));// false;
if (globalDebugLevel>1){
System.out.println("getPSFKernels(), simArray is "+((simArray==null)?"":"not ")+"null");
}
if (imp==null) return null; // Maybe convert to double pixel array once to make it faster?
if (fht_instance==null) fht_instance=new DoubleFHT(); // move upstream to reduce number of initializations
double [][] kernels= new double[6][]; // was global
String title=imp.getTitle()+"X"+x0+"Y"+y0;
Rectangle PSFCell=new Rectangle (x0,y0,size,size);
int fft_size=size/2;
double [][] input_bayer=matchSimulatedPattern.splitBayer(imp,PSFCell,colorComponents.equalizeGreens); // does it work trhe same?
boolean is_lwir = ((lwirReaderParameters != null) && lwirReaderParameters.is_LWIR(imp));
boolean is_mono = false;
boolean invert_pattern = is_lwir;
try {
is_mono = Boolean.parseBoolean((String) imp.getProperty("MONOCHROME"));
} catch (Exception e) {
}
is_mono |= is_lwir;
if (is_mono) referenceComp = 0; //
int fft_size=is_mono ? tile_size : (tile_size/2); // for LWIR - 32
int full_fft_size = fft_size * subpixel / (is_mono? 2: 1); // for LWIR - 64
Rectangle PSFCell=new Rectangle (
x0,
y0,
tile_size,
tile_size);
double [][] kernels= new double[is_mono?1:6][];
double [][] input_bayer_or_mono=null; // single mono slice will have twice dimensions of the bayer
if (is_mono) {
input_bayer_or_mono = new double[1][];
input_bayer_or_mono[0] = matchSimulatedPattern.getNoBayer(
imp,
PSFCell);
} else {
input_bayer_or_mono=matchSimulatedPattern.splitBayer(
imp,
PSFCell,
colorComponents.equalizeGreens); // does it work the same?
}
//int greensToProcess=4;
int i,j,l;
double [][] simul_pixels;
......@@ -2694,15 +2776,20 @@ public class EyesisAberrations {
double [][] dbgSimPix=null;
double [] localBarray;
double min_half_period = (is_lwir? patternDetectParameters.minGridPeriodLwir: patternDetectParameters.minGridPeriod)/2;
double max_half_period = (is_lwir? patternDetectParameters.maxGridPeriodLwir:patternDetectParameters.maxGridPeriod)/2;
if ((simArray==null) || (psfParameters.approximateGrid)){ // just for testing(never here?)
/* Calculate pattern parameters, including distortion */
if (matchSimulatedPattern.PATTERN_GRID==null) {
double[][] distortedPattern= matchSimulatedPattern.findPatternDistorted(input_bayer, // pixel array to process (no windowing!)
double[][] distortedPattern= matchSimulatedPattern.findPatternDistorted(
input_bayer_or_mono, // pixel array to process (no windowing!)
patternDetectParameters,
patternDetectParameters.minGridPeriod/2,
patternDetectParameters.maxGridPeriod/2,
true, //(greensToProcess==4), // boolean greens, // this is a pattern for combined greens (diagonal), adjust results accordingly
min_half_period, // patternDetectParameters.minGridPeriod/2,
max_half_period, // patternDetectParameters.maxGridPeriod/2,
(!is_mono), //true, //(greensToProcess==4), // boolean greens, // this is a pattern for combined greens (diagonal), adjust results accordingly
title); // title prefix to use for debug images
if (distortedPattern==null) return null;
......@@ -2716,8 +2803,7 @@ public class EyesisAberrations {
" W1_phase="+IJ.d2s(distortedPattern[1][2],2));
}
// simulationPattern.simulatePatternFullPattern( // Not thread safe!
localBarray=simulationPattern.simulatePatternFullPatternSafe(
localBarray=simulationPattern.simulatePatternFullPatternSafe(
distortedPattern[0][0],
distortedPattern[0][1],
distortedPattern[0][2],
......@@ -2726,7 +2812,7 @@ public class EyesisAberrations {
distortedPattern[1][2],
distortedPattern[2], //
simulParameters.subdiv,
fft_size,
fft_size, // FIXME?
simulParameters.center_for_g2,
false);//boolean mono
wVectors[0][0]=2.0*distortedPattern[0][0]/subpixel;
......@@ -2737,7 +2823,7 @@ public class EyesisAberrations {
double[][] distPatPars= matchSimulatedPattern.findPatternFromGrid(
x0, // top-left pixel of the square WOI
y0,
size, // size of square (pixels)
tile_size, // size of square (pixels)
Hamming, // only half-window!
false, // use linear approximation (instead of quadratic)
1.0E-10, // thershold ratio of matrix determinant to norm for linear approximation (det too low - fail)
......@@ -2755,12 +2841,10 @@ public class EyesisAberrations {
double [] phases={
1.0*Math.PI*(distPatPars[0][2]-iUV[0]+(negative?(-0.5):0.5)), // measured from the center of white
1.0*Math.PI*(distPatPars[1][2]-iUV[1]+0.5)};
// double [][]wVectors={{distPatPars[0][0],distPatPars[0][1]},{distPatPars[1][0],distPatPars[1][1]}};
wVectors[0][0]=distPatPars[0][0];
wVectors[0][1]=distPatPars[0][1];
wVectors[1][0]=distPatPars[1][0];
wVectors[1][1]=distPatPars[1][1];
// simulationPattern.simulatePatternFullPattern( // Not thread safe!
localBarray=simulationPattern.simulatePatternFullPatternSafe(
wVectors[0][0],
wVectors[0][1],
......@@ -2770,50 +2854,75 @@ public class EyesisAberrations {
phases[1],
simCorr, //
simulParameters.subdiv,
fft_size,
fft_size, // FIXME!
simulParameters.center_for_g2,
false);//boolean mono
}
// simul_pixels= simulationPattern.extractSimulPatterns (
simul_pixels= simulationPattern.extractSimulPatterns (
localBarray, // this version is thread safe
simulParameters,
subpixel, // subdivide pixels
fft_size*subpixel, // number of Bayer cells in width of the square selection (half number of pixels)
0.0, // selection center, X (in pixels)
0.0); // selection center, y (in pixels)
if (subpixel>1) {
if (colorComponents.colorsToCorrect[5]) simul_pixels=combineCheckerGreens (simul_pixels, // pixel arrays after oversampleFFTInput() or extractSimulPatterns())
subpixel); // same as used in oversampleFFTInput() - oversampling ratio
}
for (i=0;i<simul_pixels.length; i++) {
if (!colorComponents.colorsToCorrect[i]) simul_pixels[i]=null; // removed unused
if (is_mono) {
simul_pixels= new double[1][];
// TODO: so many places to invert LWIR pattern... or not
simul_pixels[0]= simulationPattern.extractSimulMono ( // TODO: can use twice smaller barray
localBarray,
invert_pattern,
simulParameters,
subpixel, // 1, // subdivide output pixels - now 4
full_fft_size, // fft_size*subpixel, // number of Bayer cells in width of the square selection (half number of pixels)
0, // selection center, X (in pixels)
0);
} else {
simul_pixels= simulationPattern.extractSimulPatterns (
localBarray, // this version is thread safe
simulParameters,
subpixel, // subdivide pixels
full_fft_size, // fft_size*subpixel, // number of Bayer cells in width of the square selection (half number of pixels)
0.0, // selection center, X (in pixels)
0.0); // selection center, y (in pixels)
if (subpixel>1) {
if (colorComponents.colorsToCorrect[5]) simul_pixels=combineCheckerGreens (simul_pixels, // pixel arrays after oversampleFFTInput() or extractSimulPatterns())
subpixel); // same as used in oversampleFFTInput() - oversampling ratio
}
for (i=0;i<simul_pixels.length; i++) {
if (!colorComponents.colorsToCorrect[i]) simul_pixels[i]=null; // removed unused
}
}
simul_pixels= normalizeAndWindow (simul_pixels, fullHamming);
} else {
Rectangle PSFCellSim=new Rectangle (x0*subpixel/2,y0*subpixel/2,size*subpixel/2,size*subpixel/2); // getting here
simul_pixels=new double[6][];
// simulationPattern.debugLevel=globalDebugLevel;
for (i=0;i<simul_pixels.length; i++) {
if (colorComponents.colorsToCorrect[i]) simul_pixels[i]=simulationPattern.extractBayerSim (
} else { //if ((simArray==null) || (psfParameters.approximateGrid)){ // never above?
Rectangle PSFCellSim = new Rectangle (
x0 * subpixel/2,
y0 * subpixel/2,
tile_size * subpixel/2,
tile_size * subpixel/2); // getting here
if (is_mono) {
//FIXME: Somewhere need to invert color for LWIR
simul_pixels=new double[1][];
simul_pixels[0]=simulationPattern.extractBayerSim ( // works with mono now
simArray, // [0] - regular pixels, [1] - shifted by 1/2 diagonally, for checker greens
imgWidth*subpixel/2,
PSFCellSim,
subpixel, // 4
i);
else simul_pixels[i]=null;
(invert_pattern? -2: -1)); //New : -1 - extract mono TODO: see if 1/2pix shift is needed
} else {
simul_pixels=new double[6][];
for (i=0;i<simul_pixels.length; i++) {
if (colorComponents.colorsToCorrect[i]) simul_pixels[i]=simulationPattern.extractBayerSim (
simArray, // [0] - regular pixels, [1] - shifted by 1/2 diagonally, for checker greens
imgWidth*subpixel/2,
PSFCellSim,
subpixel, // 4
i);
else simul_pixels[i]=null;
}
}
//System.out.println("PSFCell.y="+PSFCell.y+" PSFCell.height="+PSFCell.height+" imgWidth="+imgWidth+" PSFCell.x="+PSFCell.x+" PSFCell.width="+PSFCell.width+" matchSimulatedPattern.UV_INDEX.length="+matchSimulatedPattern.UV_INDEX.length);
int index=matchSimulatedPattern.getUVIndex((PSFCell.y+PSFCell.height/2)*imgWidth+(PSFCell.x+PSFCell.width/2));
// int index=matchSimulatedPattern.getUVIndex((PSFCell.y+PSFCell.height/2)*matchSimulatedPattern.getWOI().width+(PSFCell.x+PSFCell.width/2));
int index=matchSimulatedPattern.getUVIndex(
(PSFCell.y+PSFCell.height/2)*imgWidth+(PSFCell.x+PSFCell.width/2));
if (index<0) {
System.out.println ("Error, No UV pattern @ x="+(PSFCell.x+PSFCell.width/2)+", y="+(PSFCell.y+PSFCell.height/2));
return null;
}
// int [] iUV={index % matchSimulatedPattern.getDArrayHeight(), index / matchSimulatedPattern.getDArrayHeight()}; // TODO: make sure it is correct?
int [] iUV={index % matchSimulatedPattern.getDArrayWidth(), index / matchSimulatedPattern.getDArrayWidth()}; // TODO: make sure it is correct?
if (matchSimulatedPattern.getDArray(iUV[1],iUV[0])==null) {
if (globalDebugLevel>0){
......@@ -2824,18 +2933,25 @@ public class EyesisAberrations {
}
return null;
}
if (matchSimulatedPattern.getDArray(iUV[1],iUV[0],1)==null) {
if (globalDebugLevel>0) System.out.println ( "Tried to extract non-existent wave vectors from "+iUV[0]+"/"+iUV[1]);
return null;
}
//TODO: Need to define wave vectors here - how?
wVectors[0]=matchSimulatedPattern.getDArray(iUV[1],iUV[0],1); //null pointer
wVectors[1]=matchSimulatedPattern.getDArray(iUV[1],iUV[0],2);
// should it be averaged WV?
if (globalDebugLevel>2) System.out.println ( " x0="+x0+" y0="+y0);
if (globalDebugLevel>2) SDFA_INSTANCE.showArrays(input_bayer, true, title+"-in");
if (globalDebugLevel>2) SDFA_INSTANCE.showArrays(simul_pixels, true, title+"-S");
//if (globalDebugLevel>2) System.out.println (simArray[0][-1]); // cause error
if (debugThis || (globalDebugLevel>2)) System.out.println ( " x0="+x0+" y0="+y0);
if (debugThis || (globalDebugLevel>2)) {
SDFA_INSTANCE.showArrays(input_bayer_or_mono, true, title+"-in");
}
if (debugThis || (globalDebugLevel>2)) {
SDFA_INSTANCE.showArrays(simul_pixels, true, title+"-S");
}
if (masterDebugLevel>1){
dbgSimPix=new double[simul_pixels.length][];
for (int ii=0;ii<dbgSimPix.length;ii++)
......@@ -2846,67 +2962,91 @@ public class EyesisAberrations {
simul_pixels= normalizeAndWindow (simul_pixels, fullHamming);
}
input_bayer= normalizeAndWindow (input_bayer, Hamming);
input_bayer_or_mono= normalizeAndWindow (input_bayer_or_mono, Hamming);
if (debugThis || (globalDebugLevel>2)) {
SDFA_INSTANCE.showArrays(input_bayer_or_mono, true, title+"-in-norm");
}
if (subpixel>1) {
input_bayer= oversampleFFTInput (input_bayer,subpixel);
if (colorComponents.colorsToCorrect[5]) input_bayer=combineCheckerGreens (input_bayer, // pixel arrays after oversampleFFTInput() or extractSimulPatterns())
subpixel); // same as used in oversampleFFTInput() - oversampling ratio
if (is_mono) {
if (subpixel > 2) { // mono requires >1 !)
input_bayer_or_mono= oversampleFFTInput (input_bayer_or_mono, subpixel/2);
}
} else {
input_bayer_or_mono= oversampleFFTInput (input_bayer_or_mono,subpixel);
if (colorComponents.colorsToCorrect[5]) input_bayer_or_mono=combineCheckerGreens (input_bayer_or_mono, // pixel arrays after oversampleFFTInput() or extractSimulPatterns())
subpixel); // same as used in oversampleFFTInput() - oversampling ratio
}
}
if (!is_mono) {
for (i=0;i<4;i++) if (!colorComponents.colorsToCorrect[i]) input_bayer_or_mono[i]=null; // leave composite greens even if disabled
}
if (debugThis) {
// SDFA_INSTANCE.showArrays(input_bayer_or_mono, full_fft_size, full_fft_size, title);
}
if (globalDebugLevel>2) System.out.println ( " input_bayer.length="+input_bayer_or_mono.length+" simul_pixels.length="+simul_pixels.length+" full_fft_size="+full_fft_size*subpixel);
for (i=0;(i<input_bayer_or_mono.length) && (i<simul_pixels.length);i++) if ((colorComponents.colorsToCorrect[i]) && (input_bayer_or_mono[i]!=null)){
if (globalDebugLevel>2) System.out.println ( "input_bayer["+i+"].length="+input_bayer_or_mono[i].length+" simul_pixels["+i+"].length="+simul_pixels[i].length);
}
for (i=0;i<4;i++) if (!colorComponents.colorsToCorrect[i]) input_bayer[i]=null; // leave composite greens even if disabled
if (debugThis) {
// SDFA_INSTANCE.showArrays(input_bayer, fft_size*subpixel, fft_size*subpixel, title);
SDFA_INSTANCE.showArrays(input_bayer_or_mono, true, title+"-input");
}
if (globalDebugLevel>2) System.out.println ( " input_bayer.length="+input_bayer.length+" simul_pixels.length="+simul_pixels.length+" fft_size*subpixel="+fft_size*subpixel);
for (i=0;(i<input_bayer.length) && (i<simul_pixels.length);i++) if ((colorComponents.colorsToCorrect[i]) && (input_bayer[i]!=null)){
if (globalDebugLevel>2) System.out.println ( "input_bayer["+i+"].length="+input_bayer[i].length+" simul_pixels["+i+"].length="+simul_pixels[i].length);
if (debugThis) {
SDFA_INSTANCE.showArrays(simul_pixels, true, title+"-SIM");
}
if (debugThis) SDFA_INSTANCE.showArrays(input_bayer, true, title+"-input");
if (debugThis) SDFA_INSTANCE.showArrays(simul_pixels, true, title+"-SIM");
//if (globalDebugLevel>2)globalDebugLevel=0; //************************************************************
double [][] inverted=new double[colorComponents.colorsToCorrect.length][];
double [][] inverted=new double[is_mono? 1 : colorComponents.colorsToCorrect.length][];
double wvAverage=Math.sqrt(0.5*(wVectors[0][0]*wVectors[0][0]+wVectors[0][1]*wVectors[0][1]+
wVectors[1][0]*wVectors[1][0]+wVectors[1][1]*wVectors[1][1]));
for (i=0;(i<input_bayer.length) && (i<simul_pixels.length);i++) if ((colorComponents.colorsToCorrect[i]) && (input_bayer[i]!=null)){
if (globalDebugLevel>2) System.out.println ( "Color "+colorComponents.getColorName(i)+" is re-calculated into bayer pixels ");
if (globalDebugLevel>2) System.out.println ( "input_bayer["+i+"].length="+input_bayer[i].length+" simul_pixels["+i+"].length="+simul_pixels[i].length);
inverted[i]=limitedInverseOfFHT(input_bayer[i],
simul_pixels[i],
fft_size*subpixel,
(i==5), // boolean checker // checkerboard pattern in the source file (use when filtering)
true, // forwardOTF,
subpixel,
otfFilterParameters,
fht_instance,
psfParameters.mask1_sigma*size*wvAverage, // normalize to wave vectors!
psfParameters.mask1_threshold,
psfParameters.gaps_sigma*size*wvAverage,
psfParameters.mask_denoise,
debug,
globalDebugLevel,
title+"-"+i);
for (i=0;(i<input_bayer_or_mono.length) && (i<simul_pixels.length);i++) {
if ((is_mono || colorComponents.colorsToCorrect[i]) && (input_bayer_or_mono[i]!=null)){
if (globalDebugLevel>2) System.out.println ( "Color "+colorComponents.getColorName(i)+" is re-calculated into bayer pixels ");
if (globalDebugLevel>2) System.out.println ( "input_bayer["+i+"].length="+input_bayer_or_mono[i].length+" simul_pixels["+i+"].length="+simul_pixels[i].length);
inverted[i]=limitedInverseOfFHT(
input_bayer_or_mono[i],
simul_pixels[i],
full_fft_size, // fft_size*subpixel,
(i==5), // boolean checker // checkerboard pattern in the source file (use when filtering)
true, // forwardOTF,
(subpixel / (is_mono? 2 : 1)),
otfFilterParameters,
fht_instance,
psfParameters.mask1_sigma * (fft_size * 2) * wvAverage, // normalize to wave vectors!
psfParameters.mask1_threshold,
psfParameters.gaps_sigma * (fft_size * 2) * wvAverage, // normalize to wave vectors!
psfParameters.mask_denoise,
debug,
(globalDebugLevel + (debugThis? 3:0)),
title+"-"+i);
}
}
int debugThreshold=1;
if (debugThis) SDFA_INSTANCE.showArrays(inverted, fft_size*subpixel, fft_size*subpixel, title+"_Combined-PSF");
if (debugThis) {
SDFA_INSTANCE.showArrays(inverted, title+"_Combined-PSF"); // Here OK with mono
}
/* correct composite greens */
/* Here we divide wave vectors by subpixel as the pixels are already added */
double [][] wVrotMatrix= {{0.5,0.5},{-0.5,0.5}};
double [][]wVectors4= new double [2][2];
double [][]wVectors4= new double [2][2]; // Will only be used for color, combined diagonal greens
for (i=0;i<2;i++) for (j=0;j<2;j++) {
wVectors4[i][j]=0.0;
for (l=0;l<2;l++) wVectors4[i][j]+=wVectors[i][l]*wVrotMatrix[l][j];
}
double [][] PSF_shifts= new double [input_bayer.length][]; // X/Y shift of the PSF array, in Bayer component pixel coordinates (same as PSF arrays)
double [][] PSF_centroids= new double [input_bayer.length][]; // X/Y coordinates of the centroids of PSF in Bayer component pioxel coordinates (same as PSF arrays) (after they were optionally shifted)
double [][] lateralChromatic= new double [input_bayer.length][]; // X/Y coordinates of the centroids of Bayer component PSF in sensor pixel coordinates
double [][] kernelsForFFT= new double [input_bayer.length][];
double [][] psf_inverted= new double [input_bayer.length][];
double [][] psf_inverted_masked=new double [input_bayer.length][];
double [] lateralChromaticAbs=new double [input_bayer.length];
double [][] PSF_shifts = new double [input_bayer_or_mono.length][]; // X/Y shift of the PSF array, in Bayer component pixel coordinates (same as PSF arrays)
double [][] PSF_centroids = new double [input_bayer_or_mono.length][]; // X/Y coordinates of the centroids of PSF in Bayer component pioxel coordinates (same as PSF arrays) (after they were optionally shifted)
double [][] lateralChromatic = new double [input_bayer_or_mono.length][]; // X/Y coordinates of the centroids of Bayer component PSF in sensor pixel coordinates
double [][] kernelsForFFT = new double [input_bayer_or_mono.length][];
double [][] psf_inverted = new double [input_bayer_or_mono.length][];
double [][] psf_inverted_masked = new double [input_bayer_or_mono.length][];
double [] lateralChromaticAbs = new double [input_bayer_or_mono.length];
double [] zeroVector={0.0,0.0};
for (i=input_bayer.length-1;i>=0;i--) {
if (colorComponents.colorsToCorrect[i]) {
for (i=input_bayer_or_mono.length-1;i>=0;i--) {
if (is_mono || colorComponents.colorsToCorrect[i]) {
PSF_shifts[i]= zeroVector.clone();
PSF_centroids[i]= zeroVector.clone();
lateralChromatic[i]= zeroVector.clone();
......@@ -2922,15 +3062,15 @@ public class EyesisAberrations {
}
//int [][] clusterMask;
/* Start with referenceComp */
i= referenceComp;
if (globalDebugLevel>debugThreshold) {
System.out.println(x0+":"+y0+"1-PSF_shifts.length= "+PSF_shifts.length+" i="+i+" input_bayer.length="+input_bayer.length);
i = referenceComp; // now 0 for mono
if (globalDebugLevel > debugThreshold) {
System.out.println(x0+":"+y0+"1-PSF_shifts.length= "+PSF_shifts.length+" i="+i+" input_bayer.length="+input_bayer_or_mono.length);
System.out.println("Before: color Component "+i+" PSF_shifts["+i+"][0]="+IJ.d2s(PSF_shifts[i][0],3)+
" PSF_shifts["+i+"][1]="+IJ.d2s(PSF_shifts[i][1],3));
}
kernels[i]=combinePSF (inverted[i], // Square array of pixels with multiple repeated PSF (alternating sign)
kernels[i]=combinePSF (
inverted[i], // Square array of pixels with multiple repeated PSF (alternating sign)
!psfParameters.absoluteCenter, //true, // master, force ignoreChromatic
PSF_shifts[i], // centerXY[] - will be modified inside combinePSF() if PSF_PARS.ignoreChromatic is true
PSF_centroids[i], // will return array of XY coordinates of the result centroid
......@@ -2940,12 +3080,13 @@ public class EyesisAberrations {
title+"_"+i, // reduce the PSF cell size to this part of the area connecting first negative clones
(globalDebugLevel>4),
globalDebugLevel
);
);
if (globalDebugLevel>debugThreshold) System.out.println(x0+":"+y0+"After-1: color Component "+i+" PSF_shifts["+i+"][0]="+IJ.d2s(PSF_shifts [i][0],3)+" PSF_shifts["+i+"][1]="+IJ.d2s( PSF_shifts[i][1],3));
if (globalDebugLevel>debugThreshold) System.out.println(x0+":"+y0+"After-1: color Component "+i+" PSF_centroids["+i+"][0]="+IJ.d2s(PSF_centroids[i][0],3)+" PSF_centroids["+i+"][1]="+IJ.d2s(PSF_centroids[i][1],3));
if (!psfParameters.ignoreChromatic && !psfParameters.absoluteCenter) { /* Recalculate center to pixels from greens (diagonal)) and supply it to other colors (lateral chromatic aberration correction) */
for (j=0;j<input_bayer.length;j++) if ((colorComponents.colorsToCorrect[j]) && (j!=referenceComp)) {
if (!is_mono && !psfParameters.ignoreChromatic && !psfParameters.absoluteCenter) { /* Recalculate center to pixels from greens (diagonal)) and supply it to other colors (lateral chromatic aberration correction) */
for (j=0;j<input_bayer_or_mono.length;j++) if ((colorComponents.colorsToCorrect[j]) && (j!=referenceComp)) {
PSF_shifts[j]=shiftSensorToBayer (shiftBayerToSensor(PSF_shifts[referenceComp],referenceComp,subpixel),j,subpixel);
if (globalDebugLevel>debugThreshold) System.out.println(x0+":"+y0+"After-2 (recalc): color Component "+j+" PSF_shifts["+j+"][0]="+IJ.d2s(PSF_shifts[j][0],3)+" PSF_shifts["+j+"][1]="+IJ.d2s(PSF_shifts[j][1],3));
}
......@@ -2956,10 +3097,12 @@ public class EyesisAberrations {
i,
subpixel);
lateralChromaticAbs[i]=Math.sqrt(lateralChromatic[i][0]*lateralChromatic[i][0]+lateralChromatic[i][1]*lateralChromatic[i][1]);
/* Now process all the other components */
for (i=0; i<input_bayer.length;i++) if ((i!=referenceComp) && (colorComponents.colorsToCorrect[i])) {
for (i=0; i<input_bayer_or_mono.length;i++) if ((i!=referenceComp) && (colorComponents.colorsToCorrect[i])) {
// Will never get here for mono
if (globalDebugLevel>debugThreshold) {
System.out.println(x0+":"+y0+"2-PSF_shifts.length= "+PSF_shifts.length+" i="+i+" input_bayer.length="+input_bayer.length);
System.out.println(x0+":"+y0+"2-PSF_shifts.length= "+PSF_shifts.length+" i="+i+" input_bayer.length="+input_bayer_or_mono.length);
System.out.println(x0+":"+y0+"Before: color Component "+i+" PSF_shifts["+i+"][0]="+IJ.d2s(PSF_shifts[i][0],3)+
" PSF_shifts["+i+"][1]="+IJ.d2s(PSF_shifts[i][1],3));
......@@ -2998,27 +3141,31 @@ public class EyesisAberrations {
" lateralChromatic["+i+"][1]="+IJ.d2s(lateralChromatic[i][1],3));
}
}
if (colorComponents.colorsToCorrect[referenceComp]) for (i=0;i<colorComponents.colorsToCorrect.length;i++) if ((colorComponents.colorsToCorrect[i])&& (i!=referenceComp)){
System.out.println("#!# "+x0+":"+y0+" "+colorComponents.getColorName(i)+" lateral chromatic (from green) "+IJ.d2s(lateralChromaticAbs[i],3)+"pix(sensor): ["+i+"][0]="+IJ.d2s(lateralChromatic[i][0]-lateralChromatic[referenceComp][0],3)+
" ["+i+"][1]="+IJ.d2s(lateralChromatic[i][1]-lateralChromatic[referenceComp][1],3));
if (colorComponents.colorsToCorrect[referenceComp]) {
for (i=0;i<colorComponents.colorsToCorrect.length;i++) {
if ((colorComponents.colorsToCorrect[i])&& (i!=referenceComp)){
System.out.println("#!# "+x0+":"+y0+" "+colorComponents.getColorName(i)+" lateral chromatic (from green) "+IJ.d2s(lateralChromaticAbs[i],3)+"pix(sensor): ["+i+"][0]="+IJ.d2s(lateralChromatic[i][0]-lateralChromatic[referenceComp][0],3)+
" ["+i+"][1]="+IJ.d2s(lateralChromatic[i][1]-lateralChromatic[referenceComp][1],3));
}
}
}
System.out.println("#!# "+x0+":"+y0+" "+"Lateral shift green from simulation "+IJ.d2s(lateralChromaticAbs[referenceComp],3)+"pix(sensor): ["+referenceComp+"][0]="+IJ.d2s(lateralChromatic[referenceComp][0],3)+
" ["+referenceComp+"][1]="+IJ.d2s(lateralChromatic[referenceComp][1],3));
}
if (debugLateralTile!=null) for (i=0;i<PSF_shifts.length;i++) {
if (colorComponents.colorsToCorrect[i]){
debugLateralTile[i]=new double [6];
debugLateralTile[i][0]=lateralChromatic[i][0];
debugLateralTile[i][1]=lateralChromatic[i][1];
debugLateralTile[i][2]=PSF_shifts[i][0];
debugLateralTile[i][3]=PSF_shifts[i][1];
debugLateralTile[i][4]=PSF_centroids[i][0];
debugLateralTile[i][5]=PSF_centroids[i][1];
} else {
debugLateralTile[i]=null;
if (debugLateralTile != null) {
for (i = 0; i < PSF_shifts.length; i++) {
if (is_mono || colorComponents.colorsToCorrect[i]){
debugLateralTile[i] = new double [6];
debugLateralTile[i][0] = lateralChromatic[i][0];
debugLateralTile[i][1] = lateralChromatic[i][1];
debugLateralTile[i][2] = PSF_shifts[i][0];
debugLateralTile[i][3] = PSF_shifts[i][1];
debugLateralTile[i][4] = PSF_centroids[i][0];
debugLateralTile[i][5] = PSF_centroids[i][1];
} else {
debugLateralTile[i] = null;
}
}
}
if (debugThis && (kernels!=null)){
int debugSize=0;
......@@ -3026,7 +3173,9 @@ public class EyesisAberrations {
debugSize=(int)Math.sqrt(kernels[ii].length);
break;
}
if (debugSize>0) SDFA_INSTANCE.showArrays(kernels, debugSize, debugSize, title+"_KERNELS");
if (debugSize>0) {
SDFA_INSTANCE.showArrays(kernels, debugSize, debugSize, title+"_KERNELS");
}
}
return kernels;
}
......@@ -3082,7 +3231,8 @@ public class EyesisAberrations {
/* ======================================================================== */
private double[] limitedInverseOfFHT(double [] measuredPixels, // measured pixel array
private double[] limitedInverseOfFHT(
double [] measuredPixels, // measured pixel array
double [] modelPixels, // simulated (model) pixel array)
int size, // FFT size
boolean checker, // checkerboard pattern in the source file (use when filtering)
......@@ -3097,7 +3247,8 @@ public class EyesisAberrations {
int debug,
int globalDebugLevel,
String title){ // title base for optional plots names
return limitedInverseOfFHT(measuredPixels,
return limitedInverseOfFHT(
measuredPixels,
modelPixels,
size,
checker,
......@@ -3268,11 +3419,20 @@ public class EyesisAberrations {
double threshold_low, // leave intact if energy is below this part of maximal
DoubleFHT fht_instance,
int globalDebugLevel){ // provide DoubleFHT instance to save on initializations (or null)
double th=threshold_high*threshold_high;
double tl=threshold_low*threshold_low;
int length=fht.length;
int size=(int) Math.sqrt(fht.length);
// temporary fix to match original parameters for size = 10254 (LWIR - 64)
// double threshold_high_mod = threshold_high * 1024/size;
// double threshold_low_mod = threshold_low * 1024/size;
// double th=threshold_high_mod * threshold_high_mod;
// double tl=threshold_low_mod * threshold_low_mod;
double th=threshold_high * threshold_high;
double tl=threshold_low * threshold_low;
// double [][] ps=new double [size/2+1][size];
int i,ix,iy, cloneNx, cloneNy, cloneX, cloneY;
int cloneStep=size/oversample;
......@@ -3283,7 +3443,9 @@ public class EyesisAberrations {
for (i=0;i<length; i++) if (psMax<ps[i]) psMax=ps[i];
double k=1.0/psMax;
for (i=0;i<length; i++) ps[i]*=k;
if (globalDebugLevel>2) SDFA_INSTANCE.showArrays(ps, "PS");
if (globalDebugLevel>2) {
SDFA_INSTANCE.showArrays(ps, "PS");
}
/* Add maximum at (0,0) */
double [] psWithZero=ps;
if (zerofreq_size>0.0) {
......@@ -3311,11 +3473,15 @@ public class EyesisAberrations {
}
}
/* debug show the mask */
if (globalDebugLevel>2) SDFA_INSTANCE.showArrays(mask, "PS-cloned");
if (globalDebugLevel>2) {
SDFA_INSTANCE.showArrays(mask, "PS-cloned");
}
if (sigma>0) {
DoubleGaussianBlur gb = new DoubleGaussianBlur();
gb.blurDouble(mask,size,size,sigma,sigma, 0.01);
if (globalDebugLevel>2) SDFA_INSTANCE.showArrays(mask, "PS-smooth");
if (globalDebugLevel>2) {
SDFA_INSTANCE.showArrays(mask, "PS-smooth");
}
}
/* make mask of cloned power spectrums */
......@@ -3336,7 +3502,9 @@ public class EyesisAberrations {
mask[i]*=ps[i]/(ps[i]+k2);
}
}
if (globalDebugLevel>2) SDFA_INSTANCE.showArrays(mask, "mask-all");
if (globalDebugLevel>2) {
SDFA_INSTANCE.showArrays(mask, "mask-all");
}
/* zeros are now for FHT - in the top left corner */
fht_instance.swapQuadrants(mask);
return mask;
......@@ -3408,6 +3576,9 @@ public class EyesisAberrations {
int debugLevel)
{
if (pixels==null) return null;
// if (centroid_xy == null) {
// return null; // debugging LWIR, never before
// }
// double [] contrastCache=new double[pixelSize*pixelSize];
int i,j;
......@@ -4150,7 +4321,11 @@ public class EyesisAberrations {
else listIndex++; // increase list index
}
if (maxValue==0.0) { // Should
if (!noThreshold) System.out.println("findClusterOnPSF: - should not get here - no points around >0, and threshold is not reached yet.");
if (!noThreshold) {
SDFA_INSTANCE.showArrays(psf, title+"-failed_cluster");
System.out.println("findClusterOnPSF: - should not get here - no points around >0, and threshold is not reached yet."+
" startX="+startX+" startY="+startY);
}
break;
}
/* Add this new point to the list */
......
......@@ -725,19 +725,25 @@ public class MatchSimulatedPattern {
/* returns array of 3 arrays: first two are 3-element wave vectors (x,y,phase), last - 3-rd order correction coefficients */
public double[][] findPatternDistorted(
double [][] bayer_pixels, // pixel array to process (no windowing!), two greens will be used
double [][] bayer_mono_pixels, // pixel array to process (no windowing!), two greens will be used
PatternDetectParameters patternDetectParameters,
double min_half_period,
double max_half_period,
boolean greens, // this is a pattern for combined greens (diagonal), adjust results accordingly
String title){ // title prefix to use for debug images
if (bayer_pixels==null) return null;
if (bayer_pixels.length<4) return null;
if (bayer_pixels[0]==null) return null;
if (bayer_pixels[3]==null) return null;
int size2=bayer_pixels[0].length;
int size=(int) Math.sqrt(size2);
int hsize=size/2;
if (bayer_mono_pixels==null) return null;
if (bayer_mono_pixels.length < 1) return null;
if (bayer_mono_pixels[0]==null) return null;
if (greens) {
if (bayer_mono_pixels.length<4) return null;
if (bayer_mono_pixels[3]==null) return null;
} else {
if (bayer_mono_pixels.length > 1) return null;
}
boolean is_mono = bayer_mono_pixels.length == 1;
int tile_size2=bayer_mono_pixels[0].length;
int tile_size=(int) Math.sqrt(tile_size2);
int hsize=tile_size/2;
int hsize2=hsize*hsize;
double [] quarterHamming=initWindowFunction(hsize, patternDetectParameters.gaussWidth);
double [] patternCorr=new double[6]; // second order non-linear pattern correction (perspective+distortion)
......@@ -747,31 +753,54 @@ public class MatchSimulatedPattern {
double [][] quarter_pixels =new double[9][];
double [][][] quarter_patterns =new double[9][][];
int [] quarterIndex={0, // top left
size/2, // top right
size*size/2, // bottom left
(size+1)*size/2, // bottom right
(size+1)*size/4, // center
size/4, // top
size*size/4,// left
(size+2)*size/4, // right
(2*size+1)*size/4}; // bottom
tile_size /2, // top right
tile_size * tile_size/2, // bottom left
(tile_size + 1) * tile_size/2, // bottom right
(tile_size + 1) * tile_size/4, // center
tile_size/4, // top
tile_size * tile_size/4,// left
(tile_size + 2) * tile_size/4, // right
(2 * tile_size + 1) * tile_size/4}; // bottom
int i,j,iq;
int index,qindex;
if (this.debugLevel>2) SDFA_INSTANCE.showArrays(bayer_pixels, size, size, title+"-bayer");
if (this.debugLevel>2) SDFA_INSTANCE.showArrays(bayer_mono_pixels, tile_size, tile_size, title+"-bayer");
for (iq=0; iq<9;iq++) {
index=quarterIndex[iq];
qindex=0;
for (i=0;i<hsize;i++) {
for (j=0;j<hsize;j++) { //quarter_pixels[iq][qindex++]=input_pixels[index++];
green0[qindex]= bayer_pixels[0][index];
green3[qindex++]=bayer_pixels[3][index++];
if (is_mono) {
quarter_pixels[iq] = new double [hsize * hsize];
for (i=0;i<hsize;i++) {
for (j=0;j<hsize;j++) { //quarter_pixels[iq][qindex++]=input_pixels[index++];
quarter_pixels[iq][qindex++] = bayer_mono_pixels[0][index++];
}
index+=hsize; // jump to the next line
}
quarter_pixels[iq]=combineDiagonalGreens (green0, green3, hsize, hsize);
index+=hsize; // jump to the next line
} else {
for (i=0;i<hsize;i++) {
for (j=0;j<hsize;j++) { //quarter_pixels[iq][qindex++]=input_pixels[index++];
green0[qindex]= bayer_mono_pixels[0][index];
green3[qindex++]=bayer_mono_pixels[3][index++];
}
// quarter_pixels[iq]=combineDiagonalGreens (
// green0,
// green3,
// hsize,
// hsize);
index+=hsize; // jump to the next line
}
// Moved outside of the i-loop, that was wrong!
quarter_pixels[iq]=combineDiagonalGreens (
green0,
green3,
hsize,
hsize);
}
quarter_pixels[iq]= normalizeAndWindow (quarter_pixels[iq], quarterHamming);
if (this.debugLevel>2) SDFA_INSTANCE.showArrays(quarter_pixels[iq],hsize, hsize, title+"-new"+iq);
// findPattern - see MSP 3290:
quarter_patterns[iq] = findPattern(
null, // DoubleFHT doubleFHT,
quarter_pixels[iq],
......@@ -781,9 +810,10 @@ public class MatchSimulatedPattern {
max_half_period,
greens,
title+"Q_"+iq);
if (quarter_patterns[iq]==null) return null;
}
if (this.debugLevel>2) {
for (iq=0; iq<9;iq++) {
System.out.println("Quarter="+iq+
......@@ -4777,8 +4807,6 @@ public class MatchSimulatedPattern {
}
}
// if (nowDebugCell)correctedPatternCrossLocationAverage4(
double [] centerXY=correctedPatternCrossLocation(
lwirReaderParameters, // LwirReaderParameters lwirReaderParameters, // null is OK
patternGrid[iUV[1]][iUV[0]][0], // initial coordinates of the pattern cross point
......@@ -9232,6 +9260,12 @@ y=xy0[1] + dU*deltaUV[0]*(xy1[1]-xy0[1])+dV*deltaUV[1]*(xy2[1]-xy0[1])
boolean is_lwir = ((lwirReaderParameters != null) && lwirReaderParameters.is_LWIR(imp));
int correlation_size = is_lwir ? distortionParameters.correlationSizeLwir : distortionParameters.correlationSize;
int max_correlation_size = is_lwir ? distortionParameters.maximalCorrelationSizeLwir : distortionParameters.maximalCorrelationSize;
boolean is_mono = false;
try {
is_mono = Boolean.parseBoolean((String) imp.getProperty("MONOCHROME"));
} catch (Exception e) {
}
is_mono |= is_lwir;
int debug_threshold = 3;
// next print - same for good and bad, correction==null
......@@ -9521,14 +9555,25 @@ y=xy0[1] + dU*deltaUV[0]*(xy1[1]-xy0[1])+dV*deltaUV[1]*(xy2[1]-xy0[1])
SDFA_INSTANCE.showArrays(barray, "barray"+ixc+":"+iyc);
}
// double[][] sim_pix;
double[][] sim_pix= simulationPattern.extractSimulPatterns (
barray,
thisSimulParameters,
1, // subdivide output pixels
thisCorrelationSize, // number of Bayer cells in width of the square selection (half number of pixels)
0,
0);
double[][] sim_pix=null;
if (is_mono) {
sim_pix= new double[1][];
sim_pix[0]= simulationPattern.extractSimulMono ( // TODO: can use twice smaller barray
barray,
thisSimulParameters,
1, // subdivide output pixels - now 4
thisCorrelationSize, // number of Bayer cells in width of the square selection (half number of pixels)
0, // selection center, X (in pixels)
0);
} else {
sim_pix= simulationPattern.extractSimulPatterns (
barray,
thisSimulParameters,
1, // subdivide output pixels
thisCorrelationSize, // number of Bayer cells in width of the square selection (half number of pixels)
0,
0);
}
if (sim_pix==null){
System.out.println("***** BUG: extractSimulPatterns() FAILED *****");
return null;
......@@ -11554,6 +11599,9 @@ error=Sum(W(x,y)*(F^2 + 2*F*(A*x^2+B*y^2+C*x*y+D*x+E*y-Z(x,y)) +(...) )
// additionally multiply by Hamming
public int FFTSize;
public int FFTSize_lwir;
public int FFTOverlap; // 32 used for aberration kernels, former FFT_OVERLAP
public int FFTOverlap_lwir; // 4
public double fftGaussWidth;
public double phaseCorrelationFraction=1.0; // 1.0 - phase correlation, 0.0 - just cross-correlation
public double correlationHighPassSigma;
......@@ -11628,6 +11676,8 @@ error=Sum(W(x,y)*(F^2 + 2*F*(A*x^2+B*y^2+C*x*y+D*x+E*y-Z(x,y)) +(...) )
int zeros,
int FFTSize,
int FFTSize_lwir,
int FFTOverlap,
int FFTOverlap_lwir,
double fftGaussWidth,
double phaseCorrelationFraction,
double correlationHighPassSigma,
......@@ -11695,6 +11745,8 @@ error=Sum(W(x,y)*(F^2 + 2*F*(A*x^2+B*y^2+C*x*y+D*x+E*y-Z(x,y)) +(...) )
this.zeros=zeros;
this.FFTSize = FFTSize;
this.FFTSize_lwir = FFTSize_lwir;
this.FFTOverlap = FFTOverlap;
this.FFTOverlap_lwir = FFTOverlap_lwir;
this.fftGaussWidth = fftGaussWidth;
this.phaseCorrelationFraction=phaseCorrelationFraction;
this.correlationHighPassSigma=correlationHighPassSigma;
......@@ -11764,6 +11816,8 @@ error=Sum(W(x,y)*(F^2 + 2*F*(A*x^2+B*y^2+C*x*y+D*x+E*y-Z(x,y)) +(...) )
this.zeros,
this.FFTSize,
this.FFTSize_lwir,
this.FFTOverlap,
this.FFTOverlap_lwir,
this.fftGaussWidth,
this.phaseCorrelationFraction,
this.correlationHighPassSigma,
......@@ -11832,6 +11886,8 @@ error=Sum(W(x,y)*(F^2 + 2*F*(A*x^2+B*y^2+C*x*y+D*x+E*y-Z(x,y)) +(...) )
properties.setProperty(prefix+"zeros",this.zeros+"");
properties.setProperty(prefix+"FFTSize",this.FFTSize+"");
properties.setProperty(prefix+"FFTSize_lwir",this.FFTSize_lwir+"");
properties.setProperty(prefix+"FFTOverlap",this.FFTOverlap+"");
properties.setProperty(prefix+"FFTOverlap_lwir",this.FFTOverlap_lwir+"");
properties.setProperty(prefix+"fftGaussWidth",this.fftGaussWidth+"");
properties.setProperty(prefix+"phaseCorrelationFraction",this.phaseCorrelationFraction+"");
properties.setProperty(prefix+"correlationHighPassSigma",this.correlationHighPassSigma+"");
......@@ -11891,6 +11947,7 @@ error=Sum(W(x,y)*(F^2 + 2*F*(A*x^2+B*y^2+C*x*y+D*x+E*y-Z(x,y)) +(...) )
properties.setProperty(prefix+"legacyMode",this.minUVSpan+"");
}
public void getProperties(String prefix,Properties properties){
// EProperties properties = (EProperties) pproperties;
if (properties.getProperty(prefix+"correlationSize")!=null)
this.correlationSize=Integer.parseInt(properties.getProperty(prefix+"correlationSize"));
if (properties.getProperty(prefix+"correlationSizeLwir")!=null)
......@@ -11905,6 +11962,17 @@ error=Sum(W(x,y)*(F^2 + 2*F*(A*x^2+B*y^2+C*x*y+D*x+E*y-Z(x,y)) +(...) )
this.FFTSize=Integer.parseInt(properties.getProperty(prefix+"FFTSize"));
if (properties.getProperty(prefix+"FFTSize_lwir")!=null)
this.FFTSize_lwir=Integer.parseInt(properties.getProperty(prefix+"FFTSize_lwir"));
if (properties.getProperty(prefix+"FFTOverlap")!=null)
this.FFTOverlap=Integer.parseInt(properties.getProperty(prefix+"FFTOverlap"));
if (properties.getProperty(prefix+"FFTOverlap_lwir")!=null)
this.FFTOverlap_lwir=Integer.parseInt(properties.getProperty(prefix+"FFTOverlap_lwir"));
// finally shortened :
// this.FFTOverlap= properties.getProperty(prefix+"FFTOverlap", this.FFTOverlap);
// this.FFTOverlap_lwir= properties.getProperty(prefix+"FFTOverlap_lwir",this.FFTOverlap_lwir);
if (properties.getProperty(prefix+"absoluteCorrelationGaussWidth")!=null)
this.absoluteCorrelationGaussWidth=Boolean.parseBoolean(properties.getProperty(prefix+"absoluteCorrelationGaussWidth"));
if (properties.getProperty(prefix+"zeros")!=null)
......
......@@ -1009,14 +1009,32 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy)
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) {
return extractSimulMono ( // TODO: can use twice smaller barray
localbArray,
false, // boolean invert,
simulParameters,
outSubdiv, // subdivide output pixels - now 4
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,
boolean invert,
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) {
double pattern_sign = invert? -1.0 : 1.0;
int sampleWidth=(int) (Math.sqrt(simulParameters.fill)*simulParameters.subdiv);
int sampleN=sampleWidth*sampleWidth;
if (sampleWidth<1) sampleWidth=1;
......@@ -1043,7 +1061,7 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy)
return null;
}
}
simul_pixels[iy*size+ix]= (s-sampleAverage)/sampleAverage;
simul_pixels[iy*size+ix]= pattern_sign