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

Merge branch 'lwir-distort' of git.elphel.com:Elphel/imagej-elphel into lwir-distort

parents 7f44490f 3b485572
...@@ -31,6 +31,7 @@ import java.awt.Color; ...@@ -31,6 +31,7 @@ import java.awt.Color;
import java.awt.Frame; import java.awt.Frame;
import java.awt.GridLayout; import java.awt.GridLayout;
import java.awt.Panel; import java.awt.Panel;
import java.awt.Point;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
...@@ -49,6 +50,8 @@ import java.io.OutputStream; ...@@ -49,6 +50,8 @@ import java.io.OutputStream;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.StringWriter; import java.io.StringWriter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
...@@ -1461,7 +1464,9 @@ if (MORE_BUTTONS) { ...@@ -1461,7 +1464,9 @@ if (MORE_BUTTONS) {
"", //arg - not used in JP46 reader "", //arg - not used in JP46 reader
true, // un-apply camera color gains true, // un-apply camera color gains
imp_sel); // reuse the same image window imp_sel); // reuse the same image window
matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize); // matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize);
int sensor_type = 0; // EO
matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.getFFTSize(sensor_type));
// matchSimulatedPattern.invalidateFlatFieldForGrid(); //It is already reset, no need to do it again // matchSimulatedPattern.invalidateFlatFieldForGrid(); //It is already reset, no need to do it again
// matchSimulatedPattern.invalidateFocusMask(); // matchSimulatedPattern.invalidateFocusMask();
matchSimulatedPattern.calculateDistortions( matchSimulatedPattern.calculateDistortions(
...@@ -1829,7 +1834,9 @@ if (MORE_BUTTONS) { ...@@ -1829,7 +1834,9 @@ if (MORE_BUTTONS) {
IJ.showMessage("Error","There are no images open\nProcess canceled"); IJ.showMessage("Error","There are no images open\nProcess canceled");
return; return;
} }
matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize); // matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize);
int sensor_type = 0; // EO
matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.getFFTSize(sensor_type));
matchSimulatedPattern.debugLevel=DEBUG_LEVEL; matchSimulatedPattern.debugLevel=DEBUG_LEVEL;
matchSimulatedPattern.distortionsTest ( matchSimulatedPattern.distortionsTest (
DISTORTION, // DISTORTION, //
...@@ -1858,7 +1865,10 @@ if (MORE_BUTTONS) { ...@@ -1858,7 +1865,10 @@ if (MORE_BUTTONS) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL; DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
imp_sel = WindowManager.getCurrentImage(); imp_sel = WindowManager.getCurrentImage();
// imp_distortions=imp_sel; // imp_distortions=imp_sel;
matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize); // matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize);
int sensor_type = 0; // EO
matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.getFFTSize(sensor_type));
// matchSimulatedPattern.invalidateFlatFieldForGrid(); //It is already reset, no need to do it again // matchSimulatedPattern.invalidateFlatFieldForGrid(); //It is already reset, no need to do it again
// matchSimulatedPattern.invalidateFocusMask(); // matchSimulatedPattern.invalidateFocusMask();
int numAbsolutePoints=matchSimulatedPattern.calculateDistortions( int numAbsolutePoints=matchSimulatedPattern.calculateDistortions(
...@@ -3183,7 +3193,10 @@ if (MORE_BUTTONS) { ...@@ -3183,7 +3193,10 @@ if (MORE_BUTTONS) {
if (label.equals("Update Focusing Grid")) { if (label.equals("Update Focusing Grid")) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL; DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
if (matchSimulatedPattern==null) { if (matchSimulatedPattern==null) {
matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize); // new instance, all reset // matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize); // new instance, all reset
int sensor_type = 0; // EO
matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.getFFTSize(sensor_type));
} }
matchSimulatedPattern.debugLevel=DEBUG_LEVEL; matchSimulatedPattern.debugLevel=DEBUG_LEVEL;
imp_sel = WindowManager.getCurrentImage(); imp_sel = WindowManager.getCurrentImage();
...@@ -3345,7 +3358,10 @@ if (MORE_BUTTONS) { ...@@ -3345,7 +3358,10 @@ if (MORE_BUTTONS) {
//"Focusing Acquire PSF" //"Focusing Acquire PSF"
DEBUG_LEVEL=MASTER_DEBUG_LEVEL; DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
if (matchSimulatedPattern==null) { if (matchSimulatedPattern==null) {
matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize); // new instance, all reset // matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize); // new instance, all reset
int sensor_type = 0; // EO
matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.getFFTSize(sensor_type));
} }
matchSimulatedPattern.debugLevel=DEBUG_LEVEL; matchSimulatedPattern.debugLevel=DEBUG_LEVEL;
if (LENS_DISTORTION_PARAMETERS==null){ if (LENS_DISTORTION_PARAMETERS==null){
...@@ -3556,7 +3572,9 @@ if (MORE_BUTTONS) { ...@@ -3556,7 +3572,9 @@ if (MORE_BUTTONS) {
if (DEBUG_LEVEL>0) System.out.println("Image acquisition (@"+FOCUS_MEASUREMENT_PARAMETERS.sensorTemperature+"C) done at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3)); if (DEBUG_LEVEL>0) System.out.println("Image acquisition (@"+FOCUS_MEASUREMENT_PARAMETERS.sensorTemperature+"C) done at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
// reset matchSimulatedPattern, so it will start from scratch // reset matchSimulatedPattern, so it will start from scratch
matchSimulatedPatternSet[imgCounter] = new MatchSimulatedPattern(DISTORTION.FFTSize); // new instance, all reset int sensor_type = 0; // EO
// matchSimulatedPatternSet[imgCounter] = new MatchSimulatedPattern(DISTORTION.FFTSize); // new instance, all reset
matchSimulatedPatternSet[imgCounter] = new MatchSimulatedPattern(DISTORTION.getFFTSize(sensor_type)); // new instance, all reset
// next 2 lines are not needed for the new instance, but can be used alternatively if keeipg it // next 2 lines are not needed for the new instance, but can be used alternatively if keeipg it
matchSimulatedPatternSet[imgCounter].invalidateFlatFieldForGrid(); //Reset Flat Field calibration - different image. matchSimulatedPatternSet[imgCounter].invalidateFlatFieldForGrid(); //Reset Flat Field calibration - different image.
matchSimulatedPatternSet[imgCounter].invalidateFocusMask(); matchSimulatedPatternSet[imgCounter].invalidateFocusMask();
...@@ -3833,7 +3851,10 @@ if (MORE_BUTTONS) { ...@@ -3833,7 +3851,10 @@ if (MORE_BUTTONS) {
} }
POWER_CONTROL.lightsOnWithDelay(); POWER_CONTROL.lightsOnWithDelay();
if (matchSimulatedPattern==null) { if (matchSimulatedPattern==null) {
matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize); // new instance, all reset // matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize); // new instance, all reset
int sensor_type = 0; // EO
matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.getFFTSize(sensor_type));
} }
matchSimulatedPattern.debugLevel=DEBUG_LEVEL; matchSimulatedPattern.debugLevel=DEBUG_LEVEL;
if (LENS_DISTORTION_PARAMETERS==null){ if (LENS_DISTORTION_PARAMETERS==null){
...@@ -4180,7 +4201,9 @@ if (MORE_BUTTONS) { ...@@ -4180,7 +4201,9 @@ if (MORE_BUTTONS) {
} }
} }
if (matchSimulatedPattern==null) { if (matchSimulatedPattern==null) {
matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize); // new instance, all reset // matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize); // new instance, all reset
int sensor_type = 0; // EO
matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.getFFTSize(sensor_type));
} }
matchSimulatedPattern.debugLevel=MASTER_DEBUG_LEVEL; matchSimulatedPattern.debugLevel=MASTER_DEBUG_LEVEL;
if (LENS_DISTORTION_PARAMETERS==null){ if (LENS_DISTORTION_PARAMETERS==null){
...@@ -4389,7 +4412,9 @@ if (MORE_BUTTONS) { ...@@ -4389,7 +4412,9 @@ if (MORE_BUTTONS) {
} }
} }
if (matchSimulatedPattern==null) { if (matchSimulatedPattern==null) {
matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize); // new instance, all reset // matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize); // new instance, all reset
int sensor_type = 0; // EO
matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.getFFTSize(sensor_type));
} }
matchSimulatedPattern.debugLevel=DEBUG_LEVEL; matchSimulatedPattern.debugLevel=DEBUG_LEVEL;
if (LENS_DISTORTION_PARAMETERS==null){ if (LENS_DISTORTION_PARAMETERS==null){
...@@ -6069,211 +6094,7 @@ if (MORE_BUTTONS) { ...@@ -6069,211 +6094,7 @@ if (MORE_BUTTONS) {
return; return;
} }
LENS_DISTORTIONS.debugLevel=DEBUG_LEVEL; LENS_DISTORTIONS.debugLevel=DEBUG_LEVEL;
GenericDialog gd=new GenericDialog ("Select image set to re-calibrate"); recalibrateSet();
gd.addNumericField("Image set number", 0, 0);
gd.addCheckbox ("Set image set parameters from closest, (re-)estimate orientation", true);
gd.showDialog();
if (gd.wasCanceled()) return;
int imageSetNumber=(int) gd.getNextNumber();
boolean reEstimate=gd.getNextBoolean();
if (imageSetNumber<0) return;
if (reEstimate){
// boolean OK=
LENS_DISTORTIONS.setSetFromClosestAndEstimateOrientation(
imageSetNumber,
null, //boolean [] selectedImages,
null, //boolean [] parameterMask,
LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData,
LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.eyesisCameraParameters);
}
double tiltCenter=LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.gIS[imageSetNumber].goniometerTilt;
double axialCenter=LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.gIS[imageSetNumber].goniometerAxial;
double interCenter=LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.gIS[imageSetNumber].interAxisAngle;
int tiltNumSteps=1;
int axialNumSteps=21;
double tiltStep=0.25;
double axialStep=0.25;
boolean processAllImages=true;
boolean ignoreLaserPointers=false;
double hintGridTolerance=200.0;
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 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");
gd.addNumericField("Image set axial", axialCenter, 2,6,"degrees");
gd.addNumericField("Image set inter-axis", interCenter, 2,6,"degrees");
gd.addNumericField("Tilt number of steps", tiltNumSteps, 0,3,"");
gd.addNumericField("Axial number of steps", axialNumSteps, 0,3,"");
gd.addNumericField("Tilt scan step", tiltStep, 2,5,"degrees");
gd.addNumericField("Axial scan step", axialStep, 2,5,"degrees");
gd.addCheckbox ("Use image sets data if available (false - use camera data)", useSetsData);
gd.addCheckbox("process all images (false - enabled only)", processAllImages);
gd.showDialog();
if (gd.wasCanceled()) return;
hintGridTolerance= gd.getNextNumber();
ignoreLaserPointers= gd.getNextBoolean();
tiltCenter= gd.getNextNumber();
axialCenter= gd.getNextNumber();
interCenter= gd.getNextNumber();
tiltNumSteps= (int) gd.getNextNumber();
axialNumSteps= (int) gd.getNextNumber();
tiltStep= gd.getNextNumber();
axialStep= gd.getNextNumber();
useSetsData= gd.getNextBoolean();
processAllImages= gd.getNextBoolean();
double [] initialTilt = new double [tiltNumSteps];
double [] initialAxial= new double [axialNumSteps];
double [][] finalTilt = new double [tiltNumSteps][axialNumSteps];
double [][] finalAxial= new double [tiltNumSteps][axialNumSteps];
double [][] finalInter= new double [tiltNumSteps][axialNumSteps];
double [][] finalError= new double [tiltNumSteps][axialNumSteps];
for (int tiltIndex=0; tiltIndex<tiltNumSteps;tiltIndex++) initialTilt[tiltIndex]=tiltCenter+tiltStep*(tiltIndex-0.5*(tiltNumSteps-1));
for (int axialIndex=0;axialIndex<axialNumSteps;axialIndex++) initialAxial[axialIndex]=axialCenter+axialStep*(axialIndex-0.5*(axialNumSteps-1));
for (int tiltIndex=0; tiltIndex<tiltNumSteps;tiltIndex++) for (int axialIndex=0;axialIndex<axialNumSteps;axialIndex++) {
LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.gIS[imageSetNumber].goniometerTilt=initialTilt[tiltIndex];
LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.gIS[imageSetNumber].goniometerAxial=initialAxial[axialIndex];
LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.gIS[imageSetNumber].interAxisAngle=interCenter; // no scanning, just use center value
if (DEBUG_LEVEL>0) System.out.println("Image Set #"+imageSetNumber+
" Initial tilt="+initialTilt[tiltIndex]+
" Initial inter="+interCenter);
int [][] imageSets=LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.listImages(!processAllImages);
int [] imageSet=imageSets[imageSetNumber];
if (imageSet==null){
IJ.showMessage("Image set #"+imageSetNumber+" is empty");
return;
}
for (int i=0;i<imageSet.length;i++){
int imageNumber=imageSet[i];
LENS_DISTORTIONS.applyHintedGrids(
LASER_POINTERS, // MatchSimulatedPattern.LaserPointer laserPointer, // LaserPointer object that specifies actual laser poiners on the target
DISTORTION_PROCESS_CONFIGURATION.removeOutOfGridPointers, // boolean removeOutOfGridPointers,
hintGridTolerance, //double hintGridTolerance, // alllowed mismatch (fraction of period) or 0 - orientation only
true, //processAll, //boolean processAll, // if true - process all images, false - only disabled
ignoreLaserPointers, //true, //ignoreLaserPointers,
true, //processBlind,
imageNumber,
useSetsData,
THREADS_MAX, //int threadsMax,
UPDATE_STATUS, // boolean updateStatus,
DISTORTION.loop_debug_level, // int mspDebugLevel,
MASTER_DEBUG_LEVEL, //int global_debug_level, // DEBUG_LEVEL
MASTER_DEBUG_LEVEL //int debug_level // debug level used inside loops
);
}
// set series 0 to this set images
boolean [] selection =LENS_DISTORTIONS.fittingStrategy.selectAllImages(0); // enable all images in series 0
for (int i=0;i<selection.length;i++) selection[i]=false;
for (int i=0;i<imageSet.length;i++) selection[imageSet[i]]=true;
LENS_DISTORTIONS.fittingStrategy.setImageSelection(0,selection);
LENS_DISTORTIONS.seriesNumber= 0; // start from 0;
LENS_DISTORTIONS.initFittingSeries(false,LENS_DISTORTIONS.filterForAll,0); // will set this.currentVector
//this.stopAfterThis[numSeries]
LENS_DISTORTIONS.fittingStrategy.stopAfterThis[0]=true;
LENS_DISTORTIONS.stopEachStep= false;
LENS_DISTORTIONS.stopEachSeries= false; // will not ask for confirmation after done
LENS_DISTORTIONS.stopOnFailure=false;
LENS_DISTORTIONS.lambda=LENS_DISTORTIONS.fittingStrategy.lambdas[0]; // 0.001; // why it does not use fitting series lambda?
boolean LMA_OK=LENS_DISTORTIONS.LevenbergMarquardt(
false, // skip dialog
false); // new: dry_run use it here?
if (LMA_OK) {
finalTilt[tiltIndex][axialIndex]=LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.gIS[imageSetNumber].goniometerTilt;
finalAxial[tiltIndex][axialIndex]=LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.gIS[imageSetNumber].goniometerAxial;
finalInter[tiltIndex][axialIndex]=LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.gIS[imageSetNumber].interAxisAngle;
finalError[tiltIndex][axialIndex]=LENS_DISTORTIONS.currentRMS;
} else {
finalTilt[tiltIndex][axialIndex]=initialTilt[tiltIndex];
finalAxial[tiltIndex][axialIndex]=initialAxial[axialIndex];
finalInter[tiltIndex][axialIndex]=interCenter;
finalError[tiltIndex][axialIndex]=Double.NaN;
if (DEBUG_LEVEL>0) System.out.println("----------------- LMA FAILED -------------------------");
}
}
int bestTiltIndex=0;
int bestAxialIndex=0;
double bestRMS=finalError[bestTiltIndex][bestAxialIndex];
for (int tiltIndex=0; tiltIndex<tiltNumSteps;tiltIndex++) for (int axialIndex=0;axialIndex<axialNumSteps;axialIndex++) {
if (Double.isNaN(bestRMS) || (bestRMS>finalError[tiltIndex][axialIndex])){
bestTiltIndex=tiltIndex;
bestAxialIndex=axialIndex;
bestRMS=finalError[bestTiltIndex][bestAxialIndex];
}
}
if (DEBUG_LEVEL>0) System.out.println("================ Image Set #"+imageSetNumber+" rms="+IJ.d2s(bestRMS, 6)+
" final tilt="+finalTilt[bestTiltIndex][bestAxialIndex]+" ("+tiltCenter+": "+initialTilt[bestTiltIndex]+") " +
" final axial="+finalAxial[bestTiltIndex][bestAxialIndex]+" ("+axialCenter+": "+initialAxial[bestAxialIndex]+")"+
" final inter="+finalInter[bestTiltIndex][bestAxialIndex]+" ("+interCenter+": "+interCenter+")");
// repeat with the best indices
LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.gIS[imageSetNumber].goniometerTilt=finalTilt[bestTiltIndex][bestAxialIndex]; //initialTilt[bestTiltIndex];
LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.gIS[imageSetNumber].goniometerAxial=finalAxial[bestTiltIndex][bestAxialIndex]; //initialAxial[bestAxialIndex];
LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.gIS[imageSetNumber].interAxisAngle=finalInter[bestTiltIndex][bestAxialIndex];
if (DEBUG_LEVEL>0) System.out.println(
"Image Set #"+imageSetNumber+
" Initial tilt="+finalTilt[bestTiltIndex][bestAxialIndex]+
" Initial axial="+finalAxial[bestTiltIndex][bestAxialIndex]+
" Initial inter="+finalInter[bestTiltIndex][bestAxialIndex]
);
int [][] imageSets=LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.listImages(!processAllImages);
int [] imageSet=imageSets[imageSetNumber];
if (imageSet==null){
IJ.showMessage("Image set #"+imageSetNumber+" is empty");
return;
}
for (int i=0;i<imageSet.length;i++){
int imageNumber=imageSet[i];
LENS_DISTORTIONS.applyHintedGrids(
LASER_POINTERS, // MatchSimulatedPattern.LaserPointer laserPointer, // LaserPointer object that specifies actual laser poiners on the target
DISTORTION_PROCESS_CONFIGURATION.removeOutOfGridPointers, // boolean removeOutOfGridPointers,
hintGridTolerance, //double hintGridTolerance, // alllowed mismatch (fraction of period) or 0 - orientation only
true, //processAll, //boolean processAll, // if true - process all images, false - only disabeld
ignoreLaserPointers, //ignoreLaserPointers,
true, //processBlind,
imageNumber,
useSetsData,
THREADS_MAX, //int threadsMax,
UPDATE_STATUS, // boolean updateStatus,
DISTORTION.loop_debug_level, // int mspDebugLevel,
MASTER_DEBUG_LEVEL, //int global_debug_level, // DEBUG_LEVEL
MASTER_DEBUG_LEVEL //int debug_level // debug level used inside loops
);
}
// set series 0 to this set images
boolean [] selection =LENS_DISTORTIONS.fittingStrategy.selectAllImages(0); // enable all images in series 0
for (int i=0;i<selection.length;i++) selection[i]=false;
for (int i=0;i<imageSet.length;i++) selection[imageSet[i]]=true;
LENS_DISTORTIONS.fittingStrategy.setImageSelection(0,selection);
LENS_DISTORTIONS.seriesNumber= 0; // start from 0;
LENS_DISTORTIONS.initFittingSeries(false,LENS_DISTORTIONS.filterForAll,0); // will set this.currentVector
//this.stopAfterThis[numSeries]
LENS_DISTORTIONS.fittingStrategy.stopAfterThis[0]=true;
LENS_DISTORTIONS.stopEachStep= false;
LENS_DISTORTIONS.stopEachSeries= false; // will not ask for confirmation after done
LENS_DISTORTIONS.lambda=LENS_DISTORTIONS.fittingStrategy.lambdas[0];
LENS_DISTORTIONS.LevenbergMarquardt(
false, // skip dialog
false); // new: dry_run use it here?
// save safe settings to run LMA manually
LENS_DISTORTIONS.seriesNumber= 0; // start from 0;
LENS_DISTORTIONS.initFittingSeries(false,LENS_DISTORTIONS.filterForAll,0); // will set this.currentVector
LENS_DISTORTIONS.stopEachSeries= true; // will not ask for confirmation after done
LENS_DISTORTIONS.stopOnFailure=true;
LENS_DISTORTIONS.lambda=LENS_DISTORTIONS.fittingStrategy.lambdas[0];
if (DEBUG_LEVEL>0) System.out.println("================ Image Set #"+imageSetNumber+" rms="+IJ.d2s(bestRMS, 6)+
" final tilt="+finalTilt[bestTiltIndex][bestAxialIndex]+" ("+tiltCenter+": "+initialTilt[bestTiltIndex]+") " +
" final axial="+finalAxial[bestTiltIndex][bestAxialIndex]+" ("+axialCenter+": "+initialAxial[bestAxialIndex]+")" +
" final inter="+finalInter[bestTiltIndex][bestAxialIndex]+" ("+interCenter+")");
return; return;
} }
...@@ -9730,6 +9551,318 @@ if (MORE_BUTTONS) { ...@@ -9730,6 +9551,318 @@ if (MORE_BUTTONS) {
} }
public boolean recalibrateSet() {
GenericDialog gd=new GenericDialog ("Select image set to re-calibrate");
gd.addNumericField("Image set number", 0, 0);
gd.addCheckbox ("Set image set parameters from closest, (re-)estimate orientation", true);
gd.showDialog();
if (gd.wasCanceled()) return false;
int imageSetNumber=(int) gd.getNextNumber();
boolean reEstimate=gd.getNextBoolean();
if (imageSetNumber<0) return false;
if (reEstimate){
// boolean OK=
LENS_DISTORTIONS.setSetFromClosestAndEstimateOrientation(
imageSetNumber,
null, //boolean [] selectedImages,
null, //boolean [] parameterMask,
LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData,
LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.eyesisCameraParameters);
}
double tiltCenter=LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.gIS[imageSetNumber].goniometerTilt;
double axialCenter=LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.gIS[imageSetNumber].goniometerAxial;
double interCenter=LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.gIS[imageSetNumber].interAxisAngle;
double tiltHalfRange = 2.0; // degrees
double axialHalfRange = 15.0; // degrees
int scanHalfV = 10; // can be large - actual will be limited by angular range
int scanHalfU = 10; // can be large - actual will be limited by angular range
double stopRMS = 1.0; // exit when RMS falls below
boolean processAllImages=true;
boolean ignoreLaserPointers=false;
double hintGridTolerance=200.0;
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 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 center tilt", tiltCenter, 2,6,"degrees");
gd.addNumericField("Image set center axial", axialCenter, 2,6,"degrees");
gd.addNumericField("Image set inter-axis", interCenter, 2,6,"degrees");
gd.addNumericField("Tilt scan half-range", tiltHalfRange, 2,6,"degrees");
gd.addNumericField("Axial scan half-range", axialHalfRange, 2,6,"degrees");
gd.addNumericField("Half scan in U (almost horizontal) grid nodes (large will be limited by angular range)", scanHalfU, 0,3,"");
gd.addNumericField("Half scan in V (almost vertical) grid nodes (large will be limited by angular range)", scanHalfV, 0,3,"");
gd.addNumericField("Stop RMS - exit scan when RMS falls below", stopRMS, 2,6,"pixels");
gd.addCheckbox ("Use image sets data if available (false - use camera data)", useSetsData);
gd.addCheckbox("process all images (false - enabled only)", processAllImages);
gd.showDialog();
if (gd.wasCanceled()) return false;
hintGridTolerance= gd.getNextNumber();
ignoreLaserPointers= gd.getNextBoolean();
tiltCenter= gd.getNextNumber();
axialCenter= gd.getNextNumber();
interCenter= gd.getNextNumber();
tiltHalfRange= gd.getNextNumber();
axialHalfRange= gd.getNextNumber();
scanHalfV= (int) gd.getNextNumber();
scanHalfU= (int) gd.getNextNumber();
stopRMS = gd.getNextNumber();
useSetsData= gd.getNextBoolean();
processAllImages= gd.getNextBoolean();
// Find channel with most weight
LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.gIS[imageSetNumber].goniometerTilt=tiltCenter;
LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.gIS[imageSetNumber].goniometerAxial=axialCenter;
LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.gIS[imageSetNumber].interAxisAngle=interCenter;
// Run once with center position or Goniometer angles to determine average derivatives
int [][] imageSets=LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.listImages(!processAllImages);
int [] imageSet=imageSets[imageSetNumber];
if (imageSet==null){
IJ.showMessage("Image set #"+imageSetNumber+" is empty");
return false;
}
for (int i=0;i<imageSet.length;i++){
int imageNumber=imageSet[i];
LENS_DISTORTIONS.applyHintedGrids(
LASER_POINTERS, // MatchSimulatedPattern.LaserPointer laserPointer, // LaserPointer object that specifies actual laser poiners on the target
DISTORTION_PROCESS_CONFIGURATION.removeOutOfGridPointers, // boolean removeOutOfGridPointers,
hintGridTolerance, //double hintGridTolerance, // alllowed mismatch (fraction of period) or 0 - orientation only
true, //processAll, //boolean processAll, // if true - process all images, false - only disabeld
ignoreLaserPointers, //ignoreLaserPointers,
true, //processBlind,
imageNumber,
useSetsData,
THREADS_MAX, //int threadsMax,
UPDATE_STATUS, // boolean updateStatus,
DISTORTION.loop_debug_level, // int mspDebugLevel,
MASTER_DEBUG_LEVEL, //int global_debug_level, // DEBUG_LEVEL
MASTER_DEBUG_LEVEL //int debug_level // debug level used inside loops
);
}
boolean [] selection =LENS_DISTORTIONS.fittingStrategy.selectAllImages(0); // enable all images in series 0
for (int i=0;i<selection.length;i++) selection[i]=false;
for (int i=0;i<imageSet.length;i++) selection[imageSet[i]]=true;
LENS_DISTORTIONS.fittingStrategy.setImageSelection(0,selection);
LENS_DISTORTIONS.seriesNumber= 0; // start from 0;
LENS_DISTORTIONS.initFittingSeries(false,LENS_DISTORTIONS.filterForAll,0); // will set this.currentVector
//this.stopAfterThis[numSeries]
LENS_DISTORTIONS.fittingStrategy.stopAfterThis[0]=true;
LENS_DISTORTIONS.stopEachStep= false;
LENS_DISTORTIONS.stopEachSeries= false; // will not ask for confirmation after done
LENS_DISTORTIONS.lambda=LENS_DISTORTIONS.fittingStrategy.lambdas[0];
Distortions distortions_dbg = LENS_DISTORTIONS;
LENS_DISTORTIONS.LevenbergMarquardt( // Index 0 out of bounds for length 0
false, // skip dialog
false, // new: dry_run use it here?
true);
double [][] dTA_dUV = LENS_DISTORTIONS.getDtaDuv();
if (DEBUG_LEVEL > 0) {
System.out.println(
"Grid dTilt/dU = "+dTA_dUV[0][0]+"\n"+
"Grid dAxial/dU = "+dTA_dUV[1][0]+"\n"+
"Grid dTilt/dV = "+dTA_dUV[0][1]+"\n"+
"Grid dAxial/dV = "+dTA_dUV[1][1]);
}
// update center angles
tiltCenter= LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.gIS[imageSetNumber].goniometerTilt;
axialCenter= LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.gIS[imageSetNumber].goniometerAxial;
interCenter = LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.gIS[imageSetNumber].interAxisAngle;
double rms_last= LENS_DISTORTIONS.currentRMS;
double tilt_last = tiltCenter;
double axial_last = axialCenter;
double inter_last = interCenter;
double best_rms = rms_last;
double best_tilt = tilt_last;
double best_axial = axial_last;
double best_inter = inter_last;
Point best_pnt = new Point(0,0);
if (best_rms > stopRMS) { // do nothing if the original center is already OK
ArrayList<Point> nodeList = new ArrayList<Point>();
for (int dv = -scanHalfV; dv <= scanHalfV; dv++) {
for (int du = -scanHalfU; du <= scanHalfU; du++) {
if ((((dv+du) % 2) == 0) && ((dv !=0) || (du != 0))){
double dtilt = dTA_dUV[0][0]*du + dTA_dUV[0][1]*dv;
double daxial = dTA_dUV[1][0]*du + dTA_dUV[1][1]*dv;
if ((Math.abs(dtilt) <= tiltHalfRange) && (Math.abs(daxial) <= axialHalfRange)) {
nodeList.add(new Point(du,dv));
}
}
}
}
// sort list
Collections.sort(nodeList, new Comparator<Point>() {
@Override
public int compare(Point lhs, Point rhs) {
double rhsl2 = rhs.getX()*rhs.getX() + rhs.getY()*rhs.getY();
double lhsl2 = lhs.getX()*lhs.getX() + lhs.getY()*lhs.getY();
return (rhsl2 > lhsl2) ? -1 : (rhsl2 < lhsl2) ? 1 : 0;
}
});
for (Point pnt:nodeList) {
double dtilt = dTA_dUV[0][0]*pnt.getX() + dTA_dUV[0][1]*pnt.getY();
double daxial = dTA_dUV[1][0]*pnt.getX() + dTA_dUV[1][1]*pnt.getY();
double tilt0 = tiltCenter + dtilt;
double axial0 = axialCenter + daxial;
LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.gIS[imageSetNumber].goniometerTilt = tilt0;
LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.gIS[imageSetNumber].goniometerAxial = axial0;
LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.gIS[imageSetNumber].interAxisAngle = interCenter; // no scanning, just use center value
if (DEBUG_LEVEL>0) System.out.println("Image Set #"+imageSetNumber+
" Initial tilt=" + tilt0+
" Initial axial=" + axial0+
" Initial inter=" + interCenter);
imageSets=LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.listImages(!processAllImages);
imageSet=imageSets[imageSetNumber];
if (imageSet==null){
IJ.showMessage("Image set #"+imageSetNumber+" is empty");
return false;
}
for (int i=0;i<imageSet.length;i++){
int imageNumber=imageSet[i];
LENS_DISTORTIONS.applyHintedGrids(
LASER_POINTERS, // MatchSimulatedPattern.LaserPointer laserPointer, // LaserPointer object that specifies actual laser poiners on the target
DISTORTION_PROCESS_CONFIGURATION.removeOutOfGridPointers, // boolean removeOutOfGridPointers,
hintGridTolerance, //double hintGridTolerance, // alllowed mismatch (fraction of period) or 0 - orientation only
true, //processAll, //boolean processAll, // if true - process all images, false - only disabled
ignoreLaserPointers, //true, //ignoreLaserPointers,
true, //processBlind,
imageNumber,
useSetsData,
THREADS_MAX, //int threadsMax,
UPDATE_STATUS, // boolean updateStatus,
DISTORTION.loop_debug_level, // int mspDebugLevel,
MASTER_DEBUG_LEVEL, //int global_debug_level, // DEBUG_LEVEL
MASTER_DEBUG_LEVEL //int debug_level // debug level used inside loops
);
}
selection =LENS_DISTORTIONS.fittingStrategy.selectAllImages(0); // enable all images in series 0
for (int i=0;i<selection.length;i++) selection[i]=false;
for (int i=0;i<imageSet.length;i++) selection[imageSet[i]]=true;
LENS_DISTORTIONS.fittingStrategy.setImageSelection(0,selection);
LENS_DISTORTIONS.seriesNumber= 0; // start from 0;
LENS_DISTORTIONS.initFittingSeries(false,LENS_DISTORTIONS.filterForAll,0); // will set this.currentVector
//this.stopAfterThis[numSeries]
LENS_DISTORTIONS.fittingStrategy.stopAfterThis[0]=true;
LENS_DISTORTIONS.stopEachStep= false;
LENS_DISTORTIONS.stopEachSeries= false; // will not ask for confirmation after done
LENS_DISTORTIONS.stopOnFailure=false;
LENS_DISTORTIONS.lambda=LENS_DISTORTIONS.fittingStrategy.lambdas[0]; // 0.001; // why it does not use fitting series lambda?
boolean LMA_OK=LENS_DISTORTIONS.LevenbergMarquardt(
false, // skip dialog
false, // new: dry_run use it here?
false); // no need to calculate dTA_dUV
if (LMA_OK) {
tilt_last = LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.gIS[imageSetNumber].goniometerTilt;
axial_last = LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.gIS[imageSetNumber].goniometerAxial;
inter_last = LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.gIS[imageSetNumber].interAxisAngle;
rms_last = LENS_DISTORTIONS.currentRMS;
if (rms_last < best_rms) { // no Double.NaN for best_rms here
best_rms = rms_last;
best_tilt = tilt_last;
best_axial = axial_last;
best_inter = inter_last;
best_pnt = pnt;
}
if (best_rms <= stopRMS) {
break;
}
} else {
if (DEBUG_LEVEL>0) System.out.println("----------------- LMA FAILED -------------------------");
}
}
if (DEBUG_LEVEL>0) System.out.println("================ Image Set #"+imageSetNumber+" rms="+IJ.d2s(best_rms, 6)+
" final tilt= "+best_tilt+ " ("+tiltCenter+")\n" +
" final axial="+best_axial+" ("+axialCenter+")\n"+
" final inter="+best_inter+" ("+interCenter+")");
if (best_rms != rms_last) {
// Restore best position if it was not the last
LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.gIS[imageSetNumber].goniometerTilt= best_tilt;
LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.gIS[imageSetNumber].goniometerAxial=best_axial;
LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.gIS[imageSetNumber].interAxisAngle= best_inter;
if (DEBUG_LEVEL>0) System.out.println(
"Repeating with the best variant for Image Set #"+imageSetNumber+
" Initial tilt="+best_tilt+
" Initial axial="+best_axial+
" Initial inter="+best_inter
);
imageSets=LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.listImages(!processAllImages);
imageSet=imageSets[imageSetNumber];
if (imageSet==null){
IJ.showMessage("Image set #"+imageSetNumber+" is empty");
return false;
}
for (int i=0;i<imageSet.length;i++){
int imageNumber=imageSet[i];
LENS_DISTORTIONS.applyHintedGrids(
LASER_POINTERS, // MatchSimulatedPattern.LaserPointer laserPointer, // LaserPointer object that specifies actual laser poiners on the target
DISTORTION_PROCESS_CONFIGURATION.removeOutOfGridPointers, // boolean removeOutOfGridPointers,
hintGridTolerance, //double hintGridTolerance, // alllowed mismatch (fraction of period) or 0 - orientation only
true, //processAll, //boolean processAll, // if true - process all images, false - only disabeld
ignoreLaserPointers, //ignoreLaserPointers,
true, //processBlind,
imageNumber,
useSetsData,
THREADS_MAX, //int threadsMax,
UPDATE_STATUS, // boolean updateStatus,
DISTORTION.loop_debug_level, // int mspDebugLevel,
MASTER_DEBUG_LEVEL, //int global_debug_level, // DEBUG_LEVEL
MASTER_DEBUG_LEVEL //int debug_level // debug level used inside loops
);
}
// set series 0 to this set images
selection =LENS_DISTORTIONS.fittingStrategy.selectAllImages(0); // enable all images in series 0
for (int i=0;i<selection.length;i++) selection[i]=false;
for (int i=0;i<imageSet.length;i++) selection[imageSet[i]]=true;
LENS_DISTORTIONS.fittingStrategy.setImageSelection(0,selection);
LENS_DISTORTIONS.seriesNumber= 0; // start from 0;
LENS_DISTORTIONS.initFittingSeries(false,LENS_DISTORTIONS.filterForAll,0); // will set this.currentVector
//this.stopAfterThis[numSeries]
LENS_DISTORTIONS.fittingStrategy.stopAfterThis[0]=true;
LENS_DISTORTIONS.stopEachStep= false;
LENS_DISTORTIONS.stopEachSeries= false; // will not ask for confirmation after done
LENS_DISTORTIONS.lambda=LENS_DISTORTIONS.fittingStrategy.lambdas[0];
LENS_DISTORTIONS.LevenbergMarquardt(
false, // skip dialog
false); // new: dry_run use it here?
}
}
//save safe settings to run LMA manually
LENS_DISTORTIONS.seriesNumber= 0; // start from 0;
LENS_DISTORTIONS.initFittingSeries(false,LENS_DISTORTIONS.filterForAll,0); // will set this.currentVector
LENS_DISTORTIONS.stopEachSeries= true; // will not ask for confirmation after done
LENS_DISTORTIONS.stopOnFailure=true;
LENS_DISTORTIONS.lambda=LENS_DISTORTIONS.fittingStrategy.lambdas[0];
if (DEBUG_LEVEL > -1) System.out.println("================ Image Set #"+imageSetNumber+" rms="+IJ.d2s(best_rms, 6)+
" final tilt="+best_tilt+" ("+tiltCenter+") " +
" final axial="+best_axial+" ("+axialCenter+")" +
" final inter="+best_inter+" ("+interCenter+")" +
" final UV offset = ("+best_pnt.getX()+","+best_pnt.getY()+")");
return true;
}
public boolean lwirToEo() { public boolean lwirToEo() {
if (LENS_DISTORTIONS == null) { if (LENS_DISTORTIONS == null) {
System.out.println("LENS_DISTORTIONS is null"); System.out.println("LENS_DISTORTIONS is null");
...@@ -10204,8 +10337,14 @@ if (MORE_BUTTONS) { ...@@ -10204,8 +10337,14 @@ if (MORE_BUTTONS) {
String prefix="grid-"; String prefix="grid-";
DEBUG_LEVEL=MASTER_DEBUG_LEVEL; DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
DISTORTION_PROCESS_CONFIGURATION.debugLevel=MASTER_DEBUG_LEVEL; DISTORTION_PROCESS_CONFIGURATION.debugLevel=MASTER_DEBUG_LEVEL;
if (matchSimulatedPattern==null) matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize); /*
if (matchSimulatedPattern==null) {
int sensor_type = 0; // EO
// matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize);
matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.getFFTSize(sensor_type)); //FIXME: works only for EO !!!
}
matchSimulatedPattern.debugLevel=MASTER_DEBUG_LEVEL; matchSimulatedPattern.debugLevel=MASTER_DEBUG_LEVEL;
*/
String [] sourceSetList = DISTORTION_PROCESS_CONFIGURATION.selectSourceSets(); String [] sourceSetList = DISTORTION_PROCESS_CONFIGURATION.selectSourceSets();
LWIR_PARAMETERS.selectSourceChannels(); LWIR_PARAMETERS.selectSourceChannels();
boolean [] sel_chn = LWIR_PARAMETERS.getSelected(); boolean [] sel_chn = LWIR_PARAMETERS.getSelected();
...@@ -10271,12 +10410,14 @@ if (MORE_BUTTONS) { ...@@ -10271,12 +10410,14 @@ if (MORE_BUTTONS) {
} }
imp_sel=new ImagePlus(sourceFilesList[nset][nfile]); // read source file imp_sel=new ImagePlus(sourceFilesList[nset][nfile]); // read source file
EyesisTiff.decodeProperiesFromInfo(imp_sel); EyesisTiff.decodeProperiesFromInfo(imp_sel);
int sensor_type = LwirReaderParameters.sensorType(imp_sel);
matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize); // TODO: is it needed each time?
matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.getFFTSize(sensor_type)); // FFTSize); // TODO: is it needed each time?
matchSimulatedPattern.debugLevel=MASTER_DEBUG_LEVEL;
matchSimulatedPattern.invalidateFlatFieldForGrid(); //Reset Flat Field calibration - different image. matchSimulatedPattern.invalidateFlatFieldForGrid(); //Reset Flat Field calibration - different image.
matchSimulatedPattern.invalidateFocusMask(); matchSimulatedPattern.invalidateFocusMask();
boolean is_lwir = LWIR_PARAMETERS.is_LWIR(imp_sel); // Not used! boolean is_lwir = (sensor_type == 1); // LWIR_PARAMETERS.is_LWIR(imp_sel); // Not used! sensorType(ImagePlus imp)
int numAbsolutePoints=matchSimulatedPattern.calculateDistortions( // matchSimulatedPattern.PATTERN_GRID already set int numAbsolutePoints=matchSimulatedPattern.calculateDistortions( // matchSimulatedPattern.PATTERN_GRID already set
LWIR_PARAMETERS, // LwirReaderParameters lwirReaderParameters, LWIR_PARAMETERS, // LwirReaderParameters lwirReaderParameters,
DISTORTION, // DISTORTION, //
...@@ -10353,7 +10494,11 @@ if (MORE_BUTTONS) { ...@@ -10353,7 +10494,11 @@ if (MORE_BUTTONS) {
String prefix="grid-"; String prefix="grid-";
DEBUG_LEVEL=MASTER_DEBUG_LEVEL; DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
DISTORTION_PROCESS_CONFIGURATION.debugLevel=MASTER_DEBUG_LEVEL; DISTORTION_PROCESS_CONFIGURATION.debugLevel=MASTER_DEBUG_LEVEL;
if (matchSimulatedPattern==null) matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize); if (matchSimulatedPattern==null) {
// matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize);
int sensor_type = 0; // EO
matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.getFFTSize(sensor_type));
}
matchSimulatedPattern.debugLevel=MASTER_DEBUG_LEVEL; matchSimulatedPattern.debugLevel=MASTER_DEBUG_LEVEL;
String [] sourceFilesList=DISTORTION_PROCESS_CONFIGURATION.selectSourceFiles(); // select files - with/without dialog String [] sourceFilesList=DISTORTION_PROCESS_CONFIGURATION.selectSourceFiles(); // select files - with/without dialog
boolean saveGrids=DISTORTION_PROCESS_CONFIGURATION.saveGridImages; boolean saveGrids=DISTORTION_PROCESS_CONFIGURATION.saveGridImages;
...@@ -10384,7 +10529,9 @@ if (MORE_BUTTONS) { ...@@ -10384,7 +10529,9 @@ if (MORE_BUTTONS) {
} }
imp_sel=new ImagePlus(sourceFilesList[numFile]); // read source file imp_sel=new ImagePlus(sourceFilesList[numFile]); // read source file
JP4_INSTANCE.decodeProperiesFromInfo(imp_sel); JP4_INSTANCE.decodeProperiesFromInfo(imp_sel);
matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize); // TODO: is it needed each time? // matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize); // TODO: is it needed each time?
int sensor_type = 0; // EO
matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.getFFTSize(sensor_type));
if (!DISTORTION_PROCESS_CONFIGURATION.useNoPonters && (MatchSimulatedPattern.getPointersXYUV(imp_sel,LASER_POINTERS)==null)) { if (!DISTORTION_PROCESS_CONFIGURATION.useNoPonters && (MatchSimulatedPattern.getPointersXYUV(imp_sel,LASER_POINTERS)==null)) {
if (this.SYNC_COMMAND.stopRequested.get()>0) { if (this.SYNC_COMMAND.stopRequested.get()>0) {
System.out.println("User requested stop"); System.out.println("User requested stop");
...@@ -10499,7 +10646,9 @@ if (MORE_BUTTONS) { ...@@ -10499,7 +10646,9 @@ if (MORE_BUTTONS) {
true, // un-apply camera color gains true, // un-apply camera color gains
imp_sel); // reuse the same image window imp_sel); // reuse the same image window
//Remove for old method? //Remove for old method?
matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize); // matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize);
int sensor_type = 0; // EO
matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.getFFTSize(sensor_type));
matchSimulatedPattern.calculateDistortions( matchSimulatedPattern.calculateDistortions(
LWIR_PARAMETERS, LWIR_PARAMETERS,
DISTORTION, // DISTORTION, //
...@@ -10900,6 +11049,8 @@ if (MORE_BUTTONS) { ...@@ -10900,6 +11049,8 @@ if (MORE_BUTTONS) {
numInBase2= (int) gd.getNextNumber(); numInBase2= (int) gd.getNextNumber();
binWidth2 = gd.getNextNumber(); binWidth2 = gd.getNextNumber();
gapWidth2 = gd.getNextNumber(); gapWidth2 = gd.getNextNumber();
int sensor_type = 0; // EO
double [] defectsBayer=(new SFEPhases()).getDefectsBayer( double [] defectsBayer=(new SFEPhases()).getDefectsBayer(
imp_sel, imp_sel,
tileClearSize, tileClearSize,
...@@ -10915,7 +11066,9 @@ if (MORE_BUTTONS) { ...@@ -10915,7 +11066,9 @@ if (MORE_BUTTONS) {
numInBase2, numInBase2,
binWidth2, binWidth2,
gapWidth2, gapWidth2,
new MatchSimulatedPattern(DISTORTION.FFTSize), //matchSimulatedPattern= // new MatchSimulatedPattern(DISTORTION.FFTSize), //matchSimulatedPattern=
new MatchSimulatedPattern(DISTORTION.getFFTSize(sensor_type)),
COMPONENTS, COMPONENTS,
THREADS_MAX, THREADS_MAX,
DEBUG_LEVEL); DEBUG_LEVEL);
...@@ -10978,6 +11131,7 @@ if (MORE_BUTTONS) { ...@@ -10978,6 +11131,7 @@ if (MORE_BUTTONS) {
numInBase2= (int) gd.getNextNumber(); numInBase2= (int) gd.getNextNumber();
binWidth2 = gd.getNextNumber(); binWidth2 = gd.getNextNumber();
gapWidth2 = gd.getNextNumber(); gapWidth2 = gd.getNextNumber();
int sensor_type = 0; // EO
SFEPhases.SensorDefects[] defectsStats=(new SFEPhases()).accummulateSensorDefects( SFEPhases.SensorDefects[] defectsStats=(new SFEPhases()).accummulateSensorDefects(
DISTORTION_PROCESS_CONFIGURATION, DISTORTION_PROCESS_CONFIGURATION,
// imp_sel, // imp_sel,
...@@ -10994,7 +11148,9 @@ if (MORE_BUTTONS) { ...@@ -10994,7 +11148,9 @@ if (MORE_BUTTONS) {
numInBase2, numInBase2,
binWidth2, binWidth2,
gapWidth2, gapWidth2,
new MatchSimulatedPattern(DISTORTION.FFTSize), //matchSimulatedPattern= // new MatchSimulatedPattern(DISTORTION.FFTSize), //matchSimulatedPattern=
new MatchSimulatedPattern(DISTORTION.getFFTSize(sensor_type)),
COMPONENTS, COMPONENTS,
this.SYNC_COMMAND.stopRequested, this.SYNC_COMMAND.stopRequested,
THREADS_MAX, THREADS_MAX,
...@@ -11061,6 +11217,7 @@ if (MORE_BUTTONS) { ...@@ -11061,6 +11217,7 @@ if (MORE_BUTTONS) {
} }
if (showImages) for (ImagePlus imp:accImages) if (imp!=null) imp.show(); if (showImages) for (ImagePlus imp:accImages) if (imp!=null) imp.show();
// SFEPhases sfe_phases= new SFEPhases(); // SFEPhases sfe_phases= new SFEPhases();
int sensor_type = 0; // EO
defectList= (new SFEPhases()).interactiveExtractDefectListsFromAccumulatedImages( defectList= (new SFEPhases()).interactiveExtractDefectListsFromAccumulatedImages(
accImages, accImages,
128, // tileClearSize, 128, // tileClearSize,
...@@ -11080,7 +11237,8 @@ if (MORE_BUTTONS) { ...@@ -11080,7 +11237,8 @@ if (MORE_BUTTONS) {
true, // processCold, true, // processCold,
true, // updateSensorCalibrationFiles true, // updateSensorCalibrationFiles
false, // clearDefects, // clear defects if none detected false, // clearDefects, // clear defects if none detected
new MatchSimulatedPattern(DISTORTION.FFTSize), //matchSimulatedPattern= // new MatchSimulatedPattern(DISTORTION.FFTSize), //matchSimulatedPattern=
new MatchSimulatedPattern(DISTORTION.getFFTSize(sensor_type)),
COMPONENTS, COMPONENTS,
THREADS_MAX, THREADS_MAX,
DEBUG_LEVEL); DEBUG_LEVEL);
...@@ -21043,180 +21201,12 @@ use the result to create a rejectiobn mask - if the energy was high, (multiplica ...@@ -21043,180 +21201,12 @@ use the result to create a rejectiobn mask - if the energy was high, (multiplica
/* ======================================================================== */ /* ======================================================================== */
/* ======================================================================== */ /* ======================================================================== */
public boolean showDistortionDialog(MatchSimulatedPattern.DistortionParameters distortionParameters) { public boolean showDistortionDialog(MatchSimulatedPattern.DistortionParameters distortionParameters) {
int i; int [] mdl = {MASTER_DEBUG_LEVEL};
GenericDialog gd = new GenericDialog("Distrortion parameters"); if (distortionParameters.showDistortionDialog(mdl)) {
gd.addNumericField("FFTSize (Initial pattern and aberraton kernels):", distortionParameters.FFTSize, 0); // 256 MASTER_DEBUG_LEVEL = mdl[0];
gd.addNumericField("FFTSize for LWIR sensors):", distortionParameters.FFTSize_lwir, 0); // 32 return true;
gd.addNumericField("FFTOverlap (aberration kernels):", distortionParameters.FFTOverlap, 0); // 32 }
gd.addNumericField("FFTOverlap for LWIR sensors):", distortionParameters.FFTOverlap_lwir, 0); // 4 return false;
gd.addNumericField("FFT Gaussian width (relative):", distortionParameters.fftGaussWidth, 3);
gd.addNumericField("Correlation size:", distortionParameters.correlationSize, 0); // 64
gd.addNumericField("Correlation size LWIR:", distortionParameters.correlationSizeLwir, 0); // 16
gd.addNumericField("Maximal correlation size:", distortionParameters.maximalCorrelationSize, 0); // 128
gd.addNumericField("Maximal correlation size LWIR:", distortionParameters.maximalCorrelationSizeLwir, 0); // 16
gd.addNumericField("Correlation Gauss width (relative):", distortionParameters.correlationGaussWidth, 3);
gd.addCheckbox("Keep Gaussian width absolute when increasing FFT size",distortionParameters.absoluteCorrelationGaussWidth);
// /phaseCorrelationFraction
//// leave this number of zeros on teh margins of the window (toatal from both sides). If correlationGaussWidth>0 will
// additionally multiply by Hamming
gd.addNumericField("Leave zeros on the window margins (toatal numbedr from both sides)", distortionParameters.zeros, 0);
gd.addNumericField("Phase correlation modifier (1.0 - phase corr., 0 - just corr.)", distortionParameters.phaseCorrelationFraction, 5);
gd.addNumericField("Correlation high-pass sigma:", distortionParameters.correlationHighPassSigma, 3);
gd.addNumericField("Correlation low-pass sigma (fraction of sqrt(2)*Nyquist, lower - more filtering, 0 -none):",distortionParameters.correlationLowPassSigma, 3);
gd.addNumericField("Correlation maximal offset from predicted:",distortionParameters.correlationMaxOffset, 3);
gd.addNumericField("Detection ring width (fraction):", distortionParameters.correlationRingWidth, 3);
gd.addNumericField("Correlation minimal contrast (normalized)", distortionParameters.correlationMinContrast, 3);
gd.addNumericField("Correlation minimal contrast for initial search (normalized)", distortionParameters.correlationMinInitialContrast, 3);
gd.addNumericField("Correlation minimal contrast (absolute)", distortionParameters.correlationMinAbsoluteContrast, 3);
gd.addNumericField("Correlation minimal contrast for initial search (absolute)", distortionParameters.correlationMinAbsoluteInitialContrast, 3);
gd.addNumericField("Decrease contrast of cells that are too close to the border to be processed in refinement pass", distortionParameters.scaleFirstPassContrast, 3);
gd.addNumericField("Gaussian sigma to select correlation center in pixels, 2.0", distortionParameters.contrastSelectSigmaCenter, 3);
gd.addNumericField("Gaussian sigma to select correlation off-centers (fraction of UV period), 0.1", distortionParameters.contrastSelectSigma, 3);
gd.addNumericField("Gaussian sigma to average correlation variations (as contrast reference), 0.5", distortionParameters.contrastAverageSigma, 3);
gd.addNumericField("Minimal initial pattern cluster size (0 - disable retries)", distortionParameters.minimalPatternCluster, 0); // 40
gd.addNumericField("Minimal initial LWIR pattern cluster size (0 - disable retries)", distortionParameters.minimalPatternClusterLwir, 0); // 10
gd.addNumericField("Scale minimal contrast if the initial cluster is nonzero but smaller", distortionParameters.scaleMinimalInitialContrast, 3);
gd.addNumericField("Overlap of FFT areas when searching for pattern", distortionParameters.searchOverlap, 3);
gd.addNumericField("Pattern subdivision:", distortionParameters.patternSubdiv, 0); // 4
gd.addNumericField("Blur pattern bitmap (sigma): ", distortionParameters.bPatternSigma, 3,5,"pattern cell"); // 0.02
gd.addNumericField("Blur pattern (sigma): ", distortionParameters.barraySigma, 3,5,"sensor pix"); // 0.5
gd.addNumericField("Correlation weights (around maximum):", distortionParameters.correlationWeightSigma, 3,5,"nodes"); // 2.5
gd.addNumericField("Correlation radius scale (0 - sharp sigma)", distortionParameters.correlationRadiusScale, 1,3,"sigmas"); //2.0
gd.addNumericField("Correlation maximal radius to use", distortionParameters.correlationRadius, 0,1,"pix"); // 2.0
gd.addNumericField("Correlation maximum calculation threshold", distortionParameters.correlationThreshold*100, 2,5,"%"); // .8
gd.addNumericField("Interpolate correlation (FFT*linear)", distortionParameters.correlationSubdiv, 0,3,"x"); // 16
gd.addNumericField("Interpolate correlation with FFT", distortionParameters.correlationFFTSubdiv, 0,3,"x"); // 4
gd.addNumericField("Correlation dx (debug)", distortionParameters.correlationDx, 3);
gd.addNumericField("Correlation dy (debug)", distortionParameters.correlationDy, 3);
gd.addNumericField("Maximal size of the pattern grid (square)", distortionParameters.gridSize, 0);
gd.addCheckbox ("Refine correlations", distortionParameters.refineCorrelations);
gd.addCheckbox ("Use fast correlation on first pass", distortionParameters.fastCorrelationOnFirstPass);
gd.addCheckbox ("Use fast correlation on refine pass", distortionParameters.fastCorrelationOnFinalPass);
gd.addCheckbox ("Average correlation measurements between neighbors (on refine)", distortionParameters.correlationAverageOnRefine);
gd.addCheckbox ("Update coordinates of the grid points as they are recalculated (false - then update all at once)", distortionParameters.refineInPlace);
gd.addNumericField("Distance to ortho neighbors (for averaging)", distortionParameters.averageOrthoDist, 3,5,"sensor pix");
gd.addNumericField("Combined weight of ortho neighbors (fraction of 1.0)", distortionParameters.averageOrthoWeight, 3);
gd.addNumericField("Distance to diagonal neighbors (for averaging)", distortionParameters.averageDiagDist, 3,5,"sensor pix");
gd.addNumericField("Combined weight of diagonal neighbors (fraction of 1.0)", distortionParameters.averageDiagWeight, 3);
gd.addCheckbox ("Use quadratic extrapolation (false - force linear)", distortionParameters.useQuadratic);
gd.addCheckbox ("Remove outer (unreliable) layer before extrapolation", distortionParameters.removeLast);
gd.addNumericField("Number of extrapolated layers of nodes (final stage)", distortionParameters.numberExtrapolated, 0);
gd.addNumericField("Sigma during final extrapolation stage", distortionParameters.extrapolationSigma, 3,5,"nodes");
gd.addNumericField("Minimal UV span in correlation window to trigger FFT size increase", distortionParameters.minUVSpan, 3);
gd.addCheckbox ("Compensate uneven pattern intensity", distortionParameters.flatFieldCorrection);
gd.addNumericField("Extrapolate pattern intensity map (relative to pattern period)", distortionParameters.flatFieldExtarpolate, 3);
gd.addNumericField("Blur pattern intensity map (relative to pattern period)", distortionParameters.flatFieldBlur, 3);
gd.addNumericField("Do not use areas where intensity map is below this part of maximal", distortionParameters.flatFieldMin, 3);
gd.addNumericField("Shrink before extrapolating intensity map (relative to the average grid period)", distortionParameters.flatFieldShrink, 3);
gd.addNumericField("Expand during extrapolation (relative to the average grid period)", distortionParameters.flatFieldExpand, 3);
gd.addNumericField("Extrapolation weight effective radius (relative to the average grid period)", distortionParameters.flatFieldSigmaRadius, 3);
gd.addNumericField("Consider pixels in a square with the side twice this (relative to flatFieldSigmaRadius)", distortionParameters.flatFieldExtraRadius, 3);
gd.addNumericField("Multiply the average grid period to determine the area for averaging the grig brightness", distortionParameters.averagingAreaScale, 3);
gd.addCheckbox ("Legacy mode (deprecated)", distortionParameters.legacyMode);
gd.addNumericField("Debug level inside the loop", distortionParameters.loop_debug_level, 0);
gd.addNumericField("Debug Level:", MASTER_DEBUG_LEVEL, 0);
WindowTools.addScrollBars(gd);
gd.showDialog();
if (gd.wasCanceled()) return false;
distortionParameters.FFTSize = makePowerOfTwo((int) gd.getNextNumber());
distortionParameters.FFTSize_lwir = makePowerOfTwo((int) gd.getNextNumber());
distortionParameters.FFTOverlap = makePowerOfTwo((int) gd.getNextNumber());
distortionParameters.FFTOverlap_lwir = makePowerOfTwo((int) gd.getNextNumber());
distortionParameters.fftGaussWidth= gd.getNextNumber();
distortionParameters.correlationSize = makePowerOfTwo((int) gd.getNextNumber());
distortionParameters.correlationSizeLwir = makePowerOfTwo((int) gd.getNextNumber());
distortionParameters.maximalCorrelationSize = makePowerOfTwo((int) gd.getNextNumber());
distortionParameters.maximalCorrelationSizeLwir = makePowerOfTwo((int) gd.getNextNumber());
distortionParameters.correlationGaussWidth= gd.getNextNumber();
distortionParameters.absoluteCorrelationGaussWidth=gd.getNextBoolean();
distortionParameters.zeros= (int) gd.getNextNumber();
distortionParameters.phaseCorrelationFraction= gd.getNextNumber();
distortionParameters.correlationHighPassSigma= gd.getNextNumber();
distortionParameters.correlationLowPassSigma= gd.getNextNumber();
distortionParameters.correlationMaxOffset= gd.getNextNumber();
distortionParameters.correlationRingWidth= gd.getNextNumber();
distortionParameters.correlationMinContrast= gd.getNextNumber();
distortionParameters.correlationMinInitialContrast= gd.getNextNumber();
distortionParameters.correlationMinAbsoluteContrast= gd.getNextNumber();
distortionParameters.correlationMinAbsoluteInitialContrast= gd.getNextNumber();
distortionParameters.scaleFirstPassContrast= gd.getNextNumber();
distortionParameters.contrastSelectSigmaCenter= gd.getNextNumber();
distortionParameters.contrastSelectSigma= gd.getNextNumber();
distortionParameters.contrastAverageSigma= gd.getNextNumber();
distortionParameters.minimalPatternCluster=(int) gd.getNextNumber();
distortionParameters.minimalPatternClusterLwir=(int) gd.getNextNumber();
distortionParameters.scaleMinimalInitialContrast=gd.getNextNumber();
distortionParameters.searchOverlap= gd.getNextNumber();
distortionParameters.patternSubdiv= (int) gd.getNextNumber();
distortionParameters.bPatternSigma= gd.getNextNumber();
distortionParameters.barraySigma= gd.getNextNumber();
distortionParameters.correlationWeightSigma= gd.getNextNumber();
distortionParameters.correlationRadiusScale= gd.getNextNumber();
distortionParameters.correlationRadius= (int) gd.getNextNumber();
distortionParameters.correlationThreshold= 0.01*gd.getNextNumber();
distortionParameters.correlationSubdiv= (int) gd.getNextNumber();
distortionParameters.correlationFFTSubdiv=1;
for (i=(int) gd.getNextNumber(); i >1; i>>=1) distortionParameters.correlationFFTSubdiv <<=1; /* make it to be power of 2 */
distortionParameters.correlationDx= gd.getNextNumber();
distortionParameters.correlationDy= gd.getNextNumber();
distortionParameters.gridSize= (int) gd.getNextNumber();
distortionParameters.refineCorrelations= gd.getNextBoolean();
distortionParameters.fastCorrelationOnFirstPass=gd.getNextBoolean();
distortionParameters.fastCorrelationOnFinalPass=gd.getNextBoolean();
distortionParameters.correlationAverageOnRefine=gd.getNextBoolean();
distortionParameters.refineInPlace= gd.getNextBoolean();
distortionParameters.averageOrthoDist= gd.getNextNumber();
distortionParameters.averageOrthoWeight= gd.getNextNumber();
distortionParameters.averageDiagDist= gd.getNextNumber();
distortionParameters.averageDiagWeight= gd.getNextNumber();
distortionParameters.useQuadratic= gd.getNextBoolean();
distortionParameters.removeLast= gd.getNextBoolean();
distortionParameters.numberExtrapolated=(int) gd.getNextNumber();
distortionParameters.extrapolationSigma= gd.getNextNumber();
distortionParameters.minUVSpan= gd.getNextNumber();
distortionParameters.flatFieldCorrection= gd.getNextBoolean();
distortionParameters.flatFieldExtarpolate= gd.getNextNumber();
distortionParameters.flatFieldBlur= gd.getNextNumber();
distortionParameters.flatFieldMin= gd.getNextNumber();
distortionParameters.flatFieldShrink= gd.getNextNumber();
distortionParameters.flatFieldExpand= gd.getNextNumber();
distortionParameters.flatFieldSigmaRadius= gd.getNextNumber();
distortionParameters.flatFieldExtraRadius= gd.getNextNumber();
distortionParameters.averagingAreaScale= gd.getNextNumber();
distortionParameters.legacyMode= gd.getNextBoolean();
distortionParameters.loop_debug_level= (int) gd.getNextNumber();
MASTER_DEBUG_LEVEL= (int) gd.getNextNumber();
return true;
}
private int makePowerOfTwo(int v) {
int v2 = 1;
for (int i=v; i > 1; i>>=1 ) v2 <<=1; /* make it to be power of 2 */
return v2;
} }
/* ======================================================================== */ /* ======================================================================== */
/* ======================================================================== */ /* ======================================================================== */
...@@ -96,6 +96,7 @@ import ij.text.TextWindow; ...@@ -96,6 +96,7 @@ import ij.text.TextWindow;
return (eyesisCameraParameters==null)?0:eyesisCameraParameters.getNumStations(); return (eyesisCameraParameters==null)?0:eyesisCameraParameters.getNumStations();
} }
public double getPixelSize(int station, int channel) { public double getPixelSize(int station, int channel) {
return this.eyesisCameraParameters.eyesisSubCameras[station][channel].getPixelSize(); return this.eyesisCameraParameters.eyesisSubCameras[station][channel].getPixelSize();
} }
......
...@@ -36,6 +36,7 @@ import java.util.concurrent.atomic.AtomicInteger; ...@@ -36,6 +36,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import com.elphel.imagej.calibration.DistortionCalibrationData.GridImageParameters;
import com.elphel.imagej.calibration.hardware.CamerasInterface; import com.elphel.imagej.calibration.hardware.CamerasInterface;
import com.elphel.imagej.cameras.EyesisCameraParameters; import com.elphel.imagej.cameras.EyesisCameraParameters;
import com.elphel.imagej.cameras.EyesisSubCameraParameters; import com.elphel.imagej.cameras.EyesisSubCameraParameters;
...@@ -78,6 +79,7 @@ public class Distortions { ...@@ -78,6 +79,7 @@ public class Distortions {
public double [] Y=null; // array of "y" - for each grid image, each defined grid node - 2 elements public double [] Y=null; // array of "y" - for each grid image, each defined grid node - 2 elements
public int [] imageStartIndex=null; // elements containing index of the start point of the selected image, first element 0, last - total number of points. public int [] imageStartIndex=null; // elements containing index of the start point of the selected image, first element 0, last - total number of points.
public double [] weightFunction=null; // array of weights for pixels (to fade values near borders), corresponding to Y array public double [] weightFunction=null; // array of weights for pixels (to fade values near borders), corresponding to Y array
public double [][] dTA_dUV = null; // null or double [2][2] to return averaged {{dU/dAz,dU/dTl}{dV/dAz,dV/dTl}}.inverse
public double sumWeights; public double sumWeights;
public double [][] targetXYZ=null; // array of target {x,y,z} matching each image each grid point public double [][] targetXYZ=null; // array of target {x,y,z} matching each image each grid point
...@@ -175,7 +177,10 @@ public class Distortions { ...@@ -175,7 +177,10 @@ public class Distortions {
} }
public void setSensorHeight(int subCam, int v) {fittingStrategy.distortionCalibrationData.eyesisCameraParameters.setSensorHeight(subCam, v);} public void setSensorHeight(int subCam, int v) {fittingStrategy.distortionCalibrationData.eyesisCameraParameters.setSensorHeight(subCam, v);}
public void setDecimateMasks(int subCam, int v){fittingStrategy.distortionCalibrationData.eyesisCameraParameters.setDecimateMasks(subCam, v);} public void setDecimateMasks(int subCam, int v){fittingStrategy.distortionCalibrationData.eyesisCameraParameters.setDecimateMasks(subCam, v);}
public double [][] getDtaDuv(){
return dTA_dUV;
}
public class LMAArrays { public class LMAArrays {
...@@ -399,7 +404,7 @@ public class Distortions { ...@@ -399,7 +404,7 @@ public class Distortions {
System.out.println("initFittingSeries("+justSelection+","+filter+","+numSeries+"), pass="+pass); System.out.println("initFittingSeries("+justSelection+","+filter+","+numSeries+"), pass="+pass);
//TODO: ********* Implement comments above ************ //TODO: ********* Implement comments above ************
// calculate total number of x/y pairs in the selected images // calculate total number of x/y pairs in the selected images
if (numSeries<0) justSelection=true; if (numSeries <0 ) justSelection=true;
if ((pass==1) && (numSeries>=0)) fittingStrategy.invalidateSelectedImages(numSeries); // next selectedImages() will select all, including empty if ((pass==1) && (numSeries>=0)) fittingStrategy.invalidateSelectedImages(numSeries); // next selectedImages() will select all, including empty
if (!justSelection) { if (!justSelection) {
fittingStrategy.buildParameterMap (numSeries); // also sets currentSeriesNumber fittingStrategy.buildParameterMap (numSeries); // also sets currentSeriesNumber
...@@ -615,6 +620,14 @@ public class Distortions { ...@@ -615,6 +620,14 @@ public class Distortions {
if ((this.pixelCorrection==null) || (this.pixelCorrection[chnNum] == null)){ if ((this.pixelCorrection==null) || (this.pixelCorrection[chnNum] == null)){
this.Y[2*index]= fittingStrategy.distortionCalibrationData.gIP[imgNum].pixelsXY[pointNumber][0]; this.Y[2*index]= fittingStrategy.distortionCalibrationData.gIP[imgNum].pixelsXY[pointNumber][0];
this.Y[2*index+1]=fittingStrategy.distortionCalibrationData.gIP[imgNum].pixelsXY[pointNumber][1]; this.Y[2*index+1]=fittingStrategy.distortionCalibrationData.gIP[imgNum].pixelsXY[pointNumber][1];
if (Double.isNaN(this.Y[2*index]) || Double.isNaN(this.Y[2*index+1])) {
System.out.println("Bug 1 in initFittingSeries(): NaN! distortionCalibrationData.gIP["+imgNum+"].pixelsXY["+pointNumber+"][0]="+
fittingStrategy.distortionCalibrationData.gIP[imgNum].pixelsXY[pointNumber][0]+
", distortionCalibrationData.gIP["+imgNum+"].pixelsXY["+pointNumber+"][1]="+
fittingStrategy.distortionCalibrationData.gIP[imgNum].pixelsXY[pointNumber][1]);
this.Y[2*index]= 0.0;
this.Y[2*index + 1]= 0.0;
}
} else { } else {
// TODO: remove and use new code (if tested OK) // TODO: remove and use new code (if tested OK)
double [] pXY={ double [] pXY={
...@@ -632,6 +645,17 @@ public class Distortions { ...@@ -632,6 +645,17 @@ public class Distortions {
} else { } else {
this.Y[2*index]= pXY[0]-this.pixelCorrection[chnNum][0][indexXY]; //java.lang.ArrayIndexOutOfBoundsException: 3204663 this.Y[2*index]= pXY[0]-this.pixelCorrection[chnNum][0][indexXY]; //java.lang.ArrayIndexOutOfBoundsException: 3204663
this.Y[2*index+1]=pXY[1]-this.pixelCorrection[chnNum][1][indexXY]; this.Y[2*index+1]=pXY[1]-this.pixelCorrection[chnNum][1][indexXY];
if (Double.isNaN(this.Y[2*index]) || Double.isNaN(this.Y[2*index+1])) {
System.out.println("Bug 2 in initFittingSeries(): NaN! this.pixelCorrection["+chnNum+"][0]["+indexXY+"]="+
this.pixelCorrection[chnNum][0][indexXY]+
", this.pixelCorrection["+chnNum+"][1]["+indexXY+"]="+
this.pixelCorrection[chnNum][1][indexXY]+
", pXY[0]="+pXY[0]+", pXY[1]="+pXY[1]+
", imgNum="+imgNum+", pointNumber="+pointNumber);
this.Y[2*index]= 0.0;
this.Y[2*index + 1]= 0.0;
}
} }
// TODO: remove above and un-comment below (after testing) // TODO: remove above and un-comment below (after testing)
/* /*
...@@ -686,7 +710,7 @@ public class Distortions { ...@@ -686,7 +710,7 @@ public class Distortions {
} }
} }
// Normalize set weights // Normalize set weights
int numSetsUsed=0; int numSetsUsed=0+0;
double totalSetWeight=0.0; double totalSetWeight=0.0;
for (int imgSet=0;imgSet<this.fittingStrategy.distortionCalibrationData.gIS.length;imgSet++){ for (int imgSet=0;imgSet<this.fittingStrategy.distortionCalibrationData.gIS.length;imgSet++){
if (this.fittingStrategy.distortionCalibrationData.gIS[imgSet].setWeight>0){ if (this.fittingStrategy.distortionCalibrationData.gIS[imgSet].setWeight>0){
...@@ -703,7 +727,7 @@ public class Distortions { ...@@ -703,7 +727,7 @@ public class Distortions {
} }
} }
} }
// last? not here! // last? not here! numSetsUsed counted twice (should be = 1, is 2)
// this.imageStartIndex[numImg]=index; // this.imageStartIndex[numImg]=index;
if (justSelection) { if (justSelection) {
this.currentVector = null; this.currentVector = null;
...@@ -3327,14 +3351,20 @@ For each point in the image ...@@ -3327,14 +3351,20 @@ For each point in the image
System.out.println("Processing debug image "+numGridImage); System.out.println("Processing debug image "+numGridImage);
System.out.println("Processing debug image "+numGridImage); System.out.println("Processing debug image "+numGridImage);
} }
*/
int set_number = dcd.gIP[numGridImage].getSetNumber();
if ((set_number >= start_set) && if ((set_number >= start_set) &&
(set_number <= end_set) && (set_number <= end_set) &&
(((imageNumber<0) || (((imageNumber<0) || ((imageNumber==numGridImage)) && (processAll) ||
((imageNumber==numGridImage)) &&(processAll) ||
(!dcd.gIP[numGridImage].enabled && (!dcd.gIP[numGridImage].enabled &&
((hintGridTolerance>0.0) || ((dcd.gIP[numGridImage].matchedPointers>0)) && !ignoreLaserPointers))))){ // skip no-pointers if only orientation is hinted ((hintGridTolerance>0.0) ||
((dcd.gIP[numGridImage].matchedPointers>0)) && !ignoreLaserPointers))))){ // skip no-pointers if only orientation is hinted
*/
int set_number = dcd.gIP[numGridImage].getSetNumber();
if ((set_number >= start_set) && (set_number <= end_set) && // correct set range
((imageNumber < 0) || (imageNumber==numGridImage)) && // either all images or selected image
(processAll || !dcd.gIP[numGridImage].enabled) && // "process all" (including disabled) or this is disabled
((hintGridTolerance > 0.0) || ((dcd.gIP[numGridImage].matchedPointers>0) && !ignoreLaserPointers)) // hint tolerance is provided, or there are lasers not disabled
){ // skip no-pointers if only orientation is hinted
if (((dcd.gIP[numGridImage].matchedPointers==0) || ignoreLaserPointers)&& if (((dcd.gIP[numGridImage].matchedPointers==0) || ignoreLaserPointers)&&
(dcd.gIS[dcd.get_gIS_index(numGridImage)].orientationEstimated)) { (dcd.gIS[dcd.get_gIS_index(numGridImage)].orientationEstimated)) {
if ( !processBlind) { if ( !processBlind) {
...@@ -3708,6 +3738,11 @@ For each point in the image ...@@ -3708,6 +3738,11 @@ For each point in the image
public void manualGridHint(int imgNumber) { public void manualGridHint(int imgNumber) {
int [][] markers = getImageMarkers(imgNumber); int [][] markers = getImageMarkers(imgNumber);
if ((markers != null) && (markers.length > 0)) { if ((markers != null) && (markers.length > 0)) {
if (markers.length > 1) {
System.out.println("This image has multiple point marks - please remove extra");
IJ.showMessage("This image has multiple point marks - please remove extra");
return;
}
double [][] xyuv = new double [markers.length][4]; double [][] xyuv = new double [markers.length][4];
for (int i =0; i < markers.length; i++) { for (int i =0; i < markers.length; i++) {
xyuv[i][0]=markers[i][0]; xyuv[i][0]=markers[i][0];
...@@ -3771,25 +3806,28 @@ For each point in the image ...@@ -3771,25 +3806,28 @@ For each point in the image
} }
int ix0 = indx_best % width; int ix0 = indx_best % width;
int iy0 = indx_best / width; int iy0 = indx_best / width;
int half_range = 2; // was 1;
PolynomialApproximation polynomialApproximation =new PolynomialApproximation(0);// no debug PolynomialApproximation polynomialApproximation =new PolynomialApproximation(0);// no debug
double [][][] data = new double[9][3][]; // double [][][] data = new double[9][3][];
double [][][] data = new double[(2*half_range+1)*(2*half_range+1)][3][];
int indx = 0; int indx = 0;
for (int idy = -1; idy <=1; idy++) { for (int idy = -half_range; idy <=half_range; idy++) {
int iy = iy0+idy; int iy = iy0+idy;
for (int idx = -1; idx <=1; idx++) { for (int idx = -half_range; idx <= half_range; idx++) {
int ix = ix0 + idx; int ix = ix0 + idx;
data[indx][0] = new double[2]; data[indx][0] = new double[2];
data[indx][1] = new double[2]; data[indx][1] = new double[2];
data[indx][2] = new double[1]; data[indx][2] = new double[1];
data[indx][0][0] = idx; data[indx][0][0] = idx;
data[indx][0][1] = idy; data[indx][0][1] = idy;
data[indx][2][0] = 0.0;
if ((ix >= 0) && (ix < width) && (iy >= 0) && (iy < height)) { if ((ix >= 0) && (ix < width) && (iy >= 0) && (iy < height)) {
int offs = iy * width + ix; int offs = iy * width + ix;
data[indx][1][0] = pixels[0][offs] - xyuv[0][0]; if ((pixels[0][offs] >= 0) && (pixels[1][offs] >= 0)) {
data[indx][1][1] = pixels[1][offs] - xyuv[0][1]; data[indx][1][0] = pixels[0][offs] - xyuv[0][0];
data[indx][2][0] = 1.0; data[indx][1][1] = pixels[1][offs] - xyuv[0][1];
} else { data[indx][2][0] = 1.0;
data[indx][2][0] = 0.0; }
} }
indx++; indx++;
} }
...@@ -5877,7 +5915,7 @@ List calibration ...@@ -5877,7 +5915,7 @@ List calibration
final double [][] patternXYZ, // this.targetXYZ final double [][] patternXYZ, // this.targetXYZ
final double [] weightFunction, // may be null - make it twice smaller? - same for X and Y? final double [] weightFunction, // may be null - make it twice smaller? - same for X and Y?
final LensDistortionParameters lensDistortionParametersProto, final LensDistortionParameters lensDistortionParametersProto,
// final double lambda, final double [][] dTA_dUV, // null or double [][] to return averaged per-image {{dU/dAz,dU/dTl}{dV/dAz,dV/dTl}}
int threadsMax, int threadsMax,
boolean updateStatus){ boolean updateStatus){
...@@ -5906,6 +5944,8 @@ List calibration ...@@ -5906,6 +5944,8 @@ List calibration
if (selectedImages[i]) selectedIndex++; if (selectedImages[i]) selectedIndex++;
if (selectedIndex>=numSelectedImages) selectedIndex--; if (selectedIndex>=numSelectedImages) selectedIndex--;
} }
final double [][][] dUV_image = (dTA_dUV != null) ? new double [selectedImages.length][][]: null;
final double [] dUV_weights = (dTA_dUV != null) ? new double [selectedImages.length]: null;
final AtomicInteger stopRequested=this.stopRequested; final AtomicInteger stopRequested=this.stopRequested;
final AtomicBoolean interruptedAtomic=new AtomicBoolean(); final AtomicBoolean interruptedAtomic=new AtomicBoolean();
for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) {
...@@ -5915,6 +5955,11 @@ List calibration ...@@ -5915,6 +5955,11 @@ List calibration
LensDistortionParameters lensDistortionParameters=lensDistortionParametersProto.clone(); // see - if that is needed - maybe new is OK LensDistortionParameters lensDistortionParameters=lensDistortionParametersProto.clone(); // see - if that is needed - maybe new is OK
// LensDistortionParameters lensDistortionParameters= new LensDistortionParameters(); // LensDistortionParameters lensDistortionParameters= new LensDistortionParameters();
for (int numImage=imageNumberAtomic.getAndIncrement(); (numImage<selectedImages.length) && !interruptedAtomic.get();numImage=imageNumberAtomic.getAndIncrement()){ for (int numImage=imageNumberAtomic.getAndIncrement(); (numImage<selectedImages.length) && !interruptedAtomic.get();numImage=imageNumberAtomic.getAndIncrement()){
int length=2*(imageStartIndex[numImage+1]-imageStartIndex[numImage]);
if (length == 0) {
continue;
}
int start= 2*imageStartIndex[numImage];
double [][] partialJacobian= calculatePartialFxAndJacobian( double [][] partialJacobian= calculatePartialFxAndJacobian(
numImage, // number of grid image numImage, // number of grid image
vector, // parameters vector vector, // parameters vector
...@@ -5924,8 +5969,8 @@ List calibration ...@@ -5924,8 +5969,8 @@ List calibration
lensDistortionParameters, // initialize one per each tread? Or for each call? lensDistortionParameters, // initialize one per each tread? Or for each call?
true); // when false, modifies only this.lensDistortionParameters.* true); // when false, modifies only this.lensDistortionParameters.*
int length=2*(imageStartIndex[numImage+1]-imageStartIndex[numImage]); // int length=2*(imageStartIndex[numImage+1]-imageStartIndex[numImage]);
int start= 2*imageStartIndex[numImage]; // int start= 2*imageStartIndex[numImage];
double [][] partialJtByJmod=new double [numPars][numPars]; // out of heap space double [][] partialJtByJmod=new double [numPars][numPars]; // out of heap space
double [] partialJtByDiff=new double [numPars]; double [] partialJtByDiff=new double [numPars];
...@@ -5947,20 +5992,102 @@ List calibration ...@@ -5947,20 +5992,102 @@ List calibration
for (int i=0;i<numPars;i++) if (partialJacobian[i]!=null) { for (int i=0;i<numPars;i++) if (partialJacobian[i]!=null) {
partialJtByDiff[i]=0.0; partialJtByDiff[i]=0.0;
if (weightFunction!=null) if (weightFunction!=null)
for (int k=0;k<length;k++) partialJtByDiff[i]+=partialJacobian[i][k]*partialDiff[k]*weightFunction[start+k]; for (int k=0;k<length;k++) {
if (Double.isNaN(partialDiff[k])) {
System.out.println("calculateJacobianArrays() BUG1:partialDiff["+k+"]=NaN, i="+i);
} else {
partialJtByDiff[i]+=partialJacobian[i][k]*partialDiff[k]*weightFunction[start+k];
}
}
else else
for (int k=0;k<length;k++) partialJtByDiff[i]+=partialJacobian[i][k]*partialDiff[k]; for (int k=0;k<length;k++) {
if (Double.isNaN(partialDiff[k])) {
System.out.println("calculateJacobianArrays() BUG2:partialDiff["+k+"]=NaN, i="+i);
} else {
partialJtByDiff[i]+=partialJacobian[i][k]*partialDiff[k];
}
}
} }
// wrong! fix it int par_gh = -1;
/* int par_ga = -1;
synchronized(this){ if (dUV_image != null) {
for (int i=0;i<numPars;i++) if (partialJacobian[i]!=null){ dUV_image[numImage] = null; //new double [2][2];
JtByDiff[i]+=partialJtByDiff[i]; for (int i = 0; i < numPars; i++) {
for (int j=i;j<numPars;j++) JtByJmod[i][j]+=partialJtByJmod[i][j]; int parNum=fittingStrategy.parameterMap[i][1];
if (parNum == fittingStrategy.distortionCalibrationData.index_gh) {
par_gh = i;
} else if (parNum == fittingStrategy.distortionCalibrationData.index_ga) {
par_ga = i;
}
}
if ((par_gh >= 0) && (par_ga >= 0)) { // both defined
// partialJacobian[par_gh][2*k ] dPx/dGh
// partialJacobian[par_gh][2*k+1] dPy/dGh
// partialJacobian[par_gh][2*k ] dPx/dGa
// partialJacobian[par_gh][2*k+1] dPy/dGa
// d3780: public void updateGridToPointer(ImagePlus imp_grid, double[][] xyuv) {
// find average dX/dU, dY/dU, dX/dV, dY/dV
PolynomialApproximation polynomialApproximation =new PolynomialApproximation(0);// no debug
GridImageParameters gip = fittingStrategy.distortionCalibrationData.gIP[numImage];
int np = gip.pixelsXY.length;
double wsx=0.0, wsy=0.0, ws_dpx_dgh= 0.0, ws_dpy_dgh= 0.0, ws_dpx_dga= 0.0, ws_dpy_dga= 0.0;
for (int k = 0; k < length; k+=1) {
double w = (weightFunction!=null)? weightFunction[start+k] : 1.0;
wsx += w;
ws_dpx_dgh += w * partialJacobian[par_gh][k];
ws_dpx_dga += w * partialJacobian[par_ga][k];
k++;
w = (weightFunction!=null)? weightFunction[start+k] : 1.0;
wsy += w;
ws_dpy_dgh += w * partialJacobian[par_gh][k];
ws_dpy_dga += w * partialJacobian[par_ga][k];
}
if ((wsx == 0.0) || (wsy == 0.0)) {
if (debugLevel>2) {
System.out.println("Not enough data for dpx/dgh, dpy/dgh, dpx/dga, dpy/dga for image #"+numImage);
}
continue;
}
ws_dpx_dgh /= wsx;
ws_dpx_dga /= wsx;
ws_dpy_dgh /= wsy;
ws_dpy_dga /= wsy;
Matrix mXY_HA = new Matrix(new double[][] {{ws_dpx_dgh, ws_dpx_dga},{ws_dpy_dgh, ws_dpy_dga}});
double [][][] data = new double[np][3][];
for (int indx = 0; indx < np; indx++) {
data[indx][0] = new double[2];
data[indx][1] = new double[2];
data[indx][2] = new double[1];
data[indx][0][0] = gip.pixelsUV[indx][0]; // U
data[indx][0][1] = gip.pixelsUV[indx][1]; // V
data[indx][1][0] = gip.pixelsXY[indx][0]; // pX
data[indx][1][1] = gip.pixelsXY[indx][1]; // pY
data[indx][2][0] = gip.pixelsMask[indx]; // weighth
}
double [][] coeff = polynomialApproximation.quadraticApproximation(
data,
true); // force linear
Matrix mXY_UV=new Matrix(new double[][] {{coeff[0][0],coeff[0][1]},{coeff[1][0],coeff[1][1]}});
if (!(new LUDecomposition(mXY_UV)).isNonsingular()){
if (debugLevel>2) {
System.out.println("Skipping singular matrix for image #"+numImage);
}
continue;
}
Matrix mUV_XY= mXY_UV.inverse();
Matrix mUV_HA = mUV_XY.times(mXY_HA);
dUV_image [numImage] = mUV_HA.getArray();
dUV_weights[numImage] = wsx + wsy;
} else {
System.out.println ("Bug: ga/gh are not among the parameters, par_gh="+par_gh+", par_ga="+par_ga);
} }
} }
*/
synchronizedCombinePartialJacobians( synchronizedCombinePartialJacobians(
JtByJmod, //Transposed Jacobian multiplied by Jacobian JtByJmod, //Transposed Jacobian multiplied by Jacobian
JtByDiff, JtByDiff,
...@@ -5970,7 +6097,6 @@ List calibration ...@@ -5970,7 +6097,6 @@ List calibration
numPars ); numPars );
final int numFinished=imageFinishedAtomic.getAndIncrement(); final int numFinished=imageFinishedAtomic.getAndIncrement();
// IJ.showProgress(progressValues[numFinished]);
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() {
@Override @Override
public void run() { public void run() {
...@@ -5983,8 +6109,6 @@ List calibration ...@@ -5983,8 +6109,6 @@ List calibration
if (stopRequested.get()==1){ // ASAP if (stopRequested.get()==1){ // ASAP
interruptedAtomic.set(true); interruptedAtomic.set(true);
} }
// if (debugLevel>1) System.out.println("IJ.showProgress("+progressValues[numImage]+")");
// if (debugLevel>1) IJ.showStatus("Progress "+IJ.d2s(100*progressValues[numImage],2)+"%");
} }
} }
}; };
...@@ -6009,10 +6133,31 @@ List calibration ...@@ -6009,10 +6133,31 @@ List calibration
lMAArrays.jTByDiff=JtByDiff; lMAArrays.jTByDiff=JtByDiff;
if (debugLevel>3){ if (debugLevel>3){
String msg="calculateJacobianArrays() lMAArrays.jTByJ trace="; String msg="calculateJacobianArrays() lMAArrays.jTByJ trace=";
for (int ii=0;ii<numPars;ii++) msg+=IJ.d2s(lMAArrays.jTByJ[ii][ii],5); for (int ii=0;ii<numPars;ii++) msg+=IJ.d2s(lMAArrays.jTByJ[ii][ii],5)+" ";
System.out.println(msg); System.out.println(msg);
} }
if (dTA_dUV != null) {
double [][] dUV_average = new double [2][2];
for (int i = 0; i < 2; i++) for (int j=0; j<2; j++) dUV_average[i][j] = 0.0;
double sw = 0.0;
for (int ni = 0; ni < dUV_weights.length; ni++) {
double w = dUV_weights[ni];
if (w > 0.0) {
for (int i = 0; i < 2; i++) for (int j=0; j<2; j++) {
dUV_average[i][j] += w *dUV_image[ni][i][j] ;
}
sw += w;
}
}
if (sw > 0) {
for (int i = 0; i < 2; i++) for (int j=0; j<2; j++) {
dUV_average[i][j] /= sw;
}
Matrix mdTA_dUV = (new Matrix(dUV_average)).inverse();
this.dTA_dUV = mdTA_dUV.getArray();
}
}
return lMAArrays; return lMAArrays;
} }
...@@ -6052,7 +6197,7 @@ List calibration ...@@ -6052,7 +6197,7 @@ List calibration
M.print(10, 5); M.print(10, 5);
} }
Matrix Mb=new Matrix(lMAArrays.jTByDiff,numPars); // single column Matrix Mb=new Matrix(lMAArrays.jTByDiff,numPars); // single column {NaN,NaN}
if (!(new LUDecomposition(M)).isNonsingular()){ if (!(new LUDecomposition(M)).isNonsingular()){
double [][] arr=M.getArray(); double [][] arr=M.getArray();
System.out.println("Singular Matrix "+arr.length+"x"+arr[0].length); System.out.println("Singular Matrix "+arr.length+"x"+arr[0].length);
...@@ -6081,9 +6226,11 @@ List calibration ...@@ -6081,9 +6226,11 @@ List calibration
* @param numSeries * @param numSeries
* @return array of two booleans: { improved, finished} * @return array of two booleans: { improved, finished}
*/ */
public boolean [] stepLevenbergMarquardtFirst(int numSeries){ public boolean [] stepLevenbergMarquardtFirst(
int numSeries,
boolean calc_dUV){
double [] deltas=null; double [] deltas=null;
if (this.currentVector==null) { if ((this.currentVector==null) || (this.currentVector.length==0)) { // length==0 was debugging
int filter=this.filterForAll; int filter=this.filterForAll;
if (this.askFilter) filter=selectFilter(filter); if (this.askFilter) filter=selectFilter(filter);
initFittingSeries(false,filter,numSeries); // first step in series initFittingSeries(false,filter,numSeries); // first step in series
...@@ -6108,11 +6255,12 @@ List calibration ...@@ -6108,11 +6255,12 @@ List calibration
// IJ.showStatus(this.seriesNumber+": "+"Step #"+this.iterationStepNumber+" RMS="+IJ.d2s(this.currentRMS,8)+ " ("+IJ.d2s(this.firstRMS,8)+")"); // IJ.showStatus(this.seriesNumber+": "+"Step #"+this.iterationStepNumber+" RMS="+IJ.d2s(this.currentRMS,8)+ " ("+IJ.d2s(this.firstRMS,8)+")");
IJ.showStatus(this.seriesNumber+": initial Jacobian matrix calculation. Points:"+this.Y.length+" Parameters:"+this.currentVector.length); IJ.showStatus(this.seriesNumber+": initial Jacobian matrix calculation. Points:"+this.Y.length+" Parameters:"+this.currentVector.length);
} }
if (this.debugLevel>1) { if (this.debugLevel >1) {
System.out.println(this.seriesNumber+": initial Jacobian matrix calculation. Points:"+this.Y.length+" Parameters:"+this.currentVector.length); System.out.println(this.seriesNumber+": initial Jacobian matrix calculation. Points:"+this.Y.length+" Parameters:"+this.currentVector.length);
} }
if (this.threadedLMA) { if (this.threadedLMA) {
this.currentfX=new double[this.Y.length]; this.currentfX=new double[this.Y.length];
this.dTA_dUV = calc_dUV ? (new double [2][2]): null;
// deltas=solveLevenbergMarquardtThreaded( // deltas=solveLevenbergMarquardtThreaded(
this.lMAArrays=calculateJacobianArrays( this.lMAArrays=calculateJacobianArrays(
this.fittingStrategy.selectedImages(), // selected images to process this.fittingStrategy.selectedImages(), // selected images to process
...@@ -6123,6 +6271,7 @@ List calibration ...@@ -6123,6 +6271,7 @@ List calibration
this.targetXYZ, // this.targetXYZ this.targetXYZ, // this.targetXYZ
this.weightFunction, // may be null - make it twice smaller? - same for X and Y? this.weightFunction, // may be null - make it twice smaller? - same for X and Y?
this.lensDistortionParameters, this.lensDistortionParameters,
this.dTA_dUV,// final double [][][] dUV_average, // null or double [selectedImages.length][][] to return per-image {{dU/dAz,dU/dTl}{dV/dAz,dV/dTl}}
// this.lambda, // this.lambda,
this.threadsMax, this.threadsMax,
this.updateStatus); this.updateStatus);
...@@ -6135,7 +6284,7 @@ List calibration ...@@ -6135,7 +6284,7 @@ List calibration
// deltas=solveLevenbergMarquardt(this.currentfX,this.lambda); // deltas=solveLevenbergMarquardt(this.currentfX,this.lambda);
} }
// add termes that push selected extrinsic parameters towards average (global, per station, per tilt-station) // add termes that push selected extrinsic parameters towards average (global, per station, per tilt-station)
this.currentRMSPure= calcErrorDiffY(this.currentfX); this.currentRMSPure= calcErrorDiffY(this.currentfX) +0.0;
if ((this.fittingStrategy.varianceModes!=null) && (this.fittingStrategy.varianceModes[numSeries]!=this.fittingStrategy.varianceModeDisabled)) { if ((this.fittingStrategy.varianceModes!=null) && (this.fittingStrategy.varianceModes[numSeries]!=this.fittingStrategy.varianceModeDisabled)) {
this.fittingStrategy.addVarianceToLMA( this.fittingStrategy.addVarianceToLMA(
numSeries, numSeries,
...@@ -6238,6 +6387,7 @@ List calibration ...@@ -6238,6 +6387,7 @@ List calibration
this.targetXYZ, // this.targetXYZ this.targetXYZ, // this.targetXYZ
this.weightFunction, // may be null - make it twice smaller? - same for X and Y? this.weightFunction, // may be null - make it twice smaller? - same for X and Y?
this.lensDistortionParameters, this.lensDistortionParameters,
this.dTA_dUV,// final double [][][] dUV_average, // null or double [selectedImages.length][][] to return per-image {{dU/dAz,dU/dTl}{dV/dAz,dV/dTl}}
// this.lambda, // this.lambda,
this.threadsMax, this.threadsMax,
this.updateStatus); this.updateStatus);
...@@ -6719,7 +6869,7 @@ List calibration ...@@ -6719,7 +6869,7 @@ List calibration
/// this.pixelCorrectionHeight=height; /// this.pixelCorrectionHeight=height;
// } // }
if (this.pixelCorrection==null) { if (this.pixelCorrection==null) {
if (this.debugLevel>1) System.out.println("Initializing pixelCorrection array"); if (this.debugLevel>1) System.out.println("Initializing pixelCorrection array...");
this.pixelCorrection=new double [sensorXYCorr.length][][]; this.pixelCorrection=new double [sensorXYCorr.length][][];
this.pathNames=new String[sensorXYCorr.length]; this.pathNames=new String[sensorXYCorr.length];
for (int i=0;i<this.pixelCorrection.length;i++){ for (int i=0;i<this.pixelCorrection.length;i++){
...@@ -6775,8 +6925,15 @@ List calibration ...@@ -6775,8 +6925,15 @@ List calibration
this.pixelCorrection[i][5]=sensorXYCorr[i][indxB]; this.pixelCorrection[i][5]=sensorXYCorr[i][indxB];
} else { } else {
for (int n=3;n<numLayers;n++){ for (int n=3;n<numLayers;n++){
this.pixelCorrection[i][n]=new double[this.pixelCorrection[0].length]; // this.pixelCorrection[i][n]=new double[this.pixelCorrection[0].length];
for (int j=0;j<this.pixelCorrection[i][0].length;j++) this.pixelCorrection[i][n][j]=1.0; this.pixelCorrection[i][n]=new double[this.pixelCorrection[i][0].length]; // number of pixels
for (int j=0;j<this.pixelCorrection[i][0].length;j++) {
if ((i >= pixelCorrection.length) || (n >= pixelCorrection[i].length) || (j >= pixelCorrection[i][n].length)){
System.out.println("i="+i+", n="+n+", j="+j);
continue;
}
this.pixelCorrection[i][n][j]=1.0; // java.lang.ArrayIndexOutOfBoundsException: Index 6 out of bounds for length 6
}
} }
} }
...@@ -6910,7 +7067,15 @@ List calibration ...@@ -6910,7 +7067,15 @@ List calibration
float [][]pixels=new float [titles.length][length]; // dx, dy, sensor mask,v-r,v-g,v-b float [][]pixels=new float [titles.length][length]; // dx, dy, sensor mask,v-r,v-g,v-b
// assuming all sensors have the same dimension // assuming all sensors have the same dimension
double [] mask=null; double [] mask=null;
if (distortionCalibrationData.sensorMasks.length<=numSensor) return null; // no data if (distortionCalibrationData.sensorMasks == null) {
if (this.debugLevel>0) {
System.out.println("sensorMasks are null, calculating");
}
distortionCalibrationData.calculateSensorMasks();
}
if (distortionCalibrationData.sensorMasks.length<=numSensor) return null; // no data (make if distortionCalibrationData.sensorMasks==null
if ((distortionCalibrationData.sensorMasks!=null) && if ((distortionCalibrationData.sensorMasks!=null) &&
(distortionCalibrationData.sensorMasks[numSensor]!=null)){ (distortionCalibrationData.sensorMasks[numSensor]!=null)){
mask=distortionCalibrationData.sensorMasks[numSensor]; mask=distortionCalibrationData.sensorMasks[numSensor];
...@@ -6924,7 +7089,15 @@ List calibration ...@@ -6924,7 +7089,15 @@ List calibration
} else { } else {
pixels[0][index]= (float) pixelCorr[0][index]; pixels[0][index]= (float) pixelCorr[0][index];
pixels[1][index]= (float) pixelCorr[1][index]; pixels[1][index]= (float) pixelCorr[1][index];
for (int n=3;n<pixels.length;n++) pixels[n][index]= (float) pixelCorr[n][index]; for (int n=3;n<pixels.length;n++) {
if (pixelCorr[n] != null) {
if ((n>=pixels.length) || (index >= pixels[n].length) || (n>=pixelCorr.length) || (index >= pixelCorr[n].length)) {
System.out.println (" Bug: n="+n+", index="+index);
continue;
}
pixels[n][index]= (float) pixelCorr[n][index]; // java.lang.NullPointerException
}
}
} }
// get sensor mask here // get sensor mask here
pixels[2][index]= (mask==null)? 1.0f:((float) mask[index]); pixels[2][index]= (mask==null)? 1.0f:((float) mask[index]);
...@@ -8273,11 +8446,20 @@ List calibration ...@@ -8273,11 +8446,20 @@ List calibration
return true; return true;
} }
public boolean LevenbergMarquardt( public boolean LevenbergMarquardt(
boolean openDialog, boolean openDialog,
boolean dry_run){ // do not save results boolean dry_run){ // do not save results
return LevenbergMarquardt(
openDialog,
dry_run,
false);
}
public boolean LevenbergMarquardt(
boolean openDialog,
boolean dry_run, // do not save results
boolean calc_dUV){
if (this.fittingStrategy==null) { if (this.fittingStrategy==null) {
String msg="Fitting strategy does not exist, exiting"; String msg="Fitting strategy does not exist, exiting";
IJ.showMessage("Error",msg); IJ.showMessage("Error",msg);
...@@ -8294,7 +8476,7 @@ List calibration ...@@ -8294,7 +8476,7 @@ List calibration
boolean wasLastSeries=false; boolean wasLastSeries=false;
while (true) { // loop for the same series while (true) { // loop for the same series
boolean [] state=stepLevenbergMarquardtFirst(this.seriesNumber); boolean [] state=stepLevenbergMarquardtFirst(this.seriesNumber, calc_dUV);
if (!this.fittingStrategy.isSeriesValid(this.seriesNumber)){ if (!this.fittingStrategy.isSeriesValid(this.seriesNumber)){
System.out.println("Series "+this.seriesNumber+" is invalid when weight function filters are applied (probably removed some images)"); System.out.println("Series "+this.seriesNumber+" is invalid when weight function filters are applied (probably removed some images)");
return false; return false;
......
...@@ -1248,10 +1248,16 @@ public class EyesisAberrations { ...@@ -1248,10 +1248,16 @@ public class EyesisAberrations {
if (debugLevel>0) System.out.println("Processing file #"+(imgNum+1)+ " ( of "+files.length+") :"+files[imgNum][0]); if (debugLevel>0) System.out.println("Processing file #"+(imgNum+1)+ " ( of "+files.length+") :"+files[imgNum][0]);
ImagePlus imp=new ImagePlus(files[imgNum][0]); // read source file ImagePlus imp=new ImagePlus(files[imgNum][0]); // read source file
JP4_INSTANCE.decodeProperiesFromInfo(imp); JP4_INSTANCE.decodeProperiesFromInfo(imp);
boolean is_lwir = lwirReaderParameters.is_LWIR(imp); // boolean is_lwir = lwirReaderParameters.is_LWIR(imp);
int fft_size = is_lwir ? distortionParameters.FFTSize_lwir : distortionParameters.FFTSize; int sensor_type = LwirReaderParameters.sensorType(imp);
int fft_overlap = is_lwir ? distortionParameters.FFTOverlap_lwir : distortionParameters.FFTOverlap; // int fft_size = is_lwir ? distortionParameters.FFTSize_lwir : distortionParameters.FFTSize;
imp.setProperty("MONOCHROME",""+is_lwir); // int fft_overlap = is_lwir ? distortionParameters.FFTOverlap_lwir : distortionParameters.FFTOverlap;
int fft_size = distortionParameters.getFFTSize(sensor_type);
int fft_overlap = distortionParameters.getFFTOverlap(sensor_type);
imp.setProperty("MONOCHROME",""+(sensor_type == 1));
// pad image to full sensor size // pad image to full sensor size
int numGridImage=fileIndices[imgNum]; int numGridImage=fileIndices[imgNum];
int chn = distortions.fittingStrategy.distortionCalibrationData.gIP[numGridImage].getChannel(); int chn = distortions.fittingStrategy.distortionCalibrationData.gIP[numGridImage].getChannel();
...@@ -1261,7 +1267,8 @@ public class EyesisAberrations { ...@@ -1261,7 +1267,8 @@ public class EyesisAberrations {
sensor_width_height, // eyesisCorrections.pixelMapping.sensors[srcChannel].getSensorWH(), sensor_width_height, // eyesisCorrections.pixelMapping.sensors[srcChannel].getSensorWH(),
true); // boolean replicate); true); // boolean replicate);
// TODO: Add vignetting correction ? // TODO: Add vignetting correction ?
MatchSimulatedPattern matchSimulatedPattern= new MatchSimulatedPattern(distortionParameters.FFTSize); // MatchSimulatedPattern matchSimulatedPattern= new MatchSimulatedPattern(distortionParameters.FFTSize);
MatchSimulatedPattern matchSimulatedPattern= new MatchSimulatedPattern(distortionParameters.getFFTSize(sensor_type));
boolean [] correlationSizesUsed=null; boolean [] correlationSizesUsed=null;
float [][] simArray= null; float [][] simArray= null;
...@@ -1348,7 +1355,7 @@ public class EyesisAberrations { ...@@ -1348,7 +1355,7 @@ public class EyesisAberrations {
fft_size, // FFT_SIZE, // int fft_size, fft_size, // FFT_SIZE, // int fft_size,
colorComponents, //COMPONENTS, // ColorComponents colorComponents, colorComponents, //COMPONENTS, // ColorComponents colorComponents,
PSF_subpixel, //PSF_SUBPIXEL, // int PSF_subpixel, PSF_subpixel, //PSF_SUBPIXEL, // int PSF_subpixel,
(is_lwir?otfFilterParameters_lwir:otfFilterParameters), ((sensor_type == 1) ?otfFilterParameters_lwir:otfFilterParameters),
// otfFilterParameters, // OTF_FILTER, // OTFFilterParameters otfFilterParameters, // otfFilterParameters, // OTF_FILTER, // OTFFilterParameters otfFilterParameters,
psfParameters, //PSF_PARS, // final PSFParameters psfParameters psfParameters, //PSF_PARS, // final PSFParameters psfParameters
psfParameters.minDefinedArea , //PSF_PARS.minDefinedArea, // final double minDefinedArea, psfParameters.minDefinedArea , //PSF_PARS.minDefinedArea, // final double minDefinedArea,
......
...@@ -632,6 +632,9 @@ horizontal axis: ...@@ -632,6 +632,9 @@ horizontal axis:
int nImg=indices[index]; int nImg=indices[index];
int subCam= distortionCalibrationData.getImageChannel(images[nImg]); int subCam= distortionCalibrationData.getImageChannel(images[nImg]);
int sensor_type = eyesisCameraParameters.getSensorType(subCam);
// int stationNumber= distortionCalibrationData.getImageStation(numGridImage), // station number // int stationNumber= distortionCalibrationData.getImageStation(numGridImage), // station number
double timeStamp= distortionCalibrationData.getImageTimestamp(images[nImg]); double timeStamp= distortionCalibrationData.getImageTimestamp(images[nImg]);
...@@ -673,7 +676,9 @@ horizontal axis: ...@@ -673,7 +676,9 @@ horizontal axis:
if (this.debugLevel>1) lensDistortions.showHintGrid(hintGrid); if (this.debugLevel>1) lensDistortions.showHintGrid(hintGrid);
MatchSimulatedPattern matchSimulatedPattern = new MatchSimulatedPattern(this.distortionParametersDefault.FFTSize); // new instance, all reset /// MatchSimulatedPattern matchSimulatedPattern = new MatchSimulatedPattern(this.distortionParametersDefault.FFTSize); // new instance, all reset
MatchSimulatedPattern matchSimulatedPattern = new MatchSimulatedPattern(distortionParametersDefault.getFFTSize(sensor_type)); // new instance, all reset
//sensort_type
// next 2 lines are not needed for the new instance, but can be // next 2 lines are not needed for the new instance, but can be
// used alternatively if keeping it // used alternatively if keeping it
matchSimulatedPattern.invalidateFlatFieldForGrid(); // Reset Flat Filed calibration - different image. matchSimulatedPattern.invalidateFlatFieldForGrid(); // Reset Flat Filed calibration - different image.
...@@ -690,7 +695,7 @@ horizontal axis: ...@@ -690,7 +695,7 @@ horizontal axis:
", initial number of pointers was "+numPointers); ", initial number of pointers was "+numPointers);
} }
//matchSimulatedPatterns[numSensor].getChannel(images[numSensor])+" "); //matchSimulatedPatterns[numSensor].getChannel(images[numSensor])+" ");
MatchSimulatedPattern.DistortionParameters distortionParameters = modifyDistortionParameters(); MatchSimulatedPattern.DistortionParameters distortionParameters = modifyDistortionParameters(sensor_type);
SimulationPattern.SimulParameters simulParameters = modifySimulParameters(); SimulationPattern.SimulParameters simulParameters = modifySimulParameters();
boolean noMessageBoxes=true; boolean noMessageBoxes=true;
...@@ -729,34 +734,13 @@ horizontal axis: ...@@ -729,34 +734,13 @@ horizontal axis:
} }
/* public MatchSimulatedPattern.DistortionParameters modifyDistortionParameters(int sensor_type){
* private showDoubleFloatArrays SDFA_INSTANCE= new showDoubleFloatArrays(); // just for debugging?
this.SDFA_INSTANCE.showArrays(gridXYZCorr, getGridWidth(), getGridHeight(), true, "Grid corrections", titles);
*
gd.addChoice( // ArrayIndexOutOfBoundsException: 21
this.distortionCalibrationData.getParameterName(parIndex)+
" ("+sValue+" "+
this.distortionCalibrationData.getParameterUnits(parIndex)+")"+
(this.distortionCalibrationData.isSubcameraParameter(parIndex)?(" s"+subCam):"com "),
this.definedModes, this.definedModes[this.parameterMode[numSeries][i]]);
*
* this.parameterMode[numSeries][i]=gd.getNextChoiceIndex();
PatternParameters patternParameters, // should not be null
boolean equalizeGreens,
int threadsMax,
boolean updateStatus,
int debug_level) {// debug level used inside loops
*
*
*/
public MatchSimulatedPattern.DistortionParameters modifyDistortionParameters(){
MatchSimulatedPattern.DistortionParameters distortionParameters = this.distortionParametersDefault.clone(); MatchSimulatedPattern.DistortionParameters distortionParameters = this.distortionParametersDefault.clone();
distortionParameters.refineInPlace = false; distortionParameters.refineInPlace = false;
distortionParameters.correlationMaxOffset = this.goniometerParameters.maxCorr; distortionParameters.correlationMaxOffset = this.goniometerParameters.maxCorr;
distortionParameters.correlationSize = this.goniometerParameters.correlationSize; // distortionParameters.correlationSize = this.goniometerParameters.correlationSize;
distortionParameters.setCorrelationSize(this.goniometerParameters.correlationSize, sensor_type);
distortionParameters.correlationGaussWidth = this.goniometerParameters.correlationGaussWidth; distortionParameters.correlationGaussWidth = this.goniometerParameters.correlationGaussWidth;
distortionParameters.refineCorrelations = false; distortionParameters.refineCorrelations = false;
distortionParameters.fastCorrelationOnFirstPass = true; distortionParameters.fastCorrelationOnFirstPass = true;
...@@ -767,7 +751,8 @@ horizontal axis: ...@@ -767,7 +751,8 @@ horizontal axis:
distortionParameters.flatFieldExpand = this.goniometerParameters.flatFieldExpand; distortionParameters.flatFieldExpand = this.goniometerParameters.flatFieldExpand;
distortionParameters.numberExtrapolated = 1; // measuring distortions - distortionParameters.numberExtrapolated = 1; // measuring distortions -
distortionParameters.correlationMinInitialContrast=this.goniometerParameters.correlationMinInitialContrast; distortionParameters.correlationMinInitialContrast=this.goniometerParameters.correlationMinInitialContrast;
distortionParameters.minimalPatternCluster=this.goniometerParameters.minimalPatternCluster; // distortionParameters.minimalPatternCluster=this.goniometerParameters.minimalPatternCluster;
distortionParameters.setMinimalPatternCluster(this.goniometerParameters.minimalPatternCluster, sensor_type);
distortionParameters.scaleMinimalInitialContrast=this.goniometerParameters.scaleMinimalInitialContrast; distortionParameters.scaleMinimalInitialContrast=this.goniometerParameters.scaleMinimalInitialContrast;
distortionParameters.searchOverlap=this.goniometerParameters.searchOverlap; distortionParameters.searchOverlap=this.goniometerParameters.searchOverlap;
return distortionParameters; return distortionParameters;
...@@ -781,7 +766,7 @@ horizontal axis: ...@@ -781,7 +766,7 @@ horizontal axis:
return simulParameters; return simulParameters;
} }
public double[] estimateOrientation( public double[] estimateOrientation( // FIXME: Does not use LWIR parameters, assumes EO!
ImagePlus[] images, // last acquire images with number of pointers ImagePlus[] images, // last acquire images with number of pointers
// detected>0 // detected>0
DistortionCalibrationData distortionCalibrationData, DistortionCalibrationData distortionCalibrationData,
...@@ -792,6 +777,7 @@ horizontal axis: ...@@ -792,6 +777,7 @@ horizontal axis:
int threadsMax, int threadsMax,
boolean updateStatus, boolean updateStatus,
int debug_level) {// debug level used inside loops int debug_level) {// debug level used inside loops
int sensor_type = 0; // EO
long startTime = System.nanoTime(); long startTime = System.nanoTime();
if (lensDistortions == null) { if (lensDistortions == null) {
String msg = "lensDistortions is not initialized"; String msg = "lensDistortions is not initialized";
...@@ -801,7 +787,7 @@ horizontal axis: ...@@ -801,7 +787,7 @@ horizontal axis:
// remove unneeded, copied from updateFocusGrid() Now it is not needed? // remove unneeded, copied from updateFocusGrid() Now it is not needed?
SimulationPattern.SimulParameters simulParameters = modifySimulParameters(); SimulationPattern.SimulParameters simulParameters = modifySimulParameters();
MatchSimulatedPattern.DistortionParameters distortionParameters = modifyDistortionParameters(); MatchSimulatedPattern.DistortionParameters distortionParameters = modifyDistortionParameters(sensor_type);
int numImages = 0; int numImages = 0;
for (int i = 0; i < images.length; i++) for (int i = 0; i < images.length; i++)
...@@ -834,8 +820,8 @@ horizontal axis: ...@@ -834,8 +820,8 @@ horizontal axis:
for (int numSensor = 0; numSensor < images.length; numSensor++) for (int numSensor = 0; numSensor < images.length; numSensor++)
if (images[numSensor] != null) { if (images[numSensor] != null) {
// reset matchSimulatedPattern, so it will start from scratch // reset matchSimulatedPattern, so it will start from scratch
this.matchSimulatedPatterns[numSensor] = new MatchSimulatedPattern( // this.matchSimulatedPatterns[numSensor] = new MatchSimulatedPattern( this.distortionParametersDefault.FFTSize); // new instance, all reset
this.distortionParametersDefault.FFTSize); // new instance, all reset this.matchSimulatedPatterns[numSensor] = new MatchSimulatedPattern(distortionParametersDefault.getFFTSize(sensor_type)); // new instance, all reset
// next 2 lines are not needed for the new instance, but can be // next 2 lines are not needed for the new instance, but can be
// used alternatively if keeping it // used alternatively if keeping it
this.matchSimulatedPatterns[numSensor].invalidateFlatFieldForGrid(); // Reset Flat Filed calibration - different image. this.matchSimulatedPatterns[numSensor].invalidateFlatFieldForGrid(); // Reset Flat Filed calibration - different image.
......
...@@ -63,8 +63,9 @@ public class LensAdjustment { ...@@ -63,8 +63,9 @@ public class LensAdjustment {
distortionParameters.refineInPlace=false; distortionParameters.refineInPlace=false;
distortionParameters.correlationMaxOffset=focusMeasurementParameters.maxCorr; distortionParameters.correlationMaxOffset=focusMeasurementParameters.maxCorr;
int sensor_type = 0; // EO
distortionParameters.correlationSize=focusMeasurementParameters.correlationSize; // distortionParameters.correlationSize=focusMeasurementParameters.correlationSize;
distortionParameters.setCorrelationSize(focusMeasurementParameters.correlationSize,sensor_type);
distortionParameters.correlationGaussWidth=focusMeasurementParameters.correlationGaussWidth; distortionParameters.correlationGaussWidth=focusMeasurementParameters.correlationGaussWidth;
distortionParameters.refineCorrelations=false; distortionParameters.refineCorrelations=false;
distortionParameters.fastCorrelationOnFirstPass=true; distortionParameters.fastCorrelationOnFirstPass=true;
......
...@@ -43,6 +43,7 @@ import com.elphel.imagej.common.DoubleFHT; ...@@ -43,6 +43,7 @@ import com.elphel.imagej.common.DoubleFHT;
import com.elphel.imagej.common.DoubleGaussianBlur; import com.elphel.imagej.common.DoubleGaussianBlur;
import com.elphel.imagej.common.PolynomialApproximation; import com.elphel.imagej.common.PolynomialApproximation;
import com.elphel.imagej.common.ShowDoubleFloatArrays; import com.elphel.imagej.common.ShowDoubleFloatArrays;
import com.elphel.imagej.common.WindowTools;
import com.elphel.imagej.jp4.JP46_Reader_camera; import com.elphel.imagej.jp4.JP46_Reader_camera;
import com.elphel.imagej.lwir.LwirReaderParameters; import com.elphel.imagej.lwir.LwirReaderParameters;
...@@ -51,6 +52,7 @@ import Jama.Matrix; // Download here: http://math.nist.gov/javanumerics/jama/ ...@@ -51,6 +52,7 @@ import Jama.Matrix; // Download here: http://math.nist.gov/javanumerics/jama/
import ij.IJ; import ij.IJ;
import ij.ImagePlus; import ij.ImagePlus;
import ij.ImageStack; import ij.ImageStack;
import ij.gui.GenericDialog;
import ij.gui.PointRoi; import ij.gui.PointRoi;
import ij.gui.Roi; import ij.gui.Roi;
import ij.process.FHT; // get rid, change to double import ij.process.FHT; // get rid, change to double
...@@ -100,6 +102,10 @@ public class MatchSimulatedPattern { ...@@ -100,6 +102,10 @@ public class MatchSimulatedPattern {
public MatchSimulatedPattern() { public MatchSimulatedPattern() {
} }
// public MatchSimulatedPattern(int fft_size) {
// this.FFT_SIZE = fft_size;
// }
public MatchSimulatedPattern(int fft_size) { public MatchSimulatedPattern(int fft_size) {
this.FFT_SIZE = fft_size; this.FFT_SIZE = fft_size;
} }
...@@ -3409,16 +3415,19 @@ public class MatchSimulatedPattern { ...@@ -3409,16 +3415,19 @@ public class MatchSimulatedPattern {
/* /*
* ============================= Distortions =================================== * ============================= Distortions ===================================
*/ */
public void distortionsTest(final DistortionParameters distortionParameters, // public void distortionsTest(
final DistortionParameters distortionParameters, //
final MatchSimulatedPattern.PatternDetectParameters patternDetectParameters, final MatchSimulatedPattern.PatternDetectParameters patternDetectParameters,
final SimulationPattern.SimulParameters simulParameters, final boolean equalizeGreens, final ImagePlus imp, // image final SimulationPattern.SimulParameters simulParameters,
// to final boolean equalizeGreens,
// process final ImagePlus imp, // image to process
final int threadsMax, final boolean updateStatus, final int debug_level) {// debug level used inside loops final int threadsMax,
final boolean updateStatus,
final int debug_level) {// debug level used inside loops
if (imp == null) if (imp == null)
return; return;
final int sensor_type = LwirReaderParameters.sensorType(imp);
Roi roi = imp.getRoi(); Roi roi = imp.getRoi();
final Rectangle selection; final Rectangle selection;
if (roi == null) { if (roi == null) {
...@@ -3427,10 +3436,10 @@ public class MatchSimulatedPattern { ...@@ -3427,10 +3436,10 @@ public class MatchSimulatedPattern {
selection = (roi instanceof PointRoi) ? (new Rectangle(0, 0, imp.getWidth(), imp.getHeight())) selection = (roi instanceof PointRoi) ? (new Rectangle(0, 0, imp.getWidth(), imp.getHeight()))
: roi.getBounds(); : roi.getBounds();
} }
MatchSimulatedPattern matchSimulatedPattern = new MatchSimulatedPattern(distortionParameters.FFTSize); MatchSimulatedPattern matchSimulatedPattern = new MatchSimulatedPattern(distortionParameters.getFFTSize(sensor_type));
matchSimulatedPattern.debugLevel = debugLevel; matchSimulatedPattern.debugLevel = debugLevel;
MatchSimulatedPattern matchSimulatedPatternCorr = new MatchSimulatedPattern( MatchSimulatedPattern matchSimulatedPatternCorr = new MatchSimulatedPattern(
distortionParameters.correlationSize); distortionParameters.getCorrelationSize(sensor_type));
matchSimulatedPatternCorr.debugLevel = debugLevel; matchSimulatedPatternCorr.debugLevel = debugLevel;
final SimulationPattern.SimulParameters thisSimulParameters = simulParameters.clone(); final SimulationPattern.SimulParameters thisSimulParameters = simulParameters.clone();
thisSimulParameters.subdiv = distortionParameters.patternSubdiv; thisSimulParameters.subdiv = distortionParameters.patternSubdiv;
...@@ -3452,12 +3461,12 @@ public class MatchSimulatedPattern { ...@@ -3452,12 +3461,12 @@ public class MatchSimulatedPattern {
if (debugLevel > 2) if (debugLevel > 2)
SDFA_INSTANCE.showArrays(input_bayer, true, "selection-bayer-distortionsTest"); SDFA_INSTANCE.showArrays(input_bayer, true, "selection-bayer-distortionsTest");
double[] windowFunction = initWindowFunction(distortionParameters.FFTSize, distortionParameters.fftGaussWidth); double[] windowFunction = initWindowFunction(distortionParameters.FFTSize, distortionParameters.fftGaussWidth);
final double[] windowFunctionCorr = initWindowFunction(distortionParameters.correlationSize, final double[] windowFunctionCorr = initWindowFunction(distortionParameters.getCorrelationSize(sensor_type),
distortionParameters.correlationGaussWidth, distortionParameters.zeros); distortionParameters.correlationGaussWidth, distortionParameters.zeros);
double[] greens = normalizeAndWindow(input_bayer[4], windowFunction); double[] greens = normalizeAndWindow(input_bayer[4], windowFunction);
double[][] pattern = matchSimulatedPattern.findPattern(null, // DoubleFHT doubleFHT, double[][] pattern = matchSimulatedPattern.findPattern(null, // DoubleFHT doubleFHT,
greens, distortionParameters.FFTSize, patternDetectParameters, greens, distortionParameters.getFFTSize(sensor_type), patternDetectParameters,
patternDetectParameters.minGridPeriod / 2, patternDetectParameters.maxGridPeriod / 2, true, // this is a patternDetectParameters.minGridPeriod / 2, patternDetectParameters.maxGridPeriod / 2, true, // this is a
// pattern // pattern
// for // for
...@@ -3906,14 +3915,22 @@ public class MatchSimulatedPattern { ...@@ -3906,14 +3915,22 @@ public class MatchSimulatedPattern {
if (imp == null) if (imp == null)
return 0; return 0;
final int debugThreshold = 1; final int debugThreshold = 1;
final boolean is_lwir = ((lwirReaderParameters != null) && lwirReaderParameters.is_LWIR(imp)); // final boolean is_lwir = ((lwirReaderParameters != null) && lwirReaderParameters.is_LWIR(imp));
final int fft_size = is_lwir ? distortionParameters.FFTSize_lwir : distortionParameters.FFTSize; // final int fft_size = is_lwir ? distortionParameters.FFTSize_lwir : distortionParameters.FFTSize;
final int correlation_size = is_lwir ? distortionParameters.correlationSizeLwir // final int correlation_size = is_lwir ? distortionParameters.correlationSizeLwir
: distortionParameters.correlationSize; // : distortionParameters.correlationSize;
final int max_correlation_size = is_lwir ? distortionParameters.maximalCorrelationSizeLwir // final int max_correlation_size = is_lwir ? distortionParameters.maximalCorrelationSizeLwir
: distortionParameters.maximalCorrelationSize; // : distortionParameters.maximalCorrelationSize;
final int minimal_pattern_cluster = is_lwir ? distortionParameters.minimalPatternClusterLwir // final int minimal_pattern_cluster = is_lwir ? distortionParameters.minimalPatternClusterLwir
: distortionParameters.minimalPatternCluster; // : distortionParameters.minimalPatternCluster;
final int sensor_type = LwirReaderParameters.sensorType(imp);
final int fft_size = distortionParameters.getFFTSize(sensor_type);
final int correlation_size = distortionParameters.getCorrelationSize(sensor_type);
// final int max_correlation_size = distortionParameters.getMaximalCorrelationSize(sensor_type);
final int minimal_pattern_cluster = distortionParameters.getMinimalPatternCluster(sensor_type);
final int[][] directionsUV = { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } }; // should have opposite direction final int[][] directionsUV = { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } }; // should have opposite direction
// shifted by half // shifted by half
final int[][] directionsUV8 = { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 }, { 1, 1 }, { -1, 1 }, { -1, -1 }, final int[][] directionsUV8 = { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 }, { 1, 1 }, { -1, 1 }, { -1, -1 },
...@@ -4329,8 +4346,8 @@ public class MatchSimulatedPattern { ...@@ -4329,8 +4346,8 @@ public class MatchSimulatedPattern {
@Override @Override
public void run() { public void run() {
SimulationPattern simulationPattern = new SimulationPattern(bPattern); SimulationPattern simulationPattern = new SimulationPattern(bPattern);
MatchSimulatedPattern matchSimulatedPatternCorr = new MatchSimulatedPattern( MatchSimulatedPattern matchSimulatedPatternCorr = new MatchSimulatedPattern(correlation_size);
distortionParameters.correlationSize); // distortionParameters.correlationSize);
DoubleFHT fht_instance = new DoubleFHT(); // provide DoubleFHT instance to save on DoubleFHT fht_instance = new DoubleFHT(); // provide DoubleFHT instance to save on
// initializations (or null) // initializations (or null)
String dbgStr = ""; String dbgStr = "";
...@@ -4770,7 +4787,7 @@ public class MatchSimulatedPattern { ...@@ -4770,7 +4787,7 @@ public class MatchSimulatedPattern {
// return numDefinedCells; // return numDefinedCells;
} }
if (roi != null) { // don't use this feature with ROI as it can be small if ((roi != null) && !(roi instanceof PointRoi)) { // don't use this feature with ROI as it can be small
if (global_debug_level > 0) if (global_debug_level > 0)
System.out.println( System.out.println(
"Initial pattern cluster is small (" + numDefinedCells + "), but ROI is set - no retries"); "Initial pattern cluster is small (" + numDefinedCells + "), but ROI is set - no retries");
...@@ -5048,45 +5065,37 @@ public class MatchSimulatedPattern { ...@@ -5048,45 +5065,37 @@ public class MatchSimulatedPattern {
} }
/* ================================================================ */ /* ================================================================ */
public double refineDistortionCorrelation(final LwirReaderParameters lwirReaderParameters, // null is OK public double refineDistortionCorrelation(
final LwirReaderParameters lwirReaderParameters, // null is OK
final DistortionParameters distortionParameters, // final DistortionParameters distortionParameters, //
final MatchSimulatedPattern.PatternDetectParameters patternDetectParameters, final MatchSimulatedPattern.PatternDetectParameters patternDetectParameters,
final SimulationPattern.SimulParameters simulParameters, final boolean equalizeGreens, final ImagePlus imp, // image final SimulationPattern.SimulParameters simulParameters,
// to final boolean equalizeGreens,
// process final ImagePlus imp, // image to process
final double maxCorr, // maximal allowed correction, in pixels (0.0) - any final double maxCorr, // maximal allowed correction, in pixels (0.0) - any
final int threadsMax, final boolean updateStatus, final int debug_level) {// debug level used inside loops final int threadsMax,
final boolean updateStatus,
final int debug_level) {// debug level used inside loops
scaleContrast(distortionParameters.scaleFirstPassContrast); scaleContrast(distortionParameters.scaleFirstPassContrast);
final int sensor_type = LwirReaderParameters.sensorType(imp);
final double[][][][] patternGrid = this.PATTERN_GRID; final double[][][][] patternGrid = this.PATTERN_GRID;
final int debugThreshold = 1; final int debugThreshold = 1;
final Rectangle selection = new Rectangle(0, 0, imp.getWidth(), imp.getHeight()); final Rectangle selection = new Rectangle(0, 0, imp.getWidth(), imp.getHeight());
MatchSimulatedPattern matchSimulatedPatternCorr = new MatchSimulatedPattern( final int correlation_size = distortionParameters.getCorrelationSize(sensor_type);
distortionParameters.correlationSize); MatchSimulatedPattern matchSimulatedPatternCorr = new MatchSimulatedPattern(correlation_size);
// distortionParameters.correlationSize);
matchSimulatedPatternCorr.debugLevel = debugLevel; matchSimulatedPatternCorr.debugLevel = debugLevel;
SimulationPattern simulationPattern = new SimulationPattern(); SimulationPattern simulationPattern = new SimulationPattern();
final SimulationPattern.SimulParameters thisSimulParameters = simulParameters.clone(); final SimulationPattern.SimulParameters thisSimulParameters = simulParameters.clone();
thisSimulParameters.subdiv = distortionParameters.patternSubdiv; thisSimulParameters.subdiv = distortionParameters.patternSubdiv;
final double[] bPattern = simulationPattern.patternGenerator(simulParameters); // reuse pattern for next time final double[] bPattern = simulationPattern.patternGenerator(simulParameters); // reuse pattern for next time
/* final double[] windowFunctionCorr = initWindowFunction(correlation_size, // distortionParameters.correlationSize,
* final double [] windowFunctionCorr= initWindowFunction(
* distortionParameters.correlationSize,distortionParameters.
* correlationGaussWidth); final double []
* windowFunctionCorr2=initWindowFunction(2*distortionParameters.
* correlationSize,
* (distortionParameters.absoluteCorrelationGaussWidth?0.5:1.0)*
* distortionParameters.correlationGaussWidth); final double []
* windowFunctionCorr4=initWindowFunction(4*distortionParameters.
* correlationSize,
* (distortionParameters.absoluteCorrelationGaussWidth?0.25:1.0)*
* distortionParameters.correlationGaussWidth);
*/
final double[] windowFunctionCorr = initWindowFunction(distortionParameters.correlationSize,
distortionParameters.correlationGaussWidth, distortionParameters.zeros); distortionParameters.correlationGaussWidth, distortionParameters.zeros);
final double[] windowFunctionCorr2 = initWindowFunction(2 * distortionParameters.correlationSize, final double[] windowFunctionCorr2 = initWindowFunction(2 * correlation_size, // distortionParameters.correlationSize,
(distortionParameters.absoluteCorrelationGaussWidth ? 0.5 : 1.0) (distortionParameters.absoluteCorrelationGaussWidth ? 0.5 : 1.0)
* distortionParameters.correlationGaussWidth, * distortionParameters.correlationGaussWidth,
distortionParameters.zeros); distortionParameters.zeros);
final double[] windowFunctionCorr4 = initWindowFunction(4 * distortionParameters.correlationSize, final double[] windowFunctionCorr4 = initWindowFunction(4 * correlation_size, // distortionParameters.correlationSize,
(distortionParameters.absoluteCorrelationGaussWidth ? 0.25 : 1.0) (distortionParameters.absoluteCorrelationGaussWidth ? 0.25 : 1.0)
* distortionParameters.correlationGaussWidth, * distortionParameters.correlationGaussWidth,
distortionParameters.zeros); distortionParameters.zeros);
...@@ -5161,8 +5170,7 @@ public class MatchSimulatedPattern { ...@@ -5161,8 +5170,7 @@ public class MatchSimulatedPattern {
@Override @Override
public void run() { public void run() {
SimulationPattern simulationPattern = new SimulationPattern(bPattern); SimulationPattern simulationPattern = new SimulationPattern(bPattern);
MatchSimulatedPattern matchSimulatedPatternCorr = new MatchSimulatedPattern( MatchSimulatedPattern matchSimulatedPatternCorr = new MatchSimulatedPattern(correlation_size); // distortionParameters.correlationSize);
distortionParameters.correlationSize);
DoubleFHT fht_instance = new DoubleFHT(); // provide DoubleFHT instance to save on initializations DoubleFHT fht_instance = new DoubleFHT(); // provide DoubleFHT instance to save on initializations
// (or null) // (or null)
int[] iUV = new int[2]; int[] iUV = new int[2];
...@@ -5190,7 +5198,7 @@ public class MatchSimulatedPattern { ...@@ -5190,7 +5198,7 @@ public class MatchSimulatedPattern {
// of the // of the
// pattern cross // pattern cross
// point // point
distortionParameters.correlationSize); correlation_size/2); // distortionParameters.correlationSize);
if (!selection.contains(centerCross)) { if (!selection.contains(centerCross)) {
cellNumDoneAtomic.getAndIncrement(); cellNumDoneAtomic.getAndIncrement();
continue; // the correlation selection does not fit into WOI selection ??? WOI is now full continue; // the correlation selection does not fit into WOI selection ??? WOI is now full
...@@ -5275,23 +5283,24 @@ public class MatchSimulatedPattern { ...@@ -5275,23 +5283,24 @@ public class MatchSimulatedPattern {
} }
} }
double[] centerXY = correctedPatternCrossLocation(lwirReaderParameters, // LwirReaderParameters double[] centerXY = correctedPatternCrossLocation(
// lwirReaderParameters, lwirReaderParameters, // LwirReaderParameters lwirReaderParameters, null is OK
// // null is OK
patternGrid[iUV[1]][iUV[0]][0], // initial coordinates of the pattern cross point patternGrid[iUV[1]][iUV[0]][0], // initial coordinates of the pattern cross point
patternGrid[iUV[1]][iUV[0]][1][0], patternGrid[iUV[1]][iUV[0]][1][1], patternGrid[iUV[1]][iUV[0]][1][0], patternGrid[iUV[1]][iUV[0]][1][1],
patternGrid[iUV[1]][iUV[0]][2][0], patternGrid[iUV[1]][iUV[0]][2][1], simulPars, imp, // image patternGrid[iUV[1]][iUV[0]][2][0], patternGrid[iUV[1]][iUV[0]][2][1], simulPars, imp, // image data (Bayer mosaic)
// data
// (Bayer
// mosaic)
distortionParameters, // distortionParameters, //
patternDetectParameters, matchSimulatedPatternCorr, // correlationSize patternDetectParameters,
thisSimulParameters, equalizeGreens, windowFunctionCorr, windowFunctionCorr2, matchSimulatedPatternCorr, // correlationSize
windowFunctionCorr4, simulationPattern, ((iUV[0] ^ iUV[1]) & 1) != 0, // if true - thisSimulParameters,
// invert equalizeGreens,
// pattern windowFunctionCorr,
fht_instance, distortionParameters.fastCorrelationOnFinalPass, // windowFunctionCorr2,
locsNeib, thisDebug, // thisDebug windowFunctionCorr4,
simulationPattern, ((iUV[0] ^ iUV[1]) & 1) != 0, // if true - invert pattern
fht_instance,
distortionParameters.fastCorrelationOnFinalPass, //
locsNeib,
thisDebug, // thisDebug
null); null);
if (centerXY != null) { if (centerXY != null) {
...@@ -5299,6 +5308,13 @@ public class MatchSimulatedPattern { ...@@ -5299,6 +5308,13 @@ public class MatchSimulatedPattern {
System.out.println("==>iUV={" + iUV[0] + ", " + iUV[1] + "}. " System.out.println("==>iUV={" + iUV[0] + ", " + iUV[1] + "}. "
+ patternGrid[iUV[1]][iUV[0]][0][0] + " / " + patternGrid[iUV[1]][iUV[0]][0][1] + patternGrid[iUV[1]][iUV[0]][0][0] + " / " + patternGrid[iUV[1]][iUV[0]][0][1]
+ " -> " + centerXY[0] + " / " + centerXY[1]); + " -> " + centerXY[0] + " / " + centerXY[1]);
// refine should provide higher contrast than was there, it is so for EO, but not for LWIR
// LWIR refined contrast is approximately the same as that of non-refined, twice less than EO
// boosting it here
if (sensor_type == 1) {
centerXY[2] *= 2.0; // boosting refined LWIR
}
if (refineInPlace) if (refineInPlace)
setPatternGridCell(patternGrid, iUV, centerXY, null, // double [] wv1, setPatternGridCell(patternGrid, iUV, centerXY, null, // double [] wv1,
null); // double [] wv2); null); // double [] wv2);
...@@ -5381,13 +5397,33 @@ public class MatchSimulatedPattern { ...@@ -5381,13 +5397,33 @@ public class MatchSimulatedPattern {
} }
// Copy new values for the grid cells // Copy new values for the grid cells
boolean debug_bias = true;
double lwir_refine_dx = -0.25;
double lwir_refine_dy = -0.25;
double sw = 0.0, swx = 0.0, swy = 0.0; // finding x,y bias of refining
for (iUV[1] = 0; iUV[1] < height; iUV[1]++) for (iUV[1] = 0; iUV[1] < height; iUV[1]++)
for (iUV[0] = 0; iUV[0] < width; iUV[0]++) for (iUV[0] = 0; iUV[0] < width; iUV[0]++)
if (newGrid[iUV[1]][iUV[0]] != null) { if (newGrid[iUV[1]][iUV[0]] != null) {
if (debug_bias) {
double [] center_refined = newGrid[iUV[1]][iUV[0]];
double [] center_orig = patternGrid[iUV[1]][iUV[0]][0];
sw += center_refined[2];
swx += center_refined[2] * (center_refined[0] - center_orig[0]);
swy += center_refined[2] * (center_refined[1] - center_orig[1]);
}
setPatternGridCell(patternGrid, iUV, newGrid[iUV[1]][iUV[0]], null, // double [] wv1, setPatternGridCell(patternGrid, iUV, newGrid[iUV[1]][iUV[0]], null, // double [] wv1,
null); // double [] wv2); null); // double [] wv2);
} else if (sensor_type == 1) { // FIXME: correcting LWIR refine bias
if (isCellDefined(patternGrid, iUV)) {
patternGrid[iUV[1]][iUV[0]][0][0] += lwir_refine_dx;
patternGrid[iUV[1]][iUV[0]][0][1] += lwir_refine_dy;
}
} }
if (debug_bias && (sw > 0.0)) {
swx /= sw;
swy /= sw;
System.out.println("Refine bias dx = "+swx+"pix, dy = "+swy+"pix");
}
// correction is only calculated for simultaneous update (not for in-place) // correction is only calculated for simultaneous update (not for in-place)
if (debug_level > 1) { if (debug_level > 1) {
System.out.println("refineDistortionCorrelation(): maximal correction=" + maxActualCorr + " pixels"); System.out.println("refineDistortionCorrelation(): maximal correction=" + maxActualCorr + " pixels");
...@@ -5449,12 +5485,18 @@ public class MatchSimulatedPattern { ...@@ -5449,12 +5485,18 @@ public class MatchSimulatedPattern {
* average grid period) * average grid period)
* *
*/ */
public ImagePlus equalizeGridIntensity(ImagePlus imp, double[][][][] patternGrid, public ImagePlus equalizeGridIntensity(
ImagePlus imp,
double[][][][] patternGrid,
DistortionParameters distortionParameters, // DistortionParameters distortionParameters, //
boolean equalizeGreens, int debugLevel, boolean updateStatus, int threadsMax) { boolean equalizeGreens,
int debugLevel,
boolean updateStatus,
int threadsMax) {
int dbgThreshold = 1; int dbgThreshold = 1;
final int sensor_type = LwirReaderParameters.sensorType(imp);
double[][] gridIntensity = calcGridIntensity(4, // bayerComponent double[][] gridIntensity = calcGridIntensity(4, // bayerComponent
distortionParameters.correlationSize, // size distortionParameters.getCorrelationSize(sensor_type), // correlationSize, // size
distortionParameters, // distortionParameters, //
equalizeGreens, imp, // image to process equalizeGreens, imp, // image to process
patternGrid, threadsMax);// debug level used inside loops patternGrid, threadsMax);// debug level used inside loops
...@@ -5470,6 +5512,10 @@ public class MatchSimulatedPattern { ...@@ -5470,6 +5512,10 @@ public class MatchSimulatedPattern {
double[] fffg = calcFlatFieldForGrid(gridIntensity, patternGrid, imp.getWidth(), imp.getHeight()); double[] fffg = calcFlatFieldForGrid(gridIntensity, patternGrid, imp.getWidth(), imp.getHeight());
double averageGridPeriod = averageGridPeriod(patternGrid); double averageGridPeriod = averageGridPeriod(patternGrid);
// if (debugLevel > (dbgThreshold + 2)) {
// this.SDFA_INSTANCE.showArrays(fffg, imp.getWidth(), imp.getHeight(),
// imp.getTitle() + "-fftg");
// }
int preShrink = (int) (averageGridPeriod * distortionParameters.flatFieldShrink); int preShrink = (int) (averageGridPeriod * distortionParameters.flatFieldShrink);
int expand = (int) (averageGridPeriod * distortionParameters.flatFieldExpand); int expand = (int) (averageGridPeriod * distortionParameters.flatFieldExpand);
...@@ -5584,16 +5630,21 @@ public class MatchSimulatedPattern { ...@@ -5584,16 +5630,21 @@ public class MatchSimulatedPattern {
return this.gridContrastBrightness; return this.gridContrastBrightness;
} }
public double[][] calcGridIntensity(final int bayerComponent, final int size, public double[][] calcGridIntensity(
final int bayerComponent,
final int size,
final DistortionParameters distortionParameters, // final DistortionParameters distortionParameters, //
final boolean equalizeGreens, final ImagePlus imp, // image to process final boolean equalizeGreens,
final double[][][][] patternGrid, final int threadsMax) {// debug level used inside loops final ImagePlus imp, // image to process
final double[][][][] patternGrid,
final int threadsMax) {// debug level used inside loops
final int sensor_type = LwirReaderParameters.sensorType(imp);
final double[][] gridIntensity = new double[patternGrid.length][patternGrid[0].length]; final double[][] gridIntensity = new double[patternGrid.length][patternGrid[0].length];
for (int i = 0; i < gridIntensity.length; i++) for (int i = 0; i < gridIntensity.length; i++)
for (int j = 0; j < gridIntensity[0].length; j++) for (int j = 0; j < gridIntensity[0].length; j++)
gridIntensity[i][j] = (bayerComponent >= 0) ? -1.0 : 0.0; // undefined gridIntensity[i][j] = (bayerComponent >= 0) ? -1.0 : 0.0; // undefined
MatchSimulatedPattern matchSimulatedPatternCorr = new MatchSimulatedPattern( MatchSimulatedPattern matchSimulatedPatternCorr = new MatchSimulatedPattern(
distortionParameters.correlationSize); distortionParameters.getCorrelationSize(sensor_type)); // correlationSize);
matchSimulatedPatternCorr.debugLevel = debugLevel; matchSimulatedPatternCorr.debugLevel = debugLevel;
final double[] windowFunctionCorr = initWindowFunction(size, // distortionParameters.correlationSize, final double[] windowFunctionCorr = initWindowFunction(size, // distortionParameters.correlationSize,
distortionParameters.correlationGaussWidth, distortionParameters.zeros); distortionParameters.correlationGaussWidth, distortionParameters.zeros);
...@@ -5650,7 +5701,7 @@ public class MatchSimulatedPattern { ...@@ -5650,7 +5701,7 @@ public class MatchSimulatedPattern {
if (isCellDefined(patternGrid, iUV[0], iUV[1])) { if (isCellDefined(patternGrid, iUV[0], iUV[1])) {
double[][] patternCell = patternGrid[iUV[1]][iUV[0]]; double[][] patternCell = patternGrid[iUV[1]][iUV[0]];
if (patternCell[0].length > 2) if (patternCell[0].length > 2)
gridIntensity[iUV[1]][iUV[0]] = patternCell[0][2]; gridIntensity[iUV[1]][iUV[0]] = patternCell[0][2]; // just copy from patternGrid[v][u][0][2]
} }
/* /*
* gridIntensity[iUV[1]][iUV[0]]=localGridContrast( imp, equalizeGreens, * gridIntensity[iUV[1]][iUV[0]]=localGridContrast( imp, equalizeGreens,
...@@ -6713,6 +6764,10 @@ public class MatchSimulatedPattern { ...@@ -6713,6 +6764,10 @@ public class MatchSimulatedPattern {
setWOI(0, 0, imp.getWidth(), imp.getHeight()); setWOI(0, 0, imp.getWidth(), imp.getHeight());
selection = new Rectangle(0, 0, imp.getWidth(), imp.getHeight()); selection = new Rectangle(0, 0, imp.getWidth(), imp.getHeight());
// without setting roi to null (maybe setting image roi too?) will not retry if first attempt gets too few points
// there is also ignoring PointRoi later, but alone it outputs "Removing failed node (normally should not happen!), u=4, v=2"
// roi = null;
// imp.setRoi(roi,false);
} else { } else {
setWOI(roi.getBounds()); setWOI(roi.getBounds());
selection = roi.getBounds(); selection = roi.getBounds();
...@@ -6811,35 +6866,48 @@ public class MatchSimulatedPattern { ...@@ -6811,35 +6866,48 @@ public class MatchSimulatedPattern {
if (distortionParameters.flatFieldCorrection && (this.flatFieldForGrid == null)) // if it is not null it is if (distortionParameters.flatFieldCorrection && (this.flatFieldForGrid == null)) // if it is not null it is
// already supposed to be // already supposed to be
// applied! // applied!
imp_eq = equalizeGridIntensity(imp, this.PATTERN_GRID, distortionParameters, // imp_eq = equalizeGridIntensity(
equalizeGreens, global_debug_level, updateStatus, threadsMax); imp,
this.PATTERN_GRID,
distortionParameters, // // makes no sense for LWIR as it normalizes absolute data - actually it does!
equalizeGreens,
global_debug_level,
updateStatus,
threadsMax);
else else
imp_eq = imp; imp_eq = imp;
if (distortionParameters.refineCorrelations) { if (distortionParameters.refineCorrelations) {
refineDistortionCorrelation(lwirReaderParameters, // LwirReaderParameters lwirReaderParameters, // null is refineDistortionCorrelation(
// OK lwirReaderParameters, // LwirReaderParameters lwirReaderParameters, // null is OK
distortionParameters, // distortionParameters, //
patternDetectParameters, simulParameters, equalizeGreens, imp_eq, 0.0, // final double maxCorr, // patternDetectParameters,
// maximal allowed simulParameters,
// correction, in pixels equalizeGreens,
// (0.0) - any imp_eq,
threadsMax, updateStatus, debug_level); // debug level 0.0, // final double maxCorr, maximal allowed correction, in pixels (0.0) - any
threadsMax,
recalculateWaveVectors(updateStatus, debug_level);// debug level used inside loops updateStatus,
debug_level); // debug level
recalculateWaveVectors(
updateStatus,
debug_level);// debug level used inside loops
if (global_debug_level > (debugThreshold + 1)) if (global_debug_level > (debugThreshold + 1))
System.out.println("Second pass over at " + IJ.d2s(0.000000001 * (System.nanoTime() - startTime), 3)); System.out.println("Second pass over at " + IJ.d2s(0.000000001 * (System.nanoTime() - startTime), 3));
} }
// hack gridSize // hack gridSize
if ((distortionParameters.gridSize & 1) != 0) { if ((distortionParameters.gridSize & 1) != 0) {
refineDistortionCorrelation(lwirReaderParameters, // LwirReaderParameters lwirReaderParameters, // null is refineDistortionCorrelation(lwirReaderParameters, // LwirReaderParameters lwirReaderParameters, // null is OK
// OK
distortionParameters, // distortionParameters, //
patternDetectParameters, simulParameters, equalizeGreens, imp_eq, 0.0, // final double maxCorr, // patternDetectParameters,
// maximal allowed simulParameters,
// correction, in pixels equalizeGreens,
// (0.0) - any imp_eq,
threadsMax, updateStatus, debug_level); // debug level 0.0, // final double maxCorr, maximal allowed correction, in pixels (0.0) - any
threadsMax,
updateStatus,
debug_level); // debug level
recalculateWaveVectors(updateStatus, debug_level);// debug level used inside loops recalculateWaveVectors(updateStatus, debug_level);// debug level used inside loops
if (global_debug_level > 0) if (global_debug_level > 0)
...@@ -6847,7 +6915,7 @@ public class MatchSimulatedPattern { ...@@ -6847,7 +6915,7 @@ public class MatchSimulatedPattern {
// hack gridSize // hack gridSize
} }
patternCells = numDefinedCells(); patternCells = numDefinedCells();
if ((roi != null) && (patternCells < minimal_pattern_cluster)) { if ((roi != null) && (patternCells < minimal_pattern_cluster) && !(roi instanceof PointRoi)) {
if (global_debug_level > (debugThreshold + 0)) if (global_debug_level > (debugThreshold + 0))
System.out.println("Detected pattern is too small: " + patternCells + ", minimum is set to " System.out.println("Detected pattern is too small: " + patternCells + ", minimum is set to "
+ minimal_pattern_cluster); + minimal_pattern_cluster);
...@@ -9653,16 +9721,21 @@ public class MatchSimulatedPattern { ...@@ -9653,16 +9721,21 @@ public class MatchSimulatedPattern {
*/ */
// //
/* ======================================================================== */ /* ======================================================================== */
private double[] correctedPatternCrossLocation(LwirReaderParameters lwirReaderParameters, // null is OK private double[] correctedPatternCrossLocation(
LwirReaderParameters lwirReaderParameters, // null is OK
double[] beforeXY, // initial coordinates of the pattern cross point double[] beforeXY, // initial coordinates of the pattern cross point
double wv0x, double wv0y, double wv1x, double wv1y, double[][] correction, ImagePlus imp, // image data double wv0x,
// (Bayer double wv0y,
// mosaic) double wv1x,
double wv1y,
double[][] correction,
ImagePlus imp, // image data (Bayer mosaic)
DistortionParameters distortionParameters, // DistortionParameters distortionParameters, //
MatchSimulatedPattern.PatternDetectParameters patternDetectParameters, MatchSimulatedPattern.PatternDetectParameters patternDetectParameters,
MatchSimulatedPattern matchSimulatedPattern, // correlationSize MatchSimulatedPattern matchSimulatedPattern, // correlationSize
SimulationPattern.SimulParameters thisSimulParameters, boolean equalizeGreens, double[] window, // window SimulationPattern.SimulParameters thisSimulParameters,
// function boolean equalizeGreens,
double[] window, // window function
double[] window2, // window function - twice FFT size (or null) double[] window2, // window function - twice FFT size (or null)
double[] window4, // window function - 4x FFT size (or null) double[] window4, // window function - 4x FFT size (or null)
SimulationPattern simulationPattern, boolean negative, // invert cross phase SimulationPattern simulationPattern, boolean negative, // invert cross phase
...@@ -9670,31 +9743,52 @@ public class MatchSimulatedPattern { ...@@ -9670,31 +9743,52 @@ public class MatchSimulatedPattern {
double[][] locsNeib, // locations and weights of neighbors to average double[][] locsNeib, // locations and weights of neighbors to average
int debug_level, String dbgStr) { int debug_level, String dbgStr) {
if (distortionParameters.legacyMode) if (distortionParameters.legacyMode)
return correctedPatternCrossLocationOld(beforeXY, // initial coordinates of the pattern cross point return correctedPatternCrossLocationOld(
wv0x, wv0y, wv1x, wv1y, correction, imp, // image data (Bayer mosaic) beforeXY, // initial coordinates of the pattern cross point
wv0x,
wv0y,
wv1x,
wv1y,
correction,
imp, // image data (Bayer mosaic)
distortionParameters, // distortionParameters, //
patternDetectParameters, matchSimulatedPattern, // correlationSize patternDetectParameters,
thisSimulParameters, equalizeGreens, window, // window function matchSimulatedPattern, // correlationSize
thisSimulParameters,
equalizeGreens,
window, // window function
window2, // window function - twice FFT size (or null) window2, // window function - twice FFT size (or null)
window4, // window function - 4x FFT size (or null) window4, // window function - 4x FFT size (or null)
simulationPattern, negative, // invert cross phase simulationPattern,
negative, // invert cross phase
fht_instance, fast, // use fast measuring of the maximum on the correlation fht_instance, fast, // use fast measuring of the maximum on the correlation
locsNeib, // locations and weights of neighbors to average locsNeib, // locations and weights of neighbors to average
debug_level); debug_level);
else else
return correctedPatternCrossLocationAverage4(lwirReaderParameters, // LwirReaderParameters return correctedPatternCrossLocationAverage4(
// lwirReaderParameters, // null is OK lwirReaderParameters, // LwirReaderParameters
beforeXY, // initial coordinates of the pattern cross point beforeXY, // initial coordinates of the pattern cross point
wv0x, wv0y, wv1x, wv1y, correction, imp, // image data (Bayer mosaic) wv0x,
wv0y,
wv1x,
wv1y,
correction,
imp, // image data (Bayer mosaic)
distortionParameters, // distortionParameters, //
patternDetectParameters, matchSimulatedPattern, // correlationSize patternDetectParameters,
thisSimulParameters, equalizeGreens, window, // window function matchSimulatedPattern, // correlationSize
thisSimulParameters,
equalizeGreens,
window, // window function
window2, // window function - twice FFT size (or null) window2, // window function - twice FFT size (or null)
window4, // window function - 4x FFT size (or null) window4, // window function - 4x FFT size (or null)
simulationPattern, negative, // invert cross phase simulationPattern,
fht_instance, fast, // use fast measuring of the maximum on the correlation negative, // invert cross phase
fht_instance,
fast, // use fast measuring of the maximum on the correlation
locsNeib, // locations and weights of neighbors to average locsNeib, // locations and weights of neighbors to average
debug_level, dbgStr); debug_level,
dbgStr);
} }
private double[] correctedPatternCrossLocationOld(double[] beforeXY, // initial coordinates of the pattern cross private double[] correctedPatternCrossLocationOld(double[] beforeXY, // initial coordinates of the pattern cross
...@@ -9984,36 +10078,50 @@ public class MatchSimulatedPattern { ...@@ -9984,36 +10078,50 @@ public class MatchSimulatedPattern {
return result; return result;
} }
private double[] correctedPatternCrossLocationAverage4(LwirReaderParameters lwirReaderParameters, // null is OK private double[] correctedPatternCrossLocationAverage4(
LwirReaderParameters lwirReaderParameters, // null is OK
double[] beforeXY, // initial coordinates of the pattern cross point double[] beforeXY, // initial coordinates of the pattern cross point
double wv0x, double wv0y, double wv1x, double wv1y, double[][] correction, ImagePlus imp, // image data double wv0x,
// (Bayer double wv0y,
// mosaic) double wv1x,
double wv1y,
double[][] correction,
ImagePlus imp, // image data (Bayer mosaic)
DistortionParameters distortionParameters, // distortionParameters.refineCorrelations DistortionParameters distortionParameters, // distortionParameters.refineCorrelations
MatchSimulatedPattern.PatternDetectParameters patternDetectParameters, MatchSimulatedPattern.PatternDetectParameters patternDetectParameters,
MatchSimulatedPattern matchSimulatedPattern, // correlationSize MatchSimulatedPattern matchSimulatedPattern, // correlationSize
SimulationPattern.SimulParameters thisSimulParameters, boolean equalizeGreens, double[] window, // window SimulationPattern.SimulParameters thisSimulParameters,
// function boolean equalizeGreens,
double[] window, // window function
double[] window2, // window function - twice FFT size (or null) double[] window2, // window function - twice FFT size (or null)
double[] window4, // window function - 4x FFT size (or null) double[] window4, // window function - 4x FFT size (or null)
SimulationPattern simulationPattern, boolean negative, // invert cross phase SimulationPattern simulationPattern,
DoubleFHT fht_instance, boolean fast, // use fast measuring of the maximum on the correlation boolean negative, // invert cross phase
DoubleFHT fht_instance,
boolean fast, // use fast measuring of the maximum on the correlation
double[][] locsNeib, // locations and weights of neighbors to average double[][] locsNeib, // locations and weights of neighbors to average
int debug_level, String dbgStr) { int debug_level,
String dbgStr) {
if (imp == null) { if (imp == null) {
return null; return null;
} }
/*
boolean is_lwir = ((lwirReaderParameters != null) && lwirReaderParameters.is_LWIR(imp)); boolean is_lwir = ((lwirReaderParameters != null) && lwirReaderParameters.is_LWIR(imp));
int correlation_size = is_lwir ? distortionParameters.correlationSizeLwir int correlation_size = is_lwir ? distortionParameters.correlationSizeLwir
: distortionParameters.correlationSize; : distortionParameters.correlationSize;
int max_correlation_size = is_lwir ? distortionParameters.maximalCorrelationSizeLwir int max_correlation_size = is_lwir ? distortionParameters.maximalCorrelationSizeLwir
: distortionParameters.maximalCorrelationSize; : distortionParameters.maximalCorrelationSize;
*/
final int sensor_type = LwirReaderParameters.sensorType(imp);
final int correlation_size = distortionParameters.getCorrelationSize(sensor_type);
final int max_correlation_size = distortionParameters.getMaximalCorrelationSize(sensor_type);
boolean is_mono = false; boolean is_mono = false;
try { try {
is_mono = Boolean.parseBoolean((String) imp.getProperty("MONOCHROME")); is_mono = Boolean.parseBoolean((String) imp.getProperty("MONOCHROME"));
} catch (Exception e) { } catch (Exception e) {
} }
is_mono |= is_lwir; is_mono |= (sensor_type == 1); // is_lwir;
int debug_threshold = 3; int debug_threshold = 3;
// next print - same for good and bad, correction==null // next print - same for good and bad, correction==null
...@@ -10036,7 +10144,7 @@ public class MatchSimulatedPattern { ...@@ -10036,7 +10144,7 @@ public class MatchSimulatedPattern {
beforeXY[1] += distortionParameters.correlationDy; // offset y (in pixels) beforeXY[1] += distortionParameters.correlationDy; // offset y (in pixels)
double[][] invConvMatrix = { { 1, 0 }, { 0, 1 } }; // identity double[][] invConvMatrix = { { 1, 0 }, { 0, 1 } }; // identity
if (!is_lwir) { if (sensor_type != 1) { //(!is_lwir) {
double[][] convMatrix = { { 1.0, -1.0 }, { 1.0, 1.0 } }; // from greens2 to pixel WV double[][] convMatrix = { { 1.0, -1.0 }, { 1.0, 1.0 } }; // from greens2 to pixel WV
invConvMatrix = matrix2x2_scale(matrix2x2_invert(convMatrix), 2.0); invConvMatrix = matrix2x2_scale(matrix2x2_invert(convMatrix), 2.0);
} }
...@@ -10112,19 +10220,26 @@ public class MatchSimulatedPattern { ...@@ -10112,19 +10220,26 @@ public class MatchSimulatedPattern {
if ((debug_level > (debug_threshold - 2)) && (thisCorrelationSize > correlation_size)) if ((debug_level > (debug_threshold - 2)) && (thisCorrelationSize > correlation_size))
System.out.println("**** u/v span too small, increasing FFT size to " + thisCorrelationSize); System.out.println("**** u/v span too small, increasing FFT size to " + thisCorrelationSize);
Rectangle centerCross = correlationSelection(beforeXY, // initial coordinates of the pattern cross point Rectangle centerCross = correlationSelection(beforeXY, // initial coordinates of the pattern cross point
(is_lwir ? (thisCorrelationSize / 2) : (thisCorrelationSize))); // (is_lwir ? (thisCorrelationSize / 2) : (thisCorrelationSize)));
((sensor_type == 1) ? (thisCorrelationSize / 2) : (thisCorrelationSize)));
int ixc = centerCross.x + centerCross.width / 2; int ixc = centerCross.x + centerCross.width / 2;
int iyc = centerCross.y + centerCross.height / 2; int iyc = centerCross.y + centerCross.height / 2;
double[] diffBeforeXY = { beforeXY[0] - ixc, beforeXY[1] - iyc }; double[] diffBeforeXY = { beforeXY[0] - ixc, beforeXY[1] - iyc };
double[] greens_mono; // greens or mono double[] greens_mono; // greens or mono
if (is_lwir) { // if (is_lwir) {
if (sensor_type == 1) {
greens_mono = getNoBayer(imp, centerCross); greens_mono = getNoBayer(imp, centerCross);
if (debug_level > (debug_threshold + 0)) if (debug_level > (debug_threshold + 0))
SDFA_INSTANCE.showArrays(greens_mono, "greens_mono"); SDFA_INSTANCE.showArrays(greens_mono, "greens_mono");
if (debug_level > (debug_threshold + 0)) if (debug_level > (debug_threshold + 0))
System.out.println("ixc=" + ixc + " iyc=" + iyc); System.out.println("ixc=" + ixc + " iyc=" + iyc);
normalizeAndWindow(greens_mono, thisWindow); normalizeAndWindow(greens_mono, thisWindow);
// Twice lower contrast than EO - doubling below - did not work
// for (int i = 0; i < greens_mono.length; i++) {
// greens_mono[i] *= 2.0;
// }
} else { } else {
double[][] input_bayer = splitBayer(imp, centerCross, equalizeGreens); double[][] input_bayer = splitBayer(imp, centerCross, equalizeGreens);
if (debug_level > (debug_threshold + 1)) if (debug_level > (debug_threshold + 1))
...@@ -10176,7 +10291,8 @@ public class MatchSimulatedPattern { ...@@ -10176,7 +10291,8 @@ public class MatchSimulatedPattern {
double[][] modelCorrs = new double[numOfNeib][]; double[][] modelCorrs = new double[numOfNeib][];
double[][] debugGreens = new double[numOfNeib][0]; double[][] debugGreens = new double[numOfNeib][0];
for (numNeib = 0; numNeib < numOfNeib; numNeib++) { for (numNeib = 0; numNeib < numOfNeib; numNeib++) {
if (is_lwir) { // monochrome, use all pixels // if (is_lwir) { // monochrome, use all pixels
if (sensor_type == 1) { // monochrome, use all pixels
neibCenter[0] = diffBeforeXY[0] + gridNeib[numNeib][0]; neibCenter[0] = diffBeforeXY[0] + gridNeib[numNeib][0];
neibCenter[1] = diffBeforeXY[1] + gridNeib[numNeib][1]; neibCenter[1] = diffBeforeXY[1] + gridNeib[numNeib][1];
} else { } else {
...@@ -10184,11 +10300,13 @@ public class MatchSimulatedPattern { ...@@ -10184,11 +10300,13 @@ public class MatchSimulatedPattern {
neibCenter[1] = diffBeforeXY[1] + 0.5 * (gridNeib[numNeib][0] - gridNeib[numNeib][1]); neibCenter[1] = diffBeforeXY[1] + 0.5 * (gridNeib[numNeib][0] - gridNeib[numNeib][1]);
} }
double[] barray; double[] barray;
if (is_lwir) { // if (is_lwir) {
if (sensor_type == 1) {
// negative=!negative; // negative=!negative;
dUV = matrix2x2_scale(matrix2x2_mul(wv, neibCenter), -2 * Math.PI); dUV = matrix2x2_scale(matrix2x2_mul(wv, neibCenter), -2 * Math.PI);
// dUV[0] = 0.0; dUV[1] = 0.0; // dUV[0] = 0.0; dUV[1] = 0.0;
if (debug_level > (debug_threshold + 20)) { boolean dbg_once = false;
if (dbg_once || (debug_level > (debug_threshold + 20))) {
double[] barray0 = simulationPattern.simulatePatternFullPatternSafe( // Is it the most double[] barray0 = simulationPattern.simulatePatternFullPatternSafe( // Is it the most
// time-consuming part? // time-consuming part?
// should it be done once // should it be done once
...@@ -10429,11 +10547,11 @@ public class MatchSimulatedPattern { ...@@ -10429,11 +10547,11 @@ public class MatchSimulatedPattern {
WVgreensMono[i][j] *= 0.5; WVgreensMono[i][j] *= 0.5;
} }
double[] contrasts = correlationContrast(modelCorr, greens_mono, WVgreensMono, // wave vectors (same units as double[] contrasts = correlationContrast(modelCorr,
// the pixels array) greens_mono,
WVgreensMono, // wave vectors (same units as the pixels array)
distortionParameters.contrastSelectSigmaCenter, // 2.0 Gaussian sigma to select correlation (pixels, 2.0) distortionParameters.contrastSelectSigmaCenter, // 2.0 Gaussian sigma to select correlation (pixels, 2.0)
distortionParameters.contrastSelectSigma, // 0.1 Gaussian sigma to select correlation centers (fraction of distortionParameters.contrastSelectSigma, // 0.1 Gaussian sigma to select correlation centers (fraction of UV period), 0.1
// UV period), 0.1
centerXY[0], // x0, // center coordinates centerXY[0], // x0, // center coordinates
centerXY[1], // y0, centerXY[1], // y0,
"test-contrast"); // title base for optional plots names "test-contrast"); // title base for optional plots names
...@@ -10497,9 +10615,12 @@ public class MatchSimulatedPattern { ...@@ -10497,9 +10615,12 @@ public class MatchSimulatedPattern {
+ IJ.d2s(beforeXY[1], 3) + ")->" + IJ.d2s(result[0], 3) + ":" + IJ.d2s(result[1], 3)); + IJ.d2s(beforeXY[1], 3) + ")->" + IJ.d2s(result[0], 3) + ":" + IJ.d2s(result[1], 3));
// FIXME: maybe wrong for mono? // FIXME: maybe wrong for mono?
if (is_lwir) { // if (is_lwir) {
if (sensor_type == 1) {
result[0] = ixc + diffBeforeXY[0] + centerXY[0]; result[0] = ixc + diffBeforeXY[0] + centerXY[0];
result[1] = iyc + diffBeforeXY[1] + centerXY[1]; result[1] = iyc + diffBeforeXY[1] + centerXY[1];
// Twice lower contrast than EO - doubling below - did not work
// result[2] *= 2.0; // not just for refine
} else { } else {
result[0] = ixc + diffBeforeXY[0] - (-centerXY[0] - centerXY[1]); result[0] = ixc + diffBeforeXY[0] - (-centerXY[0] - centerXY[1]);
result[1] = iyc + diffBeforeXY[1] - (centerXY[0] - centerXY[1]); result[1] = iyc + diffBeforeXY[1] - (centerXY[0] - centerXY[1]);
...@@ -12409,103 +12530,337 @@ public class MatchSimulatedPattern { ...@@ -12409,103 +12530,337 @@ public class MatchSimulatedPattern {
/* ======================================================================== */ /* ======================================================================== */
public static class DistortionParameters { public static class DistortionParameters {
public int correlationSize; // FFTSize/4 private int correlationSize; // FFTSize/4
public int correlationSizeLwir; private int correlationSizeLwir;
public int maximalCorrelationSize; // FFTSize/2 private int maximalCorrelationSize; // FFTSize/2
public int maximalCorrelationSizeLwir; private int maximalCorrelationSizeLwir;
public double correlationGaussWidth; // 0 - no window, <0 - use Hamming public double correlationGaussWidth; // 0 - no window, <0 - use Hamming
public boolean absoluteCorrelationGaussWidth = false; // do not scale correlationGaussWidth when the FFT size is public boolean absoluteCorrelationGaussWidth = false; // do not scale correlationGaussWidth when the FFT size is
// increased // increased
public int zeros; // leave this number of zeros on the margins of the window (toatal from both public int zeros; // leave this number of zeros on the margins of the window (toatal from both
// sides). If correlationGaussWidth>0 will // sides). If correlationGaussWidth>0 will
// additionally multiply by Hamming // additionally multiply by Hamming
public int FFTSize; private int FFTSize;
public int FFTSize_lwir; private int FFTSize_lwir;
public int FFTOverlap; // 32 used for aberration kernels, former FFT_OVERLAP private int FFTOverlap; // 32 used for aberration kernels, former FFT_OVERLAP
public int FFTOverlap_lwir; // 4 private int FFTOverlap_lwir; // 4
public double fftGaussWidth; public double fftGaussWidth;
public double phaseCorrelationFraction = 1.0; // 1.0 - phase correlation, 0.0 - just cross-correlation public double phaseCorrelationFraction = 1.0; // 1.0 - phase correlation, 0.0 - just cross-correlation
public double correlationHighPassSigma; public double correlationHighPassSigma;
public double correlationLowPassSigma; public double correlationLowPassSigma;
public double correlationRingWidth; // ring (around r=0.5 dist to opposite corr) width , center circle public double correlationRingWidth; // ring (around r=0.5 dist to opposite corr) width , center circle
// r=0.5*correlationRingWidth // r=0.5*correlationRingWidth
public double correlationMaxOffset; // maximal distance between predicted and actual pattern node public double correlationMaxOffset; // maximal distance between predicted and actual pattern node
public double correlationMinContrast; // minimal contrast for the pattern to pass public double correlationMinContrast; // minimal contrast for the pattern to pass
public double correlationMinInitialContrast; // minimal contrast for the pattern of the center (initial point) public double correlationMinInitialContrast; // minimal contrast for the pattern of the center (initial point)
public double correlationMinAbsoluteContrast; // minimal contrast for the pattern to pass, does not compensate public double correlationMinAbsoluteContrast; // minimal contrast for the pattern to pass, does not compensate
// for low ligt // for low ligt
public double correlationMinAbsoluteInitialContrast; // minimal contrast for the pattern of the center (initial public double correlationMinAbsoluteInitialContrast; // minimal contrast for the pattern of the center (initial
// point) // point)
public double scaleFirstPassContrast; // Decrease contrast of cells that are too close to the border to be public double scaleFirstPassContrast; // Decrease contrast of cells that are too close to the border to be
// processed in refinement pass // processed in refinement pass
public double contrastSelectSigmaCenter; // Gaussian sigma to select correlation centers in pixels, 2.0 (center public double contrastSelectSigmaCenter; // Gaussian sigma to select correlation centers in pixels, 2.0 (center
// spot) // spot)
public double contrastSelectSigma; // Gaussian sigma to select correlation centers (fraction of UV period), 0.1 public double contrastSelectSigma; // Gaussian sigma to select correlation centers (fraction of UV period), 0.1
public double contrastAverageSigma; // Gaussian sigma to average correlation variations (as contrast reference) public double contrastAverageSigma; // Gaussian sigma to average correlation variations (as contrast reference)
// 0.5 // 0.5
public int minimalPatternCluster; // minimal pattern cluster size (0 - disable retries) private int minimalPatternCluster; // minimal pattern cluster size (0 - disable retries)
public int minimalPatternClusterLwir; // minimal pattern cluster size (0 - disable retries) private int minimalPatternClusterLwir; // minimal pattern cluster size (0 - disable retries)
public double scaleMinimalInitialContrast; // increase/decrease minimal contrast if initial cluster is >0 but public double scaleMinimalInitialContrast; // increase/decrease minimal contrast if initial cluster is >0 but
// less than minimalPatternCluster // less than minimalPatternCluster
public double searchOverlap; // when searching for grid, step this amount of the FFTSize public double searchOverlap; // when searching for grid, step this amount of the FFTSize
public int patternSubdiv; public int patternSubdiv;
public double correlationDx; // not saved public double correlationDx; // not saved
public double correlationDy; // not saved public double correlationDy; // not saved
public int gridSize; public int gridSize;
public int loop_debug_level; public int loop_debug_level;
public boolean refineCorrelations; public boolean refineCorrelations;
public boolean fastCorrelationOnFirstPass; public boolean fastCorrelationOnFirstPass;
public boolean fastCorrelationOnFinalPass; public boolean fastCorrelationOnFinalPass;
public double bPatternSigma; // blur bPattern with this sigma public double bPatternSigma; // blur bPattern with this sigma
public double barraySigma; // blur barray with this sigma, multiplied by subdiv public double barraySigma; // blur barray with this sigma, multiplied by subdiv
public double correlationWeightSigma; // sigma (in pixels) for maximum approximation - UNUSED (other maximum public double correlationWeightSigma; // sigma (in pixels) for maximum approximation - UNUSED (other maximum
// methods) // methods)
public double correlationRadiusScale; // maximal radius to consider, in sigmas (if 0 - use sigma as radius) - public double correlationRadiusScale; // maximal radius to consider, in sigmas (if 0 - use sigma as radius) -
// UNUSED // UNUSED
public int correlationRadius; // radius (green pixel) of the correlation maximum to use for x/y measurement public int correlationRadius; // radius (green pixel) of the correlation maximum to use for x/y measurement
public double correlationThreshold; // fraction of the value of the maximum fro the point to be included in public double correlationThreshold; // fraction of the value of the maximum fro the point to be included in
// centroid calculation // centroid calculation
public int correlationSubdiv; // Total subdivision of the correlation maximum (linear and FFT) public int correlationSubdiv; // Total subdivision of the correlation maximum (linear and FFT)
public int correlationFFTSubdiv; // Increase density of the correlation using FFT public int correlationFFTSubdiv; // Increase density of the correlation using FFT
public boolean correlationAverageOnRefine; // average position between neighbor samples public boolean correlationAverageOnRefine; // average position between neighbor samples
public boolean refineInPlace; // Update coordinates of the grid points as they are recalculated (false - then public boolean refineInPlace; // Update coordinates of the grid points as they are recalculated (false - then
// update all at once) // update all at once)
public double averageOrthoDist; // distance to up/down/right left neighbors (0.5) public double averageOrthoDist; // distance to up/down/right left neighbors (0.5)
public double averageOrthoWeight; // weight of 4 ortho neighbors (combined) - 0.4), weight of center -s public double averageOrthoWeight; // weight of 4 ortho neighbors (combined) - 0.4), weight of center -s
// 1.0-averageOrthoWeight-averageDiagWeight // 1.0-averageOrthoWeight-averageDiagWeight
public double averageDiagDist; // distance to diagonal neighbors (projection on x/y) (0.5) public double averageDiagDist; // distance to diagonal neighbors (projection on x/y) (0.5)
public double averageDiagWeight; // weight of 4 diagonal neighbors (combined) - 0.4) public double averageDiagWeight; // weight of 4 diagonal neighbors (combined) - 0.4)
public boolean useQuadratic; // use quadratic extrapolation to predict position/wave vectors of a new pixel public boolean useQuadratic; // use quadratic extrapolation to predict position/wave vectors of a new pixel
// (false - use linear) // (false - use linear)
public boolean removeLast; // remove outer (unreliable) row of nodes public boolean removeLast; // remove outer (unreliable) row of nodes
public int numberExtrapolated; // add this number of extrapolated nodes public int numberExtrapolated; // add this number of extrapolated nodes
public double extrapolationSigma; // use instead of the correlationWeightSigma during final extrapolation public double extrapolationSigma; // use instead of the correlationWeightSigma during final extrapolation
public double minUVSpan; // Minimal u/v span in correlation window that triggers increase of the public double minUVSpan; // Minimal u/v span in correlation window that triggers increase of the
// correlation FFT size // correlation FFT size
public boolean flatFieldCorrection = true; // compensate grid uneven intensity (vignetting, illumination) public boolean flatFieldCorrection = true; // compensate grid uneven intensity (vignetting, illumination)
public double flatFieldExtarpolate = 1.0; // extrapolate flat field intensity map (relative to the average grid public double flatFieldExtarpolate = 1.0; // extrapolate flat field intensity map (relative to the average grid
// period) // period)
public double flatFieldBlur = 1.0; // blur the intensity map (relative to the average grid period) public double flatFieldBlur = 1.0; // blur the intensity map (relative to the average grid period)
public double flatFieldMin = 0.1; // do not try to compensate if intensity less than this part of maximal public double flatFieldMin = 0.1; // do not try to compensate if intensity less than this part of maximal
public double flatFieldShrink = 1.0; // Shrink before extrapolating intensity map (relative to the average grid public double flatFieldShrink = 1.0; // Shrink before extrapolating intensity map (relative to the average grid
// period) // period)
public double flatFieldExpand = 3.0; // Expand during extrapolation (relative to the average grid period) public double flatFieldExpand = 3.0; // Expand during extrapolation (relative to the average grid period)
public double flatFieldSigmaRadius = 1.0;// Extrapolation weight effective radius (relative to the average grid public double flatFieldSigmaRadius = 1.0;// Extrapolation weight effective radius (relative to the average grid
// period) // period)
public double flatFieldExtraRadius = 1.5;// Consider pixels in a square with the side twice this (relative to public double flatFieldExtraRadius = 1.5;// Consider pixels in a square with the side twice this (relative to
// flatFieldSigmaRadius) // flatFieldSigmaRadius)
public double averagingAreaScale = 2.0; // multiply the average grid period to determine the area for averaging public double averagingAreaScale = 2.0; // multiply the average grid period to determine the area for averaging
// the grig brightness // the grig brightness
// match pointers errors // match pointers errors
public int errTooFewCells = -10; public int errTooFewCells = -10;
public int errPatternNotFound = -11; public int errPatternNotFound = -11;
public boolean legacyMode = false; // legacy mode public boolean legacyMode = false; // legacy mode
public int getCorrelationSize(int sensor_type) {
switch (sensor_type) {
case 1: return correlationSizeLwir;
default: return correlationSize;}
}
public void setCorrelationSize(int size, int sensor_type) {
switch (sensor_type) {
case 1: correlationSizeLwir = size; break;
default: correlationSize = size;}
}
public int getMaximalCorrelationSize(int sensor_type) {
switch (sensor_type) {
case 1: return maximalCorrelationSizeLwir;
default: return maximalCorrelationSize;}
}
public int getFFTSize(int sensor_type) {
switch (sensor_type) {
case 1: return FFTSize_lwir;
default: return FFTSize;}
}
/*
public void setFFTSize(int size, int sensor_type) {
switch (sensor_type) {
case 1: FFTSize_lwir = size; break;
default: FFTSize = size; }
}
*/
public int getFFTOverlap(int sensor_type) {
switch (sensor_type) {
case 1: return FFTOverlap_lwir;
default: return FFTOverlap;}
}
public int getMinimalPatternCluster(int sensor_type) {
switch (sensor_type) {
case 1: return minimalPatternClusterLwir;
default: return minimalPatternCluster;}
}
public void setMinimalPatternCluster(int size, int sensor_type) {
switch (sensor_type) {
case 1: minimalPatternClusterLwir = size; break;
default: minimalPatternCluster = size;}
}
public boolean showDistortionDialog(int [] mdl) { //MatchSimulatedPattern.DistortionParameters distortionParameters) {
MatchSimulatedPattern.DistortionParameters distortionParameters = this;
int i;
GenericDialog gd = new GenericDialog("Distrortion parameters");
gd.addNumericField("FFTSize (Initial pattern and aberraton kernels):", distortionParameters.FFTSize, 0); // 256
gd.addNumericField("FFTSize for LWIR sensors):", distortionParameters.FFTSize_lwir, 0); // 32
gd.addNumericField("FFTOverlap (aberration kernels):", distortionParameters.FFTOverlap, 0); // 32
gd.addNumericField("FFTOverlap for LWIR sensors):", distortionParameters.FFTOverlap_lwir, 0); // 4
gd.addNumericField("FFT Gaussian width (relative):", distortionParameters.fftGaussWidth, 3);
gd.addNumericField("Correlation size:", distortionParameters.correlationSize, 0); // 64
gd.addNumericField("Correlation size LWIR:", distortionParameters.correlationSizeLwir, 0); // 16
gd.addNumericField("Maximal correlation size:", distortionParameters.maximalCorrelationSize, 0); // 128
gd.addNumericField("Maximal correlation size LWIR:", distortionParameters.maximalCorrelationSizeLwir, 0); // 16
gd.addNumericField("Correlation Gauss width (relative):", distortionParameters.correlationGaussWidth, 3);
gd.addCheckbox("Keep Gaussian width absolute when increasing FFT size",distortionParameters.absoluteCorrelationGaussWidth);
// /phaseCorrelationFraction
//// leave this number of zeros on teh margins of the window (toatal from both sides). If correlationGaussWidth>0 will
// additionally multiply by Hamming
gd.addNumericField("Leave zeros on the window margins (toatal numbedr from both sides)", distortionParameters.zeros, 0);
gd.addNumericField("Phase correlation modifier (1.0 - phase corr., 0 - just corr.)", distortionParameters.phaseCorrelationFraction, 5);
gd.addNumericField("Correlation high-pass sigma:", distortionParameters.correlationHighPassSigma, 3);
gd.addNumericField("Correlation low-pass sigma (fraction of sqrt(2)*Nyquist, lower - more filtering, 0 -none):",distortionParameters.correlationLowPassSigma, 3);
gd.addNumericField("Correlation maximal offset from predicted:",distortionParameters.correlationMaxOffset, 3);
gd.addNumericField("Detection ring width (fraction):", distortionParameters.correlationRingWidth, 3);
gd.addNumericField("Correlation minimal contrast (normalized)", distortionParameters.correlationMinContrast, 3);
gd.addNumericField("Correlation minimal contrast for initial search (normalized)", distortionParameters.correlationMinInitialContrast, 3);
gd.addNumericField("Correlation minimal contrast (absolute)", distortionParameters.correlationMinAbsoluteContrast, 3);
gd.addNumericField("Correlation minimal contrast for initial search (absolute)", distortionParameters.correlationMinAbsoluteInitialContrast, 3);
gd.addNumericField("Decrease contrast of cells that are too close to the border to be processed in refinement pass", distortionParameters.scaleFirstPassContrast, 3);
gd.addNumericField("Gaussian sigma to select correlation center in pixels, 2.0", distortionParameters.contrastSelectSigmaCenter, 3);
gd.addNumericField("Gaussian sigma to select correlation off-centers (fraction of UV period), 0.1", distortionParameters.contrastSelectSigma, 3);
gd.addNumericField("Gaussian sigma to average correlation variations (as contrast reference), 0.5", distortionParameters.contrastAverageSigma, 3);
gd.addNumericField("Minimal initial pattern cluster size (0 - disable retries)", distortionParameters.minimalPatternCluster, 0); // 40
gd.addNumericField("Minimal initial LWIR pattern cluster size (0 - disable retries)", distortionParameters.minimalPatternClusterLwir, 0); // 10
gd.addNumericField("Scale minimal contrast if the initial cluster is nonzero but smaller", distortionParameters.scaleMinimalInitialContrast, 3);
gd.addNumericField("Overlap of FFT areas when searching for pattern", distortionParameters.searchOverlap, 3);
gd.addNumericField("Pattern subdivision:", distortionParameters.patternSubdiv, 0); // 4
gd.addNumericField("Blur pattern bitmap (sigma): ", distortionParameters.bPatternSigma, 3,5,"pattern cell"); // 0.02
gd.addNumericField("Blur pattern (sigma): ", distortionParameters.barraySigma, 3,5,"sensor pix"); // 0.5
gd.addNumericField("Correlation weights (around maximum):", distortionParameters.correlationWeightSigma, 3,5,"nodes"); // 2.5
gd.addNumericField("Correlation radius scale (0 - sharp sigma)", distortionParameters.correlationRadiusScale, 1,3,"sigmas"); //2.0
gd.addNumericField("Correlation maximal radius to use", distortionParameters.correlationRadius, 0,1,"pix"); // 2.0
gd.addNumericField("Correlation maximum calculation threshold", distortionParameters.correlationThreshold*100, 2,5,"%"); // .8
gd.addNumericField("Interpolate correlation (FFT*linear)", distortionParameters.correlationSubdiv, 0,3,"x"); // 16
gd.addNumericField("Interpolate correlation with FFT", distortionParameters.correlationFFTSubdiv, 0,3,"x"); // 4
gd.addNumericField("Correlation dx (debug)", distortionParameters.correlationDx, 3);
gd.addNumericField("Correlation dy (debug)", distortionParameters.correlationDy, 3);
gd.addNumericField("Maximal size of the pattern grid (square)", distortionParameters.gridSize, 0);
gd.addCheckbox ("Refine correlations", distortionParameters.refineCorrelations);
gd.addCheckbox ("Use fast correlation on first pass", distortionParameters.fastCorrelationOnFirstPass);
gd.addCheckbox ("Use fast correlation on refine pass", distortionParameters.fastCorrelationOnFinalPass);
gd.addCheckbox ("Average correlation measurements between neighbors (on refine)", distortionParameters.correlationAverageOnRefine);
gd.addCheckbox ("Update coordinates of the grid points as they are recalculated (false - then update all at once)", distortionParameters.refineInPlace);
gd.addNumericField("Distance to ortho neighbors (for averaging)", distortionParameters.averageOrthoDist, 3,5,"sensor pix");
gd.addNumericField("Combined weight of ortho neighbors (fraction of 1.0)", distortionParameters.averageOrthoWeight, 3);
gd.addNumericField("Distance to diagonal neighbors (for averaging)", distortionParameters.averageDiagDist, 3,5,"sensor pix");
gd.addNumericField("Combined weight of diagonal neighbors (fraction of 1.0)", distortionParameters.averageDiagWeight, 3);
gd.addCheckbox ("Use quadratic extrapolation (false - force linear)", distortionParameters.useQuadratic);
gd.addCheckbox ("Remove outer (unreliable) layer before extrapolation", distortionParameters.removeLast);
gd.addNumericField("Number of extrapolated layers of nodes (final stage)", distortionParameters.numberExtrapolated, 0);
gd.addNumericField("Sigma during final extrapolation stage", distortionParameters.extrapolationSigma, 3,5,"nodes");
gd.addNumericField("Minimal UV span in correlation window to trigger FFT size increase", distortionParameters.minUVSpan, 3);
gd.addCheckbox ("Compensate uneven pattern intensity", distortionParameters.flatFieldCorrection);
gd.addNumericField("Extrapolate pattern intensity map (relative to pattern period)", distortionParameters.flatFieldExtarpolate, 3);
gd.addNumericField("Blur pattern intensity map (relative to pattern period)", distortionParameters.flatFieldBlur, 3);
gd.addNumericField("Do not use areas where intensity map is below this part of maximal", distortionParameters.flatFieldMin, 3);
gd.addNumericField("Shrink before extrapolating intensity map (relative to the average grid period)", distortionParameters.flatFieldShrink, 3);
gd.addNumericField("Expand during extrapolation (relative to the average grid period)", distortionParameters.flatFieldExpand, 3);
gd.addNumericField("Extrapolation weight effective radius (relative to the average grid period)", distortionParameters.flatFieldSigmaRadius, 3);
gd.addNumericField("Consider pixels in a square with the side twice this (relative to flatFieldSigmaRadius)", distortionParameters.flatFieldExtraRadius, 3);
gd.addNumericField("Multiply the average grid period to determine the area for averaging the grig brightness", distortionParameters.averagingAreaScale, 3);
gd.addCheckbox ("Legacy mode (deprecated)", distortionParameters.legacyMode);
gd.addNumericField("Debug level inside the loop", distortionParameters.loop_debug_level, 0);
gd.addNumericField("Debug Level:", mdl[0], 0);
WindowTools.addScrollBars(gd);
gd.showDialog();
if (gd.wasCanceled()) return false;
distortionParameters.FFTSize = makePowerOfTwo((int) gd.getNextNumber());
distortionParameters.FFTSize_lwir = makePowerOfTwo((int) gd.getNextNumber());
distortionParameters.FFTOverlap = makePowerOfTwo((int) gd.getNextNumber());
distortionParameters.FFTOverlap_lwir = makePowerOfTwo((int) gd.getNextNumber());
distortionParameters.fftGaussWidth= gd.getNextNumber();
distortionParameters.correlationSize = makePowerOfTwo((int) gd.getNextNumber());
distortionParameters.correlationSizeLwir = makePowerOfTwo((int) gd.getNextNumber());
distortionParameters.maximalCorrelationSize = makePowerOfTwo((int) gd.getNextNumber());
distortionParameters.maximalCorrelationSizeLwir = makePowerOfTwo((int) gd.getNextNumber());
distortionParameters.correlationGaussWidth= gd.getNextNumber();
distortionParameters.absoluteCorrelationGaussWidth=gd.getNextBoolean();
distortionParameters.zeros= (int) gd.getNextNumber();
distortionParameters.phaseCorrelationFraction= gd.getNextNumber();
distortionParameters.correlationHighPassSigma= gd.getNextNumber();
distortionParameters.correlationLowPassSigma= gd.getNextNumber();
distortionParameters.correlationMaxOffset= gd.getNextNumber();
distortionParameters.correlationRingWidth= gd.getNextNumber();
distortionParameters.correlationMinContrast= gd.getNextNumber();
distortionParameters.correlationMinInitialContrast= gd.getNextNumber();
distortionParameters.correlationMinAbsoluteContrast= gd.getNextNumber();
distortionParameters.correlationMinAbsoluteInitialContrast= gd.getNextNumber();
distortionParameters.scaleFirstPassContrast= gd.getNextNumber();
distortionParameters.contrastSelectSigmaCenter= gd.getNextNumber();
distortionParameters.contrastSelectSigma= gd.getNextNumber();
distortionParameters.contrastAverageSigma= gd.getNextNumber();
distortionParameters.minimalPatternCluster=(int) gd.getNextNumber();
distortionParameters.minimalPatternClusterLwir=(int) gd.getNextNumber();
distortionParameters.scaleMinimalInitialContrast=gd.getNextNumber();
distortionParameters.searchOverlap= gd.getNextNumber();
distortionParameters.patternSubdiv= (int) gd.getNextNumber();
distortionParameters.bPatternSigma= gd.getNextNumber();
distortionParameters.barraySigma= gd.getNextNumber();
distortionParameters.correlationWeightSigma= gd.getNextNumber();
distortionParameters.correlationRadiusScale= gd.getNextNumber();
distortionParameters.correlationRadius= (int) gd.getNextNumber();
distortionParameters.correlationThreshold= 0.01*gd.getNextNumber();
distortionParameters.correlationSubdiv= (int) gd.getNextNumber();
distortionParameters.correlationFFTSubdiv=1;
for (i=(int) gd.getNextNumber(); i >1; i>>=1) distortionParameters.correlationFFTSubdiv <<=1; /* make it to be power of 2 */
distortionParameters.correlationDx= gd.getNextNumber();
distortionParameters.correlationDy= gd.getNextNumber();
distortionParameters.gridSize= (int) gd.getNextNumber();
distortionParameters.refineCorrelations= gd.getNextBoolean();
distortionParameters.fastCorrelationOnFirstPass=gd.getNextBoolean();
distortionParameters.fastCorrelationOnFinalPass=gd.getNextBoolean();
distortionParameters.correlationAverageOnRefine=gd.getNextBoolean();
distortionParameters.refineInPlace= gd.getNextBoolean();
distortionParameters.averageOrthoDist= gd.getNextNumber();
distortionParameters.averageOrthoWeight= gd.getNextNumber();
distortionParameters.averageDiagDist= gd.getNextNumber();
distortionParameters.averageDiagWeight= gd.getNextNumber();
distortionParameters.useQuadratic= gd.getNextBoolean();
distortionParameters.removeLast= gd.getNextBoolean();
distortionParameters.numberExtrapolated=(int) gd.getNextNumber();
distortionParameters.extrapolationSigma= gd.getNextNumber();
distortionParameters.minUVSpan= gd.getNextNumber();
distortionParameters.flatFieldCorrection= gd.getNextBoolean();
distortionParameters.flatFieldExtarpolate= gd.getNextNumber();
distortionParameters.flatFieldBlur= gd.getNextNumber();
distortionParameters.flatFieldMin= gd.getNextNumber();
distortionParameters.flatFieldShrink= gd.getNextNumber();
distortionParameters.flatFieldExpand= gd.getNextNumber();
distortionParameters.flatFieldSigmaRadius= gd.getNextNumber();
distortionParameters.flatFieldExtraRadius= gd.getNextNumber();
distortionParameters.averagingAreaScale= gd.getNextNumber();
distortionParameters.legacyMode= gd.getNextBoolean();
distortionParameters.loop_debug_level= (int) gd.getNextNumber();
mdl[0]= (int) gd.getNextNumber();
return true;
}
private int makePowerOfTwo(int v) {
int v2 = 1;
for (int i=v; i > 1; i>>=1 ) v2 <<=1; /* make it to be power of 2 */
return v2;
}
public DistortionParameters(int correlationSize, int correlationSizeLwir, int maximalCorrelationSize, public DistortionParameters(int correlationSize, int correlationSizeLwir, int maximalCorrelationSize,
int maximalCorrelationSizeLwir, double correlationGaussWidth, boolean absoluteCorrelationGaussWidth, int maximalCorrelationSizeLwir, double correlationGaussWidth, boolean absoluteCorrelationGaussWidth,
int zeros, int FFTSize, int FFTSize_lwir, int FFTOverlap, int FFTOverlap_lwir, double fftGaussWidth, int zeros, int FFTSize, int FFTSize_lwir, int FFTOverlap, int FFTOverlap_lwir, double fftGaussWidth,
......
...@@ -1407,6 +1407,10 @@ import ij.gui.GenericDialog; ...@@ -1407,6 +1407,10 @@ import ij.gui.GenericDialog;
return eyesisSubCameras[0][ncam].isLWIR(); return eyesisSubCameras[0][ncam].isLWIR();
} }
public int getSensorType(int ncam) {
return eyesisSubCameras[0][ncam].isLWIR()? 1 : 0;
}
/** /**
* Setting default camera geometry parameters for LWIR16 prototype system * Setting default camera geometry parameters for LWIR16 prototype system
* @return false if number of cameras is not 20 * @return false if number of cameras is not 20
......
...@@ -44,6 +44,7 @@ public class LwirReaderParameters { ...@@ -44,6 +44,7 @@ public class LwirReaderParameters {
public final static int [] FFC_GROUPS= {1,2,4}; public final static int [] FFC_GROUPS= {1,2,4};
public static final String [] SENSOR_TYPES = {"EO","LWIR"}; public static final String [] SENSOR_TYPES = {"EO","LWIR"};
public static final String SENSOR_TYPE = "SENSOR_TYPE"; public static final String SENSOR_TYPE = "SENSOR_TYPE";
protected static int MAX_LWIR_WIDTH = 1024; //
private boolean parameters_updated = false; private boolean parameters_updated = false;
protected String camera_name = "Talon"; // "LWIR16"; protected String camera_name = "Talon"; // "LWIR16";
...@@ -73,7 +74,6 @@ public class LwirReaderParameters { ...@@ -73,7 +74,6 @@ public class LwirReaderParameters {
protected double eo_gain_rg = 0.7705; // 1.116; halogen/fluorescent protected double eo_gain_rg = 0.7705; // 1.116; halogen/fluorescent
protected double eo_gain_bg = 2.401; // 1.476; protected double eo_gain_bg = 2.401; // 1.476;
protected boolean [] selected_channels = {true, true, true, true, true, true, true, true}; protected boolean [] selected_channels = {true, true, true, true, true, true, true, true};
protected int max_lwir_width = 1024; //
/* /*
protected double [] eo_exp_corr = {1.0, 1.0, 1.0, 1.0}; protected double [] eo_exp_corr = {1.0, 1.0, 1.0, 1.0};
protected double [] eo_gcorr_rbgb = { protected double [] eo_gcorr_rbgb = {
...@@ -145,11 +145,11 @@ public class LwirReaderParameters { ...@@ -145,11 +145,11 @@ public class LwirReaderParameters {
return 20; return 20;
} }
public boolean is_LWIR(int width) { public static boolean is_LWIR(int width) {
return width <= max_lwir_width; return width <= MAX_LWIR_WIDTH;
} }
public boolean is_LWIR(ImagePlus imp){ public static boolean is_LWIR(ImagePlus imp){
// See if image has LwirReaderParameters.SENSOR_TYPE property, then use is_LWIR(String property_value), // See if image has LwirReaderParameters.SENSOR_TYPE property, then use is_LWIR(String property_value),
// if not - use old width property // if not - use old width property
if (imp.getProperty("WOI_WIDTH")==null) { if (imp.getProperty("WOI_WIDTH")==null) {
...@@ -160,6 +160,16 @@ public class LwirReaderParameters { ...@@ -160,6 +160,16 @@ public class LwirReaderParameters {
} }
return is_LWIR(imp.getWidth()); return is_LWIR(imp.getWidth());
} }
public static int sensorType(ImagePlus imp) {
if (imp.getProperty("WOI_WIDTH")==null) {
EyesisTiff.decodeProperiesFromInfo(imp);
}
if (imp.getProperty(SENSOR_TYPE)!=null) {
return (is_LWIR((String) imp.getProperty(SENSOR_TYPE)))? 1:0;
}
return is_LWIR(imp.getWidth())? 1 : 0;
}
public int getDebugLevel() { public int getDebugLevel() {
return this.debug_level; return this.debug_level;
......
...@@ -51,6 +51,22 @@ public class ImagejJp4TiffMulti { ...@@ -51,6 +51,22 @@ public class ImagejJp4TiffMulti {
final boolean scale, final boolean scale,
final String std) throws IOException, FormatException // std - include non-elphel properties with prefix std final String std) throws IOException, FormatException // std - include non-elphel properties with prefix std
{ {
return getMultiImages(
urls,
imps,
0.0, // final double timeout_sec,
scale,
std);
}
public ImagePlus [] getMultiImages(
final String [] urls,
final ImagePlus [] imps,
final double timeout_sec,
final boolean scale,
final String std) throws IOException, FormatException // std - include non-elphel properties with prefix std
{
// final ImagePlus [] imps = new ImagePlus [urls.length]; // final ImagePlus [] imps = new ImagePlus [urls.length];
LOGGER.error("Please ignore 'File has length 0 and may be corrupt' - caused by bioformat reading memory file"); LOGGER.error("Please ignore 'File has length 0 and may be corrupt' - caused by bioformat reading memory file");
final Thread[] threads = newThreadArray(MAX_THREADS); final Thread[] threads = newThreadArray(MAX_THREADS);
......
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