Commit 9d5dd318 authored by Andrey Filippov's avatar Andrey Filippov

refactoring + fixing sensor correction for different resolutions in the

same system
parent 5e90425c
......@@ -270,7 +270,7 @@ public class Aberration_Calibration extends PlugInFrame implements ActionListene
1.0, // shiftToRadiusContrib; // Center shift (in pixels) addition to the difference relative to radius difference (in pixels)
2.0, // sharpBonusPower; // increase weight of the "sharp" kernels by dividing weight by radius to this power
0.1, // maxFracDiscardWorse=0.1; // discard up to this fraction of samples that have larger radius (i.e. falling on the target seam that may only make PSF larger)
0.5, // maxFracDiscardAll=0.5; // continue removing outlayers (combined radius and shift), removing not more that this fraction (including maxFracDiscardWorse)
0.5, // maxFracDiscardAll=0.5; // continue removing outliers (combined radius and shift), removing not more that this fraction (including maxFracDiscardWorse)
0.8, //, // internalBonus // cell having 8 around will "seem" twice better than having none (radiusDiff* twice higher)
0.75, // validateThreshold - fraction of full PSF "energy"
false, // validateShowEllipse - show ellipse parameters of partial PSF arrays
......@@ -927,7 +927,7 @@ if (MORE_BUTTONS) {
addButton("Filter Grids",panelGoniometer,color_bundle);
addButton("Update Image Set",panelGoniometer);
addButton("Remove Outlayers",panelGoniometer,color_bundle);
addButton("Remove Outliers",panelGoniometer,color_bundle);
addButton("Remove Sets",panelGoniometer,color_bundle);
addButton("Update Sets Orientation",panelGoniometer);
......@@ -2516,7 +2516,7 @@ if (MORE_BUTTONS) {
gd.addNumericField("Tile half size", tileHalfSize, 0 ,4, "pix");
gd.addNumericField("Color channel mask", cmask, 0 ,4, "9 - both green colors");
gd.addNumericField("\"Normal\" pixels variation", binWidth, 3 ,7, "");
gd.addNumericField("Empty level gap between \"normal\" pixels and outlayers (caused by wrong cable phase)", gapWidth, 3 ,7, "");
gd.addNumericField("Empty level gap between \"normal\" pixels and outliers (caused by wrong cable phase)", gapWidth, 3 ,7, "");
gd.addNumericField("Disregard pixels above this threshold", satLevel, 3 ,5, "pixel value");
gd.addNumericField("Fraction of \"normal\" pixels to determing their average", baseFrac, 3 ,5, "fraction");
gd.addNumericField("Minimal number of non-satureted pixels to process in a tile", minPixToProcess, 0 ,4, "pix");
......@@ -2548,7 +2548,7 @@ if (MORE_BUTTONS) {
COMPONENTS,
THREADS_MAX,
DEBUG_LEVEL);
System.out.println("Number of phase outlayer pixels:"+stats[0]);
System.out.println("Number of phase outlier pixels:"+stats[0]);
System.out.println("Number of processed pixels:"+stats[1]);
return;
}
......@@ -2940,7 +2940,6 @@ if (MORE_BUTTONS) {
IJ.showMessage("Error",msg);
throw new IllegalArgumentException (msg);
}
// int series=refineParameters.showDialog("Select Lens Distortion Residual Compensation Parameters", 0x1efff, (this.seriesNumber>=0)?this.seriesNumber:0);
int series=LENS_DISTORTIONS.refineParameters.showDialog(
"Select Lens Distortion Residual Compensation Parameters",
// 0x846f1,
......@@ -5870,7 +5869,7 @@ if (MORE_BUTTONS) {
return;
}
/* ======================================================================== */
if (label.equals("Remove Outlayers")) {
if (label.equals("Remove Outliers")) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
if (LENS_DISTORTIONS==null) {
IJ.showMessage("LENS_DISTORTION is not set");
......@@ -5885,9 +5884,9 @@ if (MORE_BUTTONS) {
selectedChannels=ABERRATIONS_PARAMETERS.getChannelSelection(LENS_DISTORTIONS);
}
LENS_DISTORTIONS.removeOutLayers(
LENS_DISTORTIONS.removeOutLiers(
-1, //int series, (<0 - ask)
-1, //int numOutLayers (<0 - ask)
-1, //int numOutLiers (<0 - ask)
selectedChannels
);
return;
......@@ -5903,8 +5902,8 @@ if (MORE_BUTTONS) {
IJ.showMessage("LENS_DISTORTION.fittingStrategy is not set");
return;
}
LENS_DISTORTIONS.removeOutLayerSets(
-1 //int numOutLayers (<0 - ask)
LENS_DISTORTIONS.removeOutLierSets(
-1 //int numOutLiers (<0 - ask)
);
return;
}
......@@ -6030,7 +6029,7 @@ if (MORE_BUTTONS) {
boolean useSetsData= true;
gd=new GenericDialog ("Image set # "+imageSetNumber+" re-calibration without laser pointers");
gd.addMessage("Strategy 0 should have all parameters but 2 goniometer axes disabled");
gd.addMessage("Imgages belonging to the set will be selected, possible to check with \"Remove Outlayers\" for strategy 0");
gd.addMessage("Imgages belonging to the set will be selected, possible to check with \"Remove Outliers\" for strategy 0");
gd.addNumericField("Mismatch tolerance of match between the predicted and acquired grid", hintGridTolerance, 1,4,"fraction of grid half-period");
gd.addCheckbox("Ignore laser pointers", ignoreLaserPointers);
gd.addNumericField("Image set tilt", tiltCenter, 2,6,"degrees");
......@@ -10536,17 +10535,17 @@ if (MORE_BUTTONS) {
gd.addNumericField("Tile clearSize", tileClearSize, 0 ,4, "pix");
gd.addNumericField("Tile margin (extra) width", tileMargins, 0 ,4, "pix");
gd.addNumericField("Color channel mask", cmask, 0 ,4, "9 - both green colors");
gd.addNumericField("Number of \"remove outlayers\" passes", numPasses, 0 ,4, "");
gd.addNumericField("Number of neighbors (of total 8) to base outlayers", numInBase, 0 ,4, "<=8");
gd.addNumericField("Number of \"remove outliers\" passes", numPasses, 0 ,4, "");
gd.addNumericField("Number of neighbors (of total 8) to base outliers", numInBase, 0 ,4, "<=8");
gd.addNumericField("Base low-pass sigma ", sigma, 3 ,7, "double pixels");
gd.addCheckbox ("Process tiles with no outlayer replacements", processNoReplace);
gd.addCheckbox ("Process tiles with no outlier replacements", processNoReplace);
gd.addNumericField("\"Normal\" pixels variation", binWidth, 3 ,7, "");
gd.addNumericField("Empty level gap between \"normal\" pixels and outlayers", gapWidth, 3 ,7, "");
gd.addNumericField("Empty level gap between \"normal\" pixels and outliers", gapWidth, 3 ,7, "");
gd.addNumericField("Post-HPF algorithm number", algNum, 0 ,4, "(1 or 2");
gd.addNumericField("Number of neighbors (of total 8) to base outlayers (after high-pass), 0 - no filter", numInBase2, 0 ,4, "<=8");
gd.addNumericField("Number of neighbors (of total 8) to base outliers (after high-pass), 0 - no filter", numInBase2, 0 ,4, "<=8");
gd.addNumericField("\"Normal\" pixels variation (after high-pass)", binWidth2, 3 ,7, "");
gd.addNumericField("Empty level gap between \"normal\" pixels and outlayers (after high-pass)", gapWidth2, 3 ,7, "");
gd.addNumericField("Empty level gap between \"normal\" pixels and outliers (after high-pass)", gapWidth2, 3 ,7, "");
gd.showDialog();
......@@ -10570,7 +10569,7 @@ if (MORE_BUTTONS) {
tileClearSize,
tileMargins,
cmask, // bitmask of color channels to process (9 - two greens)
numPasses, // number of passes to replace outlayers (will end if none was replaced)
numPasses, // number of passes to replace outliers (will end if none was replaced)
numInBase, // number of neighbors (of 8) to use as a base if they all agree
sigma, // for high-pass filtering
processNoReplace, // calculate differences even if no replacements were made
......@@ -10588,7 +10587,7 @@ if (MORE_BUTTONS) {
defectsBayer,
imp_sel.getWidth(),
imp_sel.getHeight(),
"Outlayer pixels");
"Outlier pixels");
int numDefects=0;
for (double d:defectsBayer) if (d!=0.0) numDefects++;
if (numDefects>0) System.out.println("Number of pixel (or phase) defects detected: "+numDefects);
......@@ -10614,17 +10613,17 @@ if (MORE_BUTTONS) {
gd.addNumericField("Tile clearSize", tileClearSize, 0 ,4, "pix");
gd.addNumericField("Tile margin (extra) width", tileMargins, 0 ,4, "pix");
gd.addNumericField("Color channel mask", cmask, 0 ,4, "9 - both green colors");
gd.addNumericField("Number of \"remove outlayers\" passes", numPasses, 0 ,4, "");
gd.addNumericField("Number of neighbors (of total 8) to base outlayers", numInBase, 0 ,4, "<=8");
gd.addNumericField("Number of \"remove outliers\" passes", numPasses, 0 ,4, "");
gd.addNumericField("Number of neighbors (of total 8) to base outliers", numInBase, 0 ,4, "<=8");
gd.addNumericField("Base low-pass sigma ", sigma, 3 ,7, "double pixels");
gd.addCheckbox ("Process tiles with no outlayer replacements", processNoReplace);
gd.addCheckbox ("Process tiles with no outlier replacements", processNoReplace);
gd.addNumericField("\"Normal\" pixels variation", binWidth, 3 ,7, "");
gd.addNumericField("Empty level gap between \"normal\" pixels and outlayers", gapWidth, 3 ,7, "");
gd.addNumericField("Empty level gap between \"normal\" pixels and outliers", gapWidth, 3 ,7, "");
gd.addNumericField("Post-HPF algorithm number", algNum, 0 ,4, "(1 or 2");
gd.addNumericField("Number of neighbors (of total 8) to base outlayers (after high-pass), 0 - no filter", numInBase2, 0 ,4, "<=8");
gd.addNumericField("Number of neighbors (of total 8) to base outliers (after high-pass), 0 - no filter", numInBase2, 0 ,4, "<=8");
gd.addNumericField("\"Normal\" pixels variation (after high-pass)", binWidth2, 3 ,7, "");
gd.addNumericField("Empty level gap between \"normal\" pixels and outlayers (after high-pass)", gapWidth2, 3 ,7, "");
gd.addNumericField("Empty level gap between \"normal\" pixels and outliers (after high-pass)", gapWidth2, 3 ,7, "");
gd.showDialog();
......@@ -10649,7 +10648,7 @@ if (MORE_BUTTONS) {
tileClearSize,
tileMargins,
cmask, // bitmask of color channels to process (9 - two greens)
numPasses, // number of passes to replace outlayers (will end if none was replaced)
numPasses, // number of passes to replace outliers (will end if none was replaced)
numInBase, // number of neighbors (of 8) to use as a base if they all agree
sigma, // for high-pass filtering
processNoReplace, // calculate differences even if no replacements were made
......@@ -10731,7 +10730,7 @@ if (MORE_BUTTONS) {
128, // tileClearSize,
16, // tileMargins,
15, // cmask, // bitmask of color channels to process (9 - two greens)
1000, // numPasses, // number of passes to replace outlayers (will end if none was replaced)
1000, // numPasses, // number of passes to replace outliers (will end if none was replaced)
5, // numInBase, // number of neighbors (of 8) to use as a base if they all agree
1.5, // sigma, // for high-pass filtering
true, // processNoReplace, // calculate differences even if no replacements were made
......@@ -20537,7 +20536,7 @@ use the result to create a rejectiobn mask - if the energy was high, (multiplica
gd.addNumericField("Increase weight of the \"sharp\" kernels by dividing weights by the radius to this power",multiFilePSF.sharpBonusPower,3); // 1.0; // Center shift (in pixels) addition to the difference relative to radius difference (in pixels)
gd.addNumericField("Discard up to this fraction of samples that have larger radius (i.e. falling on the target seam that may only make PSF larger)",100.0*multiFilePSF.maxFracDiscardWorse,1,5,"%"); // 0.1, discard up to this fraction of samples that have larger radius (i.e. falling on the target seam that may only make PSF larger)
gd.addNumericField("Continue removing outlayers (combined radius and shift), removing not more that this fraction (including maxFracDiscardWorse)",100.0*multiFilePSF.maxFracDiscardAll,1,5,"%"); // 0.5, continue removing outlayers (combined radius and shift), removing not more that this fraction (including maxFracDiscardWorse)
gd.addNumericField("Continue removing outliers (combined radius and shift), removing not more that this fraction (including maxFracDiscardWorse)",100.0*multiFilePSF.maxFracDiscardAll,1,5,"%"); // 0.5, continue removing outliers (combined radius and shift), removing not more that this fraction (including maxFracDiscardWorse)
gd.addNumericField("Cell having 8 around will have thresholds above twice higher than having none when this is set to 1.0, 0.0 - all same thresholds",multiFilePSF.internalBonus,3);
......@@ -1555,6 +1555,16 @@ import ij.text.TextWindow;
sb.append("Lens Distortion Model\t");
for (int i=0;i<numSubCameras;i++) sb.append("\t"+lensDistortionModels[i]);
sb.append("\n");
sb.append("Sensor width\t");
for (int i=0;i<numSubCameras;i++) sb.append("\t"+eyesisCameraParameters.getSensorWidth(i));
sb.append("\n");
sb.append("Sensor height\t");
for (int i=0;i<numSubCameras;i++) sb.append("\t"+eyesisCameraParameters.getSensorHeight(i));
sb.append("\n");
double [][] cameraPars=new double [numSubCameras][];
for (int i=0;i<numSubCameras;i++) cameraPars[i]=eyesisCameraParameters.getParametersVector(stationNumber,i);
......@@ -1626,6 +1636,15 @@ import ij.text.TextWindow;
// sb.append("Lens Distortion Model\t");
// for (int i=0;i<numSubCameras;i++) sb.append("\t"+lensDistortionModels[i]);
// sb.append("\n");
sb.append("Sensor width\t");
for (int i=0;i<numSubCameras;i++) sb.append("\t"+eyesisCameraParameters.getSensorWidth(i));
sb.append("\n");
sb.append("Sensor height\t");
for (int i=0;i<numSubCameras;i++) sb.append("\t"+eyesisCameraParameters.getSensorHeight(i));
sb.append("\n");
double [][] cameraPars=new double [numSubCameras][];
for (int i=0;i<numSubCameras;i++) cameraPars[i]=eyesisCameraParameters.getParametersVector(stationNumber,i);
......@@ -2396,7 +2415,7 @@ import ij.text.TextWindow;
IJ.showMessage(msg);
}
for (int i=0; i<this.gIS.length;i++){
if (selectedImages==null){ // if all selected - remove orientation if there are no enabled images (i.e. after removeOutlayers)
if (selectedImages==null){ // if all selected - remove orientation if there are no enabled images (i.e. after removeOutliers)
this.gIS[i].goniometerAxial=Double.NaN;
this.gIS[i].goniometerTilt= Double.NaN;
this.gIS[i].orientationEstimated=true;
......@@ -3379,7 +3398,7 @@ import ij.text.TextWindow;
return true;
}
/**
* Sometimes "Process grid files" generates outlayers (by 0.1..5 pixels) TODO: find the bug
* Sometimes "Process grid files" generates outliers (by 0.1..5 pixels) TODO: find the bug
* 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
......
......@@ -4102,16 +4102,16 @@ List calibration
return true;
}
public boolean removeOutLayers(
public boolean removeOutLiers(
int series,
int numOutLayers,
int numOutLiers,
boolean [] selectedChannels){
int numSeries=fittingStrategy.getNumSeries();
boolean removeEmpty=false;
boolean recalculate=false;
boolean applyChannelFilter=false;
int filter=filterForAll;
if ((series<0) || (numOutLayers<0)) {
if ((series<0) || (numOutLiers<0)) {
GenericDialog gd = new GenericDialog("Select series to process");
gd.addNumericField("Iteration number to start (0.."+(numSeries-1)+")", this.seriesNumber, 0);
if (selectedChannels != null) {
......@@ -4120,7 +4120,7 @@ List calibration
gd.addCheckbox("Filter by channel selection ("+s+")", applyChannelFilter);
}
gd.addCheckbox("Recalculate parameters vector from selected strategy",recalculate);
gd.addNumericField("Number of outlayers to show", 10, 0);
gd.addNumericField("Number of outliers to show", 10, 0);
gd.addCheckbox("Remove empty (rms==NaN) images", removeEmpty);
gd.addCheckbox("Ask filter (current filter="+filter+")", this.askFilter);
gd.showDialog();
......@@ -4128,7 +4128,7 @@ List calibration
this.seriesNumber= (int) gd.getNextNumber();
if (selectedChannels != null) applyChannelFilter= gd.getNextBoolean();
recalculate= gd.getNextBoolean();
numOutLayers= (int) gd.getNextNumber();
numOutLiers= (int) gd.getNextNumber();
removeEmpty= gd.getNextBoolean();
this.askFilter= gd.getNextBoolean();
if (this.askFilter) filter= selectFilter(filter);
......@@ -4162,14 +4162,14 @@ List calibration
int index=0;
for (int i=0;i<selectedImages.length;i++) if ( selectedImages[i] && !Double.isNaN(errors[i])) imgIndices[index++]=i; // OOB 2389
if (numOutLayers>numSelectedNotNaNImages) numOutLayers=numSelectedNotNaNImages;
int [] indices=new int [numOutLayers];
if (numOutLiers>numSelectedNotNaNImages) numOutLiers=numSelectedNotNaNImages;
int [] indices=new int [numOutLiers];
boolean [] availableImages=selectedImages.clone();
for (int i=0;i<selectedImages.length;i++) if (selectedImages[i] && Double.isNaN(errors[i])) availableImages[i]=false;
if ((this.debugLevel>0) && (numNaN>0)){
System.out.println("removeOutLayers(): Number of empty (rms=NaN) images="+numNaN+":");
System.out.println("removeOutLiers(): Number of empty (rms=NaN) images="+numNaN+":");
int n=0;
for (int i=0;i<selectedImages.length;i++) if (selectedImages[i] && Double.isNaN(errors[i])){
n++;
......@@ -4187,8 +4187,8 @@ List calibration
}
System.out.println("removeOutLayers(): availableImages.length="+availableImages.length+" numSelectedNotNaNImages="+numSelectedNotNaNImages);
for (int n=0;n<numOutLayers;n++){
System.out.println("removeOutLiers(): availableImages.length="+availableImages.length+" numSelectedNotNaNImages="+numSelectedNotNaNImages);
for (int n=0;n<numOutLiers;n++){
double maxRMS=-1.0;
indices[n]=-1;
for (int i=0;i<availableImages.length;i++)if (availableImages[i] && (Double.isNaN(errors[i]) || (errors[i]>maxRMS))){ // Double.NaN will be greater
......@@ -4196,14 +4196,14 @@ List calibration
indices[n]=i;
}
if (indices[n]<0){
System.out.println("removeOutLayers(): indices["+n+"]="+indices[n]);
System.out.println("removeOutLiers(): indices["+n+"]="+indices[n]);
continue;
}
availableImages[indices[n]]=false; // java.lang.ArrayIndexOutOfBoundsException: -1
}
GenericDialog gd = new GenericDialog("Select images to remove (RMS="+IJ.d2s(rms,3)+")");
if (this.debugLevel>0) System.out.println("Listing "+numOutLayers+" worst images:");
if (this.debugLevel>0) System.out.println("Listing "+numOutLiers+" worst images:");
for (int n=0;n<indices.length;n++){
String msg=n+" ("+indices[n]+" / "+ this.fittingStrategy.distortionCalibrationData.gIP[indices[n]].getSetNumber()+"): "+
IJ.d2s(errors[indices[n]],3)+" "+
......@@ -4218,7 +4218,7 @@ List calibration
WindowTools.addScrollBars(gd);
gd.showDialog();
if (gd.wasCanceled()) return false;
if (this.debugLevel>0) System.out.println("Removing outlayers:");
if (this.debugLevel>0) System.out.println("Removing outliers:");
for (int n=0;n<indices.length;n++){
if (gd.getNextBoolean()) {
if (this.debugLevel>0) System.out.println(n+" :"+IJ.d2s(errors[indices[n]],3)+" "+this.fittingStrategy.distortionCalibrationData.gIP[indices[n]].path);
......@@ -4230,18 +4230,18 @@ List calibration
return true;
}
public boolean removeOutLayerSets(int numOutLayers){
public boolean removeOutLierSets(int numOutLiers){
boolean removeEmptySets=false;
if (numOutLayers<0) {
if (numOutLiers<0) {
GenericDialog gd = new GenericDialog("Select sets to process");
gd.addNumericField("Series number (<0 - all images)", -1, 0);
gd.addNumericField("Number of outlayers to show", 5, 0);
gd.addNumericField("Number of outliers to show", 5, 0);
gd.addCheckbox("Remove empty sets", removeEmptySets);
gd.addCheckbox("Ask for weight function filter", this.askFilter);
gd.showDialog();
if (gd.wasCanceled()) return false;
this.seriesNumber= (int) gd.getNextNumber();
numOutLayers= (int) gd.getNextNumber();
numOutLiers= (int) gd.getNextNumber();
removeEmptySets= gd.getNextBoolean();
this.askFilter= gd.getNextBoolean();
}
......@@ -4291,12 +4291,12 @@ List calibration
// int index=0;
// for (int i=0;i<imageSets.length;i++) if ( selectedImages[i]) imgIndices[index++]=i;
if (numOutLayers>numSelectedSets) numOutLayers=numSelectedSets;
int [] indices=new int [numOutLayers];
if (numOutLiers>numSelectedSets) numOutLiers=numSelectedSets;
int [] indices=new int [numOutLiers];
boolean [] availableSets= new boolean [imageSets.length];
for (int i=0;i<imageSets.length;i++) availableSets[i]= !allNaNInSet[i]; //!Double.isNaN(rmsPerSet[i]);
if (removeEmptySets && (numNaN>0)){ //(this.debugLevel>0)
if (this.debugLevel>0) System.out.println("removeOutLayerSets(): Number of empty (rms=NaN) sets="+numNaN+":");
if (this.debugLevel>0) System.out.println("removeOutLierSets(): Number of empty (rms=NaN) sets="+numNaN+":");
// int n=0;
for (int setNum=0;setNum<imageSets.length;setNum++) if (!availableSets[setNum]){
// n++;
......@@ -4311,8 +4311,8 @@ List calibration
}
}
System.out.println("removeOutLayerSets(): availableSets.length="+availableSets.length+" numSelectedSets="+numSelectedSets);
for (int n=0;n<numOutLayers;n++){
System.out.println("removeOutLierSets(): availableSets.length="+availableSets.length+" numSelectedSets="+numSelectedSets);
for (int n=0;n<numOutLiers;n++){
double maxRMS=-1.0;
indices[n]=-1;
for (int i=0;i<availableSets.length;i++)if (availableSets[i] && (rmsPerSet[i]>maxRMS)){ // NaN are already skipped
......@@ -4320,14 +4320,14 @@ List calibration
indices[n]=i;
}
if (indices[n]<0){
System.out.println("removeOutLayerSets(): indices["+n+"]="+indices[n]);
System.out.println("removeOutLierSets(): indices["+n+"]="+indices[n]);
continue;
}
availableSets[indices[n]]=false; // java.lang.ArrayIndexOutOfBoundsException: -1
}
GenericDialog gd = new GenericDialog("Select image Sets to remove (RMS="+IJ.d2s(rms,3)+")");
if (this.debugLevel>0) System.out.println("Listing "+numOutLayers+" worst image sets");
if (this.debugLevel>0) System.out.println("Listing "+numOutLiers+" worst image sets");
for (int n=0;n<indices.length;n++){
int numSet=indices[n];
double setWeight=this.fittingStrategy.distortionCalibrationData.gIS[numSet].setWeight;
......@@ -4351,7 +4351,7 @@ List calibration
// this.fittingStrategy.setImageSelection(0, oldSelection); // restore original selection in series 0
return false;
}
if (this.debugLevel>0) System.out.println("Removing outlayers:");
if (this.debugLevel>0) System.out.println("Removing outliers:");
for (int n=0;n<indices.length;n++){
if (gd.getNextBoolean()) {
int numSet=indices[n];
......@@ -4371,16 +4371,16 @@ List calibration
return true;
}
public boolean removeOutLayersJunk(int series, int numOutLayers){
public boolean removeOutLiersJunk(int series, int numOutLiers){
int numSeries=fittingStrategy.getNumSeries();
if ((series<0) || (numOutLayers<0)) {
if ((series<0) || (numOutLiers<0)) {
GenericDialog gd = new GenericDialog("Select series to process");
gd.addNumericField("Iteration number to start (0.."+(numSeries-1)+")", this.seriesNumber, 0);
gd.addNumericField("Number of outlayers to show", 10, 0);
gd.addNumericField("Number of outliers to show", 10, 0);
gd.showDialog();
if (gd.wasCanceled()) return false;
this.seriesNumber= (int) gd.getNextNumber();
numOutLayers= (int) gd.getNextNumber();
numOutLiers= (int) gd.getNextNumber();
} else {
this.seriesNumber=series;
}
......@@ -4395,12 +4395,12 @@ List calibration
int index=0;
for (int i=0;i<selectedImages.length;i++) if ( selectedImages[i]) imgIndices[index++]=i;
if (numOutLayers>numSelectedImages) numOutLayers=numSelectedImages;
int [] indices=new int [numOutLayers];
int [] indicesSelected=new int [numOutLayers];
if (numOutLiers>numSelectedImages) numOutLiers=numSelectedImages;
int [] indices=new int [numOutLiers];
int [] indicesSelected=new int [numOutLiers];
boolean [] availableImages=new boolean[numSelectedImages];
for (int i=0;i<availableImages.length;i++)availableImages[i]=true;
for (int n=0;n<numOutLayers;n++){
for (int n=0;n<numOutLiers;n++){
double maxRMS=0;
indices[n]=-1;
indicesSelected[n]=-1;
......
......@@ -1585,7 +1585,7 @@ public class EyesisAberrations {
if (thisDebugLevel>1) sdfa_instance.showArrays(weightsMasked, kWidth, kHeight, true, "weightsMasked");
double [][][] psfRadius=c[5]; // later may remove all other calculations for c[i]?
double [][][] pxfCenterX=c[0]; // some outlayer kernels have large x/y shift with normal radius - remove them too
double [][][] pxfCenterX=c[0]; // some outlier kernels have large x/y shift with normal radius - remove them too
double [][][] pxfCenterY=c[1];
if (thisDebugLevel>1) {
for (int color=0;color<nChn;color++) sdfa_instance.showArrays(psfRadius[color], kWidth, kHeight, true, "psfRadius-"+color);
......@@ -1610,11 +1610,11 @@ public class EyesisAberrations {
pxfCenterY[color][0][index]=0.0;
}
double sumWeights=0.0;
for (int nFile=0;nFile<nFiles;nFile++) if ((weightsMasked[nFile+1][index]>0.0) && (weights[nFile+1][index]>0.0)){ // both, with outlayers removed
for (int nFile=0;nFile<nFiles;nFile++) if ((weightsMasked[nFile+1][index]>0.0) && (weights[nFile+1][index]>0.0)){ // both, with outliers removed
for (int i=0;i<dirs.length;i++) {
int yn=tileY+dirs[i][1];
int xn=tileX+dirs[i][0];
if ((yn>=0) && (yn<kHeight) && (xn>=0) && (xn<kWidth) && (weightsNotMasked[nFile+1][yn*kWidth+xn]>0.0)){ // including removed outlayers
if ((yn>=0) && (yn<kHeight) && (xn>=0) && (xn<kWidth) && (weightsNotMasked[nFile+1][yn*kWidth+xn]>0.0)){ // including removed outliers
int indexNeib=xn+ kWidth*yn;
double weight=weightsMasked[nFile+1][indexNeib];
if (multiFilePSF.sharpBonusPower>0) {
......@@ -1643,7 +1643,7 @@ public class EyesisAberrations {
double [] diffs=new double[nFiles];
double [] diffsXY2=new double[nFiles];
// for (int nFile=0;nFile<nFiles;nFile++) if ( weights[nFile+1][index]>0.0){ // here all , not just masked - why?
for (int nFile=0;nFile<nFiles;nFile++) if ((weights[nFile+1][index]>0.0) && (weightsMasked[nFile+1][index]>0.0)){ //no outlayers, no masked - find worst
for (int nFile=0;nFile<nFiles;nFile++) if ((weights[nFile+1][index]>0.0) && (weightsMasked[nFile+1][index]>0.0)){ //no outliers, no masked - find worst
diffs[nFile]=0;
diffsXY2[nFile]=0;
for (int color=0;color<nChn;color++) {
......@@ -1658,11 +1658,11 @@ public class EyesisAberrations {
diffs[nFile]+=multiFilePSF.shiftToRadiusContrib*(Math.sqrt(diffXY2)/radiusRatio[color][0][index]); // now difference combines size and position
}
}
// mask out outlayers
// mask out outliers
//weightsMasked[0]
// TODO: when averaging, divide by r^2 to some power to give bonus low-radius samples.
// also - combine dX^2+dY2+dR^2 when selecting outlayers
// also - combine dX^2+dY2+dR^2 when selecting outliers
if (thisDebugLevel>1) {
System.out.print("\n === "+tileY+":"+tileX);
for (int nFile=0;nFile<nFiles;nFile++) if ( weights[nFile+1][index]>0.0){
......@@ -1740,7 +1740,7 @@ public class EyesisAberrations {
// for each channel, each cell - compare radius calculated for neighbors (use masked weights) and the cell
// TODO: Filter out outlayers: Add bonus to cells surrounded by others?
// TODO: Filter out outliers: Add bonus to cells surrounded by others?
// double [][][][] c= new double[numResults][nChn][nFiles+1][kLength];
......@@ -4466,7 +4466,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
public double shiftToRadiusContrib=1.0; // Center shift (in pixels) addition to the difference relative to radius difference (in pixels)
public double sharpBonusPower=2.0; // increase weight of the "sharp" kernels by dividing weight by radius to this power
public double maxFracDiscardWorse=0.1; // discard up to this fraction of samples that have larger radius (i.e. falling on the target seam that may only make PSF larger)
public double maxFracDiscardAll=0.5; // continue removing outlayers (combined radius and shift), removing not more that this fraction (including maxFracDiscardWorse)
public double maxFracDiscardAll=0.5; // continue removing outliers (combined radius and shift), removing not more that this fraction (including maxFracDiscardWorse)
public double internalBonus=1.0; // cell having 8 around will "seem" twice better than having none (radiusDiff* twice higher)
public double validateThreshold; // fraction of full PSF "energy"
public boolean validateShowEllipse; // show ellipse parameters of partial PSF arrays
......@@ -4480,7 +4480,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
double shiftToRadiusContrib, // Center shift (in pixels) addition to the difference relative to radius difference (in pixels)
double sharpBonusPower, // increase weight of the "sharp" kernels by dividing weight by radius to this power
double maxFracDiscardWorse, // discard up to this fraction of samples that have larger radius (i.e. falling on the target seam that may only make PSF larger)
double maxFracDiscardAll, // continue removing outlayers (combined radius and shift), removing not more that this fraction (including maxFracDiscardWorse)
double maxFracDiscardAll, // continue removing outliers (combined radius and shift), removing not more that this fraction (including maxFracDiscardWorse)
double internalBonus,
double validateThreshold,
boolean validateShowEllipse,
......@@ -4494,7 +4494,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
this.shiftToRadiusContrib=shiftToRadiusContrib; // Center shift (in pixels) addition to the difference relative to radius difference (in pixels)
this.sharpBonusPower=sharpBonusPower; // increase weight of the "sharp" kernels by dividing weight by radius to this power
this.maxFracDiscardWorse=maxFracDiscardWorse; // discard up to this fraction of samples that have larger radius (i.e. falling on the target seam that may only make PSF larger)
this.maxFracDiscardAll=maxFracDiscardAll; // continue removing outlayers (combined radius and shift), removing not more that this fraction (including maxFracDiscardWorse)
this.maxFracDiscardAll=maxFracDiscardAll; // continue removing outliers (combined radius and shift), removing not more that this fraction (including maxFracDiscardWorse)
this.internalBonus=internalBonus;
this.validateThreshold=validateThreshold;
this.validateShowEllipse=validateShowEllipse;
......
......@@ -960,8 +960,12 @@ import ij.gui.GenericDialog;
gd.addNumericField("Channel "+numSubCam+" default weight", subCam.channelWeightDefault, 5,8,"");
}
if (this.numStations>1) gd.addMessage("--- Station number "+numStation+" ---");
gd.addNumericField("Subcamera lens distortion model", subCam.lensDistortionModel, 5,0,"");
gd.addNumericField("Subcamera lens distortion model", subCam.lensDistortionModel, 8,0,"");
gd.addCheckbox ("Enable matching w/o laser pointers", subCam.enableNoLaser);
if (numStation == 0) {
gd.addNumericField("Image sensor width", this.getSensorWidth (numSubCam), 0,4,"pix");
gd.addNumericField("Image sensor height", this.getSensorHeight(numSubCam), 0,4,"pix");
}
if (subCam.cartesian) {
gd.addNumericField("Subcamera right from the axis", subCam.right, 5,9,"mm");
gd.addNumericField("Subcamera forward from the rotation axis", subCam.forward, 5,9,"mm");
......@@ -1044,6 +1048,10 @@ import ij.gui.GenericDialog;
subCam.channelWeightDefault= channelWeightDefault; // assign to all stations
subCam.lensDistortionModel= (int) gd.getNextNumber();
subCam.enableNoLaser = gd.getNextBoolean();
if (numStation == 0) {
this.setSensorWidth (numSubCam,(int) gd.getNextNumber());
this.setSensorHeight(numSubCam,(int) gd.getNextNumber());
}
if (subCam.cartesian) {
subCam.right= gd.getNextNumber();
subCam.forward= gd.getNextNumber();
......@@ -1106,6 +1114,9 @@ import ij.gui.GenericDialog;
for (int numStation=1;numStation<this.numStations;numStation++) {
EyesisSubCameraParameters subCam=this.eyesisSubCameras[numStation][numSubCam];
if (subCam!=null) {
this.setSensorWidth (numSubCam,first.getSensorWidth ());
this.setSensorHeight(numSubCam,first.getSensorHeight ());
if (subCam.cartesian) {
subCam.right= first.right;
subCam.forward= first.forward;
......@@ -1298,22 +1309,39 @@ import ij.gui.GenericDialog;
public int getGoniometerHorizontalIndex(){return 6;}
public int getGoniometerAxialIndex(){return 7;}
public int getInterAxisAngleIndex(){return 9;}
@Deprecated
public int getSensorWidth() { return this.defaultSensorWidth;}
@Deprecated
public int getSensorHeight() { return this.defaultSensorHeight;}
@Deprecated
public int getDecimateMasks() { return this.defaultDecimateMasks;}
@Deprecated
public void setSensorWidth(int v) { this.defaultSensorWidth = v;}
@Deprecated
public void setSensorHeight(int v) { this.defaultSensorHeight = v;}
@Deprecated
public void setDecimateMasks(int v) { this.defaultDecimateMasks = v;}
public int getSensorWidth(int subCam) { return this.eyesisSubCameras[0][subCam].sensorWidth;} // for the future? different sensors
public int getSensorHeight(int subCam) { return this.eyesisSubCameras[0][subCam].sensorHeight;}// for the future? different sensors
public int getDecimateMasks(int subCam) { return this.eyesisSubCameras[0][subCam].decimateMasks;}// for the future? different sensors
public int getSensorWidth(int subCam) { return this.eyesisSubCameras[0][subCam].getSensorWidth();} // for the future? different sensors
public int getSensorHeight(int subCam) { return this.eyesisSubCameras[0][subCam].getSensorHeight();}// for the future? different sensors
public int getDecimateMasks(int subCam) { return this.eyesisSubCameras[0][subCam].getDecimateMasks();}// for the future? different sensors
public void setSensorWidth(int subCam, int v) { this.eyesisSubCameras[0][subCam].sensorWidth = v;}
public void setSensorHeight(int subCam, int v) { this.eyesisSubCameras[0][subCam].sensorHeight = v;}
public void setDecimateMasks(int subCam, int v) { this.eyesisSubCameras[0][subCam].decimateMasks = v;}
public void setSensorWidth(int subCam, int v) {
for (int station = 0; station < this.eyesisSubCameras.length; station++) {
this.eyesisSubCameras[station][subCam].setSensorWidth(v);
}
}
public void setSensorHeight(int subCam, int v) {
for (int station = 0; station < this.eyesisSubCameras.length; station++) {
this.eyesisSubCameras[station][subCam].setSensorHeight(v);
}
}
public void setDecimateMasks(int subCam, int v) {
for (int station = 0; station < this.eyesisSubCameras.length; station++) {
this.eyesisSubCameras[station][subCam].setDecimateMasks(v);
}
}
public int [] getSensorWidths() {
int [] v = new int [eyesisSubCameras[0].length];
......
......@@ -2863,10 +2863,10 @@ public class EyesisCorrectionParameters {
public double stHighMix = 0.4; // Consider merging initial planes if jumps between ratio above
public double outlayerStrength = 0.3; // Outlayer tiles weaker than this may be replaced from neighbors
public double outlayerDiff = 0.4; // Replace weak outlayer tiles that do not have neighbors within this disparity difference
public double outlayerDiffPos = 1.0; // Replace weak outlayer tiles that have higher disparity than weighted average
public double outlayerDiffNeg = 0.4; // Replace weak outlayer tiles that have lower disparity than weighted average
public double outlierStrength = 0.3; // Outlier tiles weaker than this may be replaced from neighbors
public double outlierDiff = 0.4; // Replace weak outlier tiles that do not have neighbors within this disparity difference
public double outlierDiffPos = 1.0; // Replace weak outlier tiles that have higher disparity than weighted average
public double outlierDiffNeg = 0.4; // Replace weak outlier tiles that have lower disparity than weighted average
// TODO: Make refine skip if already good?
public boolean combine_refine = true; // combine with all previous after refine pass
......@@ -3582,10 +3582,10 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"stHighMix", this.stHighMix +"");
properties.setProperty(prefix+"outlayerStrength", this.outlayerStrength +"");
properties.setProperty(prefix+"outlayerDiff", this.outlayerDiff +"");
properties.setProperty(prefix+"outlayerDiffPos", this.outlayerDiffPos +"");
properties.setProperty(prefix+"outlayerDiffNeg", this.outlayerDiffNeg +"");
properties.setProperty(prefix+"outlierStrength", this.outlierStrength +"");
properties.setProperty(prefix+"outlierDiff", this.outlierDiff +"");
properties.setProperty(prefix+"outlierDiffPos", this.outlierDiffPos +"");
properties.setProperty(prefix+"outlierDiffNeg", this.outlierDiffNeg +"");
properties.setProperty(prefix+"combine_refine", this.combine_refine+"");
......@@ -4282,10 +4282,17 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"stSmallDiff")!=null) this.stSmallDiff=Double.parseDouble(properties.getProperty(prefix+"stSmallDiff"));
if (properties.getProperty(prefix+"stHighMix")!=null) this.stHighMix=Double.parseDouble(properties.getProperty(prefix+"stHighMix"));
if (properties.getProperty(prefix+"outlayerStrength")!=null) this.outlayerStrength=Double.parseDouble(properties.getProperty(prefix+"outlayerStrength"));
if (properties.getProperty(prefix+"outlayerDiff")!=null) this.outlayerDiff=Double.parseDouble(properties.getProperty(prefix+"outlayerDiff"));
if (properties.getProperty(prefix+"outlayerDiffPos")!=null) this.outlayerDiffPos=Double.parseDouble(properties.getProperty(prefix+"outlayerDiffPos"));
if (properties.getProperty(prefix+"outlayerDiffNeg")!=null) this.outlayerDiffNeg=Double.parseDouble(properties.getProperty(prefix+"outlayerDiffNeg"));
// old wrong spelling
if (properties.getProperty(prefix+"outlayerStrength")!=null) this.outlierStrength=Double.parseDouble(properties.getProperty(prefix+"outlayerStrength"));
if (properties.getProperty(prefix+"outlayerDiff")!=null) this.outlierDiff=Double.parseDouble(properties.getProperty(prefix+"outlayerDiff"));
if (properties.getProperty(prefix+"outlayerDiffPos")!=null) this.outlierDiffPos=Double.parseDouble(properties.getProperty(prefix+"outlayerDiffPos"));
if (properties.getProperty(prefix+"outlayerDiffNeg")!=null) this.outlierDiffNeg=Double.parseDouble(properties.getProperty(prefix+"outlayerDiffNeg"));
if (properties.getProperty(prefix+"outlierStrength")!=null) this.outlierStrength=Double.parseDouble(properties.getProperty(prefix+"outlierStrength"));
if (properties.getProperty(prefix+"outlierDiff")!=null) this.outlierDiff=Double.parseDouble(properties.getProperty(prefix+"outlierDiff"));
if (properties.getProperty(prefix+"outlierDiffPos")!=null) this.outlierDiffPos=Double.parseDouble(properties.getProperty(prefix+"outlierDiffPos"));
if (properties.getProperty(prefix+"outlierDiffNeg")!=null) this.outlierDiffNeg=Double.parseDouble(properties.getProperty(prefix+"outlierDiffNeg"));
if (properties.getProperty(prefix+"combine_refine")!=null) this.combine_refine=Boolean.parseBoolean(properties.getProperty(prefix+"combine_refine"));
......@@ -5030,10 +5037,10 @@ public class EyesisCorrectionParameters {
gd.addNumericField("Consider merging initial planes if disparity difference below", this.stSmallDiff, 6);
gd.addNumericField("Consider merging initial planes if jumps between ratio above", this.stHighMix, 6);
gd.addNumericField("Outlier tiles weaker than this may be replaced from neighbors", this.outlayerStrength, 6);
gd.addNumericField("Replace weak outlier tiles that do not have neighbors within this disparity difference", this.outlayerDiff, 6);
gd.addNumericField("Replace weak outlier tiles that have higher disparity than weighted average", this.outlayerDiffPos, 6);
gd.addNumericField("Replace weak outlier tiles that have lower disparity than weighted average", this.outlayerDiffNeg, 6);
gd.addNumericField("Outlier tiles weaker than this may be replaced from neighbors", this.outlierStrength, 6);
gd.addNumericField("Replace weak outlier tiles that do not have neighbors within this disparity difference", this.outlierDiff, 6);
gd.addNumericField("Replace weak outlier tiles that have higher disparity than weighted average", this.outlierDiffPos, 6);
gd.addNumericField("Replace weak outlier tiles that have lower disparity than weighted average", this.outlierDiffNeg, 6);
gd.addCheckbox ("Combine with all previous after refine pass", this.combine_refine);
gd.addNumericField("Disregard weaker tiles when combining scans", this.combine_min_strength, 6);
......@@ -5792,10 +5799,10 @@ public class EyesisCorrectionParameters {
this.stSmallDiff= gd.getNextNumber();
this.stHighMix= gd.getNextNumber();