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

Refactored - split Distortions.java into individual class files

parent 9739c913
...@@ -371,7 +371,7 @@ public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSi ...@@ -371,7 +371,7 @@ public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSi
1,1}; 1,1};
public static Distortions LENS_DISTORTIONS; public static Distortions LENS_DISTORTIONS;
public static Distortions.PatternParameters PATTERN_PARAMETERS=new Distortions.PatternParameters( public static PatternParameters PATTERN_PARAMETERS=new PatternParameters(
viewMap, viewMap,
1, // initial number of stations 1, // initial number of stations
3022.6, // double patternWidth; // pattern full width in mm 3022.6, // double patternWidth; // pattern full width in mm
...@@ -379,10 +379,10 @@ public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSi ...@@ -379,10 +379,10 @@ public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSi
41.6667, // patternHalfPeriod; // distance between opposite sign nodes 41.6667, // patternHalfPeriod; // distance between opposite sign nodes
5.0 // double patternTilt; // pattern tilt (degrees) - U clockwise from X-right (V clockwise from Y-down) 5.0 // double patternTilt; // pattern tilt (degrees) - U clockwise from X-right (V clockwise from Y-down)
); );
// public static Distortions.LensDistortionParameters LENS_DISTORTION_PARAMETERS=new Distortions.LensDistortionParameters( // public static LensDistortionParameters LENS_DISTORTION_PARAMETERS=new LensDistortionParameters(
// public static Distortions.LensDistortionParameters LENS_DISTORTION_PARAMETERS=LENS_DISTORTIONS.new LensDistortionParameters( // public static LensDistortionParameters LENS_DISTORTION_PARAMETERS=LENS_DISTORTIONS.new LensDistortionParameters(
public static Distortions.LensDistortionParameters LENS_DISTORTION_PARAMETERS=(new Distortions()).new LensDistortionParameters( public static LensDistortionParameters LENS_DISTORTION_PARAMETERS=new LensDistortionParameters(
4.5, // double focalLength 4.5, // double focalLength
2.2, // double pixelSize (um) 2.2, // double pixelSize (um)
2.8512, //double distortionRadius mm - half width of the sensor 2.8512, //double distortionRadius mm - half width of the sensor
...@@ -406,7 +406,7 @@ public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSi ...@@ -406,7 +406,7 @@ public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSi
true// boolean flipVertical // acquired image is mirrored vertically (mirror used) true// boolean flipVertical // acquired image is mirrored vertically (mirror used)
); );
// public static double [] defaultGoniometerPosition={0.0, 0.0, 2360}; // public static double [] defaultGoniometerPosition={0.0, 0.0, 2360};
public static Distortions.EyesisCameraParameters EYESIS_CAMERA_PARAMETERS=new Distortions.EyesisCameraParameters( public static EyesisCameraParameters EYESIS_CAMERA_PARAMETERS=new EyesisCameraParameters(
1, //int numStations, 1, //int numStations,
true, //false, // boolean isTripod=false; // when true - make goniometerHorizontal rotation around "vertical" axis and "goniometerAxial" - around true, //false, // boolean isTripod=false; // when true - make goniometerHorizontal rotation around "vertical" axis and "goniometerAxial" - around
0.0, // double goniometerHorizontal, // goniometer rotation around "horizontal" axis (tilting from the target - positive) 0.0, // double goniometerHorizontal, // goniometer rotation around "horizontal" axis (tilting from the target - positive)
...@@ -491,8 +491,8 @@ public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSi ...@@ -491,8 +491,8 @@ public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSi
); );
public static Distortions.RefineParameters REFINE_PARAMETERS = new Distortions.RefineParameters(); public static Distortions.RefineParameters REFINE_PARAMETERS = new Distortions.RefineParameters();
public static Distortions.DistortionCalibrationData DISTORTION_CALIBRATION_DATA=null; public static DistortionCalibrationData DISTORTION_CALIBRATION_DATA=null;
// public static Distortions.FittingStrategy FITTING_STRATEGY=null; // public static FittingStrategy FITTING_STRATEGY=null;
// public static boolean ADVANCED_MODE=false; // public static boolean ADVANCED_MODE=false;
public static boolean ADVANCED_MODE=true; public static boolean ADVANCED_MODE=true;
...@@ -532,7 +532,7 @@ public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSi ...@@ -532,7 +532,7 @@ public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSi
public static CalibrationHardwareInterface.CamerasInterface CAMERAS=new CalibrationHardwareInterface.CamerasInterface(26,LASERS); public static CalibrationHardwareInterface.CamerasInterface CAMERAS=new CalibrationHardwareInterface.CamerasInterface(26,LASERS);
public static CalibrationHardwareInterface.FocusingMotors MOTORS=new CalibrationHardwareInterface.FocusingMotors(); public static CalibrationHardwareInterface.FocusingMotors MOTORS=new CalibrationHardwareInterface.FocusingMotors();
public static Distortions.DistortionProcessConfiguration DISTORTION_PROCESS_CONFIGURATION=new Distortions.DistortionProcessConfiguration(); public static DistortionProcessConfiguration DISTORTION_PROCESS_CONFIGURATION=new DistortionProcessConfiguration();
public static LensAdjustment.FocusMeasurementParameters FOCUS_MEASUREMENT_PARAMETERS= new LensAdjustment.FocusMeasurementParameters(MOTORS.curpos); public static LensAdjustment.FocusMeasurementParameters FOCUS_MEASUREMENT_PARAMETERS= new LensAdjustment.FocusMeasurementParameters(MOTORS.curpos);
public static CalibrationHardwareInterface.GoniometerMotors GONIOMETER_MOTORS= new CalibrationHardwareInterface.GoniometerMotors(); public static CalibrationHardwareInterface.GoniometerMotors GONIOMETER_MOTORS= new CalibrationHardwareInterface.GoniometerMotors();
...@@ -1106,7 +1106,7 @@ if (MORE_BUTTONS) { ...@@ -1106,7 +1106,7 @@ if (MORE_BUTTONS) {
ABERRATIONS_PARAMETERS, ABERRATIONS_PARAMETERS,
LENS_DISTORTIONS, // should be initialized, after update DISTORTION_CALIBRATION_DATA from this LENS_DISTORTIONS, // should be initialized, after update DISTORTION_CALIBRATION_DATA from this
PATTERN_PARAMETERS, PATTERN_PARAMETERS,
EYESIS_CAMERA_PARAMETERS, //Distortions.EyesisCameraParameters eyesisCameraParameters, EYESIS_CAMERA_PARAMETERS, //EyesisCameraParameters eyesisCameraParameters,
UPDATE_STATUS, UPDATE_STATUS,
DEBUG_LEVEL DEBUG_LEVEL
); );
...@@ -2273,8 +2273,8 @@ if (MORE_BUTTONS) { ...@@ -2273,8 +2273,8 @@ if (MORE_BUTTONS) {
" +DISTORTION_CALIBRATION_DATA.eyesisCameraParameters.goniometerHorizontal.length="+DISTORTION_CALIBRATION_DATA.eyesisCameraParameters.goniometerHorizontal.length); " +DISTORTION_CALIBRATION_DATA.eyesisCameraParameters.goniometerHorizontal.length="+DISTORTION_CALIBRATION_DATA.eyesisCameraParameters.goniometerHorizontal.length);
} }
Distortions.DistortionCalibrationData dcd=(DISTORTION_CALIBRATION_DATA!=null)?DISTORTION_CALIBRATION_DATA: DistortionCalibrationData dcd=(DISTORTION_CALIBRATION_DATA!=null)?DISTORTION_CALIBRATION_DATA:
new Distortions.DistortionCalibrationData(EYESIS_CAMERA_PARAMETERS); new DistortionCalibrationData(EYESIS_CAMERA_PARAMETERS);
if (DEBUG_LEVEL>1) System.out.println("+++++++++++ dcd.eyesisCameraParameters.numStations="+dcd.eyesisCameraParameters.numStations+ if (DEBUG_LEVEL>1) System.out.println("+++++++++++ dcd.eyesisCameraParameters.numStations="+dcd.eyesisCameraParameters.numStations+
" +dcd.eyesisCameraParameters.goniometerHorizontal.length="+dcd.eyesisCameraParameters.goniometerHorizontal.length); " +dcd.eyesisCameraParameters.goniometerHorizontal.length="+dcd.eyesisCameraParameters.goniometerHorizontal.length);
dcd.listCameraParameters(); dcd.listCameraParameters();
...@@ -2342,7 +2342,7 @@ if (MORE_BUTTONS) { ...@@ -2342,7 +2342,7 @@ if (MORE_BUTTONS) {
PATTERN_PARAMETERS.debugLevel=MASTER_DEBUG_LEVEL; PATTERN_PARAMETERS.debugLevel=MASTER_DEBUG_LEVEL;
EYESIS_CAMERA_PARAMETERS.updateNumstations (numStations); EYESIS_CAMERA_PARAMETERS.updateNumstations (numStations);
//if (MASTER_DEBUG_LEVEL==0) return; //TODO: Remove - just debugging //if (MASTER_DEBUG_LEVEL==0) return; //TODO: Remove - just debugging
DISTORTION_CALIBRATION_DATA=new Distortions.DistortionCalibrationData( DISTORTION_CALIBRATION_DATA=new DistortionCalibrationData(
gridFiles, gridFiles,
PATTERN_PARAMETERS, PATTERN_PARAMETERS,
EYESIS_CAMERA_PARAMETERS, EYESIS_CAMERA_PARAMETERS,
...@@ -2363,7 +2363,7 @@ if (MORE_BUTTONS) { ...@@ -2363,7 +2363,7 @@ if (MORE_BUTTONS) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL; DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
LENS_DISTORTIONS=new Distortions(LENS_DISTORTION_PARAMETERS,PATTERN_PARAMETERS,REFINE_PARAMETERS); LENS_DISTORTIONS=new Distortions(LENS_DISTORTION_PARAMETERS,PATTERN_PARAMETERS,REFINE_PARAMETERS);
DISTORTION_CALIBRATION_DATA=new Distortions.DistortionCalibrationData(gridFiles,PATTERN_PARAMETERS,EYESIS_CAMERA_PARAMETERS); DISTORTION_CALIBRATION_DATA=new DistortionCalibrationData(gridFiles,PATTERN_PARAMETERS,EYESIS_CAMERA_PARAMETERS);
LENS_DISTORTIONS.initImageSet( LENS_DISTORTIONS.initImageSet(
DISTORTION_CALIBRATION_DATA, DISTORTION_CALIBRATION_DATA,
EYESIS_CAMERA_PARAMETERS EYESIS_CAMERA_PARAMETERS
...@@ -2396,9 +2396,9 @@ if (MORE_BUTTONS) { ...@@ -2396,9 +2396,9 @@ if (MORE_BUTTONS) {
if (label.equals("Restore Calibration")) { if (label.equals("Restore Calibration")) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL; DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
String defaultPath= (DISTORTION_CALIBRATION_DATA!=null)?DISTORTION_CALIBRATION_DATA.pathName:""; String defaultPath= (DISTORTION_CALIBRATION_DATA!=null)?DISTORTION_CALIBRATION_DATA.pathName:"";
// public static Distortions.DistortionCalibrationData DISTORTION_CALIBRATION_DATA=null; // public static DistortionCalibrationData DISTORTION_CALIBRATION_DATA=null;
Distortions.DistortionCalibrationData oldDISTORTION_CALIBRATION_DATA=DISTORTION_CALIBRATION_DATA; DistortionCalibrationData oldDISTORTION_CALIBRATION_DATA=DISTORTION_CALIBRATION_DATA;
DISTORTION_CALIBRATION_DATA=new Distortions.DistortionCalibrationData( DISTORTION_CALIBRATION_DATA=new DistortionCalibrationData(
false, false,
defaultPath, defaultPath,
PATTERN_PARAMETERS, PATTERN_PARAMETERS,
...@@ -2434,7 +2434,7 @@ if (MORE_BUTTONS) { ...@@ -2434,7 +2434,7 @@ if (MORE_BUTTONS) {
} }
LENS_DISTORTIONS.debugLevel=DEBUG_LEVEL; LENS_DISTORTIONS.debugLevel=DEBUG_LEVEL;
if (DEBUG_LEVEL>2) System.out.println("New Strategy"); if (DEBUG_LEVEL>2) System.out.println("New Strategy");
LENS_DISTORTIONS.fittingStrategy=new Distortions.FittingStrategy(DISTORTION_CALIBRATION_DATA); LENS_DISTORTIONS.fittingStrategy=new FittingStrategy(DISTORTION_CALIBRATION_DATA);
LENS_DISTORTIONS.fittingStrategy.debugLevel=DEBUG_LEVEL; LENS_DISTORTIONS.fittingStrategy.debugLevel=DEBUG_LEVEL;
IJ.showMessage("Empty new strategy initialized"); IJ.showMessage("Empty new strategy initialized");
return; return;
...@@ -2457,7 +2457,7 @@ if (MORE_BUTTONS) { ...@@ -2457,7 +2457,7 @@ if (MORE_BUTTONS) {
LENS_DISTORTIONS.debugLevel=DEBUG_LEVEL; LENS_DISTORTIONS.debugLevel=DEBUG_LEVEL;
if (LENS_DISTORTIONS.fittingStrategy==null) { if (LENS_DISTORTIONS.fittingStrategy==null) {
if (DISTORTION_CALIBRATION_DATA==null) return; if (DISTORTION_CALIBRATION_DATA==null) return;
LENS_DISTORTIONS.fittingStrategy=new Distortions.FittingStrategy(DISTORTION_CALIBRATION_DATA); LENS_DISTORTIONS.fittingStrategy=new FittingStrategy(DISTORTION_CALIBRATION_DATA);
} }
LENS_DISTORTIONS.fittingStrategy.debugLevel=DEBUG_LEVEL; LENS_DISTORTIONS.fittingStrategy.debugLevel=DEBUG_LEVEL;
LENS_DISTORTIONS.fittingStrategy.selectStrategy(LENS_DISTORTIONS.seriesNumber); LENS_DISTORTIONS.fittingStrategy.selectStrategy(LENS_DISTORTIONS.seriesNumber);
...@@ -2494,9 +2494,9 @@ if (MORE_BUTTONS) { ...@@ -2494,9 +2494,9 @@ if (MORE_BUTTONS) {
LENS_DISTORTIONS=new Distortions(LENS_DISTORTION_PARAMETERS,PATTERN_PARAMETERS,REFINE_PARAMETERS,this.SYNC_COMMAND.stopRequested); LENS_DISTORTIONS=new Distortions(LENS_DISTORTION_PARAMETERS,PATTERN_PARAMETERS,REFINE_PARAMETERS,this.SYNC_COMMAND.stopRequested);
} }
LENS_DISTORTIONS.debugLevel=DEBUG_LEVEL; LENS_DISTORTIONS.debugLevel=DEBUG_LEVEL;
Distortions.FittingStrategy fs=LENS_DISTORTIONS.fittingStrategy; // save old value FittingStrategy fs=LENS_DISTORTIONS.fittingStrategy; // save old value
String defaultPath= ((fs!=null) && (fs.pathName != null) && (fs.pathName.length()>0)) ? fs.pathName : ""; String defaultPath= ((fs!=null) && (fs.pathName != null) && (fs.pathName.length()>0)) ? fs.pathName : "";
LENS_DISTORTIONS.fittingStrategy=new Distortions.FittingStrategy( LENS_DISTORTIONS.fittingStrategy=new FittingStrategy(
false, false,
defaultPath, defaultPath,
DISTORTION_CALIBRATION_DATA); DISTORTION_CALIBRATION_DATA);
...@@ -3821,7 +3821,7 @@ if (MORE_BUTTONS) { ...@@ -3821,7 +3821,7 @@ if (MORE_BUTTONS) {
if (findCenter){ if (findCenter){
// Read required calibration files // Read required calibration files
// initial calibration // initial calibration
DISTORTION_CALIBRATION_DATA=new Distortions.DistortionCalibrationData( DISTORTION_CALIBRATION_DATA=new DistortionCalibrationData(
true, // skip dialog if file exists true, // skip dialog if file exists
FOCUS_MEASUREMENT_PARAMETERS.initialCalibrationFile, FOCUS_MEASUREMENT_PARAMETERS.initialCalibrationFile,
PATTERN_PARAMETERS, PATTERN_PARAMETERS,
...@@ -3849,7 +3849,7 @@ if (MORE_BUTTONS) { ...@@ -3849,7 +3849,7 @@ if (MORE_BUTTONS) {
} }
LENS_DISTORTIONS.debugLevel=DEBUG_LEVEL; LENS_DISTORTIONS.debugLevel=DEBUG_LEVEL;
LENS_DISTORTIONS.fittingStrategy=new Distortions.FittingStrategy( LENS_DISTORTIONS.fittingStrategy=new FittingStrategy(
true, true,
FOCUS_MEASUREMENT_PARAMETERS.strategyFile, FOCUS_MEASUREMENT_PARAMETERS.strategyFile,
DISTORTION_CALIBRATION_DATA); DISTORTION_CALIBRATION_DATA);
...@@ -3892,7 +3892,7 @@ if (MORE_BUTTONS) { ...@@ -3892,7 +3892,7 @@ if (MORE_BUTTONS) {
if (DEBUG_LEVEL>0) System.out.println("Finished LMA at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3)); if (DEBUG_LEVEL>0) System.out.println("Finished LMA at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
int stationNumber=0; int stationNumber=0;
// Read camera parameters // Read camera parameters
Distortions.EyesisCameraParameters camPars= EyesisCameraParameters camPars=
LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.eyesisCameraParameters; LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.eyesisCameraParameters;
double threadPitch=0.35; // M1.6 double threadPitch=0.35; // M1.6
double dPx0=camPars.eyesisSubCameras[stationNumber][0].px0-(camPars.sensorWidth/2)-FOCUS_MEASUREMENT_PARAMETERS.centerDeltaX; double dPx0=camPars.eyesisSubCameras[stationNumber][0].px0-(camPars.sensorWidth/2)-FOCUS_MEASUREMENT_PARAMETERS.centerDeltaX;
...@@ -5951,7 +5951,7 @@ if (MORE_BUTTONS) { ...@@ -5951,7 +5951,7 @@ if (MORE_BUTTONS) {
CAMERAS, // CalibrationHardwareInterface.CamerasInterface cameras, CAMERAS, // CalibrationHardwareInterface.CamerasInterface cameras,
DISTORTION, //MatchSimulatedPattern.DistortionParameters distortion, DISTORTION, //MatchSimulatedPattern.DistortionParameters distortion,
PATTERN_DETECT, //MatchSimulatedPattern.PatternDetectParameters patternDetectParameters, PATTERN_DETECT, //MatchSimulatedPattern.PatternDetectParameters patternDetectParameters,
EYESIS_CAMERA_PARAMETERS, //Distortions.EyesisCameraParameters eyesisCameraParameters, EYESIS_CAMERA_PARAMETERS, //EyesisCameraParameters eyesisCameraParameters,
LASER_POINTERS, // MatchSimulatedPattern.LaserPointer laserPointers LASER_POINTERS, // MatchSimulatedPattern.LaserPointer laserPointers
SIMUL, //SimulationPattern.SimulParameters simulParametersDefault, SIMUL, //SimulationPattern.SimulParameters simulParametersDefault,
GONIOMETER_PARAMETERS, //LensAdjustment.FocusMeasurementParameters focusMeasurementParameters, GONIOMETER_PARAMETERS, //LensAdjustment.FocusMeasurementParameters focusMeasurementParameters,
...@@ -5982,7 +5982,7 @@ if (MORE_BUTTONS) { ...@@ -5982,7 +5982,7 @@ if (MORE_BUTTONS) {
CAMERAS, // CalibrationHardwareInterface.CamerasInterface cameras, CAMERAS, // CalibrationHardwareInterface.CamerasInterface cameras,
DISTORTION, //MatchSimulatedPattern.DistortionParameters distortion, DISTORTION, //MatchSimulatedPattern.DistortionParameters distortion,
PATTERN_DETECT, //MatchSimulatedPattern.PatternDetectParameters patternDetectParameters, PATTERN_DETECT, //MatchSimulatedPattern.PatternDetectParameters patternDetectParameters,
EYESIS_CAMERA_PARAMETERS, //Distortions.EyesisCameraParameters eyesisCameraParameters, EYESIS_CAMERA_PARAMETERS, //EyesisCameraParameters eyesisCameraParameters,
LASER_POINTERS, // MatchSimulatedPattern.LaserPointer laserPointers LASER_POINTERS, // MatchSimulatedPattern.LaserPointer laserPointers
SIMUL, //SimulationPattern.SimulParameters simulParametersDefault, SIMUL, //SimulationPattern.SimulParameters simulParametersDefault,
GONIOMETER_PARAMETERS, //LensAdjustment.FocusMeasurementParameters focusMeasurementParameters, GONIOMETER_PARAMETERS, //LensAdjustment.FocusMeasurementParameters focusMeasurementParameters,
...@@ -5997,8 +5997,8 @@ if (MORE_BUTTONS) { ...@@ -5997,8 +5997,8 @@ if (MORE_BUTTONS) {
// calculate angular size of the target as visible from the camera // calculate angular size of the target as visible from the camera
/* /*
Distortions.DistortionCalibrationData dcd=(DISTORTION_CALIBRATION_DATA!=null)?DISTORTION_CALIBRATION_DATA: DistortionCalibrationData dcd=(DISTORTION_CALIBRATION_DATA!=null)?DISTORTION_CALIBRATION_DATA:
new Distortions.DistortionCalibrationData(EYESIS_CAMERA_PARAMETERS);*/ new DistortionCalibrationData(EYESIS_CAMERA_PARAMETERS);*/
// double distanceToTarget=dcd.eyesisCameraParameters.GXYZ[2]; // double distanceToTarget=dcd.eyesisCameraParameters.GXYZ[2];
double distanceToTarget=GONIOMETER_PARAMETERS.targetDistance; double distanceToTarget=GONIOMETER_PARAMETERS.targetDistance;
double patternWidth= PATTERN_PARAMETERS.patternWidth; double patternWidth= PATTERN_PARAMETERS.patternWidth;
...@@ -6420,7 +6420,7 @@ if (MORE_BUTTONS) { ...@@ -6420,7 +6420,7 @@ if (MORE_BUTTONS) {
CAMERAS, // CalibrationHardwareInterface.CamerasInterface cameras, CAMERAS, // CalibrationHardwareInterface.CamerasInterface cameras,
DISTORTION, //MatchSimulatedPattern.DistortionParameters distortion, DISTORTION, //MatchSimulatedPattern.DistortionParameters distortion,
PATTERN_DETECT, //MatchSimulatedPattern.PatternDetectParameters patternDetectParameters, PATTERN_DETECT, //MatchSimulatedPattern.PatternDetectParameters patternDetectParameters,
EYESIS_CAMERA_PARAMETERS, //Distortions.EyesisCameraParameters eyesisCameraParameters, EYESIS_CAMERA_PARAMETERS, //EyesisCameraParameters eyesisCameraParameters,
LASER_POINTERS, // MatchSimulatedPattern.LaserPointer laserPointers LASER_POINTERS, // MatchSimulatedPattern.LaserPointer laserPointers
SIMUL, //SimulationPattern.SimulParameters simulParametersDefault, SIMUL, //SimulationPattern.SimulParameters simulParametersDefault,
GONIOMETER_PARAMETERS, //LensAdjustment.FocusMeasurementParameters focusMeasurementParameters, GONIOMETER_PARAMETERS, //LensAdjustment.FocusMeasurementParameters focusMeasurementParameters,
...@@ -6433,7 +6433,7 @@ if (MORE_BUTTONS) { ...@@ -6433,7 +6433,7 @@ if (MORE_BUTTONS) {
System.out.println("GONIOMETER was initialized"); System.out.println("GONIOMETER was initialized");
} }
// initialize needed classes // initialize needed classes
DISTORTION_CALIBRATION_DATA=new Distortions.DistortionCalibrationData( // images are not setup yet DISTORTION_CALIBRATION_DATA=new DistortionCalibrationData( // images are not setup yet
EYESIS_CAMERA_PARAMETERS); //EyesisCameraParameters eyesisCameraParameters EYESIS_CAMERA_PARAMETERS); //EyesisCameraParameters eyesisCameraParameters
if ((LENS_DISTORTIONS!=null) && (LENS_DISTORTIONS.fittingStrategy!=null)) { if ((LENS_DISTORTIONS!=null) && (LENS_DISTORTIONS.fittingStrategy!=null)) {
LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData=DISTORTION_CALIBRATION_DATA; LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData=DISTORTION_CALIBRATION_DATA;
...@@ -6487,8 +6487,8 @@ if (MORE_BUTTONS) { ...@@ -6487,8 +6487,8 @@ if (MORE_BUTTONS) {
// PATTERN_DETECT, //MatchSimulatedPattern.PatternDetectParameters patternDetectParameters, // PATTERN_DETECT, //MatchSimulatedPattern.PatternDetectParameters patternDetectParameters,
// LASER_POINTERS, //MatchSimulatedPattern.LaserPointer laserPointer, // null OK // LASER_POINTERS, //MatchSimulatedPattern.LaserPointer laserPointer, // null OK
// SIMUL, //SimulationPattern.SimulParameters simulParametersDefault, // SIMUL, //SimulationPattern.SimulParameters simulParametersDefault,
DISTORTION_CALIBRATION_DATA, // Distortions.DistortionCalibrationData distortionCalibrationData, DISTORTION_CALIBRATION_DATA, // DistortionCalibrationData distortionCalibrationData,
PATTERN_PARAMETERS, //Distortions.PatternParameters patternParameters, // should not be null PATTERN_PARAMETERS, //PatternParameters patternParameters, // should not be null
LENS_DISTORTIONS, //Distortions lensDistortions, // should not be null LENS_DISTORTIONS, //Distortions lensDistortions, // should not be null
COMPONENTS.equalizeGreens, //boolean equalizeGreens, COMPONENTS.equalizeGreens, //boolean equalizeGreens,
THREADS_MAX, // int threadsMax, THREADS_MAX, // int threadsMax,
...@@ -6519,7 +6519,7 @@ if (MORE_BUTTONS) { ...@@ -6519,7 +6519,7 @@ if (MORE_BUTTONS) {
CAMERAS, // CalibrationHardwareInterface.CamerasInterface cameras, CAMERAS, // CalibrationHardwareInterface.CamerasInterface cameras,
DISTORTION, //MatchSimulatedPattern.DistortionParameters distortion, DISTORTION, //MatchSimulatedPattern.DistortionParameters distortion,
PATTERN_DETECT, //MatchSimulatedPattern.PatternDetectParameters patternDetectParameters, PATTERN_DETECT, //MatchSimulatedPattern.PatternDetectParameters patternDetectParameters,
EYESIS_CAMERA_PARAMETERS, //Distortions.EyesisCameraParameters eyesisCameraParameters, EYESIS_CAMERA_PARAMETERS, //EyesisCameraParameters eyesisCameraParameters,
LASER_POINTERS, // MatchSimulatedPattern.LaserPointer laserPointers LASER_POINTERS, // MatchSimulatedPattern.LaserPointer laserPointers
SIMUL, //SimulationPattern.SimulParameters simulParametersDefault, SIMUL, //SimulationPattern.SimulParameters simulParametersDefault,
GONIOMETER_PARAMETERS, //LensAdjustment.FocusMeasurementParameters focusMeasurementParameters, GONIOMETER_PARAMETERS, //LensAdjustment.FocusMeasurementParameters focusMeasurementParameters,
...@@ -6547,8 +6547,8 @@ if (MORE_BUTTONS) { ...@@ -6547,8 +6547,8 @@ if (MORE_BUTTONS) {
GONIOMETER.testHintedTarget ( GONIOMETER.testHintedTarget (
images, //CAMERAS.getImages(0), // last acquired images with number of pointers detected>=0 images, //CAMERAS.getImages(0), // last acquired images with number of pointers detected>=0
LENS_DISTORTIONS, //Distortions lensDistortions, // should not be null LENS_DISTORTIONS, //Distortions lensDistortions, // should not be null
DISTORTION_CALIBRATION_DATA, // Distortions.DistortionCalibrationData distortionCalibrationData, DISTORTION_CALIBRATION_DATA, // DistortionCalibrationData distortionCalibrationData,
PATTERN_PARAMETERS, //Distortions.PatternParameters patternParameters, // should not be null PATTERN_PARAMETERS, //PatternParameters patternParameters, // should not be null
COMPONENTS.equalizeGreens, //boolean equalizeGreens, COMPONENTS.equalizeGreens, //boolean equalizeGreens,
THREADS_MAX, // int threadsMax, THREADS_MAX, // int threadsMax,
UPDATE_STATUS, //boolean updateStatus, UPDATE_STATUS, //boolean updateStatus,
...@@ -6565,7 +6565,7 @@ if (MORE_BUTTONS) { ...@@ -6565,7 +6565,7 @@ if (MORE_BUTTONS) {
CAMERAS, // CalibrationHardwareInterface.CamerasInterface cameras, CAMERAS, // CalibrationHardwareInterface.CamerasInterface cameras,
DISTORTION, //MatchSimulatedPattern.DistortionParameters distortion, DISTORTION, //MatchSimulatedPattern.DistortionParameters distortion,
PATTERN_DETECT, //MatchSimulatedPattern.PatternDetectParameters patternDetectParameters, PATTERN_DETECT, //MatchSimulatedPattern.PatternDetectParameters patternDetectParameters,
EYESIS_CAMERA_PARAMETERS, //Distortions.EyesisCameraParameters eyesisCameraParameters, EYESIS_CAMERA_PARAMETERS, //EyesisCameraParameters eyesisCameraParameters,
LASER_POINTERS, // MatchSimulatedPattern.LaserPointer laserPointers LASER_POINTERS, // MatchSimulatedPattern.LaserPointer laserPointers
SIMUL, //SimulationPattern.SimulParameters simulParametersDefault, SIMUL, //SimulationPattern.SimulParameters simulParametersDefault,
GONIOMETER_PARAMETERS, //LensAdjustment.FocusMeasurementParameters focusMeasurementParameters, GONIOMETER_PARAMETERS, //LensAdjustment.FocusMeasurementParameters focusMeasurementParameters,
...@@ -6593,8 +6593,8 @@ if (MORE_BUTTONS) { ...@@ -6593,8 +6593,8 @@ if (MORE_BUTTONS) {
GONIOMETER.testHintedTarget ( GONIOMETER.testHintedTarget (
CAMERAS.getImages(0), // last acquired images with number of pointers detected>=0 CAMERAS.getImages(0), // last acquired images with number of pointers detected>=0
LENS_DISTORTIONS, //Distortions lensDistortions, // should not be null LENS_DISTORTIONS, //Distortions lensDistortions, // should not be null
DISTORTION_CALIBRATION_DATA, // Distortions.DistortionCalibrationData distortionCalibrationData, DISTORTION_CALIBRATION_DATA, // DistortionCalibrationData distortionCalibrationData,
PATTERN_PARAMETERS, //Distortions.PatternParameters patternParameters, // should not be null PATTERN_PARAMETERS, //PatternParameters patternParameters, // should not be null
COMPONENTS.equalizeGreens, //boolean equalizeGreens, COMPONENTS.equalizeGreens, //boolean equalizeGreens,
THREADS_MAX, // int threadsMax, THREADS_MAX, // int threadsMax,
UPDATE_STATUS, //boolean updateStatus, UPDATE_STATUS, //boolean updateStatus,
...@@ -10173,8 +10173,8 @@ if (MORE_BUTTONS) { ...@@ -10173,8 +10173,8 @@ if (MORE_BUTTONS) {
public boolean autoLoadFiles( public boolean autoLoadFiles(
EyesisAberrations.AberrationParameters aberrationParameters, EyesisAberrations.AberrationParameters aberrationParameters,
Distortions distortions, // should be initialized, after update DISTORTION_CALIBRATION_DATA from this Distortions distortions, // should be initialized, after update DISTORTION_CALIBRATION_DATA from this
Distortions.PatternParameters patternParameters, PatternParameters patternParameters,
Distortions.EyesisCameraParameters eyesisCameraParameters, EyesisCameraParameters eyesisCameraParameters,
boolean updateStstus, boolean updateStstus,
int debugLevel int debugLevel
){ ){
...@@ -10186,7 +10186,7 @@ if (MORE_BUTTONS) { ...@@ -10186,7 +10186,7 @@ if (MORE_BUTTONS) {
if (configPaths[0]==null) return false; if (configPaths[0]==null) return false;
System.out.println("+++++++++++ autoLoadFiles() eyesisCameraParameters.numStations="+eyesisCameraParameters.numStations+ System.out.println("+++++++++++ autoLoadFiles() eyesisCameraParameters.numStations="+eyesisCameraParameters.numStations+
" +eyesisCameraParameters.goniometerHorizontal.length="+eyesisCameraParameters.goniometerHorizontal.length); " +eyesisCameraParameters.goniometerHorizontal.length="+eyesisCameraParameters.goniometerHorizontal.length);
Distortions.DistortionCalibrationData dcd=new Distortions.DistortionCalibrationData( DistortionCalibrationData dcd=new DistortionCalibrationData(
true, true,
configPaths[0], configPaths[0],
patternParameters, patternParameters,
...@@ -10201,8 +10201,8 @@ if (MORE_BUTTONS) { ...@@ -10201,8 +10201,8 @@ if (MORE_BUTTONS) {
if (configPaths[1]!=null) { if (configPaths[1]!=null) {
Distortions.FittingStrategy fs=distortions.fittingStrategy; // save old value FittingStrategy fs=distortions.fittingStrategy; // save old value
distortions.fittingStrategy=new Distortions.FittingStrategy( distortions.fittingStrategy=new FittingStrategy(
true, // do not ask if specified true, // do not ask if specified
configPaths[1], configPaths[1],
dcd); dcd);
...@@ -10240,7 +10240,7 @@ if (MORE_BUTTONS) { ...@@ -10240,7 +10240,7 @@ if (MORE_BUTTONS) {
boolean alwaysShow, // true overwrites focusMeasurementParameters.showResults boolean alwaysShow, // true overwrites focusMeasurementParameters.showResults
boolean alwaysSave, // true overwrites focusMeasurementParameters.saveResults boolean alwaysSave, // true overwrites focusMeasurementParameters.saveResults
CalibrationHardwareInterface.CamerasInterface camerasInterface, CalibrationHardwareInterface.CamerasInterface camerasInterface,
Distortions.LensDistortionParameters lensDistortionParameters, LensDistortionParameters lensDistortionParameters,
LensAdjustment.FocusMeasurementParameters focusMeasurementParameters, LensAdjustment.FocusMeasurementParameters focusMeasurementParameters,
boolean updateStatus, boolean updateStatus,
int debugLevel int debugLevel
...@@ -10369,7 +10369,7 @@ if (MORE_BUTTONS) { ...@@ -10369,7 +10369,7 @@ if (MORE_BUTTONS) {
double focusTolerance, // will exit after whatever comes first tolearance or number of iterations double focusTolerance, // will exit after whatever comes first tolearance or number of iterations
CalibrationHardwareInterface.FocusingMotors focusingMotors, CalibrationHardwareInterface.FocusingMotors focusingMotors,
CalibrationHardwareInterface.CamerasInterface camerasInterface, CalibrationHardwareInterface.CamerasInterface camerasInterface,
Distortions.LensDistortionParameters lensDistortionParameters, LensDistortionParameters lensDistortionParameters,
MatchSimulatedPattern matchSimulatedPattern, // should not bee null MatchSimulatedPattern matchSimulatedPattern, // should not bee null
LensAdjustment.FocusMeasurementParameters focusMeasurementParameters, LensAdjustment.FocusMeasurementParameters focusMeasurementParameters,
MatchSimulatedPattern.PatternDetectParameters patternDetectParameters, MatchSimulatedPattern.PatternDetectParameters patternDetectParameters,
...@@ -10471,7 +10471,7 @@ if (MORE_BUTTONS) { ...@@ -10471,7 +10471,7 @@ if (MORE_BUTTONS) {
int numIterations, // maximal number of iterations (0 - suggest only, do not move). When calling from the button - first time single iteration, second time - as specified int numIterations, // maximal number of iterations (0 - suggest only, do not move). When calling from the button - first time single iteration, second time - as specified
CalibrationHardwareInterface.FocusingMotors focusingMotors, CalibrationHardwareInterface.FocusingMotors focusingMotors,
CalibrationHardwareInterface.CamerasInterface camerasInterface, CalibrationHardwareInterface.CamerasInterface camerasInterface,
Distortions.LensDistortionParameters lensDistortionParameters, LensDistortionParameters lensDistortionParameters,
MatchSimulatedPattern matchSimulatedPattern, // should not bee null MatchSimulatedPattern matchSimulatedPattern, // should not bee null
LensAdjustment.FocusMeasurementParameters focusMeasurementParameters, LensAdjustment.FocusMeasurementParameters focusMeasurementParameters,
MatchSimulatedPattern.PatternDetectParameters patternDetectParameters, MatchSimulatedPattern.PatternDetectParameters patternDetectParameters,
...@@ -10661,7 +10661,7 @@ if (MORE_BUTTONS) { ...@@ -10661,7 +10661,7 @@ if (MORE_BUTTONS) {
int numIterations, // maximal number of iterations (0 - suggest only, do not move). When calling from the button - first time single iteration, second time - as specified int numIterations, // maximal number of iterations (0 - suggest only, do not move). When calling from the button - first time single iteration, second time - as specified
CalibrationHardwareInterface.FocusingMotors focusingMotors, CalibrationHardwareInterface.FocusingMotors focusingMotors,
CalibrationHardwareInterface.CamerasInterface camerasInterface, CalibrationHardwareInterface.CamerasInterface camerasInterface,
Distortions.LensDistortionParameters lensDistortionParameters, LensDistortionParameters lensDistortionParameters,
MatchSimulatedPattern matchSimulatedPattern, // should not bee null MatchSimulatedPattern matchSimulatedPattern, // should not bee null
LensAdjustment.FocusMeasurementParameters focusMeasurementParameters, LensAdjustment.FocusMeasurementParameters focusMeasurementParameters,
MatchSimulatedPattern.PatternDetectParameters patternDetectParameters, MatchSimulatedPattern.PatternDetectParameters patternDetectParameters,
...@@ -10869,7 +10869,7 @@ if (MORE_BUTTONS) { ...@@ -10869,7 +10869,7 @@ if (MORE_BUTTONS) {
int numIterations, // maximal number of iterations (0 - suggest only, do not move). When calling from the button - first time single iteration, second time - as specified int numIterations, // maximal number of iterations (0 - suggest only, do not move). When calling from the button - first time single iteration, second time - as specified
CalibrationHardwareInterface.FocusingMotors focusingMotors, CalibrationHardwareInterface.FocusingMotors focusingMotors,
CalibrationHardwareInterface.CamerasInterface camerasInterface, CalibrationHardwareInterface.CamerasInterface camerasInterface,
Distortions.LensDistortionParameters lensDistortionParameters, LensDistortionParameters lensDistortionParameters,
MatchSimulatedPattern matchSimulatedPattern, // should not bee null MatchSimulatedPattern matchSimulatedPattern, // should not bee null
LensAdjustment.FocusMeasurementParameters focusMeasurementParameters, LensAdjustment.FocusMeasurementParameters focusMeasurementParameters,
MatchSimulatedPattern.PatternDetectParameters patternDetectParameters, MatchSimulatedPattern.PatternDetectParameters patternDetectParameters,
...@@ -10979,7 +10979,7 @@ if (MORE_BUTTONS) { ...@@ -10979,7 +10979,7 @@ if (MORE_BUTTONS) {
int numIterations, // maximal number of iterations (0 - suggest only, do not move). When calling from the button - first time single iteration, second time - as specified int numIterations, // maximal number of iterations (0 - suggest only, do not move). When calling from the button - first time single iteration, second time - as specified
CalibrationHardwareInterface.FocusingMotors focusingMotors, CalibrationHardwareInterface.FocusingMotors focusingMotors,
CalibrationHardwareInterface.CamerasInterface camerasInterface, CalibrationHardwareInterface.CamerasInterface camerasInterface,
Distortions.LensDistortionParameters lensDistortionParameters, LensDistortionParameters lensDistortionParameters,
MatchSimulatedPattern matchSimulatedPattern, // should not bee null MatchSimulatedPattern matchSimulatedPattern, // should not bee null
LensAdjustment.FocusMeasurementParameters focusMeasurementParameters, LensAdjustment.FocusMeasurementParameters focusMeasurementParameters,
boolean updateStatus, boolean updateStatus,
...@@ -11052,7 +11052,7 @@ if (MORE_BUTTONS) { ...@@ -11052,7 +11052,7 @@ if (MORE_BUTTONS) {
int [] centerMotorPos, // null OK int [] centerMotorPos, // null OK
CalibrationHardwareInterface.FocusingMotors focusingMotors, CalibrationHardwareInterface.FocusingMotors focusingMotors,
CalibrationHardwareInterface.CamerasInterface camerasInterface, CalibrationHardwareInterface.CamerasInterface camerasInterface,
Distortions.LensDistortionParameters lensDistortionParameters, LensDistortionParameters lensDistortionParameters,
MatchSimulatedPattern matchSimulatedPattern, // should not bee null MatchSimulatedPattern matchSimulatedPattern, // should not bee null
LensAdjustment.FocusMeasurementParameters focusMeasurementParameters, LensAdjustment.FocusMeasurementParameters focusMeasurementParameters,
MatchSimulatedPattern.PatternDetectParameters patternDetectParameters, MatchSimulatedPattern.PatternDetectParameters patternDetectParameters,
...@@ -11384,7 +11384,7 @@ if (MORE_BUTTONS) { ...@@ -11384,7 +11384,7 @@ if (MORE_BUTTONS) {
int [] centerMotorPos, // null OK int [] centerMotorPos, // null OK
CalibrationHardwareInterface.FocusingMotors focusingMotors, CalibrationHardwareInterface.FocusingMotors focusingMotors,
CalibrationHardwareInterface.CamerasInterface camerasInterface, CalibrationHardwareInterface.CamerasInterface camerasInterface,
Distortions.LensDistortionParameters lensDistortionParameters, LensDistortionParameters lensDistortionParameters,
MatchSimulatedPattern matchSimulatedPattern, // should not bee null MatchSimulatedPattern matchSimulatedPattern, // should not bee null
LensAdjustment.FocusMeasurementParameters focusMeasurementParameters, LensAdjustment.FocusMeasurementParameters focusMeasurementParameters,
MatchSimulatedPattern.PatternDetectParameters patternDetectParameters, MatchSimulatedPattern.PatternDetectParameters patternDetectParameters,
...@@ -11514,7 +11514,7 @@ if (MORE_BUTTONS) { ...@@ -11514,7 +11514,7 @@ if (MORE_BUTTONS) {
int [] newMotorPos, // null OK int [] newMotorPos, // null OK
CalibrationHardwareInterface.FocusingMotors focusingMotors, CalibrationHardwareInterface.FocusingMotors focusingMotors,
CalibrationHardwareInterface.CamerasInterface camerasInterface, CalibrationHardwareInterface.CamerasInterface camerasInterface,
Distortions.LensDistortionParameters lensDistortionParameters, LensDistortionParameters lensDistortionParameters,
MatchSimulatedPattern matchSimulatedPattern, // should not bee null MatchSimulatedPattern matchSimulatedPattern, // should not bee null
LensAdjustment.FocusMeasurementParameters focusMeasurementParameters, LensAdjustment.FocusMeasurementParameters focusMeasurementParameters,
MatchSimulatedPattern.PatternDetectParameters patternDetectParameters, MatchSimulatedPattern.PatternDetectParameters patternDetectParameters,
...@@ -11555,7 +11555,7 @@ if (MORE_BUTTONS) { ...@@ -11555,7 +11555,7 @@ if (MORE_BUTTONS) {
int [] newMotorPos, // null OK int [] newMotorPos, // null OK
CalibrationHardwareInterface.FocusingMotors focusingMotors, CalibrationHardwareInterface.FocusingMotors focusingMotors,
CalibrationHardwareInterface.CamerasInterface camerasInterface, CalibrationHardwareInterface.CamerasInterface camerasInterface,
Distortions.LensDistortionParameters lensDistortionParameters, LensDistortionParameters lensDistortionParameters,
MatchSimulatedPattern matchSimulatedPattern, // should not bee null MatchSimulatedPattern matchSimulatedPattern, // should not bee null
LensAdjustment.FocusMeasurementParameters focusMeasurementParameters, LensAdjustment.FocusMeasurementParameters focusMeasurementParameters,
MatchSimulatedPattern.PatternDetectParameters patternDetectParameters, MatchSimulatedPattern.PatternDetectParameters patternDetectParameters,
...@@ -11721,7 +11721,7 @@ if (MORE_BUTTONS) { ...@@ -11721,7 +11721,7 @@ if (MORE_BUTTONS) {
int [] newMotorPos, // null OK int [] newMotorPos, // null OK
CalibrationHardwareInterface.FocusingMotors focusingMotors, CalibrationHardwareInterface.FocusingMotors focusingMotors,
CalibrationHardwareInterface.CamerasInterface camerasInterface, CalibrationHardwareInterface.CamerasInterface camerasInterface,
Distortions.LensDistortionParameters lensDistortionParameters, LensDistortionParameters lensDistortionParameters,
MatchSimulatedPattern matchSimulatedPattern, // should not bee null MatchSimulatedPattern matchSimulatedPattern, // should not bee null
LensAdjustment.FocusMeasurementParameters focusMeasurementParameters, LensAdjustment.FocusMeasurementParameters focusMeasurementParameters,
MatchSimulatedPattern.PatternDetectParameters patternDetectParameters, MatchSimulatedPattern.PatternDetectParameters patternDetectParameters,
...@@ -11815,7 +11815,7 @@ if (MORE_BUTTONS) { ...@@ -11815,7 +11815,7 @@ if (MORE_BUTTONS) {
int [] newMotorPos, // null OK int [] newMotorPos, // null OK
CalibrationHardwareInterface.FocusingMotors focusingMotors, CalibrationHardwareInterface.FocusingMotors focusingMotors,
CalibrationHardwareInterface.CamerasInterface camerasInterface, CalibrationHardwareInterface.CamerasInterface camerasInterface,
Distortions.LensDistortionParameters lensDistortionParameters, LensDistortionParameters lensDistortionParameters,
MatchSimulatedPattern matchSimulatedPattern, // should not bee null MatchSimulatedPattern matchSimulatedPattern, // should not bee null
LensAdjustment.FocusMeasurementParameters focusMeasurementParameters, LensAdjustment.FocusMeasurementParameters focusMeasurementParameters,
MatchSimulatedPattern.PatternDetectParameters patternDetectParameters, MatchSimulatedPattern.PatternDetectParameters patternDetectParameters,
...@@ -11984,7 +11984,7 @@ if (MORE_BUTTONS) { ...@@ -11984,7 +11984,7 @@ if (MORE_BUTTONS) {
int [] newMotorPos, // null OK int [] newMotorPos, // null OK
CalibrationHardwareInterface.FocusingMotors focusingMotors, CalibrationHardwareInterface.FocusingMotors focusingMotors,
CalibrationHardwareInterface.CamerasInterface camerasInterface, CalibrationHardwareInterface.CamerasInterface camerasInterface,
Distortions.LensDistortionParameters lensDistortionParameters, LensDistortionParameters lensDistortionParameters,
MatchSimulatedPattern matchSimulatedPattern, // should not bee null MatchSimulatedPattern matchSimulatedPattern, // should not bee null
LensAdjustment.FocusMeasurementParameters focusMeasurementParameters, LensAdjustment.FocusMeasurementParameters focusMeasurementParameters,
boolean updateStatus, boolean updateStatus,
...@@ -12049,7 +12049,7 @@ if (MORE_BUTTONS) { ...@@ -12049,7 +12049,7 @@ if (MORE_BUTTONS) {
public double [][] measurePSFMetrics( public double [][] measurePSFMetrics(
ImagePlus imp_sel, ImagePlus imp_sel,
Distortions.LensDistortionParameters lensDistortionParameters, LensDistortionParameters lensDistortionParameters,
MatchSimulatedPattern matchSimulatedPattern, MatchSimulatedPattern matchSimulatedPattern,
LensAdjustment.FocusMeasurementParameters focusMeasurementParameters, LensAdjustment.FocusMeasurementParameters focusMeasurementParameters,
MatchSimulatedPattern.PatternDetectParameters patternDetectParameters, MatchSimulatedPattern.PatternDetectParameters patternDetectParameters,
......
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
**
** DistortionProcessConfiguration.java
**
** Copyright (C) 2011-2014 Elphel, Inc.
**
** -----------------------------------------------------------------------------**
**
** DistortionProcessConfiguration.java is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
** -----------------------------------------------------------------------------**
**
*/
import ij.IJ;
import ij.Prefs;
import ij.gui.GenericDialog;
import java.io.File;
import java.util.Properties;
public class DistortionProcessConfiguration{
public String sourceDirectory="";
public String gridDirectory= "";
public boolean useLaserPonters=true;
public boolean useNoPonters=true; // use images that do not have any lasre pointers
public boolean showAcquiredImages=true;
public boolean saveAcquiredImages=true;
public boolean selectSourceFiles = true;
public boolean removeOutOfGridPointers=true;
public boolean showGridImages=false;
public boolean saveGridImages=true;
public boolean overwriteResultFiles=false;
public int debugLevel=1;
public String selectSourceDirectory(boolean smart, String defaultPath, boolean newAllowed) {
String dir= CalibrationFileManagement.selectDirectory(
smart,
newAllowed, // save
"Source (acquired from the camera) image directory", // title
"Select source directory", // button
null, // filter
defaultPath); // this.sourceDirectory);
if (dir!=null) this.sourceDirectory=dir;
return dir;
}
public String selectGridFileDirectory(boolean smart, String defaultPath, boolean newAllowed) {
String dir= CalibrationFileManagement.selectDirectory(
smart,
newAllowed, // save
"Grid files directory (grid patterns extracted from the images)", // title
"Select grid files directory", // button
null, // filter
defaultPath); //this.sourceDirectory);
if (dir!=null) this.gridDirectory=dir;
return dir;
}
public void setProperties(String prefix,Properties properties){
properties.setProperty(prefix+"sourceDirectory", this.sourceDirectory);
properties.setProperty(prefix+"gridDirectory", this.gridDirectory);
properties.setProperty(prefix+"useLaserPonters", this.useLaserPonters+"");
properties.setProperty(prefix+"useNoPonters", this.useNoPonters+"");
properties.setProperty(prefix+"showAcquiredImages", this.showAcquiredImages+"");
properties.setProperty(prefix+"saveAcquiredImages", this.saveAcquiredImages+"");
properties.setProperty(prefix+"selectSourceFiles", this.selectSourceFiles+"");
properties.setProperty(prefix+"removeOutOfGridPointers",this.removeOutOfGridPointers+"");
properties.setProperty(prefix+"showGridImages", this.showGridImages+"");
properties.setProperty(prefix+"saveGridImages", this.saveGridImages+"");
properties.setProperty(prefix+"overwriteResultFiles", this.overwriteResultFiles+"");
properties.setProperty(prefix+"debugLevel", this.debugLevel+"");
}
public void getProperties(String prefix,Properties properties){
if (properties.getProperty(prefix+"sourceDirectory")!=null)
this.sourceDirectory=properties.getProperty(prefix+"sourceDirectory");
if (properties.getProperty(prefix+"gridDirectory")!=null)
this.gridDirectory=properties.getProperty(prefix+"gridDirectory");
if (properties.getProperty(prefix+"useLaserPonters")!=null)
this.useLaserPonters=Boolean.parseBoolean(properties.getProperty(prefix+"useLaserPonters"));
if (properties.getProperty(prefix+"useNoPonters")!=null)
this.useNoPonters=Boolean.parseBoolean(properties.getProperty(prefix+"useNoPonters"));
if (properties.getProperty(prefix+"showAcquiredImages")!=null)
this.showAcquiredImages=Boolean.parseBoolean(properties.getProperty(prefix+"showAcquiredImages"));
if (properties.getProperty(prefix+"saveAcquiredImages")!=null)
this.saveAcquiredImages=Boolean.parseBoolean(properties.getProperty(prefix+"saveAcquiredImages"));
if (properties.getProperty(prefix+"selectSourceFiles")!=null)
this.selectSourceFiles=Boolean.parseBoolean(properties.getProperty(prefix+"selectSourceFiles"));
if (properties.getProperty(prefix+"removeOutOfGridPointers")!=null)
this.removeOutOfGridPointers=Boolean.parseBoolean(properties.getProperty(prefix+"removeOutOfGridPointers"));
if (properties.getProperty(prefix+"showGridImages")!=null)
this.showGridImages=Boolean.parseBoolean(properties.getProperty(prefix+"showGridImages"));
if (properties.getProperty(prefix+"saveGridImages")!=null)
this.saveGridImages=Boolean.parseBoolean(properties.getProperty(prefix+"saveGridImages"));
if (properties.getProperty(prefix+"overwriteResultFiles")!=null)
this.overwriteResultFiles=Boolean.parseBoolean(properties.getProperty(prefix+"overwriteResultFiles"));
if (properties.getProperty(prefix+"debugLevel")!=null)
this.debugLevel=Integer.parseInt(properties.getProperty(prefix+"debugLevel"));
}
public boolean showDialog(String title) {
GenericDialog gd = new GenericDialog(title);
gd.addStringField("Source (acquired from the camera) image directory, blank will open selection window",this.sourceDirectory,40);
gd.addStringField("Grid files directory (grid patterns extracted from the images, blank will open selection window)",this.gridDirectory,40);
gd.addCheckbox ("Locate laser pointers for each image", this.useLaserPonters);
gd.addCheckbox ("Use images that do not contain laser pointers", this.useLaserPonters);
gd.addCheckbox ("Show images after acquisition", this.showAcquiredImages);
gd.addCheckbox ("Save acquired images", this.saveAcquiredImages);
gd.addCheckbox ("Individually select source image (false use all directory)", this.selectSourceFiles);
gd.addCheckbox ("Remove detected laser pointers if they are outside of the grid", this.removeOutOfGridPointers);
gd.addCheckbox ("Show grid files as images", this.showGridImages);
gd.addCheckbox ("Save grid files", this.saveGridImages);
gd.addCheckbox ("Overwrite existing result files", this.overwriteResultFiles);
gd.addNumericField("Debug level", this.debugLevel,0);
WindowTools.addScrollBars(gd);
gd.showDialog();
if (gd.wasCanceled()) return false;
String newSourceDirectory= gd.getNextString();
String newGridDirectory= gd.getNextString();
this.useLaserPonters= gd.getNextBoolean();
this.useLaserPonters= gd.getNextBoolean();
this.showAcquiredImages= gd.getNextBoolean();
this.saveAcquiredImages= gd.getNextBoolean();
this.selectSourceFiles= gd.getNextBoolean();
this.removeOutOfGridPointers=gd.getNextBoolean();
this.showGridImages= gd.getNextBoolean();
this.saveGridImages= gd.getNextBoolean();
this.overwriteResultFiles= gd.getNextBoolean();
this.debugLevel= (int) gd.getNextNumber();
System.out.println("1.newSourceDirectory = "+newSourceDirectory);
System.out.println("1.newGridDirectory = "+ newGridDirectory);
if ((newSourceDirectory.length()==0) || (newSourceDirectory.indexOf('?')>=0))
newSourceDirectory= selectSourceDirectory(false, this.sourceDirectory, true);
else
newSourceDirectory= selectSourceDirectory(true, newSourceDirectory, true); // if matches, no dialog
if (newSourceDirectory!=null) this.sourceDirectory=newSourceDirectory;
if ((newGridDirectory.length()==0) || (newGridDirectory.indexOf('?')>=0))
newGridDirectory= selectGridFileDirectory(false, this.gridDirectory, true);
else
newGridDirectory= selectGridFileDirectory(true, newGridDirectory, true);
if (newGridDirectory!=null) this.gridDirectory=newGridDirectory;
// System.out.println("2.newSourceDirectory = "+newSourceDirectory);
// System.out.println("2.newGridDirectory = "+ newGridDirectory);
// System.out.println("this.sourceDirectory = "+this.sourceDirectory);
// System.out.println("this.gridDirectory = "+ this.gridDirectory);
return true;
}
public String [] selectSourceFiles(){
return selectSourceFiles(!this.selectSourceFiles);
}
public String [] selectSourceFiles(boolean allFiles){
String [] extensions={".tif",".tiff"};
if (this.sourceDirectory.length()==0){
String newSourceDirectory= selectSourceDirectory(true, this.sourceDirectory, true);
if (newSourceDirectory!=null) this.sourceDirectory=newSourceDirectory;
}
String [] defaultPaths={this.sourceDirectory+Prefs.getFileSeparator()};
if (this.sourceDirectory.length()==0){
defaultPaths[0]="";
}
CalibrationFileManagement.MultipleExtensionsFileFilter sourceFilter =
new CalibrationFileManagement.MultipleExtensionsFileFilter("",extensions,"Source files");
String [] sourceFiles=null;
if (allFiles){
File dir= new File (this.sourceDirectory);
if (this.debugLevel>1) System.out.println("selectSourceFiles, dir="+this.sourceDirectory);
if (!dir.exists()) {
String error="Source directory "+this.sourceDirectory+" does not exist.";
IJ.showMessage("No files selected");
if (this.debugLevel>1) System.out.println("selectSourceFiles() ERROR:"+error);
return null;
}
File [] fileList=dir.listFiles(sourceFilter);
if (this.debugLevel>1) System.out.println("Source directory "+this.sourceDirectory+" has "+fileList.length+" files.");
sourceFiles = new String[fileList.length];
for (int i=0;i<sourceFiles.length;i++) sourceFiles[i]=fileList[i].getPath();
} else {
new CalibrationFileManagement.MultipleExtensionsFileFilter("",extensions,"Source files");
sourceFiles=CalibrationFileManagement.selectFiles(false,
"Select Source files, saved as TIFF",
"Select",
sourceFilter,
defaultPaths); // String [] defaultPaths); //this.sourceDirectory // null
if ((sourceFiles==null) || (sourceFiles.length==0)) {
if (this.debugLevel>1) System.out.println("selectSourceFiles() ERROR: No files selected");
IJ.showMessage("No files selected");
return null;
}
}
return sourceFiles;
}
}
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -972,7 +972,7 @@ public class EyesisAberrations { ...@@ -972,7 +972,7 @@ public class EyesisAberrations {
public String [][] preparePartialKernelsFilesList( public String [][] preparePartialKernelsFilesList(
int debugLevel){ int debugLevel){
Distortions.DistortionCalibrationData distortionCalibrationData= distortions.fittingStrategy.distortionCalibrationData; DistortionCalibrationData distortionCalibrationData= distortions.fittingStrategy.distortionCalibrationData;
boolean [] selectedImages=distortions.fittingStrategy.selectedImagesNoBadKernels(this.aberrationParameters.allImages?-1:this.aberrationParameters.seriesNumber); // negative series number OK - will select all enabled boolean [] selectedImages=distortions.fittingStrategy.selectedImagesNoBadKernels(this.aberrationParameters.allImages?-1:this.aberrationParameters.seriesNumber); // negative series number OK - will select all enabled
int num=0; int num=0;
for (int imgNum=0;imgNum<selectedImages.length;imgNum++) if (selectedImages[imgNum]) num++; for (int imgNum=0;imgNum<selectedImages.length;imgNum++) if (selectedImages[imgNum]) num++;
...@@ -1072,7 +1072,7 @@ public class EyesisAberrations { ...@@ -1072,7 +1072,7 @@ public class EyesisAberrations {
int loopDebugLevel, // debug level used inside loops int loopDebugLevel, // debug level used inside loops
int debugLevel int debugLevel
){ ){
Distortions.DistortionCalibrationData distortionCalibrationData= distortions.fittingStrategy.distortionCalibrationData; DistortionCalibrationData distortionCalibrationData= distortions.fittingStrategy.distortionCalibrationData;
boolean partialToReprojected=this.aberrationParameters.partialToReprojected; boolean partialToReprojected=this.aberrationParameters.partialToReprojected;
boolean applySensorCorrection=this.aberrationParameters.partialCorrectSensor; boolean applySensorCorrection=this.aberrationParameters.partialCorrectSensor;
// this.distortions is set to top level LENS_DISTORTIONS // this.distortions is set to top level LENS_DISTORTIONS
......
/*
**
** EyesisCameraParameters.java
**
** Copyright (C) 2011-2014 Elphel, Inc.
**
** -----------------------------------------------------------------------------**
**
** EyesisCameraParameters.java is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
** -----------------------------------------------------------------------------**
**
*/
import ij.gui.GenericDialog;
import java.util.Properties;
import org.apache.commons.configuration.XMLConfiguration;
public class EyesisCameraParameters{
public double [] goniometerHorizontal; // goniometer rotation around "horizontal" axis (tilting from the target - positive)
public double [] goniometerAxial; // goniometer rotation around Eyesis axis (clockwise in plan - positive
public EyesisSubCameraParameters [][] eyesisSubCameras=null;
public double [] interAxisDistance; // distance in mm between two goniometer axes
public double [] interAxisAngle; // angle in degrees between two goniometer axes minus 90. negative if "vertical" axis is rotated
// clockwise when eyesis is in 'normal' position, looking to the target
public double [] horAxisErrPhi; // angle in degrees "horizontal" goniometer axis is rotated around target Y axis from target X axis (CW)
public double [] horAxisErrPsi; // angle in degrees "horizontal" goniometer axis is rotated around moving X axis (up)
public double [] entrancePupilForward; // common to all lenses - distance from the sensor to the lens entrance pupil
public double [] centerAboveHorizontal; // camera center distance along camera axis above the closest point to horizontal rotation axis (adds to height of each SFE)
public double [][] GXYZ=null; // [numStations]{x,y,z} coordinates (in mm) of the goniometer horizontal axis closest to the moving one in target system
// non-adjustable parameters, not parts of vector
public int numStations;
public double [] stationWeight; // reprojection error weights (close station - relax errors)
public boolean isTripod=false; // when true - make goniometerHorizontal rotation around "vertical" axis and "goniometerAxial" - around
// rotated horizontal.
public int sensorWidth= 2592;
public int sensorHeight= 1936;
public int shrinkGridForMask=4; //2; //shrink detected grids by one point for/vert this number of times before calculating masks
public double maskBlurSigma= -3; //2.0; // blur sensor masks (>0 - pixels, <0 - in grid units)
public int decimateMasks= 1;
public double badNodeThreshold=0.1; // filter out grid nodes with difference from quadratically predicted from 8 neighbors in pixels
public int maxBadNeighb= 1; // maximal number of bad nodes around the corrected one to fix
public int minimalValidNodes=50; // do not use images with less than this number of non-zero nodes (after all applicable weight masks)
public int weightMultiImageMode=1; // increase weight for multi-image sets (0 - do not increase, 1 - multiply by number of images in a set to weightMultiExponent power)
public double weightMultiExponent= 1.0;
public double weightDiameterExponent=1.0; // if( >0) use grid diameter to scale weights of this image
public double weightYtoX=1.0; // relative Y-to-X errors weight (to somewhat compensate for rectabular shape of the sensor)
public double minimalGridContrast=0.4; // (normally max ~0.8)
public double shrinkBlurSigma = 4.0;
public double shrinkBlurLevel = 0.5;
public double balanceChannelWeightsMode=-1.0; // <0 - use defaults, 0 - keep, >0 balance by number of points to this power
public double removeOverRMS=2.0; // error is multiplied by weight function before comparison (more permissive on the borders
public double removeOverRMSNonweighted=4.0; // error is not multiplied (no more permissions on tyhe borders
public int [] extrinsicIndices={6,7,8,9,10,11,12,13,14,15,16}; //support variations
public double [][] variationsDefaults={
null, // 0
null, // 1
null, // 2
null, // 3
null, // 4
null, // 5
{10.0,0.1,0.0,1.0}, // 6 goniometerHorizontal
{10.0,0.1,0.0,1.0}, // 7 goniometerAxial
{10.0,2.0,0.0,1.0}, // 8 interAxisDistance
{10.0,0.2,0.0,1.0}, // 9 interAxisAngle
{10.0,0.2,0.0,1.0}, // 10 horAxisErrPhi
{10.0,0.2,0.0,1.0}, // 11 horAxisErrPsi
{10.0,2.0,0.0,1.0}, // 12 entrancePupilForward
{10.0,2.0,0.0,1.0}, // 13 centerAboveHorizontal
{10.0,2.0,0.0,1.0}, // 14 GXYZ0
{10.0,2.0,0.0,1.0}, // 15 GXYZ1
{10.0,2.0,0.0,1.0} // 16 GXYZ2
};
public int tiltIndex=6;
private ParameterVariationCosts [] parameterVariationCosts=null;
public boolean isExtrinsic (int index){
for (int i=0;i<this.extrinsicIndices.length; i++) if (this.extrinsicIndices[i]==index) return true;
return false;
}
public boolean isTilt (int index){
return (index==this.tiltIndex);
}
public boolean isVarianceCostSet(int index){
return (parameterVariationCosts!=null) && (index< parameterVariationCosts.length) && (parameterVariationCosts[index]!=null);
}
public double varianceCostScale(int index){
if (!isVarianceCostSet(index)) return -1.0;
return parameterVariationCosts[index].scale;
}
public double varianceCostVariationAbs(int index){
if (!isVarianceCostSet(index)) return -1.0;
return parameterVariationCosts[index].variationAbs;
}
public double varianceCostVariationDiff(int index){
if (!isVarianceCostSet(index)) return -1.0;
return parameterVariationCosts[index].variationDiff;
}
public double varianceCostVariationExponent(int index){
if (!isVarianceCostSet(index)) return -1.0;
return parameterVariationCosts[index].exponent;
}
public String varianceCostVariationName(int index){
if (!isVarianceCostSet(index)) return null;
return parameterVariationCosts[index].parName;
}
public int getVarParsLength(){
return parameterVariationCosts.length;
}
public boolean editCostProperties(
int index,
String parameterName,
String parameterDescription,
String parameterUnits) {
if (!isExtrinsic(index)) return false; // does not have varaince parameters
getVariationCosts();
if (parameterVariationCosts[index]==null) parameterVariationCosts[index]=new ParameterVariationCosts(
this.variationsDefaults[index][0],
this.variationsDefaults[index][1],
this.variationsDefaults[index][2],
this.variationsDefaults[index][3]);
return parameterVariationCosts[index].showVarianceDialog(
parameterName,
parameterDescription,
parameterUnits);
}
private ParameterVariationCosts [] getVariationCosts(){
if (this.parameterVariationCosts==null){
int max=0;
for (int i=0;i<this.extrinsicIndices.length; i++) if (this.extrinsicIndices[i]>max) max=this.extrinsicIndices[i];
this.parameterVariationCosts=new ParameterVariationCosts [max+1];
for (int i=0;i<this.parameterVariationCosts.length;i++) this.parameterVariationCosts[i]=null;
}
return this.parameterVariationCosts;
}
public void getCostsPropertiesXML(String prefix,XMLConfiguration hConfig){
getVariationCosts();
for (int i=0;i<this.extrinsicIndices.length;i++){
int index=this.extrinsicIndices[i];
// System.out.println("getCostsPropertiesXML("+prefix+",hconfig) index="+index);
if (hConfig.configurationsAt(prefix+"varianceCosts_"+index).size()!=0){
// System.out.println("hConfig.configurationAt(prefix+\"varianceCosts_\"+index).isEmpty()=false");
this.parameterVariationCosts[index]=new ParameterVariationCosts(
this.variationsDefaults[index][0],
this.variationsDefaults[index][1],
this.variationsDefaults[index][2],
this.variationsDefaults[index][3]);
boolean isSet= this.parameterVariationCosts[index].getPropertiesXML(prefix+"varianceCosts_"+index+".", hConfig);
if (!isSet) this.parameterVariationCosts[index]=null;
}
}
}
public void setCostsPropertiesXML(String prefix,XMLConfiguration hConfig){
if (this.parameterVariationCosts==null) return;
for (int i=0;i<this.extrinsicIndices.length;i++){
int index=this.extrinsicIndices[i];
if (this.parameterVariationCosts[index]!=null) {
hConfig.addProperty(prefix+"varianceCosts_"+index,"");
this.parameterVariationCosts[index].setPropertiesXML(prefix+"varianceCosts_"+index+".", hConfig);
}
}
}
private class ParameterVariationCosts{
public double scale = 1.0; // 1 pixel
public double variationAbs =0.0; // variation of the parameter to cost 1 pixel
public double variationDiff =0.0; // variation of the parameter to cost 1 pixel
public double exponent= 1.0; // 1.0 - square diff
public String parName=null;
// public ParameterVariationCosts(){}
public ParameterVariationCosts(
double scale,
double variationAbs,
double variationDiff,
double exponent,
String parName){
this.scale=scale;
this.variationAbs=variationAbs;
this.variationDiff=variationDiff;
this.exponent=exponent;
this.parName=parName;
}
public ParameterVariationCosts(
double scale,
double variationAbs,
double variationDiff,
double exponent){
this.scale=scale;
this.variationAbs=variationAbs;
this.variationDiff=variationDiff;
this.exponent=exponent;
}
public ParameterVariationCosts clone(){
return new ParameterVariationCosts(
this.scale,
this.variationAbs,
this.variationDiff,
this.exponent,
this.parName);
}
public void setPropertiesXML(String prefix,XMLConfiguration hConfig){
hConfig.addProperty(prefix+"scale",this.scale+"");
hConfig.addProperty(prefix+"variationAbs",this.variationAbs+"");
hConfig.addProperty(prefix+"variationDiff",this.variationDiff+"");
hConfig.addProperty(prefix+"exponent",this.exponent+"");
if (this.parName!=null) hConfig.addProperty(prefix+"parName",this.parName+"");
}
public boolean getPropertiesXML(String prefix,XMLConfiguration hConfig){
// System.out.println("getPropertiesXML("+prefix+",hconfig)");
boolean isSet=false;
if (hConfig.getString(prefix+"scale")!=null){
// System.out.println("getPropertiesXML("+prefix+",hconfig), hConfig.getString(prefix+\"scale\")!=null");
this.scale=Double.parseDouble(hConfig.getString(prefix+"scale"));
isSet=true;
}
if (hConfig.getString(prefix+"variationAbs")!=null){
// System.out.println("getPropertiesXML("+prefix+",hconfig), hConfig.getString(prefix+\"variationAbs\")!=null");
this.variationAbs=Double.parseDouble(hConfig.getString(prefix+"variationAbs"));
isSet=true;
}
if (hConfig.getString(prefix+"variationDiff")!=null){
// System.out.println("getPropertiesXML("+prefix+",hconfig), hConfig.getString(prefix+\"variationDiff\")!=null");
this.variationDiff=Double.parseDouble(hConfig.getString(prefix+"variationDiff"));
isSet=true;
}
if (hConfig.getString(prefix+"exponent")!=null){
// System.out.println("getPropertiesXML("+prefix+",hconfig), hConfig.getString(prefix+\"exponent\")!=null");
this.exponent=Double.parseDouble(hConfig.getString(prefix+"exponent"));
isSet=true;
}
if (hConfig.getString(prefix+"parName")!=null){
// System.out.println("getPropertiesXML("+prefix+",hconfig), hConfig.getString(prefix+\"parName\")!=null");
this.parName=hConfig.getString(prefix+"parName");
isSet=true;
}
return isSet;
}
public boolean showVarianceDialog(
String parameterName,
String parameterDescription,
String parameterUnits) {
String title="Setup costs for image set variance of "+parameterName;
GenericDialog gd = new GenericDialog(title);
gd.addMessage("Parameter: "+parameterName+" - "+parameterDescription);
gd.addNumericField("Effective cost of the image set when the "+parameterName+" variance reaches value below",this.scale, 2,4,"pix");
gd.addNumericField("Variance amount from the average of "+parameterName+" to result in the specified cost", this.variationAbs, 3,8,parameterUnits);
gd.addNumericField("Variance amount from the p to result in the specified cost", this.variationDiff, 3,8,parameterUnits);
gd.addNumericField("Exponent of the cost vs. variance (1.0 - squared err "+parameterName+" to result in the specified cost", this.exponent, 3,8,"");
WindowTools.addScrollBars(gd);
gd.showDialog();
if (gd.wasCanceled()) return false;
this.scale= gd.getNextNumber();
this.variationAbs= gd.getNextNumber();
this.variationDiff= gd.getNextNumber();
this.exponent= gd.getNextNumber();
this.parName=parameterName;
return true;
}
}
public int getNumStations() {return this.numStations;}
public EyesisCameraParameters () {} // just create new instance, all parameters data will be provided additionally
public EyesisCameraParameters (
int numStations,
boolean isTripod,
double goniometerHorizontal, // goniometer rotation around "horizontal" axis (tilting from the target - positive)
double goniometerAxial, // goniometer rotation around Eyesis axis (clockwise in plan - positive
int numSubCameras,
double interAxisDistance, // distance in mm between two goniometer axes, positive if the vertical axis (when Eyesis is head up) is closer to the target
double interAxisAngle, // angle in degrees between two goniometer axes minus 90. negative if "vertical" axis is rotated
// clockwise when eyesis is in 'normal' position, looking to the target
double horAxisErrPhi, // angle in degrees "horizontal" goniometer axis is rotated around target Y axis from target X axis (CW)
double horAxisErrPsi, // angle in degrees "horizontal" goniometer axis is rotated around moving Z axis (CW looking at target)
double entrancePupilForward, // common to all lenses - distance from the sensor to the lens entrance pupil
double centerAboveHorizontal, // camera center distance along camera axis above the closest point to horizontal rotation axis (adds to height of each
double GXYZ_0, // coordinates (in mm) of the goniometer horizontal axis closest to the moving one in target system
double GXYZ_1, // coordinates (in mm) of the goniometer horizontal axis closest to the moving one in target system
double GXYZ_2, // coordinates (in mm) of the goniometer horizontal axis closest to the moving one in target system
int sensorWidth,
int sensorHeight,
int shrinkGridForMask, //shrink detected grids by one point for/vert this number of times before calculating masks
double maskBlurSigma, // blur sensor masks (in grid units)
int decimateMasks, // reduce masks resolution
double badNodeThreshold, // filter out grid nodes with difference from quadratically predicted from 8 neighbors in pixels
int maxBadNeighb, // maximal number of bad nodes around the corrected one to fix
int minimalValidNodes,
int weightMultiImageMode, // increase weight for multi-image sets (0 - do not increase, 1 - multiply by number of images in a set)
double weightMultiExponent,
double weightDiameterExponent, // if( >0) use grid diameter to scale weights of this image
double weightYtoX,
double minimalGridContrast,
double shrinkBlurSigma,
double shrinkBlurLevel,
double balanceChannelWeightsMode,
double removeOverRMS,
double removeOverRMSNonweighted
){
double [] GXYZ={GXYZ_0,GXYZ_1,GXYZ_2};
setSameEyesisCameraParameters (
numStations,
isTripod,
goniometerHorizontal, // goniometer rotation around "horizontal" axis (tilting from the target - positive)
goniometerAxial, // goniometer rotation around Eyesis axis (clockwise in plan - positive
numSubCameras,
interAxisDistance, // distance in mm between two goniometer axes
interAxisAngle, // angle in degrees between two goniometer axes minus 90. negative if "vertical" axis is rotated
// clockwise when eyesis is in 'normal' position, looking to the target
horAxisErrPhi, // angle in degrees "horizontal" goniometer axis is rotated around target Y axis from target X axis (CW)
horAxisErrPsi, // angle in degrees "horizontal" goniometer axis is rotated moving Z axis (CW looking at target)
entrancePupilForward, // common to all lenses - distance from the sensor to the lens entrance pupil
centerAboveHorizontal, // camera center distance along camera axis above the closest point to horizontal rotation axis (adds to height of each
GXYZ, // coordinates (in mm) of the goniometer horizontal axis closest to the moving one in target system
sensorWidth,
sensorHeight,
shrinkGridForMask, //shrink detected grids by one point for/vert this number of times before calculating masks
maskBlurSigma, // blur sensor masks (in grid units)
decimateMasks, // reduce masks resolution
badNodeThreshold, // filter out grid nodes with difference from quadratically predicted from 8 neighbors in pixels
maxBadNeighb, // maximal number of bad nodes around the corrected one to fix
minimalValidNodes,
weightMultiImageMode, // increase weight for multi-image sets (0 - do not increase, 1 - multiply by number of images in a set)
weightMultiExponent,
weightDiameterExponent, // if( >0) use grid diameter to scale weights of this image
weightYtoX,
minimalGridContrast,
shrinkBlurSigma,
shrinkBlurLevel,
balanceChannelWeightsMode,
removeOverRMS,
removeOverRMSNonweighted
);
}
public EyesisCameraParameters (
int numStations,
boolean isTripod,
double goniometerHorizontal, // goniometer rotation around "horizontal" axis (tilting from the target - positive)
double goniometerAxial, // goniometer rotation around Eyesis axis (clockwise in plan - positive
int numSubCameras,
double interAxisDistance, // distance in mm between two goniometer axes
double interAxisAngle, // angle in degrees between two goniometer axes minus 90. negative if "vertical" axis is rotated
// clockwise when eyesis is in 'normal' position, looking to the target
double horAxisErrPhi, // angle in degrees "horizontal" goniometer axis is rotated around target Y axis from target X axis (CW)
double horAxisErrPsi, // angle in degrees "horizontal" goniometer axis is rotated moving Z axis (CW looking at target)
double entrancePupilForward, // common to all lenses - distance from the sensor to the lens entrance pupil
double centerAboveHorizontal, // camera center distance along camera axis above the closest point to horizontal rotation axis (adds to height of each
double [] GXYZ, // coordinates (in mm) of the goniometer horizontal axis closest to the moving one in target system
int sensorWidth,
int sensorHeight,
int shrinkGridForMask, //shrink detected grids by one point for/vert this number of times before calculating masks
double maskBlurSigma, // blur sensor masks (in grid units)
int decimateMasks, // reduce masks resolution
double badNodeThreshold, // filter out grid nodes with difference from quadratically predicted from 8 neighbors in pixels
int maxBadNeighb, // maximal number of bad nodes around the corrected one to fix
int minimalValidNodes,
int weightMultiImageMode, // increase weight for multi-image sets (0 - do not increase, 1 - multiply by number of images in a set)
double weightMultiExponent,
double weightDiameterExponent, // if( >0) use grid diameter to scale weights of this image
double weightYtoX,
double minimalGridContrast,
double shrinkBlurSigma,
double shrinkBlurLevel,
double balanceChannelWeightsMode,
double removeOverRMS,
double removeOverRMSNonweighted
){
setSameEyesisCameraParameters (
numStations,
isTripod,
goniometerHorizontal, // goniometer rotation around "horizontal" axis (tilting from the target - positive)
goniometerAxial, // goniometer rotation around Eyesis axis (clockwise in plan - positive
numSubCameras,
interAxisDistance, // distance in mm between two goniometer axes
interAxisAngle, // angle in degrees between two goniometer axes minus 90. negative if "vertical" axis is rotated
// clockwise when eyesis is in 'normal' position, looking to the target
horAxisErrPhi, // angle in degrees "horizontal" goniometer axis is rotated around target Y axis from target X axis (CW)
horAxisErrPsi, // angle in degrees "horizontal" goniometer axis is rotated moving Z axis (CW looking at target)
entrancePupilForward, // common to all lenses - distance from the sensor to the lens entrance pupil
centerAboveHorizontal, // camera center distance along camera axis above the closest point to horizontal rotation axis (adds to height of each
GXYZ, // coordinates (in mm) of the goniometer horizontal axis closest to the moving one in target system
sensorWidth,
sensorHeight,
shrinkGridForMask, //shrink detected grids by one point for/vert this number of times before calculating masks
maskBlurSigma, // blur sensor masks (in grid units)
decimateMasks, // reduce masks resolution
badNodeThreshold, // filter out grid nodes with difference from quadratically predicted from 8 neighbors in pixels
maxBadNeighb, // maximal number of bad nodes around the corrected one to fix
minimalValidNodes,
weightMultiImageMode, // increase weight for multi-image sets (0 - do not increase, 1 - multiply by number of images in a set)
weightMultiExponent,
weightDiameterExponent, // if( >0) use grid diameter to scale weights of this image
weightYtoX,
minimalGridContrast,
shrinkBlurSigma,
shrinkBlurLevel,
balanceChannelWeightsMode,
removeOverRMS,
removeOverRMSNonweighted
);
}
void setSameEyesisCameraParameters (
int numStations,
boolean isTripod,
double goniometerHorizontal, // goniometer rotation around "horizontal" axis (tilting from the target - positive)
double goniometerAxial, // goniometer rotation around Eyesis axis (clockwise in plan - positive
int numSubCameras,
double interAxisDistance, // distance in mm between two goniometer axes
double interAxisAngle, // angle in degrees between two goniometer axes minus 90. negative if "vertical" axis is rotated
// clockwise when eyesis is in 'normal' position, looking to the target
double horAxisErrPhi, // angle in degrees "horizontal" goniometer axis is rotated around target Y axis from target X axis (CW)
double horAxisErrPsi, // angle in degrees "horizontal" goniometer axis is rotated moving Z axis (CW looking at target)
double entrancePupilForward, // common to all lenses - distance from the sensor to the lens entrance pupil
double centerAboveHorizontal, // camera center distance along camera axis above the closest point to horizontal rotation axis (adds to height of each
double [] GXYZ, // coordinates (in mm) of the goniometer horizontal axis closest to the moving one in target system
int sensorWidth,
int sensorHeight,
int shrinkGridForMask, //shrink detected grids by one point for/vert this number of times before calculating masks
double maskBlurSigma, // blur sensor masks (in grid units)
int decimateMasks, // reduce masks resolution
double badNodeThreshold, // filter out grid nodes with difference from quadratically predicted from 8 neighbors in pixels
int maxBadNeighb, // maximal number of bad nodes around the corrected one to fix
int minimalValidNodes,
int weightMultiImageMode, // increase weight for multi-image sets (0 - do not increase, 1 - multiply by number of images in a set)
double weightMultiExponent,
double weightDiameterExponent, // if( >0) use grid diameter to scale weights of this image
double weightYtoX,
double minimalGridContrast,
double shrinkBlurSigma,
double shrinkBlurLevel,
double balanceChannelWeightsMode,
double removeOverRMS,
double removeOverRMSNonweighted
){
this.numStations=numStations;
this.isTripod=isTripod;
this.sensorWidth=sensorWidth;
this.sensorHeight=sensorHeight;
this.shrinkGridForMask=shrinkGridForMask; //shrink detected grids by one point for/vert this number of times before calculating masks
this.maskBlurSigma=maskBlurSigma; // blur sensor masks (in grid units)
this.decimateMasks=decimateMasks;
this.badNodeThreshold=badNodeThreshold; // filter out grid nodes with difference from quadratically predicted from 8 neighbors in pixels
this.maxBadNeighb=maxBadNeighb; // maximal number of bad nodes around the corrected one to fix
this.minimalValidNodes=minimalValidNodes;
this.weightMultiImageMode=weightMultiImageMode; // increase weight for multi-image sets (0 - do not increase, 1 - multiply by number of images in a set)
this.weightMultiExponent=weightMultiExponent;
this.weightDiameterExponent=weightDiameterExponent; // if( >0) use grid diameter to scale weights of this image
this.weightYtoX=weightYtoX;
this.minimalGridContrast=minimalGridContrast;
this.goniometerHorizontal=new double[numStations];
this.goniometerAxial=new double[numStations];
this.interAxisDistance=new double[numStations];
this.interAxisAngle=new double[numStations];
this.horAxisErrPhi=new double[numStations];
this.horAxisErrPsi=new double[numStations];
this.entrancePupilForward=new double[numStations]; // common to all lenses - distance from the sensor to the lens entrance pupil
this.centerAboveHorizontal=new double[numStations]; // camera center distance along camera axis above the closest point to horizontal rotation axis (adds to height of each
this.GXYZ=new double[numStations][];
if (numSubCameras>0) this.eyesisSubCameras=new EyesisSubCameraParameters[numStations][];
this.stationWeight=new double[numStations];
for (int numStation=0;numStation<numStations;numStation++) {
this.stationWeight[numStation]=1.0;
this.goniometerHorizontal[numStation]=goniometerHorizontal;
this.goniometerAxial[numStation]=goniometerAxial;
this.interAxisDistance[numStation]=interAxisDistance;
this.interAxisAngle[numStation]=interAxisAngle;
this.horAxisErrPhi[numStation]=horAxisErrPhi;
this.horAxisErrPsi[numStation]=horAxisErrPsi;
this.entrancePupilForward[numStation]=entrancePupilForward; // common to all lenses - distance from the sensor to the lens entrance pupil
this.centerAboveHorizontal[numStation]=centerAboveHorizontal; // camera center distance along camera axis above the closest point to horizontal rotation axis (adds to height of each
this.GXYZ[numStation]=new double [3];
for (int i=0;i<3;i++) this.GXYZ[numStation][i]=GXYZ[i];
if (numSubCameras>0) initSubCameras(numStation,numSubCameras);
}
}
public EyesisCameraParameters clone() {
EyesisCameraParameters result= new EyesisCameraParameters ();
copyData(
this.numStations,
this,
result);
return result;
}
/**
* Capoy parameters from source EysesisCamerParameters to destination, trimming/expanding nu,ber of stations
* @param newNumStations new number of stations
* @param source source EysesisCamerParameters
* @param destination destination EysesisCamerParameters
*/
public void copyData(
int newNumStations,
EyesisCameraParameters source,
EyesisCameraParameters destination) {
destination.numStations=newNumStations;
destination.isTripod=source.isTripod;
destination.sensorWidth=source.sensorWidth;
destination.sensorHeight=source.sensorHeight;
destination.shrinkGridForMask=source.shrinkGridForMask; //shrink detected grids by one point for/vert this number of times before calculating masks
destination.maskBlurSigma=source.maskBlurSigma; // blur sensor masks (in grid units)
destination.decimateMasks=source.decimateMasks;
destination.badNodeThreshold=source.badNodeThreshold; // filter out grid nodes with difference from quadratically predicted from 8 neighbors in pixels
destination.maxBadNeighb=source.maxBadNeighb; // maximal number of bad nodes around the corrected one to fix
destination.minimalValidNodes=source.minimalValidNodes;
destination.weightMultiImageMode=source.weightMultiImageMode; // increase weight for multi-image sets (0 - do not increase, 1 - multiply by number of images in a set)
destination.weightMultiExponent= source.weightMultiExponent; // if( >0) use grid diameter to scale weights of this image
destination.weightDiameterExponent=source.weightDiameterExponent;
destination.weightYtoX=source.weightYtoX;
destination.minimalGridContrast=source.minimalGridContrast;
destination.shrinkBlurSigma=source.shrinkBlurSigma;
destination.shrinkBlurLevel=source.shrinkBlurLevel;
destination.balanceChannelWeightsMode=source.balanceChannelWeightsMode;
destination.removeOverRMSNonweighted=source.removeOverRMSNonweighted;
destination.goniometerHorizontal=new double[destination.numStations];
destination.goniometerAxial=new double[destination.numStations];
destination.interAxisDistance=new double[destination.numStations];
destination.interAxisAngle=new double[destination.numStations];
destination.horAxisErrPhi=new double[destination.numStations];
destination.horAxisErrPsi=new double[destination.numStations];
destination.entrancePupilForward=new double[destination.numStations]; // common to all lenses - distance from the sensor to the lens entrance pupil
destination.centerAboveHorizontal=new double[destination.numStations]; // camera center distance along camera axis above the closest point to horizontal rotation axis (adds to height of each
destination.GXYZ=new double[destination.numStations][];
if (source.eyesisSubCameras!=null) destination.eyesisSubCameras=new EyesisSubCameraParameters[destination.numStations][];
else destination.eyesisSubCameras=null;
destination.stationWeight=new double[destination.numStations];
for (int numStation=0;numStation<destination.numStations;numStation++) {
int srcNumStation=(numStation<source.numStations)?numStation:(source.numStations-1);
destination.stationWeight[numStation]=source.stationWeight[srcNumStation];
destination.goniometerHorizontal[numStation]=source.goniometerHorizontal[srcNumStation];
destination.goniometerAxial[numStation]=source.goniometerAxial[srcNumStation];
destination.interAxisDistance[numStation]=source.interAxisDistance[srcNumStation];
destination.interAxisAngle[numStation]=source.interAxisAngle[srcNumStation];
destination.horAxisErrPhi[numStation]=source.horAxisErrPhi[srcNumStation];
destination.horAxisErrPsi[numStation]=source.horAxisErrPsi[srcNumStation];
destination.entrancePupilForward[numStation]=source.entrancePupilForward[srcNumStation]; // common to all lenses - distance from the sensor to the lens entrance pupil
destination.centerAboveHorizontal[numStation]=source.centerAboveHorizontal[srcNumStation]; // camera center distance along camera axis above the closest point to horizontal rotation axis (adds to height of each
destination.GXYZ[numStation]=new double [3];
for (int i=0;i<3;i++) destination.GXYZ[numStation][i]=source.GXYZ[srcNumStation][i];
if (destination.eyesisSubCameras!=null){
destination.eyesisSubCameras[numStation]=new EyesisSubCameraParameters[source.eyesisSubCameras[srcNumStation].length];
for (int i=0; i<destination.eyesisSubCameras[numStation].length;i++) if (source.eyesisSubCameras[srcNumStation][i]!=null){
destination.eyesisSubCameras[numStation][i]=source.eyesisSubCameras[srcNumStation][i].clone();
}
}
}
}
public void setProperties(String prefix,Properties properties){
properties.setProperty(prefix+"isTripod",this.isTripod+"");
properties.setProperty(prefix+"sensorWidth",this.sensorWidth+"");
properties.setProperty(prefix+"sensorHeight",this.sensorHeight+"");
properties.setProperty(prefix+"shrinkGridForMask",this.shrinkGridForMask+"");
properties.setProperty(prefix+"maskBlurSigma",this.maskBlurSigma+"");
properties.setProperty(prefix+"decimateMasks",this.decimateMasks+"");
properties.setProperty(prefix+"badNodeThreshold",this.badNodeThreshold+"");
properties.setProperty(prefix+"maxBadNeighb",this.maxBadNeighb+"");
properties.setProperty(prefix+"minimalValidNodes",this.minimalValidNodes+"");
properties.setProperty(prefix+"weightMultiImageMode",this.weightMultiImageMode+"");
properties.setProperty(prefix+"weightMultiExponent",this.weightMultiExponent+"");
properties.setProperty(prefix+"weightDiameterExponent",this.weightDiameterExponent+"");
properties.setProperty(prefix+"weightYtoX",this.weightYtoX+"");
properties.setProperty(prefix+"minimalGridContrast",this.minimalGridContrast+"");
properties.setProperty(prefix+"shrinkBlurSigma",this.shrinkBlurSigma+"");
properties.setProperty(prefix+"shrinkBlurLevel",this.shrinkBlurLevel+"");
properties.setProperty(prefix+"balanceChannelWeightsMode",this.balanceChannelWeightsMode+"");
properties.setProperty(prefix+"removeOverRMS",this.removeOverRMS+"");
properties.setProperty(prefix+"removeOverRMSNonweighted",this.removeOverRMSNonweighted+"");
properties.setProperty(prefix+"numSubCameras",this.eyesisSubCameras[0].length+"");
properties.setProperty(prefix+"numStations",this.numStations+"");
for (int numStation=0;numStation<this.numStations;numStation++){
properties.setProperty(prefix+"stationWeight_"+numStation,this.stationWeight[numStation]+"");
properties.setProperty(prefix+"goniometerHorizontal_"+numStation,this.goniometerHorizontal[numStation]+"");
properties.setProperty(prefix+"goniometerAxial_"+numStation,this.goniometerAxial[numStation]+"");
properties.setProperty(prefix+"interAxisDistance_"+numStation,this.interAxisDistance[numStation]+"");
properties.setProperty(prefix+"interAxisAngle_"+numStation,this.interAxisAngle[numStation]+"");
properties.setProperty(prefix+"horAxisErrPhi_"+numStation,this.horAxisErrPhi[numStation]+"");
properties.setProperty(prefix+"horAxisErrPsi_"+numStation,this.horAxisErrPsi[numStation]+"");
properties.setProperty(prefix+"entrancePupilForward_"+numStation,this.entrancePupilForward[numStation]+"");
properties.setProperty(prefix+"centerAboveHorizontal_"+numStation,this.centerAboveHorizontal[numStation]+"");
properties.setProperty(prefix+"GXYZ_0_"+numStation,this.GXYZ[numStation][0]+"");
properties.setProperty(prefix+"GXYZ_1_"+numStation,this.GXYZ[numStation][1]+"");
properties.setProperty(prefix+"GXYZ_2_"+numStation,this.GXYZ[numStation][2]+"");
for (int i=0;i<this.eyesisSubCameras[numStation].length;i++) {
this.eyesisSubCameras[numStation][i].setProperties(prefix+numStation+"_subCamera_"+i+'.',properties);
}
}
// setCostsProperties(prefix,properties);
}
public void getProperties(String prefix,Properties properties){
if (properties.getProperty(prefix+"isTripod")!=null)
this.isTripod=Boolean.parseBoolean(properties.getProperty(prefix+"isTripod"));
if (properties.getProperty(prefix+"sensorWidth")!=null)
this.sensorWidth=Integer.parseInt(properties.getProperty(prefix+"sensorWidth"));
if (properties.getProperty(prefix+"sensorHeight")!=null)
this.sensorHeight=Integer.parseInt(properties.getProperty(prefix+"sensorHeight"));
if (properties.getProperty(prefix+"shrinkGridForMask")!=null)
this.shrinkGridForMask=Integer.parseInt(properties.getProperty(prefix+"shrinkGridForMask"));
if (properties.getProperty(prefix+"maskBlurSigma")!=null)
this.maskBlurSigma=Double.parseDouble(properties.getProperty(prefix+"maskBlurSigma"));
if (properties.getProperty(prefix+"decimateMasks")!=null)
this.decimateMasks=Integer.parseInt(properties.getProperty(prefix+"decimateMasks"));
if (properties.getProperty(prefix+"badNodeThreshold")!=null)
this.badNodeThreshold=Double.parseDouble(properties.getProperty(prefix+"badNodeThreshold"));
if (properties.getProperty(prefix+"maxBadNeighb")!=null)
this.maxBadNeighb=Integer.parseInt(properties.getProperty(prefix+"maxBadNeighb"));
if (properties.getProperty(prefix+"minimalValidNodes")!=null)
this.minimalValidNodes=Integer.parseInt(properties.getProperty(prefix+"minimalValidNodes"));
if (properties.getProperty(prefix+"weightMultiImageMode")!=null)
this.weightMultiImageMode=Integer.parseInt(properties.getProperty(prefix+"weightMultiImageMode"));
if (properties.getProperty(prefix+"weightMultiExponent")!=null)
this.weightMultiExponent=Double.parseDouble(properties.getProperty(prefix+"weightMultiExponent"));
if (properties.getProperty(prefix+"weightDiameterExponent")!=null)
this.weightDiameterExponent=Double.parseDouble(properties.getProperty(prefix+"weightDiameterExponent"));
if (properties.getProperty(prefix+"weightYtoX")!=null)
this.weightYtoX=Double.parseDouble(properties.getProperty(prefix+"weightYtoX"));
if (properties.getProperty(prefix+"minimalGridContrast")!=null)
this.minimalGridContrast=Double.parseDouble(properties.getProperty(prefix+"minimalGridContrast"));
if (properties.getProperty(prefix+"shrinkBlurSigma")!=null)
this.shrinkBlurSigma=Double.parseDouble(properties.getProperty(prefix+"shrinkBlurSigma"));
if (properties.getProperty(prefix+"shrinkBlurLevel")!=null)
this.shrinkBlurLevel=Double.parseDouble(properties.getProperty(prefix+"shrinkBlurLevel"));
if (properties.getProperty(prefix+"balanceChannelWeightsMode")!=null)
this.balanceChannelWeightsMode=Double.parseDouble(properties.getProperty(prefix+"balanceChannelWeightsMode"));
if (properties.getProperty(prefix+"removeOverRMS")!=null)
this.removeOverRMS=Double.parseDouble(properties.getProperty(prefix+"removeOverRMS"));
if (properties.getProperty(prefix+"removeOverRMSNonweighted")!=null)
this.removeOverRMSNonweighted=Double.parseDouble(properties.getProperty(prefix+"removeOverRMSNonweighted"));
boolean multiStation=true; // new default
int newNumStations=1;
int numSubCameras=0;
if (properties.getProperty(prefix+"numSubCameras")!=null) numSubCameras=Integer.parseInt(properties.getProperty(prefix+"numSubCameras"));
if (properties.getProperty(prefix+"numStations")!=null){
newNumStations=Integer.parseInt(properties.getProperty(prefix+"numStations"));
}else {
multiStation=false; // old config format
}
// TODO: trim/expand stations
updateNumstations (newNumStations);
// this.numStations
// read old/new format data
// this.numStations=newNumStations;
if (multiStation){
for (int numStation=0;numStation<this.numStations;numStation++){
if (properties.getProperty(prefix+"stationWeight_"+numStation)!=null)
this.stationWeight[numStation]=Double.parseDouble(properties.getProperty(prefix+"stationWeight_"+numStation));
if (properties.getProperty(prefix+"goniometerHorizontal_"+numStation)!=null)
this.goniometerHorizontal[numStation]=Double.parseDouble(properties.getProperty(prefix+"goniometerHorizontal_"+numStation));
if (properties.getProperty(prefix+"goniometerAxial_"+numStation)!=null)
this.goniometerAxial[numStation]=Double.parseDouble(properties.getProperty(prefix+"goniometerAxial_"+numStation));
if (properties.getProperty(prefix+"interAxisDistance_"+numStation)!=null)
this.interAxisDistance[numStation]=Double.parseDouble(properties.getProperty(prefix+"interAxisDistance_"+numStation));
if (properties.getProperty(prefix+"interAxisAngle_"+numStation)!=null)
this.interAxisAngle[numStation]=Double.parseDouble(properties.getProperty(prefix+"interAxisAngle_"+numStation));
if (properties.getProperty(prefix+"horAxisErrPhi_"+numStation)!=null)
this.horAxisErrPhi[numStation]=Double.parseDouble(properties.getProperty(prefix+"horAxisErrPhi_"+numStation));
if (properties.getProperty(prefix+"horAxisErrPsi_"+numStation)!=null)
this.horAxisErrPsi[numStation]=Double.parseDouble(properties.getProperty(prefix+"horAxisErrPsi_"+numStation));
if (properties.getProperty(prefix+"entrancePupilForward_"+numStation)!=null)
this.entrancePupilForward[numStation]=Double.parseDouble(properties.getProperty(prefix+"entrancePupilForward_"+numStation));
if (properties.getProperty(prefix+"centerAboveHorizontal_"+numStation)!=null)
this.centerAboveHorizontal[numStation]=Double.parseDouble(properties.getProperty(prefix+"centerAboveHorizontal_"+numStation));
if (properties.getProperty(prefix+"GXYZ_0_"+numStation)!=null)
this.GXYZ[numStation][0]=Double.parseDouble(properties.getProperty(prefix+"GXYZ_0_"+numStation));
if (properties.getProperty(prefix+"GXYZ_1_"+numStation)!=null)
this.GXYZ[numStation][1]=Double.parseDouble(properties.getProperty(prefix+"GXYZ_1_"+numStation));
if (properties.getProperty(prefix+"GXYZ_2_"+numStation)!=null)
this.GXYZ[numStation][2]=Double.parseDouble(properties.getProperty(prefix+"GXYZ_2_"+numStation));
if (numSubCameras>0) {
initSubCameras(numStation, numSubCameras); // set array with default parameters
for (int i=0;i<numSubCameras;i++){
this.eyesisSubCameras[numStation][i].getProperties(prefix+numStation+"_subCamera_"+i+'.',properties);
}
}
}
} else { // read old format
if (properties.getProperty(prefix+"goniometerHorizontal")!=null)
this.goniometerHorizontal[0]=Double.parseDouble(properties.getProperty(prefix+"goniometerHorizontal"));
if (properties.getProperty(prefix+"goniometerAxial")!=null)
this.goniometerAxial[0]=Double.parseDouble(properties.getProperty(prefix+"goniometerAxial"));
if (properties.getProperty(prefix+"interAxisDistance")!=null)
this.interAxisDistance[0]=Double.parseDouble(properties.getProperty(prefix+"interAxisDistance"));
if (properties.getProperty(prefix+"interAxisAngle")!=null)
this.interAxisAngle[0]=Double.parseDouble(properties.getProperty(prefix+"interAxisAngle"));
if (properties.getProperty(prefix+"horAxisErrPhi")!=null)
this.horAxisErrPhi[0]=Double.parseDouble(properties.getProperty(prefix+"horAxisErrPhi"));
if (properties.getProperty(prefix+"horAxisErrPsi")!=null)
this.horAxisErrPsi[0]=Double.parseDouble(properties.getProperty(prefix+"horAxisErrPsi"));
if (properties.getProperty(prefix+"entrancePupilForward")!=null)
this.entrancePupilForward[0]=Double.parseDouble(properties.getProperty(prefix+"entrancePupilForward"));
if (properties.getProperty(prefix+"centerAboveHorizontal")!=null)
this.centerAboveHorizontal[0]=Double.parseDouble(properties.getProperty(prefix+"centerAboveHorizontal"));
if (properties.getProperty(prefix+"GXYZ_0")!=null)
this.GXYZ[0][0]=Double.parseDouble(properties.getProperty(prefix+"GXYZ_0"));
if (properties.getProperty(prefix+"GXYZ_1")!=null)
this.GXYZ[0][1]=Double.parseDouble(properties.getProperty(prefix+"GXYZ_1"));
if (properties.getProperty(prefix+"GXYZ_2")!=null)
this.GXYZ[0][2]=Double.parseDouble(properties.getProperty(prefix+"GXYZ_2"));
System.out.println(" === numSubCameras="+numSubCameras);
if (numSubCameras>0) {
initSubCameras(0, numSubCameras); // set array with default parameters
for (int i=0;i<numSubCameras;i++){
System.out.println("this.eyesisSubCameras[0]["+i+"].getProperties("+prefix+"subCamera_"+i+".,properties);");
this.eyesisSubCameras[0][i].getProperties(prefix+"subCamera_"+i+'.',properties);
}
}
}
// getCostsProperties(prefix,properties);
}
void updateNumstations (int newNumStations){
// System.out.println("updateNumstations("+newNumStations+"), was "+this.numStations);
if (newNumStations==this.numStations) return;
System.out.println("updateNumstations("+newNumStations+"), was "+this.numStations);
EyesisCameraParameters newData=this.clone();
copyData(
newNumStations,
newData,
this);
System.out.println("updateNumstations() after copyData() this.numStations="+this.numStations);
}
// returns -1 - canceled, 0 - done, >0 - number of sub-camera to edit
private int subShowDialog(String title, int nextSubCamera) {
GenericDialog gd = new GenericDialog(title);
// public double goniometerHorizontal; // goniometer rotation around "horizontal" axis (tilting from the target - positive)
// public double goniometerAxial; // goniometer rotation around Eyesis axis (clockwise in plan - positive
//this.isTripod
gd.addCheckbox("Tripod mode (first vertical axis, then horizontal), changes meaning of the next 2 fields",this.isTripod);
gd.addMessage("=== Camera parameters to be fitted ===");
for (int numStation=0;numStation<this.numStations;numStation++) {
if (this.numStations>1){
gd.addMessage("--- Station number "+numStation+" ---");
gd.addNumericField("Station reprojection errors weight", 100*this.stationWeight[numStation], 1,5,"%");
}
if (this.isTripod) {
gd.addNumericField("Tripod rotation around vertical axis (clockwise from top - positive)",this.goniometerHorizontal[numStation], 3,7,"degrees");
gd.addNumericField("Tripod rotation around horizontal axis (camera up - positive)", this.goniometerAxial[numStation], 3,7,"degrees");
} else {
gd.addNumericField("Goniometer rotation around 'horizontal' axis (tilting from the target - positive)",this.goniometerHorizontal[numStation], 3,7,"degrees");
gd.addNumericField("Rotation around Eyesis main axis (clockwise in plan - positive)", this.goniometerAxial[numStation], 3,7,"degrees");
}
gd.addNumericField("Distance between goniometer axes", this.interAxisDistance[numStation], 3,7,"mm");
gd.addNumericField("Angle error between goniometer axes (<0 if vertical axis rotated CW )",this.interAxisAngle[numStation], 3,7,"degrees");
if (this.isTripod) {
gd.addNumericField("Vertical tripod axis tilt from true vertical", this.horAxisErrPhi[numStation], 3,7,"degrees");
gd.addNumericField("Vertical tripod axis roll error from true vertical", this.horAxisErrPsi[numStation], 3,7,"degrees");
} else {
gd.addNumericField("Horizontal axis azimuth error (CW in plan)", this.horAxisErrPhi[numStation], 3,7,"degrees");
gd.addNumericField("Horizontal axis roll error (CW looking to target)", this.horAxisErrPsi[numStation], 3,7,"degrees");
}
gd.addNumericField("Distance between the lens entrace pupil and the sensor", this.entrancePupilForward[numStation], 3,7,"mm");
gd.addNumericField("Camera center above goniometer horizontal axis", this.centerAboveHorizontal[numStation], 3,7,"mm");
gd.addNumericField("Goniometer reference point position X (target coordinates, left)", this.GXYZ[numStation][0], 3,7,"mm");
gd.addNumericField("Goniometer reference point position Y (target coordinates, up)", this.GXYZ[numStation][1], 3,7,"mm");
gd.addNumericField("Goniometer reference point position Z (target coordinates, away)", this.GXYZ[numStation][2], 3,7,"mm");
}
gd.addMessage("=== Other parameters ===");
gd.addNumericField("Image sensor width (maximal if different)", this.sensorWidth, 0,4,"pix");
gd.addNumericField("Image sensor height (maximal if different)", this.sensorHeight, 0,4,"pix");
gd.addNumericField("Shrink detected grid by this number of nodes (half/periods) for masks",this.shrinkGridForMask, 0,4,"grid nodes");
gd.addNumericField("Gaussian blur masks for the sensors (positive - pixels, negative - grid half-periods)", this.maskBlurSigma, 2,6,"pix");
gd.addNumericField("Reduce sensor resolution when calculating masks", this.decimateMasks, 0);
gd.addNumericField("Filter out grid nodes with difference from quadratically predicted from 8 neighbors", this.badNodeThreshold, 2,6,"pix");
gd.addNumericField("Maximal number of bad nodes around the corrected one to fix", this.maxBadNeighb, 0);
gd.addNumericField("Minimal number of valid (with all filters applied) nodes in each image",this.minimalValidNodes, 0);
gd.addNumericField("Increase weight of the multi-image sets (0 - do not increase, 1 - multiply by number of images in a set (to power ), 2 - same but remove single-image ",this.weightMultiImageMode, 0);
gd.addNumericField("Increase weight of the multi-image sets power (used with mode above)", this.weightMultiExponent, 2,6,"");
gd.addNumericField("Increase weight of the images by the power of their diameters", this.weightDiameterExponent, 2,6,"");
gd.addNumericField("Increase weight Y-error with respect to X-error", 100.0*this.weightYtoX, 2,6,"%");
gd.addNumericField("Filter out grid nodes with the contrast less than this value (maximal is ~0.8) ", this.minimalGridContrast, 2,6,"");
gd.addNumericField("Shrink-blur detected grids alpha", this.shrinkBlurSigma, 2,6,"grid nodes");
gd.addNumericField("Shrink-blur detected grids level (-1..+1)", this.shrinkBlurLevel, 2,6,"");
gd.addNumericField("Channel balace mode: <0 - use specified defaults, 0 - keep curent, >0 - exponent for correction (1.0 - precise equalization)", this.balanceChannelWeightsMode, 3,6,"");
gd.addNumericField("Remove nodes with error greater than scaled RMS in that image, weighted", this.removeOverRMS, 2,6,"xRMS");
gd.addNumericField("Same, not weghted (not more permissive near the borders with low weight)", this.removeOverRMSNonweighted, 2,6,"xRMS");
gd.addNumericField("Number of sub-camera modules", this.eyesisSubCameras[0].length, 0,2,"");
gd.addNumericField("Number of sub-camera module to edit (<=0 - none)", nextSubCamera, 0,2,"");
gd.enableYesNoCancel("OK", "Done");
WindowTools.addScrollBars(gd);
gd.showDialog();
if (gd.wasCanceled()) return -1;
this.isTripod= gd.getNextBoolean();
for (int numStation=0;numStation<this.numStations;numStation++) {
if (this.numStations>1){
this.stationWeight[numStation]=0.01*gd.getNextNumber();
}
this.goniometerHorizontal[numStation]= gd.getNextNumber();
this.goniometerAxial[numStation]= gd.getNextNumber();
this.interAxisDistance[numStation]= gd.getNextNumber();
this.interAxisAngle[numStation]= gd.getNextNumber();
this.horAxisErrPhi[numStation]= gd.getNextNumber();
this.horAxisErrPsi[numStation]= gd.getNextNumber();
this.entrancePupilForward[numStation]= gd.getNextNumber();
this.centerAboveHorizontal[numStation]= gd.getNextNumber();
this.GXYZ[numStation][0]= gd.getNextNumber();
this.GXYZ[numStation][1]= gd.getNextNumber();
this.GXYZ[numStation][2]= gd.getNextNumber();
}
this.sensorWidth= (int) gd.getNextNumber();
this.sensorHeight= (int) gd.getNextNumber();
this.shrinkGridForMask= (int) gd.getNextNumber();
this.maskBlurSigma= gd.getNextNumber();
this.decimateMasks= (int) gd.getNextNumber();
this.badNodeThreshold= gd.getNextNumber();
this.maxBadNeighb= (int) gd.getNextNumber();
this.minimalValidNodes= (int) gd.getNextNumber();
this.weightMultiImageMode=(int) gd.getNextNumber();
this.weightMultiExponent= gd.getNextNumber();
this.weightDiameterExponent= gd.getNextNumber();
this.weightYtoX= 0.01*gd.getNextNumber();
this.minimalGridContrast= gd.getNextNumber();
this.shrinkBlurSigma = gd.getNextNumber();
this.shrinkBlurLevel = gd.getNextNumber();
this.balanceChannelWeightsMode= gd.getNextNumber();
this.removeOverRMS = gd.getNextNumber();
this.removeOverRMSNonweighted= gd.getNextNumber();
int numSubCams= (int) gd.getNextNumber();
int numSubCam= (int) gd.getNextNumber();
if (numSubCams!=this.eyesisSubCameras[0].length){
this.eyesisSubCameras=new EyesisSubCameraParameters[this.numStations][];
for (int numStation=0;numStation<numStations;numStation++) {
initSubCameras(numStation,numSubCams); // re-initialize from defaults, discard current!
}
}
if (numSubCam<0)numSubCam=0;
return gd.wasOKed()?numSubCam:-1;
}
public boolean showSubcameraDialog(
int numSubCam,
String title) {
GenericDialog gd = new GenericDialog(title);
for (int numStation=0;numStation<this.numStations;numStation++) {
EyesisSubCameraParameters subCam=this.eyesisSubCameras[numStation][numSubCam];
if (subCam!=null) {
gd.addMessage("Channel weight "+subCam.channelWeightCurrent);
if (numStation==0){
gd.addNumericField("Channel "+numSubCam+" default weight", subCam.channelWeightDefault, 3,6,"");
}
if (this.numStations>1) gd.addMessage("--- Station number "+numStation+" ---");
gd.addNumericField("Subcamera azimuth", subCam.azimuth, 3,7,"degrees");
gd.addNumericField("Subcamera distance from the axis", subCam.radius, 3,7,"mm");
gd.addNumericField("Subcamera height from the 'equator'", subCam.height, 3,7,"mm");
gd.addNumericField("Optical axis heading (relative to azimuth)", subCam.phi, 3,7,"degrees");
gd.addNumericField("Optical axis elevation (up from equator)", subCam.theta, 3,7,"degrees");
gd.addNumericField("Camera roll, positive CW looking to the target",subCam.psi, 3,7,"degrees");
gd.addNumericField("Lens focal length", subCam.focalLength, 3,6,"mm");
gd.addNumericField("Sensor pixel period", subCam.pixelSize, 3,6,"um");
gd.addNumericField("Distortion radius (half width)", subCam.distortionRadius, 5,8,"mm");
gd.addNumericField("Distortion A8 (r^8)", subCam.distortionA8, 6,8,"");
gd.addNumericField("Distortion A7 (r^7)", subCam.distortionA7, 6,8,"");
gd.addNumericField("Distortion A6 (r^6)", subCam.distortionA6, 6,8,"");
gd.addNumericField("Distortion A5 (r^5)", subCam.distortionA5, 6,8,"");
gd.addNumericField("Distortion A (r^4)", subCam.distortionA, 6,8,"");
gd.addNumericField("Distortion B (r^3)", subCam.distortionB, 6,8,"");
gd.addNumericField("Distortion C (r^2)", subCam.distortionC, 6,8,"");
gd.addNumericField("Lens axis on the sensor (horizontal, from left edge)", subCam.px0, 2,7,"pixels");
gd.addNumericField("Lens axis on the sensor (vertical, from top edge)", subCam.py0, 2,7,"pixels");
}
}
gd.enableYesNoCancel("OK", "Done");
WindowTools.addScrollBars(gd);
gd.showDialog();
if (gd.wasCanceled()) return false;
double channelWeightDefault=1.0;
for (int numStation=0;numStation<this.numStations;numStation++) {
EyesisSubCameraParameters subCam=this.eyesisSubCameras[numStation][numSubCam];
if (subCam!=null) {
if (numStation==0){
gd.addMessage("Channel weight "+subCam.channelWeightCurrent);
channelWeightDefault=gd.getNextNumber();
}
subCam.channelWeightDefault= channelWeightDefault; // assign to all stations
subCam.azimuth= gd.getNextNumber();
subCam.radius= gd.getNextNumber();
subCam.height= gd.getNextNumber();
subCam.phi= gd.getNextNumber();
subCam.theta= gd.getNextNumber();
subCam.psi= gd.getNextNumber();
subCam.focalLength= gd.getNextNumber();
subCam.pixelSize= gd.getNextNumber();
subCam.distortionRadius=gd.getNextNumber();
subCam.distortionA8= gd.getNextNumber();
subCam.distortionA7= gd.getNextNumber();
subCam.distortionA6= gd.getNextNumber();
subCam.distortionA5= gd.getNextNumber();
subCam.distortionA= gd.getNextNumber();
subCam.distortionB= gd.getNextNumber();
subCam.distortionC= gd.getNextNumber();
subCam.px0= gd.getNextNumber();
subCam.py0= gd.getNextNumber();
}
}
return gd.wasOKed();
}
// TODO: make subcameras show numbers from 0
public boolean showDialog(String title) {
System.out.println("this.eyesisSubCameras.length="+this.eyesisSubCameras.length);
System.out.println("this.eyesisSubCameras[0].length="+this.eyesisSubCameras[0].length);
int subCam=1;
while (subCam<=this.eyesisSubCameras[0].length) {
System.out.println("subCam="+subCam);
subCam=subShowDialog(title, subCam);
if (subCam<0) return false;
if (subCam==0) return true;
while (subCam<=this.eyesisSubCameras[0].length) {
// if (!this.eyesisSubCameras[subCam-1].showDialog(title+": subcamera "+subCam)) break;
if (!showSubcameraDialog(subCam-1,title+": subcamera "+subCam+" ("+(subCam-1)+")")) break;
subCam++;
}
}
return true;
}
/**
*
* @param eyesisCameraParameters current parameters of the Eyesis camera, subcameras and goniometer
* @param subCamNumber number of sub-camera (from 0)
* @return array of the parameters (both individual sub-camera and common to all sub-cameras)
*
*/
public double [] getParametersVector(
int stationNumber,
int subCamNumber //
){
if (
(this.eyesisSubCameras==null) ||
(this.numStations<=stationNumber) ||
(this.eyesisSubCameras.length<=stationNumber) ||
(this.eyesisSubCameras[stationNumber].length<=subCamNumber)) throw new IllegalArgumentException
("Nonexistent subcamera "+subCamNumber+ " and/or station number="+stationNumber+" this.numStations="+this.numStations+" this.eyesisSubCameras.length="+this.eyesisSubCameras.length);
EyesisSubCameraParameters subCam=this.eyesisSubCameras[stationNumber][subCamNumber];
// System.out.println("getParametersVector("+stationNumber+","+subCamNumber+"), subCam is "+((subCam==null)?"null":"NOT null"));
double [] parVect={
subCam.azimuth, // 0 azimuth of the lens entrance pupil center, degrees, clockwise looking from top
subCam.radius, // 1 mm, distance from the rotation axis
subCam.height, // 2 mm, up (was downwards?) - from the origin point
subCam.phi, // 3 degrees, optical axis from azimuth/r vector, clockwise
subCam.theta, // 4 degrees, optical axis from the eyesis horizon, positive - up
subCam.psi, // 5 degrees, rotation (of the sensor) around the optical axis. Positive if camera is rotated clockwise looking to the target
this.goniometerHorizontal[stationNumber], // 6 goniometer rotation around "horizontal" axis (tilting from the target - positive)
this.goniometerAxial[stationNumber], // 7 goniometer rotation around Eyesis axis (clockwise in plan - positive
this.interAxisDistance[stationNumber], // 8 distance in mm between two goniometer axes
this.interAxisAngle[stationNumber], // 9 angle in degrees between two goniometer axes minus 90. negative if "vertical" axis is rotated
this.horAxisErrPhi[stationNumber], //10 angle in degrees "horizontal" goniometer axis is rotated around target Y axis from target X axis (CW)
this.horAxisErrPsi[stationNumber], //11 angle in degrees "horizontal" goniometer axis is rotated around moving X axis (up)
this.entrancePupilForward[stationNumber], //12 common to all lenses - distance from the sensor to the lens entrance pupil
this.centerAboveHorizontal[stationNumber],//13 camera center distance along camera axis above the closest point to horizontal rotation axis (adds to height of each
this.GXYZ[stationNumber][0], //14 (12) coordinates (in mm) of the goniometer horizontal axis closest to the moving one in target system
this.GXYZ[stationNumber][1], //15 (13) y
this.GXYZ[stationNumber][2], //16 (14) z
subCam.focalLength, //17 (15) lens focal length
subCam.px0, //18 (16) center of the lens on the sensor, pixels
subCam.py0, //19 (17) center of the lens on the sensor, pixels
subCam.distortionA8, //20 (18) r^8 (normalized to focal length or to sensor half width?)
subCam.distortionA7, //21 (19) r^7 (normalized to focal length or to sensor half width?)
subCam.distortionA6, //22 (20) r^6 (normalized to focal length or to sensor half width?)
subCam.distortionA5, //23 (21) r^5 (normalized to focal length or to sensor half width?)
subCam.distortionA, //24 (22) r^4 (normalized to focal length or to sensor half width?)
subCam.distortionB, //25 (23) r^3
subCam.distortionC, //26 (24) r^2
};
// Global parameters, not adjusted - just copied once when camera is selected
// or should they stay fixed and not copied at all?
// this.lensDistortionParameters.pixelSize=subCam.pixelSize; // has to be set separately
// this.lensDistortionParameters.distortionRadius=subCam.distortionRadius;
return parVect;
}
// public int getNumSubCameras (){return (this.eyesisSubCameras==null)?0:this.eyesisSubCameras.length;}
public int getGoniometerHorizontalIndex(){return 6;}
public int getGoniometerAxialIndex(){return 7;}
public int getSensorWidth() { return this.sensorWidth;}
public int getSensorHeight() { return this.sensorHeight;}
public int getSensorWidth(int subCam) { return this.sensorWidth;} // for the future? different sensors
public int getSensorHeight(int subCam) { return this.sensorHeight;}// for the future? different sensors
public double getPixelSize(int subCamNumber){return this.eyesisSubCameras[0][subCamNumber].pixelSize;} // use station 0's pixel size
public double getDistortionRadius(int subCamNumber){return this.eyesisSubCameras[0][subCamNumber].distortionRadius;}
public void setParametersVectorAllStations(
double [] parVect,
boolean [] update,
int subCamNumber //
){
for (int stationNumber=0;stationNumber<this.numStations;stationNumber++){
setParametersVector(
parVect,
update,
stationNumber,
subCamNumber );
}
}
/**
* Set camera/subcamera parameters from the parameters vector
* @param parVect array of the parameters (both individual sub-camera and common to all sub-cameras)
* @param update - which parameter of the vector to update
* @param eyesisCameraParameters current parameters of the Eyesis camera, subcameras and goniometer
* @param subCamNumber number of sub-camera (from 0)
*/
public void setParametersVector(
double [] parVect,
boolean [] update,
int stationNumber,
int subCamNumber //
){
if (parVect.length!=27) throw new IllegalArgumentException ("Wrong length of the parameters vector: "+parVect.length+"(should be 27)");
if (
(this.eyesisSubCameras==null) ||
(this.numStations<=stationNumber) ||
(this.eyesisSubCameras.length<=stationNumber) ||
(this.eyesisSubCameras[stationNumber].length<=subCamNumber)) throw new IllegalArgumentException
("Nonexistent subcamera "+subCamNumber+ " and/or station number="+stationNumber);
EyesisSubCameraParameters subCam=this.eyesisSubCameras[stationNumber][subCamNumber];
if (update[0]) subCam.azimuth=parVect[0]; // 0 azimuth of the lens entrance pupil center, degrees, clockwise looking from top
if (update[1]) subCam.radius=parVect[1]; // 1 mm, distance from the rotation axis
if (update[2]) subCam.height=parVect[2]; // 2 mm, up (was downwards?) - from the origin point
if (update[2]) subCam.phi=parVect[3]; // 3 degrees, optical axis from azimuth/r vector, clockwise
if (update[4]) subCam.theta=parVect[4]; // 4 degrees, optical axis from the eyesis horizon, positive - up
if (update[5]) subCam.psi=parVect[5]; // 5 degrees, rotation (of the sensor) around the optical axis. Positive if camera is rotated clockwise looking to the target
if (update[6]) this.goniometerHorizontal[stationNumber]=parVect[6]; // 6 goniometer rotation around "horizontal" axis (tilting from the target - positive)
if (update[7]) this.goniometerAxial[stationNumber]=parVect[7]; // 7 goniometer rotation around Eyesis axis (clockwise in plan - positive
if (update[8]) this.interAxisDistance[stationNumber]=parVect[8]; // 8 distance in mm between two goniometer axes
if (update[9]) this.interAxisAngle[stationNumber]=parVect[9]; // 9 angle in degrees between two goniometer axes minus 90. negative if "vertical" axis is rotated
if (update[10]) this.horAxisErrPhi[stationNumber]=parVect[10]; //10 angle in degrees "horizontal" goniometer axis is rotated around target Y axis from target X axis (CW)
if (update[11]) this.horAxisErrPsi[stationNumber]=parVect[11]; //11 angle in degrees "horizontal" goniometer axis is rotated around moving X axis (up)
if (update[12]) this.entrancePupilForward[stationNumber]=parVect[12]; //12 coordinates (in mm) of the goniometer horizontal axis closest to the moving one in target system
if (update[13]) this.centerAboveHorizontal[stationNumber]=parVect[13]; //13 y
if (update[14]) this.GXYZ[stationNumber][0]=parVect[14]; //14 coordinates (in mm) of the goniometer horizontal axis closest to the moving one in target system
if (update[15]) this.GXYZ[stationNumber][1]=parVect[15]; //15 y
if (update[16]) this.GXYZ[stationNumber][2]=parVect[16]; //16 z
if (update[17]) subCam.focalLength=parVect[17]; //17 lens focal length
if (update[18]) subCam.px0=parVect[18]; //18 center of the lens on the sensor, pixels
if (update[19]) subCam.py0=parVect[19]; //19 center of the lens on the sensor, pixels
if (update[20]) subCam.distortionA8=parVect[20]; //20 r^8 (normalized to focal length or to sensor half width?)
if (update[21]) subCam.distortionA7=parVect[21]; //21 r^7 (normalized to focal length or to sensor half width?)
if (update[22]) subCam.distortionA6=parVect[22]; //22 r^6 (normalized to focal length or to sensor half width?)
if (update[23]) subCam.distortionA5=parVect[23]; //23 r^5 (normalized to focal length or to sensor half width?)
if (update[24]) subCam.distortionA= parVect[24]; //24 r^4 (normalized to focal length or to sensor half width?)
if (update[25]) subCam.distortionB= parVect[25]; //25 r^3
if (update[26]) subCam.distortionC= parVect[26]; //26 r^2
}
public void initSubCameras(
int numStation,
int numSubCameras){
System.out.println("initSubCameras("+numStation+","+numSubCameras+")");
this.eyesisSubCameras[numStation]=new EyesisSubCameraParameters[numSubCameras];
for (int i=0;i<numSubCameras;i++) this.eyesisSubCameras[numStation][i]=null;
if (numSubCameras==3) {
this.eyesisSubCameras[numStation][0]=new EyesisSubCameraParameters( //TODO: modify for lens adjustment defaults?
0.0, // double azimuth, // azimuth of the lens entrance pupil center, degrees, clockwise looking from top
52.53, // double radius, // mm, distance from the rotation axis
34.64, // double height, // mm, up (was downwards) - from the origin point
0.0, // double phi, // degrees, optical axis from azimuth/r vector, clockwise
0.0, //double theta, // degrees, optical axis from the eyesis horizon, positive - up
180.0, //double psi; // degrees, rotation (of the sensor) around the optical axis. Positive if camera is rotated clockwise looking to the target
4.5, // double focalLength
2.2, // double pixelSize (um)
2.8512, //double distortionRadius mm - half width of the sensor
0.0, // double distortionA8 // r^8 (normalized to focal length or to sensor half width?)
0.0, // double distortionA7 // r^7 (normalized to focal length or to sensor half width?)
0.0, // double distortionA6 // r^6 (normalized to focal length or to sensor half width?)
0.0, // double distortionA5 // r^5 (normalized to focal length or to sensor half width?)
0.0, // double distortionA // r^4 (normalized to focal length or to sensor half width?)
0.0, // double distortionB // r^3
0.0, // double distortionC // r^2
1296.0, // double px0=1296.0; // center of the lens on the sensor, pixels
968.0, // double py0=968.0; // center of the lens on the sensor, pixels
1.0); //channelWeightDefault
this.eyesisSubCameras[numStation][1]=new EyesisSubCameraParameters( //TODO: modify for lens adjustment defaults?
30.0, // double azimuth, // azimuth of the lens entrance pupil center, degrees, clockwise looking from top
60.0, // double radius, // mm, distance from the rotation axis
-17.32, // double height, // mm, up (was downwards) - from the origin point
-30.0, // double phi, // degrees, optical axis from azimuth/r vector, clockwise
0.0, //double theta, // degrees, optical axis from the eyesis horizon, positive - up
180.0, //double psi; // degrees, rotation (of the sensor) around the optical axis. Positive if camera is rotated clockwise looking to the target
4.5, // double focalLength
2.2, // double pixelSize (um)
2.8512, //double distortionRadius mm - half width of the sensor
0.0, // double distortionA8 // r^8 (normalized to focal length or to sensor half width?)
0.0, // double distortionA7 // r^7 (normalized to focal length or to sensor half width?)
0.0, // double distortionA6 // r^6 (normalized to focal length or to sensor half width?)
0.0, // double distortionA5 // r^5 (normalized to focal length or to sensor half width?)
0.0, // double distortionA // r^4 (normalized to focal length or to sensor half width?)
0.0, // double distortionB // r^3
0.0, // double distortionC // r^2
1296.0, // double px0=1296.0; // center of the lens on the sensor, pixels
968.0, // double py0=968.0; // center of the lens on the sensor, pixels
1.0); //channelWeightDefault
this.eyesisSubCameras[numStation][2]=new EyesisSubCameraParameters( //TODO: modify for lens adjustment defaults?
-30.0, // double azimuth, // azimuth of the lens entrance pupil center, degrees, clockwise looking from top
60.0, // double radius, // mm, distance from the rotation axis
-17.32, // double height, // mm, up (was downwards) - from the origin point
30.0, // double phi, // degrees, optical axis from azimuth/r vector, clockwise
0.0, //double theta, // degrees, optical axis from the eyesis horizon, positive - up
180.0, //double psi; // degrees, rotation (of the sensor) around the optical axis. Positive if camera is rotated clockwise looking to the target
4.5, // double focalLength
2.2, // double pixelSize (um)
2.8512, //double distortionRadius mm - half width of the sensor
0.0, // double distortionA8 // r^8 (normalized to focal length or to sensor half width?)
0.0, // double distortionA7 // r^7 (normalized to focal length or to sensor half width?)
0.0, // double distortionA6 // r^6 (normalized to focal length or to sensor half width?)
0.0, // double distortionA5 // r^5 (normalized to focal length or to sensor half width?)
0.0, // double distortionA // r^4 (normalized to focal length or to sensor half width?)
0.0, // double distortionB // r^3
0.0, // double distortionC // r^2
1296.0, // double px0=1296.0; // center of the lens on the sensor, pixels
968.0, // double py0=968.0; // center of the lens on the sensor, pixels
1.0); //channelWeightDefault
} else if (numSubCameras==1) {
this.eyesisSubCameras[numStation][0]=new EyesisSubCameraParameters( //TODO: modify for lens adjustment defaults?
0.0, // double azimuth, // azimuth of the lens entrance pupil center, degrees, clockwise looking from top
0.0, // double radius, // mm, distance from the rotation axis
0.0, // double height, // mm, up (was downwards) - from the origin point
0.0, // double phi, // degrees, optical axis from azimuth/r vector, clockwise
0.0, //double theta, // degrees, optical axis from the eyesis horizon, positive - up
0.0, //double psi; // degrees, rotation (of the sensor) around the optical axis. Positive if camera is rotated clockwise looking to the target
4.5, // double focalLength
2.2, // double pixelSize (um)
2.8512, //double distortionRadius mm - half width of the sensor
0.0, // double distortionA8 // r^8 (normalized to focal length or to sensor half width?)
0.0, // double distortionA7 // r^7 (normalized to focal length or to sensor half width?)
0.0, // double distortionA6 // r^6 (normalized to focal length or to sensor half width?)
0.0, // double distortionA5 // r^5 (normalized to focal length or to sensor half width?)
0.0, // double distortionA // r^4 (normalized to focal length or to sensor half width?)
0.0, // double distortionB // r^3
0.0, // double distortionC // r^2
1296.0, // double px0=1296.0; // center of the lens on the sensor, pixels
968.0, // double py0=968.0; // center of the lens on the sensor, pixels
1.0); //channelWeightDefault
} else {
// default setup for the 26 sub-cameras
for (int i=0;i<8;i++) if (i<numSubCameras) this.eyesisSubCameras[numStation][i]=new EyesisSubCameraParameters( // top 8 cameras
45.0*i, // double azimuth, // azimuth of the lens entrance pupil center, degrees, clockwise looking from top
41.540, // double radius, // mm, distance from the rotation axis
42.883, // double height, // mm, up (was downwards?) - from the origin point
0.0, // double phi, // degrees, optical axis from azimuth/r vector, clockwise
60.0, //double theta, // degrees, optical axis from the eyesis horizon, positive - up
90.0, //double psi; // degrees, rotation (of the sensor) around the optical axis. Positive if camera is rotated clockwise looking to the target
4.5, // double focalLength
2.2, // double pixelSize (um)
2.8512, //double distortionRadius mm - half width of the sensor
0.0, // double distortionA8 // r^8 (normalized to focal length or to sensor half width?)
0.0, // double distortionA7 // r^7 (normalized to focal length or to sensor half width?)
0.0, // double distortionA6 // r^6 (normalized to focal length or to sensor half width?)
0.0, // double distortionA5 // r^5 (normalized to focal length or to sensor half width?)
0.0, // double distortionA // r^4 (normalized to focal length or to sensor half width?)
0.0, // double distortionB // r^3
0.0, // double distortionC // r^2
1296.0, // double px0=1296.0; // center of the lens on the sensor, pixels
968.0, // double py0=968.0; // center of the lens on the sensor, pixels
1.0); //channelWeightDefault
for (int i=8;i<16;i++) if (i<numSubCameras) this.eyesisSubCameras[numStation][i]=new EyesisSubCameraParameters( // middle 8 cameras
45.0*(i-8), // double azimuth, // azimuth of the lens entrance pupil center, degrees, clockwise looking from top
54.525, // double radius, // mm, distance from the rotation axis
0.0, // double height, // mm, up (was downwards) - from the origin point
0.0, // double phi, // degrees, optical axis from azimuth/r vector, clockwise
0.0, //double theta, // degrees, optical axis from the eyesis horizon, positive - up
90.0, //double psi; // degrees, rotation (of the sensor) around the optical axis. Positive if camera is rotated clockwise looking to the target
4.5, // double focalLength
2.2, // double pixelSize (um)
2.8512, //double distortionRadius mm - half width of the sensor
0.0, // double distortionA8 // r^8 (normalized to focal length or to sensor half width?)
0.0, // double distortionA7 // r^7 (normalized to focal length or to sensor half width?)
0.0, // double distortionA6 // r^6 (normalized to focal length or to sensor half width?)
0.0, // double distortionA5 // r^5 (normalized to focal length or to sensor half width?)
0.0, // double distortionA // r^4 (normalized to focal length or to sensor half width?)
0.0, // double distortionB // r^3
0.0, // double distortionC // r^2
1296.0, // double px0=1296.0; // center of the lens on the sensor, pixels
968.0, // double py0=968.0; // center of the lens on the sensor, pixels
1.0); //channelWeightDefault
for (int i=16;i<24;i++) if (i<numSubCameras) this.eyesisSubCameras[numStation][i]=new EyesisSubCameraParameters( // bottom eight cameras
45.0*(i-16), // double azimuth, // azimuth of the lens entrance pupil center, degrees, clockwise looking from top
41.540, // double radius, // mm, distance from the rotation axis
-42.883, // double height, // mm, up (was downwards?) - from the origin point
0.0, // double phi, // degrees, optical axis from azimuth/r vector, clockwise
-60.0, //double theta, // degrees, optical axis from the eyesis horizon, positive - up
-90.0, //double psi; // degrees, rotation (of the sensor) around the optical axis. Positive if camera is rotated clockwise looking to the target
4.5, // double focalLength
2.2, // double pixelSize (um)
2.8512, //double distortionRadius mm - half width of the sensor
0.0, // double distortionA8 // r^8 (normalized to focal length or to sensor half width?)
0.0, // double distortionA7 // r^7 (normalized to focal length or to sensor half width?)
0.0, // double distortionA6 // r^6 (normalized to focal length or to sensor half width?)
0.0, // double distortionA5 // r^5 (normalized to focal length or to sensor half width?)
0.0, // double distortionA // r^4 (normalized to focal length or to sensor half width?)
0.0, // double distortionB // r^3
0.0, // double distortionC // r^2
1296.0, // double px0=1296.0; // center of the lens on the sensor, pixels
968.0, // double py0=968.0; // center of the lens on the sensor, pixels
1.0); //channelWeightDefault
if (24<numSubCameras) this.eyesisSubCameras[numStation][24]=new EyesisSubCameraParameters(
90, // double azimuth, // azimuth of the lens entrance pupil center, degrees, clockwise looking from top
12.025, // double radius, // mm, distance from the rotation axis
-807.0, // double height, // mm, up - from the origin point
0.0, // double phi, // degrees, optical axis from azimuth/r vector, clockwise
0.0, //double theta, // degrees, optical axis from the eyesis horizon, positive - up
90.0, //double psi; // degrees, rotation (of the sensor) around the optical axis. Positive if camera is rotated clockwise looking to the target
4.5, // double focalLength
2.2, // double pixelSize (um)
2.8512, //double distortionRadius mm - half width of the sensor
0.0, // double distortionA8 // r^8 (normalized to focal length or to sensor half width?)
0.0, // double distortionA7 // r^7 (normalized to focal length or to sensor half width?)
0.0, // double distortionA6 // r^6 (normalized to focal length or to sensor half width?)
0.0, // double distortionA5 // r^5 (normalized to focal length or to sensor half width?)
0.0, // double distortionA // r^4 (normalized to focal length or to sensor half width?)
0.0, // double distortionB // r^3
0.0, // double distortionC // r^2
1296.0, // double px0=1296.0; // center of the lens on the sensor, pixels
968.0, // double py0=968.0; // center of the lens on the sensor, pixels
4.0); //channelWeightDefault
if (25<numSubCameras) this.eyesisSubCameras[numStation][25]=new EyesisSubCameraParameters(
270, // double azimuth, // azimuth of the lens entrance pupil center, degrees, clockwise looking from top
12.025, // double radius, // mm, distance from the rotation axis
-841.0, // double height, // mm, up - from the origin point
0.0, // double phi, // degrees, optical axis from azimuth/r vector, clockwise
0.0, //double theta, // degrees, optical axis from the eyesis horizon, positive - up
-90.0, //double psi; // degrees, rotation (of the sensor) around the optical axis. Positive if camera is rotated clockwise looking to the target
4.5, // double focalLength
2.2, // double pixelSize (um)
2.8512, //double distortionRadius mm - half width of the sensor
0.0, // double distortionA8 // r^8 (normalized to focal length or to sensor half width?)
0.0, // double distortionA7 // r^7 (normalized to focal length or to sensor half width?)
0.0, // double distortionA6 // r^6 (normalized to focal length or to sensor half width?)
0.0, // double distortionA5 // r^5 (normalized to focal length or to sensor half width?)
0.0, // double distortionA // r^4 (normalized to focal length or to sensor half width?)
0.0, // double distortionB // r^3
0.0, // double distortionC // r^2
1296.0, // double px0=1296.0; // center of the lens on the sensor, pixels
968.0, // double py0=968.0; // center of the lens on the sensor, pixels
4.0); //channelWeightDefault
}
}
public void recenterVertically(boolean [] subcams, boolean [] stations){
boolean sameCenterAboveHorizontal=true;
double cah=Double.NaN;
for (int i=0;i<stations.length;i++){
if (stations[i]) {
if (Double.isNaN(cah)) cah=this.centerAboveHorizontal[i];
else if (cah!=this.centerAboveHorizontal[i]) sameCenterAboveHorizontal=false;
}
}
if (Double.isNaN(cah)){
System.out.println("No stations enabled, nothing to do for vertical centering");
return;
}
System.out.println("centerAboveHorizontal "+
(sameCenterAboveHorizontal?"is common for all stations":"differs between stations"));
if (sameCenterAboveHorizontal){
System.out.println("Re-centering vertically for centerAboveHorizontal common for all stations ");
double sumWeightedHeights=0.0;
double sumWeights=0.0;
for (int i=0;i<stations.length;i++) if (stations[i]) {
for (int subIndex=0; subIndex<subcams.length;subIndex++) if (subcams[subIndex]){
System.out.println("Averaging station "+i+", subcamera "+subIndex);
sumWeights+=stationWeight[i];
sumWeightedHeights+=stationWeight[i]*eyesisSubCameras[i][subIndex].height;
}
}
if (sumWeights==0.0){
System.out.println("No subcams are enabled, nothing to do for vertical centering");
return;
}
sumWeightedHeights/=sumWeights;
for (int i=0;i<stations.length;i++) if (stations[i]) {
for (int subIndex=0; subIndex<subcams.length;subIndex++) { // need to update all channels, not only averaged
eyesisSubCameras[i][subIndex].height-=sumWeightedHeights;
}
this.centerAboveHorizontal[i]+=sumWeightedHeights;
}
} else {
System.out.println("Re-centering vertically for centerAboveHorizontal individual for each station");
for (int i=0;i<stations.length;i++) if (stations[i]) {
double sumWeightedHeights=0.0;
double sumWeights=0.0;
for (int subIndex=0; subIndex<subcams.length;subIndex++) if (subcams[subIndex]){
System.out.println("Averaging station "+i+", subcamera "+subIndex);
sumWeights+=stationWeight[i];
sumWeightedHeights+=stationWeight[i]*eyesisSubCameras[i][subIndex].height;
}
if (sumWeights==0.0){
System.out.println("No subcams are enabled, nothing to do for vertical centering");
return;
}
sumWeightedHeights/=sumWeights;
for (int subIndex=0; subIndex<subcams.length;subIndex++) { // need to update all channels, not only averaged
eyesisSubCameras[i][subIndex].height-=sumWeightedHeights;
}
this.centerAboveHorizontal[i]+=sumWeightedHeights;
}
}
}
}
\ No newline at end of file
/*
**
** EyesisSubCameraParameters.java
**
** Copyright (C) 2011-2014 Elphel, Inc.
**
** -----------------------------------------------------------------------------**
**
** EyesisSubCameraParameters.java is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
** -----------------------------------------------------------------------------**
**
*/
import java.util.Properties;
public class EyesisSubCameraParameters{
// origin is on the rotation axis of the tube body closest to the goniometer horizontal axis
public double azimuth; // azimuth of the lens entrance pupil center, degrees, clockwise looking from top
public double radius; // mm, distance from the rotation axis
public double height; // mm, up - from the origin point
public double phi; // degrees, optical axis from azimuth/r vector, clockwise
public double theta; // degrees, optical axis from the eyesis horizon, positive - up
public double psi; // degrees, rotation (of the sensor) around the optical axis. Positive if camera is rotated clockwise looking to the target
public double focalLength=4.5;
public double pixelSize= 2.2; //um
public double distortionRadius= 2.8512; // mm - half width of the sensor
public double distortionA8=0.0; //r^8 (normalized to focal length or to sensor half width?)
public double distortionA7=0.0; //r^7 (normalized to focal length or to sensor half width?)
public double distortionA6=0.0; //r^6 (normalized to focal length or to sensor half width?)
public double distortionA5=0.0; //r^5 (normalized to focal length or to sensor half width?)
public double distortionA=0.0; // r^4 (normalized to focal length or to sensor half width?)
public double distortionB=0.0; // r^3
public double distortionC=0.0; // r^2
public double px0=1296.0; // center of the lens on the sensor, pixels
public double py0=968.0; // center of the lens on the sensor, pixels
public double channelWeightDefault=1.0;
public double channelWeightCurrent=1.0;
public int [][] defectsXY=null; // pixel defects coordinates list (starting with worst)
public double [] defectsDiff=null; // pixel defects value (diff from average of neighbors), matching defectsXY
public EyesisSubCameraParameters(
double azimuth, // azimuth of the lens entrance pupil center, degrees, clockwise looking from top
double radius, // mm, distance from the rotation axis
double height, // mm, up from the origin point
double phi, // degrees, optical axis from azimuth/r vector, clockwise
double theta, // degrees, optical axis from the eyesis horizon, positive - up
double psi, // degrees, rotation (of the sensor) around the optical axis. Positive if camera is rotated clockwise looking to the target
double focalLength,
double pixelSize,//um
double distortionRadius, //mm - half width of the sensor
double distortionA8, // r^8
double distortionA7, // r^7
double distortionA6, // r^5
double distortionA5, // r^5
double distortionA, // r^4 (normalized to focal length or to sensor half width?)
double distortionB, // r^3
double distortionC, // r^2
double px0, // center of the lens on the sensor, pixels
double py0, // center of the lens on the sensor, pixels
double channelWeightDefault
){
this.azimuth=azimuth;
this.radius=radius;
this.height=height;
this.phi=phi;
this.theta=theta;
this.psi=psi;
this.focalLength=focalLength;
this.pixelSize= pixelSize; //um
this.distortionRadius= distortionRadius; // mm - half width of the sensor
this.distortionA8=distortionA8;
this.distortionA7=distortionA7;
this.distortionA6=distortionA6;
this.distortionA5=distortionA5;
this.distortionA=distortionA; // r^4 (normalized to focal length or to sensor half width?)
this.distortionB=distortionB; // r^3
this.distortionC=distortionC; // r^2
this.px0=px0;
this.py0=py0;
this.channelWeightDefault=channelWeightDefault;
this.channelWeightCurrent=this.channelWeightDefault;
this.defectsXY=null; // pixel defects coordinates list (starting with worst)
this.defectsDiff=null; // pixel defects value (diff from average of neighbors), matching defectsXY
}
// defects are not cloned!
public EyesisSubCameraParameters clone() {
return new EyesisSubCameraParameters(
this.azimuth,
this.radius,
this.height,
this.phi,
this.theta,
this.psi,
this.focalLength,
this.pixelSize,
this.distortionRadius,
this.distortionA8,
this.distortionA7,
this.distortionA6,
this.distortionA5,
this.distortionA,
this.distortionB,
this.distortionC,
this.px0,
this.py0,
this.channelWeightDefault
);
}
public void setProperties(String prefix,Properties properties){
properties.setProperty(prefix+"azimuth",this.azimuth+"");
properties.setProperty(prefix+"radius",this.radius+"");
properties.setProperty(prefix+"height",this.height+"");
properties.setProperty(prefix+"phi",this.phi+"");
properties.setProperty(prefix+"theta",this.theta+"");
properties.setProperty(prefix+"psi",this.psi+"");
properties.setProperty(prefix+"focalLength",this.focalLength+"");
properties.setProperty(prefix+"pixelSize",this.pixelSize+"");
properties.setProperty(prefix+"distortionRadius",this.distortionRadius+"");
properties.setProperty(prefix+"distortionA8",this.distortionA8+"");
properties.setProperty(prefix+"distortionA7",this.distortionA7+"");
properties.setProperty(prefix+"distortionA6",this.distortionA6+"");
properties.setProperty(prefix+"distortionA5",this.distortionA5+"");
properties.setProperty(prefix+"distortionA",this.distortionA+"");
properties.setProperty(prefix+"distortionB",this.distortionB+"");
properties.setProperty(prefix+"distortionC",this.distortionC+"");
properties.setProperty(prefix+"px0",this.px0+"");
properties.setProperty(prefix+"py0",this.py0+"");
properties.setProperty(prefix+"channelWeightDefault",this.channelWeightDefault+"");
}
public void getProperties(String prefix,Properties properties){
if (properties.getProperty(prefix+"azimuth")!=null)
this.azimuth=Double.parseDouble(properties.getProperty(prefix+"azimuth"));
if (properties.getProperty(prefix+"radius")!=null)
this.radius=Double.parseDouble(properties.getProperty(prefix+"radius"));
if (properties.getProperty(prefix+"height")!=null)
this.height=Double.parseDouble(properties.getProperty(prefix+"height"));
if (properties.getProperty(prefix+"phi")!=null)
this.phi=Double.parseDouble(properties.getProperty(prefix+"phi"));
if (properties.getProperty(prefix+"theta")!=null)
this.theta=Double.parseDouble(properties.getProperty(prefix+"theta"));
if (properties.getProperty(prefix+"psi")!=null)
this.psi=Double.parseDouble(properties.getProperty(prefix+"psi"));
if (properties.getProperty(prefix+"focalLength")!=null)
this.focalLength=Double.parseDouble(properties.getProperty(prefix+"focalLength"));
if (properties.getProperty(prefix+"pixelSize")!=null)
this.pixelSize=Double.parseDouble(properties.getProperty(prefix+"pixelSize"));
if (properties.getProperty(prefix+"distortionRadius")!=null)
this.distortionRadius=Double.parseDouble(properties.getProperty(prefix+"distortionRadius"));
if (properties.getProperty(prefix+"distortionA8")!=null)
this.distortionA8=Double.parseDouble(properties.getProperty(prefix+"distortionA8"));
if (properties.getProperty(prefix+"distortionA7")!=null)
this.distortionA7=Double.parseDouble(properties.getProperty(prefix+"distortionA7"));
if (properties.getProperty(prefix+"distortionA6")!=null)
this.distortionA6=Double.parseDouble(properties.getProperty(prefix+"distortionA6"));
if (properties.getProperty(prefix+"distortionA5")!=null)
this.distortionA5=Double.parseDouble(properties.getProperty(prefix+"distortionA5"));
if (properties.getProperty(prefix+"distortionA")!=null)
this.distortionA=Double.parseDouble(properties.getProperty(prefix+"distortionA"));
if (properties.getProperty(prefix+"distortionB")!=null)
this.distortionB=Double.parseDouble(properties.getProperty(prefix+"distortionB"));
if (properties.getProperty(prefix+"distortionC")!=null)
this.distortionC=Double.parseDouble(properties.getProperty(prefix+"distortionC"));
if (properties.getProperty(prefix+"px0")!=null)
this.px0=Double.parseDouble(properties.getProperty(prefix+"px0"));
if (properties.getProperty(prefix+"py0")!=null)
this.py0=Double.parseDouble(properties.getProperty(prefix+"py0"));
if (properties.getProperty(prefix+"channelWeightDefault")!=null) {
this.channelWeightDefault=Double.parseDouble(properties.getProperty(prefix+"channelWeightDefault"));
this.channelWeightCurrent=this.channelWeightDefault;
}
}
public void setChannelWeightCurrent(
double weight){
this.channelWeightCurrent=weight;
}
public double getChannelWeightCurrent(){
return this.channelWeightCurrent;
}
public double getChannelWeightDefault(){
return this.channelWeightDefault;
}
}
...@@ -2516,7 +2516,7 @@ private Panel panel1,panel2,panel3,panel4,panel5,panel5a, panel6,panel7,panelPos ...@@ -2516,7 +2516,7 @@ private Panel panel1,panel2,panel3,panel4,panel5,panel5a, panel6,panel7,panelPos
return false; return false;
} }
/* ======================================================================== */ /* ======================================================================== */
private String [] selectSourceFiles(String [] defaultPaths) { public String [] selectSourceFiles(String [] defaultPaths) {
String []patterns={".jp4",".jp46",".tiff",".tif"}; String []patterns={".jp4",".jp46",".tiff",".tif"};
return selectFiles(false, // save return selectFiles(false, // save
"Source file(s) selection", // title "Source file(s) selection", // title
......
/*
**
** FittingStrategy.java
**
** Copyright (C) 2011-2014 Elphel, Inc.
**
** -----------------------------------------------------------------------------**
**
** FittingStrategy.java is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
** -----------------------------------------------------------------------------**
**
*/
import ij.IJ;
import ij.gui.GenericDialog;
import ij.text.TextWindow;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.XMLConfiguration;
/**
*
* Specifies images to process and parameters to adjust
* Each parameter cab be:
* 0 - "fixed" - use individual, per-image parameters, do not modify them
* 1 - "common" - parameters are common for all selected images.
* When saving - save to all selected images.
* When loading (if different) use "master image" (or closest to it in time)
* 2 - "super common" - same as common, but save to all images, not just selected
* 3 - "individual"
* 4 - "per group"
* 5 - "per-station"
* 6 - "per-station" save to all (super)
* 7 - "weak common" - like common, but enable small individual variations (for a price) - not yet implemented, will have separate weight fixed/floating
* 8 - "weak station" - like per-station, but enable individual (for a price)
*
+====================+===========+===========+
| | Same TS | Diff TS |
| +-----+-----+-----+-----+
| | C | I | C | I |
+============+=======+=====+=====+=====+=====+
| Same |Eyesis | X | X | C | I |
| Subcamera +-------+-----+-----+-----+-----+
| |Subcam | X | X | C | I* |
+============+=======+=====+=====+=====+=====+
| Different |Eyesis | C | C | C | I |
| Subcameras +-------+-----+-----+-----+-----+
| |Subcam | I | I | I | I |
+============+=======+=====+=====+=====+=====+
I* - special case when the subcamera is being adjusted/replaced. How to deal with it?
*
*/
public class FittingStrategy{
public String pathName=null; // path to XML file this instance was created from
public DistortionCalibrationData distortionCalibrationData=null;// per-image parameters
private boolean [][] selectedImages=null; // images selected for each step (will be masked with enabled images)
private boolean [][] selectedValidImages=null; // images selected for each step same as selected, but only if number of weight>0.0 nodes > threshold
public boolean [] stopAfterThis=null;
final public int modeFixed=0,modeCommon=1,modeSupercommon=2,modeIndividual=3,modeGroup=4;
final public int modeStation=5,modeSuperStation=6,modeWeakCommon=7,modeWeakStation=8,modeTiltEqualize=9;
public String[] definedModes={
"fixed", // modeFixed=0
"common", // modeCommon=1
"common, save to all", // modeSupercommon=2
"individual", // modeIndividual=3
"per-group", // modeGroup=4
"per-station", // modeStation=5
"per-station, save to all", // modeSuperStation=6
"weak common, save to all", // modeWeakCommon=7
"weak per-station, save to all" // modeWeakStation=8
};
public String[] definedModesNoWeak={ // show for parameters that can not use weak
"fixed", // modeFixed=0
"common", // modeCommon=1
"common, save to all", // modeSupercommon=2
"individual", // modeIndividual=3
"per-group", // modeGroup=4
"per-station", // modeStation=5
"per-station, save to all" // modeSuperStation=6
// "weak common", // modeWeakCommon=7
// "weak per-station", // modeWeakStation=8
};
public String[] definedModesTiltEq={ // show for parameters that can not use weak
"fixed", // modeFixed=0
"common", // modeCommon=1
"common, save to all", // modeSupercommon=2
"individual", // modeIndividual=3
"per-group", // modeGroup=4
"per-station", // modeStation=5
"per-station, save to all", // modeSuperStation=6
"weak common, save to all", // modeWeakCommon=7
"weak per-station, save to all",// modeWeakStation=8
"tilt equalize" // modeTiltEqualize
};
public String[] definedModesAll= definedModesTiltEq;
public int [][] parameterMode=null; // per series, per-parameter
public int [][][] parameterGroups=null; // per series, per-parameter - null or array of group numbers (1 element per image)
public int [][] zGroups=null;
public boolean saveUnusedGroups=false; // purge groups for parameters when saving to XML, preserve if true
public double [] lambdas=null; // LMA initial lambda for each step
public double defaultLambda=0.001;
public int [][] parameterList=null; // list of all parameters in the system, each has subcamera number and parameters index
public boolean [] parameterEnable=null; // select which parameters (of some 320 to display in selector)
public int [] masterImages=null; // number of image no take "common" parameters from if they are different
public double defaultStepDone=1.0E-6;
public double [] stepDone=null;// delta_error to error ratio to consider series finished
// public double [] parameterVector;
public int [][] parameterMap=null;// ** valid for one strategy sequence *** for each parameter vector element hold image number/parameter number
public int [][] reverseParameterMap=null; // reversed map - for each [imageNumber][parameterNumber] -> vector index (-1 fixed)
public int currentSeriesNumber=-1; // currently selected strategy step (for which parameterMap and reverseParameterMap)
public int debugLevel=2;
public int [] varianceModes=null; // per-series: 0 - disabled, 1 - constant imageSets weight, 2 - variable imageSets weight
final public int varianceModeDisabled=0,varianceModeSameWeight=1,varianceModeVariableWeight=2;
public String [] definedVarianceModes={
"disabled",
"same weight",
"variable weight",
};
// next arrays will be initialized at buildVariancesMaps only if at least some parameters use variances, otherwise they will be null
public double [] variationsAverages=null; // holds per extrinsic parameter or per parameter/per station average values
public int [] averageCellIndex= null; // for each element in the parameters vector holds index in variationsAverages array
public double [] weightOnAverage= null; // how variation of this parameter influences average (for all or for currenrt station
public double [] weightVariance= null; // weight for LMA over variance of parameters from average
public double [] varianceErrorsSquared= null; // weighted squared errors
public FittingStrategy(
DistortionCalibrationData distortionCalibrationData// per-image parameters
) {
this.distortionCalibrationData=distortionCalibrationData;
setDflt(0);
}
public FittingStrategy(
DistortionCalibrationData distortionCalibrationData,// per-image parameters
int numSeries // number of iteration series
){
this.distortionCalibrationData=distortionCalibrationData;
this.selectedImages=new boolean[numSeries][this.distortionCalibrationData.getNumImages()];
this.selectedValidImages=new boolean[numSeries][this.distortionCalibrationData.getNumImages()];
setDflt(numSeries);
}
public FittingStrategy(
boolean smart,
String defaultPath,
DistortionCalibrationData distortionCalibrationData // per-image parameters
) {
String [] extensions={".stg-xml","-strategy.xml"};
CalibrationFileManagement.MultipleExtensionsFileFilter parFilter = new CalibrationFileManagement.MultipleExtensionsFileFilter("",extensions,"*.stg-xml files");
String pathname=CalibrationFileManagement.selectFile(
smart,
false,
"Restore Fitting Strategy",
"Restore",
parFilter,
defaultPath); //String defaultPath
if ((pathname==null) || (pathname=="")) return;
setFromXML(
distortionCalibrationData, // per-image parameters
pathname);
System.out.println("Restored fitting strategy from "+pathname);
}
/**
* Reads FittingStrategy from an XML file
* @param distortionCalibrationData should be defined before this class!
* @param pathname pathe to the saved data
*/
public FittingStrategy(
DistortionCalibrationData distortionCalibrationData, // per-image parameters
String pathname
) {
setFromXML(
distortionCalibrationData, // per-image parameters
pathname);
}
public void setFromXML(
DistortionCalibrationData distortionCalibrationData, // per-image parameters
String pathname
) {
this.distortionCalibrationData=distortionCalibrationData;
XMLConfiguration hConfig=null;
try {
hConfig=new XMLConfiguration(pathname);
} catch (ConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
hConfig.setThrowExceptionOnMissing(false); // default value, will return null on missing
// read parameterList
int len=Integer.parseInt(hConfig.getString("parameterMap.length","0"));
if (len<=0) {
String msg="No parameterMap specified in "+ pathname;
IJ.showMessage("Error",msg);
throw new IllegalArgumentException (msg);
}
this.parameterList=new int [len][2];
this.parameterEnable=new boolean[len];
for (int i=0; i<this.parameterList.length; i++){
this.parameterList[i][0]=Integer.parseInt(hConfig.getString("parameterMap.par_"+i+".subcamera"));
this.parameterList[i][1]=Integer.parseInt(hConfig.getString("parameterMap.par_"+i+".index"));
this.parameterEnable[i]= (Integer.parseInt(hConfig.getString("parameterMap.par_"+i+".visible"))>0);
}
int nSer=Integer.parseInt(hConfig.getString("series.number","0"));
if (nSer==0) return; // arrays will just be null
this.selectedImages=new boolean[nSer][];
this.selectedValidImages=new boolean[nSer][];
this.masterImages=new int[nSer];
this.stopAfterThis=new boolean[nSer];
for (int i=0;i<nSer;i++) this.stopAfterThis[i]=true; // older configuration files did not have it
this.parameterMode=new int[nSer][len];
this.varianceModes=new int[nSer];
this.zGroups=new int [nSer][];
this.parameterGroups=new int[nSer][len][];
this.lambdas=new double [nSer];
this.stepDone=new double [nSer];
for (int i=0;i<nSer;i++){ // iterate through series
//this.stopAfterThis
// read selected images (no check here that it matches to the distortionCalibrationData!
String sSeries="series.series_"+i;
String fs=hConfig.getString(sSeries+".selectedImages");
this.selectedImages[i]=new boolean[fs.length()];
this.selectedValidImages[i]=null;
for (int j=0;j<this.selectedImages[i].length;j++) this.selectedImages[i][j]=(fs.charAt(j)=='+');
this.masterImages[i]=Integer.parseInt(hConfig.getString(sSeries+".masterImage"));
if (hConfig.getString(sSeries+".varianceModes")!=null) {
this.varianceModes[i]=Integer.parseInt(hConfig.getString(sSeries+".varianceModes"));
} else {
this.varianceModes[i]=varianceModeDisabled;
}
for (int j=0;j<this.parameterList.length;j++){
int nPar=this.parameterList[j][1];
int nSub=this.parameterList[j][0];
String hconfigName=sSeries+".parameterMode."+
this.distortionCalibrationData.parameterDescriptions[nPar][0]+
(this.distortionCalibrationData.isSubcameraParameter(nPar)?("_sub"+nSub):"");
// System.out.println("Setting this.parameterMode["+i+"]["+j+"] from " +hconfigName);
if (hConfig.getString(hconfigName)!=null) this.parameterMode[i][j]=Integer.parseInt(hConfig.getString(hconfigName));
else System.out.println("Failed to set this.parameterMode["+i+"]["+j+"] from " +hconfigName+" - maybe it is a new parameter not present in the file "+pathname);
this.parameterGroups[i][j]=null;
//Try to read series
for (int ni=0;ni<this.selectedImages.length;ni++){
String sGroup=hConfig.getString(sSeries+".parameterMode."+
this.distortionCalibrationData.parameterDescriptions[nPar][0]+
(this.distortionCalibrationData.isSubcameraParameter(nPar)?("_sub"+nSub):"")+
"_group"+ni);
if (sGroup!=null){
if (this.parameterGroups[i][j]==null){
this.parameterGroups[i][j]=new int[this.selectedImages.length];
for (int ni1=0;ni1<this.selectedImages.length;ni1++)this.parameterGroups[i][j][ni1]=0;
}
this.parameterGroups[i][j][ni]=Integer.parseInt(sGroup);
}
}
}
this.lambdas[i]=Double.parseDouble(hConfig.getString(sSeries+".lambdas"));
this.stepDone[i]=Double.parseDouble(hConfig.getString(sSeries+".stepDone"));
if (hConfig.getString(sSeries+".stopAfterThis")!=null){
this.stopAfterThis[i]=Boolean.parseBoolean(hConfig.getString(sSeries+".stopAfterThis"));
}
String zGroupsName=sSeries+".zGroups";
if (hConfig.getString(zGroupsName)!=null) {
int numZgroups=Integer.parseInt(hConfig.getString(zGroupsName));
this.zGroups[i]=new int [numZgroups];
for (int nZGroup=0;nZGroup<numZgroups;nZGroup++){
this.zGroups[i][nZGroup]=Integer.parseInt(hConfig.getString(sSeries+".zGroup_"+nZGroup));
}
} else {
this.zGroups[i]=null;
}
}
// if (hConfig.getString("variances")!=null){
// if (!hConfig.configurationAt("variances").isEmpty()){
if (hConfig.configurationsAt("variances").size()>0){
// System.out.println("hConfig.configurationAt(\"variances\").isEmpty()=false");
this.distortionCalibrationData.eyesisCameraParameters.getCostsPropertiesXML("variances.",hConfig);
}
this.pathName=pathname;
// distortionCalibrationData.readAllGrids();
}
/**
* Adjust selectedImages and parameterGroups after number of images may change, old number of images should be >0
* If the new number is larger, the first images attributes will be copied, the extra ones - use those of the last of the old ones
* @param newNumberOfImages new number of images used by this series
*/
public void adjustNumberOfImages(int newNumberOfImages){
if ((this.selectedImages == null) ||(this.selectedImages[0].length==0)) {
String msg="selectedImages array is "+((this.selectedImages == null)?"null":"empty");
IJ.showMessage("Error",msg);
throw new IllegalArgumentException (msg);
}
if (this.selectedImages[0].length==newNumberOfImages) return;
for (int nSer=0;nSer<this.selectedImages.length;nSer++){
boolean [] tmp=selectedImages[nSer].clone();
this.selectedImages[nSer]=new boolean[newNumberOfImages];
this.selectedValidImages[nSer]=null; // just invalidate
for (int i=0;i<newNumberOfImages;i++) this.selectedImages[nSer][i]=(i<tmp.length)?tmp[i]:tmp[tmp.length-1];
for (int nPar=0;nPar<this.parameterList.length;nPar++){
if (this.parameterGroups[nSer][nPar]!=null){
int [] tmpGroup=this.parameterGroups[nSer][nPar].clone();
this.parameterGroups[nSer][nPar]=new int[newNumberOfImages];
for (int i=0;i<newNumberOfImages;i++) this.parameterGroups[nSer][nPar][i]=(i<tmpGroup.length)?tmpGroup[i]:tmpGroup[tmpGroup.length-1];
}
}
}
}
public String selectAndSaveToXML(
boolean smart,
String defaultPath){
String [] extensions={".stg-xml","-strategy.xml"};
CalibrationFileManagement.MultipleExtensionsFileFilter parFilter = new CalibrationFileManagement.MultipleExtensionsFileFilter("",extensions,"*.stg-xml files");
if ((defaultPath==null) || (defaultPath.length()==0)){
defaultPath=this.pathName;
}
String pathname=CalibrationFileManagement.selectFile(
smart,
true,
"Save Fitting Strategy",
"Save",
parFilter,
defaultPath); //String defaultPath
if (pathname!=null) saveToXML(pathname);
return pathname;
}
//http://commons.apache.org/configuration/userguide/howto_xml.html
public boolean saveToXML(String pathname) {
if (pathname==null) return false;
XMLConfiguration hConfig=new XMLConfiguration();
hConfig.setRootElementName("FittingStrategy");
// write which of the overall parameter correspond to each global/subcamera one, and which parameters are hidden/shown
hConfig.addProperty("parameterMap","");
hConfig.addProperty("parameterMap.length",this.parameterList.length);
for (int i=0; i<this.parameterList.length; i++){
hConfig.addProperty("parameterMap.par_"+i,"");
hConfig.addProperty("parameterMap.par_"+i+".subcamera",this.parameterList[i][0]);
hConfig.addProperty("parameterMap.par_"+i+".index",this.parameterList[i][1]);
hConfig.addProperty("parameterMap.par_"+i+".visible",this.parameterEnable[i]?"1":"0");
}
hConfig.addProperty("series","");
hConfig.addProperty("series.number",this.selectedImages.length);
for (int i=0;i<this.selectedImages.length;i++){ // iterate through series
String sSeries="series.series_"+i;
hConfig.addProperty(sSeries,"");
String fs="";
for (int j=0;j<this.selectedImages[i].length;j++)fs+=this.selectedImages[i][j]?"+":"-";
hConfig.addProperty(sSeries+".selectedImages",fs);
hConfig.addProperty(sSeries+".masterImage",this.masterImages[i]);
if (this.varianceModes!=null) hConfig.addProperty(sSeries+".varianceModes",this.varianceModes[i]);
hConfig.addProperty(sSeries+".parameterMode","");
for (int j=0;j<this.parameterList.length;j++){
int nPar=this.parameterList[j][1];
int nSub=this.parameterList[j][0];
hConfig.addProperty(sSeries+".parameterMode."+
this.distortionCalibrationData.parameterDescriptions[nPar][0]+
(this.distortionCalibrationData.isSubcameraParameter(nPar)?("_sub"+nSub):""),
this.parameterMode[i][j]);
// cleaning up output - removing unused groups (may disable
if (((this.parameterMode[i][j]==this.modeGroup) || this.saveUnusedGroups ) && (this.parameterGroups[i][j]!=null)){
for (int ni=0;ni<this.parameterGroups[i][j].length;ni++){
hConfig.addProperty(sSeries+".parameterMode."+
this.distortionCalibrationData.parameterDescriptions[nPar][0]+
(this.distortionCalibrationData.isSubcameraParameter(nPar)?("_sub"+nSub):"") +"_group"+ni,
this.parameterGroups[i][j][ni]);
}
}
}
if (this.zGroups[i]!=null) {
hConfig.addProperty(sSeries+".zGroups", this.zGroups[i].length);
for (int nZGroup=0;nZGroup<this.zGroups[i].length;nZGroup++){
hConfig.addProperty(sSeries+".zGroup_"+nZGroup,this.zGroups[i][nZGroup]);
}
}
hConfig.addProperty(sSeries+".lambdas",lambdas[i]);
hConfig.addProperty(sSeries+".stepDone",stepDone[i]);
hConfig.addProperty(sSeries+".stopAfterThis",this.stopAfterThis[i]);
}
hConfig.addProperty("variances","");
this.distortionCalibrationData.eyesisCameraParameters.setCostsPropertiesXML("variances.",hConfig);
File file=new File (pathname);
BufferedWriter writer;
try {
writer = new BufferedWriter(new FileWriter(file));
hConfig.save(writer);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.pathName=pathname;
return true;
}
/**
* Verifies that series exists and is not empty (valid for LMA)
* @param num - series to verify
* @return true if series is valid
*/
public boolean isSeriesValid(int num){
if ((num<0) || (num>=this.selectedImages.length)) return false;
boolean someImagesSelected=false;
for (int i=0;i<this.selectedImages[num].length;i++) if (this.selectedImages[num][i]){
someImagesSelected=true;
break;
}
if (!someImagesSelected) {
if (this.debugLevel>0) System.out.println("isSeriesValid("+num+"): no images selected");
return false;
}
boolean someParametersSelected=false;
for (int i=0;i<this.parameterMode[num].length;i++) if (this.parameterMode[num][i]>0){
someParametersSelected=true;
break;
}
if (!someParametersSelected) {
if (this.debugLevel>0) System.out.println("isSeriesValid("+num+"): no parameters selected");
return false;
}
return true;
}
/**
* Determins if LMA should stop after this series (either flag is set or next is invalid)
* @param num number of series to test
* @return true if LMA should stop
*/
public boolean isLastSeries(int num){
if (this.stopAfterThis[num]) return true;
if (!isSeriesValid(num+1)) return true;
return false;
}
/**
*
* Specifies images to process and parameters to adjust
* Each parameter cab be:
* 0 - "fixed" - use individual, per-image parameters, do not modify them
* 1 - "common" - parameters are common for all selected images.
* When saving - save to all selected images.
* When loading (if different) use "master image" (or closest to it in time)
* 2 - "super common" - same as common, but save to all images, not just selected
* 3 - "individual"
+====================+===========+===========+
| | Same TS | Diff TS |
| +-----+-----+-----+-----+
| | C | I | C | I |
+============+=======+=====+=====+=====+=====+
| Same |Eyesis | X | X | C | I |
| Subcamera +-------+-----+-----+-----+-----+
| |Subcam | X | X | C | I* |
+============+=======+=====+=====+=====+=====+
| Different |Eyesis | C | C | C | I |
| Subcameras +-------+-----+-----+-----+-----+
| |Subcam | X | X | X | X | subcameras for different subcameras are individual parameters
+============+=======+=====+=====+=====+=====+
I* - special case when the subcamera is being adjusted/replaced. How to deal with it?
*
*/
// public int [][] reverseParameterMap=null; // reversed map - for each [imageNumber][parameterNumber] -> vector index (-1 fixed)\
// selects all enabled images in the specified series (modifies strategy series!)
/**
* selects all enabled images in the specified series (modifies strategy series!)
* @param ser number of fitting strategy series to set
* @return old value for series images selection
*/
public boolean [] selectAllImages(int ser){
// this.selectedValidImages[ser]=null; // just invalidate - do nothing, so restore would work
boolean [] oldSelection=this.selectedImages[ser].clone();
for (int i=0;i<this.selectedImages[ser].length;i++) this.selectedImages[ser][i]=true; // select all\
return oldSelection;
}
/**
* Sets image selection. Can be used to restore saved selection after selectAllImages(int ser)
* @param ser number of fitting strategy series to set
* @param selection array specifying selected images
*/
public void setImageSelection(int ser, boolean [] selection){
this.selectedImages[ser]=selection.clone();
}
public boolean [] selectedAllImages() {
// if (this.currentSeriesNumber<0) return null;
return selectedAllImages(this.currentSeriesNumber);
}
public boolean [] selectedAllImages(int ser) {
if ((ser<0) || (ser>=this.selectedImages.length)){
boolean [] allImages=new boolean[this.selectedImages[0].length];
for (int i=0;i<allImages.length;i++) allImages[i]=true; // select all
return allImages;
} else {
return this.selectedImages[ser];
}
}
public boolean [] selectedImages() {
// if (this.currentSeriesNumber<0) return null;
return selectedImages(this.currentSeriesNumber);
}
public boolean [] selectedImagesNoBadKernels(int ser) {
boolean [] selected=selectedImages(ser);
for (int i=0;i<selected.length;i++) selected[i]&= !this.distortionCalibrationData.gIP[i].noUsefulPSFKernels;
return selected;
}
public void setNoUsefulPSFKernels(int i, boolean noUsefulPSFKernels){
this.distortionCalibrationData.gIP[i].noUsefulPSFKernels=noUsefulPSFKernels;
}
public void invalidateSelectedImages(int ser){
this.selectedValidImages[ser]=null;
}
public void initSelectedValidImages(int ser){
this.selectedValidImages[ser]=this.selectedImages[ser].clone();
}
public void invalidateSelectedImage(int ser,int nImg){
this.selectedValidImages[ser][nImg]=false;
}
//this.selectedValidImages
public boolean [] selectedImages(int ser) {
return selectedImages(ser,false);
}
public boolean [] selectedImages(int ser, boolean userSelection) {
boolean [] selectedMasked;
if ((ser<0) || (ser>=this.selectedImages.length)){
selectedMasked=new boolean[this.selectedImages[0].length];
for (int i=0;i<selectedMasked.length;i++) selectedMasked[i]=true; // select all
} else {
selectedMasked=this.selectedImages[ser].clone();
}
for (int i=0;i<selectedMasked.length;i++) selectedMasked[i] &= this.distortionCalibrationData.gIP[i].enabled;
// unselect empty
// TODO: add minimal number of nodes?
if ((ser>=0) && (this.selectedValidImages[ser]!=null) && !userSelection){
for (int i=0;i<selectedMasked.length;i++) selectedMasked[i] &= this.selectedValidImages[ser][i];
} else {
for (int i=0;i<selectedMasked.length;i++) selectedMasked[i] &= (this.distortionCalibrationData.gIP[i].pixelsXY.length>0);
}
return selectedMasked; //this.selectedImages[ser];
}
public int getNumSeries(){
return this.selectedImages.length;
}
/**
* Creates map from the parameter vector index to the {grid image number, parameter number}
* When the parameter is shared by several images, the map points to the one which value will be used
* (they might be different). Timestamp of the masterImages[] is used to determine which image to use.
* Simultaneously creates this.reverseParameterMap that maps each of the image/parameter to the parameter vector
* Needs to be run for each new strategy series
* @param numSeries number of fitting strategy series
* @return this.parameterMap
*/
public int buildParameterMap (int numSeries){
int numPars=this.distortionCalibrationData.getNumParameters();
int numImg=this.distortionCalibrationData.getNumImages();
int numTPars=this.parameterMode[numSeries].length;
this.reverseParameterMap=new int [numImg][numPars];
// boolean [] selectedEnabledImagesAll=selectedImages(numSeries,true); // strictly as in series, including no valid points ones
boolean [] selectedEnabledImages=selectedImages(numSeries);
// set defaults - -1 - "fixed", use individual parameter from this image
for (int i=0;i<numImg;i++) for (int j=0;j<numPars;j++) this.reverseParameterMap[i][j]=-1;
int vectorIndex=0;
// int [][] tmpMap=new int[numTPars][3]; // temporary array parameterMap[][] (will be truncated)
int [][] tmpMap=new int[numPars*numImg][3]; // temporary array parameterMap[][] (will be truncated)
double masterTS=this.distortionCalibrationData.getImageTimestamp(this.masterImages[numSeries]); // timestamp of the master image
// iterate through all global/subcamera parameters
for (int numTPar=0;numTPar<numTPars;numTPar++) if (this.parameterMode[numSeries][numTPar]!=this.modeFixed){ // skip "fixed"
boolean isCommon=
(this.parameterMode[numSeries][numTPar]==this.modeCommon) ||
(this.parameterMode[numSeries][numTPar]==this.modeSupercommon);
boolean isStation=
(this.parameterMode[numSeries][numTPar]==this.modeStation) ||
(this.parameterMode[numSeries][numTPar]==this.modeSuperStation);
boolean isGroup=(this.parameterMode[numSeries][numTPar]==this.modeGroup);
int numSub=this.parameterList[numTPar][0]; // number of sub-camera for this total parameter index
int numPar=this.parameterList[numTPar][1]; // number of per-image parameter for this total parameter index
boolean isSubCamera=this.distortionCalibrationData.isSubcameraParameter(numPar);
if (this.debugLevel>2) System.out.println("numTPar="+numTPar+" numSub="+numSub+" numPar="+numPar);
// iterate through available images
for (int numThisImg=0;numThisImg<numImg;numThisImg++) {
if ((selectedEnabledImages[numThisImg]) &&
(!isSubCamera || (numSub==this.distortionCalibrationData.getImageSubcamera(numThisImg))) &&
(this.reverseParameterMap[numThisImg][numPar]<0)){ // image used, this cell is not (yet) defined
if (this.debugLevel>2){
System.out.println("buildParameterMap("+numSeries+"): numThisImg="+numThisImg+", numPar="+numPar+", vectorIndex="+vectorIndex);
}
// assign it a new parameter
this.reverseParameterMap[numThisImg][numPar]=vectorIndex;
double thisTS=this.distortionCalibrationData.getImageTimestamp(numThisImg);
int thisStation=this.distortionCalibrationData.gIP[numThisImg].getStationNumber();
// set pointer to this first image
tmpMap[vectorIndex][0]=numThisImg; // vectorindex==22 > tmpMap.length?
tmpMap[vectorIndex][1]=numPar;
tmpMap[vectorIndex][2]=this.parameterMode[numSeries][numTPar];
double minDist=Math.abs(this.distortionCalibrationData.getImageTimestamp(numThisImg)-masterTS);
if (this.debugLevel>2) System.out.println("vectorIndex="+vectorIndex+" numThisImg="+numThisImg);
// see if same parameter in some other image(s) is shared
for (int numOtherImg=numThisImg+1;numOtherImg<numImg;numOtherImg++)
if ((selectedEnabledImages[numOtherImg]) && // OOB 1
(!isSubCamera || (numSub==this.distortionCalibrationData.getImageSubcamera(numOtherImg))) &&
(this.reverseParameterMap[numOtherImg][numPar]<0)){ // image used, this cell is not (yet) defined
if ((this.distortionCalibrationData.getImageTimestamp(numOtherImg)==thisTS) || // same parameter same timestamp - same group even if is set differently
(isStation && (this.distortionCalibrationData.gIP[numOtherImg].getStationNumber()==thisStation)) || // new
isCommon ||
(isGroup && (this.parameterGroups[numSeries][numTPar][numThisImg]==
this.parameterGroups[numSeries][numTPar][numOtherImg]))){
// assign it a the same parameter
this.reverseParameterMap[numOtherImg][numPar]=vectorIndex;
double thisDist=Math.abs(this.distortionCalibrationData.getImageTimestamp(numThisImg)-masterTS);
if (thisDist<minDist) {
minDist=thisDist;
tmpMap[vectorIndex][0]=numOtherImg;
}
}
}
vectorIndex++;
}
}
}
// reverseParameterMap built, vectorIndex equals to the total number of parameters needed for fitting
//truncate tmpMap into this.parameterMap[][]
this.parameterMap=new int[vectorIndex][];
for (int i=0;i<vectorIndex;i++) this.parameterMap[i] =tmpMap[i];
this.currentSeriesNumber=numSeries;
if (this.debugLevel>2) System.out.println("this.parameterMap.length="+this.parameterMap.length);
return this.parameterMap.length;
}
/**
* Prepare data for calculating additional LMA terms for parameter variances
* @param numSeries fitting series to use
* @return number of parameters for which variance is considered
*/
public int buildVariancesMaps (
int numSeries){
if (this.debugLevel>0){
System.out.println("buildVariancesMaps("+numSeries+")");
}
if ((this.varianceModes==null) || (this.varianceModes[numSeries]==varianceModeDisabled)){
this.averageCellIndex=null;
this.variationsAverages=null;
this.weightVariance=null;
this.varianceErrorsSquared=null;
return 0;
}
int debugThreshold=2;
boolean useSetWeights=(this.varianceModes[numSeries]==varianceModeVariableWeight);
int numPars=this.distortionCalibrationData.getNumParameters();
int numStations=this.distortionCalibrationData.eyesisCameraParameters.getNumStations();
// int numTPars=this.parameterMode[numSeries].length;
int numSeriesPars=this.parameterMap.length;
// count tilt positions per station
List<Integer> tiltList= new ArrayList<Integer>(1000);
Integer iStationTilt;
int tiltMotorIndex=2;
for (int numSPar=0;numSPar<numSeriesPars;numSPar++) {
if (this.parameterMap[numSPar]==null){
System.out.println("buildVariancesMaps() BUG - ,this.parameterMap["+numSPar+"]==null, numSeriesPars="+numSeriesPars);
continue;
}
int imgNumber=this.parameterMap[numSPar][0]; // null pointer for triclops after adding variances for tilt
int setNumber=this.distortionCalibrationData.gIP[imgNumber].getSetNumber();
int station= this.distortionCalibrationData.gIP[imgNumber].getStationNumber();
if (this.distortionCalibrationData.gIS[setNumber]==null){
System.out.println("buildVariancesMaps() BUG - ,this.distortionCalibrationData.gIS["+setNumber+"]==null, numSeriesPars="+numSeriesPars+
" numSPar="+numSPar+" imgNumber="+imgNumber+" station="+station);
continue;
}
if (this.distortionCalibrationData.gIS[setNumber].motors==null){
System.out.println("buildVariancesMaps() BUG - ,this.distortionCalibrationData.gIS["+setNumber+"].motors==null, numSeriesPars="+numSeriesPars+
" numSPar="+numSPar+" imgNumber="+imgNumber+" station="+station);
continue;
}
int tiltMotor=this.distortionCalibrationData.gIS[setNumber].motors[tiltMotorIndex];// null pointer for triclops after adding variances for tilt
iStationTilt=station+numStations*tiltMotor;
if (!tiltList.contains(iStationTilt)) tiltList.add(iStationTilt);
}
int numStationTilts=tiltList.size();
int [] numGroups=new int [numPars];
for (int i=0;i<numGroups.length;i++)numGroups[i]=0;
for (int numSPar=0;numSPar<numSeriesPars;numSPar++) {
int parIndex=this.parameterMap[numSPar][1];
// if ((numGroups[parIndex]==0) && (this.distortionCalibrationData.eyesisCameraParameters.isVarianceCostSet(parIndex))){
if (numGroups[parIndex]==0){
boolean isSet=this.distortionCalibrationData.eyesisCameraParameters.isVarianceCostSet(parIndex);
switch (this.parameterMap[numSPar][2]){
case modeWeakCommon:
if (isSet) numGroups[parIndex]=1;
if (this.debugLevel>debugThreshold) System.out.println(">>>1 "+numSPar+":"+parIndex +" - "+numGroups[parIndex]+" isSet="+isSet);
break;
case modeWeakStation:
if (isSet) numGroups[parIndex]=numStations;
if (this.debugLevel>debugThreshold) System.out.println(">>>2 "+numSPar+":"+parIndex +" - "+numGroups[parIndex]+" isSet="+isSet);
break;
case modeTiltEqualize:
if (isSet) numGroups[parIndex]=numStationTilts;
if (this.debugLevel>debugThreshold) System.out.println(">>>3 "+numSPar+":"+parIndex +" - "+numGroups[parIndex]+" isSet="+isSet);
break;
}
}
}
if (this.debugLevel>debugThreshold){
System.out.println("buildVariancesMaps() numGroups:");
for (int i=0;i<numGroups.length;i++) if (numGroups[i]>0) System.out.println("--- "+i+":"+numGroups[i]);
}
int startIndex=0;
for (int i=0;i<numGroups.length;i++){
if (numGroups[i]>0){
int num=numGroups[i];
numGroups[i]=startIndex;
startIndex+=num;
} else {
numGroups[i]=-1;
}
}
if (this.debugLevel>debugThreshold){
System.out.println("buildVariancesMaps() start indices:");
for (int i=0;i<numGroups.length;i++) if (numGroups[i]>=0) System.out.println("--- "+i+":"+numGroups[i]);
}
if (this.debugLevel>debugThreshold){
System.out.println("buildVariancesMaps() startIndex="+startIndex);
}
if (startIndex==0){ // no variance parameters defined
this.averageCellIndex=null;
this.variationsAverages=null;
this.weightVariance=null;
this.varianceErrorsSquared=null;
return 0;
}
// Assign average cell indices for each vector element, for each paramter it can be just 1 for global, numStations or number of tilt positions
this.averageCellIndex=new int [numSeriesPars];
for (int numSPar=0;numSPar<numSeriesPars;numSPar++) {
this.averageCellIndex[numSPar]=-1; // not applicable
int parIndex=this.parameterMap[numSPar][1];
// for (int numTPar=0;numTPar<numTPars;numTPar++) {
// int parIndex=this.parameterList[numTPar][1];
if ((numGroups[parIndex]>=0) && (this.distortionCalibrationData.eyesisCameraParameters.isVarianceCostSet(parIndex))){
int imgNumber=this.parameterMap[numSPar][0];
int setNumber=this.distortionCalibrationData.gIP[imgNumber].getSetNumber();
int station= this.distortionCalibrationData.gIP[imgNumber].getStationNumber();
switch (this.parameterMap[numSPar][2]){
case modeWeakCommon:
this.averageCellIndex[numSPar]=numGroups[parIndex];
break;
case modeWeakStation:
this.averageCellIndex[numSPar]=numGroups[parIndex]+station;
break;
case modeTiltEqualize:
int tiltMotor=this.distortionCalibrationData.gIS[setNumber].motors[tiltMotorIndex];
iStationTilt=station+numStations*tiltMotor;
this.averageCellIndex[numSPar]=numGroups[parIndex]+tiltList.indexOf(iStationTilt);
break;
}
}
}
if (this.debugLevel>1){
System.out.println("buildVariancesMaps() numStationTilts="+numStationTilts+" numSeriesPars="+numSeriesPars+ " useSetWeights="+useSetWeights+
" number of averages="+startIndex);
}
this.variationsAverages=new double [startIndex]; // total number of different averages
int [] numContributors=new int [startIndex];
for (int i=0;i<this.variationsAverages.length;i++) {
this.variationsAverages[i]=0.0;
numContributors[i]=0;
}
// Calculate total weights for averages and number of contributors (to remove single-contributor items)
for (int numSPar=0;numSPar<numSeriesPars;numSPar++) {
int avIndex=this.averageCellIndex[numSPar];
if (avIndex>=0){
double w;
if (useSetWeights){
int imgNumber=this.parameterMap[numSPar][0];
int setNumber=this.distortionCalibrationData.gIP[imgNumber].getSetNumber();
w=this.distortionCalibrationData.gIS[setNumber].getSetWeight();
} else {
w=1.0;
}
if (w>0.0) { // do not count zero-contributors (are they possible?)
this.variationsAverages[avIndex]+=w;
numContributors[avIndex]++;
}
}
}
if (this.debugLevel>debugThreshold){
System.out.println("buildVariancesMaps() numContributors:");
for (int i=0;i<numContributors.length;i++) if (numContributors[i]>0) System.out.println("--- "+i+":"+numContributors[i]);
}
// calculate each parameter share of the average TODO: disable if share =100% (single contributor)
int numVariancePars=0;
this.weightOnAverage=new double [numSeriesPars];
this.weightVariance= new double [numSeriesPars];
this.varianceErrorsSquared= new double [numSeriesPars];
for (int numSPar=0;numSPar<numSeriesPars;numSPar++) {
this.weightOnAverage[numSPar]=0.0;
this.weightVariance[numSPar]=0.0;
this.varianceErrorsSquared[numSPar]=Double.NaN;
int avIndex=this.averageCellIndex[numSPar];
if (avIndex>=0){
if (numContributors[avIndex]<2){
this.averageCellIndex[numSPar]=-1; // single element - impossible to use
if (this.debugLevel>0) System.out.println("buildVariancesMaps(): removed parameter #"+numSPar+" - single contributor to average");
} else {
numVariancePars++;
double w;
if (useSetWeights){
int imgNumber=this.parameterMap[numSPar][0];
int setNumber=this.distortionCalibrationData.gIP[imgNumber].getSetNumber();
w=this.distortionCalibrationData.gIS[setNumber].getSetWeight();
} else w=1.0;
this.weightOnAverage[numSPar]=w/this.variationsAverages[avIndex];
this.weightVariance[numSPar]= w;
}
}
}
if (this.debugLevel>debugThreshold){
System.out.println("average indices/shares:");
for (int numSPar=0;numSPar<numSeriesPars;numSPar++) {
int avIndex=this.averageCellIndex[numSPar];
if (avIndex>=0){
int parIndex=this.parameterMap[numSPar][1];
System.out.println("==="+numSPar+" parIndex="+parIndex+" avIndex="+avIndex+
" weightOnAverage="+this.weightOnAverage[numSPar]+
" weightVariance="+this.weightVariance[numSPar]);
}
}
}
if (numVariancePars==0){
this.averageCellIndex=null;
this.variationsAverages=null;
this.weightVariance=null;
this.varianceErrorsSquared=null;
return 0;
}
// TODO this.variationsAverages needs to be reset to all zeros each calculations
return numVariancePars;
}
/**
* Ammend LMA arrays to pull individual values of the extrinsic parameters to their averages
* Averages may be global, per-station or per same tilt motor position (same station)
* The function to be minimized is
* f(x) Scale*(1/p*Xeff+(1-1/p)*pow(Xeff,p)
* Xeff=x/X0*(1-shareInAverage)
* and x is difference between the poarameter and it's average over the specified set (all/station/tiltStation)
* @param numSeries fitting series number
* @param vector - parameters vector
* @param jTByJ Jacobian transposed multiplied by Jacobian - some diagonal elements may be modified (weighted) or null (will add to old values)
* @param jTByDiff Jacobian transposed multiplied by difference vector (weighted) or null (will add to old values)
* @return true if parameter variances are applicable to the fitting series
*/
public boolean addVarianceToLMA(
int numSeries,
final double [] vector,
double [][] jTByJ, // jacobian multiplied by Jacobian transposed
double [] jTByDiff){ // jacobian multiplied difference vector
if (this.averageCellIndex==null) return false; // parameter varainces are not used
// int numTPars=this.parameterMode[numSeries].length;
int numSeriesPars=this.parameterMap.length;
int debugThreshold=2;
// double [] fX= new double [numTPars];
// double [] diagJ=new double [numTPars]; // diagonal of Jacobian (here parameters only influence themselves)
double [] weights=new double [this.variationsAverages.length];
for (int i=0;i<this.variationsAverages.length;i++) {
this.variationsAverages[i]=0.0;
weights[i]=0.0;
}
// calculate appropriate averages
for (int numSPar=0;numSPar<numSeriesPars;numSPar++) {
this.varianceErrorsSquared[numSPar]=0.0;
int avIndex=this.averageCellIndex[numSPar];
if (avIndex>=0){
this.variationsAverages[avIndex]+=this.weightOnAverage[numSPar]*vector[numSPar];
}
}
// now fX and diagJ
int numModded=0;
for (int numSPar=0;numSPar<numSeriesPars;numSPar++) {
int avIndex=this.averageCellIndex[numSPar];
int parIndex=this.parameterMap[numSPar][1];
// if ((avIndex>=0) && (this.distortionCalibrationData.eyesisCameraParameters.isVarianceCostSet(parIndex))) {
if (avIndex>=0) {
double scale=this.distortionCalibrationData.eyesisCameraParameters.varianceCostScale(parIndex);
double x0= this.distortionCalibrationData.eyesisCameraParameters.varianceCostVariationAbs(parIndex);
double exp= this.distortionCalibrationData.eyesisCameraParameters.varianceCostVariationExponent(parIndex);
double xEff=(vector[numSPar]-this.variationsAverages[avIndex])*(1.0-this.weightOnAverage[numSPar])/x0; //OOB-1
double axEff=Math.abs(xEff);
double sxEff=Math.signum(xEff);
double k=1.0/exp;
double fX=sxEff*scale*(k*axEff+(1.0-k)*Math.pow(axEff,exp));
double diagJ=scale*((1.0-this.weightOnAverage[numSPar])/x0)*(k+(exp-1)*Math.pow(axEff,exp-1.0));
this.varianceErrorsSquared[numSPar]=this.weightVariance[numSPar]*fX*fX;
if (jTByJ!=null) jTByJ[numSPar][numSPar]+=this.weightVariance[numSPar]*diagJ*diagJ;
if (jTByDiff!=null) jTByDiff[numSPar]-= this.weightVariance[numSPar]*fX*diagJ;
if (this.debugLevel>debugThreshold){
System.out.print (numSPar+" "+parIndex+" "+avIndex+": "+" scale="+scale);
System.out.print (" vector["+numSPar+"]="+vector[numSPar]+" ("+this.variationsAverages[avIndex]+") xEff="+xEff+" fX="+fX+" k="+k+" exp="+exp );
System.out.print (" diagJ="+diagJ+" "+xEff+" jTByJ+"+ (this.weightVariance[numSPar]*diagJ*diagJ) );
System.out.print (" jTByDiff+"+(-this.weightVariance[numSPar]*fX*diagJ)+" ves="+(this.weightVariance[numSPar]*fX*fX));
System.out.println(" weight="+this.weightVariance[numSPar]);
}
if (this.weightVariance[numSPar]!=0.0) numModded++;
}
}
if (this.debugLevel>1)System.out.println ("addVarianceToLMA() - modified "+numModded+" elements");
return true;
}
public double [] getVarianceError2(){ return (this.averageCellIndex==null)?null:this.varianceErrorsSquared;}
public double [] getWeights(){ return (this.averageCellIndex==null)?null:this.weightVariance;}
/**
*
* @return number of the current fitting strategy series
*/
public int getCurrentSeries(){
return this.currentSeriesNumber;
}
/**
* Calculate vector of the parameters used in LMA algorithm, extracted from the
* individual data, using parameter map (calculated once after changing series)
* @return vector of parameters used for the LMA
*/
public double [] getSeriesVector(){
if (this.parameterMap==null) {
String msg="Series parameters map is not calculated";
IJ.showMessage("Error",msg);
throw new IllegalArgumentException (msg);
}
double [] vector=new double[this.parameterMap.length];
for (int i=0;i<vector.length;i++) {
// vector[i]=this.distortionCalibrationData.pars[this.parameterMap[i][0]][this.parameterMap[i][1]];
vector[i]=this.distortionCalibrationData.getParameterValue(this.parameterMap[i][0],this.parameterMap[i][1]); // (numImg, numPar)
}
return vector;
}
/**
* Saves data from the parameter vector to that of the images
* @param vector vector of parameters (after LMA fitting)
*/
// TODO: Update the temporarily disabled images also, when possible (modify buildParameterMap also?
public void saveSeriesVector(double [] vector){
if ((this.parameterMap==null) ||(vector==null) || (vector.length!=this.parameterMap.length) ) {
String msg="Vector length does not match parameters length";
IJ.showMessage("Error",msg);
throw new IllegalArgumentException (msg);
}
// save for "individual" and "common" - and "station" (week - same as individual here)
boolean [] selectedEnabledImages=selectedImages(this.currentSeriesNumber);
for (int numImg=0;numImg<this.reverseParameterMap.length;numImg++) if (selectedEnabledImages[numImg]){
for (int nPar=0;nPar<this.reverseParameterMap[numImg].length;nPar++) if (this.reverseParameterMap[numImg][nPar]>=0){
// this.distortionCalibrationData.pars[numImg][nPar]=vector[this.reverseParameterMap[numImg][nPar]];
this.distortionCalibrationData.setParameterValue(numImg,nPar,vector[this.reverseParameterMap[numImg][nPar]],true);
if (this.debugLevel>2){
System.out.println(" Updated image "+numImg+" "+distortionCalibrationData.getParameterName(nPar)+" = "+
// this.distortionCalibrationData.pars[numImg][nPar]) ; //vector[this.reverseParameterMap[numImg][nPar]]);
this.distortionCalibrationData.getParameterValue(numImg,nPar));
}
}
}
// propagate to other (unselected) images for "super common" parameters
for (int vPar=0; vPar<this.parameterMap.length;vPar++) {
if (
(this.parameterMap[vPar][2]==modeSupercommon) ||
(this.parameterMap[vPar][2]==modeSuperStation) ){ // "super common" No "weak" here!
// int nSub=this.parameterMap[vPar][0]; // that's an image number, not a subcamera number
int nSub=this.distortionCalibrationData.gIP[this.parameterMap[vPar][0]].channel;
int nStation=this.distortionCalibrationData.gIP[this.parameterMap[vPar][0]].getStationNumber();
boolean superCommon=(this.parameterMap[vPar][2]==modeSupercommon);
int nPar=this.parameterMap[vPar][1];
//this.distortionCalibrationData.channels[i]
boolean isSubCamera=this.distortionCalibrationData.isSubcameraParameter(nPar);
for (int numImg=0;numImg<this.reverseParameterMap.length;numImg++) {
if (superCommon || (this.distortionCalibrationData.gIP[numImg].getStationNumber()==nStation)) {
if (this.debugLevel>2){
System.out.println("saveSeriesVector(): numImg="+numImg+" nPar="+nPar+" isSubCamera="+isSubCamera+
" nSub="+nSub+" distortionCalibrationData.getImageSubcamera("+numImg+")="+distortionCalibrationData.getImageSubcamera(numImg)+
" vector["+vPar+"]="+vector[vPar]);
}
if ((!isSubCamera) || (nSub==this.distortionCalibrationData.getImageSubcamera(numImg))) {
// this.distortionCalibrationData.pars[numImg][nPar]=vector[vPar];
this.distortionCalibrationData.setParameterValue(numImg,nPar,vector[vPar],true);
}
}
}
}
}
}
/**
* Calculates current values of all parameters for the particular sensor - some ("fixed")
* are taken from the data stored for this individual image, others - from the parameter
* vector (used in fitting) UPDATE: works with null parameterVector
* @param numImg number of image
* @param vector parameters vector
* @return vector used for the current image (parameters influencing the acquired grid
* on the sensor (common parameters and those of the sensor's subchannel)
*/
public double [] getImageParametersVector(int numImg, double [] parameterVector){
// double [] vector = this.distortionCalibrationData.pars[numImg].clone();
double [] vector = this.distortionCalibrationData.getParameters(numImg); // returns a copy, no clone() is needed
if ((parameterVector!=null) && (this.reverseParameterMap!=null) && (this.reverseParameterMap[numImg]!=null)){
for (int i=0;i<vector.length;i++){
if (this.reverseParameterMap[numImg][i]>=0) vector[i]=parameterVector[this.reverseParameterMap[numImg][i]];
}
}
return vector;
}
/**
* Calculates which of all parameters for the particular sensor are to be adjusted (to reduce calcualtions)
* @param numImg number of image
* @param vector parameters vector
* @return mask vector to be used with the results of getImageParametersVector()
*/
public boolean [] getImageParametersVectorMask (int numImg){
if ((this.reverseParameterMap==null) || (this.reverseParameterMap[numImg]==null)) return null;
// boolean [] mask =new boolean [this.distortionCalibrationData.pars[numImg].length];
boolean [] mask =new boolean [this.distortionCalibrationData.getParametersLength(numImg)];
for (int i=0;i<mask.length;i++){
mask[i]=(this.reverseParameterMap[numImg][i]>=0);
}
return mask;
}
/**
* Calculates index in the parameter vector corresponding to each image parameter vector element
* @param numImg number of image
* @param vector parameters vector
* @return mask vector to be used with the results of getImageParametersVector()
*/
public int [] getImageParametersVectorReverseMap (int numImg){
if ((this.reverseParameterMap==null) || (this.reverseParameterMap[numImg]==null)) return null;
// int [] map =new int [this.distortionCalibrationData.pars[numImg].length];
int [] map =new int [this.distortionCalibrationData.getParametersLength(numImg)];
for (int i=0;i<map.length;i++){
map[i]=this.reverseParameterMap[numImg][i];
}
return map;
}
/**
* Opens a text window wityh a table that shows map from each element of the parameters vector
* to the image number used as a source of this parameter
* @param title Window title
*/
public void showCurrentParameterMap(String title){
String header="#\tMode\tName\tSubcamera\tImage Number\tMode";
StringBuffer sb = new StringBuffer();
for (int i=0; i<this.parameterMap.length;i++){
sb.append(
i+"\t"+
this.definedModesAll[this.parameterMap[i][2]]+"\t"+
this.distortionCalibrationData.getParameterName(this.parameterMap[i][1])+"\t"+
this.distortionCalibrationData.getImageSubcamera(this.parameterMap[i][0])+"\t"+
this.parameterMap[i][0]+"\t"+
this.definedModesAll[this.parameterMap[i][2]]+"\n");
}
new TextWindow(title, header, sb.toString(), 800,600);
}
/**
* Opens window with a table mapping each image (column) parameter (row) to parameter vector element
* "-" (-1 in teh table) - fixed parameter, use one from the individual image
* @param title Window title
*/
public void showCurrentReverseParameterMap(String title){
String header="Image";
boolean [] selectedEnabledImages=selectedImages(this.currentSeriesNumber);
for (int i=0; i<this.reverseParameterMap.length;i++) if (selectedEnabledImages[i]){
header+="\t"+i;
}
StringBuffer sb = new StringBuffer();
sb.append("timestmps");
for (int i=0; i<this.reverseParameterMap.length;i++) if (selectedEnabledImages[i]){
sb.append("\t"+IJ.d2s(this.distortionCalibrationData.getImageTimestamp(i),6));
}
sb.append("\n");
sb.append("subcamera");
for (int i=0; i<this.reverseParameterMap.length;i++) if (selectedEnabledImages[i]){
sb.append("\t"+this.distortionCalibrationData.getImageSubcamera(i));
}
sb.append("\n");
for (int k=0;k<this.reverseParameterMap[0].length;k++){
// boolean isSubCamera=this.distortionCalibrationData.isSubcameraParameter(k);
// sb.append(this.distortionCalibrationData.getParameterName(this.parameterMap[k][1])); // name of parameter
sb.append(this.distortionCalibrationData.getParameterName(k)); // name of parameter
for (int i=0; i<this.reverseParameterMap.length;i++) if (selectedEnabledImages[i]){
int mode =this.reverseParameterMap[i][k];
sb.append("\t"+((mode>=0)?mode:"-"));
}
sb.append("\n");
}
new TextWindow(title, header, sb.toString(), 800,600);
}
/**
* Add/reduce number of series in this fitting strategy
* @param numSeries new number of series
*/
public void setLength(int numSeries){
if (numSeries<=0) {
setDflt(0);
return;
}
if ((this.selectedImages!=null) && (numSeries==this.selectedImages.length)) return;
if ((this.selectedImages==null) && (numSeries==0)) return;
boolean [][] oldSelectedImages=null; // images selected for each step
int [][] oldParameterMode=null;
int [] oldVarianceModes=null;
int [][] oldZGroups=null;
int [][][] oldParameterGroups=null;
double [] oldLambdas=null; // LMA initial lambda for each step
int [] oldMasterImages=null;
double [] oldStepDone=null;
boolean [] oldStopAfterThis=null;
int oldNumSeries=(this.selectedImages==null)?0:this.selectedImages.length;
int oldLength=0;
if (this.selectedImages!=null){
// deep clone this.* to old*;
oldSelectedImages=new boolean[oldNumSeries][];
oldParameterMode=new int[oldNumSeries][];
oldParameterGroups=new int[oldNumSeries][][];
oldZGroups=new int[oldNumSeries][];
for (int i=0;i<oldNumSeries;i++){
oldSelectedImages[i]=this.selectedImages[i].clone();
oldParameterMode[i]= this.parameterMode[i].clone(); // out of bound - 2
oldParameterGroups[i]=new int[this.parameterGroups[i].length][];
for (int j=0;j<oldParameterGroups[i].length;j++)
oldParameterGroups[i][j]=(parameterGroups[i][j]==null)?null:parameterGroups[i][j].clone();
if (this.zGroups[i]!=null) oldZGroups[i]=this.zGroups[i].clone();
else this.zGroups[i]=oldZGroups[i];
}
oldVarianceModes=(this.varianceModes==null)?null:this.varianceModes.clone();
oldLambdas=this.lambdas.clone();
oldLength=this.selectedImages.length;
oldMasterImages=this.masterImages.clone();
oldStepDone=this.stepDone.clone();
oldStopAfterThis=this.stopAfterThis.clone();
}
setDflt(numSeries);
if (this.selectedImages!=null) for (int i=0;(i<this.selectedImages.length) && (i<oldLength);i++){
this.selectedImages[i]=oldSelectedImages[i];
this.parameterMode[i]= oldParameterMode[i];
this.parameterGroups[i]=oldParameterGroups[i];
this.lambdas[i]=oldLambdas[i];
this.masterImages[i]=oldMasterImages[i];
this.stepDone[i]=oldStepDone[i];
this.stopAfterThis[i]=oldStopAfterThis[i];
this.varianceModes[i]=oldVarianceModes[i];
this.zGroups[i]=(oldZGroups[i]!=null)?oldZGroups[i].clone():null;
}
}
public void updateNumberOfSubcameras(){
int numPars= this.distortionCalibrationData.getNumParameters();
int numSubCams=this.distortionCalibrationData.getNumSubCameras();
initParameterList();
int numSubPars=0;
int [] subParIndex=new int[numPars];
for (int i=0;i<numPars;i++){
if (this.distortionCalibrationData.isSubcameraParameter(i)) subParIndex[numSubPars++]=i;
}
int totalNumPars=numPars+(numSubCams-1)*numSubPars; // maximal number of parametes per timestamp?
int oldTotalPars=this.parameterEnable.length;
if (oldTotalPars==totalNumPars) return;
if (oldTotalPars>numPars) { // more than one subcamera, so last numSubPars are subcamera parameters
for (int i=0;i<numSubPars;i++)subParIndex[i]=(oldTotalPars-numSubPars)+i;
}
// public boolean isSubcameraParameter(int num){
int numSeries=this.parameterMode.length;
if (oldTotalPars<totalNumPars){ // grow, repeat last subcamera
if (this.debugLevel>1) System.out.println("Increasing total number of parameters in fitting strategy: "+oldTotalPars+" -> "+totalNumPars);
for (int nSer=0;nSer<numSeries;nSer++){
int [] parameterMode_tmp=this.parameterMode[nSer]; //.clone();
int [][] parameterGroups_tmp=this.parameterGroups[nSer]; //.clone();
this.parameterMode[nSer]=new int[totalNumPars];
this.parameterGroups[nSer]=new int[totalNumPars][];
for (int nTPar=0;nTPar<oldTotalPars;nTPar++){
this.parameterMode[nSer][nTPar]=parameterMode_tmp[nTPar];
this.parameterGroups[nSer][nTPar]=parameterGroups_tmp[nTPar];
}
for (int nTPar=oldTotalPars;nTPar<totalNumPars;nTPar++){
int index= subParIndex[(nTPar-oldTotalPars) % numSubPars];
this.parameterMode[nSer][nTPar]=parameterMode_tmp[index];
this.parameterGroups[nSer][nTPar]=(parameterGroups_tmp[index]==null)?null:parameterGroups_tmp[index].clone();
}
}
boolean [] parameterEnable_tmp=this.parameterEnable; //.clone();
this.parameterEnable= new boolean [totalNumPars];
for (int nTPar=0;nTPar<oldTotalPars;nTPar++){
this.parameterEnable[nTPar]=parameterEnable_tmp[nTPar];
}
for (int nTPar=oldTotalPars;nTPar<totalNumPars;nTPar++){
int index= subParIndex[(nTPar-oldTotalPars) % numSubPars];
this.parameterEnable[nTPar]=parameterEnable_tmp[index];
}
} else { // shrink
if (this.debugLevel>1) System.out.println("Reducing total number of parameters in fitting strategy: "+oldTotalPars+" -> "+totalNumPars);
for (int nSer=0;nSer<numSeries;nSer++){
int [] parameterMode_tmp=this.parameterMode[nSer]; //.clone();
int [][] parameterGroups_tmp=this.parameterGroups[nSer]; //.clone();
this.parameterMode[nSer]=new int[totalNumPars];
this.parameterGroups[nSer]=new int[totalNumPars][];
for (int nTPar=0;nTPar<totalNumPars;nTPar++){
this.parameterMode[nSer][nTPar]=parameterMode_tmp[nTPar];
this.parameterGroups[nSer][nTPar]=parameterGroups_tmp[nTPar];
}
}
boolean [] parameterEnable_tmp=this.parameterEnable; //.clone();
this.parameterEnable= new boolean [totalNumPars];
for (int nTPar=0;nTPar<totalNumPars;nTPar++){
this.parameterEnable[nTPar]=parameterEnable_tmp[nTPar];
}
}
}
private void setDflt(int numSeries){
if (numSeries==0) {
this.selectedImages=null;
this.lambdas=null;
this.stepDone=null;
this.parameterMode=null;
this.parameterGroups=null;
this.varianceModes=null;
this.zGroups=null;
return;
}
this.stopAfterThis=new boolean[numSeries];
for (int i=0;i<numSeries;i++) this.stopAfterThis[i]=true;
// calculate total (potential) number of parameters in the system
//TODO: modify for groups
int numPars= this.distortionCalibrationData.getNumParameters();
int numSubCams=this.distortionCalibrationData.getNumSubCameras();
int numSubPars=0;
for (int i=0;i<numPars;i++){
if (this.distortionCalibrationData.isSubcameraParameter(i)) numSubPars++;
}
int totalNumPars=numPars+(numSubCams-1)*numSubPars; // maximal number of parametes per timestamp?
// number of parameters to adjust may be greater, if they were changing between the images
this.selectedImages=new boolean[numSeries][this.distortionCalibrationData.getNumImages()];//
this.selectedValidImages=new boolean[numSeries][this.distortionCalibrationData.getNumImages()];//
this.masterImages=new int[numSeries];
this.lambdas=new double[numSeries];
this.stepDone=new double[numSeries];
this.parameterMode=new int[numSeries][totalNumPars];
this.varianceModes=new int[numSeries];
this.parameterGroups=new int[numSeries][totalNumPars][];
this.parameterEnable= new boolean [totalNumPars];
this.zGroups=new int[numSeries][];
for (int i=0;i<this.selectedImages.length;i++){
invalidateSelectedImages(i);
for (int j=0;j<this.selectedImages[i].length;j++){
this.selectedImages[i][j]=false;
}
for (int j=0;j<this.parameterMode[i].length;j++){
this.parameterMode[i][j]=this.modeFixed; // fixed
this.parameterGroups[i][j]=null; // no groups yet defined
}
this.lambdas[i]=defaultLambda;
this.stepDone[i]=defaultStepDone;
this.masterImages[i]=0; // first image, supposingly the earliest timestamp
this.varianceModes[i]=varianceModeDisabled;
this.zGroups[i]=null;
}
initParameterList();
for (int i=0;i<numPars;i++){
this.parameterEnable[i]=true; // initially enable all parameters for the first camera
}
for (int i=1;i<numSubCams;i++){
int i1=numPars+numSubPars*(i-1);
int j1=0;
for (int j=0;j<numPars;j++) if (this.distortionCalibrationData.isSubcameraParameter(j)){
this.parameterEnable[i1+j1]=false; // initially disable all other subcamera parameters
j1++;
}
}
}
private void initParameterList(){
int numPars= this.distortionCalibrationData.getNumParameters();
int numSubCams=this.distortionCalibrationData.getNumSubCameras();
int numSubPars=0;
for (int i=0;i<numPars;i++){
if (this.distortionCalibrationData.isSubcameraParameter(i)) numSubPars++;
}
int totalNumPars=numPars+(numSubCams-1)*numSubPars; // maximal number of parametes per timestamp?
this.parameterList=new int[totalNumPars][2];
for (int i=0;i<numPars;i++){
this.parameterList[i][0]=0;
this.parameterList[i][1]=i;
// this.parameterEnable[i]=true; // initially enable all parameters for the first camera
}
for (int i=1;i<numSubCams;i++){
int i1=numPars+numSubPars*(i-1);
int j1=0;
for (int j=0;j<numPars;j++) if (this.distortionCalibrationData.isSubcameraParameter(j)){
this.parameterList[i1+j1][0]=i;
this.parameterList[i1+j1][1]=j;
// this.parameterEnable[i1+j1]=false; // initially disable all other subcamera parameters
j1++;
}
}
}
/**
* Find parameter number from subcamera and index
* @param nSub number of subcamera (channel)
* @param index index of parameter
* @return number of parameter that has specified sub-camera and index. -1 if such does not exist
*/
private int getParameterNumber(int nSub, int index){
for (int i=0;i<this.parameterList.length;i++) if ((this.parameterList[i][0]==nSub) && (this.parameterList[i][1]==index)) return i;
return -1;
}
/**
*
* @param numSeries Number of series to edit
* @param useImages Select images for this series
* @param fromToImages - limit number of checkboxes, otherwise window does not show the bottom ones
* @param useParameters Select parameters for this series
* @param askNextSeries Ask for next series number
* @param zeroAndOther use 2 channels 0 and "other", propagete settings for channel 1 to all the rest
* @return -2 - cancel, -1, done, otherwise - number of step to edit
*/
public int selectStrategyStep(
int numSeries,
boolean useImages,
int [] fromToImages,
boolean allImages,
boolean useParameters,
boolean askLambdas,
boolean askNextSeries,
boolean zeroAndOther
){
boolean showDirectMap=false;
boolean showReverseMap=false;
// if current series is not valid (probably just started a new one) - look for the last valid (if any)
// and copy it;
int numEstimated=this.distortionCalibrationData.getNumberOfEstimated(true); //(boolean enabledOnly
int [] numEstimatedPerStation=this.distortionCalibrationData.getNumberOfEstimatedPerStation(true); //(boolean enabledOnly
String sNumEstimatedPerStation="";
for (int i=0;i<numEstimatedPerStation.length;i++){
if (i>0) sNumEstimatedPerStation+=", ";
sNumEstimatedPerStation+=numEstimatedPerStation[i];
}
int numNewEnabled=this.distortionCalibrationData.getNumNewEnabled();
int [] numNewEnabledPerStation=this.distortionCalibrationData.getNumNewEnabledPerStation();
String sNumNewEnabledPerStation="";
for (int i=0;i<numNewEnabledPerStation.length;i++){
if (i>0) sNumNewEnabledPerStation+=", ";
sNumNewEnabledPerStation+=numNewEnabledPerStation[i];
}
if (!isSeriesValid(numSeries)){
int sourceSeries=-1;
for (int i=numSeries-1;i>=0;i--) if (isSeriesValid(i)){
sourceSeries=i;
break;
}
if (sourceSeries>=0){
invalidateSelectedImages(numSeries); // just in case -= will be recalculated
for (int i =0; i<this.distortionCalibrationData.getNumImages();i++){
this.selectedImages[numSeries][i]=this.selectedImages[sourceSeries][i]; // copy for all, not only enabled
}
for (int i =0; i<this.parameterEnable.length;i++) if (this.parameterEnable[i]){
this.parameterMode[numSeries][i]=this.parameterMode[sourceSeries][i];
this.parameterGroups[numSeries][i]=(this.parameterGroups[sourceSeries][i]==null)?null:this.parameterGroups[sourceSeries][i].clone();
}
this.masterImages[numSeries]=this.masterImages[sourceSeries];
this.lambdas[numSeries]=this.lambdas[sourceSeries];
this.stepDone[numSeries]=this.stepDone[sourceSeries];
this.stopAfterThis[numSeries]=this.stopAfterThis[sourceSeries];
this.varianceModes[numSeries]=this.varianceModes[sourceSeries];
this.zGroups[numSeries]=(this.zGroups[sourceSeries]!=null)?this.zGroups[sourceSeries].clone():null;
}
}
GenericDialog gd = new GenericDialog("Fitting Strategy Step Configuration, step "+numSeries+" number of enabled images="+this.distortionCalibrationData.getNumEnabled());
gd.addCheckbox("Copy all from previous series (ignore all other fields)", false);
gd.addCheckbox("Remove all (but first) images, reopen dialog", false); // remove all will be invalid, copied from the previous
gd.addCheckbox("Select all images, reopen dialog", false);
if (numEstimated>0){
gd.addMessage("There are "+numEstimated+" ("+sNumEstimatedPerStation+") enabled images that have estimated orientation");
gd.addCheckbox("Select them and only them (and re-open dialog)", false);
} else {
gd.addMessage("There are no enabled images with estimated (from neighbors) orientation");
}
if (numNewEnabled>0){
gd.addMessage("There are "+numNewEnabled+" ("+sNumNewEnabledPerStation+" new enabled images");
gd.addCheckbox("Select them and only them (and re-open dialog)", false);
} else {
gd.addMessage("There are no new enabled images");
}
int numStations=this.distortionCalibrationData.eyesisCameraParameters.getNumStations();
boolean [] constrainByStation=new boolean[numStations];
for (int i=0;i<constrainByStation.length;i++) constrainByStation[i]=true;
if (this.distortionCalibrationData.eyesisCameraParameters.numStations>1){
gd.addMessage("Constrain by stations");
// gd.addCheckbox("Remove images of unselected stations below", true);
for (int i=0;i<this.distortionCalibrationData.eyesisCameraParameters.numStations;i++) gd.addCheckbox("Station "+i, constrainByStation[i]);
}
if (useImages) {
gd.addNumericField("Image sepection range, from", fromToImages[0], 0);
gd.addNumericField("Image sepection range, up to (inclufing)", fromToImages[1], 0);
gd.addMessage("Select files to include");
for (int i =0; i<this.distortionCalibrationData.getNumImages();i++)
if ((allImages || this.distortionCalibrationData.gIP[i].enabled) && (i>=fromToImages[0]) && (i<=fromToImages[1])){
int hm=this.distortionCalibrationData.gIP[i].hintedMatch;
gd.addCheckbox (i+" - "+(this.distortionCalibrationData.gIP[i].enabled?"":"(disabled) ")+
IJ.d2s(this.distortionCalibrationData.gIP[i].timestamp,6)+
": "+this.distortionCalibrationData.gIP[i].channel+
" matched "+this.distortionCalibrationData.gIP[i].matchedPointers+" pointers"+
", hinted state: "+((hm<0)?"undefined":((hm==0)?"failed":((hm==1)?"orientation":"orientation and translation"))),
this.selectedImages[numSeries][i]);
}
if (allImages) gd.addCheckbox("Enable selected, disable deselected images", false);
gd.addNumericField("The 'master' (used for common parameters)", this.masterImages[numSeries], 0);
}
if (useParameters) {
gd.addMessage("Select parameters to fit");
for (int i =0; i<this.parameterEnable.length;i++) if (this.parameterEnable[i] &&
(!zeroAndOther || (this.parameterList[i][0] <=1) || (this.parameterList[i][0] ==24))){ // in "zeroAndOther" mode do not show other subcameras
int parIndex=this.parameterList[i][1];
int subCam=this.parameterList[i][0];
boolean isSub=this.distortionCalibrationData.isSubcameraParameter(parIndex);
boolean defined=false;
double min=0.0,max=0.0;
for (int imgNumber=0;imgNumber<this.distortionCalibrationData.getNumImages(); imgNumber++)
if (this.selectedImages[numSeries][imgNumber] && this.distortionCalibrationData.gIP[imgNumber].enabled){
int sub=this.distortionCalibrationData.gIP[imgNumber].channel;
if (!isSub || (sub==subCam) || // global or same subcamera
(zeroAndOther && (subCam>=1) && (subCam<24) && (sub>=1) && (sub<24)) || // both head "other"
(zeroAndOther && (subCam>=24) && (sub>=24) )
) { // both subcameras are "other" subcameras
double parValue=this.distortionCalibrationData.getParameterValue(imgNumber,parIndex);
if (!defined) {
// min=this.distortionCalibrationData.pars[imgNumber][parIndex];
min=parValue;
max=min;
defined=true;
}
// if (this.distortionCalibrationData.pars[imgNumber][parIndex]<min) min=this.distortionCalibrationData.pars[imgNumber][parIndex];
// if (this.distortionCalibrationData.pars[imgNumber][parIndex]>max) max=this.distortionCalibrationData.pars[imgNumber][parIndex];
if (parValue<min) min=parValue;
if (parValue>max) max=parValue;
}
}
// System.out.println(i+": "+parIndex+":"+subCam+"defined="+defined+" min="+min+" max="+max);
// undefined, min, max
String sValue=(defined)?((min==max)?(min+""):(min+"..."+max)):"undefined";
String sChn=(zeroAndOther && (subCam>=1)&& (subCam<24))?"-head-other":
((zeroAndOther && (subCam>=24))?"-bottom":("-"+subCam));
boolean noWeak=!this.distortionCalibrationData.eyesisCameraParameters.isExtrinsic(parIndex);
boolean isTilt=this.distortionCalibrationData.eyesisCameraParameters.isTilt(parIndex);
gd.addChoice( // ArrayIndexOutOfBoundsException: 9
this.distortionCalibrationData.getParameterName(parIndex)+
" ("+sValue+" "+
this.distortionCalibrationData.getParameterUnits(parIndex)+")"+
(this.distortionCalibrationData.isSubcameraParameter(parIndex)?(" sub"+sChn):"com "),
(isTilt?this.definedModesTiltEq:(noWeak?this.definedModesNoWeak:this.definedModes)),
this.definedModesAll[this.parameterMode[numSeries][i]]); // definedModesAll - includes all others
}
}
if (askLambdas) {
gd.addNumericField("Initial lambda for the L-M algorithm", this.lambdas[numSeries], 6,8,"");
gd.addStringField("Relative decrese in error to error ratio to consider series finished", ""+this.stepDone[numSeries], 8);
gd.addCheckbox("Stop after this series", this.stopAfterThis[numSeries]);
}
if (this.varianceModes!=null) gd.addChoice(
"Processing of selected parameters variances",
this.definedVarianceModes,
this.definedVarianceModes[this.varianceModes[numSeries]]);
gd.addCheckbox("Edit variances costs", false);
if (numStations>1){
int oldZGroupsLength=(this.zGroups[numSeries]!=null)?this.zGroups[numSeries].length:0;
int [] oldZGroups={};
if (oldZGroupsLength>0) oldZGroups=this.zGroups[numSeries].clone();
this.zGroups[numSeries]=new int [numStations];
int nextZGroup=-1;
for (int i=0;i<numStations;i++){
if (i<oldZGroupsLength) {
this.zGroups[numSeries][i]=oldZGroups[i];
if (this.zGroups[numSeries][i]>nextZGroup) nextZGroup=this.zGroups[numSeries][i];
} else {
this.zGroups[numSeries][i]=++nextZGroup;
}
}
String [] zGroupsChoices=new String [numStations+1];
zGroupsChoices[0]="Not used";
for (int i=0;i<numStations;i++) zGroupsChoices[i+1]="Group "+i;
gd.addMessage ("Select groups of same pattern for different stations (pattern did not move between measurements). Used for pattern correction command");
for (int i=0;i<numStations;i++){
int zG=(this.zGroups[numSeries][i]<0)?0:(this.zGroups[numSeries][i]+1);
gd.addChoice( // ArrayIndexOutOfBoundsException: 9
"Same target group for station " +i,
zGroupsChoices,
zGroupsChoices[zG]); // definedModesAll - includes all others
}
} else {
this.zGroups[numSeries]=new int [1];
this.zGroups[numSeries][0]=0;
}
if (askNextSeries) {
gd.addCheckbox("Rebuild/Show parameter Map", showDirectMap);
gd.addCheckbox("Rebuild/Show reverse parameter Map", showReverseMap);
gd.addNumericField("Next series to edit (<0 - done)", numSeries+1, 0);
}
if (askNextSeries) gd.enableYesNoCancel("OK", "Done");
WindowTools.addScrollBars(gd);
gd.showDialog();
if (gd.wasCanceled()) return -2;
boolean copyFromPrevious=gd.getNextBoolean();
boolean removeAllImages=gd.getNextBoolean();
boolean selectAllImages=gd.getNextBoolean();
boolean selectEstimated=false;
if (numEstimated>0) selectEstimated=gd.getNextBoolean();
boolean selectNewEnabled=false;
if (numNewEnabled>0) selectNewEnabled=gd.getNextBoolean();
if (selectNewEnabled) {
this.selectedImages[numSeries]=this.distortionCalibrationData.selectNewEnabled();
return numSeries; // caller will repeat with the same series
}
if (this.distortionCalibrationData.eyesisCameraParameters.numStations>1){
// boolean removeUnselectedStations=gd.getNextBoolean();
for (int i=0;i<constrainByStation.length; i++) constrainByStation[i]=gd.getNextBoolean();
}
if (selectEstimated) {
this.selectedImages[numSeries]=this.distortionCalibrationData.selectEstimated(true); //(boolean enabledOnly
for (int i =0; i<this.distortionCalibrationData.getNumImages();i++){
this.selectedImages[numSeries][i]&=constrainByStation[this.distortionCalibrationData.gIP[i].getStationNumber()];
}
return numSeries; // caller will repeat with the same series
}
if (copyFromPrevious || removeAllImages || selectAllImages) {
for (int i =0; i<this.distortionCalibrationData.getNumImages();i++){
// this.selectedImages[numSeries][i]=false; // invalidate - all, regardless of .enabled
this.selectedImages[numSeries][i]=selectAllImages || ((i==0) && removeAllImages); // invalidate - all, regardless of .enabled
this.selectedImages[numSeries][i]&=constrainByStation[this.distortionCalibrationData.gIP[i].getStationNumber()];
}
return numSeries; // caller will repeat with the same series
}
boolean enableDisableSelected=false;
if (useImages) {
fromToImages[0]= (int) gd.getNextNumber();
fromToImages[1]= (int) gd.getNextNumber();
for (int i =0; i<this.distortionCalibrationData.getNumImages();i++)
if ((allImages || this.distortionCalibrationData.gIP[i].enabled) && (i>=fromToImages[0]) && (i<=fromToImages[1])){
this.selectedImages[numSeries][i]=gd.getNextBoolean();
}
if (allImages) enableDisableSelected=gd.getNextBoolean();
this.masterImages[numSeries]=(int) gd.getNextNumber();
if (this.masterImages[numSeries]<0)this.masterImages[numSeries]=0;
if (this.masterImages[numSeries]>=this.selectedImages[numSeries].length)this.masterImages[numSeries]=this.selectedImages[numSeries].length;
}
if (useParameters) {
int [] lastGroups=null;
for (int i =0; i<this.parameterEnable.length;i++) if (this.parameterEnable[i] &&
(!zeroAndOther || (this.parameterList[i][0] <=1) || (this.parameterList[i][0]==24))){ // in "zeroAndOther" mode do not show other subcameras
// for (int i =0; i<this.parameterEnable.length;i++) if (this.parameterEnable[i]){
this.parameterMode[numSeries][i]=gd.getNextChoiceIndex();
if (this.parameterMode[numSeries][i]==this.modeGroup) {
if (this.parameterGroups[numSeries][i]!=null) lastGroups=this.parameterGroups[numSeries][i]; // default groups
else if (lastGroups!=null) this.parameterGroups[numSeries][i]=lastGroups.clone(); // may be null
selectGroups(numSeries,i);
}
}
if (zeroAndOther){
for (int i =0; i<this.parameterEnable.length;i++) {
if ((this.parameterList[i][0]>1) && (this.parameterList[i][0]!=24)){ // "other" subchannels - copy from subchannel1
int refChannel=(this.parameterList[i][0]<24)?1:24;
int iSub1=getParameterNumber(refChannel, this.parameterList[i][1]);
if (this.parameterEnable[iSub1]){
// System.out.println( "parameter number="+i+" this.parameterList[i][0]="+this.parameterList[i][0]+" this.parameterList[i][1]="+this.parameterList[i][1]+" iSub1="+iSub1);
this.parameterMode[numSeries][i]=this.parameterMode[numSeries][iSub1];
if (this.parameterMode[numSeries][i]==this.modeGroup) { // copy groups from channel 1
if (this.parameterGroups[numSeries][i]!=null) this.parameterGroups[numSeries][i]=this.parameterGroups[numSeries][iSub1].clone(); // may be null
else this.parameterGroups[numSeries][i]=null;
}
}
}
}
}
}
if (askLambdas) {
this.lambdas[numSeries]=gd.getNextNumber();
this.stepDone[numSeries]=Double.parseDouble(gd.getNextString());
this.stopAfterThis[numSeries]=gd.getNextBoolean();
}
if (enableDisableSelected) {
this.distortionCalibrationData.enableSelected(this.selectedImages[numSeries]);
}
if (this.varianceModes!=null) this.varianceModes[numSeries]=gd.getNextChoiceIndex();
boolean editVariancesCosts=gd.getNextBoolean();
if (editVariancesCosts){
for (int i =0; i<this.parameterList.length;i++) {
int parIndex=this.parameterList[i][1];
if ((this.parameterMode[numSeries][i]==modeWeakCommon) ||
(this.parameterMode[numSeries][i]==modeWeakStation) ||
(this.parameterMode[numSeries][i]==modeTiltEqualize)
){
if (!this.distortionCalibrationData.eyesisCameraParameters.isExtrinsic(parIndex)){
System.out.println("BUG: this.parameterMode["+numSeries+"]["+i+"]="+this.parameterMode[numSeries][i]+
", but this parameter ("+this.distortionCalibrationData.getParameterName(parIndex)+" is not valid for variances");
continue;
}
this.distortionCalibrationData.eyesisCameraParameters.editCostProperties(
parIndex,
this.distortionCalibrationData.getParameterName(parIndex),
this.distortionCalibrationData.getParameterDescription(parIndex),
this.distortionCalibrationData.getParameterUnits(parIndex));
}
}
}
if (numStations>1){
for (int i=0;i<numStations;i++){
this.zGroups[numSeries][i]=gd.getNextChoiceIndex()-1;
}
}
if (!gd.wasOKed()) return -1; // pressed Done (no need to ask for the next number)
if (askNextSeries) {
showDirectMap=gd.getNextBoolean();
showReverseMap=gd.getNextBoolean();
if (showDirectMap || showReverseMap){
buildParameterMap(numSeries);
if (showDirectMap) showCurrentParameterMap ("Parameter map");
if (showReverseMap) showCurrentReverseParameterMap("Reverse parameter map");
}
int nextSeries= (int) gd.getNextNumber();
if (nextSeries<-1) nextSeries=-1;
return nextSeries;
}
return -1;
}
private boolean selectGroups(
int numSeries,
int numPar){
// if (this.debugLevel>1){
// System.out.println("selectGroups("+numSeries+", "+numPar+")");
// }
int parIndex=this.parameterList[numPar][1];
int subCam=this.parameterList[numPar][0];
String name=this.distortionCalibrationData.getParameterName(parIndex)+
(this.distortionCalibrationData.isSubcameraParameter(parIndex)?(" s"+subCam):"com ");
GenericDialog gd = new GenericDialog("Select image groups for "+name);
gd.addMessage("Select which images share the same value of "+name);
if (this.parameterGroups[numSeries][numPar]==null) {
this.parameterGroups[numSeries][numPar]=new int [this.distortionCalibrationData.getNumImages()];
for (int i=0;i<this.parameterGroups[numSeries][numPar].length;i++)this.parameterGroups[numSeries][numPar][i]=0;
}
String [] choices=organizeGroups(this.parameterGroups[numSeries][numPar],false); // preserve group numbers
for (int i =0; i<this.distortionCalibrationData.getNumImages();i++) if (this.selectedImages[numSeries][i]){
gd.addChoice (i+" - "+IJ.d2s(this.distortionCalibrationData.gIP[i].timestamp,6)+
": "+this.distortionCalibrationData.gIP[i].channel,
choices,
choices[this.parameterGroups[numSeries][numPar][i]]
);
}
WindowTools.addScrollBars(gd);
gd.showDialog();
if (gd.wasCanceled()) return false;
for (int i =0; i<this.distortionCalibrationData.getNumImages();i++) if (this.selectedImages[numSeries][i]){
this.parameterGroups[numSeries][numPar][i]=gd.getNextChoiceIndex();
}
return true;
}
/**
* Organizes list of groups and creates a list of selection choices. If all members fit in the range
* of 0 (length-1) and (force==false), group numbers are preserved, otherwise they are renumbered
* @param groups array of integers - group numbers
* @param force force renumbering groups
* @return list of selection choices
*/
private String [] organizeGroups(int []groups, boolean force) {
if ((groups==null) || (groups.length==0)){
String msg="Cannot organize mull or empty group";
IJ.showMessage("Error",msg);
throw new IllegalArgumentException (msg);
}
// See if 0.. length-1 groups is not enough to represent all numbers used
for (int i=0;!force && (i<groups.length);i++) if ((groups[i]<0) || (groups[i]>=(groups.length-1))) force = true;
if (force){
int [] tmp=groups.clone();
for (int i=0;i<groups.length;i++) groups[i]=-1;
int groupNumber=0;
int max=tmp[0]; for (int i=0;i<tmp.length;i++) if (max<tmp[i]) max=tmp[i];
for (boolean organized=false; !organized;){
int min=max+1;
for (int i=0;i<tmp.length;i++) if ((groups[i]<0) && (min>tmp[i])) min=tmp[i];
if (min>max) organized=true;
else {
for (int i=0;i<tmp.length;i++) if ((groups[i]<0) && (min == tmp[i])) {
groups[i]=groupNumber;
}
groupNumber++;
}
}
}
String [] rslt= new String [groups.length];
for (int i=0;i<rslt.length;i++) rslt[i]="Group "+(i+1);
return rslt;
}
public boolean selectStrategy(int startSerNumber){
int defaultLength=20;
boolean selectImages= false;
boolean allImages= false;
boolean selectParameters=true;
boolean askNextSeries= true;
boolean askLambdas= true;
boolean askParameterMask=false;
boolean zeroAndOther= true;
int [] fromToImages={0,500};
int numSeries=startSerNumber;
int oldLength=(this.selectedImages==null)?0:this.selectedImages.length;
GenericDialog gd = new GenericDialog("Fitting Strategy Step Configuration");
if (oldLength<=0) gd.addNumericField("Number of series in this strategy", defaultLength, 0);
gd.addNumericField("Number of series to edit (<0 - none)", numSeries, 0);
// gd.addNumericField("Number of series in this strategy", (oldLength>0)?oldLength:1, 0); //
gd.addCheckbox ("Select images",selectImages);
gd.addNumericField("Show image checkboxes from", fromToImages[0], 0);
gd.addNumericField("Show image checkboxes up to (inclufing)", fromToImages[1], 0);
gd.addCheckbox ("Select from all images (false - only enabled)",allImages);
gd.addCheckbox ("Select parameters",selectParameters);
gd.addCheckbox ("Ask for initial lambda",askLambdas);
gd.addCheckbox ("Ask for parameter mask",askParameterMask);
gd.addCheckbox ("Use only channel 0 and \"all other channels\"",zeroAndOther);
gd.addCheckbox ("Ask for next series",askNextSeries);
if (oldLength>0) gd.addNumericField("Increase number of series in this strategy", oldLength, 0);
gd.enableYesNoCancel("OK", "Done");
gd.showDialog();
if (gd.wasCanceled()) return false;
int numberOfSeries=0;
if (oldLength<=0) numberOfSeries= (int) gd.getNextNumber();
numSeries= (int) gd.getNextNumber();
selectImages= gd.getNextBoolean();
fromToImages[0]= (int) gd.getNextNumber();
fromToImages[1]= (int) gd.getNextNumber();
allImages= gd.getNextBoolean();
selectParameters= gd.getNextBoolean();
askLambdas= gd.getNextBoolean();
askParameterMask= gd.getNextBoolean();
zeroAndOther= gd.getNextBoolean();
askNextSeries= gd.getNextBoolean();
if (oldLength>0) numberOfSeries= (int) gd.getNextNumber();
if (numberOfSeries!=oldLength) setLength(numberOfSeries);
if (!gd.wasOKed()) return true;
if (askParameterMask) setParameterSelectionMask(zeroAndOther);
while ((numSeries>=0) && (numSeries<this.selectedImages.length)){
numSeries=selectStrategyStep(
numSeries,
selectImages,
fromToImages,
allImages,
selectParameters,
askLambdas,
askNextSeries,
zeroAndOther);
}
return true;
}
public boolean setParameterSelectionMask(boolean zeroAndOther){
GenericDialog gd = new GenericDialog("Set Parameter Selection Mask");
gd.addMessage("Common parameters and sub-camera 0 parameters");
int subCam=0;
boolean showParameter=true;
for (int i=0;i<this.parameterList.length;i++){
if (this.parameterList[i][0]!=subCam){
subCam=this.parameterList[i][0];
if (zeroAndOther) {
showParameter=true;
if (subCam==1) gd.addMessage("Other sub-cameras parameters");
else if (subCam==24) gd.addMessage("Bottom sub-cameras parameters");
// else break;
else {
showParameter=false;
// continue;
}
} else {
gd.addMessage("Sub-camera "+subCam+" parameters");
}
}
if (showParameter) gd.addCheckbox (this.distortionCalibrationData.getParameterName(parameterList[i][1]),this.parameterEnable[i]);
}
WindowTools.addScrollBars(gd);
// gd.setBackground(Color.white);
gd.showDialog();
if (gd.wasCanceled()) return false;
subCam=0;
showParameter=true;
//May add disablong all other subcameras, but try keeping it for later running with zeroAndOther==false
for (int i=0;i<this.parameterList.length;i++){
if (this.parameterList[i][0]!=subCam){
subCam=this.parameterList[i][0];
showParameter=true;
// if (subCam>1) break;
if ((subCam>1) && (subCam!=24)) showParameter=false;
}
if (showParameter) this.parameterEnable[i]=gd.getNextBoolean();
}
return true;
}
//this.currentSeriesNumber
public double getLambda(){
return getLambda(this.currentSeriesNumber);
}
public double getLambda(int numSeries){
return this.lambdas[numSeries];
}
public double getStepDone(){
return getStepDone(this.currentSeriesNumber);
}
public double getStepDone(int numSeries){
return this.stepDone[numSeries];
}
}
...@@ -47,16 +47,16 @@ horizontal axis: ...@@ -47,16 +47,16 @@ horizontal axis:
public CalibrationHardwareInterface.CamerasInterface cameras = null; public CalibrationHardwareInterface.CamerasInterface cameras = null;
// public CalibrationHardwareInterface.LaserPointers lasers = null; // public CalibrationHardwareInterface.LaserPointers lasers = null;
// public static CalibrationHardwareInterface.FocusingMotors motorsS=null; // public static CalibrationHardwareInterface.FocusingMotors motorsS=null;
// public Distortions.DistortionProcessConfiguration // public DistortionProcessConfiguration
// distortionProcessConfiguration=null; // distortionProcessConfiguration=null;
// public LensAdjustment.FocusMeasurementParameters focusMeasurementParameters = null; // public LensAdjustment.FocusMeasurementParameters focusMeasurementParameters = null;
// public Distortions.PatternParameters patternParameters=null; // public PatternParameters patternParameters=null;
// public Distortions.LensDistortionParameters // public LensDistortionParameters
// lensDistortionParameters=null; // lensDistortionParameters=null;
// public MatchSimulatedPattern.DistortionParameters distortion = null; // public MatchSimulatedPattern.DistortionParameters distortion = null;
public MatchSimulatedPattern.DistortionParameters distortionParametersDefault=null; public MatchSimulatedPattern.DistortionParameters distortionParametersDefault=null;
public Distortions.EyesisCameraParameters eyesisCameraParameters = null; public EyesisCameraParameters eyesisCameraParameters = null;
public MatchSimulatedPattern[] matchSimulatedPatterns = null; // =new public MatchSimulatedPattern[] matchSimulatedPatterns = null; // =new
// MatchSimulatedPattern(); // MatchSimulatedPattern();
...@@ -64,7 +64,7 @@ horizontal axis: ...@@ -64,7 +64,7 @@ horizontal axis:
MatchSimulatedPattern.PatternDetectParameters patternDetectParameters=null; MatchSimulatedPattern.PatternDetectParameters patternDetectParameters=null;
public SimulationPattern.SimulParameters simulParametersDefault=null; public SimulationPattern.SimulParameters simulParametersDefault=null;
public Goniometer.GoniometerParameters goniometerParameters = null; public Goniometer.GoniometerParameters goniometerParameters = null;
public Distortions.DistortionProcessConfiguration distortionProcessConfiguration=null; public DistortionProcessConfiguration distortionProcessConfiguration=null;
public int lastScanStep=-1; public int lastScanStep=-1;
public int debugLevel = 2; public int debugLevel = 2;
public double bottomRollerTilt=60.0; // decrease scan step if tilt is above this public double bottomRollerTilt=60.0; // decrease scan step if tilt is above this
...@@ -75,11 +75,11 @@ horizontal axis: ...@@ -75,11 +75,11 @@ horizontal axis:
MatchSimulatedPattern.DistortionParameters distortionParametersDefault, MatchSimulatedPattern.DistortionParameters distortionParametersDefault,
// MatchSimulatedPattern.DistortionParameters distortion, // MatchSimulatedPattern.DistortionParameters distortion,
MatchSimulatedPattern.PatternDetectParameters patternDetectParameters, MatchSimulatedPattern.PatternDetectParameters patternDetectParameters,
Distortions.EyesisCameraParameters eyesisCameraParameters, EyesisCameraParameters eyesisCameraParameters,
MatchSimulatedPattern.LaserPointer laserPointers, MatchSimulatedPattern.LaserPointer laserPointers,
SimulationPattern.SimulParameters simulParametersDefault, SimulationPattern.SimulParameters simulParametersDefault,
Goniometer.GoniometerParameters goniometerParameters, Goniometer.GoniometerParameters goniometerParameters,
Distortions.DistortionProcessConfiguration distortionProcessConfiguration DistortionProcessConfiguration distortionProcessConfiguration
) { ) {
this.cameras = cameras; this.cameras = cameras;
this.distortionParametersDefault = distortionParametersDefault; this.distortionParametersDefault = distortionParametersDefault;
...@@ -519,8 +519,8 @@ horizontal axis: ...@@ -519,8 +519,8 @@ horizontal axis:
public boolean testHintedTarget ( public boolean testHintedTarget (
ImagePlus[] images, ImagePlus[] images,
Distortions lensDistortions, // should not be null Distortions lensDistortions, // should not be null
Distortions.DistortionCalibrationData distortionCalibrationData, DistortionCalibrationData distortionCalibrationData,
Distortions.PatternParameters patternParameters, // should not be null PatternParameters patternParameters, // should not be null
boolean equalizeGreens, boolean equalizeGreens,
int threadsMax, int threadsMax,
boolean updateStatus, boolean updateStatus,
...@@ -677,7 +677,7 @@ horizontal axis: ...@@ -677,7 +677,7 @@ horizontal axis:
* *
* this.parameterMode[numSeries][i]=gd.getNextChoiceIndex(); * this.parameterMode[numSeries][i]=gd.getNextChoiceIndex();
Distortions.PatternParameters patternParameters, // should not be null PatternParameters patternParameters, // should not be null
boolean equalizeGreens, boolean equalizeGreens,
int threadsMax, int threadsMax,
boolean updateStatus, boolean updateStatus,
...@@ -724,8 +724,8 @@ horizontal axis: ...@@ -724,8 +724,8 @@ horizontal axis:
// MatchSimulatedPattern.PatternDetectParameters patternDetectParameters, // MatchSimulatedPattern.PatternDetectParameters patternDetectParameters,
// MatchSimulatedPattern.LaserPointer laserPointer, // null OK // MatchSimulatedPattern.LaserPointer laserPointer, // null OK
// SimulationPattern.SimulParameters simulParametersDefault, // SimulationPattern.SimulParameters simulParametersDefault,
Distortions.DistortionCalibrationData distortionCalibrationData, DistortionCalibrationData distortionCalibrationData,
Distortions.PatternParameters patternParameters, // should not be null PatternParameters patternParameters, // should not be null
Distortions lensDistortions, // should not be null Distortions lensDistortions, // should not be null
boolean equalizeGreens, boolean equalizeGreens,
int threadsMax, int threadsMax,
...@@ -888,8 +888,8 @@ horizontal axis: ...@@ -888,8 +888,8 @@ horizontal axis:
} }
} }
/* /*
* Distortions.DistortionCalibrationData distortionCalibrationData= new * DistortionCalibrationData distortionCalibrationData= new
* Distortions.DistortionCalibrationData( imp_calibrated, //ImagePlus [] * DistortionCalibrationData( imp_calibrated, //ImagePlus []
* images, // images in the memory patternParameters, * images, // images in the memory patternParameters,
* //PatternParameters patternParameters, eyesisCameraParameters * //PatternParameters patternParameters, eyesisCameraParameters
* //EyesisCameraParameters eyesisCameraParameters ); * //EyesisCameraParameters eyesisCameraParameters );
...@@ -914,7 +914,7 @@ horizontal axis: ...@@ -914,7 +914,7 @@ horizontal axis:
// fitting strategy // fitting strategy
// distortionCalibrationData.pathName=this.goniometerParameters.initialCalibrationFile; // distortionCalibrationData.pathName=this.goniometerParameters.initialCalibrationFile;
lensDistortions.debugLevel = this.debugLevel; lensDistortions.debugLevel = this.debugLevel;
lensDistortions.fittingStrategy = new Distortions.FittingStrategy(true, lensDistortions.fittingStrategy = new FittingStrategy(true,
this.goniometerParameters.strategyFile, this.goniometerParameters.strategyFile,
distortionCalibrationData); // will use list of grid files distortionCalibrationData); // will use list of grid files
if (lensDistortions.fittingStrategy.pathName == null) { // failed to select/open the file if (lensDistortions.fittingStrategy.pathName == null) { // failed to select/open the file
......
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
**
** PatternParameters.java
**
** Copyright (C) 2011-2014 Elphel, Inc.
**
** -----------------------------------------------------------------------------**
**
** PatternParameters.java is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
** -----------------------------------------------------------------------------**
**
*/
import ij.IJ;
import ij.ImagePlus;
import ij.ImageStack;
import ij.gui.GenericDialog;
import ij.io.FileSaver;
import ij.io.Opener;
import java.awt.Rectangle;
import java.util.Properties;
/* gridGeometry:
* [v][u][0] - x(mm) of the node(u,v), right (looking to the wall) - positive
* [v][u][1] - y(mm) of the node(u,v), down - positive
* [v][u][2] - z(mm) of the node(u,v), away (into the wall) - positive
* [v][u][3] - mask 0.0 - outside of the pattern rectangle, 1.0 - on the pattern
* RGB moved to Photometric
* [v][u][4] - R-intensity (normalized to 1.0 full scale)
* [v][u][5] - G-intensity
* [v][u][6] - B-intensity
* ... repeat 3,4,5,6 for different views of the pattern (from different points)
*/
public class PatternParameters {
public double patternWidth; // pattern full width in mm
public double patternHeight; // pattern full height in mm
public double patternHalfPeriod; // distance between opposite sign nodes
public double patternTilt; // pattern tilt (degrees) - U clockwise from X-right (V clockwise from Y-down)
public int [] viewMap=null; // should have
public int numStations=1;
public int numberOfViews=1;
public double [][][] gridGeometry=null; // [v][u]{x,y,z,{"alpha", R-intensity, G--intensity, B--intensity} alpha=0 - no ghrid, 1 - grid}
public double [][][] stationZCorr=null; // [v][u]{station0... stationN} - per-station addition to the gridGeometry[][][2]
public double [] averageRGB={1.0,1.0,1.0};
public int numGeometricChannels=4; // x,y,z,mask
public int numPhotometricChannels=4; // r,g,b,a
public int defaultNumberOfChannels=26;
// public int numLayers=7; // number of layers in gridGeometry
public int U0=0; //39
public int V0=0; //36
public int debugLevel=2;
public boolean updateStatus=true;
public String pathName=null; // path from which the grid was read/ where it was last saved to
public double [][][][] photometricByView=null; // [numStation][numView]{a,r,g,b}[pixel]
// public double [][][] photometricBySensor=null;
public double [] patternErrors=null; // weighted RMS error for each pattern node, calculated
public double [] patternErrorMask=null; // weighted RMS error for each pattern node, calculated
public double [] patternErrorMaskSaved=null; // weighted RMS error for each pattern node, calculated
public void initStationZCorr(){
this.stationZCorr=new double [this.gridGeometry.length][this.gridGeometry[0].length][this.numStations];
for (int v=0;v<this.stationZCorr.length;v++) for (int u=0;u<this.stationZCorr[0].length;u++) for (int s=0;s<this.stationZCorr[0][0].length;s++){
this.stationZCorr[v][u][s]=0.0;
}
}
public void resetStationZCorr(){
this.stationZCorr=null;
}
public Rectangle getUVDimensions(){
return new Rectangle(U0,V0,gridGeometry[0].length,gridGeometry.length);
}
public void setPatternErrors(double [] patternErrors){
this.patternErrors=patternErrors;
}
public double [] getPatternErrors(){
return this.patternErrors;
}
public double [] getPatternErrorMask(){
return this.patternErrorMask;
}
public double [] calculatePatternErrorMask(double maxRMS, double minRMS){
double [] mask=new double [this.patternErrors.length]; // null pointer
double a=1.0/(maxRMS-minRMS);
boolean binary=maxRMS==minRMS;
for (int i=0;i<this.patternErrors.length;i++){
if (Double.isNaN(this.patternErrors[i])) mask[i]=0.0;
else {
if (binary) mask[i]=(this.patternErrors[i]>=maxRMS)?0.0:1.0;
else {
double x= a*(this.patternErrors[i]-minRMS);
if (x<=0) mask[i]=1.0;
else if (x>=1.0) mask[i]=0.0;
else mask[i]=1.0+2*x*x*x-3*x*x;
}
}
}
this.patternErrorMask=mask;
return mask;
}
public double [] expandPatternErrorMask(){
Rectangle dimensions=getUVDimensions();
int [] dirs={1,dimensions.width+1,dimensions.width,dimensions.width-1,-1,-dimensions.width-1,-dimensions.width,dimensions.width+1};
double [] mask=this.patternErrorMask.clone();
for (int v=1;v<(dimensions.height-1);v++) for (int u=1;u<(dimensions.width-1);u++){
int index=v*dimensions.width+u;
double min=this.patternErrorMask[index];
for (int iDir=0;iDir<dirs.length;iDir++){
if (this.patternErrorMask[index+dirs[iDir]]<min) min=this.patternErrorMask[index+dirs[iDir]];
}
mask[index]=min;
}
this.patternErrorMask=mask;
return this.patternErrorMask;
}
//patternErrorMaskSaved
public void resetPatternErrorMask(){
this.patternErrorMask=null;
}
public void savePatternErrorMask(){
if (this.patternErrorMask!=null) this.patternErrorMaskSaved=this.patternErrorMask.clone();
else this.patternErrorMaskSaved=null;
}
public void restorePatternErrorMask(){
if (this.patternErrorMaskSaved!=null) this.patternErrorMask=this.patternErrorMaskSaved.clone();
else this.patternErrorMask=null;
}
public double [] getSavedPatternErrorMask(){
return this.patternErrorMaskSaved;
}
public PatternParameters(
int [] viewMap,
int numStations,
double patternWidth, // pattern full width in mm
double patternHeight, // pattern full height in mm
double patternHalfPeriod, // distance between opposite sign nodes
double patternTilt // pattern tilt (degrees) - U clockwise from X-right (V clockwise from Y-down)
){
this.numStations=numStations;
this.patternWidth=patternWidth;
this.patternHeight=patternHeight;
this.patternHalfPeriod=patternHalfPeriod;
this.patternTilt=patternTilt;
setPhotometric(viewMap);
calculateGridGeometryAndPhotometric(true);
}
public void updateNumStations(int numStations){
this.numStations=numStations;
if (numStations==this.photometricByView.length) {
return;
}
System.out.println ("Updating pattern number of stations from "+this.photometricByView.length+" to "+numStations);
double [][][][] photometricByViewCopy=this.photometricByView;
this.photometricByView=new double [this.numStations][][][];
for (int i=0;i<this.photometricByView.length;i++){
if (i<photometricByViewCopy.length){
this.photometricByView[i]= photometricByViewCopy[i];
} else { // deep clone last station
int iSource=photometricByViewCopy.length-1;
this.photometricByView[i]=new double [photometricByViewCopy[iSource].length][][];
for (int j=0;j<photometricByViewCopy[iSource].length;j++){
if (photometricByViewCopy[iSource][j]==null) {
this.photometricByView[i][j]=null;
} else {
this.photometricByView[i][j]=new double [photometricByViewCopy[iSource][j].length][];
for (int k=0;k<photometricByViewCopy[iSource][j].length;k++){
if (photometricByViewCopy[iSource][j][k]==null) {
this.photometricByView[i][j][k]=null;
} else {
this.photometricByView[i][j][k]=photometricByViewCopy[iSource][j][k].clone();
}
}
}
}
}
}
}
public void setPhotometric(int [] viewMap){
if (viewMap==null){
this.viewMap=null;
} else{
this.viewMap=viewMap.clone();
}
setPhotometric();
}
public void setPhotometric(){
if (this.viewMap==null){
this.viewMap=new int[1];
this.viewMap[0]=0;
}
int maxView=0;
for (int i=0;i<this.viewMap.length;i++) if (this.viewMap[i]>maxView) maxView=this.viewMap[i];
this.numberOfViews=maxView+1;
this.photometricByView=new double [this.numStations][this.numberOfViews][4][];
}
public void initDefaultChannels(int num){
this.viewMap=new int[num];
for (int i=0;i<num;i++) this.viewMap[i]=(i<24)?0:1;
this.numberOfViews=2;
}
public double [][] getPhotometricByView(int stationNumber, int nView){
if (stationNumber>=this.photometricByView.length) stationNumber=this.photometricByView.length-1;
if (nView>=this.photometricByView[stationNumber].length) nView=this.photometricByView[stationNumber].length-1;
return this.photometricByView[stationNumber][nView];
}
public double [][] getPhotometricBySensor(int stationNumber,int nSensor){
if (getNumStations()<=stationNumber) updateNumStations(stationNumber+1);
// if (stationNumber>=this.photometricByView.length) stationNumber=this.photometricByView.length-1;
int isens=nSensor;
if (nSensor>=this.viewMap.length){
System.out.println("nSensor="+nSensor+" this.viewMap.length="+this.viewMap.length+" this.photometricByView.length="+this.photometricByView.length);
nSensor=this.viewMap.length-1;
}
int nView=this.viewMap[nSensor];
if (nView>=this.photometricByView[stationNumber].length){
System.out.println("nSensor was "+isens+", nView="+nView+" this.photometricByView["+stationNumber+"].length="+this.photometricByView[stationNumber].length);
nView=this.photometricByView.length-1;
}
return this.photometricByView[stationNumber][nView];
}
// public int getNumViews(){return this.photometricByView[0].length;}
public int getNumViews(){return this.numberOfViews;}
public int getNumStations(){return this.numStations;}
public void setNumStations(int numStations){this.numStations=numStations;}
public int [] getViewMap(){return this.viewMap;}
public int getNumGeometricChannels(){return this.numGeometricChannels;}
public int getNumPhotometricChannels(){return this.numPhotometricChannels;}
public PatternParameters(
int [] viewMap,
double patternWidth, // pattern full width in mm
double patternHeight, // pattern full height in mm
double patternHalfPeriod, // distance between opposite sign nodes
double patternTilt, // pattern tilt (degrees) - U clockwise from X-right (V clockwise from Y-down)
double [] averageRGB
){
this.patternWidth=patternWidth;
this.patternHeight=patternHeight;
this.patternHalfPeriod=patternHalfPeriod;
this.patternTilt=patternTilt;
this.averageRGB=averageRGB.clone();
setPhotometric(viewMap);
calculateGridGeometryAndPhotometric(true);
}
public PatternParameters clone() {
PatternParameters patternParameters= new PatternParameters(
this.viewMap,
this.patternWidth, // pattern full width in mm
this.patternHeight, // pattern full height in mm
this.patternHalfPeriod, // distance between opposite sign nodes
this.patternTilt, // pattern tilt (degrees) - U clockwise from X-right (V clockwise from Y-down)
this.averageRGB);
patternParameters.debugLevel=this.debugLevel;
patternParameters.updateStatus=this.updateStatus;
patternParameters.pathName=this.pathName;
return patternParameters;
}
public ImagePlus saveGridAsImageStack(String title, String path){
ImagePlus imp=getGridAsImageStack(title);
if (imp==null) return null;
FileSaver fs=new FileSaver(imp);
if (updateStatus) IJ.showStatus("Saving grid "+path);
if (imp.getStackSize()>1)
fs.saveAsTiffStack(path);
else
fs.saveAsTiff(path);
this.pathName=path;
if (this.debugLevel>0) System.out.println("Pattern saved as "+this.pathName);
return imp;
}
public String selectAndSave(boolean smart, String defaultPath){
String [] extensions={".grid-tiff","-grid.tiff"};
CalibrationFileManagement.MultipleExtensionsFileFilter parFilter = new CalibrationFileManagement.MultipleExtensionsFileFilter("",extensions,"Pattern grid *.grid-tiff files");
String pathname=CalibrationFileManagement.selectFile(
smart,
true,
"Save Pattern Grid Geometry",
"Save",
parFilter,
(defaultPath==null)?this.pathName:defaultPath); //String defaultPath
if ((pathname!=null)&& (pathname.length()!=0)) saveGridAsImageStack("Pattern Grid", pathname);
return pathname;
}
public String selectAndRestore(boolean smart, String defaultPath, int numStations){
String [] extensions={".grid-tiff","-grid.tiff"};
CalibrationFileManagement.MultipleExtensionsFileFilter parFilter = new CalibrationFileManagement.MultipleExtensionsFileFilter("",extensions,"Pattern grid *.grid-tiff files");
String pathname=CalibrationFileManagement.selectFile(
smart,
false,
"Restore Pattern Grid Geometry",
"Restore",
parFilter,
(defaultPath==null)?this.pathName:defaultPath); //String defaultPath
if ((pathname==null) || (pathname=="")) return null;
setNumStations(numStations);
setGridFromImageStack(pathname);
return pathname;
}
public void setGridFromImageStack(String path){
Opener opener=new Opener();
ImagePlus imp=opener.openImage("", path);
if (imp==null) {
String msg="Failed to read grid geometry file "+path;
IJ.showMessage("Error",msg);
throw new IllegalArgumentException (msg);
}
(new JP46_Reader_camera(false)).decodeProperiesFromInfo(imp);
setGridFromImageStack(imp);
this.pathName=path;
if (this.debugLevel>0) System.out.println("Opened "+path+" as a stack of the pattern grid geometry");
}
/**
* Loads grid geomnetry (data in mm, X - left, Y - down, Z - into the wall) frome mult-slice
* ImagePlus. Properties should be set or decoded from the info in the tiff file
* @param imp - ImagePlus stack, containg x,y,z,alpha slices
*/
public void setGridFromImageStack(ImagePlus imp){
int indexAlpha=3;
if (imp == null){
String msg="Grid image is null";
IJ.showMessage("Error",msg);
throw new IllegalArgumentException (msg);
}
if (imp.getStackSize()<4){
String msg="Expected >=4 slice image with grid geometry";
IJ.showMessage("Error",msg);
throw new IllegalArgumentException (msg);
}
if ( (imp.getProperty("U0") == null) ||
(imp.getProperty("V0") == null)){
String msg="Properties \"U0\" and/or \"V0\" do not exist";
IJ.showMessage("Error",msg);
throw new IllegalArgumentException (msg);
}
this.U0=Integer.parseInt((String) imp.getProperty("U0"));
this.V0=Integer.parseInt((String) imp.getProperty("V0"));
// Other properties that are needed only during pattern generation:
if (imp.getProperty("patternWidth")!=null) this.patternWidth=Double.parseDouble((String) imp.getProperty("patternWidth"));
if (imp.getProperty("patternHeight")!=null) this.patternHeight=Double.parseDouble((String) imp.getProperty("patternHeight"));
if (imp.getProperty("patternHalfPeriod")!=null) this.patternHalfPeriod=Double.parseDouble((String) imp.getProperty("patternHalfPeriod"));
if (imp.getProperty("patternTilt")!=null) this.patternTilt=Double.parseDouble((String) imp.getProperty("patternTilt"));
if (imp.getProperty("AverageRed")!=null) this.averageRGB[0]=Double.parseDouble((String) imp.getProperty("AverageRed"));
if (imp.getProperty("AverageGreen")!=null) this.averageRGB[1]=Double.parseDouble((String) imp.getProperty("AverageGreen"));
if (imp.getProperty("AverageBlue")!=null) this.averageRGB[2]=Double.parseDouble((String) imp.getProperty("AverageBlue"));
int numZCorr=0;
if (imp.getProperty("numZCorr")!=null) numZCorr=Integer.parseInt((String) imp.getProperty("numZCorr"));
// if (imp.getProperty("numStations")!=null) this.numStations=Integer.parseInt((String) imp.getProperty("numStations"));
int width=imp.getWidth();
int height=imp.getHeight();
ImageStack stack = imp.getStack();
if (stack==null) {
String msg="Expected a image stack with grid geometry";
IJ.showMessage("Error",msg);
throw new IllegalArgumentException (msg);
}
float [][] pixels =new float[stack.getSize()][];
for (int i=0;i<pixels.length;i++) pixels[i]= (float[]) stack.getPixels(i+1);
if (this.debugLevel>3){
System.out.println("setGridFromImageStack() width="+width+", height="+height+", pixels[0].length="+pixels[0].length);
}
this.gridGeometry=new double[height][width][getNumGeometricChannels()]; // x,y,z, alpha
boolean geometryMaskOnly=(pixels.length==getNumGeometricChannels());
boolean singleNoAlpha=(pixels.length==7);
int totalNumViews=(geometryMaskOnly || singleNoAlpha)?1:((pixels.length-getNumGeometricChannels()-numZCorr)/getNumPhotometricChannels());
int fileNumStations=totalNumViews/getNumViews(); // keep current number of stations
int length=height*width;
for (int v=0;v<height;v++) for (int u=0;u<width;u++) for (int n=0;n<getNumGeometricChannels();n++){ // x,y,z, alpha
this.gridGeometry[v][u][n]=pixels[n][v*width+u];
}
if (fileNumStations!=getNumStations()){
if (this.debugLevel>0){
System.out.println("File has "+totalNumViews+" photometric slices, expected "+(getNumStations()*getNumViews())+
" ("+getNumStations()+" stations, "+getNumViews()+" views ), skipping loading photometric data");
}
/// TODO: Fix me!
return; //
}
if (numZCorr>0) {
if (numZCorr==getNumStations()) {
if (this.debugLevel>0){
System.out.println("Loading zCorr data: "+getNumStations()+" slices");
}
this.stationZCorr=new double [height][width][numZCorr];
for (int v=0;v<height;v++) for (int u=0;u<width;u++) for (int n=0;n<numZCorr;n++){
this.stationZCorr[v][u][n]=pixels[n+getNumGeometricChannels()][v*width+u];
}
} else {
System.out.println("File has "+numZCorr+" ZCorr slices, current number of stations is "+getNumStations()+
", skipping loading zCorr data (per-station pattern Z-correction from the average Z)");
}
}
if (this.debugLevel>0){
System.out.println("Loading photometric data: "+(getNumStations()*getNumViews())+" slices "+
" ("+getNumStations()+" stations, "+getNumViews()+" vies )");
}
this.photometricByView=new double [this.numStations][this.numberOfViews][getNumPhotometricChannels()][length]; // r,g,b,a
for (int numStation=0;numStation<this.numStations;numStation++) {
int useNumStation=numStation;
if ((useNumStation>0) && (useNumStation>=fileNumStations)) useNumStation=fileNumStations-1;
for (int nView=0;nView<getNumViews();nView++) {
for (int chn=0;chn<getNumPhotometricChannels();chn++){
int pixIndex=numGeometricChannels+numZCorr+(nView + getNumViews()*useNumStation)*getNumPhotometricChannels()+chn;
if ((pixIndex>=pixels.length) && (chn>2)) pixIndex=indexAlpha; // use mask for non-existent alpha
if (pixIndex>=pixels.length) {
for (int i=0;i<length;i++) {
this.photometricByView[useNumStation][nView][chn][i]=(pixels[indexAlpha][i]>0.5)?this.averageRGB[chn]:0.0; // 0<=chn<=2 here OOB =3
}
} else {
for (int i=0;i<length;i++) {
this.photometricByView[useNumStation][nView][chn][i]=pixels[pixIndex][i]; //OOB12
}
}
}
}
}
}
//getNumPhotometricChannels()
public ImagePlus getGridAsImageStack(String title){
if (this.gridGeometry==null){
String msg="Grid geometry does not exist, nothing to convert";
IJ.showMessage("Error",msg);
throw new IllegalArgumentException (msg);
}
int width=this.gridGeometry[0].length;
int height=this.gridGeometry.length;
int length=height*width;
int numZCorr=0;
if (this.stationZCorr!=null) {
for (int v=0;(v<height) && (numZCorr==0);v++ ) for (int u=0;u<width;u++) if (this.stationZCorr[v][u]!=null){
numZCorr=this.stationZCorr[v][u].length;
break;
}
}
// float [][]pixels=new float [this.gridGeometry[0][0].length][width*height];
float [][] pixels=new float [getNumGeometricChannels()+numZCorr+getNumViews()*getNumStations()*getNumPhotometricChannels()] [length];
String [] titles=new String[pixels.length];
String [] geometricTitles= {"X","Y","Z","Mask"};
String [] zCorrTitles=new String [numZCorr];
for (int i=0;i<numZCorr;i++) zCorrTitles[i]="dZ"+i;
String [] photometricTitles={"red","green","blue","alpha"};
int index=0;
for (int v=0;v<height;v++) for (int u=0;u<width;u++){
for (int n=0;n<getNumGeometricChannels();n++) { // should be 4==numGeometricChannels
pixels[n][index]= (float) this.gridGeometry[v][u][n];
}
for (int n=0;n<numZCorr;n++) { // should be 4==numGeometricChannels
pixels[n+getNumGeometricChannels()][index]= (this.stationZCorr[v][u]!=null)?((float) this.stationZCorr[v][u][n]):0.0f;
}
index++;
}
for (int n=0;n<getNumGeometricChannels();n++) titles[n]=geometricTitles[n];
for (int numStation=0;numStation<this.numStations;numStation++) {
for (int nView=0;nView<getNumViews();nView++) {
for (int chn=0;chn<getNumPhotometricChannels();chn++){
// int pixIndex=getNumGeometricChannels()+chn*this.getNumPhotometricChannels()();
int pixIndex=getNumGeometricChannels()+numZCorr+(nView + numStation*getNumViews()) *getNumPhotometricChannels()+chn;
for (int i=0;i<length;i++) pixels[pixIndex][i]= (float) this.photometricByView[numStation][nView][chn][i]; //OOB 8 //oob 12
titles[pixIndex]=photometricTitles[chn]+nView;
}
}
}
for (int i=0;i<numZCorr;i++){
titles[getNumGeometricChannels()+i]=zCorrTitles[i];
}
ImagePlus imp=null;
ImageStack stack=new ImageStack(width,height);
for (int n=0;n<pixels.length;n++) stack.addSlice(titles[n], pixels[n]);
imp = new ImagePlus(title, stack);
imp.setProperty("patternWidth", ""+this.patternWidth);
imp.setProperty("patternHeight", ""+this.patternHeight);
imp.setProperty("patternHalfPeriod", ""+this.patternHalfPeriod);
imp.setProperty("patternTilt", ""+this.patternTilt);
imp.setProperty("U0", ""+this.U0);
imp.setProperty("V0", ""+this.V0);
imp.setProperty("AverageRed", ""+this.averageRGB[0]);
imp.setProperty("AverageGreen", ""+this.averageRGB[1]);
imp.setProperty("AverageBlue", ""+this.averageRGB[2]);
if (numZCorr>0) imp.setProperty("numZCorr", ""+numZCorr);
(new JP46_Reader_camera(false)).encodeProperiesToInfo(imp);
imp.getProcessor().resetMinAndMax();
return imp;
}
public void applyGridCorrection(double [][] gridCorr){
applyGridCorrection(gridCorr, 1.0);
}
/**
* Apply X,Y,Z correction to the current grid geometry
* @param gridCorr array [4][width*height] of the corrections to grid geometry (x,y,z,weight).
* Weight is not used, just for information (1.0 - one image file used with full weight)
* @param scale scale correction
*/
public void applyGridCorrection(double [][] gridCorr, double scale){
if (this.gridGeometry==null){
String msg="Grid geometry does not exist, nothing to apply correction to";
IJ.showMessage("Error",msg);
throw new IllegalArgumentException (msg);
}
int height=this.gridGeometry.length;
int width=this.gridGeometry[0].length;
if ((gridCorr==null) || (gridCorr.length!=4) || (gridCorr[0].length!=(width*height))){
String msg="Correction is null or does not match pattern grid geometry";
IJ.showMessage("Error",msg);
throw new IllegalArgumentException (msg);
}
for (int v=0;v<height;v++) for (int u=0;u<width;u++) if (this.gridGeometry[v][u][3]>0.0){ // only apply to defined grid
int vu=v*width+u;
for (int n=0;n<3;n++) this.gridGeometry[v][u][n]+= scale*gridCorr[n][vu];
}
}
public void applyZGridCorrection(
double [][] gridZCorr3d,
double scale){
int height=this.gridGeometry.length;
int width=this.gridGeometry[0].length;
if ((gridZCorr3d==null) || (gridZCorr3d.length!=this.numStations) || (gridZCorr3d[0].length!=(width*height))){
String msg="Correction is null or does not match pattern grid geometry";
IJ.showMessage("Error",msg);
throw new IllegalArgumentException (msg);
}
this.stationZCorr=new double [height][width][this.numStations];
for (int v=0;v<height;v++) for (int u=0;u<width;u++) {
int vu=v*width+u;
for (int s=0;s<this.numStations;s++){
this.stationZCorr[v][u][s]=scale*gridZCorr3d[s][vu];
}
}
}
public void setProperties(String prefix,Properties properties){
properties.setProperty(prefix+"patternWidth",this.patternWidth+"");
properties.setProperty(prefix+"patternHeight",this.patternHeight+"");
properties.setProperty(prefix+"patternHalfPeriod",this.patternHalfPeriod+"");
properties.setProperty(prefix+"patternTilt",this.patternTilt+"");
properties.setProperty(prefix+"averageRGB_0",this.averageRGB[0]+"");
properties.setProperty(prefix+"averageRGB_1",this.averageRGB[1]+"");
properties.setProperty(prefix+"averageRGB_2",this.averageRGB[2]+"");
if (this.viewMap!=null){
properties.setProperty(prefix+"viewMap_length",this.viewMap.length+"");
for (int i=0;i<this.viewMap.length;i++) {
properties.setProperty(prefix+"viewMap_"+i,this.viewMap[i]+"");
}
}
// this.viewMap;
}
public void getProperties(String prefix,Properties properties){
if (properties.getProperty(prefix+"patternWidth")!=null)
this.patternWidth=Double.parseDouble(properties.getProperty(prefix+"patternWidth"));
if (properties.getProperty(prefix+"patternHeight")!=null)
this.patternHeight=Double.parseDouble(properties.getProperty(prefix+"patternHeight"));
if (properties.getProperty(prefix+"patternHalfPeriod")!=null)
this.patternHalfPeriod=Double.parseDouble(properties.getProperty(prefix+"patternHalfPeriod"));
if (properties.getProperty(prefix+"patternTilt")!=null)
this.patternTilt=Double.parseDouble(properties.getProperty(prefix+"patternTilt"));
if (properties.getProperty(prefix+"averageRGB_0")!=null)
this.averageRGB[0]=Double.parseDouble(properties.getProperty(prefix+"averageRGB_0"));
if (properties.getProperty(prefix+"averageRGB_1")!=null)
this.averageRGB[1]=Double.parseDouble(properties.getProperty(prefix+"averageRGB_1"));
if (properties.getProperty(prefix+"averageRGB_2")!=null)
this.averageRGB[2]=Double.parseDouble(properties.getProperty(prefix+"averageRGB_2"));
if (properties.getProperty(prefix+"viewMap_length")!=null) {
this.viewMap=new int [Integer.parseInt(properties.getProperty(prefix+"viewMap_length"))];
for (int i=0;i<this.viewMap.length;i++) {
this.viewMap[i]=0;
if (properties.getProperty(prefix+"viewMap_"+i)!=null)
this.viewMap[i]=Integer.parseInt(properties.getProperty(prefix+"viewMap_"+i));
}
}
setPhotometric();
calculateGridGeometryAndPhotometric(true); // may need to setup this.photometricBySensor
}
public boolean showDialog() {
GenericDialog gd = new GenericDialog("Initial Wall pattern parameters");
gd.addNumericField("Pattern full width", this.patternWidth, 1,6,"mm"); // pattern full width in mm
gd.addNumericField("Pattern full height", this.patternHeight, 1,6,"mm"); // pattern full width in mm
gd.addNumericField("Distance between opposite sign nodes",this.patternHalfPeriod, 4,8,"mm"); // istance between opposite sign nodes in mm
gd.addNumericField("Pattern tilt (clockwise)", this.patternTilt, 1,5,"degrees"); // pattern tilt (degrees) - U clockwise from X-right (V clockwise from Y-down)
gd.addNumericField("Average grid RED (1.0 for white)", this.averageRGB[0], 3,5,"x"); //
gd.addNumericField("Average grid GREEN (1.0 for white)", this.averageRGB[1], 3,5,"x"); //
gd.addNumericField("Average grid BLUE (1.0 for white)", this.averageRGB[2], 3,5,"x"); //
gd.addNumericField("Number of sensors (>24 - two groups, 0 - do not change)",this.defaultNumberOfChannels,0); //
gd.addMessage("Pressing OK will recalculate grid and clear current grid calibration");
gd.showDialog();
if (gd.wasCanceled()) return false;
this.patternWidth= gd.getNextNumber();
this.patternHeight= gd.getNextNumber();
this.patternHalfPeriod= gd.getNextNumber();
this.patternTilt= gd.getNextNumber();
this.averageRGB[0]= gd.getNextNumber();
this.averageRGB[1]= gd.getNextNumber();
this.averageRGB[2]= gd.getNextNumber();
int numberOfChannels= (int)gd.getNextNumber();
if (numberOfChannels>0){
initDefaultChannels(numberOfChannels);
// setPhotometric();
}
setPhotometric();
calculateGridGeometryAndPhotometric(true);
return true;
}
/**
* Calculate pattern x,y,z==0 and alpha (1.0 - inside, 0.0 - outside) for the grid
* @param resetAll - if true - reset all grid info, if false - only recalculate mask and reset flat field info, keep distortions
*/
public void calculateGridGeometryAndPhotometric(boolean resetAll){
// this.photometricByView should be initialized
int indexAlpha=3;
int indexMask=3;
double cosA=Math.cos(this.patternTilt/180*Math.PI);
double sinA=Math.sin(this.patternTilt/180*Math.PI);
double halfWidth=0.5*this.patternWidth;
double halfHeight=0.5*this.patternHeight;
double [][] uv={
{( halfWidth*cosA+halfHeight*sinA)/this.patternHalfPeriod,
(-halfWidth*sinA+halfHeight*cosA)/this.patternHalfPeriod},
{( halfWidth*cosA-halfHeight*sinA)/this.patternHalfPeriod,
(-halfWidth*sinA-halfHeight*cosA)/this.patternHalfPeriod}};
double [] maxUV={Math.max(Math.abs(uv[0][0]), Math.abs(uv[1][0])),Math.max(Math.abs(uv[0][1]), Math.abs(uv[1][1]))};
this.U0=(int)Math.ceil(maxUV[0]);
this.V0=(int)Math.ceil(maxUV[1]);
resetAll |= (this.gridGeometry==null);
double x,y;
// in any case
int len=(2*this.U0+1)*(2*this.V0+1);
for (int station=0;station<getNumStations();station++){
for (int i=0;i<getNumViews();i++){
for (int chn=0;chn<this.getNumPhotometricChannels();chn++){
this.photometricByView[station][i][chn]=new double [len]; // r,g,b,alpha
}
}
}
if (resetAll) {
for (int station=0;station<getNumStations();station++){
for (int i=0;i<getNumViews();i++){
for (int chn=0;chn<this.getNumPhotometricChannels();chn++){
this.photometricByView[station][i][chn]=new double [len]; // r,g,b,alpha
for (int j=0;j<len;j++){
this.photometricByView[station][i][chn][j]=0.0;
}
}
}
}
this.gridGeometry=new double[2*this.V0+1][2*this.U0+1][getNumGeometricChannels()]; // without resetAll all properties should be the same
for (int v=-this.V0; v<=this.V0;v++) for (int u=-this.U0; u<=this.U0;u++){
x=(u*cosA-v*sinA)*this.patternHalfPeriod;
y=(u*sinA+v*cosA)*this.patternHalfPeriod;
boolean inGrid=((x>=-halfWidth) && (x<=halfWidth) && (y>=-halfHeight) && (y<=halfHeight));
this.gridGeometry[v+this.V0][u+this.U0][0]=x;
this.gridGeometry[v+this.V0][u+this.U0][1]=y;
this.gridGeometry[v+this.V0][u+this.U0][2]=0.0;
this.gridGeometry[v+this.V0][u+this.U0][3]=inGrid?1.0:0.0; // common for all views - to be combined with per-view?
}
}
// always - copy mask to alpha for each view
int index=0;
for (int v=-this.V0; v<=this.V0;v++) for (int u=-this.U0; u<=this.U0;u++){
for (int station=0;station<getNumStations();station++){
for (int nView=0;nView<getNumViews();nView++) {
this.photometricByView[station][nView][indexAlpha][index]=this.gridGeometry[v+this.V0][u+this.U0][indexMask];
for (int c=0;c<3;c++) {
this.photometricByView[station][nView][c][index]=averageRGB[c];
}
}
}
index++;
}
}
public int [] uvIndicesToUV (int u1, int v1){
if ((v1<0) || (u1<0) ||
(v1 >= this.gridGeometry.length) ||
(u1 >= this.gridGeometry[0].length) ||
(this.gridGeometry[v1][u1][3]==0)) return null;
int [] iUV={u1-this.U0, v1-this.V0};
return iUV;
}
public double[] getXYZM(int u, int v, boolean verbose, int station){ // u=0,v=0 - center!
int u1=u+this.U0;
int v1=v+this.V0;
if ((v1<0) || (u1<0) || (v1 >= this.gridGeometry.length) || (u1 >= this.gridGeometry[0].length) ||
(this.gridGeometry[v1][u1][3]==0)) {
if ((this.debugLevel>1) && verbose && ((v1<0) || (u1<0) || (v1 >= this.gridGeometry.length) || (u1 >= this.gridGeometry[0].length))){
String msg="Requested (acquired) grid (point u="+u+",v="+v+") is outside of the physical grid ["+
(-this.U0)+"..."+(this.gridGeometry[0].length-this.U0-1)+"]x["+
(-this.V0)+"..."+(this.gridGeometry.length-this.V0-1)+"]";
//IJ.showMessage("Error",msg);
System.out.println(msg);
}
return null;
}
if (this.stationZCorr==null) return this.gridGeometry[v1][u1];
double [] result=this.gridGeometry[v1][u1].clone();
// use lower station if grid file does not have current
int useStation=(this.stationZCorr[v1][u1].length>station)?station:(this.stationZCorr[v1][u1].length-1);
result[2]+=this.stationZCorr[v1][u1][useStation];
return result;
// return this.gridGeometry[v1][u1];
}
public int getGridIndex(int u, int v){ // u=0,v=0 - center!
int u1=u+this.U0;
int v1=v+this.V0;
if ((v1<0) || (u1<0) || (v1 >= this.gridGeometry.length) || (u1 >= this.gridGeometry[0].length) ||
(this.gridGeometry[v1][u1][3]==0)) {
return -1;
}
return u1+this.gridGeometry[0].length*v1;
}
public double[] getXYZM(int u, int v, int station){ // u=0,v=0 - center!
int u1=u+this.U0;
int v1=v+this.V0;
if ((this.debugLevel >1) && ((v1<0) || (u1<0) || (v1 >= this.gridGeometry.length) || (u1 >= this.gridGeometry[0].length))) {
String msg="Requested (acquired) grid (point u="+u+",v="+v+") is outside of the physical grid ["+
(-this.U0)+"..."+(this.gridGeometry[0].length-this.U0-1)+"]x["+
(-this.V0)+"..."+(this.gridGeometry.length-this.V0-1)+"]";
IJ.showMessage("Error",msg);
throw new IllegalArgumentException (msg);
}
if (this.stationZCorr==null) return this.gridGeometry[v1][u1];
double [] result=this.gridGeometry[v1][u1].clone();
result[2]+=this.stationZCorr[v1][u1][station];
return result;
}
public double[] getXYZMAverage(int u, int v){ // u=0,v=0 - center!
int u1=u+this.U0;
int v1=v+this.V0;
if ((this.debugLevel >1) && ((v1<0) || (u1<0) || (v1 >= this.gridGeometry.length) || (u1 >= this.gridGeometry[0].length))) {
String msg="Requested (acquired) grid (point u="+u+",v="+v+") is outside of the physical grid ["+
(-this.U0)+"..."+(this.gridGeometry[0].length-this.U0-1)+"]x["+
(-this.V0)+"..."+(this.gridGeometry.length-this.V0-1)+"]";
IJ.showMessage("Error",msg);
throw new IllegalArgumentException (msg);
}
return this.gridGeometry[v1][u1];
}
public double getZCorr(int u, int v, int station){ // u=0,v=0 - center!
if (this.stationZCorr==null) return 0.0;
int u1=u+this.U0;
int v1=v+this.V0;
if ((this.debugLevel >1) && ((v1<0) || (u1<0) || (v1 >= this.gridGeometry.length) || (u1 >= this.gridGeometry[0].length))) {
String msg="Requested (acquired) grid (point u="+u+",v="+v+") is outside of the physical grid ["+
(-this.U0)+"..."+(this.gridGeometry[0].length-this.U0-1)+"]x["+
(-this.V0)+"..."+(this.gridGeometry.length-this.V0-1)+"]";
IJ.showMessage("Error",msg);
throw new IllegalArgumentException (msg);
}
return this.stationZCorr[v1][u1][station];
}
public double[] getXYZMAverage(int vu){ // u=0,v=0 - center!
int width=this.gridGeometry[0].length;
int u1=vu%width;
int v1=vu/width;
if ((this.debugLevel >1) && ((v1<0) || (u1<0) || (v1 >= this.gridGeometry.length) || (u1 >= this.gridGeometry[0].length))) {
String msg="Requested (acquired) grid (point vu="+vu+") is outside of the physical grid ["+
(-this.U0)+"..."+(this.gridGeometry[0].length-this.U0-1)+"]x["+
(-this.V0)+"..."+(this.gridGeometry.length-this.V0-1)+"]";
IJ.showMessage("Error",msg);
throw new IllegalArgumentException (msg);
}
return this.gridGeometry[v1][u1];
}
public double getZCorr(int vu, int station){ // u=0,v=0 - center!
if (this.stationZCorr==null) return 0.0;
int width=this.gridGeometry[0].length;
int u1=vu%width;
int v1=vu/width;
if ((this.debugLevel >1) && ((v1<0) || (u1<0) || (v1 >= this.gridGeometry.length) || (u1 >= this.gridGeometry[0].length))) {
String msg="Requested (acquired) grid (point vu="+vu+") is outside of the physical grid ["+
(-this.U0)+"..."+(this.gridGeometry[0].length-this.U0-1)+"]x["+
(-this.V0)+"..."+(this.gridGeometry.length-this.V0-1)+"]";
IJ.showMessage("Error",msg);
throw new IllegalArgumentException (msg);
}
return this.stationZCorr[v1][u1][station];
}
/**
* Return grid geometry and photometics: X,Y,Z,mask,R,G,B,Alpha
* @param u signed grid U (0 in the center)
* @param v signed grid V (0 in the center)
* @param station station number
* @param channel channel (sensor) number
* @param verbose report out of grid
* @return null if out of grid, otherwise X,Y,Z,mask (binary),R (~0.5..1.2),G,B,alpha (0.0..1.0)
*/
public double[] getXYZMP(
int u,
int v,
int station,
int channel,
boolean verbose){ // u=0,v=0 - center!
int u1=u+this.U0;
int v1=v+this.V0;
if ((v1<0) || (u1<0) || (v1 >= this.gridGeometry.length) || (u1 >= this.gridGeometry[0].length) ||
(this.gridGeometry[v1][u1][3]==0)) {
if ((this.debugLevel>1) && verbose && ((v1<0) || (u1<0) || (v1 >= this.gridGeometry.length) || (u1 >= this.gridGeometry[0].length))){
String msg="Requested (acquired) grid (point u="+u+",v="+v+") is outside of the physical grid ["+
(-this.U0)+"..."+(this.gridGeometry[0].length-this.U0-1)+"]x["+
(-this.V0)+"..."+(this.gridGeometry.length-this.V0-1)+"]";
//IJ.showMessage("Error",msg);
System.out.println(msg);
}
return null;
}
int index=u1+v1*this.gridGeometry[0].length;
if (getNumStations()<=station) updateNumStations(station+1);
int nView=this.viewMap[channel];
if (nView>=this.photometricByView[station].length){ // OOB 1// NUll pointer - need to run F-field first?
nView=this.photometricByView.length-1;
}
double [] result= { // null
this.gridGeometry[v1][u1][0],
this.gridGeometry[v1][u1][1],
this.gridGeometry[v1][u1][2]+((this.stationZCorr!=null)?this.stationZCorr[v1][u1][station]:0.0), // per-station correction
this.gridGeometry[v1][u1][3],
this.photometricByView[station][nView][0][index],
this.photometricByView[station][nView][1][index],
this.photometricByView[station][nView][2][index],
this.photometricByView[station][nView][3][index]
};
return result;
}
public double[] getXYZMPE(
int u,
int v,
int station,
int channel,
boolean verbose){ // u=0,v=0 - center!
int u1=u+this.U0;
int v1=v+this.V0;
if ((v1<0) || (u1<0) || (v1 >= this.gridGeometry.length) || (u1 >= this.gridGeometry[0].length) ||
(this.gridGeometry[v1][u1][3]==0)) {
if ((this.debugLevel>1) && verbose && ((v1<0) || (u1<0) || (v1 >= this.gridGeometry.length) || (u1 >= this.gridGeometry[0].length))){
String msg="Requested (acquired) grid (point u="+u+",v="+v+") is outside of the physical grid ["+
(-this.U0)+"..."+(this.gridGeometry[0].length-this.U0-1)+"]x["+
(-this.V0)+"..."+(this.gridGeometry.length-this.V0-1)+"]";
//IJ.showMessage("Error",msg);
System.out.println(msg);
}
return null;
}
int index=u1+v1*this.gridGeometry[0].length;
if (getNumStations()<=station) updateNumStations(station+1);
int nView=this.viewMap[channel];
int useStation=(this.stationZCorr!=null)?((this.stationZCorr[v1][u1].length>station)?station:(this.stationZCorr[v1][u1].length-1)):0;
if (nView>=this.photometricByView[station].length){ // OOB 1// NUll pointer - need to run F-field first? (oob1 when grid had less than now
nView=this.photometricByView.length-1;
}
double [] result= { // null
this.gridGeometry[v1][u1][0],
this.gridGeometry[v1][u1][1],
// this.gridGeometry[v1][u1][2]+((this.stationZCorr!=null)?this.stationZCorr[v1][u1][station]:0.0), // per-station correction
this.gridGeometry[v1][u1][2]+((this.stationZCorr!=null)?this.stationZCorr[v1][u1][useStation]:0.0), // per-station correction
this.gridGeometry[v1][u1][3],
this.photometricByView[station][nView][0][index],
this.photometricByView[station][nView][1][index],
this.photometricByView[station][nView][2][index],
this.photometricByView[station][nView][3][index],
(this.patternErrorMask==null)?1.0:this.patternErrorMask[index]
};
return result;
}
public double [][][] getGeometry(){return this.gridGeometry;}
}
...@@ -818,7 +818,7 @@ public class SFEPhases { ...@@ -818,7 +818,7 @@ public class SFEPhases {
// Ask for image selection (multiple directories), accumulate and create array of accumulated images // Ask for image selection (multiple directories), accumulate and create array of accumulated images
public ImagePlus[] getInteractiveAccumulatedImages( public ImagePlus[] getInteractiveAccumulatedImages(
Distortions.DistortionProcessConfiguration distortionProcessConfiguration, DistortionProcessConfiguration distortionProcessConfiguration,
final AtomicInteger stopRequested, final AtomicInteger stopRequested,
int threadsMax, int threadsMax,
boolean updateStatus, boolean updateStatus,
...@@ -1199,7 +1199,7 @@ public class SFEPhases { ...@@ -1199,7 +1199,7 @@ public class SFEPhases {
} }
public SensorDefects[] accummulateSensorDefects( public SensorDefects[] accummulateSensorDefects(
Distortions.DistortionProcessConfiguration distortionProcessConfiguration, DistortionProcessConfiguration distortionProcessConfiguration,
int tileClearSize, int tileClearSize,
int tileMargins, int tileMargins,
int cmask, // bitmask of color channels to process (9 - two greens) int cmask, // bitmask of color channels to process (9 - two greens)
......
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