Commit 5e90425c authored by Andrey Filippov's avatar Andrey Filippov

Grid matching for secondary (LWIR) sensors

parent 726f3d95
...@@ -501,7 +501,7 @@ public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSi ...@@ -501,7 +501,7 @@ public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSi
4, // int decimateMasks 4, // int decimateMasks
0.1, // double badNodeThreshold=0.1; // filter out grid nodes with difference from quadratically predicted from 8 neighbors in pixels 0.1, // double badNodeThreshold=0.1; // filter out grid nodes with difference from quadratically predicted from 8 neighbors in pixels
1, // int maxBadNeighb; // maximal number of bad nodes around the corrected one to fix 1, // int maxBadNeighb; // maximal number of bad nodes around the corrected one to fix
50, // int minimalValidNodes 10, // int minimalValidNodes
1, // int weightMultiImageMode=1; // increase weight for multi-image sets (0 - do not increase, 1 - multiply by number of images in a set) 1, // int weightMultiImageMode=1; // increase weight for multi-image sets (0 - do not increase, 1 - multiply by number of images in a set)
1.0, // public double weightMultiExponent= 1.0; // if( >0) use grid diameter to scale weights of this image 1.0, // public double weightMultiExponent= 1.0; // if( >0) use grid diameter to scale weights of this image
1.0, // public double weightDiameterExponent=1.0; 1.0, // public double weightDiameterExponent=1.0;
...@@ -511,7 +511,8 @@ public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSi ...@@ -511,7 +511,8 @@ public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSi
0.5, // public double shrinkBlurLevel = 0.5; 0.5, // public double shrinkBlurLevel = 0.5;
-1.0, // double balanceChannelWeightsMode -1.0, // double balanceChannelWeightsMode
2.0, // public double removeOverRMS=2.0; // error is multiplied by weight function before comparison (more permissive on the borders 2.0, // public double removeOverRMS=2.0; // error is multiplied by weight function before comparison (more permissive on the borders
4.0 //public double removeOverRMSNonweighted=4.0; // error is not multiplied (no more permissions on tyhe borders 4.0, //public double removeOverRMSNonweighted=4.0; // error is not multiplied (no more permissions on tyhe borders
true // boolean invertUnmarkedLwirGrid
); );
// //
...@@ -1020,6 +1021,7 @@ if (MORE_BUTTONS) { ...@@ -1020,6 +1021,7 @@ if (MORE_BUTTONS) {
addButton("Import Subsystem", panelLWIR,color_configure); addButton("Import Subsystem", panelLWIR,color_configure);
addButton("Select LWIR grids", panelLWIR,color_configure); addButton("Select LWIR grids", panelLWIR,color_configure);
addButton("Grid offset", panelLWIR,color_process); addButton("Grid offset", panelLWIR,color_process);
addButton("LWIR to EO", panelLWIR,color_process);
addButton("Manual hint", panelLWIR,color_configure); addButton("Manual hint", panelLWIR,color_configure);
add(panelLWIR); add(panelLWIR);
...@@ -2080,6 +2082,8 @@ if (MORE_BUTTONS) { ...@@ -2080,6 +2082,8 @@ if (MORE_BUTTONS) {
double[][] gridDisplay=LENS_DISTORTIONS.prepareDisplayGrid(); double[][] gridDisplay=LENS_DISTORTIONS.prepareDisplayGrid();
SDFA_INSTANCE.showArrays(gridDisplay,LENS_DISTORTIONS.getGridWidth(),LENS_DISTORTIONS.getGridHeight(), true, "Grid", SDFA_INSTANCE.showArrays(gridDisplay,LENS_DISTORTIONS.getGridWidth(),LENS_DISTORTIONS.getGridHeight(), true, "Grid",
LENS_DISTORTIONS.displayGridTitles()); LENS_DISTORTIONS.displayGridTitles());
// Does not update pixelSize and DistortionRadius !!
LENS_DISTORTIONS.calcGridOnSensor(0.0); LENS_DISTORTIONS.calcGridOnSensor(0.0);
double[][] gridDisplayOnSensor=LENS_DISTORTIONS.prepareDisplayGridOnSensor(false); double[][] gridDisplayOnSensor=LENS_DISTORTIONS.prepareDisplayGridOnSensor(false);
SDFA_INSTANCE.showArrays(gridDisplayOnSensor,LENS_DISTORTIONS.getGridWidth(),LENS_DISTORTIONS.getGridHeight(), true, "GridOnSensor", SDFA_INSTANCE.showArrays(gridDisplayOnSensor,LENS_DISTORTIONS.getGridWidth(),LENS_DISTORTIONS.getGridHeight(), true, "GridOnSensor",
...@@ -2297,7 +2301,9 @@ if (MORE_BUTTONS) { ...@@ -2297,7 +2301,9 @@ if (MORE_BUTTONS) {
if (LENS_DISTORTIONS.fittingStrategy==null) return; if (LENS_DISTORTIONS.fittingStrategy==null) return;
LENS_DISTORTIONS.fittingStrategy.debugLevel=DEBUG_LEVEL; LENS_DISTORTIONS.fittingStrategy.debugLevel=DEBUG_LEVEL;
LENS_DISTORTIONS.LevenbergMarquardt(true); // open dialog LENS_DISTORTIONS.LevenbergMarquardt(true, // open dialog
false); // dry_run
return; return;
} }
/* ======================================================================== */ /* ======================================================================== */
...@@ -3610,7 +3616,9 @@ if (MORE_BUTTONS) { ...@@ -3610,7 +3616,9 @@ if (MORE_BUTTONS) {
LENS_DISTORTIONS.thresholdFinish=FOCUS_MEASUREMENT_PARAMETERS.thresholdFinish; LENS_DISTORTIONS.thresholdFinish=FOCUS_MEASUREMENT_PARAMETERS.thresholdFinish;
LENS_DISTORTIONS.numIterations=FOCUS_MEASUREMENT_PARAMETERS.numIterations; LENS_DISTORTIONS.numIterations=FOCUS_MEASUREMENT_PARAMETERS.numIterations;
LENS_DISTORTIONS.LevenbergMarquardt(false); // skip dialog LENS_DISTORTIONS.LevenbergMarquardt(
false, // skip dialog
false); // new: dry_run use it here?
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
...@@ -3635,7 +3643,9 @@ if (MORE_BUTTONS) { ...@@ -3635,7 +3643,9 @@ if (MORE_BUTTONS) {
LENS_DISTORTIONS.thresholdFinish=FOCUS_MEASUREMENT_PARAMETERS.thresholdFinish; LENS_DISTORTIONS.thresholdFinish=FOCUS_MEASUREMENT_PARAMETERS.thresholdFinish;
LENS_DISTORTIONS.numIterations=FOCUS_MEASUREMENT_PARAMETERS.numIterations; LENS_DISTORTIONS.numIterations=FOCUS_MEASUREMENT_PARAMETERS.numIterations;
LENS_DISTORTIONS.LevenbergMarquardt(false); // skip dialog LENS_DISTORTIONS.LevenbergMarquardt(
false, // skip dialog
false); // new: dry_run use it here?
if (DEBUG_LEVEL>0) System.out.println("Finished second LMA at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3)); if (DEBUG_LEVEL>0) System.out.println("Finished second LMA at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
if (!FOCUS_MEASUREMENT_PARAMETERS.keepCircularMask) { if (!FOCUS_MEASUREMENT_PARAMETERS.keepCircularMask) {
DISTORTION_CALIBRATION_DATA.calculateSensorMasks(); // TODO: save/restore original mask for channel 0 DISTORTION_CALIBRATION_DATA.calculateSensorMasks(); // TODO: save/restore original mask for channel 0
...@@ -5922,7 +5932,7 @@ if (MORE_BUTTONS) { ...@@ -5922,7 +5932,7 @@ if (MORE_BUTTONS) {
return; return;
} }
GenericDialog gd=new GenericDialog ("Select list mode"); GenericDialog gd=new GenericDialog ("Select list mode");
gd.addNumericField("Mode 0 - pointers, 1 - shift/Rots, 2 - points/extra, 3 - rms", 0, 0); gd.addNumericField("Mode 0 - pointers, 1 - shift/Rots, 2 - points/extra, 3 - rms", 3, 0);
gd.showDialog(); gd.showDialog();
if (gd.wasCanceled()) return; if (gd.wasCanceled()) return;
int listMode= (int) gd.getNextNumber(); int listMode= (int) gd.getNextNumber();
...@@ -6100,7 +6110,9 @@ if (MORE_BUTTONS) { ...@@ -6100,7 +6110,9 @@ if (MORE_BUTTONS) {
LENS_DISTORTIONS.stopEachSeries= false; // will not ask for confirmation after done LENS_DISTORTIONS.stopEachSeries= false; // will not ask for confirmation after done
LENS_DISTORTIONS.stopOnFailure=false; LENS_DISTORTIONS.stopOnFailure=false;
LENS_DISTORTIONS.lambda=LENS_DISTORTIONS.fittingStrategy.lambdas[0]; // 0.001; // why it does not use fitting series lambda? LENS_DISTORTIONS.lambda=LENS_DISTORTIONS.fittingStrategy.lambdas[0]; // 0.001; // why it does not use fitting series lambda?
boolean LMA_OK=LENS_DISTORTIONS.LevenbergMarquardt(false); // skip dialog boolean LMA_OK=LENS_DISTORTIONS.LevenbergMarquardt(
false, // skip dialog
false); // new: dry_run use it here?
if (LMA_OK) { if (LMA_OK) {
finalTilt[tiltIndex][axialIndex]=LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.gIS[imageSetNumber].goniometerTilt; finalTilt[tiltIndex][axialIndex]=LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.gIS[imageSetNumber].goniometerTilt;
finalAxial[tiltIndex][axialIndex]=LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.gIS[imageSetNumber].goniometerAxial; finalAxial[tiltIndex][axialIndex]=LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.gIS[imageSetNumber].goniometerAxial;
...@@ -6177,7 +6189,9 @@ if (MORE_BUTTONS) { ...@@ -6177,7 +6189,9 @@ if (MORE_BUTTONS) {
LENS_DISTORTIONS.stopEachStep= false; LENS_DISTORTIONS.stopEachStep= false;
LENS_DISTORTIONS.stopEachSeries= false; // will not ask for confirmation after done LENS_DISTORTIONS.stopEachSeries= false; // will not ask for confirmation after done
LENS_DISTORTIONS.lambda=LENS_DISTORTIONS.fittingStrategy.lambdas[0]; LENS_DISTORTIONS.lambda=LENS_DISTORTIONS.fittingStrategy.lambdas[0];
LENS_DISTORTIONS.LevenbergMarquardt(false); // skip dialog LENS_DISTORTIONS.LevenbergMarquardt(
false, // skip dialog
false); // new: dry_run use it here?
// save safe settings to run LMA manually // save safe settings to run LMA manually
LENS_DISTORTIONS.seriesNumber= 0; // start from 0; LENS_DISTORTIONS.seriesNumber= 0; // start from 0;
...@@ -9435,16 +9449,17 @@ if (MORE_BUTTONS) { ...@@ -9435,16 +9449,17 @@ if (MORE_BUTTONS) {
calculateLwirGrids(); calculateLwirGrids();
return; return;
} }
/* ======================================================================== */
if (label.equals("Import Subsystem")) { if (label.equals("Import Subsystem")) {
importSystem(null, "EYESIS_CAMERA_PARAMETERS."); importSystem(null, "EYESIS_CAMERA_PARAMETERS.");
return; return;
} }
/* ======================================================================== */
if (label.equals("Select LWIR grids")) { if (label.equals("Select LWIR grids")) {
selectLwirGrids(LWIR_PARAMETERS); selectLwirGrids(LWIR_PARAMETERS);
return; return;
} }
/* ======================================================================== */
if (label.equals("Manual hint")) { if (label.equals("Manual hint")) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL; DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
if (LENS_DISTORTIONS==null) { if (LENS_DISTORTIONS==null) {
...@@ -9466,12 +9481,19 @@ if (MORE_BUTTONS) { ...@@ -9466,12 +9481,19 @@ if (MORE_BUTTONS) {
LENS_DISTORTIONS.manualGridHint(numGridImage); LENS_DISTORTIONS.manualGridHint(numGridImage);
return; return;
} }
/* ======================================================================== */
if (label.equals("Grid offset")) { if (label.equals("Grid offset")) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL; DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
offsetGrids(0, 0, null); offsetGrids(0, 0, null);
return; return;
} }
/* ======================================================================== */
if (label.equals("LWIR to EO")) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
lwirToEo();
return;
}
/* ======================================================================== */ /* ======================================================================== */
IJ.showMessage("Not yet implemented"); IJ.showMessage("Not yet implemented");
...@@ -9480,6 +9502,108 @@ if (MORE_BUTTONS) { ...@@ -9480,6 +9502,108 @@ if (MORE_BUTTONS) {
} }
/* ===== Other methods ==================================================== */ /* ===== Other methods ==================================================== */
public boolean lwirToEo() {
if (LENS_DISTORTIONS == null) {
System.out.println("LENS_DISTORTIONS is null");
return false;
}
if (PATTERN_PARAMETERS == null) {
System.out.println("PATTERN_PARAMETERS is null");
return false;
}
DistortionCalibrationData dcd = LENS_DISTORTIONS.getDistortionCalibrationData();
if (dcd == null) {
dcd = DISTORTION_CALIBRATION_DATA;
}
if (dcd == null) {
System.out.println("dcd is null");
return false;
}
int min_set = 0;
int max_set = dcd.getNumSets()-1;
boolean adjust_eo = false;
boolean adjust_lwir = true;
boolean use_lma = true;
GenericDialog gd = new GenericDialog("Initial alignment of the secondary camera to the reference one");
gd.addMessage("This command used Fitting Strategy[0] that should be set with all parameters but\n"+
"GXYZ0 and GXYZ1 are set to 'fixed', and GXYZ0 and GXYZ1 are set to 'individual'.\n"+
"Each selected set should already have GXYZ set correctly (e.g. by reference cameras)");
gd.addNumericField("Image set start", min_set, 0);
gd.addNumericField("Image set last", max_set, 0);
gd.addCheckbox("Adjust EO (reference) sensors", adjust_eo);
gd.addCheckbox("Adjust LWIR (target) sensors", adjust_lwir);
gd.addCheckbox("Use LMA (unchecked - initial approximate grid setum by correlation)", use_lma);
gd.showDialog();
if (gd.wasCanceled()) return false;
min_set = (int) gd.getNextNumber();
max_set = (int) gd.getNextNumber();
adjust_eo = gd.getNextBoolean();
adjust_lwir = gd.getNextBoolean();
use_lma = gd.getNextBoolean();
if (!dcd.hasSmallSensors()) {
String msg="This system does not have any LWIR or other dependent sub-cameras";
IJ.showMessage("Error",msg);
return false;
}
if (use_lma) {
for (int num_set = min_set; num_set <=max_set; num_set++) if
((dcd.gIS[num_set] != null) && (dcd.gIS[num_set].imageSet != null)) {
for (int nc = 0; nc < dcd.getNumChannels(); nc++) {
if (dcd.gIS[num_set].imageSet[nc]!= null) {
int num_img = dcd.gIS[num_set].imageSet[nc].imgNumber;
if (dcd.isSmallSensor(num_img)) {
if (!adjust_lwir) {
continue;
}
} else {
if (!adjust_eo) {
continue;
}
}
int [] uvr = LENS_DISTORTIONS. findImageGridOffset(
num_img,
true, // boolean even, For first time - use parameter and parity of uv_rot
PATTERN_PARAMETERS);
if ((uvr != null) && ((uvr[0] != 0) || (uvr[1] != 0))) {
int [] uv_shift_rot = {uvr[0],uvr[1],0};
// int [] new_uv_shift_rots =
dcd.offsetGrid(
num_img, // int img_num,
uv_shift_rot,
PATTERN_PARAMETERS);
if (DEBUG_LEVEL > 0) {
System.out.println(num_img+ "("+num_set+"."+nc+"): uv_shift = "+uvr[0]+":"+uvr[1]);
}
}
}
}
}
} else {
for (int num_set = min_set; num_set <=max_set; num_set++) {
int extra_search =2;
double sigma = 5;
dcd.initialSetLwirFromEO( //
num_set,
EYESIS_CAMERA_PARAMETERS.invertUnmarkedLwirGrid, // boolean invert_unmarked_grid,
extra_search, // 2
sigma, //5.0
PATTERN_PARAMETERS,
true); // debug
}
}
return true;
}
public boolean offsetGrids(int ichoice, int inum, int [] uv_shift_rot) { public boolean offsetGrids(int ichoice, int inum, int [] uv_shift_rot) {
if (LENS_DISTORTIONS == null) { if (LENS_DISTORTIONS == null) {
System.out.println("LENS_DISTORTIONS is null"); System.out.println("LENS_DISTORTIONS is null");
...@@ -9517,7 +9641,7 @@ if (MORE_BUTTONS) { ...@@ -9517,7 +9641,7 @@ if (MORE_BUTTONS) {
gd.addNumericField("Image/set number", inum, 0); gd.addNumericField("Image/set number", inum, 0);
gd.addCheckbox ("Auto calculate UV", auto); gd.addCheckbox ("Auto calculate UV", auto);
if (has_lwir) { if (has_lwir) {
gd.addCheckbox ("Auto from EO grid", true); gd.addCheckbox ("Auto from EO grid (calculatre from EO even if the requested image is LWIR)", false); //true
} }
gd.addNumericField("Grid offset U", uv_shift_rot[0], 0); gd.addNumericField("Grid offset U", uv_shift_rot[0], 0);
gd.addNumericField("Grid offset V", uv_shift_rot[1], 0); gd.addNumericField("Grid offset V", uv_shift_rot[1], 0);
...@@ -9580,11 +9704,17 @@ if (MORE_BUTTONS) { ...@@ -9580,11 +9704,17 @@ if (MORE_BUTTONS) {
// find first enabled image // find first enabled image
for (int n:img_nums) { for (int n:img_nums) {
if (n >= 0) { if (n >= 0) {
int [] auto_uvr = dcd. suggestOffset (
n, // int num_img, int [] auto_uvr = LENS_DISTORTIONS.findImageGridOffset( // null for now
true, // boolean non_estimated, n,
true, // boolean even, true, // boolean even,
PATTERN_PARAMETERS); // PatternParameters patternParameters) PATTERN_PARAMETERS); // PatternParameters patternParameters)
// int [] auto_uvr = dcd. suggestOffset (
// n, // int num_img,
// true, // boolean non_estimated,
// true, // boolean even,
// PATTERN_PARAMETERS); // PatternParameters patternParameters)
return offsetGrids(ichoice, inum, auto_uvr); return offsetGrids(ichoice, inum, auto_uvr);
} }
} }
...@@ -9616,14 +9746,14 @@ if (MORE_BUTTONS) { ...@@ -9616,14 +9746,14 @@ 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);
int min_files = 8; // use folders that have all 8 files int min_files = 8; // use folders that have all 8 files
int lwir_chn0 = lwirReaderParameters.getLwirChn0(); int lwir_chn0 = lwirReaderParameters.getLwirChn0();
int vnir_chn0 = lwirReaderParameters.getVnirChn0(); int eo_chn0 = lwirReaderParameters.getEoChn0();
int numStations = 3; int numStations = 3;
GenericDialog gd = new GenericDialog("Setup Goniometer/Camera Stations"); GenericDialog gd = new GenericDialog("Setup Goniometer/Camera Stations");
gd.addMessage("Setting up calibration that includes multiple camera tripod or goniometer positions."); gd.addMessage("Setting up calibration that includes multiple camera tripod or goniometer positions.");
gd.addMessage("File selection dialog will open for each station separateley."); gd.addMessage("File selection dialog will open for each station separateley.");
gd.addNumericField("Number of goniometer/camera stations", numStations,0); gd.addNumericField("Number of goniometer/camera stations", numStations,0);
gd.addMessage("lwir_chn0 = "+lwir_chn0); gd.addMessage("lwir_chn0 = "+lwir_chn0);
gd.addMessage("vnir_chn0 = "+vnir_chn0); gd.addMessage("eo_chn0 = "+eo_chn0);
gd.addMessage("min_files = "+min_files); gd.addMessage("min_files = "+min_files);
gd.showDialog(); gd.showDialog();
...@@ -9757,7 +9887,6 @@ if (MORE_BUTTONS) { ...@@ -9757,7 +9887,6 @@ if (MORE_BUTTONS) {
matchSimulatedPattern.debugLevel=MASTER_DEBUG_LEVEL; matchSimulatedPattern.debugLevel=MASTER_DEBUG_LEVEL;
String [] sourceSetList = DISTORTION_PROCESS_CONFIGURATION.selectSourceSets(); String [] sourceSetList = DISTORTION_PROCESS_CONFIGURATION.selectSourceSets();
LWIR_PARAMETERS.selectSourceChannels(); LWIR_PARAMETERS.selectSourceChannels();
// boolean [] sel_chn = LWIR_PARAMETERS.getSelectedVnir(); // start with regular cameras only
boolean [] sel_chn = LWIR_PARAMETERS.getSelected(); boolean [] sel_chn = LWIR_PARAMETERS.getSelected();
int numFiles = LWIR_PARAMETERS.getSourceFilesFlat(sourceSetList, sel_chn).length; // just the number int numFiles = LWIR_PARAMETERS.getSourceFilesFlat(sourceSetList, sel_chn).length; // just the number
String [][] sourceFilesList=LWIR_PARAMETERS.getSourceFiles(sourceSetList, sel_chn); String [][] sourceFilesList=LWIR_PARAMETERS.getSourceFiles(sourceSetList, sel_chn);
...@@ -91,6 +91,27 @@ import ij.text.TextWindow; ...@@ -91,6 +91,27 @@ import ij.text.TextWindow;
return (eyesisCameraParameters==null)?0:eyesisCameraParameters.getNumStations(); return (eyesisCameraParameters==null)?0:eyesisCameraParameters.getNumStations();
} }
public double getPixelSize(int station, int channel) {
return this.eyesisCameraParameters.eyesisSubCameras[station][channel].getPixelSize();
}
public double getDistortionRadius(int station, int channel) {
return this.eyesisCameraParameters.eyesisSubCameras[station][channel].getDistortionRadius();
}
public double getPixelSize(int imgNumber) {
return getPixelSize(this.gIP[imgNumber].stationNumber, this.gIP[imgNumber].channel);
}
public double getDistortionRadius(int imgNumber) {
return getDistortionRadius(this.gIP[imgNumber].stationNumber, this.gIP[imgNumber].channel);
}
public boolean isTripod() {
return (eyesisCameraParameters !=null) && this.eyesisCameraParameters.isTripod();
}
public boolean isCartesian() {
return (eyesisCameraParameters !=null) && this.eyesisCameraParameters.isCartesian();
}
public class GridImageParameters{ public class GridImageParameters{
public int imgNumber=-1; // index of this image (for pars[][]) public int imgNumber=-1; // index of this image (for pars[][])
private int setNumber=-1; // long overdue - will be some inconsistency private int setNumber=-1; // long overdue - will be some inconsistency
...@@ -127,8 +148,9 @@ import ij.text.TextWindow; ...@@ -127,8 +148,9 @@ import ij.text.TextWindow;
final int contrastIndex=2; final int contrastIndex=2;
public double getGridPeriod() { return gridPeriod;} public double getGridPeriod() { return gridPeriod;}
public void setGfridPeriod(double v) {gridPeriod = v;} public void setGridPeriod(double v) {gridPeriod = v;}
public int getSetNumber(){return this.setNumber;} public int getSetNumber(){return this.setNumber;}
public GridImageParameters(int index){ public GridImageParameters(int index){
this.imgNumber=index; this.imgNumber=index;
...@@ -145,7 +167,7 @@ import ij.text.TextWindow; ...@@ -145,7 +167,7 @@ import ij.text.TextWindow;
public void setStationNumber(int stationNumber){ // TODO: make only a single station number - in GridImageSet? public void setStationNumber(int stationNumber){ // TODO: make only a single station number - in GridImageSet?
this.stationNumber=stationNumber; this.stationNumber=stationNumber;
} }
public double []getGridWeight(){ public double [] getGridWeight(){
return this.pixelsMask; return this.pixelsMask;
} }
public void resetMask(){ public void resetMask(){
...@@ -553,6 +575,11 @@ import ij.text.TextWindow; ...@@ -553,6 +575,11 @@ import ij.text.TextWindow;
"10","11","12","13","14","15","16","17","18","19", "10","11","12","13","14","15","16","17","18","19",
"20","21","22","23","24","25","26","27","28","29"}; "20","21","22","23","24","25","26","27","28","29"};
public int getNumSets() {
return gIS.length;
}
public void setupIndices(){ // should be always called during initialization ! public void setupIndices(){ // should be always called during initialization !
this.index_right = getParameterIndexByName("subcamRight"); // 0 may be -1 if !cartesian this.index_right = getParameterIndexByName("subcamRight"); // 0 may be -1 if !cartesian
this.index_forward = getParameterIndexByName("subcamForward"); // 1 may be -1 if !cartesian this.index_forward = getParameterIndexByName("subcamForward"); // 1 may be -1 if !cartesian
...@@ -563,13 +590,10 @@ import ij.text.TextWindow; ...@@ -563,13 +590,10 @@ import ij.text.TextWindow;
this.index_ga= getParameterIndexByName("goniometerAxial"); // 7 this.index_ga= getParameterIndexByName("goniometerAxial"); // 7
} }
public boolean isCartesian(){
return (eyesisCameraParameters !=null) && eyesisCameraParameters.cartesian;
}
public String descrField(int i,int j){ public String descrField(int i,int j){
if ( if (
(eyesisCameraParameters !=null) && (eyesisCameraParameters !=null) &&
eyesisCameraParameters.cartesian && eyesisCameraParameters.isCartesian() &&
(i < this.parameterDescriptionsCartesian.length) && (i < this.parameterDescriptionsCartesian.length) &&
(this.parameterDescriptionsCartesian[i]!=null) && (this.parameterDescriptionsCartesian[i]!=null) &&
(j<this.parameterDescriptionsCartesian[i].length)){ (j<this.parameterDescriptionsCartesian[i].length)){
...@@ -795,9 +819,9 @@ import ij.text.TextWindow; ...@@ -795,9 +819,9 @@ import ij.text.TextWindow;
String set_name = (new File(dir)).getName(); String set_name = (new File(dir)).getName();
File set_dir = new File(sdir, set_name ); File set_dir = new File(sdir, set_name );
String [] sfiles = set_dir.list(sourceFilter); String [] sfiles = set_dir.list(sourceFilter);
if (sfiles == null) { if (sfiles == null) {
System.out.println("sfiles == null"); System.out.println("sfiles == null");
} }
for (String spath:sfiles) { for (String spath:sfiles) {
int last_dash = spath.lastIndexOf('-'); int last_dash = spath.lastIndexOf('-');
int last = spath.lastIndexOf('_'); int last = spath.lastIndexOf('_');
...@@ -812,6 +836,8 @@ if (sfiles == null) { ...@@ -812,6 +836,8 @@ if (sfiles == null) {
} }
} }
} }
boolean ignore_LWIR_pointers = true; // skip LWIR absolute marks, use them later
int max_lwir_width = 1023; // use LWIR class
setupIndices(); setupIndices();
this.eyesisCameraParameters=eyesisCameraParameters; this.eyesisCameraParameters=eyesisCameraParameters;
int numSubCameras=(eyesisCameraParameters==null)?1:eyesisCameraParameters.eyesisSubCameras[0].length; int numSubCameras=(eyesisCameraParameters==null)?1:eyesisCameraParameters.eyesisSubCameras[0].length;
...@@ -906,7 +932,10 @@ if (sfiles == null) { ...@@ -906,7 +932,10 @@ if (sfiles == null) {
this.gIS[nis].motors= this.gIP[numFile].motors.clone(); this.gIS[nis].motors= this.gIP[numFile].motors.clone();
this.gIP[numFile].matchedPointers = getUsedPonters(imp_grid); this.gIP[numFile].matchedPointers = getUsedPonters(imp_grid);
if (this.gIP[numFile].matchedPointers > 0) { if (this.gIP[numFile].matchedPointers > 0) {
with_pointers = numFile; // Not using LWIR pointers here!
if (!ignore_LWIR_pointers || (getImagePlusProperty(imp_grid,"WOI_TOP",0) > max_lwir_width)) {
with_pointers = numFile;
}
} }
double [] saturations=new double [4]; double [] saturations=new double [4];
for (int i=0;i<saturations.length;i++) { for (int i=0;i<saturations.length;i++) {
...@@ -981,8 +1010,8 @@ if (sfiles == null) { ...@@ -981,8 +1010,8 @@ if (sfiles == null) {
} }
} }
if (with_pointers < 0) { // no matching pointers, will try to match selected channel with the pattern if (with_pointers < 0) { // no matching pointers, will try to match selected channel with the pattern
int main_channel = 4; // one of the VNIR channels to match with the pattern int main_channel = 4; // one of the EO channels to match with the pattern
// boolean [] sensor_mask = null; // later may be used to limit scope to VNIR-only // boolean [] sensor_mask = null; // later may be used to limit scope to EO-only
int extra_search = 2; int extra_search = 2;
// int base_channel = this.gIP[with_pointers].channel; // int base_channel = this.gIP[with_pointers].channel;
if (this.gIS[nis].imageSet[main_channel] != null) { if (this.gIS[nis].imageSet[main_channel] != null) {
...@@ -1030,7 +1059,7 @@ if (sfiles == null) { ...@@ -1030,7 +1059,7 @@ if (sfiles == null) {
} }
if (with_pointers >= 0) { // set initial grids offset from the grid files in the same image set that do not have absolute calibration if (with_pointers >= 0) { // set initial grids offset from the grid files in the same image set that do not have absolute calibration
boolean [] sensor_mask = null; // later may be used to limit scope to VNIR-only boolean [] sensor_mask = null; // later may be used to limit scope to EO-only
int extra_search = 1; int extra_search = 1;
int base_channel = this.gIP[with_pointers].channel; int base_channel = this.gIP[with_pointers].channel;
for (int nc = 0; nc < this.gIS[nis].imageSet.length; nc++) if ((sensor_mask == null) || sensor_mask[nc]) { for (int nc = 0; nc < this.gIS[nis].imageSet.length; nc++) if ((sensor_mask == null) || sensor_mask[nc]) {
...@@ -1041,14 +1070,6 @@ if (sfiles == null) { ...@@ -1041,14 +1070,6 @@ if (sfiles == null) {
if (this.debugLevel>-1) System.out.print(imgNum+"*("+this.gIP[imgNum].getStationNumber()+ if (this.debugLevel>-1) System.out.print(imgNum+"*("+this.gIP[imgNum].getStationNumber()+
":"+this.gIP[imgNum].setNumber+":"+this.gIP[imgNum].channel+"): "+this.gIP[imgNum].path); ":"+this.gIP[imgNum].setNumber+":"+this.gIP[imgNum].channel+"): "+this.gIP[imgNum].path);
int [] uv_shift_rot0 = correlateGrids(
set_widths[base_channel], // int base_width,
set_pixels[base_channel], // float [][] base_pixels,
set_widths[nc], // int test_width,
set_pixels[nc], // float [][] test_pixels,
invert_color,
extra_search);
double [] sensor_wh = { double [] sensor_wh = {
this.gIP[imgNum].woi.width + this.gIP[imgNum].woi.x, this.gIP[imgNum].woi.width + this.gIP[imgNum].woi.x,
this.gIP[imgNum].woi.height + this.gIP[imgNum].woi.y}; this.gIP[imgNum].woi.height + this.gIP[imgNum].woi.y};
...@@ -1063,8 +1084,7 @@ if (sfiles == null) { ...@@ -1063,8 +1084,7 @@ if (sfiles == null) {
5.0, // 2.0, // sigma 5.0, // 2.0, // sigma
sensor_wh, sensor_wh,
false); // true); false); // true);
System.out.print(" {"+uv_shift_rot[0]+":"+uv_shift_rot[1]+"->");
System.out.print(" {"+uv_shift_rot0[0]+":"+uv_shift_rot0[1]+"->"+uv_shift_rot[0]+":"+uv_shift_rot[1]+"->");
int [] combinedUVShiftRot=MatchSimulatedPattern.combineUVShiftRot( int [] combinedUVShiftRot=MatchSimulatedPattern.combineUVShiftRot(
this.gIS[nis].imageSet[base_channel].getUVShiftRot(), this.gIS[nis].imageSet[base_channel].getUVShiftRot(),
uv_shift_rot); uv_shift_rot);
...@@ -1126,6 +1146,155 @@ if (sfiles == null) { ...@@ -1126,6 +1146,155 @@ if (sfiles == null) {
} }
public boolean initialSetLwirFromEO( //
int num_set,
boolean invert_unmarked_grid,
int extra_search, // 2
double sigma, //5.0
PatternParameters patternParameters,
boolean bdebug
) {
// see if there is any LWIR in the system is sensor and throw if there is none
if (!hasSmallSensors()) {
String msg="This system does not have any LWIR or other dependent sub-cameras";
IJ.showMessage("Error",msg);
throw new IllegalArgumentException (msg);
}
if ((this.gIS[num_set] == null) || (this.gIS[num_set].imageSet == null)) {
return false;
}
// See if any of the LWIR subcameras has a mark (absolute grid) in this set
int lwir_mark = -1;
for (int ns = 0; ns < this.gIS[num_set].imageSet.length; ns++) {
if (this.gIS[num_set].imageSet[ns]!=null) {
int imgNum = this.gIS[num_set].imageSet[ns].imgNumber;
if (isSmallSensor(imgNum) && (this.gIP[imgNum].matchedPointers > 0)) {
lwir_mark = ns;
break;
}
}
}
int master_sub = getEo0(); // lowest number EO channel, use as a reference
if (lwir_mark >=0) { // some LWIR grid already has mark
master_sub = lwir_mark;
if (bdebug) {
System.out.println ("Aligning to marked LWIR grid image rather than to EO one");
}
// return false;
}
if (this.gIS[num_set].imageSet[master_sub] == null) {
return false; // master EO is not available // may try to search other channels
}
int imgMaster = this.gIS[num_set].imageSet[master_sub].imgNumber;
// get EO image and pixels
ImagePlus imp_master_grid = null;
if (this.gIP[imgMaster].gridImage!=null){ // use in-memory grid images instead of the files
imp_master_grid=this.gIP[imgMaster].gridImage;
} else if (this.gIP[imgMaster].path != null) {
imp_master_grid=(new Opener()).openImage("", this.gIP[imgMaster].path);
if (imp_master_grid==null) {
String msg="Failed to read grid file "+this.gIP[imgMaster].path;
IJ.showMessage("Error",msg);
throw new IllegalArgumentException (msg);
}
(new JP46_Reader_camera()).decodeProperiesFromInfo(imp_master_grid);
} else {
System.out.println("EO grid is not in memory, file path is not specified");
return false;
}
ImageStack stack_master=imp_master_grid.getStack();
if ((stack_master==null) || (stack_master.getSize()<4)) {
String msg="Expected a 8-slice stack";
IJ.showMessage("Error",msg);
throw new IllegalArgumentException (msg);
}
float [][] pixels_master =new float[stack_master.getSize()][]; // now - 8 (x,y,u,v,contrast, vignR,vignG,vignB
for (int i=0;i<pixels_master.length;i++) pixels_master[i]= (float[]) stack_master.getPixels(i+1); // pixel X : negative - no grid here
int width_master = imp_master_grid.getWidth();
// If master is LWIR - reset it's shift to zero
if (lwir_mark >=0) {
// reset master sub UV shift
int [] zero_uvr = {0,0,0};
this.gIS[num_set].imageSet[master_sub].setUVShiftRot(zero_uvr); // uv_shift_rot);
int [][] shiftRotMatrix= MatchSimulatedPattern.getRemapMatrix(this.gIS[num_set].imageSet[master_sub].getUVShiftRot());
setGridsWithRemap( // null immediately
imgMaster,
shiftRotMatrix, // int [][] reMap,
pixels_master,
patternParameters);
}
for (int ns = 0; ns < this.gIS[num_set].imageSet.length; ns++) {
if ((this.gIS[num_set].imageSet[ns]!=null) &&(ns != lwir_mark)) {
int imgNum = this.gIS[num_set].imageSet[ns].imgNumber;
if (isSmallSensor(imgNum)) { // repeat for all target grid images in the image set
// get target EO image and pixels
ImagePlus imp_grid = null;
if (this.gIP[imgNum].gridImage!=null){ // use in-memory grid images instead of the files
imp_grid=this.gIP[imgNum].gridImage;
} else if (this.gIP[imgNum].path != null) {
imp_grid=(new Opener()).openImage("", this.gIP[imgNum].path);
if (imp_grid==null) {
String msg="Failed to read grid file "+this.gIP[imgNum].path;
IJ.showMessage("Error",msg);
throw new IllegalArgumentException (msg);
}
(new JP46_Reader_camera()).decodeProperiesFromInfo(imp_grid);
} else {
System.out.println("EO grid is not in memory, file path is not specified");
return false;
}
ImageStack stack = imp_grid.getStack();
if ((stack==null) || (stack.getSize()<4)) {
String msg="Expected a 8-slice stack";
IJ.showMessage("Error",msg);
throw new IllegalArgumentException (msg);
}
float [][] pixels =new float[stack.getSize()][]; // now - 8 (x,y,u,v,contrast, vignR,vignG,vignB
for (int i=0;i<pixels.length;i++) pixels[i]= (float[]) stack.getPixels(i+1); // pixel X : negative - no grid here
int width_lwir = imp_grid.getWidth();
double [] sensor_wh = {
this.gIP[imgNum].woi.width + this.gIP[imgNum].woi.x,
this.gIP[imgNum].woi.height + this.gIP[imgNum].woi.y};
int [] uv_shift_rot = correlateGrids(
width_master, // int base_width,
pixels_master, // float [][] base_pixels,
width_lwir, // int test_width,
pixels, // float [][] test_pixels,
invert_unmarked_grid,
extra_search,
sigma,
sensor_wh,
false); // true); //bdebug
// combined rotation - first this, next what is applied to EO channel
int [] combinedUVShiftRot=MatchSimulatedPattern.combineUVShiftRot(
uv_shift_rot,
this.gIS[num_set].imageSet[master_sub].getUVShiftRot()
);
if (bdebug) {
System.out.print(imgNum+": calculated uv_shift_rot= ["+uv_shift_rot[0]+":"+uv_shift_rot[1]+"], ");
System.out.print(imgNum+": EO uv_shift_rot= ["+this.gIS[num_set].imageSet[master_sub].getUVShiftRot()[0]+
":"+this.gIS[num_set].imageSet[master_sub].getUVShiftRot()[1]+"], ");
System.out.println(imgNum+": combined uv_shift_rot= ["+combinedUVShiftRot[0]+":"+combinedUVShiftRot[1]+"]");
}
this.gIS[num_set].imageSet[ns].setUVShiftRot(combinedUVShiftRot); // uv_shift_rot);
int [][] shiftRotMatrix= MatchSimulatedPattern.getRemapMatrix(this.gIS[num_set].imageSet[ns].getUVShiftRot());
setGridsWithRemap( // null immediately
imgNum,
shiftRotMatrix, // int [][] reMap,
pixels,
patternParameters);
}
}
}
return true; // OK
}
// provide image set index for the same station that has at least one marked image // provide image set index for the same station that has at least one marked image
// non_estimated - disregard images with estimated orientation // non_estimated - disregard images with estimated orientation
public int getMarkedSet(int num_set, boolean non_estimated) { public int getMarkedSet(int num_set, boolean non_estimated) {
...@@ -1151,6 +1320,12 @@ if (sfiles == null) { ...@@ -1151,6 +1320,12 @@ if (sfiles == null) {
return this.gIS[ns].GXYZ; return this.gIS[ns].GXYZ;
} }
public double [] getXYZ(int num_img) {
int ns = gIP[num_img].getSetNumber();
return this.gIS[ns].GXYZ;
}
// suggest set grid offset by comparing with known (by mark) set. // suggest set grid offset by comparing with known (by mark) set.
// Wrong Grid UV should cause parallel shift - same Z, different XY // Wrong Grid UV should cause parallel shift - same Z, different XY
public int [] suggestOffset ( public int [] suggestOffset (
...@@ -1158,8 +1333,7 @@ if (sfiles == null) { ...@@ -1158,8 +1333,7 @@ if (sfiles == null) {
boolean non_estimated, boolean non_estimated,
boolean even, boolean even,
PatternParameters patternParameters) { PatternParameters patternParameters) {
int num_set = this.gIP[num_img].setNumber; int num_set = this.gIP[num_img].getSetNumber();
int station = this.gIS[num_set].stationNumber;
double [] ref_xyz = getXYZFromMarked(num_set, non_estimated); double [] ref_xyz = getXYZFromMarked(num_set, non_estimated);
if (ref_xyz == null) { if (ref_xyz == null) {
System.out.println("Error: Could not find reference goniometer XYZ for set "+num_set); System.out.println("Error: Could not find reference goniometer XYZ for set "+num_set);
...@@ -1167,41 +1341,55 @@ if (sfiles == null) { ...@@ -1167,41 +1341,55 @@ if (sfiles == null) {
} }
double [] diff_xyz = this.gIS[num_set].GXYZ.clone(); double [] diff_xyz = this.gIS[num_set].GXYZ.clone();
for (int i = 0; i < diff_xyz.length; i++) diff_xyz[i]-=ref_xyz[i]; for (int i = 0; i < diff_xyz.length; i++) diff_xyz[i]-=ref_xyz[i];
return suggestOffset (
num_img,
diff_xyz, // z is not used, may ne just[2]
even,
patternParameters);
}
public int [] suggestOffset (
int num_img,
double [] diff_xyz, // This XYZ minus reference XYZ z is not used, may be just[2]
boolean even,
PatternParameters patternParameters) {
int num_set = this.gIP[num_img].setNumber;
int station = this.gIS[num_set].stationNumber;
int [][] pixelsUV = this.gIP[num_img].pixelsUV ; // null; // for each image, each grid node - a pair of {gridU, gridV} int [][] pixelsUV = this.gIP[num_img].pixelsUV ; // null; // for each image, each grid node - a pair of {gridU, gridV}
if ((pixelsUV == null) || ((pixelsUV.length <3 ))) { if ((pixelsUV == null) || ((pixelsUV.length <3 ))) {
System.out.println("No/too few pixelsUV data for image "+num_img); System.out.println("No/too few pixelsUV data for image "+num_img);
return null; return null;
} }
double [][][] data =new double [pixelsUV.length][3][]; double [][][] data =new double [pixelsUV.length][3][];
for (int i=0; i < pixelsUV.length; i++){ for (int i=0; i < pixelsUV.length; i++){
data[i][0]=new double[2]; data[i][0]=new double[2];
data[i][1]=new double[2]; data[i][1]=new double[2];
data[i][2]=new double[1]; data[i][2]=new double[1];
double [] xyzm = patternParameters.getXYZM( double [] xyzm = patternParameters.getXYZM(
pixelsUV[i][0], pixelsUV[i][0],
pixelsUV[i][1], pixelsUV[i][1],
false, // boolean verbose, false, // boolean verbose,
station); // int station) station); // int station)
data[i][0][0]=xyzm[0];// pixelsXY[i][0]; data[i][0][0]=xyzm[0];// pixelsXY[i][0];
data[i][0][1]=xyzm[1];// pixelsXY[i][1]; data[i][0][1]=xyzm[1];// pixelsXY[i][1];
data[i][1][0]=pixelsUV[i][0]; data[i][1][0]=pixelsUV[i][0];
data[i][1][1]=pixelsUV[i][1]; data[i][1][1]=pixelsUV[i][1];
data[i][2][0]=xyzm[3];// mask data[i][2][0]=xyzm[3];// mask
} }
double [][] coeff=new PolynomialApproximation(this.debugLevel).quadraticApproximation(data, true); // force linear double [][] coeff=new PolynomialApproximation(this.debugLevel).quadraticApproximation(data, true); // force linear
double [] dUV = { double [] dUV = {
-(coeff[0][0]* diff_xyz[0] + coeff[0][1]* diff_xyz[1]), -(coeff[0][0]* diff_xyz[0] + coeff[0][1]* diff_xyz[1]),
-(coeff[1][0]* diff_xyz[0] + coeff[1][1]* diff_xyz[1])}; -(coeff[1][0]* diff_xyz[0] + coeff[1][1]* diff_xyz[1])};
int [] idUV = {(int) Math.round(dUV[0]), (int) Math.round(dUV[1]), 0}; // 0 - no rot int [] idUV = {(int) Math.round(dUV[0]), (int) Math.round(dUV[1]), 0}; // 0 - no rot
int parity = (idUV[0]+idUV[1] + (even?0:1)) & 1; int parity = (idUV[0]+idUV[1] + (even?0:1)) & 1;
double [] UV_err = {dUV[0]-idUV[0], dUV[1]-idUV[1]}; double [] UV_err = {dUV[0]-idUV[0], dUV[1]-idUV[1]};
if (parity !=0) { if (parity !=0) {
if (UV_err[1] > UV_err[0]) { if (UV_err[1] > UV_err[0]) {
if (UV_err[1] > -UV_err[0]) idUV[1]++; if (UV_err[1] > -UV_err[0]) idUV[1]++;
else idUV[0]--; else idUV[0]--;
} else { } else {
if (UV_err[1] > -UV_err[0]) idUV[0]++; if (UV_err[1] > -UV_err[0]) idUV[0]++;
else idUV[1]--; else idUV[1]--;
} }
UV_err[0] = dUV[0] - idUV[0]; UV_err[0] = dUV[0] - idUV[0];
UV_err[1] = dUV[1] - idUV[1]; UV_err[1] = dUV[1] - idUV[1];
...@@ -3101,6 +3289,11 @@ if (sfiles == null) { ...@@ -3101,6 +3289,11 @@ if (sfiles == null) {
this.gIP[fileNumber].gridImage = imp_grid; this.gIP[fileNumber].gridImage = imp_grid;
} }
} }
this.gIP[fileNumber].woi = new Rectangle(
getImagePlusProperty(imp_grid,"WOI_LEFT",0),
getImagePlusProperty(imp_grid,"WOI_TOP",0),
getImagePlusProperty(imp_grid,"WOI_WIDTH", eyesisCameraParameters.getSensorWidth(this.gIP[fileNumber].getChannel())),
getImagePlusProperty(imp_grid,"WOI_HEIGHT", eyesisCameraParameters.getSensorHeight(this.gIP[fileNumber].getChannel())));
this.gIP[fileNumber].laserPixelCoordinates=MatchSimulatedPattern.getPointersXYUV(imp_grid, laserPointers); this.gIP[fileNumber].laserPixelCoordinates=MatchSimulatedPattern.getPointersXYUV(imp_grid, laserPointers);
this.gIP[fileNumber].motors=getMotorPositions(imp_grid, this.numMotors); this.gIP[fileNumber].motors=getMotorPositions(imp_grid, this.numMotors);
this.gIP[fileNumber].matchedPointers=getUsedPonters(imp_grid); this.gIP[fileNumber].matchedPointers=getUsedPonters(imp_grid);
...@@ -3536,7 +3729,7 @@ if (sfiles == null) { ...@@ -3536,7 +3729,7 @@ if (sfiles == null) {
// public double small_period_frac = 0; // set by filter grids - ratio of small sensor period to large sensor period // public double small_period_frac = 0; // set by filter grids - ratio of small sensor period to large sensor period
// depending on camera type, return group, groups, group name // depending on camera type, return group, groups, group name
// camera type: eyesis26, lwir/vnir (2 resolutions) , single, other // camera type: eyesis26, lwir/eo (2 resolutions) , single, other
//getNumSubCameras() //getNumSubCameras()
public int getNumLwir() { public int getNumLwir() {
if (hasSmallSensors()) { if (hasSmallSensors()) {
...@@ -3547,10 +3740,10 @@ if (sfiles == null) { ...@@ -3547,10 +3740,10 @@ if (sfiles == null) {
return 0; return 0;
} }
} }
public int getNumVnir() { public int getNumEo() {
return getNumSubCameras() - getNumLwir(); return getNumSubCameras() - getNumLwir();
} }
public int getVnir0() { public int getEo0() {
if (hasSmallSensors()) { if (hasSmallSensors()) {
for (int i = 0; i < small_sensors.length; i++) if (!small_sensors[i]) return i; for (int i = 0; i < small_sensors.length; i++) if (!small_sensors[i]) return i;
return -1; // should not happen return -1; // should not happen
...@@ -3574,7 +3767,7 @@ if (sfiles == null) { ...@@ -3574,7 +3767,7 @@ if (sfiles == null) {
int n = 2; int n = 2;
if (hasSmallSensors()) { if (hasSmallSensors()) {
if (getNumLwir() > 1) n++; if (getNumLwir() > 1) n++;
if (getNumVnir() > 1) n++; if (getNumEo() > 1) n++;
} }
return n; return n;
} }
...@@ -3594,11 +3787,11 @@ if (sfiles == null) { ...@@ -3594,11 +3787,11 @@ if (sfiles == null) {
if (hasSmallSensors()) { if (hasSmallSensors()) {
if (small_sensors[chn]) { // current is LWIR if (small_sensors[chn]) { // current is LWIR
n = 1; n = 1;
if (getNumVnir() > 1) n = 2; if (getNumEo() > 1) n = 2;
if (chn != getLwir0()) n++; if (chn != getLwir0()) n++;
} else { // current is VNIR } else { // current is EO
n = 0; n = 0;
if (chn != getVnir0()) n++; if (chn != getEo0()) n++;
} }
} }
return n; return n;
...@@ -3606,7 +3799,7 @@ if (sfiles == null) { ...@@ -3606,7 +3799,7 @@ if (sfiles == null) {
// check if the channel is the first in group // check if the channel is the first in group
public boolean firstInGroup(int chn) { public boolean firstInGroup(int chn) {
if (chn >= 24) return (chn == 24); if (chn >= 24) return (chn == 24);
if ((chn == getVnir0()) || (chn == getLwir0())) return true; if ((chn == getEo0()) || (chn == getLwir0())) return true;
int [] num = {0,0}; int [] num = {0,0};
for (int i = 0; i < chn; i++) { for (int i = 0; i < chn; i++) {
if ((small_sensors != null) && small_sensors[i]) num[1]++; if ((small_sensors != null) && small_sensors[i]) num[1]++;
...@@ -3631,13 +3824,13 @@ if (sfiles == null) { ...@@ -3631,13 +3824,13 @@ if (sfiles == null) {
if (chn != getLwir0()) return full?"Subcamera LWIR other":"sub-lwir-other"; if (chn != getLwir0()) return full?"Subcamera LWIR other":"sub-lwir-other";
if (getNumLwir() > 1) return full?"Subcamera LWIR 0":"sub-lwir0"; if (getNumLwir() > 1) return full?"Subcamera LWIR 0":"sub-lwir0";
return full?"Subcamera LWIR":"sub-lwir"; return full?"Subcamera LWIR":"sub-lwir";
} else { // current is VNIR } else { // current is EO
if (chn != getVnir0()) return full?"Subcamera VNIR other":"sub-vnir-other"; if (chn != getEo0()) return full?"Subcamera EO other":"sub-eo-other";
if (getNumVnir() > 1) return full?"Subcamera VNIR 0":"sub-vnir0"; if (getNumEo() > 1) return full?"Subcamera EO 0":"sub-eo0";
return full?"Subcamera VNIR":"sub-vnir"; return full?"Subcamera EO":"sub-eo";
} }
} }
if (chn != getVnir0()) return full?"Subcamera other":"sub-other"; if (chn != getEo0()) return full?"Subcamera other":"sub-other";
return full?"Subcamera 0":"sub0"; return full?"Subcamera 0":"sub0";
} }
......
...@@ -521,42 +521,70 @@ public class Distortions { ...@@ -521,42 +521,70 @@ public class Distortions {
// Individual image mask is needed as some parts can be obscured by moving parts - not present on all images. // Individual image mask is needed as some parts can be obscured by moving parts - not present on all images.
// grid "contrast" may be far from 1.0 but probably should work OK // grid "contrast" may be far from 1.0 but probably should work OK
/// double gridContrast= fittingStrategy.distortionCalibrationData.gIP[imgNum].pixelsXY[pointNumber][2]-minimalGridContrast;//minimalGridContrast\ /// double gridContrast= fittingStrategy.distortionCalibrationData.gIP[imgNum].pixelsXY[pointNumber][2]-minimalGridContrast;//minimalGridContrast\
double dbg;
// if (weight > 0) {
if ((weight > 0) && (imgNum == 244)) {
dbg = weight;
}
if ((filter & this.filterContrast)!=0) { if ((filter & this.filterContrast)!=0) {
double gridContrast= gridWeight[pointNumber]; double gridContrast= gridWeight[pointNumber];
weight*=gridContrast; weight*=gridContrast;
if (Double.isNaN(gridContrast) && (this.debugLevel>1)) System.out.println("gridContrast=NaN, imgNum="+imgNum); if (Double.isNaN(gridContrast) && (this.debugLevel>1)) System.out.println("gridContrast=NaN, imgNum="+imgNum);
} }
// if (weight > 0) {
if ((weight > 0) && (imgNum == 244)) {
dbg = weight;
}
if ((filter & this.filterTargetMask)!=0) { if ((filter & this.filterTargetMask)!=0) {
weight*=XYZMP[patternMaskIndex];//DONE: Use grid mask also (fade out outer grid nodes?) weight*=XYZMP[patternMaskIndex];//DONE: Use grid mask also (fade out outer grid nodes?)
if (Double.isNaN(XYZMP[patternMaskIndex]) && (this.debugLevel>1)) System.out.println("XYZMP["+patternMaskIndex+"]=NaN, imgNum="+imgNum); if (Double.isNaN(XYZMP[patternMaskIndex]) && (this.debugLevel>1)) System.out.println("XYZMP["+patternMaskIndex+"]=NaN, imgNum="+imgNum);
} }
// if (weight > 0) {
if ((weight > 0) && (imgNum == 244)) {
dbg = weight;
}
if ((filter & this.filterTargetAlpha)!=0) { if ((filter & this.filterTargetAlpha)!=0) {
weight*=XYZMP[patternAlphaIndex];//DONE: Use grid mask also (fade out outer grid nodes?) weight*=XYZMP[patternAlphaIndex];//DONE: Use grid mask also (fade out outer grid nodes?)
if (Double.isNaN(XYZMP[patternAlphaIndex]) && (this.debugLevel>1)) System.out.println("XYZMP["+patternAlphaIndex+"]=NaN, imgNum="+imgNum); if (Double.isNaN(XYZMP[patternAlphaIndex]) && (this.debugLevel>1)) System.out.println("XYZMP["+patternAlphaIndex+"]=NaN, imgNum="+imgNum);
} }
// if (weight > 0) {
if ((weight > 0) && (imgNum == 244)) {
dbg = weight;
}
if ((filter & this.filterTargetErrors)!=0) { if ((filter & this.filterTargetErrors)!=0) {
weight*=XYZMP[patternErrorMaskIndex];//DONE: Use grid mask also (fade out outer grid nodes?) weight*=XYZMP[patternErrorMaskIndex];//DONE: Use grid mask also (fade out outer grid nodes?)
if (Double.isNaN(XYZMP[patternErrorMaskIndex]) && (this.debugLevel>1)) System.out.println("XYZMP["+patternErrorMaskIndex+"]=NaN, imgNum="+imgNum); if (Double.isNaN(XYZMP[patternErrorMaskIndex]) && (this.debugLevel>1)) System.out.println("XYZMP["+patternErrorMaskIndex+"]=NaN, imgNum="+imgNum);
} }
// if (weight > 0) {
if ((weight > 0) && (imgNum == 244)) {
dbg = weight;
}
if ((filter & this.filterMulti)!=0) { if ((filter & this.filterMulti)!=0) {
weight*=multiWeight[imgNum]; weight*=multiWeight[imgNum];
if (Double.isNaN(multiWeight[imgNum]) && (this.debugLevel>1)) System.out.println("multiWeight["+imgNum+"]=NaN, imgNum="+imgNum); if (Double.isNaN(multiWeight[imgNum]) && (this.debugLevel>1)) System.out.println("multiWeight["+imgNum+"]=NaN, imgNum="+imgNum);
} }
// if (weight > 0) {
if ((weight > 0) && (imgNum == 244)) {
dbg = weight;
}
if ((filter & this.filterMaskBadNodes)!=0) { if ((filter & this.filterMaskBadNodes)!=0) {
if (fittingStrategy.distortionCalibrationData.gIP[imgNum].isNodeBad(pointNumber)) weight=0.0; if (fittingStrategy.distortionCalibrationData.gIP[imgNum].isNodeBad(pointNumber)) weight=0.0;
} }
// if (weight > 0) {
if ((weight > 0) && (imgNum == 244)) {
dbg = weight; // got here
}
//fittingStrategy.distortionCalibrationData.eyesisCameraParameters.weightMultiExponent) //fittingStrategy.distortionCalibrationData.eyesisCameraParameters.weightMultiExponent)
if (((filter & this.filterDiameter)!=0) && (fittingStrategy.distortionCalibrationData.eyesisCameraParameters.weightDiameterExponent>0.0)) { if (((filter & this.filterDiameter)!=0) && (fittingStrategy.distortionCalibrationData.eyesisCameraParameters.weightDiameterExponent>0.0)) {
weight*=gridImageWeight; weight*=gridImageWeight;
if (Double.isNaN(gridImageWeight) && (this.debugLevel>1)) System.out.println("gridImageWeight=NaN, imgNum="+imgNum); if (Double.isNaN(gridImageWeight) && (this.debugLevel>1)) System.out.println("gridImageWeight=NaN, imgNum="+imgNum);
} }
// if (weight > 0) {
if ((weight > 0) && (imgNum == 244)) {
dbg = weight;
}
if (Double.isNaN(weight)) { if (Double.isNaN(weight)) {
weight=0.0; // find who makes it NaN weight=0.0; // find who makes it NaN
if (Double.isNaN(multiWeight[imgNum])) System.out.println("weight is null, imgNum="+imgNum); if (Double.isNaN(multiWeight[imgNum])) System.out.println("weight is null, imgNum="+imgNum);
...@@ -619,7 +647,9 @@ public class Distortions { ...@@ -619,7 +647,9 @@ public class Distortions {
continue; continue;
} }
if (this.weightFunction[2*(index+pointNumber)]>0.0) numValidNodes++; //OOB 5064 if (this.weightFunction[2*(index+pointNumber)]>0.0) {
numValidNodes++; //OOB 5064
}
} }
if (numValidNodes<this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.minimalValidNodes){ if (numValidNodes<this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.minimalValidNodes){
this.fittingStrategy.invalidateSelectedImage(numSeries,imgNum); this.fittingStrategy.invalidateSelectedImage(numSeries,imgNum);
...@@ -3269,19 +3299,14 @@ For each point in the image ...@@ -3269,19 +3299,14 @@ For each point in the image
public LensDistortionParameters setupLensDistortionParameters( public LensDistortionParameters setupLensDistortionParameters(
int numImg, int numImg,
// int stationNumber,
// int subCamera,
int debugLevel){ // Axial - may be Double.NaN int debugLevel){ // Axial - may be Double.NaN
// double [] parVector=fittingStrategy.distortionCalibrationData.eyesisCameraParameters.getParametersVector(stationNumber,subCamera);
// System.out.println("setupLensDistortionParameters(): subCamera="+subCamera+", goniometerHorizontal="+goniometerHorizontal+", goniometerAxial="+goniometerAxial);
boolean isTripod=this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.isTripod;
boolean cartesian=this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.cartesian;
LensDistortionParameters lensDistortionParameters = new LensDistortionParameters ( LensDistortionParameters lensDistortionParameters = new LensDistortionParameters (
isTripod, this.fittingStrategy.distortionCalibrationData.isTripod(),
cartesian, this.fittingStrategy.distortionCalibrationData.isCartesian(),
this.fittingStrategy.distortionCalibrationData.getPixelSize(numImg),
this.fittingStrategy.distortionCalibrationData.getDistortionRadius(numImg),
null, //double [][] interParameterDerivatives, //partial derivative matrix from subcamera-camera-goniometer to single camera (12x21) if null - just values, no derivatives null, //double [][] interParameterDerivatives, //partial derivative matrix from subcamera-camera-goniometer to single camera (12x21) if null - just values, no derivatives
// this.fittingStrategy.distortionCalibrationData.pars[numImg], //parVector,
this.fittingStrategy.distortionCalibrationData.getParameters(numImg), //parVector, this.fittingStrategy.distortionCalibrationData.getParameters(numImg), //parVector,
null, //boolean [] mask, // calculate only selected derivatives (all parVect values are still null, //boolean [] mask, // calculate only selected derivatives (all parVect values are still
debugLevel debugLevel
...@@ -3298,16 +3323,13 @@ For each point in the image ...@@ -3298,16 +3323,13 @@ For each point in the image
double [] parVector=fittingStrategy.distortionCalibrationData.eyesisCameraParameters.getParametersVector(stationNumber,subCamera); double [] parVector=fittingStrategy.distortionCalibrationData.eyesisCameraParameters.getParametersVector(stationNumber,subCamera);
int goniometerHorizontalIndex=fittingStrategy.distortionCalibrationData.eyesisCameraParameters.getGoniometerHorizontalIndex(); int goniometerHorizontalIndex=fittingStrategy.distortionCalibrationData.eyesisCameraParameters.getGoniometerHorizontalIndex();
int goniometerAxialIndex=fittingStrategy.distortionCalibrationData.eyesisCameraParameters.getGoniometerAxialIndex(); int goniometerAxialIndex=fittingStrategy.distortionCalibrationData.eyesisCameraParameters.getGoniometerAxialIndex();
// int sensorWidth=fittingStrategy.distortionCalibrationData.eyesisCameraParameters.getSensorWidth(subCamera);
// int sensorHeight=fittingStrategy.distortionCalibrationData.eyesisCameraParameters.getSensorHeight(subCamera);
if (!Double.isNaN(goniometerHorizontal))parVector[goniometerHorizontalIndex]=goniometerHorizontal; if (!Double.isNaN(goniometerHorizontal))parVector[goniometerHorizontalIndex]=goniometerHorizontal;
if (!Double.isNaN(goniometerAxial))parVector[goniometerAxialIndex]=goniometerAxial; if (!Double.isNaN(goniometerAxial))parVector[goniometerAxialIndex]=goniometerAxial;
// System.out.println("setupLensDistortionParameters(): subCamera="+subCamera+", goniometerHorizontal="+goniometerHorizontal+", goniometerAxial="+goniometerAxial);
boolean isTripod=this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.isTripod;
boolean cartesian=this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.cartesian;
LensDistortionParameters lensDistortionParameters = new LensDistortionParameters ( LensDistortionParameters lensDistortionParameters = new LensDistortionParameters (
isTripod, this.fittingStrategy.distortionCalibrationData.isTripod(),
cartesian, this.fittingStrategy.distortionCalibrationData.isCartesian(),
this.fittingStrategy.distortionCalibrationData.getPixelSize(stationNumber, subCamera),
this.fittingStrategy.distortionCalibrationData.getDistortionRadius(stationNumber, subCamera),
null, //double [][] interParameterDerivatives, //partial derivative matrix from subcamera-camera-goniometer to single camera (12x21) if null - just values, no derivatives null, //double [][] interParameterDerivatives, //partial derivative matrix from subcamera-camera-goniometer to single camera (12x21) if null - just values, no derivatives
parVector, parVector,
null, //boolean [] mask, // calculate only selected derivatives (all parVect values are still null, //boolean [] mask, // calculate only selected derivatives (all parVect values are still
...@@ -3450,8 +3472,10 @@ For each point in the image ...@@ -3450,8 +3472,10 @@ For each point in the image
System.out.println("estimateGridOnSensor(): subCamera="+subCamera+", goniometerHorizontal="+goniometerHorizontal+", goniometerAxial="+goniometerAxial); System.out.println("estimateGridOnSensor(): subCamera="+subCamera+", goniometerHorizontal="+goniometerHorizontal+", goniometerAxial="+goniometerAxial);
this.lensDistortionParameters.lensCalcInterParamers( this.lensDistortionParameters.lensCalcInterParamers(
this.lensDistortionParameters, // 22-long parameter vector for the image this.lensDistortionParameters, // 22-long parameter vector for the image
this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.isTripod, this.fittingStrategy.distortionCalibrationData.isTripod(),
this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.cartesian, this.fittingStrategy.distortionCalibrationData.isCartesian(),
this.fittingStrategy.distortionCalibrationData.getPixelSize(stationNumber, subCamera),
this.fittingStrategy.distortionCalibrationData.getDistortionRadius(stationNumber, subCamera),
null, // this.interParameterDerivatives, // [22][] null, // this.interParameterDerivatives, // [22][]
parVector, parVector,
null); // if no derivatives, null is OK null); // if no derivatives, null is OK
...@@ -3570,13 +3594,14 @@ For each point in the image ...@@ -3570,13 +3594,14 @@ For each point in the image
return; // no images found return; // no images found
} }
double [] imgVector=fittingStrategy.getImageParametersVector(imgNum, vector); //this.currentVector); double [] imgVector=fittingStrategy.getImageParametersVector(imgNum, vector); //this.currentVector);
// boolean [] imgMask= fittingStrategy.getImageParametersVectorMask(imgNum);
boolean [] imgMask= new boolean[imgVector.length]; boolean [] imgMask= new boolean[imgVector.length];
for (int i=0;i<imgMask.length;i++) imgMask[i]=true; for (int i=0;i<imgMask.length;i++) imgMask[i]=true;
this.lensDistortionParameters.lensCalcInterParamers( this.lensDistortionParameters.lensCalcInterParamers(
this.lensDistortionParameters, this.lensDistortionParameters,
this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.isTripod, this.fittingStrategy.distortionCalibrationData.isTripod(),
this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.cartesian, this.fittingStrategy.distortionCalibrationData.isCartesian(),
this.fittingStrategy.distortionCalibrationData.getPixelSize(imgNum),
this.fittingStrategy.distortionCalibrationData.getDistortionRadius(imgNum),
this.interParameterDerivatives, // [22][] this.interParameterDerivatives, // [22][]
imgVector, imgVector,
imgMask); // calculate only selected derivatives (all parVect values are still imgMask); // calculate only selected derivatives (all parVect values are still
...@@ -3599,8 +3624,10 @@ For each point in the image ...@@ -3599,8 +3624,10 @@ For each point in the image
vector_delta[i]+=delta; vector_delta[i]+=delta;
this.lensDistortionParameters.lensCalcInterParamers( this.lensDistortionParameters.lensCalcInterParamers(
this.lensDistortionParameters, this.lensDistortionParameters,
this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.isTripod, this.fittingStrategy.distortionCalibrationData.isTripod(),
this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.cartesian, this.fittingStrategy.distortionCalibrationData.isCartesian(),
this.fittingStrategy.distortionCalibrationData.getPixelSize(imgNum),
this.fittingStrategy.distortionCalibrationData.getDistortionRadius(imgNum),
null, // this.interParameterDerivatives, // just values, no derivatives null, // this.interParameterDerivatives, // just values, no derivatives
vector_delta, vector_delta,
imgMask); imgMask);
...@@ -3687,8 +3714,10 @@ For each point in the image ...@@ -3687,8 +3714,10 @@ For each point in the image
this.lensDistortionParameters.debugLevel=this.debugLevel; this.lensDistortionParameters.debugLevel=this.debugLevel;
this.lensDistortionParameters.lensCalcInterParamers( this.lensDistortionParameters.lensCalcInterParamers(
this.lensDistortionParameters, this.lensDistortionParameters,
this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.isTripod, this.fittingStrategy.distortionCalibrationData.isTripod(),
this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.cartesian, this.fittingStrategy.distortionCalibrationData.isCartesian(),
this.fittingStrategy.distortionCalibrationData.getPixelSize(imgNum),
this.fittingStrategy.distortionCalibrationData.getDistortionRadius(imgNum),
calcJacobian?this.interParameterDerivatives:null, // [22][] calcJacobian?this.interParameterDerivatives:null, // [22][]
imgVector, imgVector,
imgMask); // imgMask may be null if no derivativescalculate only selected derivatives (all parVect values are still imgMask); // imgMask may be null if no derivativescalculate only selected derivatives (all parVect values are still
...@@ -3805,8 +3834,10 @@ For each point in the image ...@@ -3805,8 +3834,10 @@ For each point in the image
if (this.debugLevel>3) System.out.println("calculatePartialFxAndJacobian(), numImage="+numImage+" calcInterParamers():"); if (this.debugLevel>3) System.out.println("calculatePartialFxAndJacobian(), numImage="+numImage+" calcInterParamers():");
lensDistortionParameters.lensCalcInterParamers( lensDistortionParameters.lensCalcInterParamers(
lensDistortionParameters, lensDistortionParameters,
this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.isTripod, this.fittingStrategy.distortionCalibrationData.isTripod(),
this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.cartesian, this.fittingStrategy.distortionCalibrationData.isCartesian(),
this.fittingStrategy.distortionCalibrationData.getPixelSize(numImage),
this.fittingStrategy.distortionCalibrationData.getDistortionRadius(numImage),
calcJacobian?interParameterDerivatives:null, // [22][] calcJacobian?interParameterDerivatives:null, // [22][]
imgVector, imgVector,
imgMask); // calculate only selected derivatives (all parVect values are still imgMask); // calculate only selected derivatives (all parVect values are still
...@@ -3889,8 +3920,10 @@ For each point in the image ...@@ -3889,8 +3920,10 @@ For each point in the image
} }
this.lensDistortionParameters.lensCalcInterParamers( this.lensDistortionParameters.lensCalcInterParamers(
this.lensDistortionParameters, this.lensDistortionParameters,
this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.isTripod, this.fittingStrategy.distortionCalibrationData.isTripod(),
this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.cartesian, this.fittingStrategy.distortionCalibrationData.isCartesian(),
this.fittingStrategy.distortionCalibrationData.getPixelSize(imgNum),
this.fittingStrategy.distortionCalibrationData.getDistortionRadius(imgNum),
null, //this.interParameterDerivatives, // [22][] null, //this.interParameterDerivatives, // [22][]
imgVector, imgVector,
imgMask); // calculate only selected derivatives (all parVect values are still imgMask); // calculate only selected derivatives (all parVect values are still
...@@ -4436,8 +4469,10 @@ List calibration ...@@ -4436,8 +4469,10 @@ List calibration
} }
this.lensDistortionParameters.lensCalcInterParamers( this.lensDistortionParameters.lensCalcInterParamers(
this.lensDistortionParameters, this.lensDistortionParameters,
this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.isTripod, this.fittingStrategy.distortionCalibrationData.isTripod(),
this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.cartesian, this.fittingStrategy.distortionCalibrationData.isCartesian(),
this.fittingStrategy.distortionCalibrationData.getPixelSize(imgNum),
this.fittingStrategy.distortionCalibrationData.getDistortionRadius(imgNum),
null, //this.interParameterDerivatives, // [22][] null, //this.interParameterDerivatives, // [22][]
// fittingStrategy.distortionCalibrationData.pars[imgNum], // 22-long parameter vector for the image // fittingStrategy.distortionCalibrationData.pars[imgNum], // 22-long parameter vector for the image
fittingStrategy.distortionCalibrationData.getParameters(imgNum), // 22-long parameter vector for the image fittingStrategy.distortionCalibrationData.getParameters(imgNum), // 22-long parameter vector for the image
...@@ -7412,8 +7447,81 @@ List calibration ...@@ -7412,8 +7447,81 @@ List calibration
return masks; return masks;
} }
// Use series0 to find grid mismatch (and set it correctly). Uses that pattern in the world coordinate system is
// approximately in XY plane, so by freezing all other parameters but GXY0 and GXY1 it is possible to find
// the pattern grid match.
public int [] findImageGridOffset(
int num_img,
boolean even,
PatternParameters patternParameters) {
// set series 0 to this set images
boolean [] selection = fittingStrategy.selectAllImages(0); // enable all images in series 0
for (int i=0;i<selection.length;i++) selection[i]=false;
selection[num_img]=true;
fittingStrategy.setImageSelection(0,selection);
seriesNumber= 0; // start from 0;
initFittingSeries(false, filterForAll,0); // will set this.currentVector
//this.stopAfterThis[numSeries]
fittingStrategy.stopAfterThis[0]=true;
stopEachStep= false;
stopEachSeries= false; // will not ask for confirmation after done
lambda = fittingStrategy.lambdas[0];
boolean LMA_OK = false;
try {
LMA_OK = LevenbergMarquardt (false, true); // skip dialog, dry run (no updates)
} catch (Exception e) {
// LMA failed - e.g. not enough points (Singular Matrix)
}
if (!LMA_OK) {
return null; // LMA did not converge
}
double [] new_XY = {this.currentVector[0],this.currentVector[1]};
DistortionCalibrationData dcd = this.fittingStrategy.distortionCalibrationData;
// int num_set = dcd.gIP[num_img].getSetNumber();
double [] ref_XYZ = dcd.getXYZ(num_img);
double [] diff_XY = {
new_XY[0] -ref_XYZ[0],
new_XY[1] -ref_XYZ[1]};
//save safe settings to run LMA manually (or save what was set)
seriesNumber= 0; // start from 0;
initFittingSeries (false,filterForAll,0); // will set this.currentVector
stopEachSeries= true; // will not ask for confirmation after done
stopOnFailure= true;
lambda= fittingStrategy.lambdas[0];
int [] grid_offset = dcd.suggestOffset (
num_img,
diff_XY, // This XYZ minus reference XYZ z is not used, may be just[2]
even,
patternParameters);
return grid_offset;
public boolean LevenbergMarquardt(boolean openDialog){
/*
*
this.currentVector[0] - GXYZ[0]
this.currentVector[1] - GXYZ[1]
dcd. public int [] suggestOffset (
int num_img,
double [] diff_xyz, // This XYZ minus reference XYZ z is not used, may be just[2]
boolean even,
PatternParameters patternParameters) {
*/
}
public boolean LevenbergMarquardt(
boolean openDialog,
boolean dry_run){ // do not save results
if (this.fittingStrategy==null) { if (this.fittingStrategy==null) {
String msg="Fitting strategy does not exist, exiting"; String msg="Fitting strategy does not exist, exiting";
IJ.showMessage("Error",msg); IJ.showMessage("Error",msg);
...@@ -7497,7 +7605,7 @@ List calibration ...@@ -7497,7 +7605,7 @@ List calibration
") at "+ IJ.d2s(0.000000001*(System.nanoTime()-this.startTime),3)); ") at "+ IJ.d2s(0.000000001*(System.nanoTime()-this.startTime),3));
} }
if (!cont){ if (!cont){
if (this.saveSeries) { if (this.saveSeries && !dry_run) {
saveFittingSeries(); // will save series even if it ended in failure, vector will be only updated saveFittingSeries(); // will save series even if it ended in failure, vector will be only updated
updateCameraParametersFromCalculated(true); // update camera parameters from all (even disabled) images updateCameraParametersFromCalculated(true); // update camera parameters from all (even disabled) images
updateCameraParametersFromCalculated(false); // update camera parameters from enabled only images (may overwrite some of the above) updateCameraParametersFromCalculated(false); // update camera parameters from enabled only images (may overwrite some of the above)
...@@ -7508,11 +7616,15 @@ List calibration ...@@ -7508,11 +7616,15 @@ List calibration
//stepLevenbergMarquardtAction(); //stepLevenbergMarquardtAction();
if (state[1]) { if (state[1]) {
if (!state[0]) return false; // sequence failed if (!state[0]) return false; // sequence failed
saveFittingSeries(); if (dry_run) {
updateCameraParametersFromCalculated(true); // update camera parameters from all (even disabled) images wasLastSeries= true; // always just one series
updateCameraParametersFromCalculated(false); // update camera parameters from enabled only images (may overwrite some of the above) } else {
wasLastSeries=this.fittingStrategy.isLastSeries(this.seriesNumber); saveFittingSeries();
this.seriesNumber++; updateCameraParametersFromCalculated(true); // update camera parameters from all (even disabled) images
updateCameraParametersFromCalculated(false); // update camera parameters from enabled only images (may overwrite some of the above)
wasLastSeries=this.fittingStrategy.isLastSeries(this.seriesNumber);
this.seriesNumber++;
}
break; // while (true), proceed to the next series break; // while (true), proceed to the next series
} }
} }
...@@ -8024,8 +8136,8 @@ D2= ...@@ -8024,8 +8136,8 @@ D2=
final int threadsMax, final int threadsMax,
final boolean updateStatus final boolean updateStatus
){ ){
final boolean isTripod=this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.isTripod; // final boolean isTripod=this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.is_tripod;
final boolean cartesian=this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.cartesian; // final boolean cartesian=this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.cartesian;
final int [][] dirs= {{0,0},{-1,0},{1,0},{0,-1},{0,1}}; // possible to make 8 directions final int [][] dirs= {{0,0},{-1,0},{1,0},{0,-1},{0,1}}; // possible to make 8 directions
final double [][][] derivatives={ // for of /du, /dv 3 variants, depending on which neighbors are available final double [][][] derivatives={ // for of /du, /dv 3 variants, depending on which neighbors are available
{ {
...@@ -8078,10 +8190,11 @@ D2= ...@@ -8078,10 +8190,11 @@ D2=
// The following method sets this.lensDistortionParameters and invokes this.lensDistortionParameters.recalcCommons(); // The following method sets this.lensDistortionParameters and invokes this.lensDistortionParameters.recalcCommons();
lensDistortionParameters.lensCalcInterParamers( lensDistortionParameters.lensCalcInterParamers(
lensDistortionParameters, lensDistortionParameters,
isTripod, fittingStrategy.distortionCalibrationData.isTripod(),
cartesian, fittingStrategy.distortionCalibrationData.isCartesian(),
fittingStrategy.distortionCalibrationData.getPixelSize(imgNum),
fittingStrategy.distortionCalibrationData.getDistortionRadius(imgNum),
null, //this.interParameterDerivatives, // [22][] null, //this.interParameterDerivatives, // [22][]
// fittingStrategy.distortionCalibrationData.pars[imgNum], // 22-long parameter vector for the image
fittingStrategy.distortionCalibrationData.getParameters(imgNum), // 22-long parameter vector for the image fittingStrategy.distortionCalibrationData.getParameters(imgNum), // 22-long parameter vector for the image
null); // if no derivatives, null is OK null); // if no derivatives, null is OK
// false); // calculate this.interParameterDerivatives -derivatives array (false - just this.values) // false); // calculate this.interParameterDerivatives -derivatives array (false - just this.values)
...@@ -8276,8 +8389,10 @@ D2= ...@@ -8276,8 +8389,10 @@ D2=
// The following method sets this.lensDistortionParameters and invokes this.lensDistortionParameters.recalcCommons(); // The following method sets this.lensDistortionParameters and invokes this.lensDistortionParameters.recalcCommons();
this.lensDistortionParameters.lensCalcInterParamers( this.lensDistortionParameters.lensCalcInterParamers(
this.lensDistortionParameters, this.lensDistortionParameters,
this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.isTripod, fittingStrategy.distortionCalibrationData.isTripod(),
this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.cartesian, fittingStrategy.distortionCalibrationData.isCartesian(),
fittingStrategy.distortionCalibrationData.getPixelSize(imgNum),
fittingStrategy.distortionCalibrationData.getDistortionRadius(imgNum),
null, //this.interParameterDerivatives, // [22][] null, //this.interParameterDerivatives, // [22][]
// fittingStrategy.distortionCalibrationData.pars[imgNum], // 22-long parameter vector for the image // fittingStrategy.distortionCalibrationData.pars[imgNum], // 22-long parameter vector for the image
fittingStrategy.distortionCalibrationData.getParameters(imgNum), // 22-long parameter vector for the image fittingStrategy.distortionCalibrationData.getParameters(imgNum), // 22-long parameter vector for the image
...@@ -9722,6 +9837,8 @@ M * V = B ...@@ -9722,6 +9837,8 @@ M * V = B
} }
} }
LensDistortionParameters ldp=this.lensDistortionParameters.clone(); LensDistortionParameters ldp=this.lensDistortionParameters.clone();
// 06/2019 - need to update distortionRadius, pixelSize)
// public void setLensDistortionParameters(LensDistortionParameters ldp // public void setLensDistortionParameters(LensDistortionParameters ldp
for (int v=0; v<gridHeight; v++) for (int u=0; u<gridWidth; u++) if (patternParameters.gridGeometry[v][u][3]>0) { for (int v=0; v<gridHeight; v++) for (int u=0; u<gridWidth; u++) if (patternParameters.gridGeometry[v][u][3]>0) {
......
...@@ -1520,9 +1520,10 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit ...@@ -1520,9 +1520,10 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
for (;(endIndex<enabled.length) && !allImages && !enabled[endIndex];endIndex++); // advance over disabled images for (;(endIndex<enabled.length) && !allImages && !enabled[endIndex];endIndex++); // advance over disabled images
GenericDialog gd=new GenericDialog("Select images "+startIndex+"..."+(endIndex-1)); GenericDialog gd=new GenericDialog("Select images "+startIndex+"..."+(endIndex-1));
for (int i=startIndex;i<endIndex;i++) if (allImages || enabled[i]){ for (int i=startIndex;i<endIndex;i++) if (allImages || enabled[i]){
gd.addCheckbox (i+" - "+(this.distortionCalibrationData.gIP[i].enabled?"":"(disabled) ")+ gd.addCheckbox (i+ " ("+this.distortionCalibrationData.gIP[i].getSetNumber()+
"."+this.distortionCalibrationData.gIP[i].getChannel()+")"+
" - "+(this.distortionCalibrationData.gIP[i].enabled?"":"(disabled) ")+
IJ.d2s(this.distortionCalibrationData.gIP[i].timestamp,6)+ IJ.d2s(this.distortionCalibrationData.gIP[i].timestamp,6)+
": "+this.distortionCalibrationData.gIP[i].channel+
" matched "+this.distortionCalibrationData.gIP[i].matchedPointers+" pointers"+ " matched "+this.distortionCalibrationData.gIP[i].matchedPointers+" pointers"+
", hinted state: "+((hintedMatch[i]<0)?"undefined":((hintedMatch[i]==0)?"failed":((hintedMatch[i]==1)?"orientation":"orientation and translation"))), ", hinted state: "+((hintedMatch[i]<0)?"undefined":((hintedMatch[i]==0)?"failed":((hintedMatch[i]==1)?"orientation":"orientation and translation"))),
selection[i]); selection[i]);
...@@ -1852,7 +1853,7 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit ...@@ -1852,7 +1853,7 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
// gd.addCheckbox("Select images with estimated orientation", selectEstimated); // gd.addCheckbox("Select images with estimated orientation", selectEstimated);
// gd.addCheckbox("Select new enabled images", selectNewEnabled); // gd.addCheckbox("Select new enabled images", selectNewEnabled);
if (this.distortionCalibrationData.hasSmallSensors()) { if (this.distortionCalibrationData.hasSmallSensors()) {
gd.addMessage("=== Filter selection by High/Low resolution sensors (such as VNIR/LWIR)"); gd.addMessage("=== Filter selection by High/Low resolution sensors (such as EO/LWIR)");
gd.addCheckbox("Select high-res sensors", true); gd.addCheckbox("Select high-res sensors", true);
gd.addCheckbox("Select low-res sensors", true); gd.addCheckbox("Select low-res sensors", true);
} }
...@@ -1977,7 +1978,7 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit ...@@ -1977,7 +1978,7 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
* @param useParameters Select parameters for this series * @param useParameters Select parameters for this series
* @param askNextSeries Ask for next series number * @param askNextSeries Ask for next series number
* @param zeroAndOther use 2 channels 0 and "other", propagate settings for channel 1 to all the rest * @param zeroAndOther use 2 channels 0 and "other", propagate settings for channel 1 to all the rest
* For low/high res (LWIR/VNIR) - use first /other for each class * For low/high res (LWIR/EO) - use first /other for each class
* @return -2 - cancel, -1, done, otherwise - number of step to edit * @return -2 - cancel, -1, done, otherwise - number of step to edit
*/ */
...@@ -2055,7 +2056,7 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit ...@@ -2055,7 +2056,7 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
// sub(other): their group number - no, 0 - later add this.definedModesAll.length to master subcamera // sub(other): their group number - no, 0 - later add this.definedModesAll.length to master subcamera
// not zeroAndOther: // not zeroAndOther:
// non-sub - -1: // non-sub - -1:
// sub(>0): subCam-1 (previous index) - will suggest any with smaller index - may be useless with lwir < vnir indices // sub(>0): subCam-1 (previous index) - will suggest any with smaller index - may be useless with lwir < eo indices
// int subMaxNum = (this.distortionCalibrationData.isSubcameraParameter(parIndex) && (subCam > 0)) ? (zeroAndOther? 0 : (subCam-1)):-1; // int subMaxNum = (this.distortionCalibrationData.isSubcameraParameter(parIndex) && (subCam > 0)) ? (zeroAndOther? 0 : (subCam-1)):-1;
int subMaxNum = -1; int subMaxNum = -1;
if (this.distortionCalibrationData.isSubcameraParameter(parIndex)) { // only for subcamera parameters if (this.distortionCalibrationData.isSubcameraParameter(parIndex)) { // only for subcamera parameters
...@@ -2120,7 +2121,7 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit ...@@ -2120,7 +2121,7 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
* @param useParameters Select parameters for this series * @param useParameters Select parameters for this series
* @param askNextSeries Ask for next series number * @param askNextSeries Ask for next series number
* @param zeroAndOther use 2 channels 0 and "other", propagate settings for channel 1 to all the rest * @param zeroAndOther use 2 channels 0 and "other", propagate settings for channel 1 to all the rest
* Updated for more groups (up to 4 in LWIR/VNIR) - use 1 channel for each group, propagate to the rest of the group * Updated for more groups (up to 4 in LWIR/EO) - use 1 channel for each group, propagate to the rest of the group
* @return -2 - cancel, -1, done, otherwise - number of step to edit * @return -2 - cancel, -1, done, otherwise - number of step to edit
*/ */
public int selectStrategyStep( public int selectStrategyStep(
...@@ -2187,7 +2188,7 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit ...@@ -2187,7 +2188,7 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
for (int i=0;i<this.distortionCalibrationData.eyesisCameraParameters.numStations;i++) gd.addCheckbox("Station "+i, constrainByStation[i]); for (int i=0;i<this.distortionCalibrationData.eyesisCameraParameters.numStations;i++) gd.addCheckbox("Station "+i, constrainByStation[i]);
} }
if (this.distortionCalibrationData.hasSmallSensors()) { if (this.distortionCalibrationData.hasSmallSensors()) {
gd.addMessage("Constrain (select/remove all) by High/Low resolution sensors (such as VNIR/LWIR)"); gd.addMessage("Constrain (select/remove all) by High/Low resolution sensors (such as EO/LWIR)");
gd.addCheckbox("Select high-res sensors", true); gd.addCheckbox("Select high-res sensors", true);
gd.addCheckbox("Select low-res sensors", true); gd.addCheckbox("Select low-res sensors", true);
} }
...@@ -2272,7 +2273,7 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit ...@@ -2272,7 +2273,7 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
// sub(other): their group number - no, 0 // sub(other): their group number - no, 0
// not zeroAndOther: // not zeroAndOther:
// non-sub - -1: // non-sub - -1:
// sub(>0): subCam-1 (previous index) - will suggest any with smaller index - may be useless with lwir < vnir indices // sub(>0): subCam-1 (previous index) - will suggest any with smaller index - may be useless with lwir < eo indices
// int subMaxNum = (this.distortionCalibrationData.isSubcameraParameter(parIndex) && (subCam > 0)) ? (zeroAndOther? 0 : (subCam-1)):-1; // int subMaxNum = (this.distortionCalibrationData.isSubcameraParameter(parIndex) && (subCam > 0)) ? (zeroAndOther? 0 : (subCam-1)):-1;
int subMaxNum = -1; int subMaxNum = -1;
if (this.distortionCalibrationData.isSubcameraParameter(parIndex)) { // only for subcamera parameters if (this.distortionCalibrationData.isSubcameraParameter(parIndex)) { // only for subcamera parameters
......
...@@ -989,7 +989,9 @@ horizontal axis: ...@@ -989,7 +989,9 @@ horizontal axis:
// TODO: Set initial values for the goniometer angles from the sensor // TODO: Set initial values for the goniometer angles from the sensor
// (channel) number, average them if there are several in the list // (channel) number, average them if there are several in the list
lensDistortions.LevenbergMarquardt(false); // skip dialog lensDistortions.LevenbergMarquardt(
false, // skip dialog
false); // new: dry_run use it here?
if (debug_level > 0) if (debug_level > 0)
System.out.println("Finished LMA at " System.out.println("Finished LMA at "
+ IJ.d2s(0.000000001 * (System.nanoTime() - startTime), 3)); + IJ.d2s(0.000000001 * (System.nanoTime() - startTime), 3));
......
...@@ -5,9 +5,9 @@ import java.util.Properties; ...@@ -5,9 +5,9 @@ import java.util.Properties;
import com.elphel.imagej.cameras.EyesisSubCameraParameters; import com.elphel.imagej.cameras.EyesisSubCameraParameters;
import com.elphel.imagej.common.WindowTools; import com.elphel.imagej.common.WindowTools;
import Jama.Matrix;
import ij.IJ; import ij.IJ;
import ij.gui.GenericDialog; import ij.gui.GenericDialog;
import Jama.Matrix;
//import EyesisCameraParameters; //import EyesisCameraParameters;
//import Distortions.EyesisSubCameraParameters; //import Distortions.EyesisSubCameraParameters;
...@@ -28,7 +28,7 @@ import Jama.Matrix; ...@@ -28,7 +28,7 @@ import Jama.Matrix;
// boolean cummulativeCorrection=true; // r_xy, r_od for higher terms are relative to lower ones // boolean cummulativeCorrection=true; // r_xy, r_od for higher terms are relative to lower ones
public int defaultLensDistortionModel=200; public int defaultLensDistortionModel=200;
public int lensDistortionModel=defaultLensDistortionModel; public int lensDistortionModel=defaultLensDistortionModel;
public int lensDistortionModelType=0; // set from lensDistortionModel public int lensDistortionModelType=0; // set from lensDistortionModel
boolean cummulativeCorrection=false; //true; // r_xy, r_od for higher terms are relative to lower ones boolean cummulativeCorrection=false; //true; // r_xy, r_od for higher terms are relative to lower ones
public double focalLength=4.5; public double focalLength=4.5;
public double pixelSize= 2.2; //um public double pixelSize= 2.2; //um
...@@ -51,18 +51,18 @@ import Jama.Matrix; ...@@ -51,18 +51,18 @@ import Jama.Matrix;
public double px0=1296.0; // center of the lens on the sensor, pixels 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 py0=968.0; // center of the lens on the sensor, pixels
public boolean flipVertical; // acquired image is mirrored vertically (mirror used) public boolean flipVertical; // acquired image is mirrored vertically (mirror used)
// new non-radial parameters // new non-radial parameters
final private double [][] r_xy_dflt={{0.0,0.0},{0.0,0.0},{0.0,0.0},{0.0,0.0},{0.0,0.0},{0.0,0.0}}; // only 6, as for the first term delta x, delta y ==0 final private double [][] r_xy_dflt={{0.0,0.0},{0.0,0.0},{0.0,0.0},{0.0,0.0},{0.0,0.0},{0.0,0.0}}; // only 6, as for the first term delta x, delta y ==0
final private double [][] r_od_dflt= {{0.0,0.0},{0.0,0.0},{0.0,0.0},{0.0,0.0},{0.0,0.0},{0.0,0.0},{0.0,0.0}}; // ortho final private double [][] r_od_dflt= {{0.0,0.0},{0.0,0.0},{0.0,0.0},{0.0,0.0},{0.0,0.0},{0.0,0.0},{0.0,0.0}}; // ortho
public double [][] r_xy=null; // only 6, as for the first term delta x, delta y ==0 public double [][] r_xy=null; // only 6, as for the first term delta x, delta y ==0
public double [][] r_od=null; // ortho public double [][] r_od=null; // ortho
public double [][] r_xyod=null; //{x0,y0,ortho, diagonal} public double [][] r_xyod=null; //{x0,y0,ortho, diagonal}
// total number of new parameters = 6*2+7+7=26 // total number of new parameters = 6*2+7+7=26
public int debugLevel=1; // was 2 public int debugLevel=1; // was 2
/* /*
Modifying to accommodate for eccentricity of different terms (2 parameters per term) and elliptical shape (another 2 terms). When all are Modifying to accommodate for eccentricity of different terms (2 parameters per term) and elliptical shape (another 2 terms). When all are
...@@ -70,13 +70,13 @@ import Jama.Matrix; ...@@ -70,13 +70,13 @@ import Jama.Matrix;
Rdist/R=A8*R^7+A7*R^6+A6*R^5+A5*R^4+A*R^3+B*R^2+C*R+(1-A6-A7-A6-A5-A-B-C)"); Rdist/R=A8*R^7+A7*R^6+A6*R^5+A5*R^4+A*R^3+B*R^2+C*R+(1-A6-A7-A6-A5-A-B-C)");
Rdist/R=A8*R6^7+A7*R5^6+A6*R4^5+A5*R3^4+A*R2^3+B*R1^2+C*R0+(1-A6-A7-A6-A5-A-B-C)"); Rdist/R=A8*R6^7+A7*R5^6+A6*R4^5+A5*R3^4+A*R2^3+B*R1^2+C*R0+(1-A6-A7-A6-A5-A-B-C)");
R[i] depends on px,py and r_xy[i][], r_o[i] (positive - "landscape", negative - "portrait"), r_d (positive - along y=x, negative - along y=-x) R[i] depends on px,py and r_xy[i][], r_o[i] (positive - "landscape", negative - "portrait"), r_d (positive - along y=x, negative - along y=-x)
R[i] = r0[i]*(1+ (r_od[i][0]*(y[i]**2-x[i]**2)+ 2*r_od[i][1]*x[i]*y[i])/r0[i]**2; R[i] = r0[i]*(1+ (r_od[i][0]*(y[i]**2-x[i]**2)+ 2*r_od[i][1]*x[i]*y[i])/r0[i]**2;
r0[i]=sqrt(x[i]**2+y[2]**2) r0[i]=sqrt(x[i]**2+y[2]**2)
x[i]=pixel_x-px0-((i>0)?r_xy[i-1][0]:0) x[i]=pixel_x-px0-((i>0)?r_xy[i-1][0]:0)
y[i]=pixel_y-py0-((i>0)?r_xy[i-1][1]:0) y[i]=pixel_y-py0-((i>0)?r_xy[i-1][1]:0)
*/ */
// intermediate values // intermediate values
public double phi, theta,psi,cPH,sPH,cTH,sTH,cPS,sPS; public double phi, theta,psi,cPH,sPH,cTH,sTH,cPS,sPS;
public double [][] rotMatrix=new double[3][3]; // includes mirroring for Y (target coordinates y- down, camera - y up) public double [][] rotMatrix=new double[3][3]; // includes mirroring for Y (target coordinates y- down, camera - y up)
...@@ -97,24 +97,25 @@ import Jama.Matrix; ...@@ -97,24 +97,25 @@ import Jama.Matrix;
} }
} }
public LensDistortionParameters( public LensDistortionParameters(
// LensDistortionParameters lensDistortionParameters,
boolean isTripod, boolean isTripod,
boolean cartesian, boolean cartesian,
double pixelSize,
double distortionRadius,
double [][] interParameterDerivatives, //partial derivative matrix from subcamera-camera-goniometer to single camera (12x21) if null - just values, no derivatives double [][] interParameterDerivatives, //partial derivative matrix from subcamera-camera-goniometer to single camera (12x21) if null - just values, no derivatives
double [] parVect, double [] parVect,
boolean [] mask, // calculate only selected derivatives (all parVect values are still boolean [] mask, // calculate only selected derivatives (all parVect values are still
int debugLevel int debugLevel
// boolean calculateDerivatives // calculate this.interParameterDerivatives -derivatives array (false - just this.values)
){ ){
this.debugLevel=debugLevel; this.debugLevel=debugLevel;
lensCalcInterParamers( // changed name to move calcInterParamers method from enclosing class lensCalcInterParamers( // changed name to move calcInterParamers method from enclosing class
this, this,
isTripod, isTripod,
cartesian, cartesian,
pixelSize,
distortionRadius,
interParameterDerivatives, //partial derivative matrix from subcamera-camera-goniometer to single camera (12x21) if null - just values, no derivatives interParameterDerivatives, //partial derivative matrix from subcamera-camera-goniometer to single camera (12x21) if null - just values, no derivatives
parVect, parVect,
mask // calculate only selected derivatives (all parVect values are still mask // calculate only selected derivatives (all parVect values are still
// boolean calculateDerivatives // calculate this.interParameterDerivatives -derivatives array (false - just this.values)
); );
} }
...@@ -141,7 +142,7 @@ import Jama.Matrix; ...@@ -141,7 +142,7 @@ import Jama.Matrix;
double py0, // center of the lens on the sensor, pixels double py0, // center of the lens on the sensor, pixels
boolean flipVertical, // acquired image is mirrored vertically (mirror used) boolean flipVertical, // acquired image is mirrored vertically (mirror used)
int lensDistortionModel, int lensDistortionModel,
double [][] r_xy, double [][] r_xy,
double [][] r_od double [][] r_od
){ ){
setLensDistortionParameters( setLensDistortionParameters(
...@@ -166,10 +167,10 @@ import Jama.Matrix; ...@@ -166,10 +167,10 @@ import Jama.Matrix;
py0, py0,
flipVertical, flipVertical,
lensDistortionModel, lensDistortionModel,
r_xy, r_xy,
r_od); r_od);
} }
public LensDistortionParameters(){ public LensDistortionParameters(){
setLensDistortionParameters( setLensDistortionParameters(
4.5, // focalLength, 4.5, // focalLength,
...@@ -193,10 +194,11 @@ import Jama.Matrix; ...@@ -193,10 +194,11 @@ import Jama.Matrix;
698, // py0, 698, // py0,
true, // flipVertical, true, // flipVertical,
-1, // lensDistortionModel -1, // lensDistortionModel
null, // r_xy, null, // r_xy,
null // r_od, null // r_od,
); );
} }
@Override
public LensDistortionParameters clone() { public LensDistortionParameters clone() {
return new LensDistortionParameters( return new LensDistortionParameters(
this.focalLength, this.focalLength,
...@@ -247,7 +249,7 @@ import Jama.Matrix; ...@@ -247,7 +249,7 @@ import Jama.Matrix;
double py0, // center of the lens on the sensor, pixels double py0, // center of the lens on the sensor, pixels
boolean flipVertical, // acquired image is mirrored vertically (mirror used) boolean flipVertical, // acquired image is mirrored vertically (mirror used)
int lensDistortionModel, int lensDistortionModel,
double [][] r_xy, // per polynomial term center x,y correction only 6, as for the first term delta x, delta y ==0 double [][] r_xy, // per polynomial term center x,y correction only 6, as for the first term delta x, delta y ==0
double [][] r_od // per polynomial term orthogonal+diagonal elongation double [][] r_od // per polynomial term orthogonal+diagonal elongation
){ ){
this.focalLength=focalLength; this.focalLength=focalLength;
...@@ -279,7 +281,7 @@ import Jama.Matrix; ...@@ -279,7 +281,7 @@ import Jama.Matrix;
for (int i=0;i<r_od.length;i++)this.r_od[i]=r_od[i].clone(); for (int i=0;i<r_od.length;i++)this.r_od[i]=r_od[i].clone();
recalcCommons(); recalcCommons();
} }
public void setIntrincicFromSubcamera(EyesisSubCameraParameters pars){ public void setIntrincicFromSubcamera(EyesisSubCameraParameters pars){
setLensDistortionParameters( setLensDistortionParameters(
pars.focalLength, pars.focalLength,
...@@ -308,7 +310,7 @@ import Jama.Matrix; ...@@ -308,7 +310,7 @@ import Jama.Matrix;
pars.r_od // do not exist yet! pars.r_od // do not exist yet!
); );
} }
public void setLensDistortionParameters(LensDistortionParameters ldp public void setLensDistortionParameters(LensDistortionParameters ldp
){ ){
setLensDistortionParameters( setLensDistortionParameters(
...@@ -333,20 +335,20 @@ import Jama.Matrix; ...@@ -333,20 +335,20 @@ import Jama.Matrix;
ldp.py0, ldp.py0,
ldp.flipVertical, ldp.flipVertical,
ldp.lensDistortionModel, ldp.lensDistortionModel,
ldp.r_xy, ldp.r_xy,
ldp.r_od); ldp.r_od);
} }
// TODO: Fix for non-radial !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // TODO: Fix for non-radial !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// just for debugging // just for debugging
public void setLensDistortionParameters(LensDistortionParameters ldp, public void setLensDistortionParameters(LensDistortionParameters ldp,
int index, // parameter to add delta, 1..13->14->17 int index, // parameter to add delta, 1..13->14->17
double delta double delta
){ ){
/* /*
this.focalLength=ldp.focalLength+((index==7)?delta:0); this.focalLength=ldp.focalLength+((index==7)?delta:0);
this.pixelSize=ldp.pixelSize; this.pixelSize=ldp.pixelSize;
this.distortionRadius=ldp.distortionRadius; this.distortionRadius=ldp.distortionRadius;
...@@ -367,12 +369,12 @@ import Jama.Matrix; ...@@ -367,12 +369,12 @@ import Jama.Matrix;
this.px0=ldp.px0+((index==16)?delta:0); this.px0=ldp.px0+((index==16)?delta:0);
this.py0=ldp.py0+((index==17)?delta:0); this.py0=ldp.py0+((index==17)?delta:0);
this.flipVertical=ldp.flipVertical; this.flipVertical=ldp.flipVertical;
*/ */
setLensDistortionParameters(ldp); setLensDistortionParameters(ldp);
final int index_r_xy=18; final int index_r_xy=18;
final int index_r_od=30; final int index_r_od=30;
final int index_end=44; final int index_end=44;
switch (index){ switch (index){
case 1: this.yaw+=delta; break; case 1: this.yaw+=delta; break;
case 2: this.pitch+=delta; break; //=ldp.pitch+((index==2)?delta:0); case 2: this.pitch+=delta; break; //=ldp.pitch+((index==2)?delta:0);
...@@ -400,8 +402,8 @@ import Jama.Matrix; ...@@ -400,8 +402,8 @@ import Jama.Matrix;
} }
recalcCommons(); recalcCommons();
} }
// recalculate common (point-invariant) intermediate values (cos, sin, rotation matrix) // recalculate common (point-invariant) intermediate values (cos, sin, rotation matrix)
public void recalcCommons(){ public void recalcCommons(){
// this.cummulativeCorrection=false; // just debugging // this.cummulativeCorrection=false; // just debugging
...@@ -429,16 +431,16 @@ import Jama.Matrix; ...@@ -429,16 +431,16 @@ import Jama.Matrix;
Ye = (sPS*cPH-cPS*sTH*sPH)*Xp -cPS*cTH*Yp +(-sPS*sPH-cPS*sTH*cPH)*Zp Ye = (sPS*cPH-cPS*sTH*sPH)*Xp -cPS*cTH*Yp +(-sPS*sPH-cPS*sTH*cPH)*Zp
Ze = (cTH*sPH)*Xp -sTH*Yp +( cTH*cPH)* Zp + dist Ze = (cTH*sPH)*Xp -sTH*Yp +( cTH*cPH)* Zp + dist
theta==0, psi==0: theta==0, psi==0:
Xe = (cPH)*Xp Xe = (cPH)*Xp
Ye = Yp Ye = Yp
Ze = cPH* Zp + dist Ze = cPH* Zp + dist
(4) PXmmc =f/(cPH* Zp + dist)* (cPH)*Xp // mm, left from the lens axis intersection with the sensor (4) PXmmc =f/(cPH* Zp + dist)* (cPH)*Xp // mm, left from the lens axis intersection with the sensor
dPXmmc/dphi= dPXmmc/dphi=
*/ */
this.rotMatrix[0][0]= cPS*cPH+sPS*sTH*sPH; this.rotMatrix[0][0]= cPS*cPH+sPS*sTH*sPH;
this.rotMatrix[0][1]= sPS*cTH; this.rotMatrix[0][1]= sPS*cTH;
...@@ -476,7 +478,7 @@ dPXmmc/dphi= ...@@ -476,7 +478,7 @@ dPXmmc/dphi=
} }
} }
} }
private String [][] descriptions= private String [][] descriptions=
{ {
{"distance", "Distance from the intersection of the lens axis with z=0 target plane to the camera lens entrance pupil", "mm", "e"}, {"distance", "Distance from the intersection of the lens axis with z=0 target plane to the camera lens entrance pupil", "mm", "e"},
...@@ -502,7 +504,7 @@ dPXmmc/dphi= ...@@ -502,7 +504,7 @@ dPXmmc/dphi=
{"eccen_B_y", "Distortion center shift Y for r^3", "rel","i"}, {"eccen_B_y", "Distortion center shift Y for r^3", "rel","i"},
{"elong_B_o", "Orthogonal elongation for r^3", "rel","i"}, {"elong_B_o", "Orthogonal elongation for r^3", "rel","i"},
{"elong_B_d", "Diagonal elongation for r^3", "rel","i"}, {"elong_B_d", "Diagonal elongation for r^3", "rel","i"},
{"eccen_A_x", "Distortion center shift X for r^4", "rel","i"}, {"eccen_A_x", "Distortion center shift X for r^4", "rel","i"},
{"eccen_A_y", "Distortion center shift Y for r^4", "rel","i"}, {"eccen_A_y", "Distortion center shift Y for r^4", "rel","i"},
{"elong_A_o", "Orthogonal elongation for r^4", "rel","i"}, {"elong_A_o", "Orthogonal elongation for r^4", "rel","i"},
...@@ -615,7 +617,7 @@ dPXmmc/dphi= ...@@ -615,7 +617,7 @@ dPXmmc/dphi=
public void setAllVector(double [] vector){ public void setAllVector(double [] vector){
if (vector.length!=(getExtrinsicVector().length+getIntrinsicVector().length)){ if (vector.length!=(getExtrinsicVector().length+getIntrinsicVector().length)){
String msg="Parameter vector should have exactly"+(getExtrinsicVector().length+getIntrinsicVector().length)+" elements"; String msg="Parameter vector should have exactly"+(getExtrinsicVector().length+getIntrinsicVector().length)+" elements";
IJ.showMessage("Error",msg); IJ.showMessage("Error",msg);
throw new IllegalArgumentException (msg); throw new IllegalArgumentException (msg);
} }
this.distance= vector[ 0]; this.distance= vector[ 0];
...@@ -655,7 +657,7 @@ dPXmmc/dphi= ...@@ -655,7 +657,7 @@ dPXmmc/dphi=
*/ */
recalcCommons(); recalcCommons();
} }
public String [] getExtrinsicNames() {return getDescriptionStrings("e", 0);} public String [] getExtrinsicNames() {return getDescriptionStrings("e", 0);}
public String [] getExtrinsicDescriptions(){return getDescriptionStrings("e", 1);} public String [] getExtrinsicDescriptions(){return getDescriptionStrings("e", 1);}
public String [] getExtrinsicUnits() {return getDescriptionStrings("e", 2);} public String [] getExtrinsicUnits() {return getDescriptionStrings("e", 2);}
...@@ -673,8 +675,8 @@ dPXmmc/dphi= ...@@ -673,8 +675,8 @@ dPXmmc/dphi=
for (int i=0;i<this.descriptions.length;i++) if (type.indexOf(descriptions[i][3].charAt(0))>=0) s[num++]=this.descriptions[i][var]; for (int i=0;i<this.descriptions.length;i++) if (type.indexOf(descriptions[i][3].charAt(0))>=0) s[num++]=this.descriptions[i][var];
return s; return s;
} }
/* /*
* Calculate pixel value of projection from the pattern point [xp,yp,zp] using current distortion/position parameters * Calculate pixel value of projection from the pattern point [xp,yp,zp] using current distortion/position parameters
(1) Xe = (cPS*cPH+sPS*sTH*sPH)*(Xp-X0) +sPS*cTH*(Yp-Y0) +(-cPS*sPH+sPS*sTH*cPH)*(Zp-Z0) (1) Xe = (cPS*cPH+sPS*sTH*sPH)*(Xp-X0) +sPS*cTH*(Yp-Y0) +(-cPS*sPH+sPS*sTH*cPH)*(Zp-Z0)
...@@ -692,7 +694,7 @@ dPXmmc/dphi= ...@@ -692,7 +694,7 @@ dPXmmc/dphi=
(10) PX = 1000/Psz*( xDist) + PX0 // horizontal pixel of the image (positive - right) (10) PX = 1000/Psz*( xDist) + PX0 // horizontal pixel of the image (positive - right)
(11) PY = 1000/Psz*(-yDist) + PY0 // vertical pixel of the image (positive - down) (11) PY = 1000/Psz*(-yDist) + PY0 // vertical pixel of the image (positive - down)
*/ */
public double [] patternToPixels( public double [] patternToPixels(
double xp, // target point horizontal, positive - right, mm double xp, // target point horizontal, positive - right, mm
...@@ -780,14 +782,14 @@ dPXmmc/dphi= ...@@ -780,14 +782,14 @@ dPXmmc/dphi=
} }
/* /*
* result = {{srcDerivatives[4][0],srcDerivatives[4][1]}, - X0 * result = {{srcDerivatives[4][0],srcDerivatives[4][1]}, - X0
* {srcDerivatives[5][0],srcDerivatives[5][1]} - Y0 * {srcDerivatives[5][0],srcDerivatives[5][1]} - Y0
* {srcDerivatives[8][0],srcDerivatives[8][1]} - dist * {srcDerivatives[8][0],srcDerivatives[8][1]} - dist
* ... * ...
*/ */
/** /**
* Reorder to match the sequence of names - seems to be different :-( * Reorder to match the sequence of names - seems to be different :-(
* @param srcDerivatives values and 15 derivatives for px, py * @param srcDerivatives values and 15 derivatives for px, py
* @return * @return
*/ */
...@@ -811,27 +813,27 @@ dPXmmc/dphi= ...@@ -811,27 +813,27 @@ dPXmmc/dphi=
15, // 15 public double distortionC=0.0; // r^2 15, // 15 public double distortionC=0.0; // r^2
18, // 16 Orthogonal elongation for r^2" 18, // 16 Orthogonal elongation for r^2"
19, // 17 Diagonal elongation for r^2" 19, // 17 Diagonal elongation for r^2"
20, // 18 Distortion center shift X for r^3" 20, // 18 Distortion center shift X for r^3"
21, // 19 Distortion center shift Y for r^3" 21, // 19 Distortion center shift Y for r^3"
22, // 20 Orthogonal elongation for r^3" 22, // 20 Orthogonal elongation for r^3"
23, // 21 Diagonal elongation for r^3" 23, // 21 Diagonal elongation for r^3"
24, // 22 Distortion center shift X for r^4" 24, // 22 Distortion center shift X for r^4"
25, // 23 Distortion center shift Y for r^4" 25, // 23 Distortion center shift Y for r^4"
26, // 24 Orthogonal elongation for r^4" 26, // 24 Orthogonal elongation for r^4"
27, // 25 Diagonal elongation for r^4" 27, // 25 Diagonal elongation for r^4"
28, // 26 Distortion center shift X for r^5" 28, // 26 Distortion center shift X for r^5"
29, // 27 Distortion center shift Y for r^5" 29, // 27 Distortion center shift Y for r^5"
30, // 28 Orthogonal elongation for r^5" 30, // 28 Orthogonal elongation for r^5"
31, // 29 Diagonal elongation for r^5" 31, // 29 Diagonal elongation for r^5"
32, // 30 Distortion center shift X for r^6" 32, // 30 Distortion center shift X for r^6"
33, // 31 Distortion center shift Y for r^6" 33, // 31 Distortion center shift Y for r^6"
34, // 32 Orthogonal elongation for r^6" 34, // 32 Orthogonal elongation for r^6"
35, // 33 Diagonal elongation for r^6" 35, // 33 Diagonal elongation for r^6"
36, // 34 Distortion center shift X for r^7" 36, // 34 Distortion center shift X for r^7"
37, // 35 Distortion center shift Y for r^7" 37, // 35 Distortion center shift Y for r^7"
38, // 36 Orthogonal elongation for r^6" 38, // 36 Orthogonal elongation for r^6"
...@@ -841,7 +843,7 @@ dPXmmc/dphi= ...@@ -841,7 +843,7 @@ dPXmmc/dphi=
41, // 29 Distortion center shift Y for r^8" 41, // 29 Distortion center shift Y for r^8"
42, // 40 Orthogonal elongation for r^8" 42, // 40 Orthogonal elongation for r^8"
43 // 41 Diagonal elongation for r^8" 43 // 41 Diagonal elongation for r^8"
}; };
double [][] result = new double [order.length][2]; double [][] result = new double [order.length][2];
for (int i=0; i<order.length;i++){ for (int i=0; i<order.length;i++){
...@@ -859,21 +861,21 @@ dPXmmc/dphi= ...@@ -859,21 +861,21 @@ dPXmmc/dphi=
this.x0-this.distance*this.rotMatrix[2][0], this.x0-this.distance*this.rotMatrix[2][0],
-this.y0-this.distance*this.rotMatrix[2][1], // this.y0 - up? -this.y0-this.distance*this.rotMatrix[2][1], // this.y0 - up?
this.z0-this.distance*this.rotMatrix[2][2]}; this.z0-this.distance*this.rotMatrix[2][2]};
/* /*
Matrix MR=new Matrix(this.rotMatrix); Matrix MR=new Matrix(this.rotMatrix);
Matrix MRT=MR.transpose(); Matrix MRT=MR.transpose();
Matrix E=MR.times(MRT); Matrix E=MR.times(MRT);
System.out.println("===MR=="); MR.print(8, 5);System.out.println(""); System.out.println("===MR=="); MR.print(8, 5);System.out.println("");
System.out.println("===MRT=="); MRT.print(8, 5);System.out.println(""); System.out.println("===MRT=="); MRT.print(8, 5);System.out.println("");
System.out.println("===E==="); E.print(8, 5);System.out.println(""); System.out.println("===E==="); E.print(8, 5);System.out.println("");
System.out.println("x0="+IJ.d2s(this.x0,1)+" y0="+IJ.d2s(this.y0,1)+" z0="+IJ.d2s(this.z0,1)+" this.distance="+IJ.d2s(this.distance,1)); System.out.println("x0="+IJ.d2s(this.x0,1)+" y0="+IJ.d2s(this.y0,1)+" z0="+IJ.d2s(this.z0,1)+" this.distance="+IJ.d2s(this.distance,1));
System.out.println("phi="+IJ.d2s(this.phi,4)+" theta="+IJ.d2s(this.theta,4)+" psi="+IJ.d2s(this.psi,4)); System.out.println("phi="+IJ.d2s(this.phi,4)+" theta="+IJ.d2s(this.theta,4)+" psi="+IJ.d2s(this.psi,4));
System.out.println("|"+IJ.d2s(this.rotMatrix[0][0],4)+" "+IJ.d2s(this.rotMatrix[0][1],4)+" "+IJ.d2s(this.rotMatrix[0][2],4)+"|"); System.out.println("|"+IJ.d2s(this.rotMatrix[0][0],4)+" "+IJ.d2s(this.rotMatrix[0][1],4)+" "+IJ.d2s(this.rotMatrix[0][2],4)+"|");
System.out.println("|"+IJ.d2s(this.rotMatrix[1][0],4)+" "+IJ.d2s(this.rotMatrix[1][1],4)+" "+IJ.d2s(this.rotMatrix[1][2],4)+"|"); System.out.println("|"+IJ.d2s(this.rotMatrix[1][0],4)+" "+IJ.d2s(this.rotMatrix[1][1],4)+" "+IJ.d2s(this.rotMatrix[1][2],4)+"|");
System.out.println("|"+IJ.d2s(this.rotMatrix[2][0],4)+" "+IJ.d2s(this.rotMatrix[2][1],4)+" "+IJ.d2s(this.rotMatrix[2][2],4)+"|"); System.out.println("|"+IJ.d2s(this.rotMatrix[2][0],4)+" "+IJ.d2s(this.rotMatrix[2][1],4)+" "+IJ.d2s(this.rotMatrix[2][2],4)+"|");
*/ */
return p; return p;
} }
...@@ -951,12 +953,12 @@ dPXmmc/dphi= ...@@ -951,12 +953,12 @@ dPXmmc/dphi=
boolean calculateAll){ // calculate derivatives, false - values only boolean calculateAll){ // calculate derivatives, false - values only
double maxRelativeRadius=2.0; double maxRelativeRadius=2.0;
return calcPartialDerivatives(xp,yp,zp,maxRelativeRadius,calculateAll); return calcPartialDerivatives(xp,yp,zp,maxRelativeRadius,calculateAll);
} }
public double [][] calcPartialDerivatives( public double [][] calcPartialDerivatives(
double xp, // target point horizontal, positive - right, mm double xp, // target point horizontal, positive - right, mm
double yp, // target point vertical, positive - down, mm double yp, // target point vertical, positive - down, mm
double zp, // target point horizontal, positive - away from camera, mm double zp, // target point horizontal, positive - away from camera, mm
double maxRelativeRadius, // make configurable? double maxRelativeRadius, // make configurable?
boolean calculateAll){ // calculate derivatives, false - values only boolean calculateAll){ // calculate derivatives, false - values only
switch (this.lensDistortionModelType){ switch (this.lensDistortionModelType){
case 0: case 0:
...@@ -968,8 +970,8 @@ dPXmmc/dphi= ...@@ -968,8 +970,8 @@ dPXmmc/dphi=
return calcPartialDerivatives_type1(xp,yp,zp,maxRelativeRadius,calculateAll); return calcPartialDerivatives_type1(xp,yp,zp,maxRelativeRadius,calculateAll);
} }
} }
public double [][] calcPartialDerivatives_type1( public double [][] calcPartialDerivatives_type1(
double xp, // target point horizontal, positive - right, mm double xp, // target point horizontal, positive - right, mm
double yp, // target point vertical, positive - down, mm double yp, // target point vertical, positive - down, mm
...@@ -977,7 +979,7 @@ dPXmmc/dphi= ...@@ -977,7 +979,7 @@ dPXmmc/dphi=
double maxRelativeRadius, double maxRelativeRadius,
boolean calculateAll){ // calculate derivatives, false - values only boolean calculateAll){ // calculate derivatives, false - values only
// this.cummulativeCorrection=false; // just debugging // this.cummulativeCorrection=false; // just debugging
// TODO - add reduced calculations for less terms? // TODO - add reduced calculations for less terms?
// final int numDerivatives=44; // 18+6*2+7*2; // 18 for radial and 26 more for non-radial // final int numDerivatives=44; // 18+6*2+7*2; // 18 for radial and 26 more for non-radial
final int numRadialDerivatives=18; final int numRadialDerivatives=18;
...@@ -995,7 +997,7 @@ dPXmmc/dphi= ...@@ -995,7 +997,7 @@ dPXmmc/dphi=
double [] PXYmmc={this.focalLength/XeYeZe[2]*XeYeZe[0],this.focalLength/XeYeZe[2]*XeYeZe[1]}; double [] PXYmmc={this.focalLength/XeYeZe[2]*XeYeZe[0],this.focalLength/XeYeZe[2]*XeYeZe[1]};
// now each term has individual radius // now each term has individual radius
// double [] rr=new double [r_xyod.length]; // double [] rr=new double [r_xyod.length];
// Geometric - get to pinhole coordinates on the sensor // Geometric - get to pinhole coordinates on the sensor
double [][] dXeYeZe=null; //[14]; double [][] dXeYeZe=null; //[14];
double [][] dPXYmmc=null; double [][] dPXYmmc=null;
...@@ -1007,23 +1009,23 @@ dPXmmc/dphi= ...@@ -1007,23 +1009,23 @@ dPXmmc/dphi=
R[i] depends on px,py and r_xy[i][], r_o[i] (positive - "landscape", negative - "portrait"), r_d (positive - along y=x, negative - along y=-x) R[i] depends on px,py and r_xy[i][], r_o[i] (positive - "landscape", negative - "portrait"), r_d (positive - along y=x, negative - along y=-x)
R[i] = r0[i]*(1+ (r_od[i][0]*(y[i]**2-x[i]**2)+ 2*r_od[i][1]*x[i]*y[i])/r0[i]**2; R[i] = r0[i]*(1+ (r_od[i][0]*(y[i]**2-x[i]**2)+ 2*r_od[i][1]*x[i]*y[i])/r0[i]**2;
r0[i]=sqrt(x[i]**2+y[2]**2) r0[i]=sqrt(x[i]**2+y[2]**2)
x[i]=pixel_x-px0-((i>0)?r_xy[i-1][0]:0) x[i]=pixel_x-px0-((i>0)?r_xy[i-1][0]:0)
y[i]=pixel_y-py0-((i>0)?r_xy[i-1][1]:0) y[i]=pixel_y-py0-((i>0)?r_xy[i-1][1]:0)
*/ */
double [] a={this.distortionC,this.distortionB,this.distortionA,this.distortionA5,this.distortionA6,this.distortionA7,this.distortionA8}; double [] a={this.distortionC,this.distortionB,this.distortionA,this.distortionA5,this.distortionA6,this.distortionA7,this.distortionA8};
double deltaX=0.0,deltaY=0.0; // difference between distorted and non-distorted as a fraction of this.distortionRadius double deltaX=0.0,deltaY=0.0; // difference between distorted and non-distorted as a fraction of this.distortionRadius
double xmmc=PXYmmc[0]/this.distortionRadius; double xmmc=PXYmmc[0]/this.distortionRadius;
double ymmc=PXYmmc[1]/this.distortionRadius; double ymmc=PXYmmc[1]/this.distortionRadius;
double dDeltaX_dxmmc=0.0, dDeltaX_dymmc=0.0, dDeltaY_dxmmc=0.0, dDeltaY_dymmc=0; double dDeltaX_dxmmc=0.0, dDeltaX_dymmc=0.0, dDeltaY_dxmmc=0.0, dDeltaY_dymmc=0;
if (calculateAll){ if (calculateAll){
for (double [] r:partDeriv) Arrays.fill(r, 0.0); // will fill the [0] (value) too, should be done before calculation of these 2 values for (double [] r:partDeriv) Arrays.fill(r, 0.0); // will fill the [0] (value) too, should be done before calculation of these 2 values
// Geometric - get to pinhole coordinates on the sensor // Geometric - get to pinhole coordinates on the sensor
dXeYeZe=new double[9][3]; //[14]; dXeYeZe=new double[9][3]; //[14];
// Geometric - get to pinhole coordinates on the sensor // Geometric - get to pinhole coordinates on the sensor
dXeYeZe[0][0]=XeYeZe[0]; dXeYeZe[0][0]=XeYeZe[0];
dXeYeZe[0][1]=XeYeZe[1]; dXeYeZe[0][1]=XeYeZe[1];
dXeYeZe[0][2]=XeYeZe[2]; dXeYeZe[0][2]=XeYeZe[2];
// /dphi // /dphi
dXeYeZe[1][0]=(-cPS*sPH + sPS*sTH*cPH)*XYZ[0] +(-cPS*cPH-sPS*sTH*sPH)*XYZ[2]; dXeYeZe[1][0]=(-cPS*sPH + sPS*sTH*cPH)*XYZ[0] +(-cPS*cPH-sPS*sTH*sPH)*XYZ[2];
dXeYeZe[1][1]=(-sPS*sPH-cPS*sTH*cPH) *XYZ[0] +(-sPS*cPH+cPS*sTH*sPH)*XYZ[2]; dXeYeZe[1][1]=(-sPS*sPH-cPS*sTH*cPH) *XYZ[0] +(-sPS*cPH+cPS*sTH*sPH)*XYZ[2];
dXeYeZe[1][2]=(cTH*cPH)*XYZ[0] -cTH*sPH* XYZ[2]; dXeYeZe[1][2]=(cTH*cPH)*XYZ[0] -cTH*sPH* XYZ[2];
...@@ -1031,7 +1033,7 @@ dPXmmc/dphi= ...@@ -1031,7 +1033,7 @@ dPXmmc/dphi=
dXeYeZe[2][0]=(sPS*cTH*sPH)*XYZ[0] -sPS*sTH*XYZ[1] +(sPS*cTH*cPH)*XYZ[2]; dXeYeZe[2][0]=(sPS*cTH*sPH)*XYZ[0] -sPS*sTH*XYZ[1] +(sPS*cTH*cPH)*XYZ[2];
dXeYeZe[2][1]=(-cPS*cTH*sPH)*XYZ[0] +cPS*sTH*XYZ[1] +(-cPS*cTH*cPH)*XYZ[2]; dXeYeZe[2][1]=(-cPS*cTH*sPH)*XYZ[0] +cPS*sTH*XYZ[1] +(-cPS*cTH*cPH)*XYZ[2];
dXeYeZe[2][2]=(-sTH*sPH)*XYZ[0] -cTH*XYZ[1] -sTH*cPH* XYZ[2]; dXeYeZe[2][2]=(-sTH*sPH)*XYZ[0] -cTH*XYZ[1] -sTH*cPH* XYZ[2];
// /dpsi // /dpsi
dXeYeZe[3][0]=(-sPS*cPH+cPS*sTH*sPH)*XYZ[0] +cPS*cTH*XYZ[1] +(sPS*sPH+cPS*sTH*cPH)*XYZ[2]; dXeYeZe[3][0]=(-sPS*cPH+cPS*sTH*sPH)*XYZ[0] +cPS*cTH*XYZ[1] +(sPS*sPH+cPS*sTH*cPH)*XYZ[2];
dXeYeZe[3][1]=(cPS*cPH+ sPS*sTH*sPH)*XYZ[0] +sPS*cTH*XYZ[1] +(-cPS*sPH+sPS*sTH*cPH)*XYZ[2]; dXeYeZe[3][1]=(cPS*cPH+ sPS*sTH*sPH)*XYZ[0] +sPS*cTH*XYZ[1] +(-cPS*sPH+sPS*sTH*cPH)*XYZ[2];
dXeYeZe[3][2]=0.0; dXeYeZe[3][2]=0.0;
...@@ -1060,15 +1062,15 @@ dPXmmc/dphi= ...@@ -1060,15 +1062,15 @@ dPXmmc/dphi=
dXeYeZe[8][0]=0.0; dXeYeZe[8][0]=0.0;
dXeYeZe[8][1]=0.0; dXeYeZe[8][1]=0.0;
dXeYeZe[8][2]=1.0; dXeYeZe[8][2]=1.0;
dPXYmmc=new double[9][2]; //[14]; dPXYmmc=new double[9][2]; //[14];
// TODO: move up // TODO: move up
// double [][] dPXYmmc=new double[9][2]; //[14]; // double [][] dPXYmmc=new double[9][2]; //[14];
dPXYmmc[0][0]=PXYmmc[0]; // is it needed? probably not used dPXYmmc[0][0]=PXYmmc[0]; // is it needed? probably not used
dPXYmmc[0][1]=PXYmmc[1]; dPXYmmc[0][1]=PXYmmc[1];
//(4) PXmmc =f/Ze* Xe // mm, left from the lens axis intersection with the sensor //(4) PXmmc =f/Ze* Xe // mm, left from the lens axis intersection with the sensor
//dPXmmc/dphi = f/Ze * dXe/dphi - f*Xe/Ze^2 * dZe/dphi //dPXmmc/dphi = f/Ze * dXe/dphi - f*Xe/Ze^2 * dZe/dphi
dPXYmmc[1][0]=this.focalLength/dXeYeZe[0][2]*(dXeYeZe[1][0]-dXeYeZe[0][0]/dXeYeZe[0][2]*dXeYeZe[1][2]); dPXYmmc[1][0]=this.focalLength/dXeYeZe[0][2]*(dXeYeZe[1][0]-dXeYeZe[0][0]/dXeYeZe[0][2]*dXeYeZe[1][2]);
//dPXmmc/dtheta = f/Ze * dXe/dtheta - f*Xe/Ze^2 * dZe/dtheta //dPXmmc/dtheta = f/Ze * dXe/dtheta - f*Xe/Ze^2 * dZe/dtheta
...@@ -1103,14 +1105,14 @@ dPXmmc/dphi= ...@@ -1103,14 +1105,14 @@ dPXmmc/dphi=
dPXYmmc[7][1]=dXeYeZe[0][1]/dXeYeZe[0][2]; dPXYmmc[7][1]=dXeYeZe[0][1]/dXeYeZe[0][2];
//dPYmmc/ddist = - f*Ye/Ze^2 //dPYmmc/ddist = - f*Ye/Ze^2
dPXYmmc[8][1]=-this.focalLength*dXeYeZe[0][1]/(dXeYeZe[0][2]*dXeYeZe[0][2]); dPXYmmc[8][1]=-this.focalLength*dXeYeZe[0][1]/(dXeYeZe[0][2]*dXeYeZe[0][2]);
} }
// conversion coefficient from relative (to distortionRadius) to pixels // conversion coefficient from relative (to distortionRadius) to pixels
// negate for y! // negate for y!
double rel_to_pix=this.distortionRadius*1000.0/this.pixelSize; double rel_to_pix=this.distortionRadius*1000.0/this.pixelSize;
//TODO: seems that rr[i] can be just a single running variable, not an array //TODO: seems that rr[i] can be just a single running variable, not an array
for (int i=0;i<r_xyod.length;i++){ for (int i=0;i<r_xyod.length;i++){
double x=xmmc-r_xyod[i][0]; // relative X-shift of this term center double x=xmmc-r_xyod[i][0]; // relative X-shift of this term center
double y=ymmc-r_xyod[i][1]; // relative X-shift of this term center double y=ymmc-r_xyod[i][1]; // relative X-shift of this term center
double x2=x*x; // relative squared X-shift from this term center double x2=x*x; // relative squared X-shift from this term center
...@@ -1134,19 +1136,19 @@ dPXmmc/dphi= ...@@ -1134,19 +1136,19 @@ dPXmmc/dphi=
// double dx2_dxmmc=2*x, dy2_dymmc=2*y, dr2_dxmmc=2*x, dr2_dymmc=2*y; // double dx2_dxmmc=2*x, dy2_dymmc=2*y, dr2_dxmmc=2*x, dr2_dymmc=2*y;
// double drr_dxmmc=0.5/rr*(dr2_dxmmc+ r_xyod[i][2]*(-dx2_dxmmc)+2*r_xyod[i][3]*y)=0.5/rr*(2*x - 2*x*r_xyod[i][2]+2*r_xyod[i][3]*y)= // double drr_dxmmc=0.5/rr*(dr2_dxmmc+ r_xyod[i][2]*(-dx2_dxmmc)+2*r_xyod[i][3]*y)=0.5/rr*(2*x - 2*x*r_xyod[i][2]+2*r_xyod[i][3]*y)=
// = (x*(1.0-r_xyod[i][2])+y*r_xyod[i][3])/rr // = (x*(1.0-r_xyod[i][2])+y*r_xyod[i][3])/rr
// double drr_dymmc= (y*(1.0+r_xyod[i][2])+x*r_xyod[i][3])/rr // double drr_dymmc= (y*(1.0+r_xyod[i][2])+x*r_xyod[i][3])/rr
// double ki=a[i]*(rr^(i+1)-1.0); // double ki=a[i]*(rr^(i+1)-1.0);
// double dki_dxmmc=a[i]*(i+1)*rr^i*(x*(1.0-r_xyod[i][2])+y*r_xyod[i][3])/rr // double dki_dxmmc=a[i]*(i+1)*rr^i*(x*(1.0-r_xyod[i][2])+y*r_xyod[i][3])/rr
// double dki_dymmc=a[i]*(i+1)*rr^i*(y*(1.0+r_xyod[i][2])+x*r_xyod[i][3])/rr // double dki_dymmc=a[i]*(i+1)*rr^i*(y*(1.0+r_xyod[i][2])+x*r_xyod[i][3])/rr
// double dki_dxmmc=a[i]*(i+1)*rr_pow_i*(x*(1.0-r_xyod[i][2])+y*r_xyod[i][3])/rr // double dki_dxmmc=a[i]*(i+1)*rr_pow_i*(x*(1.0-r_xyod[i][2])+y*r_xyod[i][3])/rr
// double dki_dymmc=a[i]*(i+1)*rr_pow_i*(y*(1.0+r_xyod[i][2])+x*r_xyod[i][3])/rr // double dki_dymmc=a[i]*(i+1)*rr_pow_i*(y*(1.0+r_xyod[i][2])+x*r_xyod[i][3])/rr
double ai_iplus1_rr_pow_i= a[i]*(i+1)*rr_pow_i; double ai_iplus1_rr_pow_i= a[i]*(i+1)*rr_pow_i;
double dki_dxmmc= ai_iplus1_rr_pow_i*(x*(1.0-r_xyod[i][2])+y*r_xyod[i][3])/rr; double dki_dxmmc= ai_iplus1_rr_pow_i*(x*(1.0-r_xyod[i][2])+y*r_xyod[i][3])/rr;
double dki_dymmc= ai_iplus1_rr_pow_i*(y*(1.0+r_xyod[i][2])+x*r_xyod[i][3])/rr; double dki_dymmc= ai_iplus1_rr_pow_i*(y*(1.0+r_xyod[i][2])+x*r_xyod[i][3])/rr;
// the following 4 shifts are "extra", on top of non-distorted (pinhole) - pinhole should be added to the per-term sum // the following 4 shifts are "extra", on top of non-distorted (pinhole) - pinhole should be added to the per-term sum
double dDeltaXi_dxmmc = ki+x*dki_dxmmc; // here dDelta*_d*mmc are relative (both I/O are fractions of distortionRadius) double dDeltaXi_dxmmc = ki+x*dki_dxmmc; // here dDelta*_d*mmc are relative (both I/O are fractions of distortionRadius)
double dDeltaXi_dymmc = x*dki_dymmc; double dDeltaXi_dymmc = x*dki_dymmc;
...@@ -1168,7 +1170,7 @@ dPXmmc/dphi= ...@@ -1168,7 +1170,7 @@ dPXmmc/dphi=
partDeriv[index+1][0]= -rel_to_pix* dDeltaXi_dymmc; // dPx_dr_xyod1 partDeriv[index+1][0]= -rel_to_pix* dDeltaXi_dymmc; // dPx_dr_xyod1
partDeriv[index+1][1]= rel_to_pix*(dDeltaYi_dymmc-0.0); // dPy_dr_xyod1 partDeriv[index+1][1]= rel_to_pix*(dDeltaYi_dymmc-0.0); // dPy_dr_xyod1
} }
// d/dai // d/dai
// ki=a[i]*(rr_pow_i*rr-1.0); // ki=a[i]*(rr_pow_i*rr-1.0);
// double dki_dai=(rr_pow_i*rr-1.0); // double dki_dai=(rr_pow_i*rr-1.0);
...@@ -1178,7 +1180,7 @@ dPXmmc/dphi= ...@@ -1178,7 +1180,7 @@ dPXmmc/dphi=
index= distortionCIndex-i; // reverse order, // a8->9, a7->10, a6->11, a5->12, a->13, b->14, c->15 index= distortionCIndex-i; // reverse order, // a8->9, a7->10, a6->11, a5->12, a->13, b->14, c->15
partDeriv[index][0]= rel_to_pix*x*(rr_pow_i*rr-1.0); // OK partDeriv[index][0]= rel_to_pix*x*(rr_pow_i*rr-1.0); // OK
partDeriv[index][1]=-rel_to_pix*y*(rr_pow_i*rr-1.0); // OK partDeriv[index][1]=-rel_to_pix*y*(rr_pow_i*rr-1.0); // OK
// d/dr_xyod[0] (x shift of the center // d/dr_xyod[0] (x shift of the center
// rr=Math.sqrt(r2+ r_xyod[i][2]*(y2-x2)+ 2.0*r_xyod[i][3]*x*y ); // rr=Math.sqrt(r2+ r_xyod[i][2]*(y2-x2)+ 2.0*r_xyod[i][3]*x*y );
// ki=a[i]*(rr_pow_i*rr-1.0); // ki=a[i]*(rr_pow_i*rr-1.0);
...@@ -1212,7 +1214,7 @@ dPXmmc/dphi= ...@@ -1212,7 +1214,7 @@ dPXmmc/dphi=
// dki_dri=a[i]*(i+1)*rr^i = a[i]*(i+1)*rr_pow_i // dki_dri=a[i]*(i+1)*rr^i = a[i]*(i+1)*rr_pow_i
// dDeltaX_dri=x*a[i]*(i+1)*rr_pow_i // dDeltaX_dri=x*a[i]*(i+1)*rr_pow_i
// dDeltaY_dri=y*a[i]*(i+1)*rr_pow_i // dDeltaY_dri=y*a[i]*(i+1)*rr_pow_i
// dPx_dri= rel_to_pix*x*a[i]*(i+1)*rr_pow_i = csi*x // dPx_dri= rel_to_pix*x*a[i]*(i+1)*rr_pow_i = csi*x
// dPy_dri=-rel_to_pix*y*a[i]*(i+1)*rr_pow_i = -csi*y // dPy_dri=-rel_to_pix*y*a[i]*(i+1)*rr_pow_i = -csi*y
// dPx_dr_xyod0= dPx_dri*dri_dr_xyod0= csi*x*dri_dr_xyod0; // dPx_dr_xyod0= dPx_dri*dri_dr_xyod0= csi*x*dri_dr_xyod0;
// dPx_dr_xyod1= dPx_dri*dri_dr_xyod1= csi*x*dri_dr_xyod1; // dPx_dr_xyod1= dPx_dri*dri_dr_xyod1= csi*x*dri_dr_xyod1;
...@@ -1235,15 +1237,15 @@ dPXmmc/dphi= ...@@ -1235,15 +1237,15 @@ dPXmmc/dphi=
partDeriv[index+2][1]=-csi*y*dri_dr_xyod2; // dPy_dr_xyod2 partDeriv[index+2][1]=-csi*y*dri_dr_xyod2; // dPy_dr_xyod2
partDeriv[index+3][0]= csi*x*dri_dr_xyod3; // dPx_dr_xyod3 partDeriv[index+3][0]= csi*x*dri_dr_xyod3; // dPx_dr_xyod3
partDeriv[index+3][1]=-csi*y*dri_dr_xyod3; // dPy_dr_xyod3 partDeriv[index+3][1]=-csi*y*dri_dr_xyod3; // dPy_dr_xyod3
} }
} }
double [] xyDist={PXYmmc[0]+this.distortionRadius*deltaX,PXYmmc[1]+this.distortionRadius*deltaY}; double [] xyDist={PXYmmc[0]+this.distortionRadius*deltaX,PXYmmc[1]+this.distortionRadius*deltaY};
// convert to sensor pixels coordinates // convert to sensor pixels coordinates
partDeriv[0][0]= 1000.0/this.pixelSize*xyDist[0] + this.px0; partDeriv[0][0]= 1000.0/this.pixelSize*xyDist[0] + this.px0;
partDeriv[0][1]= -1000.0/this.pixelSize*xyDist[1] + this.py0; partDeriv[0][1]= -1000.0/this.pixelSize*xyDist[1] + this.py0;
if (!calculateAll) { // TODO: how to deal with it when calculating Jacobian??? if (!calculateAll) { // TODO: how to deal with it when calculating Jacobian???
// TODO: Looking away from the target, trying only with no dervatives. Do the same for derivatives too? // TODO: Looking away from the target, trying only with no dervatives. Do the same for derivatives too?
if ((XeYeZe[2]<0.0) || ((xmmc*xmmc+ymmc*ymmc)>maxRelativeRadius*maxRelativeRadius)){ // non-distorted too far from the axis if ((XeYeZe[2]<0.0) || ((xmmc*xmmc+ymmc*ymmc)>maxRelativeRadius*maxRelativeRadius)){ // non-distorted too far from the axis
...@@ -1261,16 +1263,16 @@ dPXmmc/dphi= ...@@ -1261,16 +1263,16 @@ dPXmmc/dphi=
partDeriv[index ][1]+=partDeriv[index+4][1]; partDeriv[index ][1]+=partDeriv[index+4][1];
partDeriv[index+1][0]+=partDeriv[index+5][0]; partDeriv[index+1][0]+=partDeriv[index+5][0];
partDeriv[index+1][1]+=partDeriv[index+5][1]; partDeriv[index+1][1]+=partDeriv[index+5][1];
} }
partDeriv[index+2][0]+=partDeriv[index+6][0]; partDeriv[index+2][0]+=partDeriv[index+6][0];
partDeriv[index+2][1]+=partDeriv[index+6][1]; partDeriv[index+2][1]+=partDeriv[index+6][1];
partDeriv[index+3][0]+=partDeriv[index+7][0]; partDeriv[index+3][0]+=partDeriv[index+7][0];
partDeriv[index+3][1]+=partDeriv[index+7][1]; partDeriv[index+3][1]+=partDeriv[index+7][1];
} }
} }
// convert dDelta*_d*mmc from relative/relative to pix/mm (invert pixel Y direction) // convert dDelta*_d*mmc from relative/relative to pix/mm (invert pixel Y direction)
// added 1.0 to account for non-distorted (pinhole) shift // added 1.0 to account for non-distorted (pinhole) shift
double dPx_dPinholeX= (1.0+dDeltaX_dxmmc)*1000.0/this.pixelSize; double dPx_dPinholeX= (1.0+dDeltaX_dxmmc)*1000.0/this.pixelSize;
double dPx_dPinholeY= dDeltaX_dymmc*1000.0/this.pixelSize; double dPx_dPinholeY= dDeltaX_dymmc*1000.0/this.pixelSize;
double dPy_dPinholeX= -dDeltaY_dxmmc*1000.0/this.pixelSize; double dPy_dPinholeX= -dDeltaY_dxmmc*1000.0/this.pixelSize;
...@@ -1281,12 +1283,12 @@ dPXmmc/dphi= ...@@ -1281,12 +1283,12 @@ dPXmmc/dphi=
System.out.println(" dDeltaX_dxmmc="+dDeltaX_dxmmc+" dDeltaX_dymmc="+dDeltaX_dymmc+" dDeltaY_dxmmc="+dDeltaY_dxmmc+" dDeltaY_dymmc"+dDeltaY_dymmc); System.out.println(" dDeltaX_dxmmc="+dDeltaX_dxmmc+" dDeltaX_dymmc="+dDeltaX_dymmc+" dDeltaY_dxmmc="+dDeltaY_dxmmc+" dDeltaY_dymmc"+dDeltaY_dymmc);
System.out.println(" dPx_dPinholeX="+dPx_dPinholeX+" dPx_dPinholeY="+dPx_dPinholeY+" dPy_dPinholeX="+dPy_dPinholeX+" dPy_dPinholeY"+dPy_dPinholeY); System.out.println(" dPx_dPinholeX="+dPx_dPinholeX+" dPx_dPinholeY="+dPx_dPinholeY+" dPy_dPinholeX="+dPy_dPinholeX+" dPy_dPinholeY"+dPy_dPinholeY);
} }
double K=Math.PI/180; // multiply all derivatives my angles double K=Math.PI/180; // multiply all derivatives my angles
// dPX/dphi = 1000/Psz* dxDist/dphi // dPX/dphi = 1000/Psz* dxDist/dphi
partDeriv[ 1][0]= K*(dPx_dPinholeX*dPXYmmc[1][0]+dPx_dPinholeY*dPXYmmc[1][1]); partDeriv[ 1][0]= K*(dPx_dPinholeX*dPXYmmc[1][0]+dPx_dPinholeY*dPXYmmc[1][1]);
partDeriv[ 1][1]= K*(dPy_dPinholeX*dPXYmmc[1][0]+dPy_dPinholeY*dPXYmmc[1][1]); partDeriv[ 1][1]= K*(dPy_dPinholeX*dPXYmmc[1][0]+dPy_dPinholeY*dPXYmmc[1][1]);
// dPX/dtheta = 1000/Psz* dxDist/dtheta // dPX/dtheta = 1000/Psz* dxDist/dtheta
partDeriv[ 2][0]= K*(dPx_dPinholeX*dPXYmmc[2][0]+dPx_dPinholeY*dPXYmmc[2][1]); partDeriv[ 2][0]= K*(dPx_dPinholeX*dPXYmmc[2][0]+dPx_dPinholeY*dPXYmmc[2][1]);
partDeriv[ 2][1]= K*(dPy_dPinholeX*dPXYmmc[2][0]+dPy_dPinholeY*dPXYmmc[2][1]); partDeriv[ 2][1]= K*(dPy_dPinholeX*dPXYmmc[2][0]+dPy_dPinholeY*dPXYmmc[2][1]);
...@@ -1308,7 +1310,7 @@ dPXmmc/dphi= ...@@ -1308,7 +1310,7 @@ dPXmmc/dphi=
// dPX/ddist = 1000/Psz* dxDist/ddist // dPX/ddist = 1000/Psz* dxDist/ddist
partDeriv[ 8][0]= dPx_dPinholeX*dPXYmmc[8][0]+dPx_dPinholeY*dPXYmmc[8][1]; partDeriv[ 8][0]= dPx_dPinholeX*dPXYmmc[8][0]+dPx_dPinholeY*dPXYmmc[8][1];
partDeriv[ 8][1]= dPy_dPinholeX*dPXYmmc[8][0]+dPy_dPinholeY*dPXYmmc[8][1]; partDeriv[ 8][1]= dPy_dPinholeX*dPXYmmc[8][0]+dPy_dPinholeY*dPXYmmc[8][1];
// dPX/dPX0 = 1 // dPX/dPX0 = 1
// dPY/dPX0 = 0 // dPY/dPX0 = 0
partDeriv[16][0]= 1.0; partDeriv[16][0]= 1.0;
...@@ -1319,7 +1321,7 @@ dPXmmc/dphi= ...@@ -1319,7 +1321,7 @@ dPXmmc/dphi=
partDeriv[17][1]= 1.0; partDeriv[17][1]= 1.0;
return partDeriv; return partDeriv;
} }
public double [][] calcPartialDerivatives_type2( public double [][] calcPartialDerivatives_type2(
double xp, // target point horizontal, positive - right, mm double xp, // target point horizontal, positive - right, mm
double yp, // target point vertical, positive - down, mm double yp, // target point vertical, positive - down, mm
...@@ -1327,7 +1329,7 @@ dPXmmc/dphi= ...@@ -1327,7 +1329,7 @@ dPXmmc/dphi=
double maxRelativeRadius, double maxRelativeRadius,
boolean calculateAll){ // calculate derivatives, false - values only boolean calculateAll){ // calculate derivatives, false - values only
// this.cummulativeCorrection=false; // just debugging // this.cummulativeCorrection=false; // just debugging
// TODO - add reduced calculations for less terms? // TODO - add reduced calculations for less terms?
// final int numDerivatives=44; // 18+6*2+7*2; // 18 for radial and 26 more for non-radial // final int numDerivatives=44; // 18+6*2+7*2; // 18 for radial and 26 more for non-radial
final int numRadialDerivatives=18; final int numRadialDerivatives=18;
...@@ -1345,7 +1347,7 @@ dPXmmc/dphi= ...@@ -1345,7 +1347,7 @@ dPXmmc/dphi=
double [] PXYmmc={this.focalLength/XeYeZe[2]*XeYeZe[0],this.focalLength/XeYeZe[2]*XeYeZe[1]}; double [] PXYmmc={this.focalLength/XeYeZe[2]*XeYeZe[0],this.focalLength/XeYeZe[2]*XeYeZe[1]};
// now each term has individual radius // now each term has individual radius
// double [] rr=new double [r_xyod.length]; // double [] rr=new double [r_xyod.length];
// Geometric - get to pinhole coordinates on the sensor // Geometric - get to pinhole coordinates on the sensor
double [][] dXeYeZe=null; //[14]; double [][] dXeYeZe=null; //[14];
double [][] dPXYmmc=null; double [][] dPXYmmc=null;
...@@ -1357,23 +1359,23 @@ dPXmmc/dphi= ...@@ -1357,23 +1359,23 @@ dPXmmc/dphi=
R[i] depends on px,py and r_xy[i][], r_o[i] (positive - "landscape", negative - "portrait"), r_d (positive - along y=x, negative - along y=-x) R[i] depends on px,py and r_xy[i][], r_o[i] (positive - "landscape", negative - "portrait"), r_d (positive - along y=x, negative - along y=-x)
R[i] = r0[i]*(1+ (r_od[i][0]*(y[i]**2-x[i]**2)+ 2*r_od[i][1]*x[i]*y[i])/r0[i]**2; R[i] = r0[i]*(1+ (r_od[i][0]*(y[i]**2-x[i]**2)+ 2*r_od[i][1]*x[i]*y[i])/r0[i]**2;
r0[i]=sqrt(x[i]**2+y[2]**2) r0[i]=sqrt(x[i]**2+y[2]**2)
x[i]=pixel_x-px0-((i>0)?r_xy[i-1][0]:0) x[i]=pixel_x-px0-((i>0)?r_xy[i-1][0]:0)
y[i]=pixel_y-py0-((i>0)?r_xy[i-1][1]:0) y[i]=pixel_y-py0-((i>0)?r_xy[i-1][1]:0)
*/ */
double [] a={this.distortionC,this.distortionB,this.distortionA,this.distortionA5,this.distortionA6,this.distortionA7,this.distortionA8}; double [] a={this.distortionC,this.distortionB,this.distortionA,this.distortionA5,this.distortionA6,this.distortionA7,this.distortionA8};
double deltaX=0.0,deltaY=0.0; // difference between distorted and non-distorted as a fraction of this.distortionRadius double deltaX=0.0,deltaY=0.0; // difference between distorted and non-distorted as a fraction of this.distortionRadius
double x=PXYmmc[0]/this.distortionRadius; // was xmmc double x=PXYmmc[0]/this.distortionRadius; // was xmmc
double y=PXYmmc[1]/this.distortionRadius; // was ymmc double y=PXYmmc[1]/this.distortionRadius; // was ymmc
double dDeltaX_dx=0.0, dDeltaX_dy=0.0, dDeltaY_dx=0.0, dDeltaY_dy=0; double dDeltaX_dx=0.0, dDeltaX_dy=0.0, dDeltaY_dx=0.0, dDeltaY_dy=0;
if (calculateAll){ if (calculateAll){
for (double [] r:partDeriv) Arrays.fill(r, 0.0); // will fill the [0] (value) too, should be done before calculation of these 2 values for (double [] r:partDeriv) Arrays.fill(r, 0.0); // will fill the [0] (value) too, should be done before calculation of these 2 values
// Geometric - get to pinhole coordinates on the sensor // Geometric - get to pinhole coordinates on the sensor
dXeYeZe=new double[9][3]; //[14]; dXeYeZe=new double[9][3]; //[14];
// Geometric - get to pinhole coordinates on the sensor // Geometric - get to pinhole coordinates on the sensor
dXeYeZe[0][0]=XeYeZe[0]; dXeYeZe[0][0]=XeYeZe[0];
dXeYeZe[0][1]=XeYeZe[1]; dXeYeZe[0][1]=XeYeZe[1];
dXeYeZe[0][2]=XeYeZe[2]; dXeYeZe[0][2]=XeYeZe[2];
// /dphi // /dphi
dXeYeZe[1][0]=(-cPS*sPH + sPS*sTH*cPH)*XYZ[0] +(-cPS*cPH-sPS*sTH*sPH)*XYZ[2]; dXeYeZe[1][0]=(-cPS*sPH + sPS*sTH*cPH)*XYZ[0] +(-cPS*cPH-sPS*sTH*sPH)*XYZ[2];
dXeYeZe[1][1]=(-sPS*sPH-cPS*sTH*cPH) *XYZ[0] +(-sPS*cPH+cPS*sTH*sPH)*XYZ[2]; dXeYeZe[1][1]=(-sPS*sPH-cPS*sTH*cPH) *XYZ[0] +(-sPS*cPH+cPS*sTH*sPH)*XYZ[2];
dXeYeZe[1][2]=(cTH*cPH)*XYZ[0] -cTH*sPH* XYZ[2]; dXeYeZe[1][2]=(cTH*cPH)*XYZ[0] -cTH*sPH* XYZ[2];
...@@ -1381,7 +1383,7 @@ dPXmmc/dphi= ...@@ -1381,7 +1383,7 @@ dPXmmc/dphi=
dXeYeZe[2][0]=(sPS*cTH*sPH)*XYZ[0] -sPS*sTH*XYZ[1] +(sPS*cTH*cPH)*XYZ[2]; dXeYeZe[2][0]=(sPS*cTH*sPH)*XYZ[0] -sPS*sTH*XYZ[1] +(sPS*cTH*cPH)*XYZ[2];
dXeYeZe[2][1]=(-cPS*cTH*sPH)*XYZ[0] +cPS*sTH*XYZ[1] +(-cPS*cTH*cPH)*XYZ[2]; dXeYeZe[2][1]=(-cPS*cTH*sPH)*XYZ[0] +cPS*sTH*XYZ[1] +(-cPS*cTH*cPH)*XYZ[2];
dXeYeZe[2][2]=(-sTH*sPH)*XYZ[0] -cTH*XYZ[1] -sTH*cPH* XYZ[2]; dXeYeZe[2][2]=(-sTH*sPH)*XYZ[0] -cTH*XYZ[1] -sTH*cPH* XYZ[2];
// /dpsi // /dpsi
dXeYeZe[3][0]=(-sPS*cPH+cPS*sTH*sPH)*XYZ[0] +cPS*cTH*XYZ[1] +(sPS*sPH+cPS*sTH*cPH)*XYZ[2]; dXeYeZe[3][0]=(-sPS*cPH+cPS*sTH*sPH)*XYZ[0] +cPS*cTH*XYZ[1] +(sPS*sPH+cPS*sTH*cPH)*XYZ[2];
dXeYeZe[3][1]=(cPS*cPH+ sPS*sTH*sPH)*XYZ[0] +sPS*cTH*XYZ[1] +(-cPS*sPH+sPS*sTH*cPH)*XYZ[2]; dXeYeZe[3][1]=(cPS*cPH+ sPS*sTH*sPH)*XYZ[0] +sPS*cTH*XYZ[1] +(-cPS*sPH+sPS*sTH*cPH)*XYZ[2];
dXeYeZe[3][2]=0.0; dXeYeZe[3][2]=0.0;
...@@ -1410,15 +1412,15 @@ dPXmmc/dphi= ...@@ -1410,15 +1412,15 @@ dPXmmc/dphi=
dXeYeZe[8][0]=0.0; dXeYeZe[8][0]=0.0;
dXeYeZe[8][1]=0.0; dXeYeZe[8][1]=0.0;
dXeYeZe[8][2]=1.0; dXeYeZe[8][2]=1.0;
dPXYmmc=new double[9][2]; //[14]; dPXYmmc=new double[9][2]; //[14];
// TODO: move up // TODO: move up
// double [][] dPXYmmc=new double[9][2]; //[14]; // double [][] dPXYmmc=new double[9][2]; //[14];
dPXYmmc[0][0]=PXYmmc[0]; // is it needed? probably not used dPXYmmc[0][0]=PXYmmc[0]; // is it needed? probably not used
dPXYmmc[0][1]=PXYmmc[1]; dPXYmmc[0][1]=PXYmmc[1];
//(4) PXmmc =f/Ze* Xe // mm, left from the lens axis intersection with the sensor //(4) PXmmc =f/Ze* Xe // mm, left from the lens axis intersection with the sensor
//dPXmmc/dphi = f/Ze * dXe/dphi - f*Xe/Ze^2 * dZe/dphi //dPXmmc/dphi = f/Ze * dXe/dphi - f*Xe/Ze^2 * dZe/dphi
dPXYmmc[1][0]=this.focalLength/dXeYeZe[0][2]*(dXeYeZe[1][0]-dXeYeZe[0][0]/dXeYeZe[0][2]*dXeYeZe[1][2]); dPXYmmc[1][0]=this.focalLength/dXeYeZe[0][2]*(dXeYeZe[1][0]-dXeYeZe[0][0]/dXeYeZe[0][2]*dXeYeZe[1][2]);
//dPXmmc/dtheta = f/Ze * dXe/dtheta - f*Xe/Ze^2 * dZe/dtheta //dPXmmc/dtheta = f/Ze * dXe/dtheta - f*Xe/Ze^2 * dZe/dtheta
...@@ -1453,7 +1455,7 @@ dPXmmc/dphi= ...@@ -1453,7 +1455,7 @@ dPXmmc/dphi=
dPXYmmc[7][1]=dXeYeZe[0][1]/dXeYeZe[0][2]; dPXYmmc[7][1]=dXeYeZe[0][1]/dXeYeZe[0][2];
//dPYmmc/ddist = - f*Ye/Ze^2 //dPYmmc/ddist = - f*Ye/Ze^2
dPXYmmc[8][1]=-this.focalLength*dXeYeZe[0][1]/(dXeYeZe[0][2]*dXeYeZe[0][2]); dPXYmmc[8][1]=-this.focalLength*dXeYeZe[0][1]/(dXeYeZe[0][2]*dXeYeZe[0][2]);
} }
// conversion coefficient from relative (to distortionRadius) to pixels // conversion coefficient from relative (to distortionRadius) to pixels
// negate for y! // negate for y!
...@@ -1509,14 +1511,14 @@ dPXmmc/dphi= ...@@ -1509,14 +1511,14 @@ dPXmmc/dphi=
double ai_iplus1_rr_pow_i_minus_1= a[i]*(i+1)*rr_pow_i_minus_1; double ai_iplus1_rr_pow_i_minus_1= a[i]*(i+1)*rr_pow_i_minus_1;
double rr_pow_i_minus_2=rr_pow_i_minus_1/rr; double rr_pow_i_minus_2=rr_pow_i_minus_1/rr;
// double ki1_div_r_mul_i=i*ki1/rr; // double ki1_div_r_mul_i=i*ki1/rr;
double ki1_r_pow_im2_mul_i=i*ki1*rr_pow_i_minus_2; // (axi*x+ayi*y)*i*rr^(i-2) double ki1_r_pow_im2_mul_i=i*ki1*rr_pow_i_minus_2; // (axi*x+ayi*y)*i*rr^(i-2)
// double ki2_div_r3_mul_im1=(i-1)*ki2/(rr*rr*rr); // double ki2_div_r3_mul_im1=(i-1)*ki2/(rr*rr*rr);
double ki2_r_pow_im3_mul_im1=(i-1)*ki2*rr_pow_i_minus_2/rr; // (aoi*(y^2-x^2)+2*adi*x*y)* (i-1)*r^(i-3) double ki2_r_pow_im3_mul_im1=(i-1)*ki2*rr_pow_i_minus_2/rr; // (aoi*(y^2-x^2)+2*adi*x*y)* (i-1)*r^(i-3)
// double dki_dx= x*(ai_iplus1_rr_pow_i_minus_1 + // double dki_dx= x*(ai_iplus1_rr_pow_i_minus_1 +
// r_xyod[i][0]*rr_pow_i_minus_1 + ki1_div_r_mul_i+ki2_div_r3_mul_im1)+ // r_xyod[i][0]*rr_pow_i_minus_1 + ki1_div_r_mul_i+ki2_div_r3_mul_im1)+
// 2*(r_xyod[i][3]*y - r_xyod[i][2]*x)/rr_pow_i_minus_1; // 2*(r_xyod[i][3]*y - r_xyod[i][2]*x)/rr_pow_i_minus_1;
double dki_dx= x*(ai_iplus1_rr_pow_i_minus_1 + double dki_dx= x*(ai_iplus1_rr_pow_i_minus_1 +
ki1_r_pow_im2_mul_i + ki2_r_pow_im3_mul_im1)+ // r_xyod[i][0]*rr_pow_i_minus_1 + ki1_r_pow_im2_mul_i + ki2_r_pow_im3_mul_im1)+ // r_xyod[i][0]*rr_pow_i_minus_1 +
r_xyod[i][0]*rr_pow_i + 2*(r_xyod[i][3]*y - r_xyod[i][2]*x)*rr_pow_i_minus_1; r_xyod[i][0]*rr_pow_i + 2*(r_xyod[i][3]*y - r_xyod[i][2]*x)*rr_pow_i_minus_1;
// double dki_dy= y*(ai_iplus1_rr_pow_i_minus_1 + // double dki_dy= y*(ai_iplus1_rr_pow_i_minus_1 +
// r_xyod[i][1]*rr_pow_i_minus_1 + ki1_div_r_mul_i + ki2_div_r3_mul_im1)+ // r_xyod[i][1]*rr_pow_i_minus_1 + ki1_div_r_mul_i + ki2_div_r3_mul_im1)+
...@@ -1524,7 +1526,7 @@ dPXmmc/dphi= ...@@ -1524,7 +1526,7 @@ dPXmmc/dphi=
double dki_dy= y*(ai_iplus1_rr_pow_i_minus_1 + double dki_dy= y*(ai_iplus1_rr_pow_i_minus_1 +
ki1_r_pow_im2_mul_i + ki2_r_pow_im3_mul_im1)+ // r_xyod[i][1]*rr_pow_i_minus_1 + ki1_r_pow_im2_mul_i + ki2_r_pow_im3_mul_im1)+ // r_xyod[i][1]*rr_pow_i_minus_1 +
r_xyod[i][1]*rr_pow_i + 2*(r_xyod[i][3]*x + r_xyod[i][2]*y)*rr_pow_i_minus_1; r_xyod[i][1]*rr_pow_i + 2*(r_xyod[i][3]*x + r_xyod[i][2]*y)*rr_pow_i_minus_1;
// double ai_iplus1_rr_pow_i= a[i]*(i+1)*rr_pow_i; // double ai_iplus1_rr_pow_i= a[i]*(i+1)*rr_pow_i;
// double dki_dxmmc= ai_iplus1_rr_pow_i*(x*(1.0-r_xyod[i][2])+y*r_xyod[i][3])/rr; // double dki_dxmmc= ai_iplus1_rr_pow_i*(x*(1.0-r_xyod[i][2])+y*r_xyod[i][3])/rr;
// double dki_dymmc= ai_iplus1_rr_pow_i*(y*(1.0+r_xyod[i][2])+x*r_xyod[i][3])/rr; // double dki_dymmc= ai_iplus1_rr_pow_i*(y*(1.0+r_xyod[i][2])+x*r_xyod[i][3])/rr;
// the following 4 shifts are "extra", on top of non-distorted (pinhole) - pinhole should be added to the per-term sum // the following 4 shifts are "extra", on top of non-distorted (pinhole) - pinhole should be added to the per-term sum
...@@ -1536,7 +1538,7 @@ dPXmmc/dphi= ...@@ -1536,7 +1538,7 @@ dPXmmc/dphi=
dDeltaX_dy += dDeltaXi_dy; dDeltaX_dy += dDeltaXi_dy;
dDeltaY_dx += dDeltaYi_dx; dDeltaY_dx += dDeltaYi_dx;
dDeltaY_dy += dDeltaYi_dy; dDeltaY_dy += dDeltaYi_dy;
//dpx_dai, dpi_dai - same as before //dpx_dai, dpi_dai - same as before
int index= distortionCIndex-i; // reverse order, // a8->9, a7->10, a6->11, a5->12, a->13, b->14, c->15 int index= distortionCIndex-i; // reverse order, // a8->9, a7->10, a6->11, a5->12, a->13, b->14, c->15
partDeriv[index][0]= rel_to_pix*x*(rr_pow_i_plus_1-1.0); // OK partDeriv[index][0]= rel_to_pix*x*(rr_pow_i_plus_1-1.0); // OK
partDeriv[index][1]=-rel_to_pix*y*(rr_pow_i_plus_1-1.0); // OK partDeriv[index][1]=-rel_to_pix*y*(rr_pow_i_plus_1-1.0); // OK
...@@ -1560,20 +1562,20 @@ dPXmmc/dphi= ...@@ -1560,20 +1562,20 @@ dPXmmc/dphi=
// dpy_daDi=-2*y*xy*r^(i-1); // dpy_daDi=-2*y*xy*r^(i-1);
double rel_to_pix_mul_y2_minus_x2_mul_rr_pow_i_minus_1=rel_to_pix* (y2-x2)*rr_pow_i_minus_1; double rel_to_pix_mul_y2_minus_x2_mul_rr_pow_i_minus_1=rel_to_pix* (y2-x2)*rr_pow_i_minus_1;
double rel_to_pix_mul_2xy_mul_rr_pow_i_minus_1=rel_to_pix*2.0*xy*rr_pow_i_minus_1; double rel_to_pix_mul_2xy_mul_rr_pow_i_minus_1=rel_to_pix*2.0*xy*rr_pow_i_minus_1;
index=numRadialDerivatives-2+4*i; index=numRadialDerivatives-2+4*i;
partDeriv[index+2][0]= x*rel_to_pix_mul_y2_minus_x2_mul_rr_pow_i_minus_1; partDeriv[index+2][0]= x*rel_to_pix_mul_y2_minus_x2_mul_rr_pow_i_minus_1;
partDeriv[index+2][1]=-y*rel_to_pix_mul_y2_minus_x2_mul_rr_pow_i_minus_1; partDeriv[index+2][1]=-y*rel_to_pix_mul_y2_minus_x2_mul_rr_pow_i_minus_1;
partDeriv[index+3][0]= x*rel_to_pix_mul_2xy_mul_rr_pow_i_minus_1; partDeriv[index+3][0]= x*rel_to_pix_mul_2xy_mul_rr_pow_i_minus_1;
partDeriv[index+3][1]=-y*rel_to_pix_mul_2xy_mul_rr_pow_i_minus_1; partDeriv[index+3][1]=-y*rel_to_pix_mul_2xy_mul_rr_pow_i_minus_1;
} }
} }
double [] xyDist={PXYmmc[0]+this.distortionRadius*deltaX,PXYmmc[1]+this.distortionRadius*deltaY}; double [] xyDist={PXYmmc[0]+this.distortionRadius*deltaX,PXYmmc[1]+this.distortionRadius*deltaY};
// convert to sensor pixels coordinates // convert to sensor pixels coordinates
partDeriv[0][0]= 1000.0/this.pixelSize*xyDist[0] + this.px0; partDeriv[0][0]= 1000.0/this.pixelSize*xyDist[0] + this.px0;
partDeriv[0][1]= -1000.0/this.pixelSize*xyDist[1] + this.py0; partDeriv[0][1]= -1000.0/this.pixelSize*xyDist[1] + this.py0;
if (!calculateAll) { // TODO: how to deal with it when calculating Jacobian??? if (!calculateAll) { // TODO: how to deal with it when calculating Jacobian???
// TODO: Looking away from the target, trying only with no dervatives. Do the same for derivatives too? // TODO: Looking away from the target, trying only with no dervatives. Do the same for derivatives too?
if ((XeYeZe[2]<0.0) || (r2>maxRelativeRadius*maxRelativeRadius)){ // non-distorted too far from the axis if ((XeYeZe[2]<0.0) || (r2>maxRelativeRadius*maxRelativeRadius)){ // non-distorted too far from the axis
...@@ -1591,16 +1593,16 @@ dPXmmc/dphi= ...@@ -1591,16 +1593,16 @@ dPXmmc/dphi=
partDeriv[index ][1]+=partDeriv[index+4][1]; partDeriv[index ][1]+=partDeriv[index+4][1];
partDeriv[index+1][0]+=partDeriv[index+5][0]; partDeriv[index+1][0]+=partDeriv[index+5][0];
partDeriv[index+1][1]+=partDeriv[index+5][1]; partDeriv[index+1][1]+=partDeriv[index+5][1];
} }
partDeriv[index+2][0]+=partDeriv[index+6][0]; partDeriv[index+2][0]+=partDeriv[index+6][0];
partDeriv[index+2][1]+=partDeriv[index+6][1]; partDeriv[index+2][1]+=partDeriv[index+6][1];
partDeriv[index+3][0]+=partDeriv[index+7][0]; partDeriv[index+3][0]+=partDeriv[index+7][0];
partDeriv[index+3][1]+=partDeriv[index+7][1]; partDeriv[index+3][1]+=partDeriv[index+7][1];
} }
} }
// convert dDelta*_d* from relative/relative to pix/mm (invert pixel Y direction) // convert dDelta*_d* from relative/relative to pix/mm (invert pixel Y direction)
// added 1.0 to account for non-distorted (pinhole) shift // added 1.0 to account for non-distorted (pinhole) shift
double dPx_dPinholeX= (1.0+dDeltaX_dx)*1000.0/this.pixelSize; double dPx_dPinholeX= (1.0+dDeltaX_dx)*1000.0/this.pixelSize;
double dPx_dPinholeY= dDeltaX_dy*1000.0/this.pixelSize; double dPx_dPinholeY= dDeltaX_dy*1000.0/this.pixelSize;
double dPy_dPinholeX= -dDeltaY_dx*1000.0/this.pixelSize; double dPy_dPinholeX= -dDeltaY_dx*1000.0/this.pixelSize;
...@@ -1611,12 +1613,12 @@ dPXmmc/dphi= ...@@ -1611,12 +1613,12 @@ dPXmmc/dphi=
System.out.println(" dDeltaX_dxmmc="+dDeltaX_dx+" dDeltaX_dymmc="+dDeltaX_dy+" dDeltaY_dxmmc="+dDeltaY_dx+" dDeltaY_dymmc"+dDeltaY_dy); System.out.println(" dDeltaX_dxmmc="+dDeltaX_dx+" dDeltaX_dymmc="+dDeltaX_dy+" dDeltaY_dxmmc="+dDeltaY_dx+" dDeltaY_dymmc"+dDeltaY_dy);
System.out.println(" dPx_dPinholeX="+dPx_dPinholeX+" dPx_dPinholeY="+dPx_dPinholeY+" dPy_dPinholeX="+dPy_dPinholeX+" dPy_dPinholeY"+dPy_dPinholeY); System.out.println(" dPx_dPinholeX="+dPx_dPinholeX+" dPx_dPinholeY="+dPx_dPinholeY+" dPy_dPinholeX="+dPy_dPinholeX+" dPy_dPinholeY"+dPy_dPinholeY);
} }
double K=Math.PI/180; // multiply all derivatives my angles double K=Math.PI/180; // multiply all derivatives my angles
// dPX/dphi = 1000/Psz* dxDist/dphi // dPX/dphi = 1000/Psz* dxDist/dphi
partDeriv[ 1][0]= K*(dPx_dPinholeX*dPXYmmc[1][0]+dPx_dPinholeY*dPXYmmc[1][1]); partDeriv[ 1][0]= K*(dPx_dPinholeX*dPXYmmc[1][0]+dPx_dPinholeY*dPXYmmc[1][1]);
partDeriv[ 1][1]= K*(dPy_dPinholeX*dPXYmmc[1][0]+dPy_dPinholeY*dPXYmmc[1][1]); partDeriv[ 1][1]= K*(dPy_dPinholeX*dPXYmmc[1][0]+dPy_dPinholeY*dPXYmmc[1][1]);
// dPX/dtheta = 1000/Psz* dxDist/dtheta // dPX/dtheta = 1000/Psz* dxDist/dtheta
partDeriv[ 2][0]= K*(dPx_dPinholeX*dPXYmmc[2][0]+dPx_dPinholeY*dPXYmmc[2][1]); partDeriv[ 2][0]= K*(dPx_dPinholeX*dPXYmmc[2][0]+dPx_dPinholeY*dPXYmmc[2][1]);
partDeriv[ 2][1]= K*(dPy_dPinholeX*dPXYmmc[2][0]+dPy_dPinholeY*dPXYmmc[2][1]); partDeriv[ 2][1]= K*(dPy_dPinholeX*dPXYmmc[2][0]+dPy_dPinholeY*dPXYmmc[2][1]);
...@@ -1638,7 +1640,7 @@ dPXmmc/dphi= ...@@ -1638,7 +1640,7 @@ dPXmmc/dphi=
// dPX/ddist = 1000/Psz* dxDist/ddist // dPX/ddist = 1000/Psz* dxDist/ddist
partDeriv[ 8][0]= dPx_dPinholeX*dPXYmmc[8][0]+dPx_dPinholeY*dPXYmmc[8][1]; partDeriv[ 8][0]= dPx_dPinholeX*dPXYmmc[8][0]+dPx_dPinholeY*dPXYmmc[8][1];
partDeriv[ 8][1]= dPy_dPinholeX*dPXYmmc[8][0]+dPy_dPinholeY*dPXYmmc[8][1]; partDeriv[ 8][1]= dPy_dPinholeX*dPXYmmc[8][0]+dPy_dPinholeY*dPXYmmc[8][1];
// dPX/dPX0 = 1 // dPX/dPX0 = 1
// dPY/dPX0 = 0 // dPY/dPX0 = 0
partDeriv[16][0]= 1.0; partDeriv[16][0]= 1.0;
...@@ -1649,9 +1651,9 @@ dPXmmc/dphi= ...@@ -1649,9 +1651,9 @@ dPXmmc/dphi=
partDeriv[17][1]= 1.0; partDeriv[17][1]= 1.0;
return partDeriv; return partDeriv;
} }
public void setProperties(String prefix,Properties properties){ public void setProperties(String prefix,Properties properties){
properties.setProperty(prefix+"focalLength",this.focalLength+""); properties.setProperty(prefix+"focalLength",this.focalLength+"");
properties.setProperty(prefix+"pixelSize",this.pixelSize+""); properties.setProperty(prefix+"pixelSize",this.pixelSize+"");
...@@ -1730,7 +1732,7 @@ dPXmmc/dphi= ...@@ -1730,7 +1732,7 @@ dPXmmc/dphi=
this.py0=Double.parseDouble(properties.getProperty(prefix+"py0")); this.py0=Double.parseDouble(properties.getProperty(prefix+"py0"));
if (properties.getProperty(prefix+"flipVertical")!=null) if (properties.getProperty(prefix+"flipVertical")!=null)
this.flipVertical=Boolean.parseBoolean(properties.getProperty(prefix+"flipVertical")); this.flipVertical=Boolean.parseBoolean(properties.getProperty(prefix+"flipVertical"));
setDefaultNonRadial(); setDefaultNonRadial();
for (int i=0;i<this.r_xy.length;i++){ for (int i=0;i<this.r_xy.length;i++){
if (properties.getProperty(prefix+"r_xy_"+i+"_x")!=null) this.r_xy[i][0]=Double.parseDouble(properties.getProperty(prefix+"r_xy_"+i+"_x")); if (properties.getProperty(prefix+"r_xy_"+i+"_x")!=null) this.r_xy[i][0]=Double.parseDouble(properties.getProperty(prefix+"r_xy_"+i+"_x"));
...@@ -1817,11 +1819,11 @@ dPXmmc/dphi= ...@@ -1817,11 +1819,11 @@ dPXmmc/dphi=
this.x0= gd.getNextNumber(); this.x0= gd.getNextNumber();
this.y0= gd.getNextNumber(); this.y0= gd.getNextNumber();
this.z0= gd.getNextNumber(); this.z0= gd.getNextNumber();
this.distance= gd.getNextNumber(); this.distance= gd.getNextNumber();
this.px0= gd.getNextNumber(); this.px0= gd.getNextNumber();
this.py0= gd.getNextNumber(); this.py0= gd.getNextNumber();
this.flipVertical= gd.getNextBoolean(); this.flipVertical= gd.getNextBoolean();
this.r_od[0][0]= 0.01*gd.getNextNumber(); this.r_od[0][0]= 0.01*gd.getNextNumber();
this.r_od[0][1]= 0.01*gd.getNextNumber(); this.r_od[0][1]= 0.01*gd.getNextNumber();
this.r_xy[0][0]= 0.01*gd.getNextNumber(); this.r_xy[0][0]= 0.01*gd.getNextNumber();
...@@ -1852,7 +1854,7 @@ dPXmmc/dphi= ...@@ -1852,7 +1854,7 @@ dPXmmc/dphi=
} }
/** /**
* Calculate/set this.lensDistortionParameters and this.interParameterDerivatives * Calculate/set this.lensDistortionParameters and this.interParameterDerivatives
* UPDATE - Modifies lensDistortionParameters, not "this" for multi-threaded * UPDATE - Modifies lensDistortionParameters, not "this" for multi-threaded
* @param parVect 21-element vector for eyesis sub-camera, including common and individual parameters * @param parVect 21-element vector for eyesis sub-camera, including common and individual parameters
* @param mask -mask - which partial derivatives are needed to be calculated (others will be null) * @param mask -mask - which partial derivatives are needed to be calculated (others will be null)
* @param calculateDerivatives calculate array of partial derivatives, if false - just the values * @param calculateDerivatives calculate array of partial derivatives, if false - just the values
...@@ -1861,13 +1863,15 @@ dPXmmc/dphi= ...@@ -1861,13 +1863,15 @@ dPXmmc/dphi=
LensDistortionParameters lensDistortionParameters, LensDistortionParameters lensDistortionParameters,
boolean isTripod, boolean isTripod,
boolean cartesian, boolean cartesian,
double pixelSize,
double distortionRadius,
double [][] interParameterDerivatives, //partial derivative matrix from subcamera-camera-goniometer to single camera (12x21) if null - just values, no derivatives double [][] interParameterDerivatives, //partial derivative matrix from subcamera-camera-goniometer to single camera (12x21) if null - just values, no derivatives
double [] parVect, double [] parVect,
boolean [] mask // calculate only selected derivatives (all parVect values are still boolean [] mask // calculate only selected derivatives (all parVect values are still
){ ){
boolean calculateDerivatives=(interParameterDerivatives!=null); // calculate this.interParameterDerivatives -derivatives array (false - just this.values) boolean calculateDerivatives=(interParameterDerivatives!=null); // calculate this.interParameterDerivatives -derivatives array (false - just this.values)
// change meaning of goniometerHorizontal (tripod vertical) and goniometerAxial (tripod horizontal) // change meaning of goniometerHorizontal (tripod vertical) and goniometerAxial (tripod horizontal)
// Alternative variables for cartesian/cylindrical modes // Alternative variables for cartesian/cylindrical modes
double azimuth_cyl= cartesian? Double.NaN: parVect[0]; double azimuth_cyl= cartesian? Double.NaN: parVect[0];
double right_cart= cartesian? parVect[0] : Double.NaN; double right_cart= cartesian? parVect[0] : Double.NaN;
...@@ -1889,19 +1893,19 @@ dPXmmc/dphi= ...@@ -1889,19 +1893,19 @@ dPXmmc/dphi=
double GXYZ0=parVect[14]; double GXYZ0=parVect[14];
double GXYZ1=parVect[15]; double GXYZ1=parVect[15];
double GXYZ2=parVect[16]; double GXYZ2=parVect[16];
double cPS= Math.cos(psi*Math.PI/180); // subCam.psi double cPS= Math.cos(psi*Math.PI/180); // subCam.psi
double sPS= Math.sin(psi*Math.PI/180); // subCam.psi double sPS= Math.sin(psi*Math.PI/180); // subCam.psi
double cTH= Math.cos(theta*Math.PI/180); // subCam.theta double cTH= Math.cos(theta*Math.PI/180); // subCam.theta
double sTH= Math.sin(theta*Math.PI/180); // subCam.theta double sTH= Math.sin(theta*Math.PI/180); // subCam.theta
double cAZP= Math.cos((cartesian?heading_cart:(azimuth_cyl+phi_cyl))*Math.PI/180); //subCam.azimuth+subCam.phi double cAZP= Math.cos((cartesian?heading_cart:(azimuth_cyl+phi_cyl))*Math.PI/180); //subCam.azimuth+subCam.phi
double sAZP= Math.sin((cartesian?heading_cart:(azimuth_cyl+phi_cyl))*Math.PI/180); //subCam.azimuth+subCam.phi double sAZP= Math.sin((cartesian?heading_cart:(azimuth_cyl+phi_cyl))*Math.PI/180); //subCam.azimuth+subCam.phi
// renaming the following 2 to be replaced for cartesian coordinates // renaming the following 2 to be replaced for cartesian coordinates
double cAZ_cyl= Math.cos(azimuth_cyl*Math.PI/180); //subCam.azimuth double cAZ_cyl= Math.cos(azimuth_cyl*Math.PI/180); //subCam.azimuth
double sAZ_cyl= Math.sin(azimuth_cyl*Math.PI/180); //subCam.azimuth double sAZ_cyl= Math.sin(azimuth_cyl*Math.PI/180); //subCam.azimuth
double cGA= Math.cos(goniometerAxial*Math.PI/180); //eyesisCameraParameters.goniometerAxial double cGA= Math.cos(goniometerAxial*Math.PI/180); //eyesisCameraParameters.goniometerAxial
double sGA= Math.sin(goniometerAxial*Math.PI/180); //eyesisCameraParameters.goniometerAxial double sGA= Math.sin(goniometerAxial*Math.PI/180); //eyesisCameraParameters.goniometerAxial
double cGH= Math.cos(goniometerHorizontal*Math.PI/180); //eyesisCameraParameters.goniometerHorizontal double cGH= Math.cos(goniometerHorizontal*Math.PI/180); //eyesisCameraParameters.goniometerHorizontal
...@@ -1912,7 +1916,7 @@ dPXmmc/dphi= ...@@ -1912,7 +1916,7 @@ dPXmmc/dphi=
double sHAEPH=Math.sin(horAxisErrPhi*Math.PI/180); //eyesisCameraParameters.horAxisErrPhi double sHAEPH=Math.sin(horAxisErrPhi*Math.PI/180); //eyesisCameraParameters.horAxisErrPhi
double cHAEPS=Math.cos(horAxisErrPsi*Math.PI/180); //eyesisCameraParameters.horAxisErrPsi double cHAEPS=Math.cos(horAxisErrPsi*Math.PI/180); //eyesisCameraParameters.horAxisErrPsi
double sHAEPS=Math.sin(horAxisErrPsi*Math.PI/180); //eyesisCameraParameters.horAxisErrPsi\ double sHAEPS=Math.sin(horAxisErrPsi*Math.PI/180); //eyesisCameraParameters.horAxisErrPsi\
/* /*
0) Translate by distance to entrance pupil (lens center) 0) Translate by distance to entrance pupil (lens center)
| Xc0 | | 0 | |Xc| | Xc0 | | 0 | |Xc|
...@@ -1921,7 +1925,7 @@ dPXmmc/dphi= ...@@ -1921,7 +1925,7 @@ dPXmmc/dphi=
*/ */
double [][] aT0={{0.0},{0.0},{entrancePupilForward}}; double [][] aT0={{0.0},{0.0},{entrancePupilForward}};
Matrix T0=new Matrix(aT0); Matrix T0=new Matrix(aT0);
/* /*
Converting from the sub-camera coordinates to the target coordinates Converting from the sub-camera coordinates to the target coordinates
1) rotate by -psi around CZ: Vc1= R1*Vc 1) rotate by -psi around CZ: Vc1= R1*Vc
...@@ -1931,7 +1935,7 @@ dPXmmc/dphi= ...@@ -1931,7 +1935,7 @@ dPXmmc/dphi=
*/ */
double [][] aR1={{cPS,sPS,0.0},{-sPS,cPS,0.0},{0.0,0.0,1.0}}; double [][] aR1={{cPS,sPS,0.0},{-sPS,cPS,0.0},{0.0,0.0,1.0}};
Matrix R1=new Matrix(aR1); Matrix R1=new Matrix(aR1);
/* /*
2) rotate by - theta around C1X:Vc2= R2*Vc1 2) rotate by - theta around C1X:Vc2= R2*Vc1
| Xc2 | | 1 0 0 | |Xc1| | Xc2 | | 1 0 0 | |Xc1|
| Yc2 | = | 0 cos(theta) sin(theta) | * |Yc1| | Yc2 | = | 0 cos(theta) sin(theta) | * |Yc1|
...@@ -1939,7 +1943,7 @@ dPXmmc/dphi= ...@@ -1939,7 +1943,7 @@ dPXmmc/dphi=
*/ */
double [][] aR2={{1.0,0.0,0.0},{0.0,cTH,sTH},{0.0,-sTH,cTH}}; double [][] aR2={{1.0,0.0,0.0},{0.0,cTH,sTH},{0.0,-sTH,cTH}};
Matrix R2=new Matrix(aR2); Matrix R2=new Matrix(aR2);
/* /*
3) rotate by -(azimuth+phi) around C2Y:Vc3= R3*Vc2 3) rotate by -(azimuth+phi) around C2Y:Vc3= R3*Vc2
| Xc3 | | cos(azimuth+phi) 0 sin(azimuth+phi) | |Xc2| | Xc3 | | cos(azimuth+phi) 0 sin(azimuth+phi) | |Xc2|
| Yc3 | = | 0 1 0 | * |Yc2| | Yc3 | = | 0 1 0 | * |Yc2|
...@@ -1947,7 +1951,7 @@ dPXmmc/dphi= ...@@ -1947,7 +1951,7 @@ dPXmmc/dphi=
*/ */
double [][] aR3={{cAZP,0.0,sAZP},{0.0,1.0,0.0},{-sAZP,0.0,cAZP}}; double [][] aR3={{cAZP,0.0,sAZP},{0.0,1.0,0.0},{-sAZP,0.0,cAZP}};
Matrix R3=new Matrix(aR3); Matrix R3=new Matrix(aR3);
/* /*
4) Now axes are aligned, just translate to get to eyesis coordinates: Vey= T1+Vc3 4) Now axes are aligned, just translate to get to eyesis coordinates: Vey= T1+Vc3
| Xey | | r * sin (azimuth) | |Xc3| | Xey | | r * sin (azimuth) | |Xc3|
| Yey | = | height+centerAboveHorizontal | + |Yc3| | Yey | = | height+centerAboveHorizontal | + |Yc3|
...@@ -1955,10 +1959,10 @@ dPXmmc/dphi= ...@@ -1955,10 +1959,10 @@ dPXmmc/dphi=
*/ */
double [][] aT1_cyl= {{radius_cyl*sAZ_cyl},{(height+centerAboveHorizontal)},{radius_cyl*cAZ_cyl}}; // {{subCam.radius*sAZ},{subCam.height},{subCam.radius*cAZ}}; double [][] aT1_cyl= {{radius_cyl*sAZ_cyl},{(height+centerAboveHorizontal)},{radius_cyl*cAZ_cyl}}; // {{subCam.radius*sAZ},{subCam.height},{subCam.radius*cAZ}};
double [][] aT1_cart={{right_cart}, {(height+centerAboveHorizontal)},{forward_cart}}; // {{subCam.radius*sAZ},{subCam.height},{subCam.radius*cAZ}}; double [][] aT1_cart={{right_cart}, {(height+centerAboveHorizontal)},{forward_cart}}; // {{subCam.radius*sAZ},{subCam.height},{subCam.radius*cAZ}};
double [][] aT1= cartesian ? aT1_cart : aT1_cyl; double [][] aT1= cartesian ? aT1_cart : aT1_cyl;
Matrix T1=new Matrix(aT1); Matrix T1=new Matrix(aT1);
/** /**
5) rotate around moving goniometer axis, by (-goniometerAxial) - same as around EY: Vgm1=R4*Vey 5) rotate around moving goniometer axis, by (-goniometerAxial) - same as around EY: Vgm1=R4*Vey
| Xgm1 | | 1 0 0 | |Xey| | Xgm1 | | 1 0 0 | |Xey|
...@@ -1966,7 +1970,7 @@ dPXmmc/dphi= ...@@ -1966,7 +1970,7 @@ dPXmmc/dphi=
| Zgm1 | | 0 -sin(goniometerAxial) cos(goniometerAxial) | |Zey| | Zgm1 | | 0 -sin(goniometerAxial) cos(goniometerAxial) | |Zey|
*/ */
double [][] aR4_tripod= {{1.0,0.0,0.0},{0.0,cGA,sGA},{0.0,-sGA,cGA}}; double [][] aR4_tripod= {{1.0,0.0,0.0},{0.0,cGA,sGA},{0.0,-sGA,cGA}};
/* /*
5) rotate around moving goniometer axis, by (-goniometerAxial) - same as around EY: Vgm1=R4*Vey 5) rotate around moving goniometer axis, by (-goniometerAxial) - same as around EY: Vgm1=R4*Vey
| Xgm1 | | cos(goniometerAxial) 0 sin(goniometerAxial) | |Xey| | Xgm1 | | cos(goniometerAxial) 0 sin(goniometerAxial) | |Xey|
| Ygm1 | = | 0 1 0 | * |Yey| | Ygm1 | = | 0 1 0 | * |Yey|
...@@ -1974,7 +1978,7 @@ dPXmmc/dphi= ...@@ -1974,7 +1978,7 @@ dPXmmc/dphi=
*/ */
double [][] aR4_goniometer={{cGA,0.0,sGA},{0.0,1.0,0.0},{-sGA,0.0,cGA}}; double [][] aR4_goniometer={{cGA,0.0,sGA},{0.0,1.0,0.0},{-sGA,0.0,cGA}};
Matrix R4=new Matrix(isTripod?aR4_tripod:aR4_goniometer); Matrix R4=new Matrix(isTripod?aR4_tripod:aR4_goniometer);
/* /*
6) move to the goniometer horizontal axis:Vgm2=T2+Vgm1 6) move to the goniometer horizontal axis:Vgm2=T2+Vgm1
| Xgm2 | | 0 | |Xgm1| | Xgm2 | | 0 | |Xgm1|
| Ygm2 | = | 0 | + |Ygm1| | Ygm2 | = | 0 | + |Ygm1|
...@@ -1982,7 +1986,7 @@ dPXmmc/dphi= ...@@ -1982,7 +1986,7 @@ dPXmmc/dphi=
*/ */
double [][] aT2={{0.0},{0.0},{interAxisDistance}}; //eyesisCameraParameters.interAxisDistance double [][] aT2={{0.0},{0.0},{interAxisDistance}}; //eyesisCameraParameters.interAxisDistance
Matrix T2=new Matrix(aT2); Matrix T2=new Matrix(aT2);
/* /*
7) rotate around Zgm2 by -interAxisAngle, so Xgm3 axis is the same as horizontal goniometer axis: Vgm3=R5*Vgm2 7) rotate around Zgm2 by -interAxisAngle, so Xgm3 axis is the same as horizontal goniometer axis: Vgm3=R5*Vgm2
| Xgm3 | | cos(interAxisAngle) sin(interAxisAngle) 0 | |Xgm2| | Xgm3 | | cos(interAxisAngle) sin(interAxisAngle) 0 | |Xgm2|
| Ygm3 | = |-sin(interAxisAngle) cos(interAxisAngle) 0 | * |Ygm2| | Ygm3 | = |-sin(interAxisAngle) cos(interAxisAngle) 0 | * |Ygm2|
...@@ -1997,7 +2001,7 @@ dPXmmc/dphi= ...@@ -1997,7 +2001,7 @@ dPXmmc/dphi=
| Zgm4 | | -sin(goniometerHorizontal) 0 cos(goniometerHorizontal) | |Zgm3| | Zgm4 | | -sin(goniometerHorizontal) 0 cos(goniometerHorizontal) | |Zgm3|
*/ */
double [][] aR6_tripod= {{cGH,0.0,sGH},{0.0,1.0,0.0},{-sGH,0.0,cGH}}; double [][] aR6_tripod= {{cGH,0.0,sGH},{0.0,1.0,0.0},{-sGH,0.0,cGH}};
/* /*
8) rotate around goniometer horizontal axis (Xgm3) by -goniometerHorizontal: Vgm4=R6*Vgm3 8) rotate around goniometer horizontal axis (Xgm3) by -goniometerHorizontal: Vgm4=R6*Vgm3
| Xgm4 | | 1 0 0 | |Xgm3| | Xgm4 | | 1 0 0 | |Xgm3|
| Ygm4 | = | 0 cos(goniometerHorizontal) sin(goniometerHorizontal) | * |Ygm3| | Ygm4 | = | 0 cos(goniometerHorizontal) sin(goniometerHorizontal) | * |Ygm3|
...@@ -2005,7 +2009,7 @@ dPXmmc/dphi= ...@@ -2005,7 +2009,7 @@ dPXmmc/dphi=
*/ */
double [][] aR6_goniometer={{1.0,0.0,0.0},{0.0,cGH,sGH},{0.0,-sGH,cGH}}; double [][] aR6_goniometer={{1.0,0.0,0.0},{0.0,cGH,sGH},{0.0,-sGH,cGH}};
Matrix R6=new Matrix(isTripod?aR6_tripod:aR6_goniometer); Matrix R6=new Matrix(isTripod?aR6_tripod:aR6_goniometer);
/* /*
9) Correct roll error of the goniometer horizontal axis - rotate by -horAxisErrPsi around Zgm4: Vgm5=R7*Vgm4 9) Correct roll error of the goniometer horizontal axis - rotate by -horAxisErrPsi around Zgm4: Vgm5=R7*Vgm4
| Xgm5 | | cos(horAxisErrPsi) sin(horAxisErrPsi) 0 | |Xgm4| | Xgm5 | | cos(horAxisErrPsi) sin(horAxisErrPsi) 0 | |Xgm4|
| Ygm5 | = |-sin(horAxisErrPsi) cos(horAxisErrPsi) 0 | * |Ygm4| | Ygm5 | = |-sin(horAxisErrPsi) cos(horAxisErrPsi) 0 | * |Ygm4|
...@@ -2013,9 +2017,9 @@ dPXmmc/dphi= ...@@ -2013,9 +2017,9 @@ dPXmmc/dphi=
*/ */
double [][] aR7={{cHAEPS,sHAEPS,0.0},{-sHAEPS,cHAEPS,0.0},{0.0,0.0,1.0}}; double [][] aR7={{cHAEPS,sHAEPS,0.0},{-sHAEPS,cHAEPS,0.0},{0.0,0.0,1.0}};
Matrix R7=new Matrix(aR7); Matrix R7=new Matrix(aR7);
/* /*
10) Correct azimuth error of the goniometer hoirizontal axis - rotate by -horAxisErrPhi around Ygm5: Vgm6=R8*Vgm5 10) Correct azimuth error of the goniometer hoirizontal axis - rotate by -horAxisErrPhi around Ygm5: Vgm6=R8*Vgm5
| Xgm6 | | cos(horAxisErrPhi) 0 sin(horAxisErrPhi) | |Xgm5| | Xgm6 | | cos(horAxisErrPhi) 0 sin(horAxisErrPhi) | |Xgm5|
| Ygm6 | = | 0 1 0 | * |Ygm5| | Ygm6 | = | 0 1 0 | * |Ygm5|
| Zgm6 | |-sin(horAxisErrPhi) 0 cos(horAxisErrPhi) | |Zgm5| | Zgm6 | |-sin(horAxisErrPhi) 0 cos(horAxisErrPhi) | |Zgm5|
...@@ -2028,14 +2032,14 @@ dPXmmc/dphi= ...@@ -2028,14 +2032,14 @@ dPXmmc/dphi=
double [][] aR8_tripod= {{1.0, 0.0, 0.0},{0.0,cHAEPH,sHAEPH},{0.0, -sHAEPH,cHAEPH}}; double [][] aR8_tripod= {{1.0, 0.0, 0.0},{0.0,cHAEPH,sHAEPH},{0.0, -sHAEPH,cHAEPH}};
double [][] aR8_goniometer={{cHAEPH,0.0,sHAEPH},{0.0, 1.0, 0.0},{-sHAEPH, 0.0,cHAEPH}}; double [][] aR8_goniometer={{cHAEPH,0.0,sHAEPH},{0.0, 1.0, 0.0},{-sHAEPH, 0.0,cHAEPH}};
Matrix R8=new Matrix(isTripod?aR8_tripod:aR8_goniometer); Matrix R8=new Matrix(isTripod?aR8_tripod:aR8_goniometer);
/* /*
11) translate to the target zero point: Vt= T3+Vgm6 11) translate to the target zero point: Vt= T3+Vgm6
| Xt | | GXYZ[0] | |Xgm6| | Xt | | GXYZ[0] | |Xgm6|
| Yt | = |-GXYZ[1] | + |Ygm6| // Y - up positive | Yt | = |-GXYZ[1] | + |Ygm6| // Y - up positive
| Zt | |-GXYZ[2] | |Zgm6| // Z - away positive | Zt | |-GXYZ[2] | |Zgm6| // Z - away positive
*/ */
// double [][] aT3={{parVect[12]},{-parVect[13]},{-parVect[14]}};//{{eyesisCameraParameters.GXYZ[0]},{eyesisCameraParameters.GXYZ[1]},{eyesisCameraParameters.GXYZ[2]}}; // double [][] aT3={{parVect[12]},{-parVect[13]},{-parVect[14]}};//{{eyesisCameraParameters.GXYZ[0]},{eyesisCameraParameters.GXYZ[1]},{eyesisCameraParameters.GXYZ[2]}};
double [][] aT3={{GXYZ0},{-GXYZ1},{-GXYZ2}};//{{eyesisCameraParameters.GXYZ[0]},{eyesisCameraParameters.GXYZ[1]},{eyesisCameraParameters.GXYZ[2]}}; double [][] aT3={{GXYZ0},{-GXYZ1},{-GXYZ2}};//{{eyesisCameraParameters.GXYZ[0]},{eyesisCameraParameters.GXYZ[1]},{eyesisCameraParameters.GXYZ[2]}};
// double [][] aT3={{parVect[12]},{ parVect[13]},{-parVect[14]}};//{{eyesisCameraParameters.GXYZ[0]},{eyesisCameraParameters.GXYZ[1]},{eyesisCameraParameters.GXYZ[2]}}; // double [][] aT3={{parVect[12]},{ parVect[13]},{-parVect[14]}};//{{eyesisCameraParameters.GXYZ[0]},{eyesisCameraParameters.GXYZ[1]},{eyesisCameraParameters.GXYZ[2]}};
Matrix T3=new Matrix(aT3); Matrix T3=new Matrix(aT3);
...@@ -2056,6 +2060,10 @@ dPXmmc/dphi= ...@@ -2056,6 +2060,10 @@ dPXmmc/dphi=
// System.out.println("interParameterDerivatives[0]="+sprintfArray(interParameterDerivatives[0])); // System.out.println("interParameterDerivatives[0]="+sprintfArray(interParameterDerivatives[0]));
} }
double [] extrinsicParams=parametersFromMAMB(MA,MB); // all after 6 are 0; double [] extrinsicParams=parametersFromMAMB(MA,MB); // all after 6 are 0;
lensDistortionParameters.pixelSize = pixelSize;
lensDistortionParameters.distortionRadius = distortionRadius;
lensDistortionParameters.distance=extrinsicParams[2]; lensDistortionParameters.distance=extrinsicParams[2];
lensDistortionParameters.x0=extrinsicParams[0]; lensDistortionParameters.x0=extrinsicParams[0];
lensDistortionParameters.y0=extrinsicParams[1]; lensDistortionParameters.y0=extrinsicParams[1];
...@@ -2074,10 +2082,10 @@ dPXmmc/dphi= ...@@ -2074,10 +2082,10 @@ dPXmmc/dphi=
lensDistortionParameters.distortionA=parVect[24]; //subCam.distortionA; lensDistortionParameters.distortionA=parVect[24]; //subCam.distortionA;
lensDistortionParameters.distortionB=parVect[25]; //subCam.distortionB; lensDistortionParameters.distortionB=parVect[25]; //subCam.distortionB;
lensDistortionParameters.distortionC=parVect[26]; //subCam.distortionC; lensDistortionParameters.distortionC=parVect[26]; //subCam.distortionC;
lensDistortionParameters.r_xy=new double [6][2]; lensDistortionParameters.r_xy=new double [6][2];
lensDistortionParameters.r_od=new double [7][2]; lensDistortionParameters.r_od=new double [7][2];
int index=27; int index=27;
for (int i=0;i<lensDistortionParameters.r_od.length;i++){ for (int i=0;i<lensDistortionParameters.r_od.length;i++){
if (i>0){ if (i>0){
...@@ -2087,23 +2095,10 @@ dPXmmc/dphi= ...@@ -2087,23 +2095,10 @@ dPXmmc/dphi=
lensDistortionParameters.r_od[i][0]=parVect[index++]; lensDistortionParameters.r_od[i][0]=parVect[index++];
lensDistortionParameters.r_od[i][1]=parVect[index++]; lensDistortionParameters.r_od[i][1]=parVect[index++];
} }
/*
for (double [] row :lensDistortionParameters.r_xy){ lensDistortionParameters.recalcCommons(); // uncluding lensDistortionParameters.r_xyod
row[0]=parVect[index++];
row[1]=parVect[index++];
}
for (double [] row :lensDistortionParameters.r_od){
row[0]=parVect[index++];
row[1]=parVect[index++];
}
*/
///
// public double [][] r_xy=null; // only 6, as for the first term delta x, delta y ==0
// public double [][] r_od=null; // ortho
lensDistortionParameters.recalcCommons(); // uncliding lensDistortionParameters.r_xyod
if (this.debugLevel>2){ if (this.debugLevel>2){
System.out.println("lensDistortionParameters.recalcCommons()"); System.out.println("lensDistortionParameters.recalcCommons()");
System.out.println("lensDistortionParameters.distance="+IJ.d2s(lensDistortionParameters.distance, 3)); System.out.println("lensDistortionParameters.distance="+IJ.d2s(lensDistortionParameters.distance, 3));
...@@ -2133,7 +2128,7 @@ dPXmmc/dphi= ...@@ -2133,7 +2128,7 @@ dPXmmc/dphi=
System.out.println("lensDistortionParameters.r_od["+i+"][1]"+IJ.d2s(lensDistortionParameters.r_od[i][1], 5)); System.out.println("lensDistortionParameters.r_od["+i+"][1]"+IJ.d2s(lensDistortionParameters.r_od[i][1], 5));
} }
} }
if (!calculateDerivatives) return; if (!calculateDerivatives) return;
/* Calculate all derivativs as a matrix. /* Calculate all derivativs as a matrix.
* Input parameters (columns): * Input parameters (columns):
0 public double azimuth; // azimuth of the lens entrance pupil center, degrees, clockwise looking from top 0 public double azimuth; // azimuth of the lens entrance pupil center, degrees, clockwise looking from top
...@@ -2143,15 +2138,15 @@ dPXmmc/dphi= ...@@ -2143,15 +2138,15 @@ dPXmmc/dphi=
4 public double theta; // degrees, optical axis from the eyesis horizon, positive - up 4 public double theta; // degrees, optical axis from the eyesis horizon, positive - up
5 public double psi; // degrees, rotation (of the sensor) around the optical axis. Positive if camera is rotated clockwise looking to the target 5 public double psi; // degrees, rotation (of the sensor) around the optical axis. Positive if camera is rotated clockwise looking to the target
6 public double goniometerHorizontal; // goniometer rotation around "horizontal" axis (tilting from the target - positive) 6 public double goniometerHorizontal; // goniometer rotation around "horizontal" axis (tilting from the target - positive)
7 public double goniometerAxial; // goniometer rotation around Eyesis axis (clockwise in plan - positive 7 public double goniometerAxial; // goniometer rotation around Eyesis axis (clockwise in plan - positive
8 public double interAxisDistance; // distance in mm between two goniometer axes 8 public double interAxisDistance; // distance in mm between two goniometer axes
9 public double interAxisAngle; // angle in degrees between two goniometer axes minus 90. negative if "vertical" axis is rotated 9 public double interAxisAngle; // angle in degrees between two goniometer axes minus 90. negative if "vertical" axis is rotated
10 public double horAxisErrPhi; // angle in degrees "horizontal" goniometer axis is rotated around target Y axis from target X axis (CW) 10 public double horAxisErrPhi; // angle in degrees "horizontal" goniometer axis is rotated around target Y axis from target X axis (CW)
11 public double horAxisErrPsi; // angle in degrees "horizontal" goniometer axis is rotated around moving X axis (up) 11 public double horAxisErrPsi; // angle in degrees "horizontal" goniometer axis is rotated around moving X axis (up)
Two new parameters Two new parameters
12 public double entrancePupilForward; // common to all lenses - distance from the sensor to the lens entrance pupil 12 public double entrancePupilForward; // common to all lenses - distance from the sensor to the lens entrance pupil
13 public double centerAboveHorizontal; // camera center distance along camera axis above the closest point to horizontal rotation axis (adds to 13 public double centerAboveHorizontal; // camera center distance along camera axis above the closest point to horizontal rotation axis (adds to
14(12) x public double [] GXYZ=null; // coordinates (in mm) of the goniometer horizontal axis closest to the moving one in target system 14(12) x public double [] GXYZ=null; // coordinates (in mm) of the goniometer horizontal axis closest to the moving one in target system
15(13) y 15(13) y
16(14) z 16(14) z
17(15) public double focalLength=4.5; 17(15) public double focalLength=4.5;
...@@ -2237,9 +2232,9 @@ dPXmmc/dphi= ...@@ -2237,9 +2232,9 @@ dPXmmc/dphi=
41 Diagonal elongation for r^8" 41 Diagonal elongation for r^8"
*/ */
// interParameterDerivatives=new double[getNumInputs()][]; //partial derivative matrix from subcamera-camera-goniometer to single camera (12x21) // interParameterDerivatives=new double[getNumInputs()][]; //partial derivative matrix from subcamera-camera-goniometer to single camera (12x21)
//calculate dMA_azimuth //calculate dMA_azimuth
//calculate dMB_azimuth //calculate dMB_azimuth
/* /*
// MA=R8*R7*R6*R5*R4*R3*R2*R1; // MA=R8*R7*R6*R5*R4*R3*R2*R1;
// MB=T3+(R8*R7*R6*R5*(T2+R4*T1)); - old // MB=T3+(R8*R7*R6*R5*(T2+R4*T1)); - old
...@@ -2260,7 +2255,7 @@ dPXmmc/dphi= ...@@ -2260,7 +2255,7 @@ dPXmmc/dphi=
double [][] aT1={{subCam.radius*sAZ},{subCam.height},{subCam.radius*cAZ}}; double [][] aT1={{subCam.radius*sAZ},{subCam.height},{subCam.radius*cAZ}};
Matrix T1=new Matrix(aT1); Matrix T1=new Matrix(aT1);
Matrix Matrix
// Make a function MA, MB - >parameters (column) - reuse it above and for each interParameterDerivatives row // Make a function MA, MB - >parameters (column) - reuse it above and for each interParameterDerivatives row
Matrix dMA_azimuth=R8*R7*R6*R5*R4*dR3_azimuth*R2*R1; Matrix dMA_azimuth=R8*R7*R6*R5*R4*dR3_azimuth*R2*R1;
Matrix dMB_azimuth=T3+(R8*R7*R6*R5*(R4*dT1_azimuth)); Matrix dMB_azimuth=T3+(R8*R7*R6*R5*(R4*dT1_azimuth));
...@@ -2367,7 +2362,7 @@ dPXmmc/dphi= ...@@ -2367,7 +2362,7 @@ dPXmmc/dphi=
System.out.println("interParameterDerivatives[1]="+sprintfArray(interParameterDerivatives[1])); System.out.println("interParameterDerivatives[1]="+sprintfArray(interParameterDerivatives[1]));
} }
} }
} else interParameterDerivatives[1]=null; } else interParameterDerivatives[1]=null;
//2 public double height; // mm, downwards - from the origin point //2 public double height; // mm, downwards - from the origin point
if (mask[2]) { if (mask[2]) {
double [][] adT1_height={{0.0},{1.0},{0.0}}; double [][] adT1_height={{0.0},{1.0},{0.0}};
...@@ -2382,7 +2377,7 @@ dPXmmc/dphi= ...@@ -2382,7 +2377,7 @@ dPXmmc/dphi=
dMB_height.print(10, 5); dMB_height.print(10, 5);
System.out.println("interParameterDerivatives[2]="+sprintfArray(interParameterDerivatives[2])); System.out.println("interParameterDerivatives[2]="+sprintfArray(interParameterDerivatives[2]));
} }
} else interParameterDerivatives[2]=null; } else interParameterDerivatives[2]=null;
//3 public double phi; // degrees, optical axis from azimuth/r vector, clockwise //3 public double phi; // degrees, optical axis from azimuth/r vector, clockwise
if (mask[3]) { // here the same for cartesian if (mask[3]) { // here the same for cartesian
double [][] adR3_phi={{-sAZP,0.0,cAZP},{0.0,0.0,0.0},{-cAZP,0.0,-sAZP}}; // same as adR3_azimuth double [][] adR3_phi={{-sAZP,0.0,cAZP},{0.0,0.0,0.0},{-cAZP,0.0,-sAZP}}; // same as adR3_azimuth
...@@ -2398,7 +2393,7 @@ dPXmmc/dphi= ...@@ -2398,7 +2393,7 @@ dPXmmc/dphi=
dMB_phi.print(10, 5); dMB_phi.print(10, 5);
System.out.println("interParameterDerivatives[3]="+sprintfArray(interParameterDerivatives[3])); System.out.println("interParameterDerivatives[3]="+sprintfArray(interParameterDerivatives[3]));
} }
} else interParameterDerivatives[3]=null; } else interParameterDerivatives[3]=null;
//4 public double theta; // degrees, optical axis from the eyesis horizon, positive - up //4 public double theta; // degrees, optical axis from the eyesis horizon, positive - up
if (mask[4]) { if (mask[4]) {
double [][] adR2_theta={{0.0,0.0,0.0},{0.0,-sTH,cTH},{0.0,-cTH,-sTH}}; double [][] adR2_theta={{0.0,0.0,0.0},{0.0,-sTH,cTH},{0.0,-cTH,-sTH}};
...@@ -2414,7 +2409,7 @@ dPXmmc/dphi= ...@@ -2414,7 +2409,7 @@ dPXmmc/dphi=
dMB_theta.print(10, 5); dMB_theta.print(10, 5);
System.out.println("interParameterDerivatives[4]="+sprintfArray(interParameterDerivatives[4])); System.out.println("interParameterDerivatives[4]="+sprintfArray(interParameterDerivatives[4]));
} }
} else interParameterDerivatives[4]=null; } else interParameterDerivatives[4]=null;
//5 public double psi; // degrees, rotation (of the sensor) around the optical axis. Positive if camera is rotated clockwise looking to the target //5 public double psi; // degrees, rotation (of the sensor) around the optical axis. Positive if camera is rotated clockwise looking to the target
if (mask[5]) { if (mask[5]) {
double [][] adR1_psi={{-sPS,cPS,0.0},{-cPS,-sPS,0.0},{0.0,0.0,0.0}}; double [][] adR1_psi={{-sPS,cPS,0.0},{-cPS,-sPS,0.0},{0.0,0.0,0.0}};
...@@ -2424,7 +2419,7 @@ dPXmmc/dphi= ...@@ -2424,7 +2419,7 @@ dPXmmc/dphi=
Matrix dMB_psi=dMA_psi.times(T0); // new term Matrix dMB_psi=dMA_psi.times(T0); // new term
interParameterDerivatives[5]=d_parametersFromMAMB(dMA_psi,dMB_psi,MA,MB,true); // all after 6 are 0; interParameterDerivatives[5]=d_parametersFromMAMB(dMA_psi,dMB_psi,MA,MB,true); // all after 6 are 0;
if (this.debugLevel>2) { if (this.debugLevel>2) {
/* /*
System.out.print("R1:"); System.out.print("R1:");
R1.print(10, 5); R1.print(10, 5);
System.out.print("dR1_psi:"); System.out.print("dR1_psi:");
...@@ -2439,7 +2434,7 @@ dPXmmc/dphi= ...@@ -2439,7 +2434,7 @@ dPXmmc/dphi=
dMB_psi.print(10, 5); dMB_psi.print(10, 5);
System.out.println("interParameterDerivatives[5]="+sprintfArray(interParameterDerivatives[5])); System.out.println("interParameterDerivatives[5]="+sprintfArray(interParameterDerivatives[5]));
} }
} else interParameterDerivatives[5]=null; } else interParameterDerivatives[5]=null;
//6 public double goniometerHorizontal; // goniometer rotation around "horizontal" axis (tilting from the target - positive) //6 public double goniometerHorizontal; // goniometer rotation around "horizontal" axis (tilting from the target - positive)
if (mask[6]) { if (mask[6]) {
/* define for isTripod */ /* define for isTripod */
...@@ -2456,8 +2451,8 @@ dPXmmc/dphi= ...@@ -2456,8 +2451,8 @@ dPXmmc/dphi=
dMB_goniometerHorizontal.print(10, 5); dMB_goniometerHorizontal.print(10, 5);
System.out.println("interParameterDerivatives[6]="+sprintfArray(interParameterDerivatives[6])); System.out.println("interParameterDerivatives[6]="+sprintfArray(interParameterDerivatives[6]));
} }
} else interParameterDerivatives[6]=null; } else interParameterDerivatives[6]=null;
//7 public double goniometerAxial; // goniometer rotation around Eyesis axis (clockwise in plan - positive //7 public double goniometerAxial; // goniometer rotation around Eyesis axis (clockwise in plan - positive
if (mask[7]) { if (mask[7]) {
// define for isTripod // define for isTripod
double [][] adR4_goniometerAxial_tripod= {{ 0.0,0.0,0.0},{0.0,-sGA,cGA},{ 0.0,-cGA,-sGA}}; double [][] adR4_goniometerAxial_tripod= {{ 0.0,0.0,0.0},{0.0,-sGA,cGA},{ 0.0,-cGA,-sGA}};
...@@ -2473,7 +2468,7 @@ dPXmmc/dphi= ...@@ -2473,7 +2468,7 @@ dPXmmc/dphi=
dMB_goniometerAxial.print(10, 5); dMB_goniometerAxial.print(10, 5);
System.out.println("interParameterDerivatives[7]="+sprintfArray(interParameterDerivatives[7])); System.out.println("interParameterDerivatives[7]="+sprintfArray(interParameterDerivatives[7]));
} }
} else interParameterDerivatives[7]=null; } else interParameterDerivatives[7]=null;
//8 public double interAxisDistance; // distance in mm between two goniometer axes //8 public double interAxisDistance; // distance in mm between two goniometer axes
if (mask[8]) { if (mask[8]) {
double [][] adT2_interAxisDistance={{0.0},{0.0},{1.0}}; double [][] adT2_interAxisDistance={{0.0},{0.0},{1.0}};
...@@ -2488,13 +2483,13 @@ dPXmmc/dphi= ...@@ -2488,13 +2483,13 @@ dPXmmc/dphi=
dMB_interAxisDistance.print(10, 5); dMB_interAxisDistance.print(10, 5);
System.out.println("interParameterDerivatives[8]="+sprintfArray(interParameterDerivatives[8])); System.out.println("interParameterDerivatives[8]="+sprintfArray(interParameterDerivatives[8]));
} }
} else interParameterDerivatives[8]=null; } else interParameterDerivatives[8]=null;
//9 public double interAxisAngle; // angle in degrees between two goniometer axes minus 90. negative if "vertical" axis is rotated //9 public double interAxisAngle; // angle in degrees between two goniometer axes minus 90. negative if "vertical" axis is rotated
if (mask[9]) { if (mask[9]) {
double [][] adR5_interAxisAngle={{-sGIAA,cGIAA,0.0},{-cGIAA,-sGIAA,0.0},{0.0,0.0,0.0}}; double [][] adR5_interAxisAngle={{-sGIAA,cGIAA,0.0},{-cGIAA,-sGIAA,0.0},{0.0,0.0,0.0}};
Matrix dR5_interAxisAngle=new Matrix(adR5_interAxisAngle); Matrix dR5_interAxisAngle=new Matrix(adR5_interAxisAngle);
Matrix dMA_interAxisAngle=R8.times(R7.times(R6.times(dR5_interAxisAngle.times(R4.times(R3.times(R2.times(R1))))))); Matrix dMA_interAxisAngle=R8.times(R7.times(R6.times(dR5_interAxisAngle.times(R4.times(R3.times(R2.times(R1)))))));
Matrix dMB_interAxisAngle=R8.times(R7.times(R6.times(dR5_interAxisAngle.times(T2.plus(R4.times(T1)))))); Matrix dMB_interAxisAngle=R8.times(R7.times(R6.times(dR5_interAxisAngle.times(T2.plus(R4.times(T1))))));
interParameterDerivatives[9]=d_parametersFromMAMB(dMA_interAxisAngle,dMB_interAxisAngle,MA,MB,true); // all after 6 are 0; interParameterDerivatives[9]=d_parametersFromMAMB(dMA_interAxisAngle,dMB_interAxisAngle,MA,MB,true); // all after 6 are 0;
if (this.debugLevel>2) { if (this.debugLevel>2) {
System.out.println("dMA_interAxisAngle:"); System.out.println("dMA_interAxisAngle:");
...@@ -2503,10 +2498,10 @@ dPXmmc/dphi= ...@@ -2503,10 +2498,10 @@ dPXmmc/dphi=
dMB_interAxisAngle.print(10, 5); dMB_interAxisAngle.print(10, 5);
System.out.println("interParameterDerivatives[9]="+sprintfArray(interParameterDerivatives[9])); System.out.println("interParameterDerivatives[9]="+sprintfArray(interParameterDerivatives[9]));
} }
} else interParameterDerivatives[9]=null; } else interParameterDerivatives[9]=null;
//10 public double horAxisErrPhi; // angle in degrees "horizontal" goniometer axis is rotated around target Y axis from target X axis (CW) //10 public double horAxisErrPhi; // angle in degrees "horizontal" goniometer axis is rotated around target Y axis from target X axis (CW)
// change sHAEPH to rotate like theta /1 0 0 /0 c s/ 0 -s c/ (derivative -/0 0 0 /0 -s c/ 0 -c -s/ // change sHAEPH to rotate like theta /1 0 0 /0 c s/ 0 -s c/ (derivative -/0 0 0 /0 -s c/ 0 -c -s/
if (mask[10]) { if (mask[10]) {
double [][] adR8_horAxisErrPhi_tripod= {{0.0, 0.0, 0.0},{0.0,-sHAEPH,cHAEPH},{ 0.0,-cHAEPH,-sHAEPH}}; double [][] adR8_horAxisErrPhi_tripod= {{0.0, 0.0, 0.0},{0.0,-sHAEPH,cHAEPH},{ 0.0,-cHAEPH,-sHAEPH}};
double [][] adR8_horAxisErrPhi_goniometer={{-sHAEPH,0.0,cHAEPH},{0.0, 0.0, 0.0},{-cHAEPH, 0.0,-sHAEPH}}; double [][] adR8_horAxisErrPhi_goniometer={{-sHAEPH,0.0,cHAEPH},{0.0, 0.0, 0.0},{-cHAEPH, 0.0,-sHAEPH}};
...@@ -2521,7 +2516,7 @@ dPXmmc/dphi= ...@@ -2521,7 +2516,7 @@ dPXmmc/dphi=
dMB_horAxisErrPhi.print(10, 5); dMB_horAxisErrPhi.print(10, 5);
System.out.println("interParameterDerivatives[10]="+sprintfArray(interParameterDerivatives[10])); System.out.println("interParameterDerivatives[10]="+sprintfArray(interParameterDerivatives[10]));
} }
} else interParameterDerivatives[10]=null; } else interParameterDerivatives[10]=null;
//11 public double horAxisErrPsi; // angle in degrees "horizontal" goniometer axis is rotated around moving X axis (up) //11 public double horAxisErrPsi; // angle in degrees "horizontal" goniometer axis is rotated around moving X axis (up)
if (mask[11]) { if (mask[11]) {
double [][] adR7_horAxisErrPsi={{-sHAEPS,cHAEPS,0.0},{-cHAEPS,-sHAEPS,0.0},{0.0,0.0,0.0}}; double [][] adR7_horAxisErrPsi={{-sHAEPS,cHAEPS,0.0},{-cHAEPS,-sHAEPS,0.0},{0.0,0.0,0.0}};
...@@ -2536,7 +2531,7 @@ dPXmmc/dphi= ...@@ -2536,7 +2531,7 @@ dPXmmc/dphi=
dMB_horAxisErrPsi.print(10, 5); dMB_horAxisErrPsi.print(10, 5);
System.out.println("interParameterDerivatives[11]="+sprintfArray(interParameterDerivatives[11])); System.out.println("interParameterDerivatives[11]="+sprintfArray(interParameterDerivatives[11]));
} }
} else interParameterDerivatives[11]=null; } else interParameterDerivatives[11]=null;
// // R1 | R2 | R3 | R4 | R5 | R6 | R7 | R8 || T0 | T1 | T2 | T3 | // // R1 | R2 | R3 | R4 | R5 | R6 | R7 | R8 || T0 | T1 | T2 | T3 |
//12 public double entrancePupilForward // | | | | | | | || + | | | | //12 public double entrancePupilForward // | | | | | | | || + | | | |
//13 public double centerAboveHorizontal // | | | | | | | || | + | | | //13 public double centerAboveHorizontal // | | | | | | | || | + | | |
...@@ -2554,8 +2549,8 @@ dPXmmc/dphi= ...@@ -2554,8 +2549,8 @@ dPXmmc/dphi=
dMB_entrancePupilForward.print(10, 5); dMB_entrancePupilForward.print(10, 5);
System.out.println("interParameterDerivatives[12]="+sprintfArray(interParameterDerivatives[12])); System.out.println("interParameterDerivatives[12]="+sprintfArray(interParameterDerivatives[12]));
} }
} else interParameterDerivatives[12]=null; } else interParameterDerivatives[12]=null;
if (mask[13]) { if (mask[13]) {
double [][] adT1_centerAboveHorizontal={{0.0},{1.0},{0.0}}; double [][] adT1_centerAboveHorizontal={{0.0},{1.0},{0.0}};
Matrix dT1_centerAboveHorizontal=new Matrix(adT1_centerAboveHorizontal); Matrix dT1_centerAboveHorizontal=new Matrix(adT1_centerAboveHorizontal);
...@@ -2569,9 +2564,9 @@ dPXmmc/dphi= ...@@ -2569,9 +2564,9 @@ dPXmmc/dphi=
dMB_centerAboveHorizontal.print(10, 5); dMB_centerAboveHorizontal.print(10, 5);
System.out.println("interParameterDerivatives[13]="+sprintfArray(interParameterDerivatives[13])); System.out.println("interParameterDerivatives[13]="+sprintfArray(interParameterDerivatives[13]));
} }
} else interParameterDerivatives[13]=null; } else interParameterDerivatives[13]=null;
//14 x public double [] GXYZ=null; // coordinates (in mm) of the goniometer horizontal axis closest to the moving one in target system //14 x public double [] GXYZ=null; // coordinates (in mm) of the goniometer horizontal axis closest to the moving one in target system
if (mask[14]) { if (mask[14]) {
double [][] adT3_GXYZ0={{1.0},{0.0},{0.0}}; double [][] adT3_GXYZ0={{1.0},{0.0},{0.0}};
...@@ -2585,7 +2580,7 @@ dPXmmc/dphi= ...@@ -2585,7 +2580,7 @@ dPXmmc/dphi=
dMB_GXYZ0.print(10, 5); dMB_GXYZ0.print(10, 5);
System.out.println("interParameterDerivatives[14]="+sprintfArray(interParameterDerivatives[14])); System.out.println("interParameterDerivatives[14]="+sprintfArray(interParameterDerivatives[14]));
} }
} else interParameterDerivatives[14]=null; } else interParameterDerivatives[14]=null;
//13 y //13 y
if (mask[15]) { if (mask[15]) {
// double [][] adT3_GXYZ1={{0.0},{1.0},{0.0}}; // double [][] adT3_GXYZ1={{0.0},{1.0},{0.0}};
...@@ -2601,7 +2596,7 @@ dPXmmc/dphi= ...@@ -2601,7 +2596,7 @@ dPXmmc/dphi=
dMB_GXYZ1.print(10, 5); dMB_GXYZ1.print(10, 5);
System.out.println("interParameterDerivatives[15]="+sprintfArray(interParameterDerivatives[15])); System.out.println("interParameterDerivatives[15]="+sprintfArray(interParameterDerivatives[15]));
} }
} else interParameterDerivatives[15]=null; } else interParameterDerivatives[15]=null;
//14 z //14 z
if (mask[16]) { if (mask[16]) {
// double [][] adT3_GXYZ2={{0.0},{0.0},{1.0}}; // double [][] adT3_GXYZ2={{0.0},{0.0},{1.0}};
...@@ -2616,7 +2611,7 @@ dPXmmc/dphi= ...@@ -2616,7 +2611,7 @@ dPXmmc/dphi=
dMB_GXYZ2.print(10, 5); dMB_GXYZ2.print(10, 5);
System.out.println("interParameterDerivatives[16]="+sprintfArray(interParameterDerivatives[16])); System.out.println("interParameterDerivatives[16]="+sprintfArray(interParameterDerivatives[16]));
} }
} else interParameterDerivatives[16]=null; } else interParameterDerivatives[16]=null;
// now fill the rest, unchanged parameters // now fill the rest, unchanged parameters
/* /*
int numInputs=22; //was 21 parameters in subcamera+... int numInputs=22; //was 21 parameters in subcamera+...
...@@ -2633,10 +2628,10 @@ dPXmmc/dphi= ...@@ -2633,10 +2628,10 @@ dPXmmc/dphi=
//24 (22) public double distortionA=0.0; // r^4 (normalized to focal length or to sensor half width?) //24 (22) public double distortionA=0.0; // r^4 (normalized to focal length or to sensor half width?)
//25 (23) public double distortionB=0.0; // r^3 //25 (23) public double distortionB=0.0; // r^3
//26 (24) public double distortionC=0.0; // r^2 //26 (24) public double distortionC=0.0; // r^2
//27..52 - non-radial parameters //27..52 - non-radial parameters
// for (int inpPar=15; inpPar<getNumInputs(); inpPar++){ // for (int inpPar=15; inpPar<getNumInputs(); inpPar++){
for (int inpPar=17; inpPar<getNumInputs(); inpPar++){ // OK with A8. Should be OK with non-radial parameters ((27..52) also for (int inpPar=17; inpPar<getNumInputs(); inpPar++){ // OK with A8. Should be OK with non-radial parameters ((27..52) also
if (mask[inpPar]){ if (mask[inpPar]){
interParameterDerivatives[inpPar]=new double[getNumOutputs()]; interParameterDerivatives[inpPar]=new double[getNumOutputs()];
for (int outPar=0; outPar<getNumOutputs(); outPar++){ for (int outPar=0; outPar<getNumOutputs(); outPar++){
...@@ -2649,7 +2644,7 @@ dPXmmc/dphi= ...@@ -2649,7 +2644,7 @@ dPXmmc/dphi=
} }
} }
public double [] parametersFromMAMB(Matrix MA, Matrix MB){ public double [] parametersFromMAMB(Matrix MA, Matrix MB){
double [] result= new double [getNumOutputs()]; // only first 6 are used double [] result= new double [getNumOutputs()]; // only first 6 are used
for (int i=6; i<getNumOutputs();i++) result[i]=0.0; for (int i=6; i<getNumOutputs();i++) result[i]=0.0;
...@@ -2705,7 +2700,7 @@ dPXmmc/dphi= ...@@ -2705,7 +2700,7 @@ dPXmmc/dphi=
return result; return result;
} }
/** /**
* *
* @param d_MA differential of the rotational matrix MA by some parameter * @param d_MA differential of the rotational matrix MA by some parameter
* @param d_MB differential of the translational matrix MB by some parameter * @param d_MB differential of the translational matrix MB by some parameter
* @param MA - rotation matrix * @param MA - rotation matrix
...@@ -2812,8 +2807,7 @@ dPXmmc/dphi= ...@@ -2812,8 +2807,7 @@ dPXmmc/dphi=
for (int i=0;i<arr.length;i++) result+= ((i>0)?", ":"")+arr[i]; for (int i=0;i<arr.length;i++) result+= ((i>0)?", ":"")+arr[i];
return "["+result+"]"; return "["+result+"]";
} }
public int getNumInputs(){return numInputs;} public int getNumInputs(){return numInputs;}
public int getNumOutputs(){return numOutputs;} public int getNumOutputs(){return numOutputs;}
} }
\ No newline at end of file
...@@ -62,8 +62,8 @@ import ij.gui.GenericDialog; ...@@ -62,8 +62,8 @@ import ij.gui.GenericDialog;
// non-adjustable parameters, not parts of vector // non-adjustable parameters, not parts of vector
public int numStations; public int numStations;
public double [] stationWeight; // reprojection error weights (close station - relax errors) 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 private boolean is_tripod= false; // when true - make goniometerHorizontal rotation around "vertical" axis and "goniometerAxial" - around
public boolean cartesian=false; // private boolean cartesian=false; //
// rotated horizontal. // rotated horizontal.
private int defaultSensorWidth= 2592; private int defaultSensorWidth= 2592;
private int defaultSensorHeight= 1936; private int defaultSensorHeight= 1936;
...@@ -73,7 +73,7 @@ import ij.gui.GenericDialog; ...@@ -73,7 +73,7 @@ import ij.gui.GenericDialog;
public double maskBlurSigma= -3; //2.0; // blur sensor masks (>0 - pixels, <0 - in grid units) public double maskBlurSigma= -3; //2.0; // blur sensor masks (>0 - pixels, <0 - in grid units)
public double badNodeThreshold=0.1; // filter out grid nodes with difference from quadratically predicted from 8 neighbors in pixels 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 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 minimalValidNodes=10; // 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 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 weightMultiExponent= 1.0;
public double weightDiameterExponent=1.0; // if( >0) use grid diameter to scale weights of this image public double weightDiameterExponent=1.0; // if( >0) use grid diameter to scale weights of this image
...@@ -84,6 +84,7 @@ import ij.gui.GenericDialog; ...@@ -84,6 +84,7 @@ import ij.gui.GenericDialog;
public double balanceChannelWeightsMode=-1.0; // <0 - use defaults, 0 - keep, >0 balance by number of points to this power 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 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 double removeOverRMSNonweighted=4.0; // error is not multiplied (no more permissions on tyhe borders
public boolean invertUnmarkedLwirGrid = true; // LWIR grid currently is saved shifted (not compensating color inversion)
public int [] extrinsicIndices={6,7,8,9,10,11,12,13,14,15,16}; //support variations public int [] extrinsicIndices={6,7,8,9,10,11,12,13,14,15,16}; //support variations
public double [][] variationsDefaults={ public double [][] variationsDefaults={
null, // 0 null, // 0
...@@ -104,6 +105,19 @@ import ij.gui.GenericDialog; ...@@ -104,6 +105,19 @@ import ij.gui.GenericDialog;
{10.0,2.0,0.0,1.0}, // 15 GXYZ1 {10.0,2.0,0.0,1.0}, // 15 GXYZ1
{10.0,2.0,0.0,1.0} // 16 GXYZ2 {10.0,2.0,0.0,1.0} // 16 GXYZ2
}; };
public boolean isTripod() {
return is_tripod;
}
public boolean isCartesian() {
return cartesian;
}
public boolean isLwirUnmarkedInverted() {
return invertUnmarkedLwirGrid;
}
public int tiltIndex=6; public int tiltIndex=6;
private ParameterVariationCosts [] parameterVariationCosts=null; private ParameterVariationCosts [] parameterVariationCosts=null;
...@@ -337,7 +351,8 @@ import ij.gui.GenericDialog; ...@@ -337,7 +351,8 @@ import ij.gui.GenericDialog;
double shrinkBlurLevel, double shrinkBlurLevel,
double balanceChannelWeightsMode, double balanceChannelWeightsMode,
double removeOverRMS, double removeOverRMS,
double removeOverRMSNonweighted double removeOverRMSNonweighted,
boolean invertUnmarkedLwirGrid
){ ){
double [] GXYZ={GXYZ_0,GXYZ_1,GXYZ_2}; double [] GXYZ={GXYZ_0,GXYZ_1,GXYZ_2};
setSameEyesisCameraParameters ( setSameEyesisCameraParameters (
...@@ -372,7 +387,8 @@ import ij.gui.GenericDialog; ...@@ -372,7 +387,8 @@ import ij.gui.GenericDialog;
shrinkBlurLevel, shrinkBlurLevel,
balanceChannelWeightsMode, balanceChannelWeightsMode,
removeOverRMS, removeOverRMS,
removeOverRMSNonweighted removeOverRMSNonweighted,
invertUnmarkedLwirGrid
); );
} }
public EyesisCameraParameters ( public EyesisCameraParameters (
...@@ -407,7 +423,8 @@ import ij.gui.GenericDialog; ...@@ -407,7 +423,8 @@ import ij.gui.GenericDialog;
double shrinkBlurLevel, double shrinkBlurLevel,
double balanceChannelWeightsMode, double balanceChannelWeightsMode,
double removeOverRMS, double removeOverRMS,
double removeOverRMSNonweighted double removeOverRMSNonweighted,
boolean invertUnmarkedLwirGrid
){ ){
setSameEyesisCameraParameters ( setSameEyesisCameraParameters (
numStations, numStations,
...@@ -441,7 +458,8 @@ import ij.gui.GenericDialog; ...@@ -441,7 +458,8 @@ import ij.gui.GenericDialog;
shrinkBlurLevel, shrinkBlurLevel,
balanceChannelWeightsMode, balanceChannelWeightsMode,
removeOverRMS, removeOverRMS,
removeOverRMSNonweighted removeOverRMSNonweighted,
invertUnmarkedLwirGrid
); );
} }
void setSameEyesisCameraParameters ( void setSameEyesisCameraParameters (
...@@ -476,10 +494,11 @@ import ij.gui.GenericDialog; ...@@ -476,10 +494,11 @@ import ij.gui.GenericDialog;
double shrinkBlurLevel, double shrinkBlurLevel,
double balanceChannelWeightsMode, double balanceChannelWeightsMode,
double removeOverRMS, double removeOverRMS,
double removeOverRMSNonweighted double removeOverRMSNonweighted,
boolean invertUnmarkedLwirGrid
){ ){
this.numStations=numStations; this.numStations=numStations;
this.isTripod=isTripod; this.is_tripod=isTripod;
this.cartesian = cartesian; // Need to set each subcamera? this.cartesian = cartesian; // Need to set each subcamera?
this.defaultSensorWidth=defaultSensorWidth; this.defaultSensorWidth=defaultSensorWidth;
this.defaultSensorHeight=defaultSensorHeight; this.defaultSensorHeight=defaultSensorHeight;
...@@ -543,7 +562,7 @@ import ij.gui.GenericDialog; ...@@ -543,7 +562,7 @@ import ij.gui.GenericDialog;
EyesisCameraParameters source, EyesisCameraParameters source,
EyesisCameraParameters destination) { EyesisCameraParameters destination) {
destination.numStations=newNumStations; destination.numStations=newNumStations;
destination.isTripod=source.isTripod; destination.is_tripod=source.is_tripod;
destination.defaultSensorWidth=source.defaultSensorWidth; destination.defaultSensorWidth=source.defaultSensorWidth;
destination.defaultSensorHeight=source.defaultSensorHeight; destination.defaultSensorHeight=source.defaultSensorHeight;
destination.shrinkGridForMask=source.shrinkGridForMask; //shrink detected grids by one point for/vert this number of times before calculating masks destination.shrinkGridForMask=source.shrinkGridForMask; //shrink detected grids by one point for/vert this number of times before calculating masks
...@@ -561,6 +580,7 @@ import ij.gui.GenericDialog; ...@@ -561,6 +580,7 @@ import ij.gui.GenericDialog;
destination.shrinkBlurLevel=source.shrinkBlurLevel; destination.shrinkBlurLevel=source.shrinkBlurLevel;
destination.balanceChannelWeightsMode=source.balanceChannelWeightsMode; destination.balanceChannelWeightsMode=source.balanceChannelWeightsMode;
destination.removeOverRMSNonweighted=source.removeOverRMSNonweighted; destination.removeOverRMSNonweighted=source.removeOverRMSNonweighted;
destination.invertUnmarkedLwirGrid=source.invertUnmarkedLwirGrid;
destination.goniometerHorizontal=new double[destination.numStations]; destination.goniometerHorizontal=new double[destination.numStations];
destination.goniometerAxial=new double[destination.numStations]; destination.goniometerAxial=new double[destination.numStations];
destination.interAxisDistance=new double[destination.numStations]; destination.interAxisDistance=new double[destination.numStations];
...@@ -598,7 +618,7 @@ import ij.gui.GenericDialog; ...@@ -598,7 +618,7 @@ import ij.gui.GenericDialog;
} }
public void setProperties(String prefix,Properties properties){ public void setProperties(String prefix,Properties properties){
properties.setProperty(prefix+"isTripod",this.isTripod+""); properties.setProperty(prefix+"isTripod",this.is_tripod+"");
properties.setProperty(prefix+"cartesian",this.cartesian+""); properties.setProperty(prefix+"cartesian",this.cartesian+"");
properties.setProperty(prefix+"defaultSensorWidth",this.defaultSensorWidth+""); properties.setProperty(prefix+"defaultSensorWidth",this.defaultSensorWidth+"");
properties.setProperty(prefix+"defaultSensorHeight",this.defaultSensorHeight+""); properties.setProperty(prefix+"defaultSensorHeight",this.defaultSensorHeight+"");
...@@ -618,6 +638,7 @@ import ij.gui.GenericDialog; ...@@ -618,6 +638,7 @@ import ij.gui.GenericDialog;
properties.setProperty(prefix+"balanceChannelWeightsMode",this.balanceChannelWeightsMode+""); properties.setProperty(prefix+"balanceChannelWeightsMode",this.balanceChannelWeightsMode+"");
properties.setProperty(prefix+"removeOverRMS",this.removeOverRMS+""); properties.setProperty(prefix+"removeOverRMS",this.removeOverRMS+"");
properties.setProperty(prefix+"removeOverRMSNonweighted",this.removeOverRMSNonweighted+""); properties.setProperty(prefix+"removeOverRMSNonweighted",this.removeOverRMSNonweighted+"");
properties.setProperty(prefix+"invertUnmarkedLwirGrid",this.invertUnmarkedLwirGrid+"");
properties.setProperty(prefix+"numSubCameras",this.eyesisSubCameras[0].length+""); properties.setProperty(prefix+"numSubCameras",this.eyesisSubCameras[0].length+"");
properties.setProperty(prefix+"numStations",this.numStations+""); properties.setProperty(prefix+"numStations",this.numStations+"");
for (int numStation=0;numStation<this.numStations;numStation++){ for (int numStation=0;numStation<this.numStations;numStation++){
...@@ -641,7 +662,7 @@ import ij.gui.GenericDialog; ...@@ -641,7 +662,7 @@ import ij.gui.GenericDialog;
} }
public void getProperties(String prefix,Properties properties){ public void getProperties(String prefix,Properties properties){
if (properties.getProperty(prefix+"isTripod")!=null) if (properties.getProperty(prefix+"isTripod")!=null)
this.isTripod=Boolean.parseBoolean(properties.getProperty(prefix+"isTripod")); this.is_tripod=Boolean.parseBoolean(properties.getProperty(prefix+"isTripod"));
if (properties.getProperty(prefix+"cartesian")!=null) if (properties.getProperty(prefix+"cartesian")!=null)
this.cartesian=Boolean.parseBoolean(properties.getProperty(prefix+"cartesian")); this.cartesian=Boolean.parseBoolean(properties.getProperty(prefix+"cartesian"));
// For old compatibility // For old compatibility
...@@ -690,6 +711,9 @@ import ij.gui.GenericDialog; ...@@ -690,6 +711,9 @@ import ij.gui.GenericDialog;
this.removeOverRMS=Double.parseDouble(properties.getProperty(prefix+"removeOverRMS")); this.removeOverRMS=Double.parseDouble(properties.getProperty(prefix+"removeOverRMS"));
if (properties.getProperty(prefix+"removeOverRMSNonweighted")!=null) if (properties.getProperty(prefix+"removeOverRMSNonweighted")!=null)
this.removeOverRMSNonweighted=Double.parseDouble(properties.getProperty(prefix+"removeOverRMSNonweighted")); this.removeOverRMSNonweighted=Double.parseDouble(properties.getProperty(prefix+"removeOverRMSNonweighted"));
if (properties.getProperty(prefix+"invertUnmarkedLwirGrid")!=null)
this.invertUnmarkedLwirGrid=Boolean.parseBoolean(properties.getProperty(prefix+"invertUnmarkedLwirGrid"));
boolean multiStation=true; // new default boolean multiStation=true; // new default
int newNumStations=1; int newNumStations=1;
int numSubCameras=0; int numSubCameras=0;
...@@ -799,14 +823,14 @@ import ij.gui.GenericDialog; ...@@ -799,14 +823,14 @@ import ij.gui.GenericDialog;
modelChoice[0]="--- keep current ---"; modelChoice[0]="--- keep current ---";
for (int i=0;i<distortionModelDescriptions.length;i++) modelChoice[i+1]=distortionModelDescriptions[i]; for (int i=0;i<distortionModelDescriptions.length;i++) modelChoice[i+1]=distortionModelDescriptions[i];
gd.addChoice("Change camera distortion model for all channels", modelChoice, modelChoice[0]); gd.addChoice("Change camera distortion model for all channels", modelChoice, modelChoice[0]);
gd.addCheckbox("Tripod mode (first vertical axis, then horizontal), changes meaning of the next 2 fields",this.isTripod); gd.addCheckbox("Tripod mode (first vertical axis, then horizontal), changes meaning of the next 2 fields",this.is_tripod);
gd.addMessage("=== Camera parameters to be fitted ==="); gd.addMessage("=== Camera parameters to be fitted ===");
for (int numStation=0;numStation<this.numStations;numStation++) { for (int numStation=0;numStation<this.numStations;numStation++) {
if (this.numStations>1){ if (this.numStations>1){
gd.addMessage("--- Station number "+numStation+" ---"); gd.addMessage("--- Station number "+numStation+" ---");
gd.addNumericField("Station reprojection errors weight", 100*this.stationWeight[numStation], 1,5,"%"); gd.addNumericField("Station reprojection errors weight", 100*this.stationWeight[numStation], 1,5,"%");
} }
if (this.isTripod) { if (this.is_tripod) {
gd.addNumericField("Tripod rotation around vertical axis (clockwise from top - positive)",this.goniometerHorizontal[numStation], 3,7,"degrees"); 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"); gd.addNumericField("Tripod rotation around horizontal axis (camera up - positive)", this.goniometerAxial[numStation], 3,7,"degrees");
} else { } else {
...@@ -816,7 +840,7 @@ import ij.gui.GenericDialog; ...@@ -816,7 +840,7 @@ import ij.gui.GenericDialog;
gd.addNumericField("Distance between goniometer axes", this.interAxisDistance[numStation], 3,7,"mm"); 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"); gd.addNumericField("Angle error between goniometer axes (<0 if vertical axis rotated CW )",this.interAxisAngle[numStation], 3,7,"degrees");
if (this.isTripod) { if (this.is_tripod) {
gd.addNumericField("Vertical tripod axis tilt from true vertical", this.horAxisErrPhi[numStation], 3,7,"degrees"); 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"); gd.addNumericField("Vertical tripod axis roll error from true vertical", this.horAxisErrPsi[numStation], 3,7,"degrees");
} else { } else {
...@@ -852,6 +876,7 @@ import ij.gui.GenericDialog; ...@@ -852,6 +876,7 @@ import ij.gui.GenericDialog;
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("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("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("Same, not weghted (not more permissive near the borders with low weight)", this.removeOverRMSNonweighted, 2,6,"xRMS");
gd.addCheckbox ("Unmared grid files for LWIR is saved invereted", this.invertUnmarkedLwirGrid);
gd.addNumericField("Number of sub-camera modules", this.eyesisSubCameras[0].length, 0,2,""); 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.addNumericField("Number of sub-camera module to edit (<=0 - none)", nextSubCamera, 0,2,"");
gd.enableYesNoCancel("OK", "Done"); gd.enableYesNoCancel("OK", "Done");
...@@ -868,7 +893,7 @@ import ij.gui.GenericDialog; ...@@ -868,7 +893,7 @@ import ij.gui.GenericDialog;
} }
} }
this.isTripod= gd.getNextBoolean(); this.is_tripod= gd.getNextBoolean();
for (int numStation=0;numStation<this.numStations;numStation++) { for (int numStation=0;numStation<this.numStations;numStation++) {
if (this.numStations>1){ if (this.numStations>1){
this.stationWeight[numStation]=0.01*gd.getNextNumber(); this.stationWeight[numStation]=0.01*gd.getNextNumber();
...@@ -904,6 +929,7 @@ import ij.gui.GenericDialog; ...@@ -904,6 +929,7 @@ import ij.gui.GenericDialog;
this.balanceChannelWeightsMode= gd.getNextNumber(); this.balanceChannelWeightsMode= gd.getNextNumber();
this.removeOverRMS = gd.getNextNumber(); this.removeOverRMS = gd.getNextNumber();
this.removeOverRMSNonweighted= gd.getNextNumber(); this.removeOverRMSNonweighted= gd.getNextNumber();
this.invertUnmarkedLwirGrid = gd.getNextBoolean();
int numSubCams= (int) gd.getNextNumber(); int numSubCams= (int) gd.getNextNumber();
int numSubCam= (int) gd.getNextNumber(); int numSubCam= (int) gd.getNextNumber();
if (numSubCams!=this.eyesisSubCameras[0].length){ if (numSubCams!=this.eyesisSubCameras[0].length){
...@@ -2504,8 +2530,8 @@ import ij.gui.GenericDialog; ...@@ -2504,8 +2530,8 @@ import ij.gui.GenericDialog;
public int offset_channel = 4; // 0; public int offset_channel = 4; // 0;
public int new_subcam = 1; // new subcamera number public int new_subcam = 1; // new subcamera number
public double offset_height = 50.8; public double offset_height = 50.8;
public double offset_right = -35.0; //vnir -35., lwir +35.0 public double offset_right = -35.0; //eo -35., lwir +35.0
public double offset_forward = 15.0; //vnir +??, lwir -?? public double offset_forward = 15.0; //eo +??, lwir -??
public double offset_heading = 0.0; public double offset_heading = 0.0;
public double offset_elevation = 0.0; public double offset_elevation = 0.0;
public double offset_roll = 0.0; public double offset_roll = 0.0;
......
...@@ -5476,7 +5476,7 @@ public class EyesisCorrectionParameters { ...@@ -5476,7 +5476,7 @@ public class EyesisCorrectionParameters {
gd.addMessage ("Unity up vector in camera coordinate system (x - right, y - up, z - to camera): {"+ gd.addMessage ("Unity up vector in camera coordinate system (x - right, y - up, z - to camera): {"+
this.vertical_xyz[0]+","+this.vertical_xyz[1]+","+this.vertical_xyz[2]+"}"); this.vertical_xyz[0]+","+this.vertical_xyz[1]+","+this.vertical_xyz[2]+"}");
gd.addTab ("LWIR", "parameters for LWIR/VNIR 8-camera rig"); gd.addTab ("LWIR", "parameters for LWIR/EO 8-camera rig");
this.lwir.dialogQuestions(gd); this.lwir.dialogQuestions(gd);
// gd.buildDialog(); // gd.buildDialog();
......
...@@ -362,4 +362,12 @@ import java.util.Properties; ...@@ -362,4 +362,12 @@ import java.util.Properties;
updateCartesian(); updateCartesian();
this.cartesian = cartesian; this.cartesian = cartesian;
} }
public double getPixelSize() {
return this.pixelSize;
}
public double getDistortionRadius() {
return this.distortionRadius;
}
} }
...@@ -496,12 +496,12 @@ public class LwirReader { ...@@ -496,12 +496,12 @@ public class LwirReader {
if (lrp.lwir_ffc) { if (lrp.lwir_ffc) {
calibrate(lrp); // seems to work. test calibration duration and if any images are sent during calibration calibrate(lrp); // seems to work. test calibration duration and if any images are sent during calibration
} }
int num_frames = lrp.avg_number + lrp.vnir_lag + 2 * lrp.max_frame_diff; int num_frames = lrp.avg_number + lrp.eo_lag + 2 * lrp.max_frame_diff;
ImagePlus [][] imps = readAllMultiple( ImagePlus [][] imps = readAllMultiple(
num_frames, num_frames,
// lrp.lwir_telemetry, // lrp.lwir_telemetry,
false, // final boolean show, false, // final boolean show,
lrp.vnir_scale); lrp.eo_scale);
if (imps == null) { if (imps == null) {
LOGGER.error("acquire(): failed to acquire images"); LOGGER.error("acquire(): failed to acquire images");
return null; return null;
...@@ -521,9 +521,9 @@ public class LwirReader { ...@@ -521,9 +521,9 @@ public class LwirReader {
LOGGER.warn(String.format("LWIR channel %d time from FFC: %.3f", chn, after_ffc[chn])); LOGGER.warn(String.format("LWIR channel %d time from FFC: %.3f", chn, after_ffc[chn]));
} }
int [] lags = new int [lrp.lwir_channels.length + lrp.vnir_channels.length]; int [] lags = new int [lrp.lwir_channels.length + lrp.eo_channels.length];
for (int i = 0; i < lags.length; i++) { for (int i = 0; i < lags.length; i++) {
lags[i] = (i >= lrp.lwir_channels.length) ? lrp.vnir_lag : 0; lags[i] = (i >= lrp.lwir_channels.length) ? lrp.eo_lag : 0;
} }
ImagePlus [][] imps_sync = matchSets( ImagePlus [][] imps_sync = matchSets(
imps, imps,
...@@ -605,10 +605,10 @@ public class LwirReader { ...@@ -605,10 +605,10 @@ public class LwirReader {
public boolean programLWIRCamera(LwirReaderParameters lrp) { public boolean programLWIRCamera(LwirReaderParameters lrp) {
int lwir_master_port = 0; int lwir_master_port = 0;
int vnir_master_port = 0; int eo_master_port = 0;
int num_lwir = lrp.lwir_channels.length; int num_lwir = lrp.lwir_channels.length;
int num_vnir = lrp.vnir_channels.length; int num_eo = lrp.eo_channels.length;
final String [] urls = new String [num_lwir + num_vnir]; final String [] urls = new String [num_lwir + num_eo];
for (int chn:lrp.lwir_channels) { for (int chn:lrp.lwir_channels) {
urls[chn] = "http://"+lrp.lwir_ip+"/parsedit.php?immediate&sensor_port="+chn+ urls[chn] = "http://"+lrp.lwir_ip+"/parsedit.php?immediate&sensor_port="+chn+
"&BITS=16"+ "&BITS=16"+
...@@ -623,21 +623,21 @@ public class LwirReader { ...@@ -623,21 +623,21 @@ public class LwirReader {
"&XMIT_TIMESTAMP=1*0"; "&XMIT_TIMESTAMP=1*0";
} }
} }
for (int chn:lrp.vnir_channels) { for (int chn:lrp.eo_channels) {
int minExposure=10; // usec int minExposure=10; // usec
int maxExposure=1000000; //usec int maxExposure=1000000; //usec
int minGain=(int) (0x10000*1.0); int minGain=(int) (0x10000*1.0);
int maxGain=(int) (0x10000*15.75); int maxGain=(int) (0x10000*15.75);
int minScale=0; int minScale=0;
int maxScale=(int) (0x10000*4.0); int maxScale=(int) (0x10000*4.0);
int exposure= (int) (Math.round(1000*lrp.vnir_exposure_ms * lrp.vnir_exp_corr[chn])); int exposure= (int) (Math.round(1000*lrp.eo_exposure_ms * lrp.eo_exp_corr[chn]));
int autoExposureMax= (int) (Math.round(1000*lrp.vnir_max_autoexp_ms)); int autoExposureMax= (int) (Math.round(1000*lrp.eo_max_autoexp_ms));
int gain= (int) (Math.round(0x10000*lrp.vnir_gain_g)); int gain= (int) (Math.round(0x10000*lrp.eo_gain_g));
int rScale= (int) (Math.round(0x10000*lrp.vnir_gain_rg*lrp.vnir_gcorr_rbgb[3*chn+0])); int rScale= (int) (Math.round(0x10000*lrp.eo_gain_rg*lrp.eo_gcorr_rbgb[3*chn+0]));
int bScale= (int) (Math.round(0x10000*lrp.vnir_gain_bg*lrp.vnir_gcorr_rbgb[3*chn+1])); int bScale= (int) (Math.round(0x10000*lrp.eo_gain_bg*lrp.eo_gcorr_rbgb[3*chn+1]));
int gScale= (int) (Math.round(0x10000* lrp.vnir_gcorr_rbgb[3*chn+2])); int gScale= (int) (Math.round(0x10000* lrp.eo_gcorr_rbgb[3*chn+2]));
int autoExp= lrp.vnir_autoexp?1:0; int autoExp= lrp.eo_autoexp?1:0;
int autoWB= lrp.vnir_whitebal?1:0; int autoWB= lrp.eo_whitebal?1:0;
if (exposure<minExposure) exposure=minExposure; else if (exposure>maxExposure) exposure=maxExposure; if (exposure<minExposure) exposure=minExposure; else if (exposure>maxExposure) exposure=maxExposure;
if (autoExposureMax<minExposure) autoExposureMax=minExposure; else if (autoExposureMax>maxExposure) autoExposureMax=maxExposure; if (autoExposureMax<minExposure) autoExposureMax=minExposure; else if (autoExposureMax>maxExposure) autoExposureMax=maxExposure;
if (gain<minGain) gain= minGain ; else if (gain> maxGain) gain= maxGain; if (gain<minGain) gain= minGain ; else if (gain> maxGain) gain= maxGain;
...@@ -645,9 +645,9 @@ public class LwirReader { ...@@ -645,9 +645,9 @@ public class LwirReader {
if (bScale<minScale) bScale= minScale ; else if (bScale> maxScale) bScale= maxScale; if (bScale<minScale) bScale= minScale ; else if (bScale> maxScale) bScale= maxScale;
if (gScale<minScale) gScale= minScale ; else if (gScale> maxScale) gScale= maxScale; if (gScale<minScale) gScale= minScale ; else if (gScale> maxScale) gScale= maxScale;
urls[num_lwir+chn] = "http://"+lrp.vnir_ip+"/parsedit.php?immediate&sensor_port="+chn+ urls[num_lwir+chn] = "http://"+lrp.eo_ip+"/parsedit.php?immediate&sensor_port="+chn+
"&COLOR="+COLOR_JP4+ // "*1"+ // JP4 always "&COLOR="+COLOR_JP4+ // "*1"+ // JP4 always
"&QUALITY="+lrp.vnir_quality+ // "*0"+ "&QUALITY="+lrp.eo_quality+ // "*0"+
"&EXPOS="+exposure+ // "*0"+ "&EXPOS="+exposure+ // "*0"+
"&AUTOEXP_EXP_MAX="+autoExposureMax+//"*0"+ "&AUTOEXP_EXP_MAX="+autoExposureMax+//"*0"+
"&AUTOEXP_ON="+autoExp+//"*0"+ "&AUTOEXP_ON="+autoExp+//"*0"+
...@@ -659,7 +659,7 @@ public class LwirReader { ...@@ -659,7 +659,7 @@ public class LwirReader {
"&DAEMON_EN_TEMPERATURE=1";//"*0"; "&DAEMON_EN_TEMPERATURE=1";//"*0";
if (chn == vnir_master_port) { if (chn == eo_master_port) {
urls[num_lwir+chn] += "&TRIG=4*0"+ urls[num_lwir+chn] += "&TRIG=4*0"+
"&TRIG_CONDITION=611669*0"+ // external input "&TRIG_CONDITION=611669*0"+ // external input
"&TRIG_BITLENGTH=31*0"+ "&TRIG_BITLENGTH=31*0"+
......
...@@ -41,45 +41,45 @@ public class LwirReaderParameters { ...@@ -41,45 +41,45 @@ public class LwirReaderParameters {
protected boolean lwir_ffc = true; protected boolean lwir_ffc = true;
protected boolean avg_all = true; protected boolean avg_all = true;
protected String lwir_ip = "192.168.0.36"; protected String lwir_ip = "192.168.0.36";
protected String vnir_ip = "192.168.0.38"; protected String eo_ip = "192.168.0.38";
protected int [] lwir_channels = {0, 1, 2 ,3}; protected int [] lwir_channels = {0, 1, 2 ,3};
protected int [] vnir_channels = {0, 1, 2 ,3}; protected int [] eo_channels = {0, 1, 2 ,3};
protected boolean lwir_telemetry = true; protected boolean lwir_telemetry = true;
protected double vnir_quality = 98.0; protected double eo_quality = 98.0;
protected boolean vnir_scale = false; // restore sensor pixel values, undo camera white balancing protected boolean eo_scale = false; // restore sensor pixel values, undo camera white balancing
protected boolean vnir_autoexp = false; protected boolean eo_autoexp = false;
protected double vnir_max_autoexp_ms = 20.0; protected double eo_max_autoexp_ms = 20.0;
protected double vnir_exposure_ms = 5.0; protected double eo_exposure_ms = 5.0;
protected boolean vnir_whitebal = false; protected boolean eo_whitebal = false;
protected double vnir_gain_g = 2.0; protected double eo_gain_g = 2.0;
protected double vnir_gain_rg = 0.7705; // 1.116; halogen/fluorescent protected double eo_gain_rg = 0.7705; // 1.116; halogen/fluorescent
protected double vnir_gain_bg = 2.401; // 1.476; protected double eo_gain_bg = 2.401; // 1.476;
protected boolean [] selected_channels = {true, true, true, true, true, true, true, true}; protected boolean [] selected_channels = {true, true, true, true, true, true, true, true};
protected int max_lwir_width = 1024; // protected int max_lwir_width = 1024; //
/* /*
protected double [] vnir_exp_corr = {1.0, 1.0, 1.0, 1.0}; protected double [] eo_exp_corr = {1.0, 1.0, 1.0, 1.0};
protected double [] vnir_gcorr_rbgb = { protected double [] eo_gcorr_rbgb = {
1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 1.0}; 1.0, 1.0, 1.0};
*/ */
protected double [] vnir_exp_corr = { protected double [] eo_exp_corr = {
1.0, 1.0026, 0.9868, 1.0211}; 1.0, 1.0026, 0.9868, 1.0211};
protected double [] vnir_gcorr_rbgb = { // example after autobalance for 192.168.0.38 with halogen lamps protected double [] eo_gcorr_rbgb = { // example after autobalance for 192.168.0.38 with halogen lamps
1.0, 1.0, 0.9743, 1.0, 1.0, 0.9743,
1.0668, 1.1055, 1.0006, 1.0668, 1.1055, 1.0006,
1.1533, 1.0780, 1.0015, 1.1533, 1.0780, 1.0015,
0.9966, 1.0445, 1.0023}; 0.9966, 1.0445, 1.0023};
protected int lwir_trig_dly = 9000000; //in 100MHz clock cycle, current FPGA requires >0 (used 1000) protected int lwir_trig_dly = 9000000; //in 100MHz clock cycle, current FPGA requires >0 (used 1000)
protected int vnir_lag = 2;//1; // frames protected int eo_lag = 2;//1; // frames
protected double max_mismatch_ms = 0.05; protected double max_mismatch_ms = 0.05;
protected int max_frame_diff = 2;// 1; // 2; protected int max_frame_diff = 2;// 1; // 2;
protected int debug_level = 0;//-3: OFF, -2:Fatal, -1:ERROR, 0:WARN, 1:INFO,2:DEBUG protected int debug_level = 0;//-3: OFF, -2:Fatal, -1:ERROR, 0:WARN, 1:INFO,2:DEBUG
protected boolean show_images = false; protected boolean show_images = false;
protected int lwir_chn0 = 0; // not configurable protected int lwir_chn0 = 0; // not configurable
protected int vnir_chn0 = 4; // not configurable protected int eo_chn0 = 4; // not configurable
// --- interface methods // --- interface methods
...@@ -87,8 +87,8 @@ public class LwirReaderParameters { ...@@ -87,8 +87,8 @@ public class LwirReaderParameters {
return lwir_chn0; return lwir_chn0;
} }
public int getVnirChn0 () { public int getEoChn0 () {
return vnir_chn0; return eo_chn0;
} }
public boolean is_LWIR(int width) { public boolean is_LWIR(int width) {
...@@ -115,23 +115,23 @@ public class LwirReaderParameters { ...@@ -115,23 +115,23 @@ public class LwirReaderParameters {
properties.setProperty(prefix+"lwir_ffc", this.lwir_ffc+""); properties.setProperty(prefix+"lwir_ffc", this.lwir_ffc+"");
properties.setProperty(prefix+"avg_all", this.avg_all+""); properties.setProperty(prefix+"avg_all", this.avg_all+"");
properties.setProperty(prefix+"lwir_ip", this.lwir_ip+""); properties.setProperty(prefix+"lwir_ip", this.lwir_ip+"");
properties.setProperty(prefix+"vnir_ip", this.vnir_ip+""); properties.setProperty(prefix+"eo_ip", this.eo_ip+"");
properties.setProperty(prefix+"lwir_channels", arr_to_str(this.lwir_channels)); properties.setProperty(prefix+"lwir_channels", arr_to_str(this.lwir_channels));
properties.setProperty(prefix+"vnir_channels", arr_to_str(this.vnir_channels)); properties.setProperty(prefix+"eo_channels", arr_to_str(this.eo_channels));
properties.setProperty(prefix+"lwir_telemetry", this.lwir_telemetry+""); properties.setProperty(prefix+"lwir_telemetry", this.lwir_telemetry+"");
properties.setProperty(prefix+"vnir_quality", this.vnir_quality+""); properties.setProperty(prefix+"eo_quality", this.eo_quality+"");
properties.setProperty(prefix+"vnir_scale", this.vnir_scale+""); properties.setProperty(prefix+"eo_scale", this.eo_scale+"");
properties.setProperty(prefix+"vnir_autoexp", this.vnir_autoexp+""); properties.setProperty(prefix+"eo_autoexp", this.eo_autoexp+"");
properties.setProperty(prefix+"vnir_max_autoexp_ms", this.vnir_max_autoexp_ms+""); properties.setProperty(prefix+"eo_max_autoexp_ms", this.eo_max_autoexp_ms+"");
properties.setProperty(prefix+"vnir_exposure_ms", this.vnir_exposure_ms+""); properties.setProperty(prefix+"eo_exposure_ms", this.eo_exposure_ms+"");
properties.setProperty(prefix+"vnir_whitebal", this.vnir_whitebal+""); properties.setProperty(prefix+"eo_whitebal", this.eo_whitebal+"");
properties.setProperty(prefix+"vnir_gain_g", this.vnir_gain_g+""); properties.setProperty(prefix+"eo_gain_g", this.eo_gain_g+"");
properties.setProperty(prefix+"vnir_gain_rg", this.vnir_gain_rg+""); properties.setProperty(prefix+"eo_gain_rg", this.eo_gain_rg+"");
properties.setProperty(prefix+"vnir_gain_bg", this.vnir_gain_bg+""); properties.setProperty(prefix+"eo_gain_bg", this.eo_gain_bg+"");
properties.setProperty(prefix+"vnir_exp_corr", arr_to_str(this.vnir_exp_corr)); properties.setProperty(prefix+"eo_exp_corr", arr_to_str(this.eo_exp_corr));
properties.setProperty(prefix+"vnir_gcorr_rbgb", arr_to_str(this.vnir_gcorr_rbgb)); properties.setProperty(prefix+"eo_gcorr_rbgb", arr_to_str(this.eo_gcorr_rbgb));
properties.setProperty(prefix+"lwir_trig_dly", this.lwir_trig_dly+""); properties.setProperty(prefix+"lwir_trig_dly", this.lwir_trig_dly+"");
properties.setProperty(prefix+"vnir_lag", this.vnir_lag+""); properties.setProperty(prefix+"eo_lag", this.eo_lag+"");
properties.setProperty(prefix+"max_mismatch_ms", this.max_mismatch_ms+""); properties.setProperty(prefix+"max_mismatch_ms", this.max_mismatch_ms+"");
properties.setProperty(prefix+"max_frame_diff", this.max_frame_diff+""); properties.setProperty(prefix+"max_frame_diff", this.max_frame_diff+"");
properties.setProperty(prefix+"debug_level", this.debug_level+""); properties.setProperty(prefix+"debug_level", this.debug_level+"");
...@@ -141,27 +141,42 @@ public class LwirReaderParameters { ...@@ -141,27 +141,42 @@ public class LwirReaderParameters {
} }
public void getProperties(String prefix,Properties properties){ public void getProperties(String prefix,Properties properties){
if (properties.getProperty(prefix+"vnir_ip")!=null) this.eo_ip= properties.getProperty(prefix+"vnir_ip");
if (properties.getProperty(prefix+"vnir_channels")!=null) this.eo_channels=str_to_iarr(properties.getProperty(prefix+"vnir_channels"));
if (properties.getProperty(prefix+"vnir_quality")!=null) this.eo_quality=Double.parseDouble(properties.getProperty(prefix+"vnir_quality"));
if (properties.getProperty(prefix+"vnir_scale")!=null) this.eo_scale= Boolean.parseBoolean(properties.getProperty(prefix+"vnir_scale"));
if (properties.getProperty(prefix+"vnir_autoexp")!=null) this.eo_autoexp= Boolean.parseBoolean(properties.getProperty(prefix+"vnir_autoexp"));
if (properties.getProperty(prefix+"vnir_max_autoexp_ms")!=null) this.eo_max_autoexp_ms=Double.parseDouble(properties.getProperty(prefix+"vnir_max_autoexp_ms"));
if (properties.getProperty(prefix+"vnir_exposure_ms")!=null) this.eo_exposure_ms=Double.parseDouble(properties.getProperty(prefix+"vnir_exposure_ms"));
if (properties.getProperty(prefix+"vnir_whitebal")!=null) this.eo_whitebal= Boolean.parseBoolean(properties.getProperty(prefix+"vnir_whitebal"));
if (properties.getProperty(prefix+"vnir_gain_g")!=null) this.eo_gain_g=Double.parseDouble(properties.getProperty(prefix+"vnir_gain_g"));
if (properties.getProperty(prefix+"vnir_gain_rg")!=null) this.eo_gain_rg=Double.parseDouble(properties.getProperty(prefix+"vnir_gain_rg"));
if (properties.getProperty(prefix+"vnir_gain_bg")!=null) this.eo_gain_bg=Double.parseDouble(properties.getProperty(prefix+"vnir_gain_bg"));
if (properties.getProperty(prefix+"vnir_exp_corr")!=null) this.eo_exp_corr=str_to_darr(properties.getProperty(prefix+"vnir_exp_corr"));
if (properties.getProperty(prefix+"vnir_gcorr_rbgb")!=null) this.eo_gcorr_rbgb=str_to_darr(properties.getProperty(prefix+"vnir_gcorr_rbgb"));
if (properties.getProperty(prefix+"vnir_lag")!=null) this.eo_lag=Integer.parseInt(properties.getProperty(prefix+"vnir_lag")); // old version
if (properties.getProperty(prefix+"avg_number")!=null) this.avg_number=Integer.parseInt(properties.getProperty(prefix+"avg_number")); if (properties.getProperty(prefix+"avg_number")!=null) this.avg_number=Integer.parseInt(properties.getProperty(prefix+"avg_number"));
if (properties.getProperty(prefix+"lwir_ffc")!=null) this.lwir_ffc= Boolean.parseBoolean(properties.getProperty(prefix+"lwir_ffc")); if (properties.getProperty(prefix+"lwir_ffc")!=null) this.lwir_ffc= Boolean.parseBoolean(properties.getProperty(prefix+"lwir_ffc"));
if (properties.getProperty(prefix+"avg_all")!=null) this.avg_all= Boolean.parseBoolean(properties.getProperty(prefix+"avg_all")); if (properties.getProperty(prefix+"avg_all")!=null) this.avg_all= Boolean.parseBoolean(properties.getProperty(prefix+"avg_all"));
if (properties.getProperty(prefix+"lwir_ip")!=null) this.lwir_ip= properties.getProperty(prefix+"lwir_ip"); if (properties.getProperty(prefix+"lwir_ip")!=null) this.lwir_ip= properties.getProperty(prefix+"lwir_ip");
if (properties.getProperty(prefix+"vnir_ip")!=null) this.vnir_ip= properties.getProperty(prefix+"vnir_ip"); if (properties.getProperty(prefix+"eo_ip")!=null) this.eo_ip= properties.getProperty(prefix+"eo_ip");
if (properties.getProperty(prefix+"lwir_channels")!=null) this.lwir_channels=str_to_iarr(properties.getProperty(prefix+"lwir_channels")); if (properties.getProperty(prefix+"lwir_channels")!=null) this.lwir_channels=str_to_iarr(properties.getProperty(prefix+"lwir_channels"));
if (properties.getProperty(prefix+"vnir_channels")!=null) this.vnir_channels=str_to_iarr(properties.getProperty(prefix+"vnir_channels")); if (properties.getProperty(prefix+"eo_channels")!=null) this.eo_channels=str_to_iarr(properties.getProperty(prefix+"eo_channels"));
if (properties.getProperty(prefix+"lwir_telemetry")!=null) this.lwir_telemetry= Boolean.parseBoolean(properties.getProperty(prefix+"lwir_telemetry")); if (properties.getProperty(prefix+"lwir_telemetry")!=null) this.lwir_telemetry= Boolean.parseBoolean(properties.getProperty(prefix+"lwir_telemetry"));
if (properties.getProperty(prefix+"vnir_quality")!=null) this.vnir_quality=Double.parseDouble(properties.getProperty(prefix+"vnir_quality")); if (properties.getProperty(prefix+"eo_quality")!=null) this.eo_quality=Double.parseDouble(properties.getProperty(prefix+"eo_quality"));
if (properties.getProperty(prefix+"vnir_scale")!=null) this.vnir_scale= Boolean.parseBoolean(properties.getProperty(prefix+"vnir_scale")); if (properties.getProperty(prefix+"eo_scale")!=null) this.eo_scale= Boolean.parseBoolean(properties.getProperty(prefix+"eo_scale"));
if (properties.getProperty(prefix+"vnir_autoexp")!=null) this.vnir_autoexp= Boolean.parseBoolean(properties.getProperty(prefix+"vnir_autoexp")); if (properties.getProperty(prefix+"eo_autoexp")!=null) this.eo_autoexp= Boolean.parseBoolean(properties.getProperty(prefix+"eo_autoexp"));
if (properties.getProperty(prefix+"vnir_max_autoexp_ms")!=null) this.vnir_max_autoexp_ms=Double.parseDouble(properties.getProperty(prefix+"vnir_max_autoexp_ms")); if (properties.getProperty(prefix+"eo_max_autoexp_ms")!=null) this.eo_max_autoexp_ms=Double.parseDouble(properties.getProperty(prefix+"eo_max_autoexp_ms"));
if (properties.getProperty(prefix+"vnir_exposure_ms")!=null) this.vnir_exposure_ms=Double.parseDouble(properties.getProperty(prefix+"vnir_exposure_ms")); if (properties.getProperty(prefix+"eo_exposure_ms")!=null) this.eo_exposure_ms=Double.parseDouble(properties.getProperty(prefix+"eo_exposure_ms"));
if (properties.getProperty(prefix+"vnir_whitebal")!=null) this.vnir_whitebal= Boolean.parseBoolean(properties.getProperty(prefix+"vnir_whitebal")); if (properties.getProperty(prefix+"eo_whitebal")!=null) this.eo_whitebal= Boolean.parseBoolean(properties.getProperty(prefix+"eo_whitebal"));
if (properties.getProperty(prefix+"vnir_gain_g")!=null) this.vnir_gain_g=Double.parseDouble(properties.getProperty(prefix+"vnir_gain_g")); if (properties.getProperty(prefix+"eo_gain_g")!=null) this.eo_gain_g=Double.parseDouble(properties.getProperty(prefix+"eo_gain_g"));
if (properties.getProperty(prefix+"vnir_gain_rg")!=null) this.vnir_gain_rg=Double.parseDouble(properties.getProperty(prefix+"vnir_gain_rg")); if (properties.getProperty(prefix+"eo_gain_rg")!=null) this.eo_gain_rg=Double.parseDouble(properties.getProperty(prefix+"eo_gain_rg"));
if (properties.getProperty(prefix+"vnir_gain_bg")!=null) this.vnir_gain_bg=Double.parseDouble(properties.getProperty(prefix+"vnir_gain_bg")); if (properties.getProperty(prefix+"eo_gain_bg")!=null) this.eo_gain_bg=Double.parseDouble(properties.getProperty(prefix+"eo_gain_bg"));
if (properties.getProperty(prefix+"vnir_exp_corr")!=null) this.vnir_exp_corr=str_to_darr(properties.getProperty(prefix+"vnir_exp_corr")); if (properties.getProperty(prefix+"eo_exp_corr")!=null) this.eo_exp_corr=str_to_darr(properties.getProperty(prefix+"eo_exp_corr"));
if (properties.getProperty(prefix+"vnir_gcorr_rbgb")!=null) this.vnir_gcorr_rbgb=str_to_darr(properties.getProperty(prefix+"vnir_gcorr_rbgb")); if (properties.getProperty(prefix+"eo_gcorr_rbgb")!=null) this.eo_gcorr_rbgb=str_to_darr(properties.getProperty(prefix+"eo_gcorr_rbgb"));
if (properties.getProperty(prefix+"lwir_trig_dly")!=null) this.lwir_trig_dly=Integer.parseInt(properties.getProperty(prefix+"lwir_trig_dly")); if (properties.getProperty(prefix+"lwir_trig_dly")!=null) this.lwir_trig_dly=Integer.parseInt(properties.getProperty(prefix+"lwir_trig_dly"));
if (properties.getProperty(prefix+"vnir_lag")!=null) this.vnir_lag=Integer.parseInt(properties.getProperty(prefix+"vnir_lag")); if (properties.getProperty(prefix+"eo_lag")!=null) this.eo_lag=Integer.parseInt(properties.getProperty(prefix+"eo_lag"));
if (properties.getProperty(prefix+"max_mismatch_ms")!=null) this.max_mismatch_ms=Double.parseDouble(properties.getProperty(prefix+"max_mismatch_ms")); if (properties.getProperty(prefix+"max_mismatch_ms")!=null) this.max_mismatch_ms=Double.parseDouble(properties.getProperty(prefix+"max_mismatch_ms"));
if (properties.getProperty(prefix+"max_frame_diff")!=null) this.max_frame_diff=Integer.parseInt(properties.getProperty(prefix+"max_frame_diff")); if (properties.getProperty(prefix+"max_frame_diff")!=null) this.max_frame_diff=Integer.parseInt(properties.getProperty(prefix+"max_frame_diff"));
if (properties.getProperty(prefix+"debug_level")!=null) this.debug_level=Integer.parseInt(properties.getProperty(prefix+"debug_level")); if (properties.getProperty(prefix+"debug_level")!=null) this.debug_level=Integer.parseInt(properties.getProperty(prefix+"debug_level"));
...@@ -176,23 +191,23 @@ public class LwirReaderParameters { ...@@ -176,23 +191,23 @@ public class LwirReaderParameters {
lrp.lwir_ffc= this.lwir_ffc; lrp.lwir_ffc= this.lwir_ffc;
lrp.avg_all= this.avg_all; lrp.avg_all= this.avg_all;
lrp.lwir_ip= this.lwir_ip; lrp.lwir_ip= this.lwir_ip;
lrp.vnir_ip= this.vnir_ip; lrp.eo_ip= this.eo_ip;
lrp.lwir_channels= this.lwir_channels.clone(); lrp.lwir_channels= this.lwir_channels.clone();
lrp.vnir_channels= this.vnir_channels.clone(); lrp.eo_channels= this.eo_channels.clone();
lrp.lwir_telemetry= this.lwir_telemetry; lrp.lwir_telemetry= this.lwir_telemetry;
lrp.vnir_quality= this.vnir_quality; lrp.eo_quality= this.eo_quality;
lrp.vnir_scale= this.vnir_scale; lrp.eo_scale= this.eo_scale;
lrp.vnir_autoexp= this.vnir_autoexp; lrp.eo_autoexp= this.eo_autoexp;
lrp.vnir_max_autoexp_ms= this.vnir_max_autoexp_ms; lrp.eo_max_autoexp_ms= this.eo_max_autoexp_ms;
lrp.vnir_exposure_ms= this.vnir_exposure_ms; lrp.eo_exposure_ms= this.eo_exposure_ms;
lrp.vnir_whitebal= this.vnir_whitebal; lrp.eo_whitebal= this.eo_whitebal;
lrp.vnir_gain_g= this.vnir_gain_g; lrp.eo_gain_g= this.eo_gain_g;
lrp.vnir_gain_rg= this.vnir_gain_rg; lrp.eo_gain_rg= this.eo_gain_rg;
lrp.vnir_gain_bg= this.vnir_gain_bg; lrp.eo_gain_bg= this.eo_gain_bg;
lrp.vnir_exp_corr= this.vnir_exp_corr.clone(); lrp.eo_exp_corr= this.eo_exp_corr.clone();
lrp.vnir_gcorr_rbgb= this.vnir_gcorr_rbgb.clone(); lrp.eo_gcorr_rbgb= this.eo_gcorr_rbgb.clone();
lrp.lwir_trig_dly= this.lwir_trig_dly; lrp.lwir_trig_dly= this.lwir_trig_dly;
lrp.vnir_lag= this.vnir_lag; lrp.eo_lag= this.eo_lag;
lrp.max_mismatch_ms= this.max_mismatch_ms; lrp.max_mismatch_ms= this.max_mismatch_ms;
lrp.max_frame_diff= this.max_frame_diff; lrp.max_frame_diff= this.max_frame_diff;
lrp.debug_level= this.debug_level; lrp.debug_level= this.debug_level;
...@@ -214,23 +229,23 @@ public class LwirReaderParameters { ...@@ -214,23 +229,23 @@ public class LwirReaderParameters {
(lrp.lwir_ffc == this.lwir_ffc) && (lrp.lwir_ffc == this.lwir_ffc) &&
(lrp.avg_all == this.avg_all) && (lrp.avg_all == this.avg_all) &&
(lrp.lwir_ip.equals(this.lwir_ip)) && (lrp.lwir_ip.equals(this.lwir_ip)) &&
(lrp.vnir_ip.equals(this.vnir_ip)) && (lrp.eo_ip.equals(this.eo_ip)) &&
(java.util.Arrays.equals(lrp.lwir_channels, this.lwir_channels)) && (java.util.Arrays.equals(lrp.lwir_channels, this.lwir_channels)) &&
(java.util.Arrays.equals(lrp.vnir_channels, this.vnir_channels)) && (java.util.Arrays.equals(lrp.eo_channels, this.eo_channels)) &&
(lrp.lwir_telemetry == this.lwir_telemetry) && (lrp.lwir_telemetry == this.lwir_telemetry) &&
(lrp.vnir_quality == this.vnir_quality) && (lrp.eo_quality == this.eo_quality) &&
(lrp.vnir_scale == this.vnir_scale) && (lrp.eo_scale == this.eo_scale) &&
(lrp.vnir_autoexp == this.vnir_autoexp) && (lrp.eo_autoexp == this.eo_autoexp) &&
(lrp.vnir_max_autoexp_ms == this.vnir_max_autoexp_ms) && (lrp.eo_max_autoexp_ms == this.eo_max_autoexp_ms) &&
(lrp.vnir_exposure_ms == this.vnir_exposure_ms) && (lrp.eo_exposure_ms == this.eo_exposure_ms) &&
(lrp.vnir_whitebal == this.vnir_whitebal) && (lrp.eo_whitebal == this.eo_whitebal) &&
(lrp.vnir_gain_g == this.vnir_gain_g) && (lrp.eo_gain_g == this.eo_gain_g) &&
(lrp.vnir_gain_rg == this.vnir_gain_rg) && (lrp.eo_gain_rg == this.eo_gain_rg) &&
(lrp.vnir_gain_bg == this.vnir_gain_bg) && (lrp.eo_gain_bg == this.eo_gain_bg) &&
(java.util.Arrays.equals(lrp.vnir_exp_corr, this.vnir_exp_corr)) && (java.util.Arrays.equals(lrp.eo_exp_corr, this.eo_exp_corr)) &&
(java.util.Arrays.equals(lrp.vnir_gcorr_rbgb, this.vnir_gcorr_rbgb)) && (java.util.Arrays.equals(lrp.eo_gcorr_rbgb, this.eo_gcorr_rbgb)) &&
(lrp.lwir_trig_dly == this.lwir_trig_dly) && (lrp.lwir_trig_dly == this.lwir_trig_dly) &&
(lrp.vnir_lag == this.vnir_lag) && (lrp.eo_lag == this.eo_lag) &&
(lrp.max_mismatch_ms == this.max_mismatch_ms) && (lrp.max_mismatch_ms == this.max_mismatch_ms) &&
(lrp.max_frame_diff == this.max_frame_diff) && (lrp.max_frame_diff == this.max_frame_diff) &&
(lrp.debug_level == this.debug_level) && (lrp.debug_level == this.debug_level) &&
...@@ -246,25 +261,25 @@ public class LwirReaderParameters { ...@@ -246,25 +261,25 @@ public class LwirReaderParameters {
result = prime * result + (lwir_ffc?1:0); result = prime * result + (lwir_ffc?1:0);
result = prime * result + (avg_all?1:0); result = prime * result + (avg_all?1:0);
result = prime * result + lwir_ip.hashCode(); result = prime * result + lwir_ip.hashCode();
result = prime * result + vnir_ip.hashCode(); result = prime * result + eo_ip.hashCode();
result = prime * result + arr_to_str(lwir_channels).hashCode(); result = prime * result + arr_to_str(lwir_channels).hashCode();
result = prime * result + arr_to_str(vnir_channels).hashCode(); result = prime * result + arr_to_str(eo_channels).hashCode();
result = prime * result + (lwir_telemetry?1:0); result = prime * result + (lwir_telemetry?1:0);
result = prime * result + (new Double(vnir_quality)).hashCode(); result = prime * result + (new Double(eo_quality)).hashCode();
result = prime * result + (vnir_scale?1:0); result = prime * result + (eo_scale?1:0);
result = prime * result + (vnir_autoexp?1:0); result = prime * result + (eo_autoexp?1:0);
result = prime * result + (new Double(vnir_max_autoexp_ms)).hashCode(); result = prime * result + (new Double(eo_max_autoexp_ms)).hashCode();
result = prime * result + (new Double(vnir_exposure_ms)).hashCode(); result = prime * result + (new Double(eo_exposure_ms)).hashCode();
result = prime * result + (vnir_whitebal?1:0); result = prime * result + (eo_whitebal?1:0);
result = prime * result + (new Double(vnir_gain_g)).hashCode(); result = prime * result + (new Double(eo_gain_g)).hashCode();
result = prime * result + (new Double(vnir_gain_rg)).hashCode(); result = prime * result + (new Double(eo_gain_rg)).hashCode();
result = prime * result + (new Double(vnir_gain_bg)).hashCode(); result = prime * result + (new Double(eo_gain_bg)).hashCode();
result = prime * result + arr_to_str(vnir_exp_corr).hashCode(); result = prime * result + arr_to_str(eo_exp_corr).hashCode();
result = prime * result + arr_to_str(vnir_gcorr_rbgb).hashCode(); result = prime * result + arr_to_str(eo_gcorr_rbgb).hashCode();
result = prime * result + (new Integer(lwir_trig_dly)).hashCode(); result = prime * result + (new Integer(lwir_trig_dly)).hashCode();
result = prime * result + arr_to_str(selected_channels).hashCode(); result = prime * result + arr_to_str(selected_channels).hashCode();
// next are not needed to be programmed to the cameras // next are not needed to be programmed to the cameras
// result = prime * result + (new Integer(vnir_lag)).hashCode(); // result = prime * result + (new Integer(eo_lag)).hashCode();
// result = prime * result + (new Double(max_mismatch_ms)).hashCode(); // result = prime * result + (new Double(max_mismatch_ms)).hashCode();
// result = prime * result + (new Integer(max_frame_diff)).hashCode(); // result = prime * result + (new Integer(max_frame_diff)).hashCode();
return 0; return 0;
...@@ -275,23 +290,23 @@ public class LwirReaderParameters { ...@@ -275,23 +290,23 @@ public class LwirReaderParameters {
gd.addCheckbox ("Run FFC", this.lwir_ffc, "Perform calibration before each measurements to average (takes ~1.6 sec, 15 frames)"); gd.addCheckbox ("Run FFC", this.lwir_ffc, "Perform calibration before each measurements to average (takes ~1.6 sec, 15 frames)");
gd.addCheckbox ("Average all", this.avg_all, "Average all simultaneously acquired images (unchecked - only requested number to average)"); gd.addCheckbox ("Average all", this.avg_all, "Average all simultaneously acquired images (unchecked - only requested number to average)");
gd.addStringField ("LWIR IP", this.lwir_ip, 20, "LWIR camera IP address"); gd.addStringField ("LWIR IP", this.lwir_ip, 20, "LWIR camera IP address");
gd.addStringField ("VNIR IP", this.vnir_ip, 20, "Visible range high resolution camera IP address"); gd.addStringField ("EO IP", this.eo_ip, 20, "Visible range high resolution camera IP address");
gd.addStringField ("LWIR channels", arr_to_str(this.lwir_channels), 20, "Space-separated list of used LWIR camera channels, such as '0 1 2 3'"); gd.addStringField ("LWIR channels", arr_to_str(this.lwir_channels), 20, "Space-separated list of used LWIR camera channels, such as '0 1 2 3'");
gd.addStringField ("VNIR channels", arr_to_str(this.vnir_channels), 20, "Space-separated list of used visible range camera channels, such as '0 1 2 3'"); gd.addStringField ("EO channels", arr_to_str(this.eo_channels), 20, "Space-separated list of used visible range camera channels, such as '0 1 2 3'");
gd.addCheckbox ("LWIR telemetry", this.lwir_telemetry, "Set LWIR sesnors to provide telemetry data in the last 2 lines (may become mandatory later)"); gd.addCheckbox ("LWIR telemetry", this.lwir_telemetry, "Set LWIR sesnors to provide telemetry data in the last 2 lines (may become mandatory later)");
gd.addNumericField("VNIR quality", this.vnir_quality, 3,6,"%", "Visible range camera JPEG compression quality (all channels)"); gd.addNumericField("EO quality", this.eo_quality, 3,6,"%", "Visible range camera JPEG compression quality (all channels)");
gd.addCheckbox ("VNIR undo white balance", this.vnir_scale, "Undo in-camera white balancing"); gd.addCheckbox ("EO undo white balance", this.eo_scale, "Undo in-camera white balancing");
gd.addCheckbox ("VNIR autoexposure", this.vnir_autoexp, "Enable autoexposure for the visible range camera"); gd.addCheckbox ("EO autoexposure", this.eo_autoexp, "Enable autoexposure for the visible range camera");
gd.addNumericField("VNIR vnir_max_autoexp_ms", this.vnir_max_autoexp_ms, 3,6,"ms", "Visible range camera maximal exposure in autoexposure mode"); gd.addNumericField("EO eo_max_autoexp_ms", this.eo_max_autoexp_ms, 3,6,"ms", "Visible range camera maximal exposure in autoexposure mode");
gd.addNumericField("VNIR exposure", this.vnir_exposure_ms, 3,6,"ms", "Visible range camera exposure time (all channels)"); gd.addNumericField("EO exposure", this.eo_exposure_ms, 3,6,"ms", "Visible range camera exposure time (all channels)");
gd.addCheckbox ("VNIR white balance", this.vnir_whitebal, "Enable automatic white balancing for the visible range camera"); gd.addCheckbox ("EO white balance", this.eo_whitebal, "Enable automatic white balancing for the visible range camera");
gd.addNumericField("VNIR gain G", this.vnir_gain_g, 3,6,"","Analog gain for green channel for all visible range camera channels (normally 2.0)"); gd.addNumericField("EO gain G", this.eo_gain_g, 3,6,"","Analog gain for green channel for all visible range camera channels (normally 2.0)");
gd.addNumericField("VNIR gain R/G", this.vnir_gain_rg, 3,6,"","Red to green gain ratio for all visible range camera channels"); gd.addNumericField("EO gain R/G", this.eo_gain_rg, 3,6,"","Red to green gain ratio for all visible range camera channels");
gd.addNumericField("VNIR gain B/G", this.vnir_gain_bg, 3,6,"","Blue to green gain ratio for all visible range camera channels"); gd.addNumericField("EO gain B/G", this.eo_gain_bg, 3,6,"","Blue to green gain ratio for all visible range camera channels");
gd.addStringField ("VNIR exposuere corrections", arr_to_str(this.vnir_exp_corr), 50, "Fine corrections of channel exposures (4 channel relative exposures)"); gd.addStringField ("EO exposuere corrections", arr_to_str(this.eo_exp_corr), 50, "Fine corrections of channel exposures (4 channel relative exposures)");
gd.addStringField ("VNIR gain corrections", arr_to_str(this.vnir_gcorr_rbgb), 100, "Fine corrections to per channel, per color gains:'r0 b0 gb0 r1 b1 gb1 ...'"); gd.addStringField ("EO gain corrections", arr_to_str(this.eo_gcorr_rbgb), 100, "Fine corrections to per channel, per color gains:'r0 b0 gb0 r1 b1 gb1 ...'");
gd.addNumericField("LWIR trig dly", this.lwir_trig_dly, 0,10,"x10ns","Output trigger delay, should eventually match Lepton+FPGA latency to trigger VNIR exactly 1 frame after LWIR. 0 does not work with current FPGA - usec do not match sec in transmitted timestamp"); gd.addNumericField("LWIR trig dly", this.lwir_trig_dly, 0,10,"x10ns","Output trigger delay, should eventually match Lepton+FPGA latency to trigger EO exactly 1 frame after LWIR. 0 does not work with current FPGA - usec do not match sec in transmitted timestamp");
gd.addNumericField("VNIR lag", this.vnir_lag, 0,3,"","Visible camera lag (in frames) relative to LWIR one"); gd.addNumericField("EO lag", this.eo_lag, 0,3,"","Visible camera lag (in frames) relative to LWIR one");
gd.addNumericField("Max mismatch", this.max_mismatch_ms, 3,6,"ms","Maximal mismatch between image timestamps. Larger mismatch requires LWIR sinsor reinitialization"); gd.addNumericField("Max mismatch", this.max_mismatch_ms, 3,6,"ms","Maximal mismatch between image timestamps. Larger mismatch requires LWIR sinsor reinitialization");
gd.addNumericField("Max frame diff",this.max_frame_diff, 0,3,"","Maximal difference in frames between simultaneously acquired channels as calculated from the timestamps"); gd.addNumericField("Max frame diff",this.max_frame_diff, 0,3,"","Maximal difference in frames between simultaneously acquired channels as calculated from the timestamps");
gd.addNumericField("Debug level", this.debug_level, 0,3,"","Image acquisition log level: -3: OFF, -2:FATAL, -1:ERROR, 0:WARN, 1:INFO, 2:DEBUG"); gd.addNumericField("Debug level", this.debug_level, 0,3,"","Image acquisition log level: -3: OFF, -2:FATAL, -1:ERROR, 0:WARN, 1:INFO, 2:DEBUG");
...@@ -304,23 +319,23 @@ public class LwirReaderParameters { ...@@ -304,23 +319,23 @@ public class LwirReaderParameters {
this.lwir_ffc = gd.getNextBoolean(); this.lwir_ffc = gd.getNextBoolean();
this.avg_all = gd.getNextBoolean(); this.avg_all = gd.getNextBoolean();
this.lwir_ip = gd.getNextString(); this.lwir_ip = gd.getNextString();
this.vnir_ip = gd.getNextString(); this.eo_ip = gd.getNextString();
this.lwir_channels = str_to_iarr(gd.getNextString()); this.lwir_channels = str_to_iarr(gd.getNextString());
this.vnir_channels = str_to_iarr(gd.getNextString()); this.eo_channels = str_to_iarr(gd.getNextString());
this.lwir_telemetry = gd.getNextBoolean(); this.lwir_telemetry = gd.getNextBoolean();
this.vnir_quality = gd.getNextNumber(); this.eo_quality = gd.getNextNumber();
this.vnir_scale = gd.getNextBoolean(); this.eo_scale = gd.getNextBoolean();
this.vnir_autoexp = gd.getNextBoolean(); this.eo_autoexp = gd.getNextBoolean();
this.vnir_max_autoexp_ms = gd.getNextNumber(); this.eo_max_autoexp_ms = gd.getNextNumber();
this.vnir_exposure_ms = gd.getNextNumber(); this.eo_exposure_ms = gd.getNextNumber();
this.vnir_whitebal = gd.getNextBoolean(); this.eo_whitebal = gd.getNextBoolean();
this.vnir_gain_g = gd.getNextNumber(); this.eo_gain_g = gd.getNextNumber();
this.vnir_gain_rg = gd.getNextNumber(); this.eo_gain_rg = gd.getNextNumber();
this.vnir_gain_bg = gd.getNextNumber(); this.eo_gain_bg = gd.getNextNumber();
this.vnir_exp_corr = str_to_darr(gd.getNextString()); this.eo_exp_corr = str_to_darr(gd.getNextString());
this.vnir_gcorr_rbgb = str_to_darr(gd.getNextString()); this.eo_gcorr_rbgb = str_to_darr(gd.getNextString());
this.lwir_trig_dly = (int) gd.getNextNumber(); this.lwir_trig_dly = (int) gd.getNextNumber();
this.vnir_lag = (int) gd.getNextNumber(); this.eo_lag = (int) gd.getNextNumber();
this.max_mismatch_ms = gd.getNextNumber(); this.max_mismatch_ms = gd.getNextNumber();
this.max_frame_diff = (int) gd.getNextNumber(); this.max_frame_diff = (int) gd.getNextNumber();
this.debug_level = (int) gd.getNextNumber(); this.debug_level = (int) gd.getNextNumber();
...@@ -361,7 +376,7 @@ public class LwirReaderParameters { ...@@ -361,7 +376,7 @@ public class LwirReaderParameters {
return sel; return sel;
} }
public boolean [] getSelectedVnir(){ public boolean [] getSelectedEo(){
boolean [] sel = selected_channels.clone(); boolean [] sel = selected_channels.clone();
for (int i = 0; i < lwir_channels.length; i++ ) { for (int i = 0; i < lwir_channels.length; i++ ) {
sel[i] = false; sel[i] = false;
......
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