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
4, // int decimateMasks
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
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.0, // public double weightMultiExponent= 1.0; // if( >0) use grid diameter to scale weights of this image
1.0, // public double weightDiameterExponent=1.0;
......@@ -511,7 +511,8 @@ public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSi
0.5, // public double shrinkBlurLevel = 0.5;
-1.0, // double balanceChannelWeightsMode
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) {
addButton("Import Subsystem", panelLWIR,color_configure);
addButton("Select LWIR grids", panelLWIR,color_configure);
addButton("Grid offset", panelLWIR,color_process);
addButton("LWIR to EO", panelLWIR,color_process);
addButton("Manual hint", panelLWIR,color_configure);
add(panelLWIR);
......@@ -2080,6 +2082,8 @@ if (MORE_BUTTONS) {
double[][] gridDisplay=LENS_DISTORTIONS.prepareDisplayGrid();
SDFA_INSTANCE.showArrays(gridDisplay,LENS_DISTORTIONS.getGridWidth(),LENS_DISTORTIONS.getGridHeight(), true, "Grid",
LENS_DISTORTIONS.displayGridTitles());
// Does not update pixelSize and DistortionRadius !!
LENS_DISTORTIONS.calcGridOnSensor(0.0);
double[][] gridDisplayOnSensor=LENS_DISTORTIONS.prepareDisplayGridOnSensor(false);
SDFA_INSTANCE.showArrays(gridDisplayOnSensor,LENS_DISTORTIONS.getGridWidth(),LENS_DISTORTIONS.getGridHeight(), true, "GridOnSensor",
......@@ -2297,7 +2301,9 @@ if (MORE_BUTTONS) {
if (LENS_DISTORTIONS.fittingStrategy==null) return;
LENS_DISTORTIONS.fittingStrategy.debugLevel=DEBUG_LEVEL;
LENS_DISTORTIONS.LevenbergMarquardt(true); // open dialog
LENS_DISTORTIONS.LevenbergMarquardt(true, // open dialog
false); // dry_run
return;
}
/* ======================================================================== */
......@@ -3610,7 +3616,9 @@ if (MORE_BUTTONS) {
LENS_DISTORTIONS.thresholdFinish=FOCUS_MEASUREMENT_PARAMETERS.thresholdFinish;
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));
int stationNumber=0;
// Read camera parameters
......@@ -3635,7 +3643,9 @@ if (MORE_BUTTONS) {
LENS_DISTORTIONS.thresholdFinish=FOCUS_MEASUREMENT_PARAMETERS.thresholdFinish;
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 (!FOCUS_MEASUREMENT_PARAMETERS.keepCircularMask) {
DISTORTION_CALIBRATION_DATA.calculateSensorMasks(); // TODO: save/restore original mask for channel 0
......@@ -5922,7 +5932,7 @@ if (MORE_BUTTONS) {
return;
}
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();
if (gd.wasCanceled()) return;
int listMode= (int) gd.getNextNumber();
......@@ -6100,7 +6110,9 @@ if (MORE_BUTTONS) {
LENS_DISTORTIONS.stopEachSeries= false; // will not ask for confirmation after done
LENS_DISTORTIONS.stopOnFailure=false;
LENS_DISTORTIONS.lambda=LENS_DISTORTIONS.fittingStrategy.lambdas[0]; // 0.001; // why it does not use fitting series lambda?
boolean LMA_OK=LENS_DISTORTIONS.LevenbergMarquardt(false); // skip dialog
boolean LMA_OK=LENS_DISTORTIONS.LevenbergMarquardt(
false, // skip dialog
false); // new: dry_run use it here?
if (LMA_OK) {
finalTilt[tiltIndex][axialIndex]=LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.gIS[imageSetNumber].goniometerTilt;
finalAxial[tiltIndex][axialIndex]=LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.gIS[imageSetNumber].goniometerAxial;
......@@ -6177,7 +6189,9 @@ if (MORE_BUTTONS) {
LENS_DISTORTIONS.stopEachStep= false;
LENS_DISTORTIONS.stopEachSeries= false; // will not ask for confirmation after done
LENS_DISTORTIONS.lambda=LENS_DISTORTIONS.fittingStrategy.lambdas[0];
LENS_DISTORTIONS.LevenbergMarquardt(false); // skip dialog
LENS_DISTORTIONS.LevenbergMarquardt(
false, // skip dialog
false); // new: dry_run use it here?
// save safe settings to run LMA manually
LENS_DISTORTIONS.seriesNumber= 0; // start from 0;
......@@ -9435,16 +9449,17 @@ if (MORE_BUTTONS) {
calculateLwirGrids();
return;
}
/* ======================================================================== */
if (label.equals("Import Subsystem")) {
importSystem(null, "EYESIS_CAMERA_PARAMETERS.");
return;
}
/* ======================================================================== */
if (label.equals("Select LWIR grids")) {
selectLwirGrids(LWIR_PARAMETERS);
return;
}
/* ======================================================================== */
if (label.equals("Manual hint")) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
if (LENS_DISTORTIONS==null) {
......@@ -9466,12 +9481,19 @@ if (MORE_BUTTONS) {
LENS_DISTORTIONS.manualGridHint(numGridImage);
return;
}
/* ======================================================================== */
if (label.equals("Grid offset")) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
offsetGrids(0, 0, null);
return;
}
/* ======================================================================== */
if (label.equals("LWIR to EO")) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
lwirToEo();
return;
}
/* ======================================================================== */
IJ.showMessage("Not yet implemented");
......@@ -9480,6 +9502,108 @@ if (MORE_BUTTONS) {
}
/* ===== 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) {
if (LENS_DISTORTIONS == null) {
System.out.println("LENS_DISTORTIONS is null");
......@@ -9517,7 +9641,7 @@ if (MORE_BUTTONS) {
gd.addNumericField("Image/set number", inum, 0);
gd.addCheckbox ("Auto calculate UV", auto);
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 V", uv_shift_rot[1], 0);
......@@ -9580,11 +9704,17 @@ if (MORE_BUTTONS) {
// find first enabled image
for (int n:img_nums) {
if (n >= 0) {
int [] auto_uvr = dcd. suggestOffset (
n, // int num_img,
true, // boolean non_estimated,
int [] auto_uvr = LENS_DISTORTIONS.findImageGridOffset( // null for now
n,
true, // boolean even,
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);
}
}
......@@ -9616,14 +9746,14 @@ if (MORE_BUTTONS) {
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 lwir_chn0 = lwirReaderParameters.getLwirChn0();
int vnir_chn0 = lwirReaderParameters.getVnirChn0();
int eo_chn0 = lwirReaderParameters.getEoChn0();
int numStations = 3;
GenericDialog gd = new GenericDialog("Setup Goniometer/Camera Stations");
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.addNumericField("Number of goniometer/camera stations", numStations,0);
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.showDialog();
......@@ -9757,7 +9887,6 @@ if (MORE_BUTTONS) {
matchSimulatedPattern.debugLevel=MASTER_DEBUG_LEVEL;
String [] sourceSetList = DISTORTION_PROCESS_CONFIGURATION.selectSourceSets();
LWIR_PARAMETERS.selectSourceChannels();
// boolean [] sel_chn = LWIR_PARAMETERS.getSelectedVnir(); // start with regular cameras only
boolean [] sel_chn = LWIR_PARAMETERS.getSelected();
int numFiles = LWIR_PARAMETERS.getSourceFilesFlat(sourceSetList, sel_chn).length; // just the number
String [][] sourceFilesList=LWIR_PARAMETERS.getSourceFiles(sourceSetList, sel_chn);
......@@ -91,6 +91,27 @@ import ij.text.TextWindow;
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 int imgNumber=-1; // index of this image (for pars[][])
private int setNumber=-1; // long overdue - will be some inconsistency
......@@ -127,8 +148,9 @@ import ij.text.TextWindow;
final int contrastIndex=2;
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 GridImageParameters(int index){
this.imgNumber=index;
......@@ -145,7 +167,7 @@ import ij.text.TextWindow;
public void setStationNumber(int stationNumber){ // TODO: make only a single station number - in GridImageSet?
this.stationNumber=stationNumber;
}
public double []getGridWeight(){
public double [] getGridWeight(){
return this.pixelsMask;
}
public void resetMask(){
......@@ -553,6 +575,11 @@ import ij.text.TextWindow;
"10","11","12","13","14","15","16","17","18","19",
"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 !
this.index_right = getParameterIndexByName("subcamRight"); // 0 may be -1 if !cartesian
this.index_forward = getParameterIndexByName("subcamForward"); // 1 may be -1 if !cartesian
......@@ -563,13 +590,10 @@ import ij.text.TextWindow;
this.index_ga= getParameterIndexByName("goniometerAxial"); // 7
}
public boolean isCartesian(){
return (eyesisCameraParameters !=null) && eyesisCameraParameters.cartesian;
}
public String descrField(int i,int j){
if (
(eyesisCameraParameters !=null) &&
eyesisCameraParameters.cartesian &&
eyesisCameraParameters.isCartesian() &&
(i < this.parameterDescriptionsCartesian.length) &&
(this.parameterDescriptionsCartesian[i]!=null) &&
(j<this.parameterDescriptionsCartesian[i].length)){
......@@ -795,9 +819,9 @@ import ij.text.TextWindow;
String set_name = (new File(dir)).getName();
File set_dir = new File(sdir, set_name );
String [] sfiles = set_dir.list(sourceFilter);
if (sfiles == null) {
if (sfiles == null) {
System.out.println("sfiles == null");
}
}
for (String spath:sfiles) {
int last_dash = spath.lastIndexOf('-');
int last = spath.lastIndexOf('_');
......@@ -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();
this.eyesisCameraParameters=eyesisCameraParameters;
int numSubCameras=(eyesisCameraParameters==null)?1:eyesisCameraParameters.eyesisSubCameras[0].length;
......@@ -906,8 +932,11 @@ if (sfiles == null) {
this.gIS[nis].motors= this.gIP[numFile].motors.clone();
this.gIP[numFile].matchedPointers = getUsedPonters(imp_grid);
if (this.gIP[numFile].matchedPointers > 0) {
// 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];
for (int i=0;i<saturations.length;i++) {
saturations[i]=Double.NaN;
......@@ -981,8 +1010,8 @@ if (sfiles == null) {
}
}
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
// boolean [] sensor_mask = null; // later may be used to limit scope to VNIR-only
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 EO-only
int extra_search = 2;
// int base_channel = this.gIP[with_pointers].channel;
if (this.gIS[nis].imageSet[main_channel] != 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
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 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]) {
......@@ -1041,14 +1070,6 @@ if (sfiles == null) {
if (this.debugLevel>-1) System.out.print(imgNum+"*("+this.gIP[imgNum].getStationNumber()+
":"+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 = {
this.gIP[imgNum].woi.width + this.gIP[imgNum].woi.x,
this.gIP[imgNum].woi.height + this.gIP[imgNum].woi.y};
......@@ -1063,8 +1084,7 @@ if (sfiles == null) {
5.0, // 2.0, // sigma
sensor_wh,
false); // true);
System.out.print(" {"+uv_shift_rot0[0]+":"+uv_shift_rot0[1]+"->"+uv_shift_rot[0]+":"+uv_shift_rot[1]+"->");
System.out.print(" {"+uv_shift_rot[0]+":"+uv_shift_rot[1]+"->");
int [] combinedUVShiftRot=MatchSimulatedPattern.combineUVShiftRot(
this.gIS[nis].imageSet[base_channel].getUVShiftRot(),
uv_shift_rot);
......@@ -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
// non_estimated - disregard images with estimated orientation
public int getMarkedSet(int num_set, boolean non_estimated) {
......@@ -1151,6 +1320,12 @@ if (sfiles == null) {
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.
// Wrong Grid UV should cause parallel shift - same Z, different XY
public int [] suggestOffset (
......@@ -1158,8 +1333,7 @@ if (sfiles == null) {
boolean non_estimated,
boolean even,
PatternParameters patternParameters) {
int num_set = this.gIP[num_img].setNumber;
int station = this.gIS[num_set].stationNumber;
int num_set = this.gIP[num_img].getSetNumber();
double [] ref_xyz = getXYZFromMarked(num_set, non_estimated);
if (ref_xyz == null) {
System.out.println("Error: Could not find reference goniometer XYZ for set "+num_set);
......@@ -1167,6 +1341,20 @@ if (sfiles == null) {
}
double [] diff_xyz = this.gIS[num_set].GXYZ.clone();
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}
if ((pixelsUV == null) || ((pixelsUV.length <3 ))) {
System.out.println("No/too few pixelsUV data for image "+num_img);
......@@ -3101,6 +3289,11 @@ if (sfiles == null) {
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].motors=getMotorPositions(imp_grid, this.numMotors);
this.gIP[fileNumber].matchedPointers=getUsedPonters(imp_grid);
......@@ -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
// 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()
public int getNumLwir() {
if (hasSmallSensors()) {
......@@ -3547,10 +3740,10 @@ if (sfiles == null) {
return 0;
}
}
public int getNumVnir() {
public int getNumEo() {
return getNumSubCameras() - getNumLwir();
}
public int getVnir0() {
public int getEo0() {
if (hasSmallSensors()) {
for (int i = 0; i < small_sensors.length; i++) if (!small_sensors[i]) return i;
return -1; // should not happen
......@@ -3574,7 +3767,7 @@ if (sfiles == null) {
int n = 2;
if (hasSmallSensors()) {
if (getNumLwir() > 1) n++;
if (getNumVnir() > 1) n++;
if (getNumEo() > 1) n++;
}
return n;
}
......@@ -3594,11 +3787,11 @@ if (sfiles == null) {
if (hasSmallSensors()) {
if (small_sensors[chn]) { // current is LWIR
n = 1;
if (getNumVnir() > 1) n = 2;
if (getNumEo() > 1) n = 2;
if (chn != getLwir0()) n++;
} else { // current is VNIR
} else { // current is EO
n = 0;
if (chn != getVnir0()) n++;
if (chn != getEo0()) n++;
}
}
return n;
......@@ -3606,7 +3799,7 @@ if (sfiles == null) {
// check if the channel is the first in group
public boolean firstInGroup(int chn) {
if (chn >= 24) return (chn == 24);
if ((chn == getVnir0()) || (chn == getLwir0())) return true;
if ((chn == getEo0()) || (chn == getLwir0())) return true;
int [] num = {0,0};
for (int i = 0; i < chn; i++) {
if ((small_sensors != null) && small_sensors[i]) num[1]++;
......@@ -3631,13 +3824,13 @@ if (sfiles == null) {
if (chn != getLwir0()) return full?"Subcamera LWIR other":"sub-lwir-other";
if (getNumLwir() > 1) return full?"Subcamera LWIR 0":"sub-lwir0";
return full?"Subcamera LWIR":"sub-lwir";
} else { // current is VNIR
if (chn != getVnir0()) return full?"Subcamera VNIR other":"sub-vnir-other";
if (getNumVnir() > 1) return full?"Subcamera VNIR 0":"sub-vnir0";
return full?"Subcamera VNIR":"sub-vnir";
} else { // current is EO
if (chn != getEo0()) return full?"Subcamera EO other":"sub-eo-other";
if (getNumEo() > 1) return full?"Subcamera EO 0":"sub-eo0";
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";
}
......
......@@ -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.
// 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 dbg;
// if (weight > 0) {
if ((weight > 0) && (imgNum == 244)) {
dbg = weight;
}
if ((filter & this.filterContrast)!=0) {
double gridContrast= gridWeight[pointNumber];
weight*=gridContrast;
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) {
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 (weight > 0) {
if ((weight > 0) && (imgNum == 244)) {
dbg = weight;
}
if ((filter & this.filterTargetAlpha)!=0) {
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 (weight > 0) {
if ((weight > 0) && (imgNum == 244)) {
dbg = weight;
}
if ((filter & this.filterTargetErrors)!=0) {
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 (weight > 0) {
if ((weight > 0) && (imgNum == 244)) {
dbg = weight;
}
if ((filter & this.filterMulti)!=0) {
weight*=multiWeight[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 (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)
if (((filter & this.filterDiameter)!=0) && (fittingStrategy.distortionCalibrationData.eyesisCameraParameters.weightDiameterExponent>0.0)) {
weight*=gridImageWeight;
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)) {
weight=0.0; // find who makes it NaN
if (Double.isNaN(multiWeight[imgNum])) System.out.println("weight is null, imgNum="+imgNum);
......@@ -619,7 +647,9 @@ public class Distortions {
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){
this.fittingStrategy.invalidateSelectedImage(numSeries,imgNum);
......@@ -3269,19 +3299,14 @@ For each point in the image
public LensDistortionParameters setupLensDistortionParameters(
int numImg,
// int stationNumber,
// int subCamera,
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 (
isTripod,
cartesian,
this.fittingStrategy.distortionCalibrationData.isTripod(),
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
// this.fittingStrategy.distortionCalibrationData.pars[numImg], //parVector,
this.fittingStrategy.distortionCalibrationData.getParameters(numImg), //parVector,
null, //boolean [] mask, // calculate only selected derivatives (all parVect values are still
debugLevel
......@@ -3298,16 +3323,13 @@ For each point in the image
double [] parVector=fittingStrategy.distortionCalibrationData.eyesisCameraParameters.getParametersVector(stationNumber,subCamera);
int goniometerHorizontalIndex=fittingStrategy.distortionCalibrationData.eyesisCameraParameters.getGoniometerHorizontalIndex();
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(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 (
isTripod,
cartesian,
this.fittingStrategy.distortionCalibrationData.isTripod(),
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
parVector,
null, //boolean [] mask, // calculate only selected derivatives (all parVect values are still
......@@ -3450,8 +3472,10 @@ For each point in the image
System.out.println("estimateGridOnSensor(): subCamera="+subCamera+", goniometerHorizontal="+goniometerHorizontal+", goniometerAxial="+goniometerAxial);
this.lensDistortionParameters.lensCalcInterParamers(
this.lensDistortionParameters, // 22-long parameter vector for the image
this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.isTripod,
this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.cartesian,
this.fittingStrategy.distortionCalibrationData.isTripod(),
this.fittingStrategy.distortionCalibrationData.isCartesian(),
this.fittingStrategy.distortionCalibrationData.getPixelSize(stationNumber, subCamera),
this.fittingStrategy.distortionCalibrationData.getDistortionRadius(stationNumber, subCamera),
null, // this.interParameterDerivatives, // [22][]
parVector,
null); // if no derivatives, null is OK
......@@ -3570,13 +3594,14 @@ For each point in the image
return; // no images found
}
double [] imgVector=fittingStrategy.getImageParametersVector(imgNum, vector); //this.currentVector);
// boolean [] imgMask= fittingStrategy.getImageParametersVectorMask(imgNum);
boolean [] imgMask= new boolean[imgVector.length];
for (int i=0;i<imgMask.length;i++) imgMask[i]=true;
this.lensDistortionParameters.lensCalcInterParamers(
this.lensDistortionParameters,
this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.isTripod,
this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.cartesian,
this.fittingStrategy.distortionCalibrationData.isTripod(),
this.fittingStrategy.distortionCalibrationData.isCartesian(),
this.fittingStrategy.distortionCalibrationData.getPixelSize(imgNum),
this.fittingStrategy.distortionCalibrationData.getDistortionRadius(imgNum),
this.interParameterDerivatives, // [22][]
imgVector,
imgMask); // calculate only selected derivatives (all parVect values are still
......@@ -3599,8 +3624,10 @@ For each point in the image
vector_delta[i]+=delta;
this.lensDistortionParameters.lensCalcInterParamers(
this.lensDistortionParameters,
this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.isTripod,
this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.cartesian,
this.fittingStrategy.distortionCalibrationData.isTripod(),
this.fittingStrategy.distortionCalibrationData.isCartesian(),
this.fittingStrategy.distortionCalibrationData.getPixelSize(imgNum),
this.fittingStrategy.distortionCalibrationData.getDistortionRadius(imgNum),
null, // this.interParameterDerivatives, // just values, no derivatives
vector_delta,
imgMask);
......@@ -3687,8 +3714,10 @@ For each point in the image
this.lensDistortionParameters.debugLevel=this.debugLevel;
this.lensDistortionParameters.lensCalcInterParamers(
this.lensDistortionParameters,
this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.isTripod,
this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.cartesian,
this.fittingStrategy.distortionCalibrationData.isTripod(),
this.fittingStrategy.distortionCalibrationData.isCartesian(),
this.fittingStrategy.distortionCalibrationData.getPixelSize(imgNum),
this.fittingStrategy.distortionCalibrationData.getDistortionRadius(imgNum),
calcJacobian?this.interParameterDerivatives:null, // [22][]
imgVector,
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
if (this.debugLevel>3) System.out.println("calculatePartialFxAndJacobian(), numImage="+numImage+" calcInterParamers():");
lensDistortionParameters.lensCalcInterParamers(
lensDistortionParameters,
this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.isTripod,
this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.cartesian,
this.fittingStrategy.distortionCalibrationData.isTripod(),
this.fittingStrategy.distortionCalibrationData.isCartesian(),
this.fittingStrategy.distortionCalibrationData.getPixelSize(numImage),
this.fittingStrategy.distortionCalibrationData.getDistortionRadius(numImage),
calcJacobian?interParameterDerivatives:null, // [22][]
imgVector,
imgMask); // calculate only selected derivatives (all parVect values are still
......@@ -3889,8 +3920,10 @@ For each point in the image
}
this.lensDistortionParameters.lensCalcInterParamers(
this.lensDistortionParameters,
this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.isTripod,
this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.cartesian,
this.fittingStrategy.distortionCalibrationData.isTripod(),
this.fittingStrategy.distortionCalibrationData.isCartesian(),
this.fittingStrategy.distortionCalibrationData.getPixelSize(imgNum),
this.fittingStrategy.distortionCalibrationData.getDistortionRadius(imgNum),
null, //this.interParameterDerivatives, // [22][]
imgVector,
imgMask); // calculate only selected derivatives (all parVect values are still
......@@ -4436,8 +4469,10 @@ List calibration
}
this.lensDistortionParameters.lensCalcInterParamers(
this.lensDistortionParameters,
this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.isTripod,
this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.cartesian,
this.fittingStrategy.distortionCalibrationData.isTripod(),
this.fittingStrategy.distortionCalibrationData.isCartesian(),
this.fittingStrategy.distortionCalibrationData.getPixelSize(imgNum),
this.fittingStrategy.distortionCalibrationData.getDistortionRadius(imgNum),
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
......@@ -7412,8 +7447,81 @@ List calibration
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;
/*
*
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){
*/
}
public boolean LevenbergMarquardt(
boolean openDialog,
boolean dry_run){ // do not save results
if (this.fittingStrategy==null) {
String msg="Fitting strategy does not exist, exiting";
IJ.showMessage("Error",msg);
......@@ -7497,7 +7605,7 @@ List calibration
") at "+ IJ.d2s(0.000000001*(System.nanoTime()-this.startTime),3));
}
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
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)
......@@ -7508,11 +7616,15 @@ List calibration
//stepLevenbergMarquardtAction();
if (state[1]) {
if (!state[0]) return false; // sequence failed
if (dry_run) {
wasLastSeries= true; // always just one series
} else {
saveFittingSeries();
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
}
}
......@@ -8024,8 +8136,8 @@ D2=
final int threadsMax,
final boolean updateStatus
){
final boolean isTripod=this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.isTripod;
final boolean cartesian=this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.cartesian;
// final boolean isTripod=this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.is_tripod;
// 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 double [][][] derivatives={ // for of /du, /dv 3 variants, depending on which neighbors are available
{
......@@ -8078,10 +8190,11 @@ D2=
// The following method sets this.lensDistortionParameters and invokes this.lensDistortionParameters.recalcCommons();
lensDistortionParameters.lensCalcInterParamers(
lensDistortionParameters,
isTripod,
cartesian,
fittingStrategy.distortionCalibrationData.isTripod(),
fittingStrategy.distortionCalibrationData.isCartesian(),
fittingStrategy.distortionCalibrationData.getPixelSize(imgNum),
fittingStrategy.distortionCalibrationData.getDistortionRadius(imgNum),
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
null); // if no derivatives, null is OK
// false); // calculate this.interParameterDerivatives -derivatives array (false - just this.values)
......@@ -8276,8 +8389,10 @@ D2=
// The following method sets this.lensDistortionParameters and invokes this.lensDistortionParameters.recalcCommons();
this.lensDistortionParameters.lensCalcInterParamers(
this.lensDistortionParameters,
this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.isTripod,
this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.cartesian,
fittingStrategy.distortionCalibrationData.isTripod(),
fittingStrategy.distortionCalibrationData.isCartesian(),
fittingStrategy.distortionCalibrationData.getPixelSize(imgNum),
fittingStrategy.distortionCalibrationData.getDistortionRadius(imgNum),
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
......@@ -9722,6 +9837,8 @@ M * V = B
}
}
LensDistortionParameters ldp=this.lensDistortionParameters.clone();
// 06/2019 - need to update distortionRadius, pixelSize)
// 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) {
......
......@@ -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
GenericDialog gd=new GenericDialog("Select images "+startIndex+"..."+(endIndex-1));
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)+
": "+this.distortionCalibrationData.gIP[i].channel+
" matched "+this.distortionCalibrationData.gIP[i].matchedPointers+" pointers"+
", hinted state: "+((hintedMatch[i]<0)?"undefined":((hintedMatch[i]==0)?"failed":((hintedMatch[i]==1)?"orientation":"orientation and translation"))),
selection[i]);
......@@ -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 new enabled images", selectNewEnabled);
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 low-res sensors", true);
}
......@@ -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 askNextSeries Ask for next series number
* @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
*/
......@@ -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
// not zeroAndOther:
// 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 = -1;
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
* @param useParameters Select parameters for this series
* @param askNextSeries Ask for next series number
* @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
*/
public int selectStrategyStep(
......@@ -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]);
}
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 low-res sensors", true);
}
......@@ -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
// not zeroAndOther:
// 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 = -1;
if (this.distortionCalibrationData.isSubcameraParameter(parIndex)) { // only for subcamera parameters
......
......@@ -989,7 +989,9 @@ horizontal axis:
// TODO: Set initial values for the goniometer angles from the sensor
// (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)
System.out.println("Finished LMA at "
+ IJ.d2s(0.000000001 * (System.nanoTime() - startTime), 3));
......
......@@ -5,9 +5,9 @@ import java.util.Properties;
import com.elphel.imagej.cameras.EyesisSubCameraParameters;
import com.elphel.imagej.common.WindowTools;
import Jama.Matrix;
import ij.IJ;
import ij.gui.GenericDialog;
import Jama.Matrix;
//import EyesisCameraParameters;
//import Distortions.EyesisSubCameraParameters;
......@@ -97,24 +97,25 @@ import Jama.Matrix;
}
}
public LensDistortionParameters(
// LensDistortionParameters lensDistortionParameters,
boolean isTripod,
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 [] parVect,
boolean [] mask, // calculate only selected derivatives (all parVect values are still
int debugLevel
// boolean calculateDerivatives // calculate this.interParameterDerivatives -derivatives array (false - just this.values)
){
this.debugLevel=debugLevel;
lensCalcInterParamers( // changed name to move calcInterParamers method from enclosing class
this,
isTripod,
cartesian,
pixelSize,
distortionRadius,
interParameterDerivatives, //partial derivative matrix from subcamera-camera-goniometer to single camera (12x21) if null - just values, no derivatives
parVect,
mask // calculate only selected derivatives (all parVect values are still
// boolean calculateDerivatives // calculate this.interParameterDerivatives -derivatives array (false - just this.values)
);
}
......@@ -197,6 +198,7 @@ import Jama.Matrix;
null // r_od,
);
}
@Override
public LensDistortionParameters clone() {
return new LensDistortionParameters(
this.focalLength,
......@@ -1861,6 +1863,8 @@ dPXmmc/dphi=
LensDistortionParameters lensDistortionParameters,
boolean isTripod,
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 [] parVect,
boolean [] mask // calculate only selected derivatives (all parVect values are still
......@@ -2056,6 +2060,10 @@ dPXmmc/dphi=
// System.out.println("interParameterDerivatives[0]="+sprintfArray(interParameterDerivatives[0]));
}
double [] extrinsicParams=parametersFromMAMB(MA,MB); // all after 6 are 0;
lensDistortionParameters.pixelSize = pixelSize;
lensDistortionParameters.distortionRadius = distortionRadius;
lensDistortionParameters.distance=extrinsicParams[2];
lensDistortionParameters.x0=extrinsicParams[0];
lensDistortionParameters.y0=extrinsicParams[1];
......@@ -2087,21 +2095,8 @@ dPXmmc/dphi=
lensDistortionParameters.r_od[i][0]=parVect[index++];
lensDistortionParameters.r_od[i][1]=parVect[index++];
}
/*
for (double [] row :lensDistortionParameters.r_xy){
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
lensDistortionParameters.recalcCommons(); // uncluding lensDistortionParameters.r_xyod
if (this.debugLevel>2){
......@@ -2816,4 +2811,3 @@ dPXmmc/dphi=
public int getNumInputs(){return numInputs;}
public int getNumOutputs(){return numOutputs;}
}
\ No newline at end of file
......@@ -62,8 +62,8 @@ import ij.gui.GenericDialog;
// non-adjustable parameters, not parts of vector
public int numStations;
public double [] stationWeight; // reprojection error weights (close station - relax errors)
public boolean isTripod= false; // when true - make goniometerHorizontal rotation around "vertical" axis and "goniometerAxial" - around
public boolean cartesian=false; //
private boolean is_tripod= false; // when true - make goniometerHorizontal rotation around "vertical" axis and "goniometerAxial" - around
private boolean cartesian=false; //
// rotated horizontal.
private int defaultSensorWidth= 2592;
private int defaultSensorHeight= 1936;
......@@ -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 badNodeThreshold=0.1; // filter out grid nodes with difference from quadratically predicted from 8 neighbors in pixels
public int maxBadNeighb= 1; // maximal number of bad nodes around the corrected one to fix
public int minimalValidNodes=50; // do not use images with less than this number of non-zero nodes (after all applicable weight masks)
public int 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 double weightMultiExponent= 1.0;
public double weightDiameterExponent=1.0; // if( >0) use grid diameter to scale weights of this image
......@@ -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 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 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 double [][] variationsDefaults={
null, // 0
......@@ -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} // 16 GXYZ2
};
public boolean isTripod() {
return is_tripod;
}
public boolean isCartesian() {
return cartesian;
}
public boolean isLwirUnmarkedInverted() {
return invertUnmarkedLwirGrid;
}
public int tiltIndex=6;
private ParameterVariationCosts [] parameterVariationCosts=null;
......@@ -337,7 +351,8 @@ import ij.gui.GenericDialog;
double shrinkBlurLevel,
double balanceChannelWeightsMode,
double removeOverRMS,
double removeOverRMSNonweighted
double removeOverRMSNonweighted,
boolean invertUnmarkedLwirGrid
){
double [] GXYZ={GXYZ_0,GXYZ_1,GXYZ_2};
setSameEyesisCameraParameters (
......@@ -372,7 +387,8 @@ import ij.gui.GenericDialog;
shrinkBlurLevel,
balanceChannelWeightsMode,
removeOverRMS,
removeOverRMSNonweighted
removeOverRMSNonweighted,
invertUnmarkedLwirGrid
);
}
public EyesisCameraParameters (
......@@ -407,7 +423,8 @@ import ij.gui.GenericDialog;
double shrinkBlurLevel,
double balanceChannelWeightsMode,
double removeOverRMS,
double removeOverRMSNonweighted
double removeOverRMSNonweighted,
boolean invertUnmarkedLwirGrid
){
setSameEyesisCameraParameters (
numStations,
......@@ -441,7 +458,8 @@ import ij.gui.GenericDialog;
shrinkBlurLevel,
balanceChannelWeightsMode,
removeOverRMS,
removeOverRMSNonweighted
removeOverRMSNonweighted,
invertUnmarkedLwirGrid
);
}
void setSameEyesisCameraParameters (
......@@ -476,10 +494,11 @@ import ij.gui.GenericDialog;
double shrinkBlurLevel,
double balanceChannelWeightsMode,
double removeOverRMS,
double removeOverRMSNonweighted
double removeOverRMSNonweighted,
boolean invertUnmarkedLwirGrid
){
this.numStations=numStations;
this.isTripod=isTripod;
this.is_tripod=isTripod;
this.cartesian = cartesian; // Need to set each subcamera?
this.defaultSensorWidth=defaultSensorWidth;
this.defaultSensorHeight=defaultSensorHeight;
......@@ -543,7 +562,7 @@ import ij.gui.GenericDialog;
EyesisCameraParameters source,
EyesisCameraParameters destination) {
destination.numStations=newNumStations;
destination.isTripod=source.isTripod;
destination.is_tripod=source.is_tripod;
destination.defaultSensorWidth=source.defaultSensorWidth;
destination.defaultSensorHeight=source.defaultSensorHeight;
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;
destination.shrinkBlurLevel=source.shrinkBlurLevel;
destination.balanceChannelWeightsMode=source.balanceChannelWeightsMode;
destination.removeOverRMSNonweighted=source.removeOverRMSNonweighted;
destination.invertUnmarkedLwirGrid=source.invertUnmarkedLwirGrid;
destination.goniometerHorizontal=new double[destination.numStations];
destination.goniometerAxial=new double[destination.numStations];
destination.interAxisDistance=new double[destination.numStations];
......@@ -598,7 +618,7 @@ import ij.gui.GenericDialog;
}
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+"defaultSensorWidth",this.defaultSensorWidth+"");
properties.setProperty(prefix+"defaultSensorHeight",this.defaultSensorHeight+"");
......@@ -618,6 +638,7 @@ import ij.gui.GenericDialog;
properties.setProperty(prefix+"balanceChannelWeightsMode",this.balanceChannelWeightsMode+"");
properties.setProperty(prefix+"removeOverRMS",this.removeOverRMS+"");
properties.setProperty(prefix+"removeOverRMSNonweighted",this.removeOverRMSNonweighted+"");
properties.setProperty(prefix+"invertUnmarkedLwirGrid",this.invertUnmarkedLwirGrid+"");
properties.setProperty(prefix+"numSubCameras",this.eyesisSubCameras[0].length+"");
properties.setProperty(prefix+"numStations",this.numStations+"");
for (int numStation=0;numStation<this.numStations;numStation++){
......@@ -641,7 +662,7 @@ import ij.gui.GenericDialog;
}
public void getProperties(String prefix,Properties properties){
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)
this.cartesian=Boolean.parseBoolean(properties.getProperty(prefix+"cartesian"));
// For old compatibility
......@@ -690,6 +711,9 @@ import ij.gui.GenericDialog;
this.removeOverRMS=Double.parseDouble(properties.getProperty(prefix+"removeOverRMS"));
if (properties.getProperty(prefix+"removeOverRMSNonweighted")!=null)
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
int newNumStations=1;
int numSubCameras=0;
......@@ -799,14 +823,14 @@ import ij.gui.GenericDialog;
modelChoice[0]="--- keep current ---";
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.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 ===");
for (int numStation=0;numStation<this.numStations;numStation++) {
if (this.numStations>1){
gd.addMessage("--- Station number "+numStation+" ---");
gd.addNumericField("Station reprojection errors weight", 100*this.stationWeight[numStation], 1,5,"%");
}
if (this.isTripod) {
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 horizontal axis (camera up - positive)", this.goniometerAxial[numStation], 3,7,"degrees");
} else {
......@@ -816,7 +840,7 @@ import ij.gui.GenericDialog;
gd.addNumericField("Distance between goniometer axes", this.interAxisDistance[numStation], 3,7,"mm");
gd.addNumericField("Angle error between goniometer axes (<0 if vertical axis rotated CW )",this.interAxisAngle[numStation], 3,7,"degrees");
if (this.isTripod) {
if (this.is_tripod) {
gd.addNumericField("Vertical tripod axis tilt from true vertical", this.horAxisErrPhi[numStation], 3,7,"degrees");
gd.addNumericField("Vertical tripod axis roll error from true vertical", this.horAxisErrPsi[numStation], 3,7,"degrees");
} else {
......@@ -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("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.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 module to edit (<=0 - none)", nextSubCamera, 0,2,"");
gd.enableYesNoCancel("OK", "Done");
......@@ -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++) {
if (this.numStations>1){
this.stationWeight[numStation]=0.01*gd.getNextNumber();
......@@ -904,6 +929,7 @@ import ij.gui.GenericDialog;
this.balanceChannelWeightsMode= gd.getNextNumber();
this.removeOverRMS = gd.getNextNumber();
this.removeOverRMSNonweighted= gd.getNextNumber();
this.invertUnmarkedLwirGrid = gd.getNextBoolean();
int numSubCams= (int) gd.getNextNumber();
int numSubCam= (int) gd.getNextNumber();
if (numSubCams!=this.eyesisSubCameras[0].length){
......@@ -2504,8 +2530,8 @@ import ij.gui.GenericDialog;
public int offset_channel = 4; // 0;
public int new_subcam = 1; // new subcamera number
public double offset_height = 50.8;
public double offset_right = -35.0; //vnir -35., lwir +35.0
public double offset_forward = 15.0; //vnir +??, lwir -??
public double offset_right = -35.0; //eo -35., lwir +35.0
public double offset_forward = 15.0; //eo +??, lwir -??
public double offset_heading = 0.0;
public double offset_elevation = 0.0;
public double offset_roll = 0.0;
......
......@@ -5476,7 +5476,7 @@ public class EyesisCorrectionParameters {
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]+"}");
gd.addTab ("LWIR", "parameters for LWIR/VNIR 8-camera rig");
gd.addTab ("LWIR", "parameters for LWIR/EO 8-camera rig");
this.lwir.dialogQuestions(gd);
// gd.buildDialog();
......
......@@ -362,4 +362,12 @@ import java.util.Properties;
updateCartesian();
this.cartesian = cartesian;
}
public double getPixelSize() {
return this.pixelSize;
}
public double getDistortionRadius() {
return this.distortionRadius;
}
}
......@@ -496,12 +496,12 @@ public class LwirReader {
if (lrp.lwir_ffc) {
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(
num_frames,
// lrp.lwir_telemetry,
false, // final boolean show,
lrp.vnir_scale);
lrp.eo_scale);
if (imps == null) {
LOGGER.error("acquire(): failed to acquire images");
return null;
......@@ -521,9 +521,9 @@ public class LwirReader {
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++) {
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(
imps,
......@@ -605,10 +605,10 @@ public class LwirReader {
public boolean programLWIRCamera(LwirReaderParameters lrp) {
int lwir_master_port = 0;
int vnir_master_port = 0;
int eo_master_port = 0;
int num_lwir = lrp.lwir_channels.length;
int num_vnir = lrp.vnir_channels.length;
final String [] urls = new String [num_lwir + num_vnir];
int num_eo = lrp.eo_channels.length;
final String [] urls = new String [num_lwir + num_eo];
for (int chn:lrp.lwir_channels) {
urls[chn] = "http://"+lrp.lwir_ip+"/parsedit.php?immediate&sensor_port="+chn+
"&BITS=16"+
......@@ -623,21 +623,21 @@ public class LwirReader {
"&XMIT_TIMESTAMP=1*0";
}
}
for (int chn:lrp.vnir_channels) {
for (int chn:lrp.eo_channels) {
int minExposure=10; // usec
int maxExposure=1000000; //usec
int minGain=(int) (0x10000*1.0);
int maxGain=(int) (0x10000*15.75);
int minScale=0;
int maxScale=(int) (0x10000*4.0);
int exposure= (int) (Math.round(1000*lrp.vnir_exposure_ms * lrp.vnir_exp_corr[chn]));
int autoExposureMax= (int) (Math.round(1000*lrp.vnir_max_autoexp_ms));
int gain= (int) (Math.round(0x10000*lrp.vnir_gain_g));
int rScale= (int) (Math.round(0x10000*lrp.vnir_gain_rg*lrp.vnir_gcorr_rbgb[3*chn+0]));
int bScale= (int) (Math.round(0x10000*lrp.vnir_gain_bg*lrp.vnir_gcorr_rbgb[3*chn+1]));
int gScale= (int) (Math.round(0x10000* lrp.vnir_gcorr_rbgb[3*chn+2]));
int autoExp= lrp.vnir_autoexp?1:0;
int autoWB= lrp.vnir_whitebal?1:0;
int exposure= (int) (Math.round(1000*lrp.eo_exposure_ms * lrp.eo_exp_corr[chn]));
int autoExposureMax= (int) (Math.round(1000*lrp.eo_max_autoexp_ms));
int gain= (int) (Math.round(0x10000*lrp.eo_gain_g));
int rScale= (int) (Math.round(0x10000*lrp.eo_gain_rg*lrp.eo_gcorr_rbgb[3*chn+0]));
int bScale= (int) (Math.round(0x10000*lrp.eo_gain_bg*lrp.eo_gcorr_rbgb[3*chn+1]));
int gScale= (int) (Math.round(0x10000* lrp.eo_gcorr_rbgb[3*chn+2]));
int autoExp= lrp.eo_autoexp?1:0;
int autoWB= lrp.eo_whitebal?1:0;
if (exposure<minExposure) exposure=minExposure; else if (exposure>maxExposure) exposure=maxExposure;
if (autoExposureMax<minExposure) autoExposureMax=minExposure; else if (autoExposureMax>maxExposure) autoExposureMax=maxExposure;
if (gain<minGain) gain= minGain ; else if (gain> maxGain) gain= maxGain;
......@@ -645,9 +645,9 @@ public class LwirReader {
if (bScale<minScale) bScale= minScale ; else if (bScale> maxScale) bScale= 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
"&QUALITY="+lrp.vnir_quality+ // "*0"+
"&QUALITY="+lrp.eo_quality+ // "*0"+
"&EXPOS="+exposure+ // "*0"+
"&AUTOEXP_EXP_MAX="+autoExposureMax+//"*0"+
"&AUTOEXP_ON="+autoExp+//"*0"+
......@@ -659,7 +659,7 @@ public class LwirReader {
"&DAEMON_EN_TEMPERATURE=1";//"*0";
if (chn == vnir_master_port) {
if (chn == eo_master_port) {
urls[num_lwir+chn] += "&TRIG=4*0"+
"&TRIG_CONDITION=611669*0"+ // external input
"&TRIG_BITLENGTH=31*0"+
......
......@@ -41,45 +41,45 @@ public class LwirReaderParameters {
protected boolean lwir_ffc = true;
protected boolean avg_all = true;
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 [] vnir_channels = {0, 1, 2 ,3};
protected int [] eo_channels = {0, 1, 2 ,3};
protected boolean lwir_telemetry = true;
protected double vnir_quality = 98.0;
protected boolean vnir_scale = false; // restore sensor pixel values, undo camera white balancing
protected boolean vnir_autoexp = false;
protected double vnir_max_autoexp_ms = 20.0;
protected double vnir_exposure_ms = 5.0;
protected boolean vnir_whitebal = false;
protected double vnir_gain_g = 2.0;
protected double vnir_gain_rg = 0.7705; // 1.116; halogen/fluorescent
protected double vnir_gain_bg = 2.401; // 1.476;
protected double eo_quality = 98.0;
protected boolean eo_scale = false; // restore sensor pixel values, undo camera white balancing
protected boolean eo_autoexp = false;
protected double eo_max_autoexp_ms = 20.0;
protected double eo_exposure_ms = 5.0;
protected boolean eo_whitebal = false;
protected double eo_gain_g = 2.0;
protected double eo_gain_rg = 0.7705; // 1.116; halogen/fluorescent
protected double eo_gain_bg = 2.401; // 1.476;
protected boolean [] selected_channels = {true, true, true, true, true, true, true, true};
protected int max_lwir_width = 1024; //
/*
protected double [] vnir_exp_corr = {1.0, 1.0, 1.0, 1.0};
protected double [] vnir_gcorr_rbgb = {
protected double [] eo_exp_corr = {1.0, 1.0, 1.0, 1.0};
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};
*/
protected double [] vnir_exp_corr = {
protected double [] eo_exp_corr = {
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.0668, 1.1055, 1.0006,
1.1533, 1.0780, 1.0015,
0.9966, 1.0445, 1.0023};
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 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 boolean show_images = false;
protected int lwir_chn0 = 0; // not configurable
protected int vnir_chn0 = 4; // not configurable
protected int eo_chn0 = 4; // not configurable
// --- interface methods
......@@ -87,8 +87,8 @@ public class LwirReaderParameters {
return lwir_chn0;
}
public int getVnirChn0 () {
return vnir_chn0;
public int getEoChn0 () {
return eo_chn0;
}
public boolean is_LWIR(int width) {
......@@ -115,23 +115,23 @@ public class LwirReaderParameters {
properties.setProperty(prefix+"lwir_ffc", this.lwir_ffc+"");
properties.setProperty(prefix+"avg_all", this.avg_all+"");
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+"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+"vnir_quality", this.vnir_quality+"");
properties.setProperty(prefix+"vnir_scale", this.vnir_scale+"");
properties.setProperty(prefix+"vnir_autoexp", this.vnir_autoexp+"");
properties.setProperty(prefix+"vnir_max_autoexp_ms", this.vnir_max_autoexp_ms+"");
properties.setProperty(prefix+"vnir_exposure_ms", this.vnir_exposure_ms+"");
properties.setProperty(prefix+"vnir_whitebal", this.vnir_whitebal+"");
properties.setProperty(prefix+"vnir_gain_g", this.vnir_gain_g+"");
properties.setProperty(prefix+"vnir_gain_rg", this.vnir_gain_rg+"");
properties.setProperty(prefix+"vnir_gain_bg", this.vnir_gain_bg+"");
properties.setProperty(prefix+"vnir_exp_corr", arr_to_str(this.vnir_exp_corr));
properties.setProperty(prefix+"vnir_gcorr_rbgb", arr_to_str(this.vnir_gcorr_rbgb));
properties.setProperty(prefix+"eo_quality", this.eo_quality+"");
properties.setProperty(prefix+"eo_scale", this.eo_scale+"");
properties.setProperty(prefix+"eo_autoexp", this.eo_autoexp+"");
properties.setProperty(prefix+"eo_max_autoexp_ms", this.eo_max_autoexp_ms+"");
properties.setProperty(prefix+"eo_exposure_ms", this.eo_exposure_ms+"");
properties.setProperty(prefix+"eo_whitebal", this.eo_whitebal+"");
properties.setProperty(prefix+"eo_gain_g", this.eo_gain_g+"");
properties.setProperty(prefix+"eo_gain_rg", this.eo_gain_rg+"");
properties.setProperty(prefix+"eo_gain_bg", this.eo_gain_bg+"");
properties.setProperty(prefix+"eo_exp_corr", arr_to_str(this.eo_exp_corr));
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+"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_frame_diff", this.max_frame_diff+"");
properties.setProperty(prefix+"debug_level", this.debug_level+"");
......@@ -141,27 +141,42 @@ public class LwirReaderParameters {
}
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+"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+"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+"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+"vnir_quality")!=null) this.vnir_quality=Double.parseDouble(properties.getProperty(prefix+"vnir_quality"));
if (properties.getProperty(prefix+"vnir_scale")!=null) this.vnir_scale= Boolean.parseBoolean(properties.getProperty(prefix+"vnir_scale"));
if (properties.getProperty(prefix+"vnir_autoexp")!=null) this.vnir_autoexp= Boolean.parseBoolean(properties.getProperty(prefix+"vnir_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+"vnir_exposure_ms")!=null) this.vnir_exposure_ms=Double.parseDouble(properties.getProperty(prefix+"vnir_exposure_ms"));
if (properties.getProperty(prefix+"vnir_whitebal")!=null) this.vnir_whitebal= Boolean.parseBoolean(properties.getProperty(prefix+"vnir_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+"vnir_gain_rg")!=null) this.vnir_gain_rg=Double.parseDouble(properties.getProperty(prefix+"vnir_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+"vnir_exp_corr")!=null) this.vnir_exp_corr=str_to_darr(properties.getProperty(prefix+"vnir_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_quality")!=null) this.eo_quality=Double.parseDouble(properties.getProperty(prefix+"eo_quality"));
if (properties.getProperty(prefix+"eo_scale")!=null) this.eo_scale= Boolean.parseBoolean(properties.getProperty(prefix+"eo_scale"));
if (properties.getProperty(prefix+"eo_autoexp")!=null) this.eo_autoexp= Boolean.parseBoolean(properties.getProperty(prefix+"eo_autoexp"));
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+"eo_exposure_ms")!=null) this.eo_exposure_ms=Double.parseDouble(properties.getProperty(prefix+"eo_exposure_ms"));
if (properties.getProperty(prefix+"eo_whitebal")!=null) this.eo_whitebal= Boolean.parseBoolean(properties.getProperty(prefix+"eo_whitebal"));
if (properties.getProperty(prefix+"eo_gain_g")!=null) this.eo_gain_g=Double.parseDouble(properties.getProperty(prefix+"eo_gain_g"));
if (properties.getProperty(prefix+"eo_gain_rg")!=null) this.eo_gain_rg=Double.parseDouble(properties.getProperty(prefix+"eo_gain_rg"));
if (properties.getProperty(prefix+"eo_gain_bg")!=null) this.eo_gain_bg=Double.parseDouble(properties.getProperty(prefix+"eo_gain_bg"));
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+"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+"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_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"));
......@@ -176,23 +191,23 @@ public class LwirReaderParameters {
lrp.lwir_ffc= this.lwir_ffc;
lrp.avg_all= this.avg_all;
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.vnir_channels= this.vnir_channels.clone();
lrp.eo_channels= this.eo_channels.clone();
lrp.lwir_telemetry= this.lwir_telemetry;
lrp.vnir_quality= this.vnir_quality;
lrp.vnir_scale= this.vnir_scale;
lrp.vnir_autoexp= this.vnir_autoexp;
lrp.vnir_max_autoexp_ms= this.vnir_max_autoexp_ms;
lrp.vnir_exposure_ms= this.vnir_exposure_ms;
lrp.vnir_whitebal= this.vnir_whitebal;
lrp.vnir_gain_g= this.vnir_gain_g;
lrp.vnir_gain_rg= this.vnir_gain_rg;
lrp.vnir_gain_bg= this.vnir_gain_bg;
lrp.vnir_exp_corr= this.vnir_exp_corr.clone();
lrp.vnir_gcorr_rbgb= this.vnir_gcorr_rbgb.clone();
lrp.eo_quality= this.eo_quality;
lrp.eo_scale= this.eo_scale;
lrp.eo_autoexp= this.eo_autoexp;
lrp.eo_max_autoexp_ms= this.eo_max_autoexp_ms;
lrp.eo_exposure_ms= this.eo_exposure_ms;
lrp.eo_whitebal= this.eo_whitebal;
lrp.eo_gain_g= this.eo_gain_g;
lrp.eo_gain_rg= this.eo_gain_rg;
lrp.eo_gain_bg= this.eo_gain_bg;
lrp.eo_exp_corr= this.eo_exp_corr.clone();
lrp.eo_gcorr_rbgb= this.eo_gcorr_rbgb.clone();
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_frame_diff= this.max_frame_diff;
lrp.debug_level= this.debug_level;
......@@ -214,23 +229,23 @@ public class LwirReaderParameters {
(lrp.lwir_ffc == this.lwir_ffc) &&
(lrp.avg_all == this.avg_all) &&
(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.vnir_channels, this.vnir_channels)) &&
(java.util.Arrays.equals(lrp.eo_channels, this.eo_channels)) &&
(lrp.lwir_telemetry == this.lwir_telemetry) &&
(lrp.vnir_quality == this.vnir_quality) &&
(lrp.vnir_scale == this.vnir_scale) &&
(lrp.vnir_autoexp == this.vnir_autoexp) &&
(lrp.vnir_max_autoexp_ms == this.vnir_max_autoexp_ms) &&
(lrp.vnir_exposure_ms == this.vnir_exposure_ms) &&
(lrp.vnir_whitebal == this.vnir_whitebal) &&
(lrp.vnir_gain_g == this.vnir_gain_g) &&
(lrp.vnir_gain_rg == this.vnir_gain_rg) &&
(lrp.vnir_gain_bg == this.vnir_gain_bg) &&
(java.util.Arrays.equals(lrp.vnir_exp_corr, this.vnir_exp_corr)) &&
(java.util.Arrays.equals(lrp.vnir_gcorr_rbgb, this.vnir_gcorr_rbgb)) &&
(lrp.eo_quality == this.eo_quality) &&
(lrp.eo_scale == this.eo_scale) &&
(lrp.eo_autoexp == this.eo_autoexp) &&
(lrp.eo_max_autoexp_ms == this.eo_max_autoexp_ms) &&
(lrp.eo_exposure_ms == this.eo_exposure_ms) &&
(lrp.eo_whitebal == this.eo_whitebal) &&
(lrp.eo_gain_g == this.eo_gain_g) &&
(lrp.eo_gain_rg == this.eo_gain_rg) &&
(lrp.eo_gain_bg == this.eo_gain_bg) &&
(java.util.Arrays.equals(lrp.eo_exp_corr, this.eo_exp_corr)) &&
(java.util.Arrays.equals(lrp.eo_gcorr_rbgb, this.eo_gcorr_rbgb)) &&
(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_frame_diff == this.max_frame_diff) &&
(lrp.debug_level == this.debug_level) &&
......@@ -246,25 +261,25 @@ public class LwirReaderParameters {
result = prime * result + (lwir_ffc?1:0);
result = prime * result + (avg_all?1:0);
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(vnir_channels).hashCode();
result = prime * result + arr_to_str(eo_channels).hashCode();
result = prime * result + (lwir_telemetry?1:0);
result = prime * result + (new Double(vnir_quality)).hashCode();
result = prime * result + (vnir_scale?1:0);
result = prime * result + (vnir_autoexp?1:0);
result = prime * result + (new Double(vnir_max_autoexp_ms)).hashCode();
result = prime * result + (new Double(vnir_exposure_ms)).hashCode();
result = prime * result + (vnir_whitebal?1:0);
result = prime * result + (new Double(vnir_gain_g)).hashCode();
result = prime * result + (new Double(vnir_gain_rg)).hashCode();
result = prime * result + (new Double(vnir_gain_bg)).hashCode();
result = prime * result + arr_to_str(vnir_exp_corr).hashCode();
result = prime * result + arr_to_str(vnir_gcorr_rbgb).hashCode();
result = prime * result + (new Double(eo_quality)).hashCode();
result = prime * result + (eo_scale?1:0);
result = prime * result + (eo_autoexp?1:0);
result = prime * result + (new Double(eo_max_autoexp_ms)).hashCode();
result = prime * result + (new Double(eo_exposure_ms)).hashCode();
result = prime * result + (eo_whitebal?1:0);
result = prime * result + (new Double(eo_gain_g)).hashCode();
result = prime * result + (new Double(eo_gain_rg)).hashCode();
result = prime * result + (new Double(eo_gain_bg)).hashCode();
result = prime * result + arr_to_str(eo_exp_corr).hashCode();
result = prime * result + arr_to_str(eo_gcorr_rbgb).hashCode();
result = prime * result + (new Integer(lwir_trig_dly)).hashCode();
result = prime * result + arr_to_str(selected_channels).hashCode();
// 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 Integer(max_frame_diff)).hashCode();
return 0;
......@@ -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 ("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 ("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 ("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.addNumericField("VNIR quality", this.vnir_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 ("VNIR autoexposure", this.vnir_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("VNIR exposure", this.vnir_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.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("VNIR gain R/G", this.vnir_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.addStringField ("VNIR exposuere corrections", arr_to_str(this.vnir_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.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("VNIR lag", this.vnir_lag, 0,3,"","Visible camera lag (in frames) relative to LWIR one");
gd.addNumericField("EO quality", this.eo_quality, 3,6,"%", "Visible range camera JPEG compression quality (all channels)");
gd.addCheckbox ("EO undo white balance", this.eo_scale, "Undo in-camera white balancing");
gd.addCheckbox ("EO autoexposure", this.eo_autoexp, "Enable autoexposure for the visible range camera");
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("EO exposure", this.eo_exposure_ms, 3,6,"ms", "Visible range camera exposure time (all channels)");
gd.addCheckbox ("EO white balance", this.eo_whitebal, "Enable automatic white balancing for the visible range camera");
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("EO gain R/G", this.eo_gain_rg, 3,6,"","Red 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 ("EO exposuere corrections", arr_to_str(this.eo_exp_corr), 50, "Fine corrections of channel exposures (4 channel relative exposures)");
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 EO exactly 1 frame after LWIR. 0 does not work with current FPGA - usec do not match sec in transmitted timestamp");
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 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");
......@@ -304,23 +319,23 @@ public class LwirReaderParameters {
this.lwir_ffc = gd.getNextBoolean();
this.avg_all = gd.getNextBoolean();
this.lwir_ip = gd.getNextString();
this.vnir_ip = gd.getNextString();
this.eo_ip = 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.vnir_quality = gd.getNextNumber();
this.vnir_scale = gd.getNextBoolean();
this.vnir_autoexp = gd.getNextBoolean();
this.vnir_max_autoexp_ms = gd.getNextNumber();
this.vnir_exposure_ms = gd.getNextNumber();
this.vnir_whitebal = gd.getNextBoolean();
this.vnir_gain_g = gd.getNextNumber();
this.vnir_gain_rg = gd.getNextNumber();
this.vnir_gain_bg = gd.getNextNumber();
this.vnir_exp_corr = str_to_darr(gd.getNextString());
this.vnir_gcorr_rbgb = str_to_darr(gd.getNextString());
this.eo_quality = gd.getNextNumber();
this.eo_scale = gd.getNextBoolean();
this.eo_autoexp = gd.getNextBoolean();
this.eo_max_autoexp_ms = gd.getNextNumber();
this.eo_exposure_ms = gd.getNextNumber();
this.eo_whitebal = gd.getNextBoolean();
this.eo_gain_g = gd.getNextNumber();
this.eo_gain_rg = gd.getNextNumber();
this.eo_gain_bg = gd.getNextNumber();
this.eo_exp_corr = str_to_darr(gd.getNextString());
this.eo_gcorr_rbgb = str_to_darr(gd.getNextString());
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_frame_diff = (int) gd.getNextNumber();
this.debug_level = (int) gd.getNextNumber();
......@@ -361,7 +376,7 @@ public class LwirReaderParameters {
return sel;
}
public boolean [] getSelectedVnir(){
public boolean [] getSelectedEo(){
boolean [] sel = selected_channels.clone();
for (int i = 0; i < lwir_channels.length; i++ ) {
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