Commit 9230dca4 authored by Andrey Filippov's avatar Andrey Filippov

improving residual sensor correction

parent aa2f8dcb
......@@ -510,6 +510,10 @@ public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSi
2, //int shrinkGridForMask=2; //shrink detected grids by one point for/vert this number of times before calculating masks
-2.0, // double maskBlurSigma= 2.0; // blur sensor masks (>0 - pixels, <0 - in grid units)
4, // int decimateMasks
true, // replaceBad - remove bad, do not try to fix
false, // removeWorst - when removing, remove only local worst (false - all bad)
0.3, // public double weightBad = 0.3; // reduce contrast of bad nodes
0.05, // public double weightWorst = 0.05; // reduce contrast of bad, local worst nodes
0.1, // double badNodeThreshold=0.1; // filter out grid nodes with difference from quadratically predicted from 8 neighbors in pixels
1, // int maxBadNeighb; // maximal number of bad nodes around the corrected one to fix
10, // int minimalValidNodes
......@@ -517,6 +521,7 @@ public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSi
1.0, // public double weightMultiExponent= 1.0; // if( >0) use grid diameter to scale weights of this image
1.0, // public double weightDiameterExponent=1.0;
1.0, // public double weightYtoX=1.0; // relative Y-to-X errors weight (to somewhat compensate for rectabular shape of the sensor)
0.2, // public double gridMarginScale = 0.2; // apply -scaled maximal to grid margins (_extra) for masks
0.4, //minimalGridContrast
4.0, // public double shrinkBlurSigma = 4.0;
0.5, // public double shrinkBlurLevel = 0.5;
......@@ -582,7 +587,7 @@ public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSi
1 // public int debugLevel=1;
);
public static Distortions.RefineParameters REFINE_PARAMETERS = new Distortions.RefineParameters();
public static RefineParameters REFINE_PARAMETERS = new RefineParameters();
public static DistortionCalibrationData DISTORTION_CALIBRATION_DATA=null;
// public static FittingStrategy FITTING_STRATEGY=null;
......@@ -837,7 +842,7 @@ public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSi
addButton("Reset Sensor",panelCorrectGrid,color_bundle);
addButton("Restore Sensor",panelCorrectGrid,color_restore);
if (MORE_BUTTONS1) addButton("Correct Sensor Old",panelCorrectGrid,color_process);
// if (MORE_BUTTONS1) addButton("Correct Sensor Old",panelCorrectGrid,color_process);
addButton("Correct Sensor",panelCorrectGrid,color_process);
addButton("Save Sensor",panelCorrectGrid,color_bundle);
// addButton("TestIpl",panelCorrectGrid);
......@@ -2863,8 +2868,39 @@ if (MORE_BUTTONS) {
return;
}
LENS_DISTORTIONS.debugLevel=DEBUG_LEVEL;
LENS_DISTORTIONS.resetSensorCorrection();
LENS_DISTORTIONS.initSensorCorrection(); // set zero corrections (to be able to save sensor correction files)
int numChannels=LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.getNumChannels(); // number of used channels
boolean [] selection=new boolean[numChannels];
for (int i = 0; i < numChannels; i++) {
selection[i] = true;
}
while (true) {
GenericDialog gd = new GenericDialog("Select sensors to reset");
for (int i=0;i<numChannels;i++) gd.addCheckbox("channel "+i, selection[i]);
gd.enableYesNoCancel("OK", "All like channel 0");
WindowTools.addScrollBars(gd);
gd.showDialog();
if (gd.wasCanceled()) return;
for (int i=0;i<numChannels;i++) selection[i]=gd.getNextBoolean();
if (gd.wasOKed()){
break;
} else {
for (int i=1;i<numChannels;i++) selection[i]=selection[0];
}
}
// are all selected?
boolean all_selected = true;
for (boolean s : selection) all_selected &= s;
if (all_selected) {
LENS_DISTORTIONS.resetSensorCorrection();
LENS_DISTORTIONS.initSensorCorrection(); // set zero corrections (to be able to save sensor correction files)
} else {
for (int chNum = 0; chNum < numChannels; chNum++) if (selection[chNum]){
LENS_DISTORTIONS.resetSensorCorrection(chNum);
LENS_DISTORTIONS.initSensorCorrection(chNum);
}
}
return;
}
/* ======================================================================== */
......@@ -2911,36 +2947,7 @@ if (MORE_BUTTONS) {
return;
}
/* ======================================================================== */
if (label.equals("Correct Sensor Old")) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
if (LENS_DISTORTIONS==null) {
IJ.showMessage("LENS_DISTORTION is not set");
return;
}
LENS_DISTORTIONS.debugLevel=DEBUG_LEVEL;
PATTERN_PARAMETERS.debugLevel=DEBUG_LEVEL;
if (LENS_DISTORTIONS.fittingStrategy==null){
IJ.showMessage("Distortion Fitting strategy is not initialized - create it with" +
"\"New Strategy\", \"Edit Strategy\" or \"Restore Strategy\"");
return;
}
if (DISTORTION_CALIBRATION_DATA==null){
IJ.showMessage("Distortion Calibration data is not initialized - create it with"+
"\"SelectGrid Files\" or \"Restore Calibration\"");
return;
}
DISTORTION_CALIBRATION_DATA.debugLevel=DEBUG_LEVEL;
LENS_DISTORTIONS.fittingStrategy.debugLevel=DEBUG_LEVEL;
/*
if (DISTORTION_CALIBRATION_DATA.sensorMasks==null){
IJ.showMessage("Sensor mask(s) are not initialized - create them with"+
"\"Calculate Sensor Masks\" or \"Restore Sensor Masks\"");
return;
}
*/
LENS_DISTORTIONS.modifyPixelCorrection(DISTORTION_CALIBRATION_DATA);
return;
}
// if (label.equals("Correct Sensor Old")) { //removed
/* ======================================================================== */
if (label.equals("Correct Sensor")) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
......@@ -2970,9 +2977,10 @@ if (MORE_BUTTONS) {
int series=LENS_DISTORTIONS.refineParameters.showDialog(
"Select Lens Distortion Residual Compensation Parameters",
// 0x846f1,
0x94ff1,
0x1094ff1,
((LENS_DISTORTIONS.seriesNumber>=0)?LENS_DISTORTIONS.seriesNumber:0),
null); // averageRGB - only for target flat-field correction
null, // averageRGB - only for target flat-field correction
DISTORTION_CALIBRATION_DATA.hasSmallSensors());
if (series<0) return;
LENS_DISTORTIONS.seriesNumber=series;
LENS_DISTORTIONS.modifyPixelCorrection(
......@@ -8860,7 +8868,8 @@ if (MORE_BUTTONS) {
"Select Lens Distortion Residual Compensation Parameters",
0x100000,
((LENS_DISTORTIONS.seriesNumber>=0)?LENS_DISTORTIONS.seriesNumber:0),
LENS_DISTORTIONS.patternParameters.averageRGB);
LENS_DISTORTIONS.patternParameters.averageRGB,
DISTORTION_CALIBRATION_DATA.hasSmallSensors());
if (series<0) return;
LENS_DISTORTIONS.correctPatternFlatField(true); // boolean enableShow
return;
......@@ -8877,7 +8886,8 @@ if (MORE_BUTTONS) {
"Removing specular reflections from the target",
0x400000,
((LENS_DISTORTIONS.seriesNumber>=0)?LENS_DISTORTIONS.seriesNumber:0),
LENS_DISTORTIONS.patternParameters.averageRGB);
LENS_DISTORTIONS.patternParameters.averageRGB,
DISTORTION_CALIBRATION_DATA.hasSmallSensors());
if (series<0) return;
/*
double highPassSigma=10.0;
......@@ -8940,10 +8950,12 @@ if (MORE_BUTTONS) {
// int series=refineParameters.showDialog("Select Lens Distortion Residual Compensation Parameters", 0x1efff, (this.seriesNumber>=0)?this.seriesNumber:0);
int series=LENS_DISTORTIONS.refineParameters.showDialog(
"Select Sensor and Target Flat-Field Correction Parameters",
0x794ff1,
0x1794ff1,
// /0x94ff1,
((LENS_DISTORTIONS.seriesNumber>=0)?LENS_DISTORTIONS.seriesNumber:0),
LENS_DISTORTIONS.patternParameters.averageRGB); // averageRGB - only for target flat-field correction
LENS_DISTORTIONS.patternParameters.averageRGB, // averageRGB - only for target flat-field correction
DISTORTION_CALIBRATION_DATA.hasSmallSensors());
if (series<0) return;
LENS_DISTORTIONS.seriesNumber=series;
long startTime=System.nanoTime();
......@@ -8988,147 +9000,6 @@ if (MORE_BUTTONS) {
/* ======================================================================== */
if (label.equals("Pattern Flat-Field0")) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
if (LENS_DISTORTIONS==null) {
IJ.showMessage("LENS_DISTORTION is not set");
return;
}
LENS_DISTORTIONS.debugLevel=DEBUG_LEVEL;
GenericDialog gd=new GenericDialog("Pattern Flat Field parameters");
gd.addNumericField("Fitting series number (to select images), negative - use all enabled images", -1,0);
gd.addNumericField("Reference station number (unity target brightness)", 0,0);
gd.addNumericField("Shrink sensor mask", 100.0, 1,6,"sensor pix");
gd.addNumericField("Non-vignetted radius", 1000.0, 1,6,"sensor pix");
gd.addNumericField("Minimal alpha", 1.0, 3,7,"%");
gd.addNumericField("Minimal contrast (occlusion detection)", 0.1, 3,7,"(0 .. ~0.8");
gd.addNumericField("Minimal alpha for accumulation", 1.0, 3,7,"%");
gd.addNumericField("Shrink pattern for matching", 2.0, 3,7,"grid nodes");
gd.addNumericField("Maximal relative difference between nodes", 10.0, 3,7,"%");
gd.addNumericField("Shrink pattern border", 2, 0,3,"grid nodes");
gd.addNumericField("Fade pattern border", 2.0, 3,7,"grid nodes");
gd.addMessage("Update pattern white balance (if the illumination is yellowish, increase red and green here)");
gd.addNumericField("Average grid RED (1.0 for white)", LENS_DISTORTIONS.patternParameters.averageRGB[0], 3,5,"x"); //
gd.addNumericField("Average grid GREEN (1.0 for white)", LENS_DISTORTIONS.patternParameters.averageRGB[1], 3,5,"x"); //
gd.addNumericField("Average grid BLUE (1.0 for white)", LENS_DISTORTIONS.patternParameters.averageRGB[2], 3,5,"x"); //
gd.addCheckbox("Reset pattern mask", true);
gd.addCheckbox("Show non-vignetting sensor masks", false);
gd.addCheckbox("Show per-sensor patterns", false);
gd.addCheckbox("Show result mask", true);
gd.addCheckbox("Apply pattern flat field and mask",true);
gd.addCheckbox("Use interpolation for sensor correction",true);
gd.addNumericField("Suspect occlusion only if grid is missing in the area where sensor mask is above this threshold",15, 3,7,"%");
gd.addNumericField("Expand suspected occlusion area", 2, 0,3,"grid nodes");
gd.addNumericField("Fade grid on image (occlusion handling)", 2.0, 3,7,"grid nodes");
gd.addCheckbox("Ignore existent sensor flat-field calibration",false);
gd.addCheckbox("Use only selected channels",false);
gd.showDialog();
if (gd.wasCanceled()) return;
int serNumber= (int) gd.getNextNumber();
int referenceStation= (int) gd.getNextNumber();
double shrink= gd.getNextNumber();
double nonVignettedRadius = gd.getNextNumber();
double minimalAlpha = 0.01*gd.getNextNumber();
double minimalContrast = gd.getNextNumber();
double minimalAccumulate = 0.01*gd.getNextNumber();
double shrinkForMatching = gd.getNextNumber();
double maxRelDiff = 0.01*gd.getNextNumber();
int shrinkMask= (int) gd.getNextNumber();
double fadeBorder = gd.getNextNumber();
LENS_DISTORTIONS.patternParameters.averageRGB[0]=gd.getNextNumber();
LENS_DISTORTIONS.patternParameters.averageRGB[1]=gd.getNextNumber();
LENS_DISTORTIONS.patternParameters.averageRGB[2]=gd.getNextNumber();
boolean resetMask= gd.getNextBoolean();
boolean showSensorMasks=gd.getNextBoolean();
boolean showIndividual= gd.getNextBoolean();
boolean showResult= gd.getNextBoolean();
boolean applyResult= gd.getNextBoolean();
boolean useInterpolate= gd.getNextBoolean();
double maskThresholdOcclusion=0.01*gd.getNextNumber();
int shrinkOcclusion= (int)gd.getNextNumber();
double fadeOcclusion= gd.getNextNumber();
boolean ignoreSensorFlatField= gd.getNextBoolean();
boolean useSelectedChannels= gd.getNextBoolean();
boolean [] selectedChannels=null;
LENS_DISTORTIONS.patternParameters.updateNumStations(LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.getNumStations());
if (useSelectedChannels && (ABERRATIONS_PARAMETERS!=null))selectedChannels=ABERRATIONS_PARAMETERS.selectedChannels;
double [][] masks= LENS_DISTORTIONS.nonVignettedMasks(
shrink,
nonVignettedRadius,
minimalAlpha);
if (selectedChannels!=null){
for (int nChn=0;nChn<masks.length;nChn++) if ((nChn<selectedChannels.length)&&!selectedChannels[nChn]) masks[nChn]=null;
}
if (showSensorMasks) {
boolean same_size = true;
for (int i = 1; i < masks.length; i++) same_size &= (masks[i].length == masks[0].length);
if (same_size) {
this.SDFA_INSTANCE.showArrays( //java.lang.ArrayIndexOutOfBoundsException: 313632
masks,
LENS_DISTORTIONS.getSensorWidth(0)/ LENS_DISTORTIONS.getDecimateMasks(0),
LENS_DISTORTIONS.getSensorHeight(0)/LENS_DISTORTIONS.getDecimateMasks(0),
true,
"nonVinetting masks");
} else {
System.out.println("**** Can't show sesnor masks for different size sesnors as a stack! ");
}
}
double [][][][] sensorGrids=LENS_DISTORTIONS.calculateGridFlatField(
serNumber,
masks,
minimalContrast,
minimalAccumulate,
useInterpolate,
maskThresholdOcclusion, // suspect occlusion only if grid is missing in the area where sensor mask is above this threshold
shrinkOcclusion,
fadeOcclusion,
ignoreSensorFlatField);
double [][][] geometry= LENS_DISTORTIONS.patternParameters.getGeometry();
if (showIndividual){
for (int station=0;station<sensorGrids.length;station++) if (sensorGrids[station]!=null){
for (int i=0;i<sensorGrids[station].length;i++) if (sensorGrids[station][i]!=null){
this.SDFA_INSTANCE.showArrays(
sensorGrids[station][i],
geometry[0].length,
geometry.length,
true,
"chn"+i+":"+station+"-pattern");
}
}
}
double [][][][] patternArray= LENS_DISTORTIONS.combineGridFlatField(
referenceStation,
sensorGrids,
shrinkForMatching,
resetMask,
maxRelDiff,
shrinkMask,
fadeBorder);
if (showResult) {
String [] titles={"Alpha","Red","Green","Blue","Number of images used"};
for (int station=0;station<patternArray.length;station++) if (patternArray[station]!=null){
for (int nView=0;nView<patternArray[station].length;nView++) if (patternArray[station][nView]!=null){
this.SDFA_INSTANCE.showArrays(
patternArray[station][nView],
geometry[0].length,
geometry.length,
true,
"St"+station+"_V"+nView+"_Pattern_Colors "+maxRelDiff,
titles);
}
}
}
if (applyResult) LENS_DISTORTIONS.applyGridFlatField(patternArray); // {alpha, red,green,blue, number of images used}[pixel_index]
return;
}
//"Pattern Flat-Field"
//"Generate & Save Equirectangular"
/* ======================================================================== */
......@@ -9588,6 +9459,10 @@ if (MORE_BUTTONS) {
boolean adjust_eo = false;
boolean adjust_lwir = true;
boolean use_lma = true;
boolean use_nonlma = true;
int extra_search =2;
double sigma = 5;
GenericDialog gd = new GenericDialog("Initial alignment of the secondary camera to the reference one");
// gd.addMessage("This command used Fitting Strategy[last] that should be set with all parameters but\n"+
......@@ -9601,13 +9476,21 @@ if (MORE_BUTTONS) {
gd.addCheckbox("Adjust EO (reference) sensors", adjust_eo);
gd.addCheckbox("Adjust LWIR (target) sensors", adjust_lwir);
gd.addCheckbox("Use LMA (unchecked - initial approximate grid set by correlation)", use_lma);
gd.addCheckbox("Use initial approximate grid set by correlation before LMA", use_nonlma);
gd.addNumericField("Extra search for the non-LMA method", extra_search, 0);
gd.addNumericField("Sigma for the non-LMA method", sigma, 3 ,7, "");
gd.showDialog();
if (gd.wasCanceled()) return false;
min_set = (int) gd.getNextNumber();
max_set = (int) gd.getNextNumber();
adjust_eo = gd.getNextBoolean();
adjust_lwir = gd.getNextBoolean();
use_lma = gd.getNextBoolean();
min_set = (int) gd.getNextNumber();
max_set = (int) gd.getNextNumber();
adjust_eo = gd.getNextBoolean();
adjust_lwir = gd.getNextBoolean();
use_lma = gd.getNextBoolean();
use_nonlma = gd.getNextBoolean();
extra_search = (int) gd.getNextNumber();
sigma = gd.getNextNumber();
use_nonlma |= !use_lma; // at least something
if (!dcd.hasSmallSensors()) {
String msg="This system does not have any LWIR or other dependent sub-cameras";
IJ.showMessage("Error",msg);
......@@ -9617,6 +9500,16 @@ if (MORE_BUTTONS) {
if (use_lma) {
for (int num_set = min_set; num_set <=max_set; num_set++) if
((dcd.gIS[num_set] != null) && (dcd.gIS[num_set].imageSet != null)) {
if (use_nonlma) {
dcd.initialSetLwirFromEO( //
num_set,
EYESIS_CAMERA_PARAMETERS.invertUnmarkedLwirGrid, // boolean invert_unmarked_grid,
extra_search, // 2
sigma, //5.0
PATTERN_PARAMETERS,
true); // debug
}
for (int nc = 0; nc < dcd.getNumChannels(); nc++) {
if (dcd.gIS[num_set].imageSet[nc]!= null) {
int num_img = dcd.gIS[num_set].imageSet[nc].imgNumber;
......@@ -9659,8 +9552,8 @@ if (MORE_BUTTONS) {
} else {
for (int num_set = min_set; num_set <=max_set; num_set++) {
int extra_search =2;
double sigma = 5;
// int extra_search =2;
// double sigma = 5;
dcd.initialSetLwirFromEO( //
......@@ -139,7 +139,7 @@ import ij.text.TextWindow;
public double [][] pixelsXY= null; // for each image, each grid node - a set of of {px,py,contrast,vignR,vignG,vignB} vign* is in the 0..1.0 range
public double [] pixelsMask= null; // for each image, each grid node - weight function derived from contrast and 3 parameters
public int [][] pixelsUV= null; // for each image, each grid node - a pair of {gridU, gridV}
public boolean [] badNodes= null; // if not null, marks node with excessive errors
private boolean [] badNodes= null; // if not null, marks node with excessive errors
public double [][] pixelsXY_extra= null; // extra data, for nodes that are out of the physical grid (may be needed after re-calibration)
public int [][] pixelsUV_extra= null;
private double gridPeriod=0.0; // average grid period, in pixels (to filter out (double-) reflected images
......@@ -269,6 +269,8 @@ import ij.text.TextWindow;
}
public void calculateMask(
boolean proportional,
double gridMarginScale,
double minContrast,
double shrinkBlurSigma,
double shrinkBlurLevel){
......@@ -298,11 +300,48 @@ import ij.text.TextWindow;
int width= (maxU-minU+1+2*margin);
int height=(maxV-minV+1+2*margin);
double [] mask = new double [width*height];
/*
for (int i=0;i<mask.length;i++) mask[i]=-1.0;
for (int i=0;i<this.pixelsUV.length;i++){
int index=(this.pixelsUV[i][0]-U0)+width*(this.pixelsUV[i][1]-V0);
mask[index]=(this.pixelsXY[i][contrastIndex]>=minContrast)?1.0:-1.0; // java.lang.ArrayIndexOutOfBoundsException: 2230
}
*/
// for (int i=0;i<mask.length;i++) mask[i]=-1.0;
// trying to shrink grid only where there is an edge of the grid, keeping sensor outer regions intact
double contrast = 0;
for (int i=0;i<this.pixelsUV.length;i++){
int index=(this.pixelsUV[i][0]-U0)+width*(this.pixelsUV[i][1]-V0);
if (this.pixelsXY[i][contrastIndex] > contrast) contrast = this.pixelsXY[i][contrastIndex];
if (proportional) {
if (this.pixelsXY[i][contrastIndex] > 0.0) {
mask[index] = this.pixelsXY[i][contrastIndex];
}
} else {
if (this.pixelsXY[i][contrastIndex]>=minContrast) mask[index] = 1.0;
}
}
contrast *= -gridMarginScale;
if (!proportional) {
contrast =-1;
}
if (this.pixelsUV_extra !=null) {
for (int i=0;i<this.pixelsUV_extra.length;i++){
int iu = this.pixelsUV_extra[i][0]-U0;
int iv = this.pixelsUV_extra[i][1]-V0;
if ((iu >= 0) && (iv >= 0) && (iu < width) && (iv < height)) {
int index = iu +iv * width;
mask[index] = contrast;
}
}
}
for (int i=0;i<this.pixelsUV.length;i++){
int index=(this.pixelsUV[i][0]-U0)+width*(this.pixelsUV[i][1]-V0);
mask[index]=(this.pixelsXY[i][contrastIndex]>=minContrast)?1.0:-1.0; // java.lang.ArrayIndexOutOfBoundsException: 2230
}
(new DoubleGaussianBlur()).blurDouble(
mask,
width,
......@@ -320,7 +359,83 @@ import ij.text.TextWindow;
}
// System.out.print(" "+IJ.d2s(dbgMax,2)+" ");
}
}
public void showGridImage() {
if (this.pixelsUV==null) return;
int len0 = this.pixelsUV.length;
if (this.pixelsUV_extra== null) this.pixelsUV_extra = new int[0][];
if (this.pixelsXY_extra== null) this.pixelsXY_extra = new double[0][];
int lenE = this.pixelsUV_extra.length;
int len = len0 + lenE;
if (len==0) return;
// find
String [] titles = {
"pX", // 0
"pY", // 1
"U", //2
"V", // 3
"contrast", // 4
"R", //5
"G", //6
"B", //7
"Extra", // 8
"Mask"}; //9
int minU=this.pixelsUV[0][0],minV=this.pixelsUV[0][1];
int maxU=minU,maxV=minV;
int margin=0;//(int) (2*shrinkBlurSigma);
int [][][] pUV= {this.pixelsUV, this.pixelsUV_extra};
double [][][] pXY= {this.pixelsXY, this.pixelsXY_extra};
for (int mode = 0; mode < pUV.length; mode++) {
for (int i=0; i < pUV[mode].length; i++){
if (pUV[mode][i][0] > maxU) maxU = pUV[mode][i][0];
if (pUV[mode][i][0] < minU) minU = pUV[mode][i][0];
if (pUV[mode][i][1] > maxV) maxV = pUV[mode][i][1];
if (pUV[mode][i][1] < minV) minV = pUV[mode][i][1];
}
}
int U0=minU-margin;
int V0=minV-margin;
int width= (maxU-minU+1+2*margin);
int height=(maxV-minV+1+2*margin);
double [][] dbg_img = new double [titles.length][width*height];
for (int i = 0; i < dbg_img.length;i++) for (int j = 0; j < dbg_img[i].length;j++) {
dbg_img[i][j] = Double.NaN;
}
for (int mode = 0; mode < pUV.length; mode++) {
for (int i=0; i < pUV[mode].length; i++){
int index=(pUV[mode][i][0]-U0)+width*(pUV[mode][i][1]-V0);
if ((index >= dbg_img[0].length) || (i >= pXY[mode].length)) {
System.out.println("BUG");
}
dbg_img[0][index] = pXY[mode][i][0];
dbg_img[1][index] = pXY[mode][i][1];
dbg_img[2][index] = pUV[mode][i][0];
dbg_img[3][index] = pUV[mode][i][1];
dbg_img[4][index] = pXY[mode][i][2]; // contrast
dbg_img[5][index] = pXY[mode][i][3]; // R
dbg_img[6][index] = pXY[mode][i][4]; // G
dbg_img[7][index] = pXY[mode][i][5]; // B
dbg_img[8][index] = mode+1; // 9
if ((this.pixelsMask != null) && (mode == 0)) {
dbg_img[9][index] = this.pixelsMask[i]; // 9
}
}
}
(new ShowDoubleFloatArrays()).showArrays(
dbg_img,
width,
height,
true,
"GI-"+this.imgNumber,
titles);
}
}
public class GridImageSet{
private int numPars=53; // 27;
private int thisParsStartIndex=6;
......@@ -992,13 +1107,17 @@ import ij.text.TextWindow;
set_widths[nc] = imp_grid.getWidth();
int numBadNodes = 0;
int [] numBadNodes = new int [2];
if (this.eyesisCameraParameters.badNodeThreshold>0.0){
boolean thisDebug =false;
// thisDebug|= (fileNumber== 720); // chn 25
numBadNodes=fixBadGridNodes(
pixels,
stack.getWidth(),
this.eyesisCameraParameters.replaceBad,
this.eyesisCameraParameters.removeWorst,
this.eyesisCameraParameters.weightBad,
this.eyesisCameraParameters.weightWorst,
this.eyesisCameraParameters.badNodeThreshold,
this.eyesisCameraParameters.maxBadNeighb,
this.debugLevel+(thisDebug?3:0),
......@@ -1023,8 +1142,15 @@ import ij.text.TextWindow;
} else {
System.out.print(" [null]");
}
if (numBadNodes>0)
System.out.print(" -- replaced "+numBadNodes+" bad grid nodes");
if ((numBadNodes[0] + numBadNodes [1])>0) {
if (this.eyesisCameraParameters.removeWorst) {
System.out.print(" -- removed "+numBadNodes[0]+"("+numBadNodes[1]+")locally worst grid nodes,");
} else if (this.eyesisCameraParameters.replaceBad){
System.out.print(" -- replaced "+numBadNodes[0]+"("+numBadNodes[1]+") bad grid nodes,");
} else {
System.out.print(" -- scaled "+numBadNodes[0]+"("+numBadNodes[1]+") bad grid nodes,");
}
}
int [] uvrot=this.gIP[numFile].getUVShiftRot();
System.out.println(" shift:rot="+uvrot[0]+"/"+uvrot[1]+":"+uvrot[2]+
" enabled="+this.gIP[numFile].enabled+" hintedMatch="+this.gIP[numFile].hintedMatch);
......@@ -3797,25 +3923,37 @@ import ij.text.TextWindow;
}
if (this.eyesisCameraParameters.badNodeThreshold>0.0){
boolean thisDebug =false;
// thisDebug|= (fileNumber== 720); // chn 25
int numBadNodes=fixBadGridNodes(
pixels,
stack.getWidth(),
this.eyesisCameraParameters.badNodeThreshold,
this.eyesisCameraParameters.maxBadNeighb,
this.debugLevel+(thisDebug?3:0),
thisDebug?("fixBad-"+fileNumber):null
);
if (this.debugLevel>-1) {
if (numBadNodes>0)
System.out.print(" -- replaced "+numBadNodes+" bad grid nodes");
int [] uvrot=this.gIP[fileNumber].getUVShiftRot();
System.out.println(" shift:rot="+uvrot[0]+"/"+uvrot[1]+":"+uvrot[2]+
" enabled="+this.gIP[fileNumber].enabled+" hintedMatch="+this.gIP[fileNumber].hintedMatch);
}
}
if (this.eyesisCameraParameters.badNodeThreshold>0.0){
boolean thisDebug =false;
// thisDebug|= (fileNumber== 720); // chn 25
int [] numBadNodes=fixBadGridNodes(
pixels,
stack.getWidth(),
this.eyesisCameraParameters.replaceBad,
this.eyesisCameraParameters.removeWorst,
this.eyesisCameraParameters.weightBad,
this.eyesisCameraParameters.weightWorst,
this.eyesisCameraParameters.badNodeThreshold,
this.eyesisCameraParameters.maxBadNeighb,
this.debugLevel+(thisDebug?3:0),
thisDebug?("fixBad-"+fileNumber):null
);
if (this.debugLevel>-1) {
if ((numBadNodes[0] + numBadNodes [1])>0) {
if (this.eyesisCameraParameters.removeWorst) {
System.out.print(" -- removed "+numBadNodes[0]+"("+numBadNodes[1]+") locally worst grid nodes,");
} else if (this.eyesisCameraParameters.replaceBad){
System.out.print(" -- replaced "+numBadNodes[0]+"("+numBadNodes[1]+") bad grid nodes,");
} else {
System.out.print(" -- scaled "+numBadNodes[0]+"("+numBadNodes[1]+") bad grid nodes,");
}
}
int [] uvrot=this.gIP[fileNumber].getUVShiftRot();
System.out.println(" shift:rot="+uvrot[0]+"/"+uvrot[1]+":"+uvrot[2]+
" enabled="+this.gIP[fileNumber].enabled+" hintedMatch="+this.gIP[fileNumber].hintedMatch);
}
}
this.gIP[fileNumber].flatFieldAvailable=pixels.length>=8;
if (disableNoFlatfield && !this.gIP[fileNumber].flatFieldAvailable) this.gIP[fileNumber].enabled=false; // just to use old mixed data
......@@ -3860,25 +3998,33 @@ import ij.text.TextWindow;
* This program replaces the "bad" ones with predicted by 8 neighbors using 2-nd order interpolation
* @param fPixels stack of pX,pY,target-U,target-V,contrast (some bad pixels have low contrast), red,green,blue
* @param width grid width
* @param removeBad remove bad nodes, do not try to fix them
* @param tolerance maximal tolerated difference between the predicted by 8 neigbors and center pixels
* @parame maxBadNeighb - maximal number of bad cells among 8 neighbors
* @parame gebugLevel debug level
* @return number of fixed nodes
* @return number of fixed/removed nodes (first - fixed/removed, second other bad
* Neighbors of bad pixels can be reported bad, so they have to be re-tried with the worst removed
*/
public int fixBadGridNodes(
public int [] fixBadGridNodes(
float [][] fpixels,
int width,
boolean replaceBad,
boolean removeWorst,
double weightBad,
double weightWorst,
double tolerance,
int maxBadNeighb,
int debugLevel,
String dbgTitle){
int badMark = -2; // use -1?
// double zeroContrast = 1.0; // 0.1; // 1.0; // interpolation weight of nodes with zero contreast
// boolean allBad=true; // false - only local worst
int debugThreshold=3;
double tolerance2=tolerance*tolerance;
double tolerance2Final=10.0*tolerance2; // final pass - fix even if the surronding are not that good
int [][] dirs8= {{1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1}};
int [] dirs8Index={1,width+1,width,width-1,-1,-width-1,-width,-width+1};
double [] diffs2=new double [fpixels[0].length];
double [] diffs2=new double [fpixels[INDEX_PX].length];
int height=diffs2.length/width;
for (int i=0;i<diffs2.length;i++) diffs2[i]=-1.0; // no nodes
double [][][] data=new double [8][3][];
......@@ -3891,18 +4037,18 @@ import ij.text.TextWindow;
double maxDiff2=0.0;
for (int y=1; y<(height-1);y++) for (int x=1;x<(width-1);x++) {
int index=y*width+x;
if (fpixels[0][index]>=0.0){
if (fpixels[INDEX_PX][index]>=0.0){
int numNonZero=0;
for (int iDir=0;iDir<dirs8.length;iDir++){
int index1=index+dirs8[iDir][1]*width+dirs8[iDir][0];
data[iDir][0][0]=dirs8[iDir][0];
data[iDir][0][1]=dirs8[iDir][1];
data[iDir][1][0]=fpixels[0][index1];
data[iDir][1][1]=fpixels[1][index1];
if ((fpixels[0][index1]<0) || (fpixels[1][index1]<0)){
data[iDir][1][0]=fpixels[INDEX_PX][index1];
data[iDir][1][1]=fpixels[INDEX_PY][index1];
if ((fpixels[INDEX_PX][index1]<0) || (fpixels[INDEX_PY][index1]<0)){
data[iDir][2][0]=0.0;
} else {
data[iDir][2][0]=1.0;
data[iDir][2][0]= 1.0; // fpixels[INDEX_CONTRAST][index1] + zeroContrast; // 1.0; Make it weighted
numNonZero++;
}
}
......@@ -3919,10 +4065,19 @@ import ij.text.TextWindow;
}
}
}
double dx=coeff[0][coeff[0].length-1] - fpixels[0][index];
double dy=coeff[1][coeff[1].length-1] - fpixels[1][index];
double dx=coeff[0][coeff[0].length-1] - fpixels[INDEX_PX][index];
double dy=coeff[1][coeff[1].length-1] - fpixels[INDEX_PY][index];
diffs2[index]=dx*dx+dy*dy;
if (diffs2[index]>maxDiff2) maxDiff2=diffs2[index];
if (diffs2[index]>maxDiff2) {
maxDiff2=diffs2[index];
}
if (maxDiff2 > tolerance2) {
if (debugLevel> 2){
System.out.println("index="+index+": "+Math.sqrt(maxDiff2));
}
}
} else {
if (debugLevel>0){
System.out.println("fixBadGridNodes() failed for x="+x+", y="+y);
......@@ -3930,15 +4085,19 @@ import ij.text.TextWindow;
}
}
}
if (maxDiff2<=tolerance2) return 0; // nothing to fix
if (maxDiff2<=tolerance2) return new int[2]; // nothing to fix
// here - first debug show?
boolean [] localWorst=new boolean[diffs2.length];
boolean [] badNodes= new boolean[diffs2.length];
int numBad=0;
for (int i=0;i<localWorst.length;i++){
if (diffs2[i]<tolerance2){
localWorst[i]=false;
badNodes[i] = false;
} else {
localWorst[i]=true;
badNodes[i] = true;
for (int iDir=0;iDir<dirs8Index.length;iDir++) if (diffs2[i+dirs8Index[iDir]] > diffs2[i]){
localWorst[i]=false;
break;
......@@ -3948,8 +4107,9 @@ import ij.text.TextWindow;
}
if (numBad==0) {
System.out.println("fixBadGridNodes() BUG - should not get here.");
return 0; // should not get here -
return new int[2]; // should not get here -
}
double [][] dbgData=null;
if (debugLevel>debugThreshold){
dbgData=new double[9][];
......@@ -3958,171 +4118,197 @@ import ij.text.TextWindow;
for (int i=0;i< dbgData[2].length;i++) if (!localWorst[i]) dbgData[2][i]=-1.0;
// (new showDoubleFloatArrays()).showArrays(diffs2, width, height, "diffs2");
}
// Trying to eliminate all non local worst (may that is just extra as there anot too many bad nodes)
int numStillBad=0;
for (int i=0;i<localWorst.length;i++) if (localWorst[i]){
for (int iDir0=0;iDir0<dirs8Index.length;iDir0++) if (diffs2[i+dirs8Index[iDir0]] > tolerance2){ // don't bother with not-so-bad
int index=i+dirs8Index[iDir0]; // will never be on the border as diffs2 is <=0.0 there
int numNonZero=0;
for (int iDir=0;iDir<dirs8.length;iDir++){
int index1=index+dirs8[iDir][1]*width+dirs8[iDir][0];
data[iDir][0][0]=dirs8[iDir][0];
data[iDir][0][1]=dirs8[iDir][1];
data[iDir][1][0]=fpixels[0][index1];
data[iDir][1][1]=fpixels[1][index1];
if ((data[iDir][1][0]<0) || (data[iDir][1][1]<0) || localWorst[index1]){
data[iDir][2][0]=0.0;
} else {
data[iDir][2][0]=1.0;
numNonZero++;
}
}
if (debugLevel>3){
System.out.print("+++ fixBadGridNodes() trying to fix for x="+(index%width)+", y="+(index/width)+", iDir0="+iDir0+" numNonZero="+numNonZero+" maxBadNeighb="+maxBadNeighb);
}
if (replaceBad) {
// Trying to eliminate all non local worst (may that is just extra as there anot too many bad nodes)
int numStillBad=0;
for (int i=0;i<localWorst.length;i++) if (localWorst[i]){
for (int iDir0=0;iDir0<dirs8Index.length;iDir0++) if (diffs2[i+dirs8Index[iDir0]] > tolerance2){ // don't bother with not-so-bad
int index=i+dirs8Index[iDir0]; // will never be on the border as diffs2 is <=0.0 there
int numNonZero=0;
for (int iDir=0;iDir<dirs8.length;iDir++){
int index1=index+dirs8[iDir][1]*width+dirs8[iDir][0];
data[iDir][0][0]=dirs8[iDir][0];
data[iDir][0][1]=dirs8[iDir][1];
data[iDir][1][0]=fpixels[INDEX_PX][index1];
data[iDir][1][1]=fpixels[INDEX_PY][index1];
if ((data[iDir][1][0]<0) || (data[iDir][1][1]<0) || localWorst[index1]){
data[iDir][2][0]=0.0;
} else {
data[iDir][2][0] = 1.0; // fpixels[INDEX_CONTRAST][index1] + zeroContrast; // 1.0; Make it weighted
numNonZero++;
}
if (numNonZero<(data.length-maxBadNeighb-1)) continue;
double [][] coeff=polynomialApproximation.quadraticApproximation(
data,
false); // boolean forceLinear // use linear approximation
if (coeff!=null) {
double dx=coeff[0][coeff[0].length-1] - fpixels[0][index];
double dy=coeff[1][coeff[1].length-1] - fpixels[1][index];
if (debugLevel>3){
System.out.print("fixBadGridNodes() old diffs2["+index+"]="+diffs2[index]);
}
diffs2[index]=dx*dx+dy*dy; // updated value
if (debugLevel>3){
System.out.print(" new diffs2["+index+"]="+diffs2[index]);
}
if (diffs2[index]>tolerance2) {
numStillBad++;
if (debugLevel>3){
System.out.print(" --- BAD");
}
} else if (debugLevel>3){
System.out.print(" --- GOOD");
}
if ((coeff[0].length<6) || (coeff[1].length<6)){
if (debugLevel>3){
System.out.print("fixBadGridNodes() 2 linear interpolate for x="+(index%width)+", y="+(index/width));
for (int j=0;j<data.length;j++){
System.out.println(j+" "+data[j][0][0]+"/"+data[j][0][1]+" - "+data[j][1][0]+"/"+data[j][1][1]+" : "+data[j][2][0]);
}
}
}
}
if (debugLevel>3){
System.out.print("+++ fixBadGridNodes() trying to fix for x="+(index%width)+", y="+(index/width)+", iDir0="+iDir0+" numNonZero="+numNonZero+" maxBadNeighb="+maxBadNeighb);
}
if (numNonZero<(data.length-maxBadNeighb-1)) continue;
double [][] coeff=polynomialApproximation.quadraticApproximation(
data,
false); // boolean forceLinear // use linear approximation
if (coeff!=null) {
double dx=coeff[0][coeff[0].length-1] - fpixels[INDEX_PX][index];
double dy=coeff[1][coeff[1].length-1] - fpixels[INDEX_PY][index];
if (debugLevel>3){
System.out.print("fixBadGridNodes() old diffs2["+index+"]="+diffs2[index]);
}
diffs2[index]=dx*dx+dy*dy; // updated value
if (debugLevel>3){
System.out.print(" new diffs2["+index+"]="+diffs2[index]);
}
if (diffs2[index]>tolerance2) {
numStillBad++;
if (debugLevel>3){
System.out.print(" --- BAD");
}
} else if (debugLevel>3){
System.out.print(" --- GOOD");
}
if ((coeff[0].length<6) || (coeff[1].length<6)){
if (debugLevel>3){
System.out.print("fixBadGridNodes() 2 linear interpolate for x="+(index%width)+", y="+(index/width));
for (int j=0;j<data.length;j++){
System.out.println(j+" "+data[j][0][0]+"/"+data[j][0][1]+" - "+data[j][1][0]+"/"+data[j][1][1]+" : "+data[j][2][0]);
}
}
}
} else {
if (debugLevel>3){
System.out.println("fixBadGridNodes() failed for x="+(index%width)+", y="+(index/width)+", iDir0="+iDir0);
}
}
if (debugLevel>3) System.out.println();
}
}
if (numStillBad>0){
if (debugLevel>3){
System.out.println("fixBadGridNodes(): numStillBad="+numStillBad+" > 0 - probably near the border, just make sure OK.");
}
}
if (debugLevel>debugThreshold){
dbgData[1]=diffs2.clone();
for (int i=0;i< dbgData[1].length;i++) if (localWorst[i]) dbgData[1][i]=0.0;
dbgData[3]=new double[dbgData[0].length];
for (int i=0;i< dbgData[3].length;i++) dbgData[3][i]=0.0;
dbgData[4]=dbgData[3].clone();
dbgData[5]=dbgData[3].clone();
dbgData[6]=dbgData[3].clone();
dbgData[7]=dbgData[3].clone();
dbgData[8]=dbgData[3].clone();
for (int i=0;i< dbgData[3].length;i++) {
dbgData[3][i]=fpixels[INDEX_PX][i];
dbgData[4][i]=fpixels[INDEX_PY][i];
}
}
// TODO - try to fix some around pixels first?
// Actually patching locally worst nodes
for (int index=0;index<localWorst.length;index++) if (localWorst[index]){
int numNonZero=0;
for (int iDir=0;iDir<dirs8.length;iDir++){
int index1=index+dirs8[iDir][1]*width+dirs8[iDir][0];
data[iDir][0][0]=dirs8[iDir][0];
data[iDir][0][1]=dirs8[iDir][1];
data[iDir][1][0]=fpixels[INDEX_PX][index1];
data[iDir][1][1]=fpixels[INDEX_PY][index1];
if (diffs2[index1]>tolerance2Final){ // increased tolerance for the final correction
data[iDir][2][0]=0.0; // do not count neighbors who are bad themselves
} else {
data[iDir][2][0]= 1.0; // fpixels[INDEX_CONTRAST][index1]+ zeroContrast; // 1.0; Make it weighted
numNonZero++;
}
}
if (numNonZero<(data.length-maxBadNeighb)){
if (debugLevel>3){
System.out.println("fixBadGridNodes() failed x="+(index%width)+", y="+(index/width)+", number of good neighbors="+numNonZero);
}
continue; // do not fix anything
}
double [][] coeff=polynomialApproximation.quadraticApproximation(
data,
false); // boolean forceLinear // use linear approximation
if (coeff!=null) {
if ((coeff[0].length<6) || (coeff[1].length<6)){
if (debugLevel>3){
System.out.println("fixBadGridNodes() linear interpolate for x="+(index%width)+", y="+(index/width));
for (int j=0;j<data.length;j++){
System.out.println(j+" "+data[j][0][0]+"/"+data[j][0][1]+" - "+data[j][1][0]+"/"+data[j][1][1]+" : "+data[j][2][0]);
}
for (int n=0;n<coeff.length;n++){
for (int j=0;j<coeff[n].length;j++){
System.out.print(coeff[n][j]+" ");
}
System.out.println();
}
}
} else if (debugLevel>3){
System.out.println("fixBadGridNodes() qudratic interpolate for x="+(index%width)+", y="+(index/width));
for (int j=0;j<data.length;j++){
System.out.println(j+" "+data[j][0][0]+"/"+data[j][0][1]+" - "+data[j][1][0]+"/"+data[j][1][1]+" : "+data[j][2][0]);
}
for (int n=0;n<coeff.length;n++){
for (int j=0;j<coeff[n].length;j++){
System.out.print(coeff[n][j]+" ");
}
System.out.println();
}
if (((index%width)==19) && ((index/width)==57)){
coeff=(new PolynomialApproximation(4)).quadraticApproximation(
data,
false);
}
}
fpixels[INDEX_PX][index]=(float) coeff[0][coeff[0].length-1];
fpixels[INDEX_PY][index]=(float) coeff[1][coeff[1].length-1];
} else {
if (debugLevel>3){
System.out.println("fixBadGridNodes() failed for x="+(index%width)+", y="+(index/width)+", last pass");
}
}
}
}
// scale contrasts of bad and worst nodes
numBad = 0;
int numWorst = 0;
for (int i=0; i<badNodes.length; i++){
if (localWorst[i]) {
numWorst++;
numBad++;
if (removeWorst ) {
fpixels[INDEX_PX][i] = badMark;
fpixels[INDEX_PY][i] = badMark;
} else {
if (debugLevel>3){
System.out.println("fixBadGridNodes() failed for x="+(index%width)+", y="+(index/width)+", iDir0="+iDir0);
}
fpixels[INDEX_CONTRAST][i] *= weightWorst;
}
if (debugLevel>3) System.out.println();
} else if (badNodes[i]) {
numBad++;
fpixels[INDEX_CONTRAST][i] *= weightBad;
}
}
if (numStillBad>0){
if (debugLevel>3){
System.out.println("fixBadGridNodes(): numStillBad="+numStillBad+" > 0 - probably near the border, just make sure OK.");
}
}
if (debugLevel>debugThreshold){
dbgData[1]=diffs2.clone();
for (int i=0;i< dbgData[1].length;i++) if (localWorst[i]) dbgData[1][i]=0.0;
dbgData[3]=new double[dbgData[0].length];
for (int i=0;i< dbgData[3].length;i++) dbgData[3][i]=0.0;
dbgData[4]=dbgData[3].clone();
dbgData[5]=dbgData[3].clone();
dbgData[6]=dbgData[3].clone();
dbgData[7]=dbgData[3].clone();
dbgData[8]=dbgData[3].clone();
for (int i=0;i< dbgData[3].length;i++) {
dbgData[3][i]=fpixels[0][i];
dbgData[4][i]=fpixels[1][i];
}
}
// TODO - try to fix some around pixels first?
// Actually patching locally worst nodes
for (int index=0;index<localWorst.length;index++) if (localWorst[index]){
int numNonZero=0;
for (int iDir=0;iDir<dirs8.length;iDir++){
int index1=index+dirs8[iDir][1]*width+dirs8[iDir][0];
data[iDir][0][0]=dirs8[iDir][0];
data[iDir][0][1]=dirs8[iDir][1];
data[iDir][1][0]=fpixels[0][index1];
data[iDir][1][1]=fpixels[1][index1];
if (diffs2[index1]>tolerance2Final){ // increased tolerance for the final correction
data[iDir][2][0]=0.0; // do not count neighbors who are bad themselves
} else {
data[iDir][2][0]=1.0;
numNonZero++;
}
}
if (numNonZero<(data.length-maxBadNeighb)){
if (debugLevel>3){
System.out.println("fixBadGridNodes() failed x="+(index%width)+", y="+(index/width)+", number of good neighbors="+numNonZero);
}
continue; // do not fix anything
}
double [][] coeff=polynomialApproximation.quadraticApproximation(
data,
false); // boolean forceLinear // use linear approximation
if (coeff!=null) {
if ((coeff[0].length<6) || (coeff[1].length<6)){
if (debugLevel>3){
System.out.println("fixBadGridNodes() linear interpolate for x="+(index%width)+", y="+(index/width));
for (int j=0;j<data.length;j++){
System.out.println(j+" "+data[j][0][0]+"/"+data[j][0][1]+" - "+data[j][1][0]+"/"+data[j][1][1]+" : "+data[j][2][0]);
}
for (int n=0;n<coeff.length;n++){
for (int j=0;j<coeff[n].length;j++){
System.out.print(coeff[n][j]+" ");
}
System.out.println();
}
}
} else if (debugLevel>3){
System.out.println("fixBadGridNodes() qudratic interpolate for x="+(index%width)+", y="+(index/width));
for (int j=0;j<data.length;j++){
System.out.println(j+" "+data[j][0][0]+"/"+data[j][0][1]+" - "+data[j][1][0]+"/"+data[j][1][1]+" : "+data[j][2][0]);
}
for (int n=0;n<coeff.length;n++){
for (int j=0;j<coeff[n].length;j++){
System.out.print(coeff[n][j]+" ");
}
System.out.println();
}
if (((index%width)==19) && ((index/width)==57)){
coeff=(new PolynomialApproximation(4)).quadraticApproximation(
data,
false);
}
}
fpixels[0][index]=(float) coeff[0][coeff[0].length-1];
fpixels[1][index]=(float) coeff[1][coeff[1].length-1];
} else {
if (debugLevel>3){
System.out.println("fixBadGridNodes() failed for x="+(index%width)+", y="+(index/width)+", last pass");
}
}
}
if (debugLevel>debugThreshold){
for (int i=0;i< dbgData[3].length;i++) {
dbgData[5][i]=fpixels[0][i];
dbgData[6][i]=fpixels[1][i];
dbgData[7][i]=dbgData[3][i]-fpixels[0][i];
dbgData[8][i]=dbgData[4][i]-fpixels[1][i];
dbgData[7][i]=dbgData[3][i]-fpixels[INDEX_PX][i];
dbgData[8][i]=dbgData[4][i]-fpixels[INDEX_PY][i];
}
String [] dbgTitles={"diff20","diff2Mod","localWorst", "old-X", "old-Y", "new-X", "new-Y","old-new-X","old-new-Y"};
if (dbgTitle!=null) (new ShowDoubleFloatArrays()).showArrays(dbgData, width, height, true, dbgTitle, dbgTitles);
}
return numBad;
int [] nums = {numWorst, numBad};
return nums;
}
// TODO: Move all custom image properties (including encode/decode from JP4_reader_camera) to a separate class.
// below is a duplicatie from MatchSimulatedPattern
// below is a duplicate from MatchSimulatedPattern
@Deprecated
public double[][] getPointersXY(ImagePlus imp, int numPointers){
// read image info to properties (if it was not done yet - should it?
......@@ -4854,6 +5040,13 @@ import ij.text.TextWindow;
eyesisCameraParameters.maskBlurSigma);
}
public double [] calculateSensorMasks(int chNum) {
return calculateSensorMasks(
chNum,
eyesisCameraParameters.shrinkGridForMask,
eyesisCameraParameters.maskBlurSigma);
}
/**
*
* @param width image width, in pixels (pixel X coordinates are between 0 and width-1, inclusive)
......@@ -4922,7 +5115,7 @@ import ij.text.TextWindow;
for (int i=0;i<this.sensorMasks[chNum].length;i++) if (preMask[1][i]>0.0) this.sensorMasks[chNum][i]=1.0;
}
if (rAverageNum==0.0) continue; // nothing to blur/process for this channel
rAverage/=rAverageNum; // average distance to the fartherst node from the current
rAverage/=rAverageNum; // average distance to the farthest node from the current
double sigma=sigmaUV;
if(sigma<0) sigma*=-rAverage;
gb.blurDouble(this.sensorMasks[chNum], dWidth, dHeight, sigma/decimate, sigma/decimate, 0.01);
......@@ -4930,6 +5123,36 @@ import ij.text.TextWindow;
return this.sensorMasks;
}
public double [] calculateSensorMasks(int chNum, int shrinkGridForMask, double sigmaUV) {
DoubleGaussianBlur gb=new DoubleGaussianBlur();
if ((this.debugLevel>1) && (SDFA_INSTANCE==null)) SDFA_INSTANCE=new ShowDoubleFloatArrays();
if (this.debugLevel>2)System.out.println("calculateSensorMasks("+shrinkGridForMask+","+sigmaUV+")");
int decimate = eyesisCameraParameters.getDecimateMasks(chNum);
int width = eyesisCameraParameters.getSensorWidth(chNum);
int height = eyesisCameraParameters.getSensorHeight(chNum);
int dWidth= (width -1)/decimate+1;
int dHeight= (height-1)/decimate+1;
this.sensorMasks[chNum]=new double[dWidth*dHeight];
for (int i=0;i<this.sensorMasks[chNum].length;i++) this.sensorMasks[chNum][i]=0.0;
double rAverage=0.0;
double rAverageNum=0.0;
for (int imgNum=0;imgNum<this.gIP.length;imgNum++) if (this.gIP[imgNum].channel==chNum){ // image is for this this channel
double [][] preMask=preCalculateSingleImageMask(imgNum, decimate, width, height, shrinkGridForMask);
if (preMask==null) continue; //nothing in this channel
rAverage+=preMask[0][0];
rAverageNum+=preMask[0][1];
for (int i=0;i<this.sensorMasks[chNum].length;i++) if (preMask[1][i]>0.0) this.sensorMasks[chNum][i]=1.0;
}
if (rAverageNum != 0.0) { // nothing to blur/process for this channel
rAverage/=rAverageNum; // average distance to the farthest node from the current
double sigma=sigmaUV;
if(sigma<0) sigma*=-rAverage;
gb.blurDouble(this.sensorMasks[chNum], dWidth, dHeight, sigma/decimate, sigma/decimate, 0.01);
}
return this.sensorMasks[chNum];
}
......
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
**
** RefineParameters.java - Parameters for sensor residual correction
**
** Copyright (C) 2011-2020 Elphel, Inc.
**
** -----------------------------------------------------------------------------**
**
** Distortions.java is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
** -----------------------------------------------------------------------------**
**
*/
package com.elphel.imagej.calibration;
import java.util.Properties;
import com.elphel.imagej.common.WindowTools;
import ij.gui.GenericDialog;
public class RefineParameters{
// New parameters 2020
public double center_fract = 0.5; // 0.5 of half-height
public double transit_fract = 0.2; // 0.2 of half-height - transition from center ortho to outer polar
public double gaus_ang = 0.2; // in radians
public double gaus_rad = 0.05; // in fractions of the full radius
public double max_diff_err_geom = 0.25; // before second pass linearly fade R/T and RGB where high-frequency error nears thios value
public double max_diff_err_photo = 0.25;
@Deprecated public boolean extrapolate=true; // extrapolate sensor distortion correction
@Deprecated public double alphaThreshold =0.8; // ignore sensor correction pixels with mask value below this
@Deprecated public double fatZero=0.01; // when extrapolatging color transfer coefficients (flat field) use this for logariphm
@Deprecated public double extrapolationSigma=30.0; // sigmna for Gaussian weight function when fittinga plane to known pixels
// calculated for non-decimated pixels
@Deprecated public double extrapolationKSigma=2.0; // consider pixels in 2*extrapolationSigma*extrapolationKSigma square when fitting
@Deprecated public boolean smoothCorrection=true; // apply Gaussian blur to calculated pixel correction field
@Deprecated public double smoothSigma=50.0; // sigma for Gaussian weight function when fittinga plane to known pixels
public double correctionScale=1.0; // scale correction when accumulating;
public boolean showCumulativeCorrection=false; // show correction afther this one is applied
public boolean showUnfilteredCorrection=true; // show this (additional) correction before extrapolation and/or smoothing
public boolean showExtrapolationCorrection=false; // show Extrapolation
public boolean showThisCorrection=false; // show this (additional) correction separately
public boolean showPerImage=false; // show residuals for each individual image
public int showIndividualNumber=0; // which image to show (-1 - all)
public boolean applyCorrection=true; // apply calculated corerction
public boolean applyFlatField=true; // apply calculated flat-field
public boolean grid3DCorrection=true; // Correct patetrn grid node locations in 3d (false - in 2d only)
public boolean rotateCorrection=true; // old value - did not yet understand why is it needed
public double grid3DMaximalZCorr=20.0; // Maximal Z-axis correction (if more will fall back to 2d correction algorithm)
public boolean useVariations= false; // allow different Z for different stations (for not a wall/stable pattern)
public double variationPenalty=0.001; // "stiffness" of individual (per-station) Z-values of the target pattern
public boolean fixXY= false; // adjust only Z of the target pattern, keep X and Y
public boolean resetVariations=false;
public boolean noFallBack= true; // may have bugs - not tested yet
@Deprecated public boolean usePatternAlpha= true; // use pattern grid alpha data, false - old calculation
// New individual parameters for modify pattern grid
public boolean targetShowPerImage=false;
public boolean targetShowThisCorrection=false;
public boolean targetApplyCorrection=true;
public double targetCorrectionScale=1.0; // scale correction when accumulating;
// New parameters for new sensor correction
@Deprecated public boolean sensorExtrapolateDiff = false; // true - extrapolate correction, false - composite
@Deprecated public double sensorShrinkBlurComboSigma = 50.0;
@Deprecated public double sensorShrinkBlurComboLevel = 0.25;
@Deprecated public double sensorAlphaThreshold = 0.1;
@Deprecated public double sensorStep = 5;
@Deprecated public double sensorInterpolationSigma= 100;
@Deprecated public double sensorTangentialRadius= 0.5;
@Deprecated public int sensorScanDistance= 200;
@Deprecated public int sensorResultDistance= 500;
@Deprecated public int sensorInterpolationDegree= 2;
//New parameters for Flat field correction
public int flatFieldSerNumber= -1;
public int flatFieldReferenceStation= 0;
public double flatFieldShrink= 100.0;
public double flatFieldNonVignettedRadius = 1000.0;
public double flatFieldMinimalAlpha = 0.01; // use %
public double flatFieldMinimalContrast= 0.1;
@Deprecated public double flatFieldMinimalAccumulate = 0.01; // use %
public double flatFieldShrinkForMatching = 2.0;
public double flatFieldMaxRelDiff = 0.1; // use %
public int flatFieldShrinkMask= 2;
public double flatFieldFadeBorder = 2.0;
public boolean flatFieldResetMask= true;
public boolean flatFieldShowSensorMasks=false;
public boolean flatFieldShowIndividual= false;
public boolean flatFieldShowResult= true;
public boolean flatFieldApplyResult= true;
public boolean flatFieldUseInterpolate= true;
public double flatFieldMaskThresholdOcclusion=0.15; // use %
public int flatFieldShrinkOcclusion= 2;
public double flatFieldFadeOcclusion= 2.0;
public boolean flatFieldIgnoreSensorFlatField= false;
// Other
public int repeatFlatFieldSensor=10; // TODO: add stop !
public double specularHighPassSigma= 10.0;
public double specularLowPassSigma= 2.0;
public double specularDiffFromAverageThreshold= 0.01;
public int specularNumIter= 5;
public boolean specularApplyNewWeights= true;
public boolean specularPositiveDiffOnly= true;
public int specularShowDebug= 1; // 0 - do not show, 1 - show on last iteration only, 2 - show always
public RefineParameters refineParametersSmall; // same parameters for a small sensor
public boolean is_small = false;
// will keep @Deprecated parameters, but remove them from dialogs
public RefineParameters(){}
public RefineParameters(
//new in 2020
double center_fract,
double transit_fract,
double gaus_ang,
double gaus_rad,
double max_diff_err_geom,
double max_diff_err_photo,
boolean extrapolate,
double alphaThreshold,
double fatZero,
double extrapolationSigma,
double extrapolationKSigma,
boolean smoothCorrection,
double smoothSigma,
double correctionScale,
boolean showCumulativeCorrection,
boolean showUnfilteredCorrection,
boolean showExtrapolationCorrection,
boolean showThisCorrection,
boolean showPerImage,
int showIndividualNumber, // which image to show (-1 - all)
boolean applyCorrection,
boolean applyFlatField, // apply calculated flat-field
boolean grid3DCorrection, // Correct patetrn grid node locations in 3d (false - in 2d only)
boolean rotateCorrection, // not clear
double grid3DMaximalZCorr, // Maximal Z-axis correc tion (if more will fall back to 2d correction algorithm)
boolean useVariations,
double variationPenalty, // "stiffness" of individual (per-station) Z-values of the target pattern
boolean fixXY,
boolean resetVariations,
boolean noFallBack, // may have bugs - not tested yet
boolean usePatternAlpha,
boolean targetShowPerImage,
boolean targetShowThisCorrection,
boolean targetApplyCorrection,
double targetCorrectionScale,
boolean sensorExtrapolateDiff,
double sensorShrinkBlurComboSigma,
double sensorShrinkBlurComboLevel,
double sensorAlphaThreshold,
double sensorStep,
double sensorInterpolationSigma,
double sensorTangentialRadius,
int sensorScanDistance,
int sensorResultDistance,
int sensorInterpolationDegree,
int flatFieldSerNumber,
int flatFieldReferenceStation,
double flatFieldShrink,
double flatFieldNonVignettedRadius,
double flatFieldMinimalAlpha,
double flatFieldMinimalContrast,
double flatFieldMinimalAccumulate,
double flatFieldShrinkForMatching,
double flatFieldMaxRelDiff,
int flatFieldShrinkMask,
double flatFieldFadeBorder,
boolean flatFieldResetMask,
boolean flatFieldShowSensorMasks,
boolean flatFieldShowIndividual,
boolean flatFieldShowResult,
boolean flatFieldApplyResult,
boolean flatFieldUseInterpolate,
double flatFieldMaskThresholdOcclusion,
int flatFieldShrinkOcclusion,
double flatFieldFadeOcclusion,
boolean flatFieldIgnoreSensorFlatField,
int repeatFlatFieldSensor,
double specularHighPassSigma,
double specularLowPassSigma,
double specularDiffFromAverageThreshold,
int specularNumIter,
boolean specularApplyNewWeights,
boolean specularPositiveDiffOnly,
int specularShowDebug,
RefineParameters refineParametersSmall, // same parameters for a small sensor
boolean is_small
){
//new in 2020
this.center_fract = center_fract;
this.transit_fract = transit_fract;
this.gaus_ang = gaus_ang;
this.gaus_rad = gaus_rad;
this.max_diff_err_geom = max_diff_err_geom;
this.max_diff_err_photo = max_diff_err_photo;
this.extrapolate=extrapolate;
this.alphaThreshold=alphaThreshold;
this.fatZero=fatZero; // when extrapolatging color transfer coefficients (flat field) use this for logariphm
this.extrapolationSigma=extrapolationSigma;
this.extrapolationKSigma=extrapolationKSigma;
this.smoothCorrection=smoothCorrection;
this.smoothSigma=smoothSigma;
this.correctionScale=correctionScale;
this.showCumulativeCorrection=showCumulativeCorrection;
this.showUnfilteredCorrection=showUnfilteredCorrection;
this.showExtrapolationCorrection=showExtrapolationCorrection;
this.showThisCorrection=showThisCorrection;
this.showPerImage=showPerImage;
this.showIndividualNumber=showIndividualNumber; // which image to show (-1 - all)
this.applyCorrection=applyCorrection;
this.applyFlatField=applyFlatField;
this.grid3DCorrection=grid3DCorrection;
this.rotateCorrection=rotateCorrection; // not clear
this.grid3DMaximalZCorr=grid3DMaximalZCorr; // Maximal Z-axis correc tion (if more will fall back to 2d correction algorithm)
this.useVariations=useVariations;
this.variationPenalty=variationPenalty; // "stiffness" of individual (per-station) Z-values of the target pattern
this.fixXY=fixXY;
this.resetVariations=resetVariations;
this.noFallBack= noFallBack; // may have bugs - not tested yet
this.usePatternAlpha=usePatternAlpha;
this.targetShowPerImage= targetShowPerImage;
this.targetShowThisCorrection= targetShowThisCorrection;
this.targetApplyCorrection= targetApplyCorrection;
this.targetCorrectionScale= targetCorrectionScale;
this.sensorExtrapolateDiff= sensorExtrapolateDiff;
this.sensorShrinkBlurComboSigma=sensorShrinkBlurComboSigma;
this.sensorShrinkBlurComboLevel=sensorShrinkBlurComboLevel;
this.sensorAlphaThreshold=sensorAlphaThreshold;
this.sensorStep=sensorStep;
this.sensorInterpolationSigma=sensorInterpolationSigma;
this.sensorTangentialRadius=sensorTangentialRadius;
this.sensorScanDistance=sensorScanDistance;
this.sensorResultDistance=sensorResultDistance;
this.sensorInterpolationDegree=sensorInterpolationDegree;
this.flatFieldSerNumber=flatFieldSerNumber;
this.flatFieldReferenceStation=flatFieldReferenceStation;
this.flatFieldShrink=flatFieldShrink;
this.flatFieldNonVignettedRadius=flatFieldNonVignettedRadius;
this.flatFieldMinimalAlpha=flatFieldMinimalAlpha;
this.flatFieldMinimalContrast=flatFieldMinimalContrast;
this.flatFieldMinimalAccumulate=flatFieldMinimalAccumulate;
this.flatFieldShrinkForMatching=flatFieldShrinkForMatching;
this.flatFieldMaxRelDiff=flatFieldMaxRelDiff;
this.flatFieldShrinkMask=flatFieldShrinkMask;
this.flatFieldFadeBorder=flatFieldFadeBorder;
this.flatFieldResetMask=flatFieldResetMask;
this.flatFieldShowSensorMasks=flatFieldShowSensorMasks;
this.flatFieldShowIndividual=flatFieldShowIndividual;
this.flatFieldShowResult=flatFieldShowResult;
this.flatFieldApplyResult=flatFieldApplyResult;
this.flatFieldUseInterpolate=flatFieldUseInterpolate;
this.flatFieldMaskThresholdOcclusion=flatFieldMaskThresholdOcclusion;
this.flatFieldShrinkOcclusion=flatFieldShrinkOcclusion;
this.flatFieldFadeOcclusion=flatFieldFadeOcclusion;
this.flatFieldIgnoreSensorFlatField=flatFieldIgnoreSensorFlatField;
// this.flatFieldUseSelectedChannels=flatFieldUseSelectedChannels;
this.repeatFlatFieldSensor=repeatFlatFieldSensor;
this.specularHighPassSigma=specularHighPassSigma;
this.specularLowPassSigma=specularLowPassSigma;
this.specularDiffFromAverageThreshold=specularDiffFromAverageThreshold;
this.specularNumIter=specularNumIter;
this.specularApplyNewWeights=specularApplyNewWeights;
this.specularPositiveDiffOnly=specularPositiveDiffOnly;
this.specularShowDebug=specularShowDebug;
this.refineParametersSmall=refineParametersSmall; // same parameters for a small sensor
this.is_small = is_small;
}
@Override
public RefineParameters clone(){
return new RefineParameters(
//new in 2020
this.center_fract,
this.transit_fract,
this.gaus_ang,
this.gaus_rad,
this.max_diff_err_geom,
this.max_diff_err_photo,
this.extrapolate,
this.alphaThreshold,
this.fatZero,
this.extrapolationSigma,
this.extrapolationKSigma,
this.smoothCorrection,
this.smoothSigma,
this.correctionScale,
this.showCumulativeCorrection,
this.showUnfilteredCorrection,
this.showExtrapolationCorrection,
this.showThisCorrection,
this.showPerImage,
this.showIndividualNumber,
this.applyCorrection,
this.applyFlatField,
this.grid3DCorrection,
this.rotateCorrection, // not clear
this.grid3DMaximalZCorr, // Maximal Z-axis correc tion (if more will fall back to 2d correction algorithm)
this.useVariations,
this.variationPenalty, // "stiffness" of individual (per-station) Z-values of the target pattern
this.fixXY,
this.resetVariations,
this.noFallBack, // may have bugs - not tested yet
this.usePatternAlpha,
this.targetShowPerImage,
this.targetShowThisCorrection,
this.targetApplyCorrection,
this.targetCorrectionScale,
this.sensorExtrapolateDiff,
this.sensorShrinkBlurComboSigma,
this.sensorShrinkBlurComboLevel,
this.sensorAlphaThreshold,
this.sensorStep,
this.sensorInterpolationSigma,
this.sensorTangentialRadius,
this.sensorScanDistance,
this.sensorResultDistance,
this.sensorInterpolationDegree,
this.flatFieldSerNumber,
this.flatFieldReferenceStation,
this.flatFieldShrink,
this.flatFieldNonVignettedRadius,
this.flatFieldMinimalAlpha,
this.flatFieldMinimalContrast,
this.flatFieldMinimalAccumulate,
this.flatFieldShrinkForMatching,
this.flatFieldMaxRelDiff,
this.flatFieldShrinkMask,
this.flatFieldFadeBorder,
this.flatFieldResetMask,
this.flatFieldShowSensorMasks,
this.flatFieldShowIndividual,
this.flatFieldShowResult,
this.flatFieldApplyResult,
this.flatFieldUseInterpolate,
this.flatFieldMaskThresholdOcclusion,
this.flatFieldShrinkOcclusion,
this.flatFieldFadeOcclusion,
this.flatFieldIgnoreSensorFlatField,
this.repeatFlatFieldSensor,
this.specularHighPassSigma,
this.specularLowPassSigma,
this.specularDiffFromAverageThreshold,
this.specularNumIter,
this.specularApplyNewWeights,
this.specularPositiveDiffOnly,
this.specularShowDebug,
this.refineParametersSmall,
this.is_small);
}
public void setProperties(String prefix,Properties properties){
//new in 2020
properties.setProperty(prefix+"center_fract", this.center_fract+"");
properties.setProperty(prefix+"transit_fract", this.transit_fract+"");
properties.setProperty(prefix+"gaus_ang", this.gaus_ang+"");
properties.setProperty(prefix+"gaus_rad", this.gaus_rad+"");
properties.setProperty(prefix+"max_diff_err_geom", this.max_diff_err_geom+"");
properties.setProperty(prefix+"max_diff_err_photo",this.max_diff_err_photo+"");
properties.setProperty(prefix+"extrapolate",this.extrapolate+"");
properties.setProperty(prefix+"alphaThreshold",this.alphaThreshold+"");
properties.setProperty(prefix+"fatZero",this.fatZero+"");
properties.setProperty(prefix+"extrapolationSigma",this.extrapolationSigma+"");
properties.setProperty(prefix+"extrapolationKSigma",this.extrapolationKSigma+"");
properties.setProperty(prefix+"smoothCorrection",this.smoothCorrection+"");
properties.setProperty(prefix+"smoothSigma",this.smoothSigma+"");
properties.setProperty(prefix+"correctionScale",this.correctionScale+"");
properties.setProperty(prefix+"showCumulativeCorrection",this.showCumulativeCorrection+"");
properties.setProperty(prefix+"showUnfilteredCorrection",this.showUnfilteredCorrection+"");
properties.setProperty(prefix+"showExtrapolationCorrection",this.showExtrapolationCorrection+"");
properties.setProperty(prefix+"showThisCorrection",this.showThisCorrection+"");
properties.setProperty(prefix+"showPerImage",this.showPerImage+"");
properties.setProperty(prefix+"showIndividualNumber",this.showIndividualNumber+"");
properties.setProperty(prefix+"applyCorrection",this.applyCorrection+"");
properties.setProperty(prefix+"applyFlatField",this.applyFlatField+"");
properties.setProperty(prefix+"grid3DCorrection",this.grid3DCorrection+"");
properties.setProperty(prefix+"rotateCorrection",this.rotateCorrection+"");
properties.setProperty(prefix+"grid3DMaximalZCorr",this.grid3DMaximalZCorr+"");
properties.setProperty(prefix+"useVariations",this.useVariations+"");
properties.setProperty(prefix+"variationPenalty",this.variationPenalty+"");
properties.setProperty(prefix+"fixXY",this.fixXY+"");
properties.setProperty(prefix+"resetVariations",this.resetVariations+"");
properties.setProperty(prefix+"noFallBack",this.noFallBack+"");
properties.setProperty(prefix+"usePatternAlpha",this.usePatternAlpha+"");
properties.setProperty(prefix+"targetShowPerImage",this.targetShowPerImage+"");
properties.setProperty(prefix+"targetShowThisCorrection",this.targetShowThisCorrection+"");
properties.setProperty(prefix+"targetApplyCorrection",this.targetApplyCorrection+"");
properties.setProperty(prefix+"targetCorrectionScale",this.targetCorrectionScale+"");
properties.setProperty(prefix+"sensorExtrapolateDiff",this.sensorExtrapolateDiff+"");
properties.setProperty(prefix+"sensorShrinkBlurComboSigma",this.sensorShrinkBlurComboSigma+"");
properties.setProperty(prefix+"sensorShrinkBlurComboLevel",this.sensorShrinkBlurComboLevel+"");
properties.setProperty(prefix+"sensorAlphaThreshold",this.sensorAlphaThreshold+"");
properties.setProperty(prefix+"sensorStep",this.sensorStep+"");
properties.setProperty(prefix+"sensorInterpolationSigma",this.sensorInterpolationSigma+"");
properties.setProperty(prefix+"sensorTangentialRadius",this.sensorTangentialRadius+"");
properties.setProperty(prefix+"sensorScanDistance",this.sensorScanDistance+"");
properties.setProperty(prefix+"sensorResultDistance",this.sensorResultDistance+"");
properties.setProperty(prefix+"sensorInterpolationDegree",this.sensorInterpolationDegree+"");
properties.setProperty(prefix+"flatFieldSerNumber",this.flatFieldSerNumber+"");
properties.setProperty(prefix+"flatFieldReferenceStation",this.flatFieldReferenceStation+"");
properties.setProperty(prefix+"flatFieldShrink",this.flatFieldShrink+"");
properties.setProperty(prefix+"flatFieldNonVignettedRadius",this.flatFieldNonVignettedRadius+"");
properties.setProperty(prefix+"flatFieldMinimalAlpha",this.flatFieldMinimalAlpha+"");
properties.setProperty(prefix+"flatFieldMinimalContrast",this.flatFieldMinimalContrast+"");
properties.setProperty(prefix+"flatFieldMinimalAccumulate",this.flatFieldMinimalAccumulate+"");
properties.setProperty(prefix+"flatFieldShrinkForMatching",this.flatFieldShrinkForMatching+"");
properties.setProperty(prefix+"flatFieldMaxRelDiff",this.flatFieldMaxRelDiff+"");
properties.setProperty(prefix+"flatFieldShrinkMask",this.flatFieldShrinkMask+"");
properties.setProperty(prefix+"flatFieldFadeBorder",this.flatFieldFadeBorder+"");
properties.setProperty(prefix+"flatFieldResetMask",this.flatFieldResetMask+"");
properties.setProperty(prefix+"flatFieldShowSensorMasks",this.flatFieldShowSensorMasks+"");
properties.setProperty(prefix+"flatFieldShowIndividual",this.flatFieldShowIndividual+"");
properties.setProperty(prefix+"flatFieldShowResult",this.flatFieldShowResult+"");
properties.setProperty(prefix+"flatFieldApplyResult",this.flatFieldApplyResult+"");
properties.setProperty(prefix+"flatFieldUseInterpolate",this.flatFieldUseInterpolate+"");
properties.setProperty(prefix+"flatFieldMaskThresholdOcclusion",this.flatFieldMaskThresholdOcclusion+"");
properties.setProperty(prefix+"flatFieldShrinkOcclusion",this.flatFieldShrinkOcclusion+"");
properties.setProperty(prefix+"flatFieldFadeOcclusion",this.flatFieldFadeOcclusion+"");
properties.setProperty(prefix+"flatFieldIgnoreSensorFlatField",this.flatFieldIgnoreSensorFlatField+"");
properties.setProperty(prefix+"repeatFlatFieldSensor",this.repeatFlatFieldSensor+"");
properties.setProperty(prefix+"specularHighPassSigma",this.specularHighPassSigma+"");
properties.setProperty(prefix+"specularLowPassSigma", this.specularLowPassSigma+"");
properties.setProperty(prefix+"specularDiffFromAverageThreshold",this.specularDiffFromAverageThreshold+"");
properties.setProperty(prefix+"specularNumIter",this.specularNumIter+"");
properties.setProperty(prefix+"specularApplyNewWeights",this.specularApplyNewWeights+"");
properties.setProperty(prefix+"specularPositiveDiffOnly",this.specularPositiveDiffOnly+"");
properties.setProperty(prefix+"specularShowDebug",this.specularShowDebug+"");
properties.setProperty(prefix+"is_small",this.is_small+"");
if (this.refineParametersSmall != null) {
/*
if (this.refineParametersSmall.refineParametersSmall != null) {
System.out.println("Multiple-recursive RefineParameters - should only be main and small");
System.out.println("*********** This is a bug! ***************");
this.refineParametersSmall.refineParametersSmall = null;
return;
}
*/
this.refineParametersSmall.setProperties(prefix+"SMALL.", properties);
}
}
public void getProperties(String prefix,Properties properties){
//new in 2020
if (properties.getProperty(prefix+"center_fract")!=null) this.center_fract=Double.parseDouble(properties.getProperty(prefix+"center_fract"));
if (properties.getProperty(prefix+"transit_fract")!=null) this.transit_fract=Double.parseDouble(properties.getProperty(prefix+"transit_fract"));
if (properties.getProperty(prefix+"gaus_ang")!=null) this.gaus_ang=Double.parseDouble(properties.getProperty(prefix+"gaus_ang"));
if (properties.getProperty(prefix+"gaus_rad")!=null) this.gaus_rad=Double.parseDouble(properties.getProperty(prefix+"gaus_rad"));
if (properties.getProperty(prefix+"max_diff_err_geom")!=null) this.max_diff_err_geom=Double.parseDouble(properties.getProperty(prefix+"max_diff_err_geom"));
if (properties.getProperty(prefix+"max_diff_err_photo")!=null) this.max_diff_err_photo=Double.parseDouble(properties.getProperty(prefix+"max_diff_err_photo"));
if (properties.getProperty(prefix+"extrapolate")!=null)
this.extrapolate=Boolean.parseBoolean(properties.getProperty(prefix+"extrapolate"));
if (properties.getProperty(prefix+"alphaThreshold")!=null)
this.alphaThreshold=Double.parseDouble(properties.getProperty(prefix+"alphaThreshold"));
if (properties.getProperty(prefix+"fatZero")!=null)
this.fatZero=Double.parseDouble(properties.getProperty(prefix+"fatZero"));
if (properties.getProperty(prefix+"extrapolationSigma")!=null)
this.extrapolationSigma=Double.parseDouble(properties.getProperty(prefix+"extrapolationSigma"));
if (properties.getProperty(prefix+"extrapolationKSigma")!=null)
this.extrapolationKSigma=Double.parseDouble(properties.getProperty(prefix+"extrapolationKSigma"));
if (properties.getProperty(prefix+"smoothCorrection")!=null)
this.smoothCorrection=Boolean.parseBoolean(properties.getProperty(prefix+"smoothCorrection"));
if (properties.getProperty(prefix+"smoothSigma")!=null)
this.smoothSigma=Double.parseDouble(properties.getProperty(prefix+"smoothSigma"));
if (properties.getProperty(prefix+"correctionScale")!=null)
this.correctionScale=Double.parseDouble(properties.getProperty(prefix+"correctionScale"));
if (properties.getProperty(prefix+"showCumulativeCorrection")!=null)
this.showCumulativeCorrection=Boolean.parseBoolean(properties.getProperty(prefix+"showCumulativeCorrection"));
if (properties.getProperty(prefix+"showUnfilteredCorrection")!=null)
this.showUnfilteredCorrection=Boolean.parseBoolean(properties.getProperty(prefix+"showUnfilteredCorrection"));
if (properties.getProperty(prefix+"showExtrapolationCorrection")!=null)
this.showExtrapolationCorrection=Boolean.parseBoolean(properties.getProperty(prefix+"showExtrapolationCorrection"));
if (properties.getProperty(prefix+"showThisCorrection")!=null)
this.showThisCorrection=Boolean.parseBoolean(properties.getProperty(prefix+"showThisCorrection"));
if (properties.getProperty(prefix+"showPerImage")!=null)
this.showPerImage=Boolean.parseBoolean(properties.getProperty(prefix+"showPerImage"));
if (properties.getProperty(prefix+"showIndividualNumber")!=null)
this.showIndividualNumber=Integer.parseInt(properties.getProperty(prefix+"showIndividualNumber"));
if (properties.getProperty(prefix+"applyCorrection")!=null)
this.applyCorrection=Boolean.parseBoolean(properties.getProperty(prefix+"applyCorrection"));
if (properties.getProperty(prefix+"applyFlatField")!=null)
this.applyFlatField=Boolean.parseBoolean(properties.getProperty(prefix+"applyFlatField"));
if (properties.getProperty(prefix+"grid3DCorrection")!=null)
this.grid3DCorrection=Boolean.parseBoolean(properties.getProperty(prefix+"grid3DCorrection"));
if (properties.getProperty(prefix+"rotateCorrection")!=null)
this.rotateCorrection=Boolean.parseBoolean(properties.getProperty(prefix+"rotateCorrection"));
if (properties.getProperty(prefix+"grid3DMaximalZCorr")!=null)
this.grid3DMaximalZCorr=Double.parseDouble(properties.getProperty(prefix+"grid3DMaximalZCorr"));
if (properties.getProperty(prefix+"useVariations")!=null)
this.useVariations=Boolean.parseBoolean(properties.getProperty(prefix+"useVariations"));
if (properties.getProperty(prefix+"variationPenalty")!=null)
this.variationPenalty=Double.parseDouble(properties.getProperty(prefix+"variationPenalty"));
if (properties.getProperty(prefix+"fixXY")!=null)
this.fixXY=Boolean.parseBoolean(properties.getProperty(prefix+"fixXY"));
if (properties.getProperty(prefix+"resetVariations")!=null)
this.resetVariations=Boolean.parseBoolean(properties.getProperty(prefix+"resetVariations"));
if (properties.getProperty(prefix+"noFallBack")!=null)
this.noFallBack=Boolean.parseBoolean(properties.getProperty(prefix+"noFallBack"));
if (properties.getProperty(prefix+"usePatternAlpha")!=null)
this.usePatternAlpha=Boolean.parseBoolean(properties.getProperty(prefix+"usePatternAlpha"));
if (properties.getProperty(prefix+"targetShowPerImage")!=null)
this.targetShowPerImage=Boolean.parseBoolean(properties.getProperty(prefix+"targetShowPerImage"));
if (properties.getProperty(prefix+"targetShowThisCorrection")!=null)
this.targetShowThisCorrection=Boolean.parseBoolean(properties.getProperty(prefix+"targetShowThisCorrection"));
if (properties.getProperty(prefix+"targetApplyCorrection")!=null)
this.targetApplyCorrection=Boolean.parseBoolean(properties.getProperty(prefix+"targetApplyCorrection"));
if (properties.getProperty(prefix+"targetCorrectionScale")!=null)
this.targetCorrectionScale=Double.parseDouble(properties.getProperty(prefix+"targetCorrectionScale"));
if (properties.getProperty(prefix+"sensorExtrapolateDiff")!=null)
this.sensorExtrapolateDiff=Boolean.parseBoolean(properties.getProperty(prefix+"sensorExtrapolateDiff"));
if (properties.getProperty(prefix+"sensorShrinkBlurComboSigma")!=null)
this.sensorShrinkBlurComboSigma=Double.parseDouble(properties.getProperty(prefix+"sensorShrinkBlurComboSigma"));
if (properties.getProperty(prefix+"sensorShrinkBlurComboLevel")!=null)
this.sensorShrinkBlurComboLevel=Double.parseDouble(properties.getProperty(prefix+"sensorShrinkBlurComboLevel"));
if (properties.getProperty(prefix+"sensorAlphaThreshold")!=null)
this.sensorAlphaThreshold=Double.parseDouble(properties.getProperty(prefix+"sensorAlphaThreshold"));
if (properties.getProperty(prefix+"sensorStep")!=null)
this.sensorStep=Double.parseDouble(properties.getProperty(prefix+"sensorStep"));
if (properties.getProperty(prefix+"sensorInterpolationSigma")!=null)
this.sensorInterpolationSigma=Double.parseDouble(properties.getProperty(prefix+"sensorInterpolationSigma"));
if (properties.getProperty(prefix+"sensorTangentialRadius")!=null)
this.sensorTangentialRadius=Double.parseDouble(properties.getProperty(prefix+"sensorTangentialRadius"));
if (properties.getProperty(prefix+"sensorScanDistance")!=null)
this.sensorScanDistance=Integer.parseInt(properties.getProperty(prefix+"sensorScanDistance"));
if (properties.getProperty(prefix+"sensorResultDistance")!=null)
this.sensorResultDistance=Integer.parseInt(properties.getProperty(prefix+"sensorResultDistance"));
if (properties.getProperty(prefix+"sensorInterpolationDegree")!=null)
this.sensorInterpolationDegree=Integer.parseInt(properties.getProperty(prefix+"sensorInterpolationDegree"));
if (properties.getProperty(prefix+"flatFieldSerNumber")!=null)
this.flatFieldSerNumber=Integer.parseInt(properties.getProperty(prefix+"flatFieldSerNumber"));
if (properties.getProperty(prefix+"flatFieldReferenceStation")!=null)
this.flatFieldReferenceStation=Integer.parseInt(properties.getProperty(prefix+"flatFieldReferenceStation"));
if (properties.getProperty(prefix+"flatFieldShrink")!=null)
this.flatFieldShrink=Double.parseDouble(properties.getProperty(prefix+"flatFieldShrink"));
if (properties.getProperty(prefix+"flatFieldNonVignettedRadius")!=null)
this.flatFieldNonVignettedRadius=Double.parseDouble(properties.getProperty(prefix+"flatFieldNonVignettedRadius"));
if (properties.getProperty(prefix+"flatFieldMinimalAlpha")!=null)
this.flatFieldMinimalAlpha=Double.parseDouble(properties.getProperty(prefix+"flatFieldMinimalAlpha"));
if (properties.getProperty(prefix+"flatFieldMinimalContrast")!=null)
this.flatFieldMinimalContrast=Double.parseDouble(properties.getProperty(prefix+"flatFieldMinimalContrast"));
if (properties.getProperty(prefix+"flatFieldMinimalAccumulate")!=null)
this.flatFieldMinimalAccumulate=Double.parseDouble(properties.getProperty(prefix+"flatFieldMinimalAccumulate"));
if (properties.getProperty(prefix+"flatFieldShrinkForMatching")!=null)
this.flatFieldShrinkForMatching=Double.parseDouble(properties.getProperty(prefix+"flatFieldShrinkForMatching"));
if (properties.getProperty(prefix+"flatFieldMaxRelDiff")!=null)
this.flatFieldMaxRelDiff=Double.parseDouble(properties.getProperty(prefix+"flatFieldMaxRelDiff"));
if (properties.getProperty(prefix+"flatFieldShrinkMask")!=null)
this.flatFieldShrinkMask=Integer.parseInt(properties.getProperty(prefix+"flatFieldShrinkMask"));
if (properties.getProperty(prefix+"flatFieldFadeBorder")!=null)
this.flatFieldFadeBorder=Double.parseDouble(properties.getProperty(prefix+"flatFieldFadeBorder"));
if (properties.getProperty(prefix+"flatFieldResetMask")!=null)
this.flatFieldResetMask=Boolean.parseBoolean(properties.getProperty(prefix+"flatFieldResetMask"));
if (properties.getProperty(prefix+"flatFieldShowSensorMasks")!=null)
this.flatFieldShowSensorMasks=Boolean.parseBoolean(properties.getProperty(prefix+"flatFieldShowSensorMasks"));
if (properties.getProperty(prefix+"flatFieldShowIndividual")!=null)
this.flatFieldShowIndividual=Boolean.parseBoolean(properties.getProperty(prefix+"flatFieldShowIndividual"));
if (properties.getProperty(prefix+"flatFieldShowResult")!=null)
this.flatFieldShowResult=Boolean.parseBoolean(properties.getProperty(prefix+"flatFieldShowResult"));
if (properties.getProperty(prefix+"flatFieldApplyResult")!=null)
this.flatFieldApplyResult=Boolean.parseBoolean(properties.getProperty(prefix+"flatFieldApplyResult"));
if (properties.getProperty(prefix+"flatFieldUseInterpolate")!=null)
this.flatFieldUseInterpolate=Boolean.parseBoolean(properties.getProperty(prefix+"flatFieldUseInterpolate"));
if (properties.getProperty(prefix+"flatFieldMaskThresholdOcclusion")!=null)
this.flatFieldMaskThresholdOcclusion=Double.parseDouble(properties.getProperty(prefix+"flatFieldMaskThresholdOcclusion"));
if (properties.getProperty(prefix+"flatFieldShrinkOcclusion")!=null)
this.flatFieldShrinkOcclusion=Integer.parseInt(properties.getProperty(prefix+"flatFieldShrinkOcclusion"));
if (properties.getProperty(prefix+"flatFieldFadeOcclusion")!=null)
this.flatFieldFadeOcclusion=Double.parseDouble(properties.getProperty(prefix+"flatFieldFadeOcclusion"));
if (properties.getProperty(prefix+"flatFieldIgnoreSensorFlatField")!=null)
this.flatFieldIgnoreSensorFlatField=Boolean.parseBoolean(properties.getProperty(prefix+"flatFieldIgnoreSensorFlatField"));
if (properties.getProperty(prefix+"repeatFlatFieldSensor")!=null)
this.repeatFlatFieldSensor=Integer.parseInt(properties.getProperty(prefix+"repeatFlatFieldSensor"));
if (properties.getProperty(prefix+"specularHighPassSigma")!=null)
this.specularHighPassSigma=Double.parseDouble(properties.getProperty(prefix+"specularHighPassSigma"));
if (properties.getProperty(prefix+"specularLowPassSigma")!=null)
this.specularLowPassSigma=Double.parseDouble(properties.getProperty(prefix+"specularLowPassSigma"));
if (properties.getProperty(prefix+"specularDiffFromAverageThreshold")!=null)
this.specularDiffFromAverageThreshold=Double.parseDouble(properties.getProperty(prefix+"specularDiffFromAverageThreshold"));
if (properties.getProperty(prefix+"specularNumIter")!=null)
this.specularNumIter=Integer.parseInt(properties.getProperty(prefix+"specularNumIter"));
if (properties.getProperty(prefix+"specularApplyNewWeights")!=null)
this.specularApplyNewWeights=Boolean.parseBoolean(properties.getProperty(prefix+"specularApplyNewWeights"));
if (properties.getProperty(prefix+"specularPositiveDiffOnly")!=null)
this.specularPositiveDiffOnly=Boolean.parseBoolean(properties.getProperty(prefix+"specularPositiveDiffOnly"));
if (properties.getProperty(prefix+"specularShowDebug")!=null)
this.specularShowDebug=Integer.parseInt(properties.getProperty(prefix+"specularShowDebug"));
if (properties.getProperty(prefix+"is_small")!=null) this.is_small=Boolean.parseBoolean(properties.getProperty(prefix+"is_small"));
if (properties.getProperty(prefix+"SMALL."+"is_small")!=null) {
this.refineParametersSmall = new RefineParameters();
this.refineParametersSmall.getProperties(prefix+"SMALL.", properties);
}
}
public int showDialog(String title, int parMask, int numSeries, double [] averageRGB, boolean include_lwir) { // average RGB?
int rslt = showDialogThis(title, parMask, numSeries, averageRGB, null);
if ((rslt < 0) || !include_lwir) {// (this.refineParametersSmall == null) || ) {
return rslt;
}
if (this.refineParametersSmall == null) {
this.refineParametersSmall = new RefineParameters(); // maybe add small defaults?
}
return this.refineParametersSmall.showDialogThis(title+"-small (LWIR) sensors", parMask, numSeries, averageRGB, this);
}
public int showDialogThis(String title, int parMask, int numSeries, double [] averageRGB, RefineParameters large) {
// sensor 0xfff, grid - 0xcc0 // cannot show result (cumulative) grid correction
GenericDialog gd = new GenericDialog(title);
if (numSeries>=0) gd.addNumericField("Fitting strategy series number (selects images to process) ", numSeries,0);
if ((parMask&0x200000)!=0) gd.addNumericField("Repeat target/sensor flat-field calculation", this.repeatFlatFieldSensor,0,3,"times");
// new parameters for expanding/blurring sensor distortions and photometrics
if ((parMask&0x1000000)!=0) gd.addMessage("Parameters for extrapolating sensors distortions and vignetting to the frame edges (2020)");
if ((parMask&0x1000000)!=0) gd.addNumericField("Center fraction (of half-height) used for orthogonal Gaussian blur", this.center_fract, 2,6,"");
if ((parMask&0x1000000)!=0) gd.addNumericField("Transition fraction (of half-height) between center ortho and peripheral polar extrapolatioon", this.transit_fract, 2,6,"");
if ((parMask&0x1000000)!=0) gd.addNumericField("Angular Gaussian sigma", this.gaus_ang, 2,6,"radian");
if ((parMask&0x1000000)!=0) gd.addNumericField("Radial and ortho (central) Gaussian sigma (fraction of half-height)", this.gaus_rad, 2,6,"");
if ((parMask&0x1000000)!=0) gd.addNumericField("Maximal high-frequency error to remove from the second pass (for distortions)", this.max_diff_err_geom, 2,6,"");
if ((parMask&0x1000000)!=0) gd.addNumericField("Maximal high-frequency error to remove from the second pass (for vignetting)", this.max_diff_err_photo, 2,6,"");
if ((parMask&0x1000000)!=0) gd.addMessage("---");
//sensorExtrapolateDiff
/// if ((parMask&0x80000)!=0) gd.addCheckbox("Extrapolate incremetal (not checked - cumulative) correction", this.sensorExtrapolateDiff);
/// if ((parMask&0x80000) !=0) gd.addNumericField("Shrink-blur combined sigma", this.sensorShrinkBlurComboSigma, 2,6,"sensor pixels"); // 20
/// if ((parMask&0x80000) !=0) gd.addNumericField("Shrink-blur combined level (-1..+1)", this.sensorShrinkBlurComboLevel, 2,6,""); // 0
/// if ((parMask&0x80000) !=0) gd.addNumericField("Combined alpha extrapolation threshold", this.sensorAlphaThreshold, 2,6,""); // normalize later?
/// if ((parMask&0x80000) !=0) gd.addNumericField("Extrapolation seed step",this.sensorStep, 1,4,"decimated pixels");
/// if ((parMask&0x80000) !=0) gd.addNumericField("Extrapolation gaussian sigma", this.sensorInterpolationSigma, 2,6,"sensor pixels"); // 50
/// if ((parMask&0x80000) !=0) gd.addNumericField("Extrapolation effective radius (doubling sigma in tangential direction)", this.sensorTangentialRadius, 2,6,"fraction of full image radius");
/// if ((parMask&0x80000) !=0) gd.addNumericField("Extrapolation half-square side for polynomial approximation", this.sensorScanDistance, 0,3,"sensor pixels");
/// if ((parMask&0x80000) !=0) gd.addNumericField("Extrapolation half-square side for extrapolation", this.sensorResultDistance, 0,3,"sensor pixels");
/// if ((parMask&0x80000) !=0) gd.addNumericField("Extrapolation polynomial degree", this.sensorInterpolationDegree, 0,1,"");
if ((parMask&0x100000)!=0) gd.addNumericField("Fitting series number (to select images), negative - use all enabled images (eo -> lwir)", this.flatFieldSerNumber,0);
if ((parMask&0x100000)!=0) gd.addNumericField("Reference station number (unity target brightness) (eo -> lwir)", this.flatFieldReferenceStation,0);
if ((parMask&0x100000)!=0) gd.addNumericField("Shrink sensor mask", this.flatFieldShrink, 1,6,"sensor pix");
if ((parMask&0x100000)!=0) gd.addNumericField("Non-vignetted radius", this.flatFieldNonVignettedRadius, 1,6,"sensor pix");
if ((parMask&0x100000)!=0) gd.addNumericField("Minimal alpha", 100.0*this.flatFieldMinimalAlpha, 3,7,"%");
if ((parMask&0x100000)!=0) gd.addNumericField("Minimal contrast (occlusion detection)", this.flatFieldMinimalContrast, 3,7,"(0 .. ~0.8");
/// if ((parMask&0x100000)!=0) gd.addNumericField("Minimal alpha for accumulation", 100.0*this.flatFieldMinimalAccumulate, 3,7,"%");
if ((parMask&0x100000)!=0) gd.addNumericField("Shrink pattern for matching (eo -> lwir)", this.flatFieldShrinkForMatching, 3,7,"grid nodes");
if ((parMask&0x100000)!=0) gd.addNumericField("Maximal relative difference between nodes (eo -> lwir)", 100.0*this.flatFieldMaxRelDiff, 3,7,"%");
if ((parMask&0x100000)!=0) gd.addNumericField("Shrink pattern border (eo -> lwir)", this.flatFieldShrinkMask, 0,3,"grid nodes");
if ((parMask&0x100000)!=0) gd.addNumericField("Fade pattern border (eo -> lwir)", this.flatFieldFadeBorder, 3,7,"grid nodes");
if ((parMask&0x100000)!=0) gd.addMessage("Update pattern white balance (if the illumination is yellowish, increase red and green here)");
if ((parMask&0x100000)!=0) gd.addNumericField("Average grid RED (1.0 for white)", averageRGB[0], 3,5,"x"); //
if ((parMask&0x100000)!=0) gd.addNumericField("Average grid GREEN (1.0 for white)", averageRGB[1], 3,5,"x"); //
if ((parMask&0x100000)!=0) gd.addNumericField("Average grid BLUE (1.0 for white)", averageRGB[2], 3,5,"x"); //
if ((parMask&0x100000)!=0) gd.addCheckbox("Reset pattern mask (eo -> lwir)", this.flatFieldResetMask);
if ((parMask&0x100000)!=0) gd.addCheckbox("Show non-vignetting sensor masks", this.flatFieldShowSensorMasks);
if ((parMask&0x100000)!=0) gd.addCheckbox("Show per-sensor patterns", this.flatFieldShowIndividual);
if ((parMask&0x100000)!=0) gd.addCheckbox("Show result mask", this.flatFieldShowResult);
if ((parMask&0x100000)!=0) gd.addCheckbox("Apply pattern flat field and mask",this.flatFieldApplyResult);
if ((parMask&0x100000)!=0) gd.addCheckbox("Use interpolation for sensor correction",this.flatFieldUseInterpolate);
if ((parMask&0x100000)!=0) gd.addNumericField("Suspect occlusion only if grid is missing in the area where sensor mask is above this threshold",100.0* this.flatFieldMaskThresholdOcclusion, 3,7,"%");
if ((parMask&0x100000)!=0) gd.addNumericField("Expand suspected occlusion area", this.flatFieldShrinkOcclusion, 0,3,"grid nodes");
if ((parMask&0x100000)!=0) gd.addNumericField("Fade grid on image (occlusion handling)", this.flatFieldFadeOcclusion, 3,7,"grid nodes");
if ((parMask&0x100000)!=0) gd.addCheckbox("Ignore existent sensor flat-field calibration",this.flatFieldIgnoreSensorFlatField);
if ((parMask&0x400000)!=0) gd.addMessage("Specular reflections removal parameters:");
if ((parMask&0x400000)!=0) gd.addCheckbox("Apply new (after removal of specular reflections) weights", this.specularApplyNewWeights);
if ((parMask&0x400000)!=0) gd.addCheckbox("Process only positive difference from average", this.specularPositiveDiffOnly);
if ((parMask&0x400000)!=0) gd.addNumericField("High-pass sigma for difference from average (to detect specular)",this.specularHighPassSigma, 3,7,"pix");
if ((parMask&0x400000)!=0) gd.addNumericField("Low-pass sigma for difference from average (to detect specular)",this.specularLowPassSigma, 3,7,"pix");
if ((parMask&0x400000)!=0) gd.addNumericField("Difference from average threshold", 100.0*this.specularDiffFromAverageThreshold, 3,7,"%");
if ((parMask&0x400000)!=0) gd.addNumericField("Number of iterations for calculating average", this.specularNumIter, 0);
if ((parMask&0x400000)!=0) gd.addNumericField("Debug show mode (0 - off, 1 - last iteration only, 2 - all iterations)",this.specularShowDebug, 0);
/// if ((parMask & 1) !=0) gd.addCheckbox ("Extrapolate correction results", this.extrapolate);
/// if ((parMask & 2) !=0) gd.addNumericField("Threshold alpha (discard pixels with mask below that value)", this.alphaThreshold,3);
/// if ((parMask &0x8000) !=0) gd.addNumericField("Fat zero for color trasfer functions", this.fatZero,3);
/// if ((parMask & 4) !=0) gd.addNumericField("Fitting radius for extrapolation, Gaussian weight function sigma (in non-decimated pixels) ", this.extrapolationSigma,3);
/// if ((parMask & 8) !=0) gd.addNumericField("Fitting scan half-size of the square, in multiples of Fitting Radius", this.extrapolationKSigma,3);
/// if ((parMask & 0x10) !=0) gd.addCheckbox ("Apply smoothing to the correction results", this.smoothCorrection);
/// if ((parMask & 0x20) !=0) gd.addNumericField("Smoothing sigma, in non-decimated pixels", this.smoothSigma,3);
if ((parMask & 0x40) !=0) gd.addCheckbox ("Apply correction", this.applyCorrection);
if ((parMask&0x40000) !=0) gd.addCheckbox ("Apply correction", this.targetApplyCorrection);
if ((parMask &0x4000) !=0) gd.addCheckbox ("Apply flat-field correction", this.applyFlatField);
if ((parMask & 0x80) !=0) gd.addNumericField("Scale correction before applying", this.correctionScale,3);
if ((parMask&0x40000) !=0) gd.addNumericField("Scale correction before applying", this.targetCorrectionScale,3);
if ((parMask & 0x100) !=0) gd.addCheckbox ("Show result (cumulative) correction", this.showCumulativeCorrection);
if ((parMask & 0x200) !=0) gd.addCheckbox ("Show additional correction before blurring",this.showUnfilteredCorrection);
if ((parMask & 0x200) !=0) gd.addCheckbox ("Show correction extrapolatiuon (polar)", this.showExtrapolationCorrection);
if ((parMask & 0x400) !=0) gd.addCheckbox ("Show this step (additional) correction", this.showThisCorrection);
if ((parMask&0x40000) !=0) gd.addCheckbox ("Show this (additional) target correction", this.targetShowThisCorrection);
if ((parMask & 0x800) !=0) gd.addCheckbox ("Show individual, per-image residuals", this.showPerImage); // used in 2020
if ((parMask&0x40000) !=0) gd.addCheckbox ("Show individual, per-image target residuals", this.targetShowPerImage);
if ((parMask&0x10000) !=0) gd.addNumericField("Show individual residuals for image number (<0 - all images)", this.showIndividualNumber,0);
if ((parMask &0x1000) !=0) gd.addCheckbox ("Correct patetrn grid node locations in 3d (false - in 2d only)", this.grid3DCorrection);
if ((parMask &0x1000) !=0) gd.addCheckbox ("Rotate final 3d pattern correction (?)", this.rotateCorrection);
if ((parMask&0x20000) !=0) gd.addNumericField("Maximal Z-axis correction (if more will fall back to 2d correction algorithm)", this.grid3DMaximalZCorr,1,3,"mm");
if ((parMask&0x20000) !=0) gd.addCheckbox ("Use Z-variations of the pattern for different stations", this.useVariations);
if ((parMask&0x20000) !=0) gd.addNumericField("Penalty for different Z for the same target nodes for different stations", 100.0*this.variationPenalty,3,7,"%");
if ((parMask&0x20000) !=0) gd.addCheckbox ("Keep X and Y pattern correction, adjust only Z",this.fixXY);
if ((parMask&0x20000) !=0) gd.addCheckbox ("Reset previous Z variations before calculating the new one", this.resetVariations);
if ((parMask&0x20000) !=0) gd.addCheckbox ("Do not fall back to 2-d calculation if 3d fails", this.noFallBack);
if (large != null) gd.addCheckbox ("Copy all parameters from the main sensors (large), ignore other filedsr", false);
//large
/// if ((parMask &0x2000) !=0) gd.addCheckbox ("Use pattern grid alpha data", this.usePatternAlpha);
WindowTools.addScrollBars(gd);
gd.showDialog();
if (gd.wasCanceled()) return -1;
int selectedSeries=0;
if (numSeries>=0) selectedSeries= (int) gd.getNextNumber();
if ((parMask&0x200000)!=0) this.repeatFlatFieldSensor= (int) gd.getNextNumber();
// new in 2020
if ((parMask&0x1000000)!=0) this.center_fract= gd.getNextNumber();
if ((parMask&0x1000000)!=0) this.transit_fract= gd.getNextNumber();
if ((parMask&0x1000000)!=0) this.gaus_ang= gd.getNextNumber();
if ((parMask&0x1000000)!=0) this.gaus_rad= gd.getNextNumber();
if ((parMask&0x1000000)!=0) this.max_diff_err_geom= gd.getNextNumber();
if ((parMask&0x1000000)!=0) this.max_diff_err_photo= gd.getNextNumber();
/// if ((parMask&0x80000) !=0) this.sensorExtrapolateDiff= gd.getNextBoolean();
/// if ((parMask&0x80000) !=0) this.sensorShrinkBlurComboSigma= gd.getNextNumber();
/// if ((parMask&0x80000) !=0) this.sensorShrinkBlurComboLevel= gd.getNextNumber();
/// if ((parMask&0x80000) !=0) this.sensorAlphaThreshold= gd.getNextNumber();
/// if ((parMask&0x80000) !=0) this.sensorStep= gd.getNextNumber();
/// if ((parMask&0x80000) !=0) this.sensorInterpolationSigma= gd.getNextNumber();
/// if ((parMask&0x80000) !=0) this.sensorTangentialRadius= gd.getNextNumber();
/// if ((parMask&0x80000) !=0) this.sensorScanDistance= (int) gd.getNextNumber();
/// if ((parMask&0x80000) !=0) this.sensorResultDistance= (int) gd.getNextNumber();
/// if ((parMask&0x80000) !=0) this.sensorInterpolationDegree=(int) gd.getNextNumber();
if ((parMask&0x100000)!=0) this.flatFieldSerNumber= (int) gd.getNextNumber();
if ((parMask&0x100000)!=0) this.flatFieldReferenceStation= (int) gd.getNextNumber();
if ((parMask&0x100000)!=0) this.flatFieldShrink= gd.getNextNumber();
if ((parMask&0x100000)!=0) this.flatFieldNonVignettedRadius= gd.getNextNumber();
if ((parMask&0x100000)!=0) this.flatFieldMinimalAlpha= 0.01*gd.getNextNumber();
if ((parMask&0x100000)!=0) this.flatFieldMinimalContrast= gd.getNextNumber();
/// if ((parMask&0x100000)!=0) this.flatFieldMinimalAccumulate= 0.01*gd.getNextNumber();
if ((parMask&0x100000)!=0) this.flatFieldShrinkForMatching= gd.getNextNumber();
if ((parMask&0x100000)!=0) this.flatFieldMaxRelDiff= 0.01*gd.getNextNumber();
if ((parMask&0x100000)!=0) this.flatFieldShrinkMask= (int) gd.getNextNumber();
if ((parMask&0x100000)!=0) this.flatFieldFadeBorder= gd.getNextNumber();
if ((parMask&0x100000)!=0) averageRGB[0]= gd.getNextNumber();
if ((parMask&0x100000)!=0) averageRGB[1]= gd.getNextNumber();
if ((parMask&0x100000)!=0) averageRGB[2]= gd.getNextNumber();
if ((parMask&0x100000)!=0) this.flatFieldResetMask= gd.getNextBoolean();
if ((parMask&0x100000)!=0) this.flatFieldShowSensorMasks= gd.getNextBoolean();
if ((parMask&0x100000)!=0) this.flatFieldShowIndividual= gd.getNextBoolean();
if ((parMask&0x100000)!=0) this.flatFieldShowResult= gd.getNextBoolean();
if ((parMask&0x100000)!=0) this.flatFieldApplyResult= gd.getNextBoolean();
if ((parMask&0x100000)!=0) this.flatFieldUseInterpolate= gd.getNextBoolean();
if ((parMask&0x100000)!=0) this.flatFieldMaskThresholdOcclusion=0.01*gd.getNextNumber();
if ((parMask&0x100000)!=0) this.flatFieldShrinkOcclusion= (int) gd.getNextNumber();
if ((parMask&0x100000)!=0) this.flatFieldFadeOcclusion= gd.getNextNumber();
if ((parMask&0x100000)!=0) this.flatFieldIgnoreSensorFlatField= gd.getNextBoolean();
if ((parMask&0x400000)!=0) this.specularApplyNewWeights= gd.getNextBoolean();
if ((parMask&0x400000)!=0) this.specularPositiveDiffOnly= gd.getNextBoolean();
if ((parMask&0x400000)!=0) this.specularHighPassSigma= gd.getNextNumber();
if ((parMask&0x400000)!=0) this.specularLowPassSigma= gd.getNextNumber();
if ((parMask&0x400000)!=0) this.specularDiffFromAverageThreshold=0.01*gd.getNextNumber();;
if ((parMask&0x400000)!=0) this.specularNumIter= (int) gd.getNextNumber();
if ((parMask&0x400000)!=0) this.specularShowDebug= (int) gd.getNextNumber();
// if ((parMask & 1) !=0) this.extrapolate= gd.getNextBoolean();
// if ((parMask & 2) !=0) this.alphaThreshold= gd.getNextNumber();
// if ((parMask &0x8000) !=0) this.fatZero= gd.getNextNumber();
// if ((parMask & 4) !=0) this.extrapolationSigma= gd.getNextNumber();
// if ((parMask & 8) !=0) this.extrapolationKSigma= gd.getNextNumber();
// if ((parMask & 0x10) !=0) this.smoothCorrection= gd.getNextBoolean();
// if ((parMask & 0x20) !=0) this.smoothSigma= gd.getNextNumber();
if ((parMask & 0x40) !=0) this.applyCorrection= gd.getNextBoolean();
if ((parMask&0x40000) !=0) this.targetApplyCorrection= gd.getNextBoolean();
if ((parMask &0x4000) !=0) this.applyFlatField= gd.getNextBoolean();
if ((parMask & 0x80) !=0) this.correctionScale= gd.getNextNumber();
if ((parMask&0x40000) !=0) this.targetCorrectionScale= gd.getNextNumber();
if ((parMask & 0x100) !=0) this.showCumulativeCorrection= gd.getNextBoolean();
if ((parMask & 0x200) !=0) this.showUnfilteredCorrection= gd.getNextBoolean();
if ((parMask & 0x200) !=0) this.showExtrapolationCorrection= gd.getNextBoolean();
if ((parMask & 0x400) !=0) this.showThisCorrection= gd.getNextBoolean();
if ((parMask&0x40000) !=0) this.targetShowThisCorrection= gd.getNextBoolean();
if ((parMask & 0x800) !=0) this.showPerImage= gd.getNextBoolean();
if ((parMask&0x40000) !=0) this.targetShowPerImage= gd.getNextBoolean();
if ((parMask&0x10000) !=0) this.showIndividualNumber=(int)gd.getNextNumber();
if ((parMask &0x1000) !=0) this.grid3DCorrection= gd.getNextBoolean();
if ((parMask &0x1000) !=0) this.rotateCorrection= gd.getNextBoolean();
if ((parMask&0x20000) !=0) this.grid3DMaximalZCorr= gd.getNextNumber();
if ((parMask&0x20000) !=0) this.useVariations= gd.getNextBoolean();
if ((parMask&0x20000) !=0) this.variationPenalty = 0.01*gd.getNextNumber();
if ((parMask&0x20000) !=0) this.fixXY= gd.getNextBoolean();
if ((parMask&0x20000) !=0) this.resetVariations= gd.getNextBoolean();
if ((parMask&0x20000) !=0) this.noFallBack= gd.getNextBoolean();
// if ((parMask &0x2000) !=0) this.usePatternAlpha= gd.getNextBoolean();
if ((large != null) && gd.getNextBoolean()) {
copyFrom(large);
return this.refineParametersSmall.showDialogThis(title, parMask, numSeries, averageRGB, large);
}
return selectedSeries;
}
private void copyFrom(RefineParameters other) {
this.center_fract = other.center_fract;
this.transit_fract = other.transit_fract;
this.gaus_ang = other.gaus_ang;
this.gaus_rad = other.gaus_rad;
this.max_diff_err_geom = other.max_diff_err_geom;
this.max_diff_err_photo = other.max_diff_err_photo;
this.extrapolate= other.extrapolate;
this.alphaThreshold= other.alphaThreshold;
this.fatZero= other.fatZero; // when extrapolatging color transfer coefficients (flat field) use this for logariphm
this.extrapolationSigma= other.extrapolationSigma;
this.extrapolationKSigma= other.extrapolationKSigma;
this.smoothCorrection= other.smoothCorrection;
this.smoothSigma= other.smoothSigma;
this.correctionScale= other.correctionScale;
this.showCumulativeCorrection= other.showCumulativeCorrection;
this.showUnfilteredCorrection= other.showUnfilteredCorrection;
this.showExtrapolationCorrection= other.showExtrapolationCorrection;
this.showThisCorrection= other.showThisCorrection;
this.showPerImage= other.showPerImage;
this.showIndividualNumber= other.showIndividualNumber; // which image to show (-1 - all)
this.applyCorrection= other.applyCorrection;
this.applyFlatField= other.applyFlatField;
this.grid3DCorrection= other.grid3DCorrection;
this.rotateCorrection= other.rotateCorrection; // not clear
this.grid3DMaximalZCorr= other.grid3DMaximalZCorr; // Maximal Z-axis correc tion (if more will fall back to 2d correction algorithm)
this.useVariations= other.useVariations;
this.variationPenalty= other.variationPenalty; // "stiffness" of individual (per-station) Z-values of the target pattern
this.fixXY= other.fixXY;
this.resetVariations= other.resetVariations;
this.noFallBack= other.noFallBack; // may have bugs - not tested yet
this.usePatternAlpha= other.usePatternAlpha;
this.targetShowPerImage= other.targetShowPerImage;
this.targetShowThisCorrection= other.targetShowThisCorrection;
this.targetApplyCorrection= other.targetApplyCorrection;
this.targetCorrectionScale= other.targetCorrectionScale;
this.sensorExtrapolateDiff= other.sensorExtrapolateDiff;
this.sensorShrinkBlurComboSigma= other.sensorShrinkBlurComboSigma;
this.sensorShrinkBlurComboLevel= other.sensorShrinkBlurComboLevel;
this.sensorAlphaThreshold= other.sensorAlphaThreshold;
this.sensorStep= other.sensorStep;
this.sensorInterpolationSigma= other.sensorInterpolationSigma;
this.sensorTangentialRadius= other.sensorTangentialRadius;
this.sensorScanDistance= other.sensorScanDistance;
this.sensorResultDistance= other.sensorResultDistance;
this.sensorInterpolationDegree= other.sensorInterpolationDegree;
this.flatFieldSerNumber= other.flatFieldSerNumber;
this.flatFieldReferenceStation= other.flatFieldReferenceStation;
this.flatFieldShrink= other.flatFieldShrink;
this.flatFieldNonVignettedRadius= other.flatFieldNonVignettedRadius;
this.flatFieldMinimalAlpha= other.flatFieldMinimalAlpha;
this.flatFieldMinimalContrast= other.flatFieldMinimalContrast;
this.flatFieldMinimalAccumulate= other.flatFieldMinimalAccumulate;
this.flatFieldShrinkForMatching= other.flatFieldShrinkForMatching;
this.flatFieldMaxRelDiff= other.flatFieldMaxRelDiff;
this.flatFieldShrinkMask= other.flatFieldShrinkMask;
this.flatFieldFadeBorder= other.flatFieldFadeBorder;
this.flatFieldResetMask= other.flatFieldResetMask;
this.flatFieldShowSensorMasks= other.flatFieldShowSensorMasks;
this.flatFieldShowIndividual= other.flatFieldShowIndividual;
this.flatFieldShowResult= other.flatFieldShowResult;
this.flatFieldApplyResult= other.flatFieldApplyResult;
this.flatFieldUseInterpolate= other.flatFieldUseInterpolate;
this.flatFieldMaskThresholdOcclusion= other.flatFieldMaskThresholdOcclusion;
this.flatFieldShrinkOcclusion= other.flatFieldShrinkOcclusion;
this.flatFieldFadeOcclusion= other.flatFieldFadeOcclusion;
this.flatFieldIgnoreSensorFlatField= other.flatFieldIgnoreSensorFlatField;
this.repeatFlatFieldSensor= other.repeatFlatFieldSensor;
this.specularHighPassSigma= other.specularHighPassSigma;
this.specularLowPassSigma= other.specularLowPassSigma;
this.specularDiffFromAverageThreshold= other.specularDiffFromAverageThreshold;
this.specularNumIter= other.specularNumIter;
this.specularApplyNewWeights= other.specularApplyNewWeights;
this.specularPositiveDiffOnly= other.specularPositiveDiffOnly;
this.specularShowDebug= other.specularShowDebug;
}
public boolean isSmall() {
return is_small;
}
public RefineParameters getSmall() {
return this.refineParametersSmall;
}
}
\ No newline at end of file
......@@ -73,6 +73,10 @@ import ij.gui.GenericDialog;
public int shrinkGridForMask=4; //2; //shrink detected grids by one point for/vert this number of times before calculating masks
public double maskBlurSigma= -3; //2.0; // blur sensor masks (>0 - pixels, <0 - in grid units)
public boolean replaceBad = false; // fix bad nodes x/y, false - keep (2020)
public boolean removeWorst = false; // remove completely locally worst nodes
public double weightBad = 0.3; // reduce contrast of bad nodes
public double weightWorst = 0.05; // reduce contrast of bad, local worst nodes
public double badNodeThreshold=0.1; // filter out grid nodes with difference from quadratically predicted from 8 neighbors in pixels
public int maxBadNeighb= 1; // maximal number of bad nodes around the corrected one to fix
public int minimalValidNodes=10; // do not use images with less than this number of non-zero nodes (after all applicable weight masks)
......@@ -80,6 +84,9 @@ import ij.gui.GenericDialog;
public double weightMultiExponent= 1.0;
public double weightDiameterExponent=1.0; // if( >0) use grid diameter to scale weights of this image
public double weightYtoX=1.0; // relative Y-to-X errors weight (to somewhat compensate for rectabular shape of the sensor)
public double gridMarginScale = 0.2; // apply -scaled maximal to grid margins (_extra) for masks
public double minimalGridContrast=0.4; // (normally max ~0.8)
public double shrinkBlurSigma = 4.0;
public double shrinkBlurLevel = 0.5;
......@@ -341,6 +348,10 @@ import ij.gui.GenericDialog;
int shrinkGridForMask, //shrink detected grids by one point for/vert this number of times before calculating masks
double maskBlurSigma, // blur sensor masks (in grid units)
int decimateMasks, // reduce masks resolution
boolean replaceBad,
boolean removeWorst,
double weightBad,
double weightWorst,
double badNodeThreshold, // filter out grid nodes with difference from quadratically predicted from 8 neighbors in pixels
int maxBadNeighb, // maximal number of bad nodes around the corrected one to fix
int minimalValidNodes,
......@@ -348,6 +359,7 @@ import ij.gui.GenericDialog;
double weightMultiExponent,
double weightDiameterExponent, // if( >0) use grid diameter to scale weights of this image
double weightYtoX,
double gridMarginScale,
double minimalGridContrast,
double shrinkBlurSigma,
double shrinkBlurLevel,
......@@ -377,6 +389,10 @@ import ij.gui.GenericDialog;
shrinkGridForMask, //shrink detected grids by one point for/vert this number of times before calculating masks
maskBlurSigma, // blur sensor masks (in grid units)
decimateMasks, // reduce masks resolution
replaceBad,
removeWorst,
weightBad,
weightWorst,
badNodeThreshold, // filter out grid nodes with difference from quadratically predicted from 8 neighbors in pixels
maxBadNeighb, // maximal number of bad nodes around the corrected one to fix
minimalValidNodes,
......@@ -384,6 +400,7 @@ import ij.gui.GenericDialog;
weightMultiExponent,
weightDiameterExponent, // if( >0) use grid diameter to scale weights of this image
weightYtoX,
gridMarginScale,
minimalGridContrast,
shrinkBlurSigma,
shrinkBlurLevel,
......@@ -413,6 +430,10 @@ import ij.gui.GenericDialog;
int shrinkGridForMask, //shrink detected grids by one point for/vert this number of times before calculating masks
double maskBlurSigma, // blur sensor masks (in grid units)
int decimateMasks, // reduce masks resolution
boolean replaceBad,
boolean removeWorst,
double weightBad,
double weightWorst,
double badNodeThreshold, // filter out grid nodes with difference from quadratically predicted from 8 neighbors in pixels
int maxBadNeighb, // maximal number of bad nodes around the corrected one to fix
int minimalValidNodes,
......@@ -420,6 +441,7 @@ import ij.gui.GenericDialog;
double weightMultiExponent,
double weightDiameterExponent, // if( >0) use grid diameter to scale weights of this image
double weightYtoX,
double gridMarginScale,
double minimalGridContrast,
double shrinkBlurSigma,
double shrinkBlurLevel,
......@@ -448,6 +470,10 @@ import ij.gui.GenericDialog;
shrinkGridForMask, //shrink detected grids by one point for/vert this number of times before calculating masks
maskBlurSigma, // blur sensor masks (in grid units)
decimateMasks, // reduce masks resolution
replaceBad,
removeWorst,
weightBad,
weightWorst,
badNodeThreshold, // filter out grid nodes with difference from quadratically predicted from 8 neighbors in pixels
maxBadNeighb, // maximal number of bad nodes around the corrected one to fix
minimalValidNodes,
......@@ -455,6 +481,7 @@ import ij.gui.GenericDialog;
weightMultiExponent,
weightDiameterExponent, // if( >0) use grid diameter to scale weights of this image
weightYtoX,
gridMarginScale,
minimalGridContrast,
shrinkBlurSigma,
shrinkBlurLevel,
......@@ -484,6 +511,10 @@ import ij.gui.GenericDialog;
int shrinkGridForMask, //shrink detected grids by one point for/vert this number of times before calculating masks
double maskBlurSigma, // blur sensor masks (in grid units)
int defaultDecimateMasks, // reduce masks resolution
boolean replaceBad,
boolean removeWorst,
double weightBad,
double weightWorst,
double badNodeThreshold, // filter out grid nodes with difference from quadratically predicted from 8 neighbors in pixels
int maxBadNeighb, // maximal number of bad nodes around the corrected one to fix
int minimalValidNodes,
......@@ -491,6 +522,7 @@ import ij.gui.GenericDialog;
double weightMultiExponent,
double weightDiameterExponent, // if( >0) use grid diameter to scale weights of this image
double weightYtoX,
double gridMarginScale,
double minimalGridContrast,
double shrinkBlurSigma,
double shrinkBlurLevel,
......@@ -507,6 +539,10 @@ import ij.gui.GenericDialog;
this.shrinkGridForMask=shrinkGridForMask; //shrink detected grids by one point for/vert this number of times before calculating masks
this.maskBlurSigma=maskBlurSigma; // blur sensor masks (in grid units)
this.defaultDecimateMasks=defaultDecimateMasks;
this.replaceBad = replaceBad;
this.removeWorst = removeWorst;
this.weightBad = weightBad;
this.weightWorst = weightWorst;
this.badNodeThreshold=badNodeThreshold; // filter out grid nodes with difference from quadratically predicted from 8 neighbors in pixels
this.maxBadNeighb=maxBadNeighb; // maximal number of bad nodes around the corrected one to fix
this.minimalValidNodes=minimalValidNodes;
......@@ -514,6 +550,7 @@ import ij.gui.GenericDialog;
this.weightMultiExponent=weightMultiExponent;
this.weightDiameterExponent=weightDiameterExponent; // if( >0) use grid diameter to scale weights of this image
this.weightYtoX=weightYtoX;
this.gridMarginScale=gridMarginScale;
this.minimalGridContrast=minimalGridContrast;
this.goniometerHorizontal=new double[numStations];
this.goniometerAxial=new double[numStations];
......@@ -570,6 +607,10 @@ import ij.gui.GenericDialog;
destination.shrinkGridForMask=source.shrinkGridForMask; //shrink detected grids by one point for/vert this number of times before calculating masks
destination.maskBlurSigma=source.maskBlurSigma; // blur sensor masks (in grid units)
destination.defaultDecimateMasks=source.defaultDecimateMasks;
destination.replaceBad = source.replaceBad;
destination.removeWorst = source.removeWorst;
destination.weightBad = source.weightBad;
destination.weightWorst = source.weightWorst;
destination.badNodeThreshold=source.badNodeThreshold; // filter out grid nodes with difference from quadratically predicted from 8 neighbors in pixels
destination.maxBadNeighb=source.maxBadNeighb; // maximal number of bad nodes around the corrected one to fix
destination.minimalValidNodes=source.minimalValidNodes;
......@@ -577,6 +618,7 @@ import ij.gui.GenericDialog;
destination.weightMultiExponent= source.weightMultiExponent; // if( >0) use grid diameter to scale weights of this image
destination.weightDiameterExponent=source.weightDiameterExponent;
destination.weightYtoX=source.weightYtoX;
destination.gridMarginScale=source.gridMarginScale;
destination.minimalGridContrast=source.minimalGridContrast;
destination.shrinkBlurSigma=source.shrinkBlurSigma;
destination.shrinkBlurLevel=source.shrinkBlurLevel;
......@@ -627,6 +669,10 @@ import ij.gui.GenericDialog;
properties.setProperty(prefix+"shrinkGridForMask",this.shrinkGridForMask+"");
properties.setProperty(prefix+"maskBlurSigma",this.maskBlurSigma+"");
properties.setProperty(prefix+"defaultDecimateMasks",this.defaultDecimateMasks+"");
properties.setProperty(prefix+"replaceBad", this.replaceBad+"");
properties.setProperty(prefix+"removeWorst", this.removeWorst+"");
properties.setProperty(prefix+"weightBad", this.weightBad+"");
properties.setProperty(prefix+"weightWorst",this.weightWorst+"");
properties.setProperty(prefix+"badNodeThreshold",this.badNodeThreshold+"");
properties.setProperty(prefix+"maxBadNeighb",this.maxBadNeighb+"");
properties.setProperty(prefix+"minimalValidNodes",this.minimalValidNodes+"");
......@@ -634,6 +680,7 @@ import ij.gui.GenericDialog;
properties.setProperty(prefix+"weightMultiExponent",this.weightMultiExponent+"");
properties.setProperty(prefix+"weightDiameterExponent",this.weightDiameterExponent+"");
properties.setProperty(prefix+"weightYtoX",this.weightYtoX+"");
properties.setProperty(prefix+"gridMarginScale",this.gridMarginScale+"");
properties.setProperty(prefix+"minimalGridContrast",this.minimalGridContrast+"");
properties.setProperty(prefix+"shrinkBlurSigma",this.shrinkBlurSigma+"");
properties.setProperty(prefix+"shrinkBlurLevel",this.shrinkBlurLevel+"");
......@@ -687,6 +734,16 @@ import ij.gui.GenericDialog;
if (properties.getProperty(prefix+"maskBlurSigma")!=null)
this.maskBlurSigma=Double.parseDouble(properties.getProperty(prefix+"maskBlurSigma"));
if (properties.getProperty(prefix+"replaceBad")!=null)
this.replaceBad=Boolean.parseBoolean(properties.getProperty(prefix+"replaceBad"));
if (properties.getProperty(prefix+"removeWorst")!=null)
this.removeWorst=Boolean.parseBoolean(properties.getProperty(prefix+"removeWorst"));
if (properties.getProperty(prefix+"weightBad")!=null)
this.weightBad=Double.parseDouble(properties.getProperty(prefix+"weightBad"));
if (properties.getProperty(prefix+"weightWorst")!=null)
this.weightWorst=Double.parseDouble(properties.getProperty(prefix+"weightWorst"));
if (properties.getProperty(prefix+"badNodeThreshold")!=null)
this.badNodeThreshold=Double.parseDouble(properties.getProperty(prefix+"badNodeThreshold"));
if (properties.getProperty(prefix+"maxBadNeighb")!=null)
......@@ -701,6 +758,8 @@ import ij.gui.GenericDialog;
this.weightDiameterExponent=Double.parseDouble(properties.getProperty(prefix+"weightDiameterExponent"));
if (properties.getProperty(prefix+"weightYtoX")!=null)
this.weightYtoX=Double.parseDouble(properties.getProperty(prefix+"weightYtoX"));
if (properties.getProperty(prefix+"gridMarginScale")!=null)
this.gridMarginScale=Double.parseDouble(properties.getProperty(prefix+"gridMarginScale"));
if (properties.getProperty(prefix+"minimalGridContrast")!=null)
this.minimalGridContrast=Double.parseDouble(properties.getProperty(prefix+"minimalGridContrast"));
if (properties.getProperty(prefix+"shrinkBlurSigma")!=null)
......@@ -865,6 +924,11 @@ import ij.gui.GenericDialog;
gd.addNumericField("Gaussian blur masks for the sensors (positive - pixels, negative - grid half-periods)", this.maskBlurSigma, 2,6,"pix");
gd.addNumericField("Reduce sensor resolution when calculating masks", this.defaultDecimateMasks, 0);
gd.addCheckbox ("Replace bad/locally worst nodes by interpolation", this.replaceBad);
gd.addCheckbox ("Rremove completely locally worst nodes ", this.removeWorst);
gd.addNumericField("Scale weight of bad nodes", this.weightBad, 3,6,"");
gd.addNumericField("Scale weight of bad, locally worst nodes", this.weightWorst, 3,6,"");
gd.addNumericField("Filter out grid nodes with difference from quadratically predicted from 8 neighbors", this.badNodeThreshold, 2,6,"pix");
gd.addNumericField("Maximal number of bad nodes around the corrected one to fix", this.maxBadNeighb, 0);
gd.addNumericField("Minimal number of valid (with all filters applied) nodes in each image",this.minimalValidNodes, 0);
......@@ -872,6 +936,7 @@ import ij.gui.GenericDialog;
gd.addNumericField("Increase weight of the multi-image sets power (used with mode above)", this.weightMultiExponent, 2,6,"");
gd.addNumericField("Increase weight of the images by the power of their diameters", this.weightDiameterExponent, 2,6,"");
gd.addNumericField("Increase weight Y-error with respect to X-error", 100.0*this.weightYtoX, 2,6,"%");
gd.addNumericField("Apply -scaled maximal to grid margins (_extra) for masks", this.gridMarginScale, 2,6,"");
gd.addNumericField("Filter out grid nodes with the contrast less than this value (maximal is ~0.8) ", this.minimalGridContrast, 2,6,"");
gd.addNumericField("Shrink-blur detected grids alpha", this.shrinkBlurSigma, 2,6,"grid nodes");
gd.addNumericField("Shrink-blur detected grids level (-1..+1)", this.shrinkBlurLevel, 2,6,"");
......@@ -918,6 +983,10 @@ import ij.gui.GenericDialog;
this.shrinkGridForMask= (int) gd.getNextNumber();
this.maskBlurSigma= gd.getNextNumber();
this.defaultDecimateMasks=(int) gd.getNextNumber();
this.replaceBad = gd.getNextBoolean();
this.removeWorst = gd.getNextBoolean();
this.weightBad= gd.getNextNumber();
this.weightWorst= gd.getNextNumber();
this.badNodeThreshold= gd.getNextNumber();
this.maxBadNeighb= (int) gd.getNextNumber();
this.minimalValidNodes= (int) gd.getNextNumber();
......@@ -925,6 +994,7 @@ import ij.gui.GenericDialog;
this.weightMultiExponent= gd.getNextNumber();
this.weightDiameterExponent= gd.getNextNumber();
this.weightYtoX= 0.01*gd.getNextNumber();
this.gridMarginScale= gd.getNextNumber();
this.minimalGridContrast= gd.getNextNumber();
this.shrinkBlurSigma = gd.getNextNumber();
this.shrinkBlurLevel = gd.getNextNumber();
......
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