Commit 001d0838 authored by Andrey Filippov's avatar Andrey Filippov

Created partial kernel with monochrome (LWIR) sensors

parent 0d69b27b
...@@ -208,13 +208,22 @@ public class Aberration_Calibration extends PlugInFrame implements ActionListene ...@@ -208,13 +208,22 @@ public class Aberration_Calibration extends PlugInFrame implements ActionListene
public static EyesisAberrations.OTFFilterParameters OTF_FILTER = new EyesisAberrations.OTFFilterParameters( 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 0.002, // 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) 1.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) 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.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 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 ( public static MatchSimulatedPattern.PatternDetectParameters PATTERN_DETECT = new MatchSimulatedPattern.PatternDetectParameters (
0.4, // GAUSS_WIDTH= 0.4; //0 - use Hamming window - initWindowFunction() 0.4, // GAUSS_WIDTH= 0.4; //0 - use Hamming window - initWindowFunction()
0.2, // corrGamma - pattern detection: gamma applied to PS 0.2, // corrGamma - pattern detection: gamma applied to PS
...@@ -1185,7 +1194,7 @@ if (MORE_BUTTONS) { ...@@ -1185,7 +1194,7 @@ if (MORE_BUTTONS) {
return; return;
/* ======================================================================== */ /* ======================================================================== */
} else if (label.equals("Conf. OTF Filter")) { } else if (label.equals("Conf. OTF Filter")) {
showOTFFilterParametersDialog(OTF_FILTER); showOTFFilterParametersDialog(OTF_FILTER, OTF_FILTER_LWIR); // second may be null
return; return;
/* ======================================================================== */ /* ======================================================================== */
} else if (label.equals("Conf. Interpolation")) { } else if (label.equals("Conf. Interpolation")) {
...@@ -9168,7 +9177,8 @@ if (MORE_BUTTONS) { ...@@ -9168,7 +9177,8 @@ if (MORE_BUTTONS) {
// FFT_OVERLAP, ////int fft_overlap, // FFT_OVERLAP, ////int fft_overlap,
// FFT_SIZE, //int fft_size, // FFT_SIZE, //int fft_size,
PSF_SUBPIXEL, // //int PSF_subpixel, PSF_SUBPIXEL, // //int PSF_subpixel,
OTF_FILTER, // //OTFFilterParameters otfFilterParameters, OTF_FILTER, // OTFFilterParameters otfFilterParameters,
OTF_FILTER_LWIR, //OTFFilterParameters otfFilterParameters_lwir,
PSF_PARS, //PSFParameters psfParameters, PSF_PARS, //PSFParameters psfParameters,
INVERSE.dSize, //int PSFKernelSize, // size of square used in the new map (should be multiple of map step) INVERSE.dSize, //int PSFKernelSize, // size of square used in the new map (should be multiple of map step)
...@@ -15516,6 +15526,7 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) { ...@@ -15516,6 +15526,7 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) {
boolean select_INVERSE=!select; boolean select_INVERSE=!select;
boolean select_PSF_PARS=!select; boolean select_PSF_PARS=!select;
boolean select_OTF_FILTER=!select; boolean select_OTF_FILTER=!select;
boolean select_OTF_FILTER_LWIR=!select;
boolean select_PATTERN_DETECT=!select; boolean select_PATTERN_DETECT=!select;
boolean select_COMPONENTS=!select; boolean select_COMPONENTS=!select;
boolean select_SHOW_RESULTS=!select; boolean select_SHOW_RESULTS=!select;
...@@ -15557,6 +15568,7 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) { ...@@ -15557,6 +15568,7 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) {
gd.addCheckbox("INVERSE",select_INVERSE); gd.addCheckbox("INVERSE",select_INVERSE);
gd.addCheckbox("PSF_PARS",select_PSF_PARS); gd.addCheckbox("PSF_PARS",select_PSF_PARS);
gd.addCheckbox("OTF_FILTER",select_OTF_FILTER); 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("PATTERN_DETECT",select_PATTERN_DETECT);
gd.addCheckbox("COMPONENTS",select_COMPONENTS); gd.addCheckbox("COMPONENTS",select_COMPONENTS);
gd.addCheckbox("SHOW_RESULTS",select_SHOW_RESULTS); gd.addCheckbox("SHOW_RESULTS",select_SHOW_RESULTS);
...@@ -15599,6 +15611,7 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) { ...@@ -15599,6 +15611,7 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) {
select_INVERSE=gd.getNextBoolean(); select_INVERSE=gd.getNextBoolean();
select_PSF_PARS=gd.getNextBoolean(); select_PSF_PARS=gd.getNextBoolean();
select_OTF_FILTER=gd.getNextBoolean(); select_OTF_FILTER=gd.getNextBoolean();
select_OTF_FILTER_LWIR=gd.getNextBoolean();
select_PATTERN_DETECT=gd.getNextBoolean(); select_PATTERN_DETECT=gd.getNextBoolean();
select_COMPONENTS=gd.getNextBoolean(); select_COMPONENTS=gd.getNextBoolean();
select_SHOW_RESULTS=gd.getNextBoolean(); select_SHOW_RESULTS=gd.getNextBoolean();
...@@ -15639,6 +15652,7 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) { ...@@ -15639,6 +15652,7 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) {
if (select_INVERSE) INVERSE.setProperties( "INVERSE.", properties); if (select_INVERSE) INVERSE.setProperties( "INVERSE.", properties);
if (select_PSF_PARS) PSF_PARS.setProperties( "PSF_PARS.", 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_PATTERN_DETECT) PATTERN_DETECT.setProperties( "PATTERN_DETECT.", properties);
if (select_COMPONENTS) COMPONENTS.setProperties( "COMPONENTS.", properties); if (select_COMPONENTS) COMPONENTS.setProperties( "COMPONENTS.", properties);
if (select_SHOW_RESULTS) SHOW_RESULTS.setProperties( "SHOW_RESULTS.", properties); if (select_SHOW_RESULTS) SHOW_RESULTS.setProperties( "SHOW_RESULTS.", properties);
...@@ -15682,6 +15696,7 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) { ...@@ -15682,6 +15696,7 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) {
INVERSE.getProperties("INVERSE.", properties); INVERSE.getProperties("INVERSE.", properties);
PSF_PARS.getProperties("PSF_PARS.", properties); PSF_PARS.getProperties("PSF_PARS.", properties);
OTF_FILTER.getProperties("OTF_FILTER.", properties); OTF_FILTER.getProperties("OTF_FILTER.", properties);
OTF_FILTER_LWIR.getProperties("OTF_FILTER_LWIR.", properties);
PATTERN_DETECT.getProperties("PATTERN_DETECT.", properties); PATTERN_DETECT.getProperties("PATTERN_DETECT.", properties);
COMPONENTS.getProperties("COMPONENTS.", properties); COMPONENTS.getProperties("COMPONENTS.", properties);
SHOW_RESULTS.getProperties("SHOW_RESULTS.", properties); SHOW_RESULTS.getProperties("SHOW_RESULTS.", properties);
...@@ -20391,13 +20406,29 @@ use the result to create a rejectiobn mask - if the energy was high, (multiplica ...@@ -20391,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 */ /**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"); 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("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 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 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 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 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(); gd.showDialog();
if (gd.wasCanceled()) return false; if (gd.wasCanceled()) return false;
otfFilterParameters.deconvInvert= gd.getNextNumber(); otfFilterParameters.deconvInvert= gd.getNextNumber();
...@@ -20405,6 +20436,13 @@ use the result to create a rejectiobn mask - if the energy was high, (multiplica ...@@ -20405,6 +20436,13 @@ use the result to create a rejectiobn mask - if the energy was high, (multiplica
otfFilterParameters.smoothPS= gd.getNextNumber(); otfFilterParameters.smoothPS= gd.getNextNumber();
otfFilterParameters.thresholdHigh= gd.getNextNumber(); otfFilterParameters.thresholdHigh= gd.getNextNumber();
otfFilterParameters.thresholdLow= 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; return true;
} }
/* ======================================================================== */ /* ======================================================================== */
...@@ -1065,6 +1065,7 @@ public class EyesisAberrations { ...@@ -1065,6 +1065,7 @@ public class EyesisAberrations {
// int fft_size, // int fft_size,
int PSF_subpixel, int PSF_subpixel,
OTFFilterParameters otfFilterParameters, OTFFilterParameters otfFilterParameters,
OTFFilterParameters otfFilterParameters_lwir,
PSFParameters psfParameters, PSFParameters psfParameters,
int PSFKernelSize, // size of square used in the new map (should be multiple of map step) int PSFKernelSize, // size of square used in the new map (should be multiple of map step)
double gaussWidth, // ** NEW double gaussWidth, // ** NEW
...@@ -1291,7 +1292,7 @@ public class EyesisAberrations { ...@@ -1291,7 +1292,7 @@ public class EyesisAberrations {
} }
int rslt=matchSimulatedPattern.calculateDistortions( int rslt=matchSimulatedPattern.calculateDistortions(
null, // LwirReaderParameters lwirReaderParameters, // null is OK lwirReaderParameters, // LwirReaderParameters lwirReaderParameters, // null is OK
distortionParameters, // distortionParameters, //
patternDetectParameters, patternDetectParameters,
// patternDetectParameters.minGridPeriod/2, // patternDetectParameters.minGridPeriod/2,
...@@ -1343,7 +1344,8 @@ public class EyesisAberrations { ...@@ -1343,7 +1344,8 @@ public class EyesisAberrations {
fft_size, // FFT_SIZE, // int fft_size, fft_size, // FFT_SIZE, // int fft_size,
colorComponents, //COMPONENTS, // ColorComponents colorComponents, colorComponents, //COMPONENTS, // ColorComponents colorComponents,
PSF_subpixel, //PSF_SUBPIXEL, // int PSF_subpixel, 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, //PSF_PARS, // final PSFParameters psfParameters
psfParameters.minDefinedArea , //PSF_PARS.minDefinedArea, // final double minDefinedArea, 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) PSFKernelSize, //// int PSFKernelSize, // size of square used in the new map (should be multiple of map step)
...@@ -2163,7 +2165,8 @@ public class EyesisAberrations { ...@@ -2163,7 +2165,8 @@ public class EyesisAberrations {
jp4_instance.encodeProperiesToInfo(impPsf); jp4_instance.encodeProperiesToInfo(impPsf);
FileSaver fs=new FileSaver(impPsf); FileSaver fs=new FileSaver(impPsf);
fs.saveAsTiffStack(path); // fs.saveAsTiffStack(path);
fs.saveAsTiff(path);
} }
...@@ -2176,15 +2179,24 @@ public class EyesisAberrations { ...@@ -2176,15 +2179,24 @@ public class EyesisAberrations {
if (kernels==null) return null; if (kernels==null) return null;
int tilesY=kernels.length; int tilesY=kernels.length;
int tilesX=kernels[0].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; double [][]kernel=null;
for (i=0;(i<tilesY) && (kernel==null);i++) for (j=0;(j<tilesX) && (kernel==null);j++) kernel=kernels[i][j]; for (i=0;(i<tilesY) && (kernel==null);i++) {
if (kernel==null) return null; for (j=0;(j<tilesX) && (kernel==null);j++) {
int length=0; kernel=kernels[i][j];
for (i=0;i<kernel.length;i++) if (kernel[i]!=null){ }
length=kernel[i].length;
break;
} }
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){ if (length==0){
System.out.println("mergeKernelsToStack(): no non-null kernels"); System.out.println("mergeKernelsToStack(): no non-null kernels");
return null; return null;
...@@ -2194,7 +2206,7 @@ public class EyesisAberrations { ...@@ -2194,7 +2206,7 @@ public class EyesisAberrations {
for (i=0;i<tilesY ;i++) for (j=0;j<tilesX;j++) if (kernels[i][j]!=null) { 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) { for (k=0;(k<kernel.length)&& (k<channelsMask.length);k++) if (kernels[i][j][k]!=null) {
channelsMask[k]=1; 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;
} }
} }
...@@ -2268,6 +2280,9 @@ public class EyesisAberrations { ...@@ -2268,6 +2280,9 @@ public class EyesisAberrations {
} }
is_mono |= is_lwir; 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); final boolean debugLateralShifts=(globalDebugLevel>1);
System.out.println("createPSFMap(): masterDebugLevel="+masterDebugLevel+" globalDebugLevel="+globalDebugLevel+" debug_level="+debug_level); // 2 2 0 System.out.println("createPSFMap(): masterDebugLevel="+masterDebugLevel+" globalDebugLevel="+globalDebugLevel+" debug_level="+debug_level); // 2 2 0
final long startTime = System.nanoTime(); final long startTime = System.nanoTime();
...@@ -2349,7 +2364,7 @@ public class EyesisAberrations { ...@@ -2349,7 +2364,7 @@ public class EyesisAberrations {
final double [] overexposed=(overexposedAllowed>0)?JP4_INSTANCE.overexposedMap (imp_sel):null; final double [] overexposed=(overexposedAllowed>0)?JP4_INSTANCE.overexposedMap (imp_sel):null;
final AtomicInteger tilesFinishedAtomic = new AtomicInteger(1); // first finished will be 1 final AtomicInteger tilesFinishedAtomic = new AtomicInteger(1); // first finished will be 1
final int debugNumColors = is_mono? 1 : colorComponents.colorsToCorrect.length; final int debugNumColors = is_mono? 1 : colorComponents.colorsToCorrect.length;
final int dbgTile0 = -1; // 245; // // final int dbgTile0 = 217; // -1; // 245; //
for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) {
// Concurrently run in as many threads as CPUs // Concurrently run in as many threads as CPUs
threads[ithread] = new Thread() { threads[ithread] = new Thread() {
...@@ -2374,7 +2389,9 @@ public class EyesisAberrations { ...@@ -2374,7 +2389,9 @@ public class EyesisAberrations {
SimulationPattern simulationPattern= new SimulationPattern(bitmaskPattern); SimulationPattern simulationPattern= new SimulationPattern(bitmaskPattern);
simulationPattern.debugLevel=globalDebugLevel; simulationPattern.debugLevel=globalDebugLevel;
double [] windowFFTSize= matchSimulatedPattern.initWindowFunction(fft_size,gaussWidth); //=initHamming( fft_size) calculate once 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) DoubleFHT fht_instance =new DoubleFHT(); // provide DoubleFHT instance to save on initializations (or null)
double over; double over;
// individual per-thread - will be needed when converted to doubleFHT // individual per-thread - will be needed when converted to doubleFHT
...@@ -2384,7 +2401,8 @@ public class EyesisAberrations { ...@@ -2384,7 +2401,8 @@ public class EyesisAberrations {
nTY=tilesToProcessXY[nTile][1]; nTY=tilesToProcessXY[nTile][1];
y0=tilesToProcessXY[nTile][3]; y0=tilesToProcessXY[nTile][3];
x0=tilesToProcessXY[nTile][2]; 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)); 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 (updateStatus) IJ.showStatus("Processing tile["+nTY+"]["+nTX+"] ("+(nTile+1)+" of "+patternCells+")");
...@@ -2412,7 +2430,7 @@ public class EyesisAberrations { ...@@ -2412,7 +2430,7 @@ public class EyesisAberrations {
tile_size, // 2*fft_size, // size in pixels (twice fft_size for Bayer only?) tile_size, // 2*fft_size, // size in pixels (twice fft_size for Bayer only?)
x0, // top left corner X (pixels) x0, // top left corner X (pixels)
y0, // top left corner Y (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, matchSimulatedPattern,
patternDetectParameters, patternDetectParameters,
windowFFTSize, //=initHamming( fft_size) calculate once windowFFTSize, //=initHamming( fft_size) calculate once
...@@ -2425,14 +2443,18 @@ public class EyesisAberrations { ...@@ -2425,14 +2443,18 @@ public class EyesisAberrations {
psfParameters, psfParameters,
fht_instance, // provide DoubleFHT instance to save on initializations (or null) fht_instance, // provide DoubleFHT instance to save on initializations (or null)
debug_level,// ((x0<512)&& (y0<512))?3:debug_level DEBUG during "focusing" debug_level,// ((x0<512)&& (y0<512))?3:debug_level DEBUG during "focusing"
masterDebugLevel, // get rid of it? // ** NEW masterDebugLevel+ (debugThis? 3:0), // get rid of it? // ** NEW
globalDebugLevel + ((nTile == dbgTile0)? 3:0),// ** NEW globalDebugLevel + (debugThis? 3:0),// ** NEW
debugLateralShifts?debugLateral[nTY][nTX]:null debugLateralShifts?debugLateral[nTY][nTX] : null
); );
if (kernels!=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 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){ for (nChn=0;nChn<kernels.length;nChn++) if (kernels[nChn]!=null){
pdfKernelMap[nTY][nTX][nChn]=kernels[nChn]; // not .clone()? pdfKernelMap[nTY][nTX][nChn]=kernels[nChn]; // not .clone()?
} }
...@@ -2688,7 +2710,7 @@ public class EyesisAberrations { ...@@ -2688,7 +2710,7 @@ public class EyesisAberrations {
MatchSimulatedPattern matchSimulatedPattern, MatchSimulatedPattern matchSimulatedPattern,
MatchSimulatedPattern.PatternDetectParameters patternDetectParameters, MatchSimulatedPattern.PatternDetectParameters patternDetectParameters,
double [] Hamming, //=initHamming( fft_size) calculate once double [] Hamming, //=initHamming( fft_size) calculate once
double [] fullHamming, //=initHamming( fft_size*subpixel); double [] fullHamming, //=initHamming( fft_size*subpixel); for mono - twice smaller !
int subpixel, // use finer grid than actual pixels int subpixel, // use finer grid than actual pixels
SimulationPattern.SimulParameters simulParameters, SimulationPattern.SimulParameters simulParameters,
EyesisAberrations.ColorComponents colorComponents, EyesisAberrations.ColorComponents colorComponents,
...@@ -2701,7 +2723,7 @@ public class EyesisAberrations { ...@@ -2701,7 +2723,7 @@ public class EyesisAberrations {
int debug, int debug,
double [][] debugLateralTile 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){ if (globalDebugLevel>1){
System.out.println("getPSFKernels(), simArray is "+((simArray==null)?"":"not ")+"null"); System.out.println("getPSFKernels(), simArray is "+((simArray==null)?"":"not ")+"null");
} }
...@@ -2711,6 +2733,7 @@ public class EyesisAberrations { ...@@ -2711,6 +2733,7 @@ public class EyesisAberrations {
boolean is_lwir = ((lwirReaderParameters != null) && lwirReaderParameters.is_LWIR(imp)); boolean is_lwir = ((lwirReaderParameters != null) && lwirReaderParameters.is_LWIR(imp));
boolean is_mono = false; boolean is_mono = false;
boolean invert_pattern = is_lwir;
try { try {
is_mono = Boolean.parseBoolean((String) imp.getProperty("MONOCHROME")); is_mono = Boolean.parseBoolean((String) imp.getProperty("MONOCHROME"));
} catch (Exception e) { } catch (Exception e) {
...@@ -2719,7 +2742,8 @@ public class EyesisAberrations { ...@@ -2719,7 +2742,8 @@ public class EyesisAberrations {
is_mono |= is_lwir; is_mono |= is_lwir;
if (is_mono) referenceComp = 0; // if (is_mono) referenceComp = 0; //
int fft_size=is_mono ? tile_size : (tile_size/2); 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 ( Rectangle PSFCell=new Rectangle (
x0, x0,
...@@ -2765,7 +2789,7 @@ public class EyesisAberrations { ...@@ -2765,7 +2789,7 @@ public class EyesisAberrations {
patternDetectParameters, patternDetectParameters,
min_half_period, // patternDetectParameters.minGridPeriod/2, min_half_period, // patternDetectParameters.minGridPeriod/2,
max_half_period, // patternDetectParameters.maxGridPeriod/2, max_half_period, // patternDetectParameters.maxGridPeriod/2,
true, //(greensToProcess==4), // boolean greens, // this is a pattern for combined greens (diagonal), adjust results accordingly (!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 title); // title prefix to use for debug images
if (distortedPattern==null) return null; if (distortedPattern==null) return null;
...@@ -2779,7 +2803,6 @@ public class EyesisAberrations { ...@@ -2779,7 +2803,6 @@ public class EyesisAberrations {
" W1_phase="+IJ.d2s(distortedPattern[1][2],2)); " W1_phase="+IJ.d2s(distortedPattern[1][2],2));
} }
// simulationPattern.simulatePatternFullPattern( // Not thread safe!
localBarray=simulationPattern.simulatePatternFullPatternSafe( localBarray=simulationPattern.simulatePatternFullPatternSafe(
distortedPattern[0][0], distortedPattern[0][0],
distortedPattern[0][1], distortedPattern[0][1],
...@@ -2789,7 +2812,7 @@ public class EyesisAberrations { ...@@ -2789,7 +2812,7 @@ public class EyesisAberrations {
distortedPattern[1][2], distortedPattern[1][2],
distortedPattern[2], // distortedPattern[2], //
simulParameters.subdiv, simulParameters.subdiv,
fft_size, fft_size, // FIXME?
simulParameters.center_for_g2, simulParameters.center_for_g2,
false);//boolean mono false);//boolean mono
wVectors[0][0]=2.0*distortedPattern[0][0]/subpixel; wVectors[0][0]=2.0*distortedPattern[0][0]/subpixel;
...@@ -2831,17 +2854,19 @@ public class EyesisAberrations { ...@@ -2831,17 +2854,19 @@ public class EyesisAberrations {
phases[1], phases[1],
simCorr, // simCorr, //
simulParameters.subdiv, simulParameters.subdiv,
fft_size, fft_size, // FIXME!
simulParameters.center_for_g2, simulParameters.center_for_g2,
false);//boolean mono false);//boolean mono
} }
if (is_mono) { if (is_mono) {
simul_pixels= new double[1][]; 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 simul_pixels[0]= simulationPattern.extractSimulMono ( // TODO: can use twice smaller barray
localBarray, localBarray,
invert_pattern,
simulParameters, simulParameters,
1, // subdivide output pixels - now 4 subpixel, // 1, // subdivide output pixels - now 4
fft_size*subpixel, // number of Bayer cells in width of the square selection (half number of pixels) 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, // selection center, X (in pixels)
0); 0);
} else { } else {
...@@ -2849,10 +2874,9 @@ public class EyesisAberrations { ...@@ -2849,10 +2874,9 @@ public class EyesisAberrations {
localBarray, // this version is thread safe localBarray, // this version is thread safe
simulParameters, simulParameters,
subpixel, // subdivide pixels subpixel, // subdivide pixels
fft_size*subpixel, // number of Bayer cells in width of the square selection (half number of 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, X (in pixels)
0.0); // selection center, y (in pixels) 0.0); // selection center, y (in pixels)
}
if (subpixel>1) { if (subpixel>1) {
if (colorComponents.colorsToCorrect[5]) simul_pixels=combineCheckerGreens (simul_pixels, // pixel arrays after oversampleFFTInput() or extractSimulPatterns()) if (colorComponents.colorsToCorrect[5]) simul_pixels=combineCheckerGreens (simul_pixels, // pixel arrays after oversampleFFTInput() or extractSimulPatterns())
subpixel); // same as used in oversampleFFTInput() - oversampling ratio subpixel); // same as used in oversampleFFTInput() - oversampling ratio
...@@ -2860,22 +2884,24 @@ public class EyesisAberrations { ...@@ -2860,22 +2884,24 @@ public class EyesisAberrations {
for (i=0;i<simul_pixels.length; i++) { for (i=0;i<simul_pixels.length; i++) {
if (!colorComponents.colorsToCorrect[i]) simul_pixels[i]=null; // removed unused if (!colorComponents.colorsToCorrect[i]) simul_pixels[i]=null; // removed unused
} }
}
simul_pixels= normalizeAndWindow (simul_pixels, fullHamming); simul_pixels= normalizeAndWindow (simul_pixels, fullHamming);
} else { //if ((simArray==null) || (psfParameters.approximateGrid)){ // just for testing(never here?) } else { //if ((simArray==null) || (psfParameters.approximateGrid)){ // never above?
Rectangle PSFCellSim = new Rectangle ( Rectangle PSFCellSim = new Rectangle (
x0 * subpixel/2, x0 * subpixel/2,
y0 * subpixel/2, y0 * subpixel/2,
tile_size * subpixel/2, tile_size * subpixel/2,
tile_size * subpixel/2); // getting here tile_size * subpixel/2); // getting here
if (is_mono) { if (is_mono) {
//FIXME: Somewhere need to invert color for LWIR
simul_pixels=new double[1][]; simul_pixels=new double[1][];
simul_pixels[0]=simulationPattern.extractBayerSim ( simul_pixels[0]=simulationPattern.extractBayerSim ( // works with mono now
simArray, // [0] - regular pixels, [1] - shifted by 1/2 diagonally, for checker greens simArray, // [0] - regular pixels, [1] - shifted by 1/2 diagonally, for checker greens
imgWidth*subpixel/2, imgWidth*subpixel/2,
PSFCellSim, PSFCellSim,
subpixel, // 4 subpixel, // 4
-1); //New : -1 - extract mono TODO: see if 1/2pix shift is needed (invert_pattern? -2: -1)); //New : -1 - extract mono TODO: see if 1/2pix shift is needed
} else { } else {
simul_pixels=new double[6][]; simul_pixels=new double[6][];
for (i=0;i<simul_pixels.length; i++) { for (i=0;i<simul_pixels.length; i++) {
...@@ -2918,9 +2944,13 @@ public class EyesisAberrations { ...@@ -2918,9 +2944,13 @@ public class EyesisAberrations {
wVectors[1]=matchSimulatedPattern.getDArray(iUV[1],iUV[0],2); wVectors[1]=matchSimulatedPattern.getDArray(iUV[1],iUV[0],2);
// should it be averaged WV? // should it be averaged WV?
if (globalDebugLevel>2) System.out.println ( " x0="+x0+" y0="+y0); if (debugThis || (globalDebugLevel>2)) System.out.println ( " x0="+x0+" y0="+y0);
if (globalDebugLevel>2) SDFA_INSTANCE.showArrays(input_bayer_or_mono, true, title+"-in"); if (debugThis || (globalDebugLevel>2)) {
if (globalDebugLevel>2) SDFA_INSTANCE.showArrays(simul_pixels, true, title+"-S"); 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){ if (masterDebugLevel>1){
dbgSimPix=new double[simul_pixels.length][]; dbgSimPix=new double[simul_pixels.length][];
...@@ -2933,28 +2963,42 @@ public class EyesisAberrations { ...@@ -2933,28 +2963,42 @@ public class EyesisAberrations {
} }
input_bayer_or_mono= normalizeAndWindow (input_bayer_or_mono, 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) { if (subpixel>1) {
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); 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()) 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 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 for (i=0;i<4;i++) if (!colorComponents.colorsToCorrect[i]) input_bayer_or_mono[i]=null; // leave composite greens even if disabled
}
if (debugThis) { if (debugThis) {
// SDFA_INSTANCE.showArrays(input_bayer, fft_size*subpixel, fft_size*subpixel, title); // 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+" fft_size*subpixel="+fft_size*subpixel); 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)){ 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); if (globalDebugLevel>2) System.out.println ( "input_bayer["+i+"].length="+input_bayer_or_mono[i].length+" simul_pixels["+i+"].length="+simul_pixels[i].length);
} }
if (debugThis) SDFA_INSTANCE.showArrays(input_bayer_or_mono, true, title+"-input"); if (debugThis) {
if (debugThis) SDFA_INSTANCE.showArrays(simul_pixels, true, title+"-SIM"); SDFA_INSTANCE.showArrays(input_bayer_or_mono, true, title+"-input");
}
if (debugThis) {
SDFA_INSTANCE.showArrays(simul_pixels, true, title+"-SIM");
}
//if (globalDebugLevel>2)globalDebugLevel=0; //************************************************************ //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]+ 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])); wVectors[1][0]*wVectors[1][0]+wVectors[1][1]*wVectors[1][1]));
...@@ -2965,10 +3009,10 @@ public class EyesisAberrations { ...@@ -2965,10 +3009,10 @@ public class EyesisAberrations {
inverted[i]=limitedInverseOfFHT( inverted[i]=limitedInverseOfFHT(
input_bayer_or_mono[i], input_bayer_or_mono[i],
simul_pixels[i], simul_pixels[i],
fft_size*subpixel, full_fft_size, // fft_size*subpixel,
(i==5), // boolean checker // checkerboard pattern in the source file (use when filtering) (i==5), // boolean checker // checkerboard pattern in the source file (use when filtering)
true, // forwardOTF, true, // forwardOTF,
subpixel, (subpixel / (is_mono? 2 : 1)),
otfFilterParameters, otfFilterParameters,
fht_instance, fht_instance,
psfParameters.mask1_sigma * (fft_size * 2) * wvAverage, // normalize to wave vectors! psfParameters.mask1_sigma * (fft_size * 2) * wvAverage, // normalize to wave vectors!
...@@ -2976,12 +3020,14 @@ public class EyesisAberrations { ...@@ -2976,12 +3020,14 @@ public class EyesisAberrations {
psfParameters.gaps_sigma * (fft_size * 2) * wvAverage, // normalize to wave vectors! psfParameters.gaps_sigma * (fft_size * 2) * wvAverage, // normalize to wave vectors!
psfParameters.mask_denoise, psfParameters.mask_denoise,
debug, debug,
globalDebugLevel, (globalDebugLevel + (debugThis? 3:0)),
title+"-"+i); title+"-"+i);
} }
} }
int debugThreshold=1; 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 */ /* correct composite greens */
/* Here we divide wave vectors by subpixel as the pixels are already added */ /* Here we divide wave vectors by subpixel as the pixels are already added */
double [][] wVrotMatrix= {{0.5,0.5},{-0.5,0.5}}; double [][] wVrotMatrix= {{0.5,0.5},{-0.5,0.5}};
...@@ -3000,7 +3046,7 @@ public class EyesisAberrations { ...@@ -3000,7 +3046,7 @@ public class EyesisAberrations {
double [] lateralChromaticAbs = new double [input_bayer_or_mono.length]; double [] lateralChromaticAbs = new double [input_bayer_or_mono.length];
double [] zeroVector={0.0,0.0}; double [] zeroVector={0.0,0.0};
for (i=input_bayer_or_mono.length-1;i>=0;i--) { for (i=input_bayer_or_mono.length-1;i>=0;i--) {
if (colorComponents.colorsToCorrect[i]) { if (is_mono || colorComponents.colorsToCorrect[i]) {
PSF_shifts[i]= zeroVector.clone(); PSF_shifts[i]= zeroVector.clone();
PSF_centroids[i]= zeroVector.clone(); PSF_centroids[i]= zeroVector.clone();
lateralChromatic[i]= zeroVector.clone(); lateralChromatic[i]= zeroVector.clone();
...@@ -3127,7 +3173,9 @@ public class EyesisAberrations { ...@@ -3127,7 +3173,9 @@ public class EyesisAberrations {
debugSize=(int)Math.sqrt(kernels[ii].length); debugSize=(int)Math.sqrt(kernels[ii].length);
break; 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; return kernels;
} }
...@@ -3183,7 +3231,8 @@ public class EyesisAberrations { ...@@ -3183,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) double [] modelPixels, // simulated (model) pixel array)
int size, // FFT size int size, // FFT size
boolean checker, // checkerboard pattern in the source file (use when filtering) boolean checker, // checkerboard pattern in the source file (use when filtering)
...@@ -3198,7 +3247,8 @@ public class EyesisAberrations { ...@@ -3198,7 +3247,8 @@ public class EyesisAberrations {
int debug, int debug,
int globalDebugLevel, int globalDebugLevel,
String title){ // title base for optional plots names String title){ // title base for optional plots names
return limitedInverseOfFHT(measuredPixels, return limitedInverseOfFHT(
measuredPixels,
modelPixels, modelPixels,
size, size,
checker, checker,
...@@ -3369,11 +3419,20 @@ public class EyesisAberrations { ...@@ -3369,11 +3419,20 @@ public class EyesisAberrations {
double threshold_low, // leave intact if energy is below this part of maximal double threshold_low, // leave intact if energy is below this part of maximal
DoubleFHT fht_instance, DoubleFHT fht_instance,
int globalDebugLevel){ // provide DoubleFHT instance to save on initializations (or null) 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 length=fht.length;
int size=(int) Math.sqrt(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]; // double [][] ps=new double [size/2+1][size];
int i,ix,iy, cloneNx, cloneNy, cloneX, cloneY; int i,ix,iy, cloneNx, cloneNy, cloneX, cloneY;
int cloneStep=size/oversample; int cloneStep=size/oversample;
...@@ -3384,7 +3443,9 @@ public class EyesisAberrations { ...@@ -3384,7 +3443,9 @@ public class EyesisAberrations {
for (i=0;i<length; i++) if (psMax<ps[i]) psMax=ps[i]; for (i=0;i<length; i++) if (psMax<ps[i]) psMax=ps[i];
double k=1.0/psMax; double k=1.0/psMax;
for (i=0;i<length; i++) ps[i]*=k; 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) */ /* Add maximum at (0,0) */
double [] psWithZero=ps; double [] psWithZero=ps;
if (zerofreq_size>0.0) { if (zerofreq_size>0.0) {
...@@ -3412,11 +3473,15 @@ public class EyesisAberrations { ...@@ -3412,11 +3473,15 @@ public class EyesisAberrations {
} }
} }
/* debug show the mask */ /* 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) { if (sigma>0) {
DoubleGaussianBlur gb = new DoubleGaussianBlur(); DoubleGaussianBlur gb = new DoubleGaussianBlur();
gb.blurDouble(mask,size,size,sigma,sigma, 0.01); 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 */ /* make mask of cloned power spectrums */
...@@ -3437,7 +3502,9 @@ public class EyesisAberrations { ...@@ -3437,7 +3502,9 @@ public class EyesisAberrations {
mask[i]*=ps[i]/(ps[i]+k2); 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 */ /* zeros are now for FHT - in the top left corner */
fht_instance.swapQuadrants(mask); fht_instance.swapQuadrants(mask);
return mask; return mask;
...@@ -3509,6 +3576,9 @@ public class EyesisAberrations { ...@@ -3509,6 +3576,9 @@ public class EyesisAberrations {
int debugLevel) int debugLevel)
{ {
if (pixels==null) return null; if (pixels==null) return null;
// if (centroid_xy == null) {
// return null; // debugging LWIR, never before
// }
// double [] contrastCache=new double[pixelSize*pixelSize]; // double [] contrastCache=new double[pixelSize*pixelSize];
int i,j; int i,j;
...@@ -4251,7 +4321,11 @@ public class EyesisAberrations { ...@@ -4251,7 +4321,11 @@ public class EyesisAberrations {
else listIndex++; // increase list index else listIndex++; // increase list index
} }
if (maxValue==0.0) { // Should 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; break;
} }
/* Add this new point to the list */ /* Add this new point to the list */
......
...@@ -4807,8 +4807,6 @@ public class MatchSimulatedPattern { ...@@ -4807,8 +4807,6 @@ public class MatchSimulatedPattern {
} }
} }
// if (nowDebugCell)correctedPatternCrossLocationAverage4(
double [] centerXY=correctedPatternCrossLocation( double [] centerXY=correctedPatternCrossLocation(
lwirReaderParameters, // LwirReaderParameters lwirReaderParameters, // null is OK lwirReaderParameters, // LwirReaderParameters lwirReaderParameters, // null is OK
patternGrid[iUV[1]][iUV[0]][0], // initial coordinates of the pattern cross point patternGrid[iUV[1]][iUV[0]][0], // initial coordinates of the pattern cross point
......
...@@ -1009,14 +1009,32 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy) ...@@ -1009,14 +1009,32 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy)
y0); 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 public double [] extractSimulMono ( // TODO: can use twice smaller barray
double [] localbArray, double [] localbArray,
boolean invert,
SimulParameters simulParameters, SimulParameters simulParameters,
int outSubdiv, // subdivide output pixels - now 4 int outSubdiv, // subdivide output pixels - now 4
int size, // number of Bayer cells in width of the square selection (half number of 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 x0, // selection center, X (in pixels)
double y0) { double y0) {
double pattern_sign = invert? -1.0 : 1.0;
int sampleWidth=(int) (Math.sqrt(simulParameters.fill)*simulParameters.subdiv); int sampleWidth=(int) (Math.sqrt(simulParameters.fill)*simulParameters.subdiv);
int sampleN=sampleWidth*sampleWidth; int sampleN=sampleWidth*sampleWidth;
if (sampleWidth<1) sampleWidth=1; if (sampleWidth<1) sampleWidth=1;
...@@ -1043,7 +1061,7 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy) ...@@ -1043,7 +1061,7 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy)
return null; return null;
} }
} }
simul_pixels[iy*size+ix]= (s-sampleAverage)/sampleAverage; simul_pixels[iy*size+ix]= pattern_sign * (s - sampleAverage) / sampleAverage;
} }
} }
if (this.debugLevel>2) { if (this.debugLevel>2) {
...@@ -1069,6 +1087,7 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy) ...@@ -1069,6 +1087,7 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy)
return rslt; return rslt;
} }
// colorComp == -1 = mono, positive, colorComp == -2 - mono, negative
public double[] extractBayerSim ( public double[] extractBayerSim (
float [][] spixels, // [0] - regular pixels, [1] - shifted by 1/2 diagonally, for checker greens float [][] spixels, // [0] - regular pixels, [1] - shifted by 1/2 diagonally, for checker greens
int full_width, int full_width,
...@@ -1106,6 +1125,7 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy) ...@@ -1106,6 +1125,7 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy)
} }
} else { // components 0..3 } else { // components 0..3
int ser; int ser;
double pattern_sign = (colorComp == -2)? -1.0: 1.0;
if (colorComp < 0) { if (colorComp < 0) {
ser = 1; // offset by 1/2 pix? should it be so? // FIXME: verify and fix if needed - compare to extractSimulMono() ser = 1; // offset by 1/2 pix? should it be so? // FIXME: verify and fix if needed - compare to extractSimulMono()
} else { } else {
...@@ -1125,7 +1145,7 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy) ...@@ -1125,7 +1145,7 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy)
else if (iy >= full_height) iy = full_height - 1; else if (iy >= full_height) iy = full_height - 1;
if (ix < 0) ix = 0; if (ix < 0) ix = 0;
else if (ix >= full_width) iy = full_width - 1; else if (ix >= full_width) iy = full_width - 1;
result[index] = spixels[ser][iy * full_width + ix]; result[index] = pattern_sign * spixels[ser][iy * full_width + ix];
} }
} }
return result; return result;
......
...@@ -171,7 +171,7 @@ public class DoubleGaussianBlur { ...@@ -171,7 +171,7 @@ public class DoubleGaussianBlur {
if (kRadius > maxRadius) kRadius = maxRadius; if (kRadius > maxRadius) kRadius = maxRadius;
double[][] kernel = new double[2][kRadius]; double[][] kernel = new double[2][kRadius];
for (int i=0; i<kRadius; i++) // Gaussian function for (int i=0; i<kRadius; i++) // Gaussian function
kernel[0][i] = (double)(Math.exp(-0.5*i*i/sigma/sigma)); kernel[0][i] = (Math.exp(-0.5*i*i/sigma/sigma));
if (kRadius < maxRadius && kRadius > 3) { // edge correction if (kRadius < maxRadius && kRadius > 3) { // edge correction
double sqrtSlope = Double.MAX_VALUE; double sqrtSlope = Double.MAX_VALUE;
int r = kRadius; int r = kRadius;
...@@ -184,7 +184,7 @@ public class DoubleGaussianBlur { ...@@ -184,7 +184,7 @@ public class DoubleGaussianBlur {
break; break;
} }
for (int r1 = r+2; r1 < kRadius; r1++) for (int r1 = r+2; r1 < kRadius; r1++)
kernel[0][r1] = (double)((kRadius-r1)*(kRadius-r1)*sqrtSlope*sqrtSlope); kernel[0][r1] = (kRadius-r1)*(kRadius-r1)*sqrtSlope*sqrtSlope;
} }
double sum; // sum over all kernel elements for normalization double sum; // sum over all kernel elements for normalization
if (kRadius < maxRadius) { if (kRadius < maxRadius) {
...@@ -197,9 +197,9 @@ public class DoubleGaussianBlur { ...@@ -197,9 +197,9 @@ public class DoubleGaussianBlur {
double rsum = 0.5 + 0.5*kernel[0][0]/sum; double rsum = 0.5 + 0.5*kernel[0][0]/sum;
for (int i=0; i<kRadius; i++) { for (int i=0; i<kRadius; i++) {
double v = (kernel[0][i]/sum); double v = (kernel[0][i]/sum);
kernel[0][i] = (double)v; kernel[0][i] = v;
rsum -= v; rsum -= v;
kernel[1][i] = (double)rsum; kernel[1][i] = rsum;
//IJ.log("k["+i+"]="+(float)v+" sum="+(float)rsum); //IJ.log("k["+i+"]="+(float)v+" sum="+(float)rsum);
} }
return kernel; return kernel;
...@@ -213,6 +213,10 @@ public class DoubleGaussianBlur { ...@@ -213,6 +213,10 @@ public class DoubleGaussianBlur {
*/ */
void downscaleLine(double[] pixels, double[] cache, double[] kernel, void downscaleLine(double[] pixels, double[] cache, double[] kernel,
int reduceBy, int pixel0, int unscaled0, int length, int pointInc, int newLength) { int reduceBy, int pixel0, int unscaled0, int length, int pointInc, int newLength) {
if (pixel0 > pixels.length) {
System.out.println("++++++ Error in DoubleGaussianBlur, pixel0="+pixel0+", pixels.length="+(pixels.length));
return;
}
double first = pixels[pixel0]; double first = pixels[pixel0];
double last = pixels[pixel0 + pointInc*(length-1)]; double last = pixels[pixel0 + pointInc*(length-1)];
int xin = unscaled0 - reduceBy/2; int xin = unscaled0 - reduceBy/2;
...@@ -241,13 +245,13 @@ public class DoubleGaussianBlur { ...@@ -241,13 +245,13 @@ public class DoubleGaussianBlur {
double[] kernel = new double[3*unitLength]; double[] kernel = new double[3*unitLength];
for (int i=0; i<=unitLength/2; i++) { for (int i=0; i<=unitLength/2; i++) {
double x = i/(double)unitLength; double x = i/(double)unitLength;
double v = (double)((0.75-x*x)/unitLength); double v = (0.75-x*x)/unitLength;
kernel[mid-i] = v; kernel[mid-i] = v;
kernel[mid+i] = v; kernel[mid+i] = v;
} }
for (int i=unitLength/2+1; i<(unitLength*3+1)/2; i++) { for (int i=unitLength/2+1; i<(unitLength*3+1)/2; i++) {
double x = i/(double)unitLength; double x = i/(double)unitLength;
double v = (double)((0.125 + 0.5*(x-1)*(x-2))/unitLength); double v = (0.125 + 0.5*(x-1)*(x-2))/unitLength;
kernel[mid-i] = v; kernel[mid-i] = v;
kernel[mid+i] = v; kernel[mid+i] = v;
} }
...@@ -284,13 +288,13 @@ public class DoubleGaussianBlur { ...@@ -284,13 +288,13 @@ public class DoubleGaussianBlur {
kernel[0] = 0; kernel[0] = 0;
for (int i=0; i<unitLength; i++) { for (int i=0; i<unitLength; i++) {
double x = i/(double)unitLength; double x = i/(double)unitLength;
double v = (double)((2./3. -x*x*(1-0.5*x))); double v = ((2./3. -x*x*(1-0.5*x)));
kernel[mid+i] = v; kernel[mid+i] = v;
kernel[mid-i] = v; kernel[mid-i] = v;
} }
for (int i=unitLength; i<2*unitLength; i++) { for (int i=unitLength; i<2*unitLength; i++) {
double x = i/(double)unitLength; double x = i/(double)unitLength;
double v = (double)((2.-x)*(2.-x)*(2.-x)/6.); double v = (2.-x)*(2.-x)*(2.-x)/6.;
kernel[mid+i] = v; kernel[mid+i] = v;
kernel[mid-i] = v; kernel[mid-i] = v;
} }
......
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