Commit 96c4558f authored by Andrey Filippov's avatar Andrey Filippov

Debugging fitting strategies, initial image parameter setup

parent f1c19f00
......@@ -2634,6 +2634,7 @@ if (MORE_BUTTONS) {
parFilter,
""); //String defaultPath
if ((pathname==null) || (pathname=="")) return;
System.out.println("*** Will not work with different size senspors !!!");
DISTORTION_CALIBRATION_DATA.setMaskFromImageStack(pathname);
if (LENS_DISTORTIONS!=null) LENS_DISTORTIONS.updateSensorMasks();
return;
......@@ -3642,8 +3643,8 @@ if (MORE_BUTTONS) {
double threadPitch=0.35; // M1.6
double dPx0=camPars.eyesisSubCameras[stationNumber][0].px0-(camPars.sensorWidth/2)-FOCUS_MEASUREMENT_PARAMETERS.centerDeltaX;
double dPy0=camPars.eyesisSubCameras[stationNumber][0].py0-(camPars.sensorHeight/2)-FOCUS_MEASUREMENT_PARAMETERS.centerDeltaY;
double dPx0=camPars.eyesisSubCameras[stationNumber][0].px0-(camPars.getSensorWidth(0)/2)-FOCUS_MEASUREMENT_PARAMETERS.centerDeltaX;
double dPy0=camPars.eyesisSubCameras[stationNumber][0].py0-(camPars.getSensorHeight(0)/2)-FOCUS_MEASUREMENT_PARAMETERS.centerDeltaY;
double psi=camPars.eyesisSubCameras[stationNumber][0].psi; // degrees, rotation (of the sensor) around the optical axis. Positive if camera is rotated clockwise looking to the target
FOCUS_MEASUREMENT_PARAMETERS.result_PX0=camPars.eyesisSubCameras[stationNumber][0].px0;
......@@ -5026,8 +5027,8 @@ if (MORE_BUTTONS) {
if (DEBUG_LEVEL>2) System.out.println("sfeParameters["+numSFE+"].length="+sfeParameters[numSFE].length);
if (DEBUG_LEVEL>2) System.out.println("sfeParameters["+numSFE+"]["+iLens+"].length="+sfeParameters[numSFE][iLens].length);
sfeParameters[numSFE][iLens][iState]=FOCUS_MEASUREMENT_PARAMETERS.clone();
sensorDimensions[numSFE][0]=EYESIS_CAMERA_PARAMETERS.sensorWidth; // should be the same for all lenses/states
sensorDimensions[numSFE][1]=EYESIS_CAMERA_PARAMETERS.sensorHeight;
sensorDimensions[numSFE][0]=EYESIS_CAMERA_PARAMETERS.getSensorWidth(numSFE); // should be the same for all lenses/states
sensorDimensions[numSFE][1]=EYESIS_CAMERA_PARAMETERS.getSensorHeight(numSFE);
iState++;
}
iLens++;
......@@ -5492,12 +5493,12 @@ if (MORE_BUTTONS) {
String path=dFile+Prefs.getFileSeparator()+lensPrefix+CAMERAS.getLastTimestampUnderscored()+
(modeAverage?"-summary.csv":"-tempscan.csv");
if (MASTER_DEBUG_LEVEL>0) System.out.println ((modeAverage?"Saving averaged measurements to ":"Saving temperature measurement log data to ")+path);
int sensorWidth=2992,sensorHeight=1936;
int sensorWidth=2592,sensorHeight=1936;
if ((LENS_DISTORTIONS!=null) && (LENS_DISTORTIONS.fittingStrategy!=null) && (LENS_DISTORTIONS.fittingStrategy!=null)&&
(LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData!=null) &&
(LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.eyesisCameraParameters!=null)){
sensorWidth=LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.sensorWidth;
sensorHeight=LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.sensorHeight;
sensorWidth=LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.getSensorWidth(0);
sensorHeight=LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.getSensorHeight(0);
}
if (FOCUSING_FIELD!=null){
sensorWidth=FOCUSING_FIELD.sensorWidth;
......@@ -5918,7 +5919,12 @@ if (MORE_BUTTONS) {
IJ.showMessage("LENS_DISTORTION.fittingStrategy is not set");
return;
}
LENS_DISTORTIONS.listImageSets();
GenericDialog gd=new GenericDialog ("Select list mode");
gd.addNumericField("Mode 0 - old, 1 - shift/Rots", 0, 0);
gd.showDialog();
if (gd.wasCanceled()) return;
int listMode= (int) gd.getNextNumber();
LENS_DISTORTIONS.listImageSets(listMode);
return;
}
/* ======================================================================== */
......@@ -8986,12 +8992,20 @@ if (MORE_BUTTONS) {
for (int nChn=0;nChn<masks.length;nChn++) if ((nChn<selectedChannels.length)&&!selectedChannels[nChn]) masks[nChn]=null;
}
if (showSensorMasks) this.SDFA_INSTANCE.showArrays( //java.lang.ArrayIndexOutOfBoundsException: 313632
masks,
LENS_DISTORTIONS.pixelCorrectionWidth/ LENS_DISTORTIONS.pixelCorrectionDecimation,
LENS_DISTORTIONS.pixelCorrectionHeight/LENS_DISTORTIONS.pixelCorrectionDecimation,
true,
"nonVinetting masks");
if (showSensorMasks) {
boolean same_size = true;
for (int i = 1; i < masks.length; i++) same_size &= (masks[i].length == masks[0].length);
if (same_size) {
this.SDFA_INSTANCE.showArrays( //java.lang.ArrayIndexOutOfBoundsException: 313632
masks,
LENS_DISTORTIONS.getSensorWidth(0)/ LENS_DISTORTIONS.getDecimateMasks(0),
LENS_DISTORTIONS.getSensorHeight(0)/LENS_DISTORTIONS.getDecimateMasks(0),
true,
"nonVinetting masks");
} else {
System.out.println("**** Can't show sesnor masks for different size sesnors as a stack! ");
}
}
double [][][][] sensorGrids=LENS_DISTORTIONS.calculateGridFlatField(
serNumber,
masks,
......@@ -9556,7 +9570,7 @@ if (MORE_BUTTONS) {
true, // boolean read_grids
MASTER_DEBUG_LEVEL);
if (MASTER_DEBUG_LEVEL <100) return true;
/// if (MASTER_DEBUG_LEVEL <100) return true;
// patterns are not yet read here!
/*
......@@ -9639,6 +9653,11 @@ if (MORE_BUTTONS) {
path,
PROCESS_PARAMETERS.useXML,
null); // Properties properties
if (LENS_DISTORTIONS==null) {
System.out.println("Creating new LENS_DISTORTIONS");
LENS_DISTORTIONS=new Distortions(LENS_DISTORTION_PARAMETERS,PATTERN_PARAMETERS,REFINE_PARAMETERS,this.SYNC_COMMAND.stopRequested);
}
// ABERRATIONS_PARAMETERS.selectCalibrationDirectory(true, ABERRATIONS_PARAMETERS.calibrationDirectory, true);
return EYESIS_CAMERA_PARAMETERS.importSystem(
properties,
prefix,
......@@ -23,6 +23,7 @@ package com.elphel.imagej.calibration;
**
*/
import java.awt.Rectangle;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
......@@ -67,6 +68,8 @@ import ij.text.TextWindow;
public static final int INDEX_R = 5;
public static final int INDEX_G = 6;
public static final int INDEX_B = 7;
public static final double SMALL_FRACTION = 0.8; // consider sesnor to be a "small" if average grid period < this fraction of the large
public String pathName=null;
public EyesisCameraParameters eyesisCameraParameters; // has "cartesian"
public int numSubCameras=1;
......@@ -74,6 +77,8 @@ import ij.text.TextWindow;
public int numMotors =3; // maximal number of motors to look for
public GridImageParameters [] gIP= null; // per-grid image parameters
public GridImageSet [] gIS= null; // sets of images with the same timestamp
public boolean [] small_sensors = null; // set by filter grids
public double small_period_frac = 0; // set by filter grids - ratio of small sensor period to large sensor period
// keep for now?
public double [][] pars=null; // for each defined image: set of (22) parameters
public double [][] sensorMasks= null; // per-channel (not image) mask
......@@ -86,7 +91,7 @@ import ij.text.TextWindow;
return (eyesisCameraParameters==null)?0:eyesisCameraParameters.getNumStations();
}
public class GridImageParameters{
public class GridImageParameters{
public int imgNumber=-1; // index of this image (for pars[][])
private int setNumber=-1; // long overdue - will be some inconsistency
GridImageSet gridImageSet=null;
......@@ -114,11 +119,16 @@ import ij.text.TextWindow;
public boolean [] badNodes= null; // if not null, marks node with excessive errors
public double [][] pixelsXY_extra= null; // extra data, for nodes that are out of the physical grid (may be needed after re-calibration)
public int [][] pixelsUV_extra= null;
public double gridPeriod=0.0; // average grid period, in pixels (to filter out (double-) reflected images
private double gridPeriod=0.0; // average grid period, in pixels (to filter out (double-) reflected images
public boolean noUsefulPSFKernels=false; // used to mark images w/o good PSF data
public double diameter=0.0;
public int [] UVShiftRot={0,0,0}; // shift and rotation of the grid
public Rectangle woi;
final int contrastIndex=2;
public double getGridPeriod() { return gridPeriod;}
public void setGfridPeriod(double v) {gridPeriod = v;}
public int getSetNumber(){return this.setNumber;}
public GridImageParameters(int index){
this.imgNumber=index;
......@@ -165,6 +175,12 @@ import ij.text.TextWindow;
for (int i=0;i<this.pixelsXY.length;i++) if (this.pixelsXY[i][contrastIndex]>=minContrast) num++;
return num;
}
public int getChannel() {
return channel;
}
/**
* Calculate "diameter" of the image to be used for image weight
* @param xc image center pixel X
......@@ -773,11 +789,13 @@ import ij.text.TextWindow;
}
spaths = new String[num_chn];
if (sdir != null) {
// consruct source image set directory name
// construct source image set directory name
String set_name = (new File(dir)).getName();
File set_dir = new File(sdir, set_name );
String [] sfiles = set_dir.list(sourceFilter);
if (sfiles == null) {
System.out.println("sfiles == null");
}
for (String spath:sfiles) {
int last_dash = spath.lastIndexOf('-');
int last = spath.lastIndexOf('_');
......@@ -872,11 +890,16 @@ import ij.text.TextWindow;
IJ.showMessage("Error",msg);
throw new IllegalArgumentException (msg);
}
this.gIP[numFile].gridImage = imp_grid; // Save all images?
// TODO: here - need to decode properties
// TODO: here - need to decode properties
jp4_reader.decodeProperiesFromInfo(imp_grid);
this.gIP[numFile].laserPixelCoordinates = MatchSimulatedPattern.getPointersXYUV(imp_grid, laserPointers);
this.gIP[numFile].woi = new Rectangle(
getImagePlusProperty(imp_grid,"WOI_LEFT",0),
getImagePlusProperty(imp_grid,"WOI_TOP",0),
getImagePlusProperty(imp_grid,"WOI_WIDTH", eyesisCameraParameters.getSensorWidth(nc)),
getImagePlusProperty(imp_grid,"WOI_HEIGHT", eyesisCameraParameters.getSensorHeight(nc)));
this.gIP[numFile].gridImage = imp_grid; // Save all images?
this.gIP[numFile].laserPixelCoordinates = MatchSimulatedPattern.getPointersXYUV(imp_grid, laserPointers);
this.gIP[numFile].motors = getMotorPositions(imp_grid, this.numMotors);
this.gIS[nis].motors= this.gIP[numFile].motors.clone();
this.gIP[numFile].matchedPointers = getUsedPonters(imp_grid);
......@@ -934,7 +957,7 @@ import ij.text.TextWindow;
if (this.debugLevel>-1) {
if (this.gIP[numFile].pixelsUV != null) {
System.out.print(" ["+ this.gIP[numFile].pixelsUV.length+"]");
System.out.print(" ["+ this.gIP[numFile].pixelsUV.length+"+"+this.gIP[numFile].pixelsUV_extra.length+"]");
} else {
System.out.print(" [null]");
}
......@@ -945,12 +968,8 @@ import ij.text.TextWindow;
" enabled="+this.gIP[numFile].enabled+" hintedMatch="+this.gIP[numFile].hintedMatch);
}
calcGridPeriod(numFile); // will be used to filter out reflections
calcGridPeriod(numFile, true); // may be not absolutely calibrated, use_extra out-of-pattern nodes will be used to filter out reflections
//System.out.println ("pixelsXY["+fileNumber+"]length="+pixelsXY[fileNumber].length);
} //if (read_grids)
// not reading the grid itself
first_in_set = false;
......@@ -959,40 +978,115 @@ import ij.text.TextWindow;
}
}
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 extra_search = 2;
// int base_channel = this.gIP[with_pointers].channel;
if (this.gIS[nis].imageSet[main_channel] != null) {
int imgNum = this.gIS[nis].imageSet[main_channel].imgNumber;
boolean invert_color = (main_channel & 4) == 0; // first 4 - LWIR
if (this.updateStatus) IJ.showStatus("Matching with the pattern, grid file "+(imgNum+1)+" (of "+(numFiles)+"): "+this.gIP[imgNum].path);
if (this.debugLevel>-1) System.out.print(imgNum+">("+this.gIP[imgNum].getStationNumber()+
":"+this.gIP[imgNum].setNumber+":"+this.gIP[imgNum].channel+"): "+this.gIP[imgNum].path);
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 = correlateWithPattern(
patternParameters,
set_widths[main_channel], // int test_width,
set_pixels[main_channel], // float [][] test_pixels,
invert_color,
extra_search,
5.0, // double sigma,
sensor_wh, // test set pixels width/height pair to reduce weight near the margins (or null)
false // true // boolean bdebug
);
System.out.print(" {"+uv_shift_rot[0]+":"+uv_shift_rot[1]+"]");
this.gIS[nis].imageSet[main_channel].setUVShiftRot(uv_shift_rot);
int [][] shiftRotMatrix= MatchSimulatedPattern.getRemapMatrix(this.gIS[nis].imageSet[main_channel].getUVShiftRot());
setGridsWithRemap( // null immediately
imgNum,
shiftRotMatrix, // int [][] reMap,
set_pixels[main_channel],
patternParameters);
calcGridPeriod(imgNum, false); // centered, can skip _extra
if (this.gIP[imgNum].pixelsUV != null) {
System.out.println(" ["+ this.gIP[imgNum].pixelsUV.length+"+"+this.gIP[imgNum].pixelsUV_extra.length+"]");
} else {
System.out.println(" [null]");
}
with_pointers = imgNum; // no adjust all other channels by this one
}
}
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
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]) {
boolean invert_color = ((base_channel ^ nc) & 4) != 0;
if (this.gIS[nis].imageSet[nc].matchedPointers <= 0) {
int [] uv_shift_rot = correlateGrids(
if ((this.gIS[nis].imageSet[nc].matchedPointers <= 0) && (nc != base_channel)) { // Later add non-laser conditions
int imgNum = this.gIS[nis].imageSet[nc].imgNumber; // with_pointers - base_channel + nc;
if (this.updateStatus) IJ.showStatus("Re-reading grid file "+(imgNum+1)+" (of "+(numFiles)+"): "+this.gIP[imgNum].path);
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);
this.gIS[nis].imageSet[nc].setUVShiftRot(uv_shift_rot);
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(
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,
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]+"->");
int [] combinedUVShiftRot=MatchSimulatedPattern.combineUVShiftRot(
this.gIS[nis].imageSet[base_channel].getUVShiftRot(),
uv_shift_rot);
this.gIS[nis].imageSet[nc].setUVShiftRot(combinedUVShiftRot); // uv_shift_rot);
System.out.print(combinedUVShiftRot[0]+":"+combinedUVShiftRot[1]+"}");
int [][] shiftRotMatrix= MatchSimulatedPattern.getRemapMatrix(this.gIS[nis].imageSet[nc].getUVShiftRot());
// int [] sizeSizeExtra=
int imgNum = with_pointers - base_channel + nc;
setGridsWithRemap( // null immediately
imgNum,
shiftRotMatrix, // int [][] reMap,
set_pixels[nc],
patternParameters);
calcGridPeriod(imgNum, false); // centered, can skip _extra
if (this.gIP[imgNum].pixelsUV != null) {
System.out.println(" ["+ this.gIP[imgNum].pixelsUV.length+"+"+this.gIP[imgNum].pixelsUV_extra.length+"]");
} else {
System.out.println(" [null]");
}
}
}
// for (this.gIS[nis]
} else {
}
//
} // for (int nis = 0; nis<this.gIS.length; nis++)
......@@ -1030,7 +1124,40 @@ import ij.text.TextWindow;
}
public static int getImagePlusProperty(ImagePlus imp, String name, int dflt) {
try {
dflt = Integer.parseInt((String) (imp.getProperty(name)));
} catch (Exception e) {
}
return dflt;
}
public static double getImagePlusProperty(ImagePlus imp, String name, double dflt) {
try {
dflt = Double.parseDouble((String) (imp.getProperty(name)));
} catch (Exception e) {
}
return dflt;
}
public static boolean getImagePlusProperty(ImagePlus imp, String name, boolean dflt) {
try {
dflt = Boolean.parseBoolean((String) (imp.getProperty(name)));
} catch (Exception e) {
}
return dflt;
}
public static String getImagePlusProperty(ImagePlus imp, String name, String dflt) {
Object obj = imp.getProperty(name);
if (obj != null) {
dflt = (String) obj;
}
return dflt;
}
public DistortionCalibrationData (
......@@ -1081,6 +1208,7 @@ import ij.text.TextWindow;
}
if (xcam && (numSubCameras == 4)) {
// if (xcam) {
listCameraParametersXcam();
} else {
listCameraParameters();
......@@ -1357,10 +1485,11 @@ import ij.text.TextWindow;
}
public void listImageSet(){
listImageSet(null,null, null);
listImageSet(0, null,null, null);
}
public void listImageSet(
int mode,
int [] numPoints,
double [] setRMS,
boolean [] hasNaNInSet){
......@@ -1446,21 +1575,44 @@ import ij.text.TextWindow;
sb.append("\t"+(((hasNaNInSet!=null) && hasNaNInSet[i])?"*":"")+IJ.d2s(setRMS[i],3));
sb.append("\t"+IJ.d2s(this.gIS[i].setWeight,3));
}
for (int n=0;n<this.gIS[i].imageSet.length;n++){
sb.append("\t");
if (this.gIS[i].imageSet[n]!=null){
int numPointers=0; // count number of laser pointers
if (this.gIS[i].imageSet[n].laserPixelCoordinates!=null){
for (int j=0;j<this.gIS[i].imageSet[n].laserPixelCoordinates.length;j++) {
if (this.gIS[i].imageSet[n].laserPixelCoordinates[j]!=null) numPointers++;
switch (mode) {
case 0:
for (int n=0;n<this.gIS[i].imageSet.length;n++){
sb.append("\t");
if (this.gIS[i].imageSet[n]!=null){
int numPointers=0; // count number of laser pointers
if (this.gIS[i].imageSet[n].laserPixelCoordinates!=null){
for (int j=0;j<this.gIS[i].imageSet[n].laserPixelCoordinates.length;j++) {
if (this.gIS[i].imageSet[n].laserPixelCoordinates[j]!=null) numPointers++;
}
}
if (!this.gIS[i].imageSet[n].enabled) sb.append("(");
sb.append(numPointers+"("+this.gIS[i].imageSet[n].matchedPointers+"):"+this.gIS[i].imageSet[n].hintedMatch +
" "+IJ.d2s(this.gIS[i].imageSet[n].getGridPeriod(),1));
if (!this.gIS[i].imageSet[n].enabled) sb.append(")");
}
if (!this.gIS[i].imageSet[n].enabled) sb.append("(");
sb.append(numPointers+"("+this.gIS[i].imageSet[n].matchedPointers+"):"+this.gIS[i].imageSet[n].hintedMatch +
" "+IJ.d2s(this.gIS[i].imageSet[n].gridPeriod,1));
if (!this.gIS[i].imageSet[n].enabled) sb.append(")");
}
break;
case 1:
for (int n=0;n<this.gIS[i].imageSet.length;n++){
sb.append("\t");
if (this.gIS[i].imageSet[n]!=null){
int [] uvrot = this.gIS[i].imageSet[n].getUVShiftRot();
sb.append(uvrot[0]+":"+uvrot[1]+"("+uvrot[2]+")");
}
}
break;
case 2:
for (int n=0;n<this.gIS[i].imageSet.length;n++){
sb.append("\t");
if (this.gIS[i].imageSet[n]!=null){
sb.append(this.gIS[i].imageSet[n].pixelsXY.length+"+"+this.gIS[i].imageSet[n].pixelsXY_extra.length);
}
}
break;
}
sb.append("\n");
}
......@@ -1488,7 +1640,7 @@ import ij.text.TextWindow;
* Filter images (grids) by calibration status with laser pointers and "hinted" from the camera orientation
* buildImageSets may be needed to be re-ran (if it was ran with all=false)
* @param resetHinted - if true - reset status of "hinted" calibration to undefined
* @param minPointers minimal number of laser pointers considered to be enough (usually 2, as mirror/non-mirror is apriori known
* @param minPointers minimal number of laser pointers considered to be enough (usually 2, as mirror/non-mirror is aPriori known
* @parame minGridPeriod - minimal detected grid period as a fraction of the maximal (filtering reflected grids)
* @return number of enabled images
*/
......@@ -1508,12 +1660,51 @@ import ij.text.TextWindow;
double [] medianGridPeriod=new double [this.eyesisCameraParameters.numStations];
double [] maxGridPeriod=new double [this.eyesisCameraParameters.numStations];
double [] minGridPeriod=new double [this.eyesisCameraParameters.numStations];
// With different sensors different channels wil have different periods
int numChannels = getNumSubCameras(); // this.eyesisCameraParameters.getNumChannels();
double [][] sw = new double [numChannels][2];
for (int i=0;i<this.gIP.length;i++) if (getNumNodes(i, false) >0) {
double period = this.gIP[i].getGridPeriod();
if (!Double.isNaN(period) && !Double.isInfinite(period) ) {
int chn = this.gIP[i].getChannel();
sw[chn][0] += getNumNodes(i, false); // weight
sw[chn][1] += getNumNodes(i, false) * period; // weight
}
}
double [] avg_periods = new double [numChannels];
double [] ravg_periods = new double [numChannels];
this.small_sensors = new boolean [numChannels];
double max_per = 0;
for (int i = 0; i < numChannels; i++) {
avg_periods[i] =sw[i][1] / sw[i][0];
if (max_per < avg_periods[i]) max_per = avg_periods[i];
}
double [][] sw1 = new double [2][2];
for (int i = 0; i < numChannels; i++) {
ravg_periods[i] = avg_periods[i] / max_per;
small_sensors[i] = ravg_periods[i] < SMALL_FRACTION;
sw1[small_sensors[i]?1:0][0] += sw[i][0];
sw1[small_sensors[i]?1:0][1] += sw[i][0] * ravg_periods[i];
}
this.small_period_frac = (sw1[1][0] == 0) ? 0.0 : (sw1[1][1] * sw1[0][0] / (sw1[1][0] * sw1[0][1]));
if (small_period_frac > 0.0) {
System.out.println(String.format("2 types of sensors are detected, lowres has %5.2f%% resolution",100*small_period_frac));
System.out.print("Sensor map: ");
for (int i = 0; i < numChannels; i++) {
System.out.print(i+":"+(small_sensors[i]?"low-res":"high-res")+", ");
}
System.out.println();
}
for (int stationNumber=0;stationNumber<this.eyesisCameraParameters.numStations;stationNumber++){
for (int i=0;i<numBins;i++) periodHistogram[i]=0.0;
int numSamples=0;
for (int i=0;i<this.gIP.length;i++) if (this.gIP[i].getStationNumber()==stationNumber){
if (!Double.isNaN(this.gIP[i].gridPeriod)) {
int iPeriod=(int) Math.round(this.gIP[i].gridPeriod*periodSubdivide);
double period = getEffectivePeriod(i);
// if (!Double.isNaN(this.gIP[i].getGridPeriod())) {
if (!Double.isNaN(period)) {
// int iPeriod=(int) Math.round(this.gIP[i].getGridPeriod()*periodSubdivide);
int iPeriod=(int) Math.round(period*periodSubdivide);
if (iPeriod>=numBins) iPeriod=numBins-1;
else if (iPeriod<0) iPeriod=0; // does not count NaN
if (iPeriod>0) {
......@@ -1534,7 +1725,12 @@ import ij.text.TextWindow;
maxGridPeriod[stationNumber]=0.0;
for (int i=0;i<this.gIP.length;i++) if (this.gIP[i].getStationNumber()==stationNumber){
if (this.gIP[i].gridPeriod>maxGridPeriod[stationNumber]) maxGridPeriod[stationNumber]=this.gIP[i].gridPeriod;
// if (this.gIP[i].getGridPeriod()>maxGridPeriod[stationNumber]) {
// maxGridPeriod[stationNumber]=this.gIP[i].getGridPeriod();
// }
if (getEffectivePeriod(i) > maxGridPeriod[stationNumber]) {
maxGridPeriod[stationNumber]=getEffectivePeriod(i);
}
}
minGridPeriod[stationNumber]=medianGridPeriod[stationNumber]*minGridPeriodFraction;
System.out.print("Station "+stationNumber+ ": maximal grid period="+maxGridPeriod[stationNumber]+" minimal grid period="+minGridPeriod[stationNumber]+" median grid period="+medianGridPeriod[stationNumber]+" numSamples="+numSamples);
......@@ -1556,13 +1752,17 @@ import ij.text.TextWindow;
boolean enableNoLaser=this.eyesisCameraParameters.getEnableNoLaser(stationNumber,this.gIP[i].channel);
boolean wasEnabled=this.gIP[i].enabled;
if (resetHinted) this.gIP[i].hintedMatch=-1; // undefined
if (Double.isNaN(this.gIP[i].gridPeriod) ||
((minGridPeriodFraction>0) && ((this.gIP[i].gridPeriod<minGridPeriod[stationNumber]) || (this.gIP[i].gridPeriod>maxGridPeriod[stationNumber])))){
/// if (Double.isNaN(this.gIP[i].getGridPeriod()) ||
/// ((minGridPeriodFraction>0) && ((this.gIP[i].getGridPeriod()<minGridPeriod[stationNumber]) || (this.gIP[i].getGridPeriod()>maxGridPeriod[stationNumber])))){
if (Double.isNaN(getEffectivePeriod(i)) ||
((minGridPeriodFraction>0) && ((getEffectivePeriod(i)<minGridPeriod[stationNumber]) ||
(getEffectivePeriod(i) > maxGridPeriod[stationNumber])))){
this.gIP[i].hintedMatch=0; // is it needed?
this.gIP[i].enabled=false; // failed against minimal grid period (too far) - probably double reflection in the windows
}
if (this.gIP[i].hintedMatch==0) this.gIP[i].enabled=false; // failed against predicted grid
else {
if (this.gIP[i].hintedMatch==0) {
this.gIP[i].enabled=false; // failed against predicted grid
} else {
if (
(this.gIP[i].matchedPointers>=minPointers) ||
((this.gIP[i].matchedPointers>0) && (this.gIP[i].hintedMatch>0)) || // orientation and one pointer
......@@ -1573,7 +1773,9 @@ import ij.text.TextWindow;
if (!Double.isNaN(this.gIS[gIS_index[i]].goniometerAxial)) setGA(i,this.gIS[gIS_index[i]].goniometerAxial );
}
this.gIP[i].enabled=true;
} else this.gIP[i].enabled=false;
} else {
this.gIP[i].enabled=false;
}
if ((this.gIP[i].hintedMatch>1) && !enableNoLaser && (this.gIP[i].matchedPointers==0)){
disabledNoLaser++;
}
......@@ -1591,7 +1793,9 @@ import ij.text.TextWindow;
break;
}
}
if (hasMotors) this.gIP[i].enabled=false; // got some no-motor images made without scanning
if (hasMotors) {
this.gIP[i].enabled=false; // got some no-motor images made without scanning
}
}
/* Disable no-pointer, new, number of points less than required */
......@@ -2556,18 +2760,35 @@ import ij.text.TextWindow;
}
// public double gridPeriod=0.0; // average grid period, in pixels (to filter out (double-) reflected images
public double calcGridPeriod(int fileNumber){
if ((this.gIP[fileNumber].pixelsXY==null) || (this.gIP[fileNumber].pixelsXY.length<3)) {
public double calcGridPeriod(
int fileNumber,
boolean use_extra){ // use out-of grid nodes (can be w/o absolute matching
use_extra &= (this.gIP[fileNumber].pixelsXY_extra !=null);
int len = (this.gIP[fileNumber].pixelsXY==null)? 0 : this.gIP[fileNumber].pixelsXY.length;
int len0 = len;
if (use_extra ) {
len += this.gIP[fileNumber].pixelsXY_extra.length;
}
if (len<3) {
this.gIP[fileNumber].gridPeriod=Double.NaN;
} else {
double [][][] data =new double [this.gIP[fileNumber].pixelsXY.length][2][2];
// double [][][] data =new double [this.gIP[fileNumber].pixelsXY.length][2][2];
double [][][] data =new double [len][2][2];
// U(x,y), v(x,y)
for (int i=0;i<data.length;i++){
for (int i=0; i < this.gIP[fileNumber].pixelsXY.length; i++){
data[i][0][0]=this.gIP[fileNumber].pixelsXY[i][0];
data[i][0][1]=this.gIP[fileNumber].pixelsXY[i][1];
data[i][1][0]=this.gIP[fileNumber].pixelsUV[i][0];
data[i][1][1]=this.gIP[fileNumber].pixelsUV[i][1];
}
if (use_extra) {
for (int i=0; i < this.gIP[fileNumber].pixelsXY_extra.length; i++){
data[i + len0][0][0]=this.gIP[fileNumber].pixelsXY_extra[i][0];
data[i + len0][0][1]=this.gIP[fileNumber].pixelsXY_extra[i][1];
data[i + len0][1][0]=this.gIP[fileNumber].pixelsUV_extra[i][0];
data[i + len0][1][1]=this.gIP[fileNumber].pixelsUV_extra[i][1];
}
}
if (this.debugLevel>3) {
System.out.println("calcGridPeriod("+fileNumber+"), debugLevel="+this.debugLevel+":");
for (int i=0;i<data.length;i++)System.out.println(i+": {{"+data[i][0][0]+","+data[i][0][1]+"},{"+data[i][1][0]+","+data[i][1][1]+"}}");
......@@ -2583,9 +2804,9 @@ import ij.text.TextWindow;
}
}
if (this.debugLevel>3) {
System.out.println("calcGridPeriod("+fileNumber+") => "+this.gIP[fileNumber].gridPeriod);
System.out.println("calcGridPeriod("+fileNumber+") => "+this.gIP[fileNumber].getGridPeriod());
}
return this.gIP[fileNumber].gridPeriod;
return this.gIP[fileNumber].getGridPeriod();
}
......@@ -2747,7 +2968,7 @@ import ij.text.TextWindow;
numOfGridNodes+=sizeSizeExtra[0];
numOfGridNodes_extra+=sizeSizeExtra[1];
calcGridPeriod(fileNumber); // will be used to filter out reflections
calcGridPeriod(fileNumber,true); // use _extra (out-of-pattern nodes) will be used to filter out reflections
//System.out.println ("pixelsXY["+fileNumber+"]length="+pixelsXY[fileNumber].length);
}
if (this.debugLevel>3) {
......@@ -3095,6 +3316,129 @@ import ij.text.TextWindow;
}
// get "effective" grid period scaled for low-res (as LWIR) sensors
public double getEffectivePeriod(int numImg) {
double period = this.gIP[numImg].getGridPeriod();
int chn = this.gIP[numImg].getChannel();
if ((this.small_sensors != null) && this.small_sensors[chn]) period /= small_period_frac;
return period;
}
public boolean hasSmallSensors() {
return small_period_frac > 0.0;
}
public boolean [] getSmallSensors() {
return small_sensors;
}
public boolean isSmallSensor(int numImg) {
if ((this.gIP != null) && (numImg < this.gIP.length) && (small_sensors == null)){
return small_sensors[this.gIP[numImg].getChannel()];
}
return false;
}
public double getSmallPeriodFrac() {
return small_period_frac;
}
// public boolean [] small_sensors = null; // set by filter grids
// 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
//getNumSubCameras()
public int getNumLwir() {
if (hasSmallSensors()) {
int n = 0;
for (int i = 0; i < small_sensors.length; i++) if (small_sensors[i]) n++;
return n;
} else {
return 0;
}
}
public int getNumVnir() {
return getNumSubCameras() - getNumLwir();
}
public int getVnir0() {
if (hasSmallSensors()) {
for (int i = 0; i < small_sensors.length; i++) if (!small_sensors[i]) return i;
return -1; // should not happen
}
return 0;
}
public int getLwir0() {
if (hasSmallSensors()) {
for (int i = 0; i < small_sensors.length; i++) if (small_sensors[i]) return i;
return -1; // should not happen
}
return -1;
}
// Get number of different subcameras for adjustments (to share adjustment types)
public int getSubGroups() {
int num_sub = getNumSubCameras();
if (num_sub == 1) return 1; // single
if (num_sub == 26) return 3; // eyesis4pi-26
int n = 2;
if (hasSmallSensors()) {
if (getNumLwir() > 1) n++;
if (getNumVnir() > 1) n++;
}
return n;
}
// Get subcamera adjustment group
// May be modified to use other subcamera as zero (eyesis in the middle row)
public int getSubGroup(int chn) {
int groups = getSubGroups();
if (groups == 1) return 0; // single camera
int num_sub = getNumSubCameras();
if (num_sub == 26) { // eyesis4pi-26
if (chn == 0) return 0;
if (chn < 24) return 1;
return 2;
}
int n = 0;
if (hasSmallSensors()) {
if (small_sensors[chn]) { // current is LWIR
n = 1;
if (getNumVnir() > 1) n = 2;
if (chn != getLwir0()) n++;
} else { // current is VNIR
n = 0;
if (chn != getVnir0()) n++;
}
}
return n;
}
public String getSubName(int chn) {
int groups = getSubGroups();
if (groups == 1) return "sub"; // single camera
int num_sub = getNumSubCameras();
if (num_sub == 26) { // eyesis4pi-26
if (chn == 0) return "sub-head-0";
if (chn < 24) return "sub-head-other";
return "sub-bottom";
}
if (hasSmallSensors()) {
if (small_sensors[chn]) { // current is LWIR
if (chn != getLwir0()) return "sub-lwir-other";
if (getNumLwir() > 1) return "sub-lwir0";
return "sub-lwir";
} else { // current is VNIR
if (chn != getVnir0()) return "sub-vnir-other";
if (getNumVnir() > 1) return "sub-vnir0";
return "sub-vnir";
}
}
if (chn != getVnir0()) return "sub-other";
return "sub0";
}
public int getImageNumPoints(int numImg){
return this.gIP[numImg].pixelsUV.length;
}
......@@ -3362,6 +3706,13 @@ import ij.text.TextWindow;
public int getNumSubCameras() {
return this.numSubCameras;
}
public int getNumNodes(int num, boolean use_extra) {
if ((this.gIP == null) || (num >= this.gIP.length) || (this.gIP[num].pixelsXY == null)) return 0;
int len = this.gIP[num].pixelsXY.length;
if (use_extra && (this.gIP[num].pixelsXY_extra != null)) len += this.gIP[num].pixelsXY_extra.length;
return len;
}
/**
*
* @param imgNumber number of grid image to edit parameters (location, distortion) for
......@@ -3394,7 +3745,8 @@ import ij.text.TextWindow;
if (!gd.wasOKed()) return -1; // pressed Done (no need to ask for the next number)
return imgNumber;
}
public void setMaskFromImageStack(String path){
@Deprecated
public void setMaskFromImageStack(String path){ // can not work with different size senors
Opener opener=new Opener();
if (this.debugLevel>1) System.out.println("Opening "+path+" as a stack of sensor masks");
ImagePlus imp=opener.openImage("", path);
......@@ -3409,11 +3761,11 @@ import ij.text.TextWindow;
if (imp.getProperty("maskBlurSigma")!=null)
eyesisCameraParameters.maskBlurSigma=Double.parseDouble((String) imp.getProperty("maskBlurSigma"));
if (imp.getProperty("decimateMasks")!=null)
eyesisCameraParameters.decimateMasks=Integer.parseInt((String) imp.getProperty("decimateMasks"));
eyesisCameraParameters.setDecimateMasks(Integer.parseInt((String) imp.getProperty("decimateMasks")));
if (imp.getProperty("sensorWidth")!=null)
eyesisCameraParameters.sensorWidth=Integer.parseInt((String) imp.getProperty("sensorWidth"));
eyesisCameraParameters.setSensorWidth(Integer.parseInt((String) imp.getProperty("sensorWidth")));
if (imp.getProperty("sensorHeight")!=null)
eyesisCameraParameters.sensorHeight=Integer.parseInt((String) imp.getProperty("sensorHeight"));
eyesisCameraParameters.setSensorHeight(Integer.parseInt((String) imp.getProperty("sensorHeight")));
setMaskFromImageStack(imp);
}
/**
......@@ -3427,39 +3779,38 @@ import ij.text.TextWindow;
}
public double getMask(int chnNum, double px, double py){
int width= eyesisCameraParameters.sensorWidth/eyesisCameraParameters.decimateMasks;
int height=eyesisCameraParameters.sensorHeight/eyesisCameraParameters.decimateMasks;
int iPX= ((int) Math.round(px))/eyesisCameraParameters.decimateMasks;
int iPY= ((int) Math.round(py))/eyesisCameraParameters.decimateMasks;
int width= eyesisCameraParameters.getSensorWidth(chnNum)/eyesisCameraParameters.getDecimateMasks(chnNum);
int height=eyesisCameraParameters.getSensorHeight(chnNum)/eyesisCameraParameters.getDecimateMasks(chnNum);
int iPX= ((int) Math.round(px))/eyesisCameraParameters.getDecimateMasks(chnNum);
int iPY= ((int) Math.round(py))/eyesisCameraParameters.getDecimateMasks(chnNum);
if ((iPX<0) || (iPY<0) || (iPX>=width) || (iPY>=height)) return 0.0;
if ((this.sensorMasks==null) || (this.sensorMasks[chnNum]==null)) return 1.0;
return this.sensorMasks[chnNum][iPY*width+iPX];
}
public double getMask(double[] mask, double px, double py){
@Deprecated
public double getMask(double[] mask, double px, double py){ // problems with different size sensors
if (mask==null) return 0;
int width= eyesisCameraParameters.sensorWidth/eyesisCameraParameters.decimateMasks;
int height=eyesisCameraParameters.sensorHeight/eyesisCameraParameters.decimateMasks;
int iPX= ((int) Math.round(px))/eyesisCameraParameters.decimateMasks;
int iPY= ((int) Math.round(py))/eyesisCameraParameters.decimateMasks;
int width= eyesisCameraParameters.getSensorWidth()/eyesisCameraParameters.getDecimateMasks();
int height=eyesisCameraParameters.getSensorHeight()/eyesisCameraParameters.getDecimateMasks();
int iPX= ((int) Math.round(px))/eyesisCameraParameters.getDecimateMasks();
int iPY= ((int) Math.round(py))/eyesisCameraParameters.getDecimateMasks();
if ((iPX<0) || (iPY<0) || (iPX>=width) || (iPY>=height)) return 0.0;
return mask[iPY*width+iPX]; // null ponter
}
@Deprecated
public void setMaskFromImageStack(ImagePlus imp){
if (imp == null){
String msg="sensors mask image is null";
IJ.showMessage("Error",msg);
throw new IllegalArgumentException (msg);
}
if (imp.getProperty("decimateMasks")!=null)
eyesisCameraParameters.decimateMasks=Integer.parseInt((String) imp.getProperty("decimateMasks"));
eyesisCameraParameters.sensorWidth= imp.getWidth()*eyesisCameraParameters.decimateMasks;
eyesisCameraParameters.sensorHeight=imp.getHeight()*eyesisCameraParameters.decimateMasks;
if (imp.getProperty("sensorWidth")!=null)
eyesisCameraParameters.sensorWidth=Integer.parseInt((String) imp.getProperty("sensorWidth"));
if (imp.getProperty("sensorHeight")!=null)
eyesisCameraParameters.sensorHeight=Integer.parseInt((String) imp.getProperty("sensorHeight"));
if (imp.getProperty("decimateMasks")!=null) eyesisCameraParameters.setDecimateMasks(Integer.parseInt((String) imp.getProperty("decimateMasks")));
eyesisCameraParameters.setSensorWidth(imp.getWidth()*eyesisCameraParameters.getDecimateMasks());
eyesisCameraParameters.setSensorHeight(imp.getHeight()*eyesisCameraParameters.getDecimateMasks());
if (imp.getProperty("sensorWidth")!=null) eyesisCameraParameters.setSensorWidth(Integer.parseInt((String) imp.getProperty("sensorWidth")));
if (imp.getProperty("sensorHeight")!=null) eyesisCameraParameters.setSensorHeight(Integer.parseInt((String) imp.getProperty("sensorHeight")));
if (this.sensorMasks==null) {
this.sensorMasks=new double[getNumChannels()][];
......@@ -3479,7 +3830,7 @@ import ij.text.TextWindow;
for (int i=0;i<numChannels;i++) pixels[i]= (float[]) stack.getPixels(i+1);
}
for (int numChn=0;(numChn<numChannels) && (numChn<this.sensorMasks.length);numChn++){
//Make shure masks contain non-zero (>0.0) pixels, otherwise skip those
//Make sure masks contain non-zero (>0.0) pixels, otherwise skip those
boolean defined=false;
for (int i=0;i<pixels[numChn].length;i++) if (pixels[numChn][i]>0.0){
defined=true;
......@@ -3491,7 +3842,6 @@ import ij.text.TextWindow;
}
}
}
public ImagePlus saveMaskAsImageStack(String title, String path){
ImagePlus imp=getMaskAsImageStack(title);
if (imp==null) return null;
......@@ -3505,14 +3855,15 @@ import ij.text.TextWindow;
return imp;
}
@Deprecated
public ImagePlus getMaskAsImageStack(String title){
if (this.sensorMasks==null){
String msg="Sensor mask array does not exist, nothing to convert";
IJ.showMessage("Error",msg);
throw new IllegalArgumentException (msg);
}
int width= eyesisCameraParameters.sensorWidth/eyesisCameraParameters.decimateMasks;
int height=eyesisCameraParameters.sensorHeight/eyesisCameraParameters.decimateMasks;
int width= eyesisCameraParameters.getSensorWidth()/eyesisCameraParameters.getDecimateMasks();
int height=eyesisCameraParameters.getSensorHeight()/eyesisCameraParameters.getDecimateMasks();
float [][]pixels=new float [getNumChannels()][width*height];
ImagePlus imp=null;
for (int numChn=0;numChn<getNumChannels();numChn++){
......@@ -3529,11 +3880,11 @@ import ij.text.TextWindow;
imp=new ImagePlus(title, ip);
}
// TODO: add more properties here (MAC+channel)? preserve other properties?
imp.setProperty("sensorWidth", ""+eyesisCameraParameters.sensorWidth);
imp.setProperty("sensorHeight", ""+eyesisCameraParameters.sensorHeight);
imp.setProperty("sensorWidth", ""+eyesisCameraParameters.getSensorWidth());
imp.setProperty("sensorHeight", ""+eyesisCameraParameters.getSensorHeight());
imp.setProperty("shrinkGridForMask", ""+eyesisCameraParameters.shrinkGridForMask);
imp.setProperty("maskBlurSigma", ""+eyesisCameraParameters.maskBlurSigma);
imp.setProperty("decimateMasks", ""+eyesisCameraParameters.decimateMasks);
imp.setProperty("decimateMasks", ""+eyesisCameraParameters.getDecimateMasks());
(new JP46_Reader_camera(false)).encodeProperiesToInfo(imp);
imp.getProcessor().resetMinAndMax();
......@@ -3582,23 +3933,31 @@ import ij.text.TextWindow;
if (minimalAlpha>0.0) for (int i=0;i<mask.length;i++) if (mask[i]<minimalAlpha) mask[i]=0.0;
return mask;
}
@Deprecated
public double [][] calculateSensorMasksOld() {
return calculateSensorMasks(
eyesisCameraParameters.getDecimateMasks(),
eyesisCameraParameters.getSensorWidth(),
eyesisCameraParameters.getSensorHeight(),
eyesisCameraParameters.shrinkGridForMask,
eyesisCameraParameters.maskBlurSigma);
}
public double [][] calculateSensorMasks() {
return calculateSensorMasks(
eyesisCameraParameters.decimateMasks,
eyesisCameraParameters.sensorWidth,
eyesisCameraParameters.sensorHeight,
eyesisCameraParameters.shrinkGridForMask,
eyesisCameraParameters.maskBlurSigma);
}
/**
*
* @param width image width, in pixels (pixel X coordinates are between 0 and width-1, inclusive)
* @param height image height, in pixels (pixel Y coordinates are between 0 and height-1, inclusive)
* @param shrinkGridForMask shrink detected grids by this number of nodes in each direction before bluring
* @param sigmaUV Gaussian sigma fro bluring of the sensor mask (if negative - in grid inter-node distances)
* @param sigmaUV Gaussian sigma for blurring of the sensor mask (if negative - in grid inter-node distances)
* @return array of pixel arrays (or nulls) for each camera subchannel (also keeps it in the class instance)
*/
@Deprecated
public double [][] calculateSensorMasks( int decimate, int width, int height, int shrinkGridForMask, double sigmaUV) {
int dWidth= (width -1)/decimate+1;
int dHeight= (height-1)/decimate+1;
......@@ -3633,6 +3992,42 @@ import ij.text.TextWindow;
return this.sensorMasks;
}
public double [][] calculateSensorMasks(int shrinkGridForMask, double sigmaUV) {
int numChannels=getNumChannels();
this.sensorMasks=new double [numChannels][];
DoubleGaussianBlur gb=new DoubleGaussianBlur();
if ((this.debugLevel>1) && (SDFA_INSTANCE==null)) SDFA_INSTANCE=new ShowDoubleFloatArrays();
if (this.debugLevel>2)System.out.println("calculateSensorMasks("+shrinkGridForMask+","+sigmaUV+")");
for (int chNum=0;chNum<numChannels; chNum++){
int decimate = eyesisCameraParameters.getDecimateMasks(chNum);
int width = eyesisCameraParameters.getSensorWidth(chNum);
int height = eyesisCameraParameters.getSensorHeight(chNum);
int dWidth= (width -1)/decimate+1;
int dHeight= (height-1)/decimate+1;
this.sensorMasks[chNum]=new double[dWidth*dHeight];
for (int i=0;i<this.sensorMasks[chNum].length;i++) this.sensorMasks[chNum][i]=0.0;
double rAverage=0.0;
double rAverageNum=0.0;
for (int imgNum=0;imgNum<this.gIP.length;imgNum++) if (this.gIP[imgNum].channel==chNum){ // image is for this this channel
double [][] preMask=preCalculateSingleImageMask(imgNum, decimate, width, height, shrinkGridForMask);
if (preMask==null) continue; //nothing in this channel
rAverage+=preMask[0][0];
rAverageNum+=preMask[0][1];
for (int i=0;i<this.sensorMasks[chNum].length;i++) if (preMask[1][i]>0.0) this.sensorMasks[chNum][i]=1.0;
}
if (rAverageNum==0.0) continue; // nothing to blur/process for this channel
rAverage/=rAverageNum; // average distance to the fartherst node from the current
double sigma=sigmaUV;
if(sigma<0) sigma*=-rAverage;
gb.blurDouble(this.sensorMasks[chNum], dWidth, dHeight, sigma/decimate, sigma/decimate, 0.01);
}
return this.sensorMasks;
}
/**
* Create round mask inside the actual one, with the provided center. Blur result with the same sigma as original
......@@ -3642,14 +4037,12 @@ import ij.text.TextWindow;
* @return this channel mask, also sets the round mask instead of the original
*/
public double [] roundOffMask(int chn, double xCenter, double yCenter){
int dWidth= (eyesisCameraParameters.sensorWidth -1)/eyesisCameraParameters.decimateMasks+1;
int dHeight= (eyesisCameraParameters.sensorHeight-1)/eyesisCameraParameters.decimateMasks+1;
int dWidth= (eyesisCameraParameters.getSensorWidth(chn) -1)/eyesisCameraParameters.getDecimateMasks(chn)+1;
int dHeight= (eyesisCameraParameters.getSensorHeight(chn)-1)/eyesisCameraParameters.getDecimateMasks(chn)+1;
DoubleGaussianBlur gb=new DoubleGaussianBlur();
int iXC=(int) Math.round(xCenter/eyesisCameraParameters.decimateMasks);
int iYC=(int) Math.round(yCenter/eyesisCameraParameters.decimateMasks);
// int dcW=eyesisCameraParameters.sensorWidth/eyesisCameraParameters.decimateMasks;
// int dcH=eyesisCameraParameters.sensorHeight/eyesisCameraParameters.decimateMasks;
int iXC=(int) Math.round(xCenter/eyesisCameraParameters.getDecimateMasks(chn));
int iYC=(int) Math.round(yCenter/eyesisCameraParameters.getDecimateMasks(chn));
double r0=iXC;
r0 = Math.min(r0, iYC);
r0 = Math.min(r0, dWidth - iXC);
......@@ -3673,9 +4066,9 @@ import ij.text.TextWindow;
}
// blur result
double [][] preMask=preCalculateSingleImageMask(chn,
eyesisCameraParameters.decimateMasks,
eyesisCameraParameters.sensorWidth,
eyesisCameraParameters.sensorHeight,
eyesisCameraParameters.getDecimateMasks(chn),
eyesisCameraParameters.getSensorWidth(chn),
eyesisCameraParameters.getSensorHeight(chn),
eyesisCameraParameters.shrinkGridForMask);
if (preMask==null) return null; //nothing in this channel
......@@ -3685,7 +4078,7 @@ import ij.text.TextWindow;
rAverage/=rAverageNum; // average distance to the fartherst node from the current
double sigma = eyesisCameraParameters.maskBlurSigma;
if(sigma<0) sigma*=-rAverage;
gb.blurDouble(mask, dWidth, dHeight, sigma/eyesisCameraParameters.decimateMasks, sigma/eyesisCameraParameters.decimateMasks, 0.01);
gb.blurDouble(mask, dWidth, dHeight, sigma/eyesisCameraParameters.getDecimateMasks(chn), sigma/eyesisCameraParameters.getDecimateMasks(chn), 0.01);
for (int i=0;i < mask.length;i++){
this.sensorMasks[chn][i] = Math.min(this.sensorMasks[chn][i],mask[i]);
}
......@@ -3694,11 +4087,12 @@ import ij.text.TextWindow;
public double [] calculateImageGridMask(int imgNum) {
int chn = this.gIP[imgNum].channel; // getChannel()
return calculateImageGridMask(
imgNum,
eyesisCameraParameters.decimateMasks,
eyesisCameraParameters.sensorWidth,
eyesisCameraParameters.sensorHeight,
eyesisCameraParameters.getDecimateMasks(chn),
eyesisCameraParameters.getSensorWidth(chn),
eyesisCameraParameters.getSensorHeight(chn),
eyesisCameraParameters.shrinkGridForMask,
eyesisCameraParameters.maskBlurSigma);
}
......@@ -3890,6 +4284,169 @@ import ij.text.TextWindow;
int offs_x = base_width/2 - test_width/2; // subtract from test.x
int offs_y = base_height/2 - test_height/2; // subtract from test.y
double [] corr = new double [(2*search_rad + 1)*(2*search_rad + 1)];
for (int dy = -search_rad; dy <= search_rad; dy++) {
for (int dx = -search_rad; dx <= search_rad; dx++) {
double sum = 0;
for (int y0 = 0; y0 < base_height; y0++) {
int y1 = y0 - offs_y - dy;
if ((y1 >= 0) && (y1 < test_height)) {
for (int x0 = 0; x0 < base_width; x0++) {
int x1 = x0 - offs_x - dx;
if ((x1 >= 0) && (x1 < test_width)) {
sum+= base_pixels[INDEX_CONTRAST][y0*base_width + x0] * test_pixels[INDEX_CONTRAST][y1*test_width + x1];
}
}
}
}
corr[(2*search_rad + 1)*(search_rad + dy) +(search_rad + dx)] = sum;
}
}
int [] indx_max_even_odd = {0,0};
for (int i = 1; i < corr.length; i++) {
int parity = ((i /(2*search_rad + 1)) + (i %(2*search_rad + 1))) & 1;
if (corr[indx_max_even_odd[parity]] <corr[i]) {
indx_max_even_odd[parity] = i;
}
}
// find first non-zero matching cell
int indx0=-1,indx1=-1;
int [] rslt = new int[3];
for (int parity = 0; parity < 2; parity++) {
int dy = indx_max_even_odd[parity] / (2*search_rad + 1) - search_rad;
int dx = indx_max_even_odd[parity] % (2*search_rad + 1) - search_rad;
first_nonzero:
for (int y0 = 0; y0 < base_height; y0++) {
int y1 = y0 - offs_y - dy;
if ((y1 >= 0) && (y1 < test_height)) {
for (int x0 = 0; x0 < base_width; x0++) {
int x1 = x0 - offs_x - dx;
if ((x1 >= 0) && (x1 < test_width)) {
indx0 = y0*base_width + x0;
indx1 = y1*test_width + x1;
if ((base_pixels[INDEX_CONTRAST][indx0] > 0 )&&
(test_pixels[INDEX_CONTRAST][indx1] > 0)) {
break first_nonzero;
}
}
}
}
}
// test grid with index indx1 matches base grid with indx0
rslt[0] = Math.round(base_pixels[INDEX_U][indx0] - test_pixels[INDEX_U][indx1]);
rslt[1] = Math.round(base_pixels[INDEX_V][indx0] - test_pixels[INDEX_V][indx1]);
rslt[2] = 0; // rotation
if (((rslt[0] + rslt[1] + (invert_color?1:0)) & 1) == 0) break;
}
return rslt;
}
int [] correlateWithPattern(
PatternParameters patternParameters,
int test_width,
float [][] test_pixels,
boolean invert_color,
int extra_search,
double sigma,
double [] sensor_wh, // test set pixels width/height pair to reduce weight near the margins (or null)
boolean bdebug
) {
int base_height = patternParameters.gridGeometry.length;
int base_width = patternParameters.gridGeometry[0].length;
int index_mask = 3;
float [][] base_pixels = new float [INDEX_CONTRAST+1][base_height*base_width];
int indx = 0;
for (int iv = 0; iv < base_height; iv++) {
for (int iu = 0; iu < base_width; iu++) {
base_pixels[INDEX_U][indx] = iu - patternParameters.U0;
base_pixels[INDEX_V][indx] = iv - patternParameters.V0;
base_pixels[INDEX_CONTRAST][indx] = (float) patternParameters.gridGeometry[iv][iu][index_mask];
indx++;
}
}
return correlateGrids(
base_width,
base_pixels,
test_width,
test_pixels,
invert_color,
extra_search,
sigma,
sensor_wh, // test set pixels width/height pair to reduce weight near the margins (or null)
bdebug
) ;
}
int [] correlateGrids(
int base_width,
float [][] base_pixels,
int test_width,
float [][] test_pixels,
boolean invert_color,
int extra_search,
double sigma,
double [] sensor_wh, // test set pixels width/height pair to reduce weight near the margins (or null)
boolean bdebug
) { // Gaussian blur sigma to subtract
int base_height = base_pixels[0].length/base_width;
int test_height = test_pixels[0].length/test_width;
int search_rad = Math.max(
(Math.max(base_width, test_width)- Math.min(base_width, test_width) + 1) /2,
(Math.max(base_height, test_height)-Math.min(base_height, test_height) + 1) /2) + extra_search;
int offs_x = base_width/2 - test_width/2; // subtract from test.x
int offs_y = base_height/2 - test_height/2; // subtract from test.y
double [] corr = new double [(2*search_rad + 1)*(2*search_rad + 1)];
double [] base_contrast = new double [base_pixels[INDEX_U].length];
double [] test_contrast = new double [test_pixels[INDEX_U].length];
for (int i = 0; i < base_contrast.length; i++) {
base_contrast[i] = base_pixels[INDEX_CONTRAST][i];
}
for (int i = 0; i < test_contrast.length; i++) {
test_contrast[i] = test_pixels[INDEX_CONTRAST][i];
}
double [] tmp_b = base_contrast.clone();
DoubleGaussianBlur gb = new DoubleGaussianBlur();
gb.blurDouble(tmp_b, base_width, base_height, sigma, sigma, 0.01);
// subtract DC
double s = 0.0;
for (int i = 0; i < base_contrast.length; i++) {
base_contrast[i] -= tmp_b[i];
s+=base_contrast[i];
}
s/=base_contrast.length;
for (int i = 0; i < base_contrast.length; i++) {
base_contrast[i] -= s;
}
tmp_b = test_contrast.clone();
gb.blurDouble(tmp_b, test_width, test_height, sigma, sigma, 0.01);
// subtract DC
s = 0.0;
for (int i = 0; i < test_contrast.length; i++) {
test_contrast[i] -= tmp_b[i];
s+=test_contrast[i];
}
s/=test_contrast.length;
for (int i = 0; i < test_contrast.length; i++) {
test_contrast[i] -= s;
}
if (sensor_wh != null) {
double x0 = sensor_wh[0]/2;
double y0 = sensor_wh[1]/2;
for (int i = 0; i < test_contrast.length; i++) {
double x = (test_pixels[INDEX_PX][i] - x0)/x0;
double y = (test_pixels[INDEX_PY][i] - y0)/y0;
test_contrast[i] *= (1.0 - x*x)* (1.0 - y*y);
}
}
if (bdebug) {
(new ShowDoubleFloatArrays()).showArrays(base_contrast, base_width, base_height, "base_sigma-"+sigma);
(new ShowDoubleFloatArrays()).showArrays(test_contrast, test_width, test_height, "test_sigma-"+sigma);
}
for (int dy = -search_rad; dy <= search_rad; dy++) {
for (int dx = -search_rad; dx <= search_rad; dx++) {
double sum = 0;
......@@ -3900,7 +4457,7 @@ import ij.text.TextWindow;
for (int x0 = 0; x0 < base_width; x0++) {
int x1 = x0 - offs_x - dx;
if ((x1 >= 0) && (x1 < test_width)) {
sum+= base_pixels[INDEX_CONTRAST][y0*base_width + x0] * test_pixels[INDEX_CONTRAST][y1*test_width + x1];
sum+= base_contrast[y0*base_width + x0] * test_contrast[y1*test_width + x1];
}
}
}
......@@ -3908,10 +4465,13 @@ import ij.text.TextWindow;
corr[(2*search_rad + 1)*(search_rad + dy) +(search_rad + dx)] = sum;
}
}
int [] indx_max_even_odd = {0,0};
if (bdebug) {
(new ShowDoubleFloatArrays()).showArrays(corr, "corr_sigma-"+sigma);
}
int [] indx_max_even_odd = {-1,-1};
for (int i = 1; i < corr.length; i++) {
int parity = ((i /(2*search_rad + 1)) + (i %(2*search_rad + 1))) & 1;
if (corr[indx_max_even_odd[parity]] <corr[i]) {
if ((indx_max_even_odd[parity] < 0) || (corr[indx_max_even_odd[parity]] < corr[i])) {
indx_max_even_odd[parity] = i;
}
}
......@@ -3948,7 +4508,15 @@ import ij.text.TextWindow;
}
return rslt;
}
// Set initial shifts for the grids that do not have absolute match from the one in the same set that does
// end of class DistortionCalibrationData
}
// Set initial shifts for the grids that do not have absolute match from the one in the same set that does
// end of class DistortionCalibrationData
}
......@@ -119,9 +119,23 @@ public class Distortions {
public boolean saveSeries=false; // just for the dialog
public double [][][] pixelCorrection=null; // for each sensor: corr-X, corr-Y, mask, flat-field-Red, flat-field-Green, flat-field-Blue
public String [] pathNames=null;
public int pixelCorrectionDecimation=1;
public int pixelCorrectionWidth=2592;
public int pixelCorrectionHeight=1936;
// Will have to chage for different resolution
// public int [][] pixelCorrectionWHD= null; // For each sensor -width, height, decimation
// public int defaultPixelCorrectionDecimation= 1;
// public int defaultPixelCorrectionWidth= 2592;
// public int defaultPixelCorrectionHeight= 1936;
// @Deprecated
// public int pixelCorrectionDecimation= 1;
// @Deprecated
// public int pixelCorrectionWidth= 2592;
// @Deprecated
// public int pixelCorrectionHeight= 1936;
public double RMSscale=Math.sqrt(2.0); // errors for x and y are calculated separately, so actual error is larger
public boolean showIndex=true;
......@@ -143,23 +157,27 @@ public class Distortions {
public AtomicInteger stopRequested=null; // 1 - stop now, 2 - when convenient
public String [] status ={"",""};
/*
public void showStatus (String msg, int slot){
String separator = " | ";
if ((slot<0) || (slot>=status.length)) return;
status[slot]=msg;
String s=status[0];
for (int i=1;i<status.length;i++) if (status[i].length()>0) s+=separator+status[i];
IJ.showStatus(s);
}
public void showProgress(double frac){
if ((frac>=1.0) || (frac <=0)) showStatus("",1);
showStatus(IJ.d2s(100*frac,2)+"%",1);
}
public void showProgress(int currentIndex, int finalIndex){
showProgress((currentIndex+1.0)/(double)finalIndex);
public int getSensorWidth(int subCam) { return fittingStrategy.distortionCalibrationData.eyesisCameraParameters.getSensorWidth(subCam);} // for the future? different sensors
public int getSensorHeight(int subCam) { return fittingStrategy.distortionCalibrationData.eyesisCameraParameters.getSensorHeight(subCam);}// for the future? different sensors
public int getDecimateMasks(int subCam) { return fittingStrategy.distortionCalibrationData.eyesisCameraParameters.getDecimateMasks(subCam);}// for the future? different sensors
public int getSensorWidth() { return fittingStrategy.distortionCalibrationData.eyesisCameraParameters.getSensorWidth();} // for the future? different sensors
public int getSensorHeight() { return fittingStrategy.distortionCalibrationData.eyesisCameraParameters.getSensorHeight();}// for the future? different sensors
public int getDecimateMasks() { return fittingStrategy.distortionCalibrationData.eyesisCameraParameters.getDecimateMasks();}// for the future? different sensors
public int getSensorCorrWidth(int subCam) { return(getSensorWidth(subCam)-1)/getDecimateMasks(subCam)+1;}
public int getSensorCorrWidth() { return(getSensorWidth()-1)/getDecimateMasks()+1;}
public void setSensorWidth(int subCam, int v) {
fittingStrategy.distortionCalibrationData.eyesisCameraParameters.setSensorWidth(subCam, v);
}
*/
public void setSensorHeight(int subCam, int v) {fittingStrategy.distortionCalibrationData.eyesisCameraParameters.setSensorHeight(subCam, v);}
public void setDecimateMasks(int subCam, int v){fittingStrategy.distortionCalibrationData.eyesisCameraParameters.setDecimateMasks(subCam, v);}
public class LMAArrays {
public double [][] jTByJ= null; // jacobian multiplied by Jacobian transposed
public double [] jTByDiff=null; // jacobian multiplied difference vector
......@@ -393,12 +411,11 @@ public class Distortions {
this.sumWeights=0.0;
this.imageStartIndex=new int [numImg+1];
// added here, was using pixelCorrectionDecimation==1
this.pixelCorrectionDecimation=fittingStrategy.distortionCalibrationData.eyesisCameraParameters.decimateMasks;
this.pixelCorrectionWidth= fittingStrategy.distortionCalibrationData.eyesisCameraParameters.sensorWidth;
this.pixelCorrectionHeight= fittingStrategy.distortionCalibrationData.eyesisCameraParameters.sensorHeight;
/// this.pixelCorrectionDecimation=fittingStrategy.distortionCalibrationData.eyesisCameraParameters.getDecimateMasks();
/// this.pixelCorrectionWidth= fittingStrategy.distortionCalibrationData.eyesisCameraParameters.getSensorWidth();
/// this.pixelCorrectionHeight= fittingStrategy.distortionCalibrationData.eyesisCameraParameters.getSensorHeight();
/// int sensorCorrWidth= (this.pixelCorrectionWidth-1)/this.pixelCorrectionDecimation+1;
int sensorCorrWidth= (this.pixelCorrectionWidth-1)/this.pixelCorrectionDecimation+1;
double [] multiWeight=new double [numImg];
for (int imgNum=0;imgNum<numImg;imgNum++) multiWeight[imgNum]=0.0;
double minimalGridContrast=fittingStrategy.distortionCalibrationData.eyesisCameraParameters.minimalGridContrast;
......@@ -556,12 +573,12 @@ public class Distortions {
fittingStrategy.distortionCalibrationData.gIP[imgNum].pixelsXY[pointNumber][1]
};
// TODO: Should it be interpolated? Correction is normally small/smooth, so it may be not important
int indexXY=((int) Math.floor(pXY[0]/this.pixelCorrectionDecimation)) +
((int) Math.floor(pXY[1]/this.pixelCorrectionDecimation))*sensorCorrWidth;
int indexXY=((int) Math.floor(pXY[0]/getDecimateMasks(chnNum))) +
((int) Math.floor(pXY[1]/getDecimateMasks(chnNum)))*getSensorCorrWidth(chnNum);
if (this.pixelCorrection[chnNum][0].length<=indexXY){
System.out.println("initFittingSeries("+numSeries+") bug:");
System.out.println("this.pixelCorrection["+chnNum+"][0].length="+this.pixelCorrection[chnNum][0].length);
System.out.println("indexXY="+indexXY+" pXY[0]="+pXY[0]+", pXY[1]="+pXY[1]+" sensorCorrWidth="+sensorCorrWidth);
System.out.println("indexXY="+indexXY+" pXY[0]="+pXY[0]+", pXY[1]="+pXY[1]+" sensorCorrWidth="+getSensorCorrWidth(chnNum));
} else {
this.Y[2*index]= pXY[0]-this.pixelCorrection[chnNum][0][indexXY]; //java.lang.ArrayIndexOutOfBoundsException: 3204663
......@@ -727,7 +744,7 @@ public class Distortions {
return this.fittingStrategy.distortionCalibrationData.gIP[imgNum].getGridDiameter();
}
public void listImageSets(){ // TODO: use series -1 - should work now
public void listImageSets(int mode){ // TODO: use series -1 - should work now
// boolean [] oldSelection=this.fittingStrategy.selectAllImages(0); // enable all images in series 0
if (this.fittingStrategy.distortionCalibrationData.gIS!=null){
if (this.debugLevel>2){
......@@ -783,7 +800,11 @@ public class Distortions {
numSetPoints[setNum]=numInSet;
rmsPerSet[setNum]=Math.sqrt(error2/numInSet);
}
this.fittingStrategy.distortionCalibrationData.listImageSet(numSetPoints, rmsPerSet,hasNaNInSet );
this.fittingStrategy.distortionCalibrationData.listImageSet(
mode,
numSetPoints,
rmsPerSet,
hasNaNInSet );
// this.fittingStrategy.setImageSelection(0, oldSelection); // restore original selection in series 0
}
......@@ -813,12 +834,24 @@ public class Distortions {
for (int nChn=0;nChn<masks.length;nChn++) if ((nChn<selectedChannels.length)&&!selectedChannels[nChn]) masks[nChn]=null;
}
*/
if (enableShow && this.refineParameters.flatFieldShowSensorMasks) (new ShowDoubleFloatArrays()).showArrays( //java.lang.ArrayIndexOutOfBoundsException: 313632
boolean same_size = true;
for (int nChn=1; nChn < masks.length; nChn++) same_size &= (masks[nChn].length == masks[0].length);
if (enableShow && this.refineParameters.flatFieldShowSensorMasks) {
if (same_size) {
(new ShowDoubleFloatArrays()).showArrays( //java.lang.ArrayIndexOutOfBoundsException: 313632
masks,
this.pixelCorrectionWidth/ this.pixelCorrectionDecimation,
this.pixelCorrectionHeight/this.pixelCorrectionDecimation,
getSensorWidth(0)/ getDecimateMasks(0),
getSensorHeight(0)/getDecimateMasks(0),
true,
"nonVinetting masks");
} else {
System.out.println ("Can not display different saze masks in a stack");
}
}
double [][][][] sensorGrids=calculateGridFlatField(
this.refineParameters.flatFieldSerNumber,
masks,
......@@ -895,11 +928,11 @@ public class Distortions {
updateStatus,
debugLevel);
String [] titles={"X-corr(pix)","Y-corr(pix)","weight","Red","Green","Blue"};
int decimate=fittingStrategy.distortionCalibrationData.eyesisCameraParameters.decimateMasks;
int sWidth= (fittingStrategy.distortionCalibrationData.eyesisCameraParameters.sensorWidth-1)/decimate+1;
int sHeight=(fittingStrategy.distortionCalibrationData.eyesisCameraParameters.sensorHeight-1)/decimate+1;
if (enableShow && this.refineParameters.showUnfilteredCorrection) {
for (int numChn=0;numChn<sensorXYRGBCorr.length;numChn++) if (sensorXYRGBCorr[numChn]!=null){
int decimate=getDecimateMasks(numChn);
int sWidth= (getSensorWidth(numChn)-1)/decimate+1;
//this.SDFA_INSTANCE.showArrays(sensorXYRGBCorr[numChn], sWidth, sHeight, true, "chn_"+numChn+"_extra_correction", titles);
showWithRadialTangential(
titles,
......@@ -943,6 +976,9 @@ public class Distortions {
boolean [] whichBlur={true,true,false,true,true,true}; // all but weight
IJ.showStatus("Bluring sensor corrections...");
for (int numChn=0;numChn<sensorXYRGBCorr.length;numChn++) if (sensorXYRGBCorr[numChn]!=null){
int decimate=getDecimateMasks(numChn);
int sWidth= (getSensorWidth(numChn)-1)/decimate+1;
int sHeight=(getSensorHeight(numChn)-1)/decimate+1;
DoubleGaussianBlur gb=new DoubleGaussianBlur();
for (int m=0;m<whichBlur.length;m++) if (whichBlur[m]){
gb.blurDouble(
......@@ -960,6 +996,8 @@ public class Distortions {
if (enableShow && this.refineParameters.showThisCorrection ) {
for (int numChn=0;numChn<sensorXYRGBCorr.length;numChn++) if (sensorXYRGBCorr[numChn]!=null){
int decimate=getDecimateMasks(numChn);
int sWidth= (getSensorWidth(numChn)-1)/decimate+1;
// this.SDFA_INSTANCE.showArrays(sensorXYRGBCorr[numChn], sWidth, sHeight, true, "chn_"+numChn+"_filtered", titles);
showWithRadialTangential(
titles,
......@@ -989,6 +1027,8 @@ public class Distortions {
fittingStrategy.distortionCalibrationData);
if (enableShow && this.refineParameters.showCumulativeCorrection) {
for (int numChn=0;numChn<sensorXYRGBCorr.length;numChn++) if (sensorXYRGBCorr[numChn]!=null){
int decimate=getDecimateMasks(numChn);
int sWidth= (getSensorWidth(numChn)-1)/decimate+1;
// this.SDFA_INSTANCE.showArrays(sensorXYRGBCorr[numChn], sWidth, sHeight, true, "Cumulative_chn_"+numChn+"_corrections", titles);
showWithRadialTangential(
titles,
......@@ -1365,11 +1405,11 @@ public class Distortions {
final int alphaIndex=2;
final int sensorWidth= fittingStrategy.distortionCalibrationData.eyesisCameraParameters.sensorWidth;
final int sensorHeight= fittingStrategy.distortionCalibrationData.eyesisCameraParameters.sensorHeight;
final int decimation=fittingStrategy.distortionCalibrationData.eyesisCameraParameters.decimateMasks;
final int width= (sensorWidth-1)/decimation+1; // decimated width (648)
final int height= (sensorHeight-1)/decimation+1; // decimated width (648)
// final int sensorWidth= fittingStrategy.distortionCalibrationData.eyesisCameraParameters.sensorWidth;
// final int sensorHeight= fittingStrategy.distortionCalibrationData.eyesisCameraParameters.sensorHeight;
// final int decimation=fittingStrategy.distortionCalibrationData.eyesisCameraParameters.decimateMasks;
// final int width= (sensorWidth-1)/decimation+1; // decimated width (648)
// final int height= (sensorHeight-1)/decimation+1; // decimated width (648)
final boolean extraShowDebug=showDebugImages&& (debugLevel>2);
for (int ithread = 0; ithread < threads.length; ithread++) {
......@@ -1386,6 +1426,12 @@ public class Distortions {
}
if (shrinkBlurComboSigma>0.0) gb=new DoubleGaussianBlur();
for (int sensorNum=sensorNumberAtomic.getAndIncrement(); (sensorNum<gridPCorr.length) && !interruptedAtomic.get();sensorNum=sensorNumberAtomic.getAndIncrement()){
int sensorWidth= fittingStrategy.distortionCalibrationData.eyesisCameraParameters.getSensorWidth(sensorNum);
int sensorHeight= fittingStrategy.distortionCalibrationData.eyesisCameraParameters.getSensorHeight(sensorNum);
int decimation=fittingStrategy.distortionCalibrationData.eyesisCameraParameters.getDecimateMasks(sensorNum);
int width= (sensorWidth-1)/decimation+1; // decimated width (648)
int height= (sensorHeight-1)/decimation+1; // decimated width (648)
if (gridPCorr[sensorNum]!=null){
final double [] centerPXY={
eyesisSubCameras[sensorNum].px0,
......@@ -1821,9 +1867,10 @@ public class Distortions {
showIntermediate,
debugLevel);
if (showIntermediate) correctionInNodes.show("finNode-"+imgNum);
int sensorWidth= fittingStrategy.distortionCalibrationData.eyesisCameraParameters.sensorWidth;
int sensorHeight= fittingStrategy.distortionCalibrationData.eyesisCameraParameters.sensorHeight;
int decimation=fittingStrategy.distortionCalibrationData.eyesisCameraParameters.decimateMasks;
int chnNum=fittingStrategy.distortionCalibrationData.gIP[imgNum].channel;
int sensorWidth= fittingStrategy.distortionCalibrationData.eyesisCameraParameters.getSensorWidth(chnNum);
int sensorHeight= fittingStrategy.distortionCalibrationData.eyesisCameraParameters.getSensorHeight(chnNum);
int decimation=fittingStrategy.distortionCalibrationData.eyesisCameraParameters.getDecimateMasks(chnNum);
double [][] additionalCorrection=correctionInNodes.mapToPixels(
decimation,
sensorWidth,
......@@ -2362,14 +2409,15 @@ public class Distortions {
double [] vector={0.0,0.0,1.0,1.0,1.0,1.0};
return vector;
}
this.pixelCorrectionDecimation=fittingStrategy.distortionCalibrationData.eyesisCameraParameters.decimateMasks;
this.pixelCorrectionWidth= fittingStrategy.distortionCalibrationData.eyesisCameraParameters.sensorWidth;
this.pixelCorrectionHeight= fittingStrategy.distortionCalibrationData.eyesisCameraParameters.sensorHeight;
// this.pixelCorrectionDecimation=fittingStrategy.distortionCalibrationData.eyesisCameraParameters.decimateMasks;
// this.pixelCorrectionWidth= fittingStrategy.distortionCalibrationData.eyesisCameraParameters.sensorWidth;
// this.pixelCorrectionHeight= fittingStrategy.distortionCalibrationData.eyesisCameraParameters.sensorHeight;
int sensorCorrWidth= (this.pixelCorrectionWidth-1)/this.pixelCorrectionDecimation+1;
int sensorCorrWidth= getSensorCorrWidth(chnNum);
int sensorCorrHeight=this.pixelCorrection[chnNum][0].length/sensorCorrWidth;
int [] ix={(int) Math.floor(px/this.pixelCorrectionDecimation), (int) Math.floor(px/this.pixelCorrectionDecimation)+1};
int [] iy={(int) Math.floor(py/this.pixelCorrectionDecimation),(int) Math.floor(py/this.pixelCorrectionDecimation)+1};
int [] ix={(int) Math.floor(px/getDecimateMasks(chnNum)), (int) Math.floor(px/getDecimateMasks(chnNum))+1};
int [] iy={(int) Math.floor(py/getDecimateMasks(chnNum)),(int) Math.floor(py/getDecimateMasks(chnNum))+1};
for (int i=0;i<2;i++){
if (ix[i]<0) ix[i]=0;
else if (ix[i]>=sensorCorrWidth) ix[i]=sensorCorrWidth-1;
......@@ -2403,17 +2451,18 @@ public class Distortions {
* @return interpolated mask data at specified fractional pixel
*/
public double interpolateMask (
int chnNum,
double [] mask,
double px,
double py){
this.pixelCorrectionDecimation=fittingStrategy.distortionCalibrationData.eyesisCameraParameters.decimateMasks;
this.pixelCorrectionWidth= fittingStrategy.distortionCalibrationData.eyesisCameraParameters.sensorWidth;
this.pixelCorrectionHeight= fittingStrategy.distortionCalibrationData.eyesisCameraParameters.sensorHeight;
/// this.pixelCorrectionDecimation=fittingStrategy.distortionCalibrationData.eyesisCameraParameters.decimateMasks;
/// this.pixelCorrectionWidth= fittingStrategy.distortionCalibrationData.eyesisCameraParameters.sensorWidth;
/// this.pixelCorrectionHeight= fittingStrategy.distortionCalibrationData.eyesisCameraParameters.sensorHeight;
int sensorCorrWidth= (this.pixelCorrectionWidth-1)/this.pixelCorrectionDecimation+1;
int sensorCorrWidth= getSensorCorrWidth(chnNum); // (this.pixelCorrectionWidth-1)/this.pixelCorrectionDecimation+1;
int sensorCorrHeight=mask.length/sensorCorrWidth;
int [] ix={(int) Math.floor(px/this.pixelCorrectionDecimation), (int) Math.floor(px/this.pixelCorrectionDecimation)+1};
int [] iy={(int) Math.floor(py/this.pixelCorrectionDecimation),(int) Math.floor(py/this.pixelCorrectionDecimation)+1};
int [] ix={(int) Math.floor(px/getDecimateMasks(chnNum)), (int) Math.floor(px/getDecimateMasks(chnNum))+1};
int [] iy={(int) Math.floor(py/getDecimateMasks(chnNum)), (int) Math.floor(py/getDecimateMasks(chnNum))+1};
for (int i=0;i<2;i++){
if (ix[i]<0) ix[i]=0;
else if (ix[i]>=sensorCorrWidth) ix[i]=sensorCorrWidth-1;
......@@ -2499,8 +2548,8 @@ For each point in the image
matchSimulatedPattern.debugLevel = mspDebugLevel;
// MatchSimulatedPattern.DistortionParameters distortionParameters = modifyDistortionParameters();
// SimulationPattern.SimulParameters simulParameters = modifySimulParameters();
int sensorWidth=fittingStrategy.distortionCalibrationData.eyesisCameraParameters.getSensorWidth(subCam);
int sensorHeight=fittingStrategy.distortionCalibrationData.eyesisCameraParameters.getSensorHeight(subCam);
int sensorWidth= getSensorWidth(subCam);
int sensorHeight= getSensorHeight(subCam);
double [][][] hintGrid=estimateGridOnSensor(
stationNumber,
......@@ -2630,7 +2679,7 @@ For each point in the image
System.out.println("\n---- applyHintedGrids() image #"+numGridImage+" (imageNumber="+imageNumber+") "+
" dcd.gIP["+numGridImage+"].pixelsXY.length="+dcd.gIP[numGridImage].pixelsXY.length+
" dcd.gIP["+numGridImage+"].pixelsXY_extra.length="+dcd.gIP[numGridImage].pixelsXY_extra.length+
" grid period="+dcd.gIP[numGridImage].gridPeriod+
" grid period="+dcd.gIP[numGridImage].getGridPeriod()+
" enabled="+dcd.gIP[numGridImage].enabled+
" hintedMatch="+dcd.gIP[numGridImage].hintedMatch
);
......@@ -4390,7 +4439,7 @@ List calibration
sb.append("\t");
if (!gip.enabled) sb.append("(");
sb.append(numPointers+"("+gip.matchedPointers+"):"+gip.hintedMatch +
" "+IJ.d2s(gip.gridPeriod,1));
" "+IJ.d2s(gip.getGridPeriod(),1));
if (!gip.enabled) sb.append(")");
}
sb.append("\n");
......@@ -4754,6 +4803,13 @@ List calibration
}
} else {
selectedImages=tmpSelectedImages;
int numImg = 0;
for (int i=0;i<selectedImages.length;i++) if (selectedImages[i]) numImg++;
imageNumbers = new int [numImg];
numImg = 0;
for (int i=0;i<selectedImages.length;i++) if (selectedImages[i]) {
imageNumbers[numImg++] = i;
}
}
int width= getGridWidth();
int height=getGridHeight();
......@@ -5816,23 +5872,26 @@ List calibration
this.refineParameters.showIndividualNumber,
this.refineParameters.usePatternAlpha);
String [] titles={"X-corr(pix)","Y-corr(pix)","alpha","weight","Red","Green","Blue"};
int decimate=distortionCalibrationData.eyesisCameraParameters.decimateMasks;
int sWidth= (distortionCalibrationData.eyesisCameraParameters.sensorWidth-1)/decimate+1;
int sHeight=(distortionCalibrationData.eyesisCameraParameters.sensorHeight-1)/decimate+1;
if (this.refineParameters.showUnfilteredCorrection) {
for (int numChn=0;numChn<sensorXYCorr.length;numChn++) if (sensorXYCorr[numChn]!=null){
this.SDFA_INSTANCE.showArrays(sensorXYCorr[numChn], sWidth, sHeight, true, "chn_"+numChn+"_extra_correction", titles);
}
}
if (this.refineParameters.extrapolate) {
boolean [] whichExtrapolate={true, true,false,false,true,true,true};
boolean [] whichPositive= {false,false,false,false,true,true,true};
IJ.showStatus("Extrapolating sensor corrections...");
for (int numChn=0;numChn<sensorXYCorr.length;numChn++) if (sensorXYCorr[numChn]!=null){
int decimate=getDecimateMasks(numChn);
int sWidth= (getSensorWidth(numChn)-1)/decimate+1;
int sHeight=(getSensorHeight(numChn)-1)/decimate+1;
if (this.refineParameters.showUnfilteredCorrection) {
this.SDFA_INSTANCE.showArrays(sensorXYCorr[numChn], sWidth, sHeight, true, "chn_"+numChn+"_extra_correction", titles);
}
for (int i=0;i<whichPositive.length;i++) if (whichPositive[i]){
logScale(sensorXYCorr[numChn][i],this.refineParameters.fatZero);
}
boolean extrapolateOK=extrapolateSensorCorrection( //ava.lang.NullPointerException at Distortions.modifyPixelCorrection(Distortions.java:2595)
numChn,
whichExtrapolate,
sensorXYCorr[numChn],
sensorXYCorr[numChn][2],// alpha - it is more pessimistic than fittingStrategy.distortionCalibrationData.sensorMasks[numChn]
......@@ -5851,7 +5910,10 @@ List calibration
if (this.refineParameters.showExtrapolationCorrection && this.refineParameters.extrapolate && this.refineParameters.smoothCorrection) {
for (int numChn=0;numChn<sensorXYCorr.length;numChn++) if (sensorXYCorr[numChn]!=null){
this.SDFA_INSTANCE.showArrays(sensorXYCorr[numChn], sWidth, sHeight, true, "chn_"+numChn+"_extrapolated", titles);
int decimate=getDecimateMasks(numChn);
int sWidth= (getSensorWidth(numChn)-1)/decimate+1;
int sHeight=(getSensorHeight(numChn)-1)/decimate+1;
this.SDFA_INSTANCE.showArrays(sensorXYCorr[numChn], sWidth, sHeight, true, "chn_"+numChn+"_extrapolated", titles);
}
}
......@@ -5859,6 +5921,9 @@ List calibration
boolean [] whichBlur={true,true,false,false,true,true,true};
IJ.showStatus("Bluring sensor corrections...");
for (int numChn=0;numChn<sensorXYCorr.length;numChn++) if (sensorXYCorr[numChn]!=null){
int decimate=getDecimateMasks(numChn);
int sWidth= (getSensorWidth(numChn)-1)/decimate+1;
int sHeight=(getSensorHeight(numChn)-1)/decimate+1;
DoubleGaussianBlur gb=new DoubleGaussianBlur();
for (int m=0;m<whichBlur.length;m++) if (whichBlur[m]){
gb.blurDouble(sensorXYCorr[numChn][m],
......@@ -5874,7 +5939,10 @@ List calibration
}
if (this.refineParameters.showThisCorrection ) {
for (int numChn=0;numChn<sensorXYCorr.length;numChn++) if (sensorXYCorr[numChn]!=null){
this.SDFA_INSTANCE.showArrays(sensorXYCorr[numChn], sWidth, sHeight, true, "chn_"+numChn+"_filtered", titles);
int decimate=getDecimateMasks(numChn);
int sWidth= (getSensorWidth(numChn)-1)/decimate+1;
int sHeight=(getSensorHeight(numChn)-1)/decimate+1;
this.SDFA_INSTANCE.showArrays(sensorXYCorr[numChn], sWidth, sHeight, true, "chn_"+numChn+"_filtered", titles);
}
}
// if (!selectCorrectionScale()) return false;
......@@ -5894,12 +5962,13 @@ List calibration
distortionCalibrationData);
if (this.refineParameters.showCumulativeCorrection) {
for (int numChn=0;numChn<sensorXYCorr.length;numChn++) if (sensorXYCorr[numChn]!=null){
this.SDFA_INSTANCE.showArrays(sensorXYCorr[numChn], sWidth, sHeight, true, "Cumulative_chn_"+numChn+"_corrections", titles);
int decimate=getDecimateMasks(numChn);
int sWidth= (getSensorWidth(numChn)-1)/decimate+1;
int sHeight=(getSensorHeight(numChn)-1)/decimate+1;
this.SDFA_INSTANCE.showArrays(sensorXYCorr[numChn], sWidth, sHeight, true, "Cumulative_chn_"+numChn+"_corrections", titles);
}
}
if (result) {
// updateCameraParametersFromCalculated();
// NEED to update from all?
// 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)
......@@ -5951,18 +6020,18 @@ List calibration
double [][][] sensorXYCorr,
DistortionCalibrationData distortionCalibrationData){
int numLayers=6;
int decimate=distortionCalibrationData.eyesisCameraParameters.decimateMasks;
int width= distortionCalibrationData.eyesisCameraParameters.sensorWidth;
int height=distortionCalibrationData.eyesisCameraParameters.sensorHeight;
if ((this.pixelCorrection!=null) && (this.pixelCorrectionDecimation!=decimate)){
IJ.showMessage("Error","Can not apply correction as the current correction and the new one have different decimations");
return false;
}
/// int decimate=distortionCalibrationData.eyesisCameraParameters.decimateMasks;
/// int width= distortionCalibrationData.eyesisCameraParameters.sensorWidth;
/// int height=distortionCalibrationData.eyesisCameraParameters.sensorHeight;
/// if ((this.pixelCorrection!=null) && (this.pixelCorrectionDecimation!=decimate)){
/// IJ.showMessage("Error","Can not apply correction as the current correction and the new one have different decimations");
/// return false;
/// }
if ((this.pixelCorrection==null) && !update && !updateFlatField) return true;
if (update){
this.pixelCorrectionDecimation=decimate;
this.pixelCorrectionWidth=width;
this.pixelCorrectionHeight=height;
/// this.pixelCorrectionDecimation=decimate;
/// this.pixelCorrectionWidth=width;
/// this.pixelCorrectionHeight=height;
}
if (this.pixelCorrection==null) {
if (this.debugLevel>1) System.out.println("Initializing pixelCorrection array");
......@@ -5996,7 +6065,6 @@ List calibration
int indxR=in6?3:4;
int indxG=in6?4:5;
int indxB=in6?5:6;
// System.out.println("applySensorCorrection(): in6="+in6+" indxR="+indxR+" indxG="+indxG+" indxB="+indxB);
double [] sensorMask=in6?((fittingStrategy.distortionCalibrationData.sensorMasks==null)?null:fittingStrategy.distortionCalibrationData.sensorMasks[i]):sensorXYCorr[i][2];
if (this.pixelCorrection[i]==null) {
if (update || updateFlatField) {
......@@ -6014,7 +6082,6 @@ List calibration
this.pixelCorrection[i][4]=sensorXYCorr[i][indxG];
this.pixelCorrection[i][5]=sensorXYCorr[i][indxB];
} else {
// for (int n=2;n<numLayers;n++){
for (int n=3;n<numLayers;n++){
this.pixelCorrection[i][n]=new double[this.pixelCorrection[0].length];
for (int j=0;j<this.pixelCorrection[i][0].length;j++) this.pixelCorrection[i][n][j]=1.0;
......@@ -6139,8 +6206,12 @@ List calibration
}
if ((this.pixelCorrection!=null) && (numSensor>=0) && (numSensor<this.pixelCorrection.length))
pixelCorr=this.pixelCorrection[numSensor];
int width=this.pixelCorrectionWidth/this.pixelCorrectionDecimation;
int height=this.pixelCorrectionHeight/this.pixelCorrectionDecimation;
int width = distortionCalibrationData.eyesisCameraParameters.getSensorWidth(numSensor) /
distortionCalibrationData.eyesisCameraParameters.getDecimateMasks(numSensor);
int height = distortionCalibrationData.eyesisCameraParameters.getSensorHeight(numSensor) /
distortionCalibrationData.eyesisCameraParameters.getDecimateMasks(numSensor);
// int length=this.pixelCorrection[numSensor][0].length; // should be == width*height
int length=width*height;
......@@ -6180,9 +6251,9 @@ List calibration
imp.setProperty("comment_arrays", "Array corrections from acquired image to radially distorted, in pixels");
imp.setProperty("arraysSet", ""+(pixelCorr!=null)); // per-pixel arrays are not set, using 0.0
imp.setProperty("maskSet", ""+(mask!=null)); // per-pixel masks is not set, using 1.0
imp.setProperty("pixelCorrectionWidth", ""+this.pixelCorrectionWidth);
imp.setProperty("pixelCorrectionHeight", ""+this.pixelCorrectionHeight);
imp.setProperty("pixelCorrectionDecimation", ""+this.pixelCorrectionDecimation);
imp.setProperty("pixelCorrectionWidth", ""+distortionCalibrationData.eyesisCameraParameters.getSensorWidth(numSensor)); // this.pixelCorrectionWidth);
imp.setProperty("pixelCorrectionHeight", ""+distortionCalibrationData.eyesisCameraParameters.getSensorHeight(numSensor));
imp.setProperty("pixelCorrectionDecimation", ""+distortionCalibrationData.eyesisCameraParameters.getDecimateMasks(numSensor));
imp.setProperty("comment_decimation", "when decimation use integer divide to find the index, corection values are in non-decimated pixels");
imp.setProperty("distortion_formula", "(normalized by distortionRadius in mm) Rdist/R=A8*R^7+A7*R^6+A6*R^5+A5*R^4+A*R^3+B*R^2+C*R+(1-A6-A7-A6-A5-A-B-C)");
imp.setProperty("distortionRadius", ""+subCam.distortionRadius);
......@@ -6394,17 +6465,17 @@ List calibration
EyesisSubCameraParameters subCam;
EyesisCameraParameters cam= distortionCalibrationData.eyesisCameraParameters;
this.pixelCorrectionWidth= Integer.parseInt ((String) imp.getProperty("pixelCorrectionWidth"));
this.pixelCorrectionHeight= Integer.parseInt ((String) imp.getProperty("pixelCorrectionHeight"));
this.pixelCorrectionDecimation= Integer.parseInt ((String) imp.getProperty("pixelCorrectionDecimation"));
if ((distortionCalibrationData!=null) && (distortionCalibrationData.eyesisCameraParameters!=null)){
distortionCalibrationData.eyesisCameraParameters.decimateMasks=this.pixelCorrectionDecimation;
distortionCalibrationData.eyesisCameraParameters.sensorWidth= this.pixelCorrectionWidth;
distortionCalibrationData.eyesisCameraParameters.sensorHeight=this.pixelCorrectionHeight;
// Now it is the same
/// distortionCalibrationData.eyesisCameraParameters.decimateMasks=this.pixelCorrectionDecimation;
/// distortionCalibrationData.eyesisCameraParameters.sensorWidth= this.pixelCorrectionWidth;
/// distortionCalibrationData.eyesisCameraParameters.sensorHeight=this.pixelCorrectionHeight;
}
for (int stationNumber=0; stationNumber < distortionCalibrationData.eyesisCameraParameters.numStations; stationNumber++){
subCam=distortionCalibrationData.eyesisCameraParameters.eyesisSubCameras[stationNumber][numSensor];
distortionCalibrationData.eyesisCameraParameters.setSensorWidth( numSensor, Integer.parseInt ((String) imp.getProperty("pixelCorrectionWidth")));
distortionCalibrationData.eyesisCameraParameters.setSensorHeight( numSensor, Integer.parseInt ((String) imp.getProperty("pixelCorrectionHeight")));
distortionCalibrationData.eyesisCameraParameters.setDecimateMasks(numSensor, Integer.parseInt ((String) imp.getProperty("pixelCorrectionDecimation")));
subCam.distortionRadius= Double.parseDouble((String) imp.getProperty("distortionRadius"));
subCam.focalLength= Double.parseDouble((String) imp.getProperty("focalLength"));
......@@ -6579,18 +6650,15 @@ List calibration
boolean ignoreSensorFlatField){
// TODO: add standard weight function used elsethere.
int indexContrast=2;
// int indexRGB=3;
boolean [] selectedImages=fittingStrategy.selectedImages(serNumber); // negative series number OK - will select all enabled
int gridHeight=this.patternParameters.gridGeometry.length;
int gridWidth=this.patternParameters.gridGeometry[0].length;
// was not here
this.pixelCorrectionDecimation=fittingStrategy.distortionCalibrationData.eyesisCameraParameters.decimateMasks;
this.pixelCorrectionWidth= fittingStrategy.distortionCalibrationData.eyesisCameraParameters.sensorWidth;
this.pixelCorrectionHeight= fittingStrategy.distortionCalibrationData.eyesisCameraParameters.sensorHeight;
/// this.pixelCorrectionDecimation=fittingStrategy.distortionCalibrationData.eyesisCameraParameters.decimateMasks;
/// this.pixelCorrectionWidth= fittingStrategy.distortionCalibrationData.eyesisCameraParameters.sensorWidth;
/// this.pixelCorrectionHeight= fittingStrategy.distortionCalibrationData.eyesisCameraParameters.sensorHeight;
// int sensorCorrWidth= (this.pixelCorrectionWidth-1)/this.pixelCorrectionDecimation+1;
int maxChannel=0;
// int numVierws= this.patternParameters.getNumViews();
int numStations=this.patternParameters.getNumStations();
for (int numImg=0;numImg<fittingStrategy.distortionCalibrationData.gIP.length;numImg++) if (selectedImages[numImg]){
if (fittingStrategy.distortionCalibrationData.gIP[numImg].channel>maxChannel) maxChannel=fittingStrategy.distortionCalibrationData.gIP[numImg].channel;
......@@ -6638,6 +6706,7 @@ List calibration
int index=patternParameters.getGridIndex(pixelsUV[i][0], pixelsUV[i][1]);
bMask[index]=(pixelsXY[i][indexContrast]>=minContrast);
mask[index]=interpolateMask (
channel,
sensorMasks[channel],
pixelsXY[i][0],
pixelsXY[i][1]);
......@@ -6745,9 +6814,9 @@ List calibration
int chnNum,
double px,
double py){
int sensorCorrWidth= (this.pixelCorrectionWidth-1)/this.pixelCorrectionDecimation+1;
int indexXY=((int) Math.floor(px/this.pixelCorrectionDecimation)) +
((int) Math.floor(py/this.pixelCorrectionDecimation))*sensorCorrWidth;
int sensorCorrWidth= getSensorCorrWidth(chnNum);
int indexXY=((int) Math.floor(px/getDecimateMasks(chnNum))) +
((int) Math.floor(py/getDecimateMasks(chnNum)))*sensorCorrWidth;
double []vector=new double[this.pixelCorrection[chnNum].length];
for (int i=0;i<vector.length;i++) vector[i]=this.pixelCorrection[chnNum][i][indexXY];
return vector;
......@@ -7288,8 +7357,8 @@ List calibration
else {
masks[numSensor] = fittingStrategy.distortionCalibrationData.nonVignettedMask(
this.pixelCorrection[numSensor][maskIndex],
this.pixelCorrectionWidth,
this.pixelCorrectionHeight,
getSensorWidth(numSensor), // this.pixelCorrectionWidth,
getSensorHeight(numSensor), // this.pixelCorrectionHeight,
fittingStrategy.distortionCalibrationData.eyesisCameraParameters.eyesisSubCameras[0][numSensor].px0, // lens center X (sensor, non-decimated pix)
fittingStrategy.distortionCalibrationData.eyesisCameraParameters.eyesisSubCameras[0][numSensor].py0, // lens center Y (sensor, non-decimated pix)
shrink,
......@@ -8829,6 +8898,7 @@ M * V = B
* @return false if nothing to extrapolate (too small mask)?
*/
public boolean extrapolateSensorCorrection(
int numChn,
boolean [] whichExtrapolate,
double [][] fieldXY,
double []sMask,
......@@ -8836,9 +8906,9 @@ M * V = B
double nsigma,
double ksigma){
int decimate=fittingStrategy.distortionCalibrationData.eyesisCameraParameters.decimateMasks;
int sWidth= (fittingStrategy.distortionCalibrationData.eyesisCameraParameters.sensorWidth-1)/decimate+1;
int sHeight=(fittingStrategy.distortionCalibrationData.eyesisCameraParameters.sensorHeight-1)/decimate+1;
int decimate = getDecimateMasks(numChn);
int sWidth = (getSensorWidth(numChn)-1)/decimate+1;
int sHeight = (getSensorHeight(numChn)-1)/decimate+1;
double sigma=nsigma/decimate;
boolean [] fMask=new boolean[fieldXY[0].length];
for (int i=0;i<fMask.length;i++)
......@@ -9016,9 +9086,6 @@ M * V = B
int showIndividualNumber, // which image to show (-1 - all)
boolean useGridAlpha // use grid alpha, false - use old calculations
){
int decimate=distortionCalibrationData.eyesisCameraParameters.decimateMasks;
int sWidth= (distortionCalibrationData.eyesisCameraParameters.sensorWidth-1)/decimate+1;
int sHeight=(distortionCalibrationData.eyesisCameraParameters.sensorHeight-1)/decimate+1;
int numChannels=distortionCalibrationData.getNumChannels(); // number of used channels
int width=getGridWidth();
int height=getGridHeight();
......@@ -9042,6 +9109,11 @@ M * V = B
for (int imgNum=0;imgNum<selectedImages.length;imgNum++) if (selectedImages[imgNum]) {
if (debugExit) break;
int chnNum=fittingStrategy.distortionCalibrationData.gIP[imgNum].channel; // number of sub-camera
int decimate=getDecimateMasks(chnNum);
int sWidth= (getSensorWidth(chnNum)-1)/decimate+1;
int sHeight=(getSensorHeight(chnNum)-1)/decimate+1;
int station=fittingStrategy.distortionCalibrationData.gIP[imgNum].getStationNumber(); // number of sub-camera
double [][] photometrics=patternParameters.getPhotometricBySensor(station,chnNum); // head/bottom grid intensity/alpha
......@@ -9366,293 +9438,6 @@ M * V = B
return gridPCorr;
}
public double [][][] calculateSensorXYCorrOld(
DistortionCalibrationData distortionCalibrationData,
boolean showIndividual
){
int decimate=distortionCalibrationData.eyesisCameraParameters.decimateMasks;
int sWidth= (distortionCalibrationData.eyesisCameraParameters.sensorWidth-1)/decimate+1;
int sHeight=(distortionCalibrationData.eyesisCameraParameters.sensorHeight-1)/decimate+1;
int numChannels=distortionCalibrationData.getNumChannels(); // number of used channels
int width=getGridWidth();
int height=getGridHeight();
int [] uvInc={0,1,width,width+1}; // four corners as vu index
int [][] cycles={ // counter-clockwise corners bounding the area (only orthogonal sides?)
// {0,2,3,1}, //
{1,0,2},
{2,3,1},
{0,2,3},
{3,1,0}};
// prepare grid correction arrays
// if ((decimate!=)
// public double [][][] pixelCorrection=null;
// public int pixelCorrectionDecimation=1;
double [][][] gridPCorr=new double [numChannels][][];
for (int chnNum=0;chnNum<gridPCorr.length;chnNum++) gridPCorr[chnNum]=null;
boolean [] selectedImages=fittingStrategy.selectedImages();
boolean debugExit=false;
int debugCntr=2;
for (int imgNum=0;imgNum<selectedImages.length;imgNum++) if (selectedImages[imgNum]) {
if (debugExit) break;
int chnNum=fittingStrategy.distortionCalibrationData.gIP[imgNum].channel; // number of sub-camera
// initialize this array if it is needed, leave unused null
if (gridPCorr[chnNum]==null){
gridPCorr[chnNum]=new double [4][sWidth*sHeight];
for (int n=0;n<gridPCorr[chnNum].length;n++) for (int i=0;i<gridPCorr[chnNum][0].length;i++) gridPCorr[chnNum][n][i]=0.0;
}
double [][] thisPCorr=null;
thisPCorr=new double [4][sWidth*sHeight]; // calculate for a single (this) image, accumulate in the end
for (int n=0;n<thisPCorr.length;n++) for (int i=0;i<thisPCorr[0].length;i++) thisPCorr[n][i]=0.0;
double [] diff=calcYminusFx(this.currentfX);
// find data range for the selected image
int index=0;
int numImg=fittingStrategy.distortionCalibrationData.getNumImages();
for (int iNum=0;(iNum<imgNum) && (iNum<numImg) ;iNum++) if (selectedImages[iNum])
index+=fittingStrategy.distortionCalibrationData.gIP[iNum].pixelsUV.length;
if (this.debugLevel>2) {
System.out.println("calculateGridXYCorr(): fX.length="+this.currentfX.length+" this image index="+index);
}
double [][] imgData=new double[5][getGridHeight() * width]; // dPX, dPY, Px, Py, alpha
for (int i=0;i<imgData.length;i++) for (int j=0;j<imgData[i].length;j++)imgData[i][j]=0.0;
// first pass - prepare [v][u]arrays
double []mask= fittingStrategy.distortionCalibrationData.calculateImageGridMask(imgNum);
for (int i=0;i<fittingStrategy.distortionCalibrationData.gIP[imgNum].pixelsUV.length;i++){
int u=fittingStrategy.distortionCalibrationData.gIP[imgNum].pixelsUV[i][0]+patternParameters.U0;
int v=fittingStrategy.distortionCalibrationData.gIP[imgNum].pixelsUV[i][1]+patternParameters.V0;
int vu=u+width*v;
imgData[0][vu]= diff[2*(index+i)];
imgData[1][vu]= diff[2*(index+i)+1];
imgData[2][vu]= this.Y[2*(index+i)]; // measured pixel x
imgData[3][vu]= this.Y[2*(index+i)+1];// measured pixel y
// imgData[2][vu]= this.currentfX[2*(index+i)]; // calculated pixel x
// imgData[3][vu]= this.currentfX[2*(index+i)+1];// calculated pixel y
// next line not needed? - no, let it stay, 0.0 / >0 will be needed
// TODO: Use grid alpha
imgData[4][vu]= fittingStrategy.distortionCalibrationData.getMask(mask, imgData[2][vu], imgData[3][vu]); // will decimate
}
// now use imgData array to fill thisPCorr by linear interpolation
for (int v=0;v<(height-1); v++) for (int u=0; u<(width-1);u++){
if (debugExit) break;
int vu=u+width*v;
double [][] cornerXY =new double[4][];
for (int i=0;i<uvInc.length;i++){
int vu1=vu+uvInc[i];
if (imgData[4][vu1]>0.0){
cornerXY[i]=new double[2];
cornerXY[i][0]=imgData[2][vu1];
cornerXY[i][1]=imgData[3][vu1];
} else cornerXY[i]=null;
}
boolean [] cycleFits=new boolean[cycles.length];
boolean anyFits=false;
for (int i=0;i<cycles.length;i++){
cycleFits[i]=true;
for (int j=0;j<cycles[i].length;j++) if (cornerXY[cycles[i][j]]==null) {
cycleFits[i]=false;
break;
}
}
if (!anyFits) continue; // not a single cycle
if ((this.debugLevel>3) && !debugExit) {
String debugString="cycleFits ";
for (int i =0;i<cycleFits.length; i++) debugString+=" "+cycleFits[i];
System.out.println(debugString);
}
if (cycleFits[0]&&cycleFits[1]){ // remove overlaps
cycleFits[2]=false;
cycleFits[3]=false;
}
boolean minMaxUndefined=true;
double minX=0,maxX=0,minY=0,maxY=0;
// find bounding rectangle;
for (int nCycle=0;nCycle<cycles.length;nCycle++) if (cycleFits[nCycle]){
int [] cycle=cycles[nCycle];
for (int corner=0; corner<cycle.length;corner++){
if (minMaxUndefined || (minX>cornerXY[cycle[corner]][0])) minX=cornerXY[cycle[corner]][0];
if (minMaxUndefined || (maxX<cornerXY[cycle[corner]][0])) maxX=cornerXY[cycle[corner]][0];
if (minMaxUndefined || (minY>cornerXY[cycle[corner]][1])) minY=cornerXY[cycle[corner]][1];
if (minMaxUndefined || (maxY<cornerXY[cycle[corner]][1])) maxY=cornerXY[cycle[corner]][1];
minMaxUndefined=false;
}
}
int iMinX=(int) Math.floor(minX/decimate);
int iMinY=(int) Math.floor(minY/decimate);
int iMaxX=(int) Math.ceil(maxX/decimate);
int iMaxY=(int) Math.ceil(maxY/decimate);
double [] originXY=new double [2];
double [] endXY=new double [2];
boolean debugHadPixels=false;
//TODO: scan X,Y in this rectangle, for points in defined squares/triangles find if the point is inside (accurate not to loose any).
for (int idY=iMinY; idY<=iMaxY;idY++){
double pY=idY*decimate; // in sensor pixels
for (int idX=iMinX; idX<=iMaxX;idX++){
double pX=idX*decimate; // in sensor pixels
// scan allowed triangles, usually 2
for (int nCycle=0;nCycle<cycles.length;nCycle++) if (cycleFits[nCycle]){
int [] cycle=cycles[nCycle];
// is this point inside?
if (debugExit) {
for (int nEdge=0;nEdge<cycle.length;nEdge++){
int nextNEdge=(nEdge==(cycle.length-1))?0:(nEdge+1);
System.out.println("nEdge="+nEdge+" nextNEdge"+nextNEdge);
originXY[0]=imgData[2][vu+uvInc[cycle[nEdge]]];
originXY[1]=imgData[3][vu+uvInc[cycle[nEdge]]];
endXY[0]= imgData[2][vu+uvInc[cycle[nextNEdge]]];
endXY[1]= imgData[3][vu+uvInc[cycle[nextNEdge]]];
System.out.println("--- pX="+IJ.d2s(pX,1)+" originXY[0]="+IJ.d2s(originXY[0],1)+
" endXY[1]="+IJ.d2s(endXY[1],1)+" originXY[1]="+IJ.d2s(originXY[1],1));
System.out.println("--- pY="+IJ.d2s(pY,1)+" originXY[1]="+IJ.d2s(originXY[1],1)+
" endXY[0]="+IJ.d2s(endXY[0],1)+" originXY[0]="+IJ.d2s(originXY[0],1));
System.out.println("Cross-product="+IJ.d2s(((pX-originXY[0])*(endXY[1]-originXY[1]) - (pY-originXY[1])*(endXY[0]-originXY[0])),1));
}
}
boolean inside=true;
for (int nEdge=0;nEdge<cycle.length;nEdge++){
int nextNEdge=(nEdge==(cycle.length-1))?0:(nEdge+1);
originXY[0]=imgData[2][vu+uvInc[cycle[nEdge]]];
originXY[1]=imgData[3][vu+uvInc[cycle[nEdge]]];
endXY[0]= imgData[2][vu+uvInc[cycle[nextNEdge]]];
endXY[1]= imgData[3][vu+uvInc[cycle[nextNEdge]]];
if (((pX-originXY[0])*(endXY[1]-originXY[1]) - (pY-originXY[1])*(endXY[0]-originXY[0]))<0.0){
inside=false;
break;
}
}
if (!inside) continue; // point is outside of the interpolation area, try next triangle (if any)
// if ((this.debugLevel>3) && !debugExit) {
if (this.debugLevel>3) {
System.out.println("idX="+idX+" idY="+idY+" nCycle="+nCycle);
String debugString1="cycle:";
for (int i =0;i<cycle.length; i++) debugString1+=" "+cycle[i];
System.out.println(debugString1);
}
/* interpolate:
1. taking cycles[0] as origin and two (non co-linear) edge vectors - V1:from 0 to 1 and V2 from 1 to 2
find a1 and a2 so that vector V (from 0 to pXY) = a1*V1+ a2*V2
2. if F0 is the value of the interpolated function at cycles[0], F1 and F2 - at cycles[1] and cycles2
then F=F0+(F1-F0)*a1 +(F2-F1)*a2
*/
double [] XY0={imgData[2][vu+uvInc[cycle[0]]],imgData[3][vu+uvInc[cycle[0]]]};
double [] XY1={imgData[2][vu+uvInc[cycle[1]]],imgData[3][vu+uvInc[cycle[1]]]};
double [] XY2={imgData[2][vu+uvInc[cycle[2]]],imgData[3][vu+uvInc[cycle[2]]]};
double [] V= {pX-XY0[0],pY-XY0[1]};
double [][] M={
{XY1[0]-XY0[0],XY2[0]-XY1[0]},
{XY1[1]-XY0[1],XY2[1]-XY1[1]}};
double det=M[0][0]*M[1][1]-M[1][0]*M[0][1];
double [][] MInverse={
{ M[1][1]/det,-M[0][1]/det},
{-M[1][0]/det, M[0][0]/det}};
double [] a12={
MInverse[0][0]*V[0]+MInverse[0][1]*V[1],
MInverse[1][0]*V[0]+MInverse[1][1]*V[1]};
int pCorrIndex=idY*sWidth+idX;
// some points may be accumulated multiple times - thisPCorr[3] will take care of this
if (this.debugLevel>3) {
System.out.println("XY0="+IJ.d2s(XY0[0],3)+":"+IJ.d2s(XY0[1],3));
System.out.println("XY1="+IJ.d2s(XY1[0],3)+":"+IJ.d2s(XY1[1],3));
System.out.println("XY2="+IJ.d2s(XY2[0],3)+":"+IJ.d2s(XY2[1],3));
System.out.println("M00="+IJ.d2s(M[0][0],3)+" M01="+IJ.d2s(M[0][1],3));
System.out.println("M10="+IJ.d2s(M[1][0],3)+" M11="+IJ.d2s(M[1][1],3));
System.out.println("MInverse00="+IJ.d2s(MInverse[0][0],5)+" MInverse01="+IJ.d2s(MInverse[0][1],5));
System.out.println("MInverse10="+IJ.d2s(MInverse[1][0],5)+" MInverse11="+IJ.d2s(MInverse[1][1],5));
System.out.println("a12="+IJ.d2s(a12[0],3)+":"+IJ.d2s(a12[1],3));
System.out.println("imgData[0][vu+uvInc[cycle[0]]]="+IJ.d2s(imgData[0][vu+uvInc[cycle[0]]],3)+
"imgData[1][vu+uvInc[cycle[0]]]="+IJ.d2s(imgData[1][vu+uvInc[cycle[0]]],3));
System.out.println("imgData[0][vu+uvInc[cycle[1]]]="+IJ.d2s(imgData[0][vu+uvInc[cycle[1]]],3)+
"imgData[1][vu+uvInc[cycle[1]]]="+IJ.d2s(imgData[1][vu+uvInc[cycle[1]]],3));
System.out.println("imgData[0][vu+uvInc[cycle[2]]]="+IJ.d2s(imgData[0][vu+uvInc[cycle[2]]],3)+
"imgData[1][vu+uvInc[cycle[2]]]="+IJ.d2s(imgData[1][vu+uvInc[cycle[2]]],3));
}
double [] corr={
imgData[0][vu+uvInc[cycle[0]]]+ // dPx
(imgData[0][vu+uvInc[cycle[1]]]-imgData[0][vu+uvInc[cycle[0]]])*a12[0]+
(imgData[0][vu+uvInc[cycle[2]]]-imgData[0][vu+uvInc[cycle[1]]])*a12[1],
imgData[1][vu+uvInc[cycle[0]]]+ // dPy
(imgData[1][vu+uvInc[cycle[1]]]-imgData[1][vu+uvInc[cycle[0]]])*a12[0]+
(imgData[1][vu+uvInc[cycle[2]]]-imgData[1][vu+uvInc[cycle[1]]])*a12[1],
imgData[4][vu+uvInc[cycle[0]]]+ // alpha
(imgData[4][vu+uvInc[cycle[1]]]-imgData[4][vu+uvInc[cycle[0]]])*a12[0]+
(imgData[4][vu+uvInc[cycle[2]]]-imgData[4][vu+uvInc[cycle[1]]])*a12[1]};
if (this.debugLevel>3) {
System.out.println("corr="+IJ.d2s(corr[0],3)+" "+IJ.d2s(corr[1],3)+" "+IJ.d2s(corr[2],3));
}
thisPCorr[0][pCorrIndex]+= corr[0];// dPx
thisPCorr[1][pCorrIndex]+= corr[1];// dPy
thisPCorr[2][pCorrIndex]+= corr[2];// alpha
thisPCorr[3][pCorrIndex]+= 1.0; // number of times accumulated
if (this.debugLevel>3) {
debugHadPixels=true;
// if (!debugExit) debugCntr--;
// if (debugCntr==0) debugExit=true; // exit after first non-empty tile
}
//gridPCorr[chnNum]
}
} // idX
// use same order in calculations, make sure no gaps
} // idY
if ((this.debugLevel>3) && (debugHadPixels)){
if (!debugExit) {
System.out.println(
" minX="+IJ.d2s(minX,1)+
" maxX="+IJ.d2s(maxX,1));
System.out.println(
" minY="+IJ.d2s(minY,1)+
" maxY="+IJ.d2s(maxY,1));
System.out.println(
" iMinX="+iMinX+
" iMaxX="+iMaxX);
System.out.println(
" iMinY="+iMinY+
" iMaxY="+iMaxY);
}
if (!debugExit) debugCntr--;
if (debugCntr==0) debugExit=true; // exit after first non-empty tile
}
} // finished image
// some points may be calculated multiple times
for (int i=0;i<gridPCorr[chnNum][0].length;i++) if (thisPCorr[3][i]>=1.0){
thisPCorr[0][i]/=thisPCorr[3][i];
thisPCorr[1][i]/=thisPCorr[3][i];
thisPCorr[2][i]/=thisPCorr[3][i];
}
if (showIndividual) {
String [] titles={"dPx","dPy","alpha","Multiple"};
this.SDFA_INSTANCE.showArrays(thisPCorr, sWidth, sHeight, true, "thisPCorr"+imgNum, titles);
}
for (int i=0;i<gridPCorr[chnNum][0].length;i++) if (thisPCorr[2][i]>0){
gridPCorr[chnNum][0][i]+=thisPCorr[0][i]*thisPCorr[2][i];
gridPCorr[chnNum][1][i]+=thisPCorr[1][i]*thisPCorr[2][i];
/**TODO: not used anyway - just for debugging? see if just the sensor mask should go here? Or when saving?*/
if (gridPCorr[chnNum][2][i]<thisPCorr[2][i]) gridPCorr[chnNum][2][i]=thisPCorr[2][i]; // best alpha
gridPCorr[chnNum][3][i]+= thisPCorr[2][i]; // sum of weights from all images
}
}
for (int chnNum=0;chnNum<gridPCorr.length;chnNum++){
for (int i=0;i<gridPCorr[chnNum][0].length;i++) if (gridPCorr[chnNum][2][i]>0){ //null pointer
gridPCorr[chnNum][0][i]/=gridPCorr[chnNum][3][i];
gridPCorr[chnNum][1][i]/=gridPCorr[chnNum][3][i];
}
}
return gridPCorr;
}
/**
* Calculate partial derivative analytically (as the Jacobian calculation) and by difference divided by delta and compare
* Done to debug derivatives calculation
......
......@@ -37,7 +37,6 @@ import java.util.Set;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.XMLConfiguration;
import com.elphel.imagej.calibration.CalibrationFileManagement.MultipleExtensionsFileFilter;
import com.elphel.imagej.common.WindowTools;
import ij.IJ;
......@@ -1627,6 +1626,16 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
"Image sets, start from empty selection", // 5
"Image sets, start from current selection" // 6
};
String help = "<html>"+
"<h2>Use of buttons in this dialog:</h2>"+
"<ul>"+
"<li><b>More</b> will re-open dialog after performin selection modification actions,"+
" in case of selecting individual images that may happen after multiple selection "+
"screens</li>"+
"<li><b>Cancel</b> - keep current selection that you do not want to modify further"+
" (e.g. if you wrongly pressed 'More' in this dialog earlier)</li>"+
"<li><b>OK</b> - perform selection modification once (same as 'More'...'Cancel')</li>"+
"</ul><br/>";
int numStations=this.distortionCalibrationData.eyesisCameraParameters.getNumStations();
int numChannels=this.distortionCalibrationData.eyesisCameraParameters.getNumChannels(0); // for station 0
boolean [] selected= this.selectedImages[numSeries];
......@@ -1833,6 +1842,11 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
//selectionType
// 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.addCheckbox("Select high-res sensors", true);
gd.addCheckbox("Select low-res sensors", true);
}
gd.addMessage("=== Filter selection by the number of matched laser pointers ===");
for (int i=0;i<matchedPointersIndex.length;i++){
gd.addCheckbox("Select images with "+matchedPointersIndex[i]+" pointers", requiredMatchedPointers[i]);
......@@ -1850,14 +1864,21 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
gd.addCheckbox("Select channel "+i, requiredChannels[i]);
}
gd.enableYesNoCancel("OK", "More");
gd.addHelp(help);
WindowTools.addScrollBars(gd);
gd.showDialog();
if (gd.wasCanceled()) return -1;
boolean more=!gd.wasOKed();
System.out.println("manageSelection(): more=!gd.wasOKed() = "+more);
operIndex=gd.getNextChoiceIndex();
selectionTypeIndex=gd.getNextChoiceIndex(); // TODO:Implement!
// selectEstimated=gd.getNextBoolean();
// selectNewEnabled=gd.getNextBoolean();
boolean [] selectHiLowRes = null;
if (this.distortionCalibrationData.hasSmallSensors()) {
selectHiLowRes = new boolean[2];
selectHiLowRes[0] = gd.getNextBoolean(); // gd.addCheckbox("Select high-res sensors", true);
selectHiLowRes[1] = gd.getNextBoolean(); // gd.addCheckbox("Select low-res sensors", true);
}
for (int i=0;i<matchedPointersIndex.length;i++) requiredMatchedPointers[i]=gd.getNextBoolean();
for (int i=0;i<hintedMatchIndex.length;i++) requiredHintedMatch[i]= gd.getNextBoolean();
for (int i=0;i<requiredStations.length;i++) requiredStations[i]=gd.getNextBoolean();
......@@ -1882,6 +1903,7 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
false, // allImages,
0, // star iIndex
500)) return -1; //perPage))
break;
case 6: // start from current selection
selection=selected.clone();
break;
......@@ -1899,9 +1921,19 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
for (int i=0;i<selection.length;i++) if (imageStations[i]>=0) selection[i] &= requiredStations[imageStations[i]];
else selection[i] = false;
if (selectHiLowRes != null) {
boolean [] lowres_channel = this.distortionCalibrationData.getSmallSensors();
for (int i =0; i < requiredChannels.length;i++) {
if ((lowres_channel[i] && !selectHiLowRes[1]) ||(!lowres_channel[i] && !selectHiLowRes[0])) {
requiredChannels[i] = false;
}
}
}
for (int i=0;i<selection.length;i++) if (imageChannels[i]>=0) selection[i] &= requiredChannels[imageChannels[i]];
else selection[i] = false;
// now combine new/old selections
switch (operIndex){
case 0: // keep new selection
......@@ -1926,6 +1958,7 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
for (int i=0;i<selection.length;i++) selection[i] &= enabled[i];
// replace current selection
this.selectedImages[numSeries]=selection;
System.out.println("manageSelection(): on exit more = "+more);
return more?0:1;
}
/**
......@@ -1936,21 +1969,8 @@ 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
* @return -2 - cancel, -1, done, otherwise - number of step to edit
public int selectStrategyStep(
int numSeries,
boolean useImages,
int [] fromToImages,
boolean allImages,
boolean useParameters,
boolean askLambdas,
boolean askNextSeries,
boolean zeroAndOther
){
GenericDialog gd = new GenericDialog("Fitting Strategy Step Configuration, step "+numSeries+
" number of enabled images="+this.distortionCalibrationData.getNumEnabled());
gd.addStringField ("Comment", this.strategyComment[numSeries],80);
*/
public void listStrategies() {
......@@ -2117,9 +2137,15 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
for (int i=0;i<constrainByStation.length;i++) constrainByStation[i]=true;
if (this.distortionCalibrationData.eyesisCameraParameters.numStations>1){
gd.addMessage("Constrain by stations");
// gd.addCheckbox("Remove images of unselected stations below", true);
for (int i=0;i<this.distortionCalibrationData.eyesisCameraParameters.numStations;i++) gd.addCheckbox("Station "+i, constrainByStation[i]);
}
if (this.distortionCalibrationData.hasSmallSensors()) {
gd.addMessage("Constrain by High/Low resolution sensors (such as VNIR/LWIR)");
gd.addCheckbox("Select high-res sensors", true);
gd.addCheckbox("Select low-res sensors", true);
}
if (useImages) {
gd.addNumericField("Image selection range, from", fromToImages[0], 0);
......@@ -2141,7 +2167,6 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
}
if (useParameters) {
// choice_offsets = new int [this.parameterEnable.length];
gd.addMessage("Select parameters to fit");
for (int i =0; i<this.parameterEnable.length;i++) if (this.parameterEnable[i] &&
(!zeroAndOther || (this.parameterList[i][0] <= 1) || (this.parameterList[i][0] ==24))){ // in "zeroAndOther" mode do not show other subcameras
......@@ -2159,18 +2184,14 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
) { // both subcameras are "other" subcameras
double parValue=this.distortionCalibrationData.getParameterValue(imgNumber,parIndex);
if (!defined) {
// min=this.distortionCalibrationData.pars[imgNumber][parIndex];
min=parValue;
max=min;
defined=true;
}
// if (this.distortionCalibrationData.pars[imgNumber][parIndex]<min) min=this.distortionCalibrationData.pars[imgNumber][parIndex];
// if (this.distortionCalibrationData.pars[imgNumber][parIndex]>max) max=this.distortionCalibrationData.pars[imgNumber][parIndex];
if (parValue<min) min=parValue;
if (parValue>max) max=parValue;
}
}
// System.out.println(i+": "+parIndex+":"+subCam+"defined="+defined+" min="+min+" max="+max);
// undefined, min, max
String sValue=(defined)?((min==max)?(min+""):(min+"..."+max)):"undefined";
String sChn=(zeroAndOther && (subCam>=1)&& (subCam<24))?"-head-other":
......@@ -2263,8 +2284,9 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
showAdvancedImageSelection=gd.getNextBoolean();
if (showAdvancedImageSelection){
int rslt=0;
while (rslt==0) rslt=manageSelection(numSeries);
// return (rslt<0)?-2:numSeries;
while (rslt==0) {
rslt=manageSelection(numSeries);
}
return numSeries; // cancel from manageSelection will just exit that mode with no changes
}
boolean copyFromPrevious=gd.getNextBoolean();
......@@ -2276,9 +2298,15 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
boolean selectNewEnabled=false;
if (numNewEnabled>0) selectNewEnabled=gd.getNextBoolean();
if (this.distortionCalibrationData.eyesisCameraParameters.numStations>1){
// boolean removeUnselectedStations=gd.getNextBoolean();
for (int i=0;i<constrainByStation.length; i++) constrainByStation[i]=gd.getNextBoolean();
}
boolean [] selectHiLowRes = null;
if (this.distortionCalibrationData.hasSmallSensors()) {
selectHiLowRes = new boolean[2];
selectHiLowRes[0] = gd.getNextBoolean(); // gd.addCheckbox("Select high-res sensors", true);
selectHiLowRes[1] = gd.getNextBoolean(); // gd.addCheckbox("Select low-res sensors", true);
}
if (selectNewEnabled) {
this.selectedImages[numSeries]=this.distortionCalibrationData.selectNewEnabled();
for (int i =0; i<this.distortionCalibrationData.getNumImages();i++){
......@@ -2308,9 +2336,7 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
return numSeries; // caller will repeat with the same series
}
if (removeAllImages || selectAllImages) {
//
for (int i =0; i<this.distortionCalibrationData.getNumImages();i++){
// this.selectedImages[numSeries][i]=false; // invalidate - all, regardless of .enabled
this.selectedImages[numSeries][i]=selectAllImages || ((i==0) && removeAllImages); // invalidate - all, regardless of .enabled
this.selectedImages[numSeries][i]&=constrainByStation[this.distortionCalibrationData.gIP[i].getStationNumber()];
}
......@@ -2329,6 +2355,15 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
if (this.masterImages[numSeries]<0)this.masterImages[numSeries]=0;
if (this.masterImages[numSeries]>=this.selectedImages[numSeries].length)this.masterImages[numSeries]=this.selectedImages[numSeries].length;
}
if (selectHiLowRes != null) {
for (int i =0; i<this.distortionCalibrationData.getNumImages();i++) {
boolean low_res = this.distortionCalibrationData.isSmallSensor(i);
if ((low_res && !selectHiLowRes[1]) && (!low_res && !selectHiLowRes[0])){
this.selectedImages[numSeries][i]= false;
}
}
}
if (useParameters) {
int [] lastGroups=null;
for (int i =0; i<this.parameterEnable.length;i++) if (this.parameterEnable[i] &&
......
package com.elphel.imagej.calibration;
import java.awt.Rectangle;
import java.util.Properties;
import com.elphel.imagej.jp4.JP46_Reader_camera;
/*
**
** PatternParameters.java
......@@ -6,7 +11,7 @@ package com.elphel.imagej.calibration;
** Copyright (C) 2011-2014 Elphel, Inc.
**
** -----------------------------------------------------------------------------**
**
**
** PatternParameters.java is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
......@@ -28,16 +33,10 @@ import ij.ImageStack;
import ij.gui.GenericDialog;
import ij.io.FileSaver;
import ij.io.Opener;
import java.awt.Rectangle;
import java.util.Properties;
import com.elphel.imagej.calibration.CalibrationFileManagement.MultipleExtensionsFileFilter;
import com.elphel.imagej.jp4.JP46_Reader_camera;
/* gridGeometry:
* [v][u][0] - x(mm) of the node(u,v), right (looking to the wall) - positive
* [v][u][1] - y(mm) of the node(u,v), down - positive
* [v][u][2] - z(mm) of the node(u,v), away (into the wall) - positive
* [v][u][1] - y(mm) of the node(u,v), down - positive
* [v][u][2] - z(mm) of the node(u,v), away (into the wall) - positive
* [v][u][3] - mask 0.0 - outside of the pattern rectangle, 1.0 - on the pattern
* RGB moved to Photometric
* [v][u][4] - R-intensity (normalized to 1.0 full scale)
......@@ -54,8 +53,8 @@ import com.elphel.imagej.jp4.JP46_Reader_camera;
public int numStations=1;
public int numberOfViews=1;
public double [][][] gridGeometry=null; // [v][u]{x,y,z,{"alpha", R-intensity, G--intensity, B--intensity} alpha=0 - no ghrid, 1 - grid}
public double [][][] stationZCorr=null; // [v][u]{station0... stationN} - per-station addition to the gridGeometry[][][2]
public double [] averageRGB={1.0,1.0,1.0};
public double [][][] stationZCorr=null; // [v][u]{station0... stationN} - per-station addition to the gridGeometry[][][2]
public double [] averageRGB={1.0,1.0,1.0};
public int numGeometricChannels=4; // x,y,z,mask
public int numPhotometricChannels=4; // r,g,b,a
public int defaultNumberOfChannels=26;
......@@ -71,7 +70,7 @@ import com.elphel.imagej.jp4.JP46_Reader_camera;
public double [] patternErrors=null; // weighted RMS error for each pattern node, calculated
public double [] patternErrorMask=null; // weighted RMS error for each pattern node, calculated
public double [] patternErrorMaskSaved=null; // weighted RMS error for each pattern node, calculated
public void initStationZCorr(){
this.stationZCorr=new double [this.gridGeometry.length][this.gridGeometry[0].length][this.numStations];
for (int v=0;v<this.stationZCorr.length;v++) for (int u=0;u<this.stationZCorr[0].length;u++) for (int s=0;s<this.stationZCorr[0][0].length;s++){
......@@ -97,7 +96,7 @@ import com.elphel.imagej.jp4.JP46_Reader_camera;
double [] mask=new double [this.patternErrors.length]; // null pointer
double a=1.0/(maxRMS-minRMS);
boolean binary=maxRMS==minRMS;
for (int i=0;i<this.patternErrors.length;i++){
if (Double.isNaN(this.patternErrors[i])) mask[i]=0.0;
else {
......@@ -184,7 +183,7 @@ import com.elphel.imagej.jp4.JP46_Reader_camera;
this.photometricByView[i][j][k]=null;
} else {
this.photometricByView[i][j][k]=photometricByViewCopy[iSource][j][k].clone();
}
}
}
}
}
......@@ -214,7 +213,7 @@ import com.elphel.imagej.jp4.JP46_Reader_camera;
for (int i=0;i<num;i++) this.viewMap[i]=(i<24)?0:1;
this.numberOfViews=2;
}
public double [][] getPhotometricByView(int stationNumber, int nView){
if (stationNumber>=this.photometricByView.length) stationNumber=this.photometricByView.length-1;
if (nView>=this.photometricByView[stationNumber].length) nView=this.photometricByView[stationNumber].length-1;
......@@ -240,7 +239,7 @@ import com.elphel.imagej.jp4.JP46_Reader_camera;
public int getNumStations(){return this.numStations;}
public void setNumStations(int numStations){this.numStations=numStations;}
public int [] getViewMap(){return this.viewMap;}
public int getNumGeometricChannels(){return this.numGeometricChannels;}
public int getNumPhotometricChannels(){return this.numPhotometricChannels;}
......@@ -260,6 +259,7 @@ import com.elphel.imagej.jp4.JP46_Reader_camera;
setPhotometric(viewMap);
calculateGridGeometryAndPhotometric(true);
}
@Override
public PatternParameters clone() {
PatternParameters patternParameters= new PatternParameters(
this.viewMap,
......@@ -282,12 +282,12 @@ import com.elphel.imagej.jp4.JP46_Reader_camera;
fs.saveAsTiffStack(path);
else
fs.saveAsTiff(path);
this.pathName=path;
if (this.debugLevel>0) System.out.println("Pattern saved as "+this.pathName);
return imp;
}
public String selectAndSave(boolean smart, String defaultPath){
String [] extensions={".grid-tiff","-grid.tiff"};
CalibrationFileManagement.MultipleExtensionsFileFilter parFilter = new CalibrationFileManagement.MultipleExtensionsFileFilter("",extensions,"Pattern grid *.grid-tiff files");
......@@ -302,7 +302,7 @@ import com.elphel.imagej.jp4.JP46_Reader_camera;
return pathname;
}
public String selectAndRestore(boolean smart, String defaultPath, int numStations){
String [] extensions={".grid-tiff","-grid.tiff"};
CalibrationFileManagement.MultipleExtensionsFileFilter parFilter = new CalibrationFileManagement.MultipleExtensionsFileFilter("",extensions,"Pattern grid *.grid-tiff files");
......@@ -354,14 +354,14 @@ import com.elphel.imagej.jp4.JP46_Reader_camera;
IJ.showMessage("Error",msg);
throw new IllegalArgumentException (msg);
}
this.U0=Integer.parseInt((String) imp.getProperty("U0"));
this.U0=Integer.parseInt((String) imp.getProperty("U0"));
this.V0=Integer.parseInt((String) imp.getProperty("V0"));
// Other properties that are needed only during pattern generation:
if (imp.getProperty("patternWidth")!=null) this.patternWidth=Double.parseDouble((String) imp.getProperty("patternWidth"));
if (imp.getProperty("patternHeight")!=null) this.patternHeight=Double.parseDouble((String) imp.getProperty("patternHeight"));
if (imp.getProperty("patternHalfPeriod")!=null) this.patternHalfPeriod=Double.parseDouble((String) imp.getProperty("patternHalfPeriod"));
if (imp.getProperty("patternTilt")!=null) this.patternTilt=Double.parseDouble((String) imp.getProperty("patternTilt"));
if (imp.getProperty("AverageRed")!=null) this.averageRGB[0]=Double.parseDouble((String) imp.getProperty("AverageRed"));
if (imp.getProperty("AverageGreen")!=null) this.averageRGB[1]=Double.parseDouble((String) imp.getProperty("AverageGreen"));
if (imp.getProperty("AverageBlue")!=null) this.averageRGB[2]=Double.parseDouble((String) imp.getProperty("AverageBlue"));
......@@ -369,7 +369,7 @@ import com.elphel.imagej.jp4.JP46_Reader_camera;
if (imp.getProperty("numZCorr")!=null) numZCorr=Integer.parseInt((String) imp.getProperty("numZCorr"));
// if (imp.getProperty("numStations")!=null) this.numStations=Integer.parseInt((String) imp.getProperty("numStations"));
int width=imp.getWidth();
int height=imp.getHeight();
ImageStack stack = imp.getStack();
......@@ -384,8 +384,8 @@ import com.elphel.imagej.jp4.JP46_Reader_camera;
System.out.println("setGridFromImageStack() width="+width+", height="+height+", pixels[0].length="+pixels[0].length);
}
this.gridGeometry=new double[height][width][getNumGeometricChannels()]; // x,y,z, alpha
boolean geometryMaskOnly=(pixels.length==getNumGeometricChannels());
boolean singleNoAlpha=(pixels.length==7);
int totalNumViews=(geometryMaskOnly || singleNoAlpha)?1:((pixels.length-getNumGeometricChannels()-numZCorr)/getNumPhotometricChannels());
......@@ -394,7 +394,7 @@ import com.elphel.imagej.jp4.JP46_Reader_camera;
for (int v=0;v<height;v++) for (int u=0;u<width;u++) for (int n=0;n<getNumGeometricChannels();n++){ // x,y,z, alpha
this.gridGeometry[v][u][n]=pixels[n][v*width+u];
}
if (fileNumStations!=getNumStations()){
if (this.debugLevel>0){
System.out.println("File has "+totalNumViews+" photometric slices, expected "+(getNumStations()*getNumViews())+
......@@ -415,16 +415,16 @@ import com.elphel.imagej.jp4.JP46_Reader_camera;
} else {
System.out.println("File has "+numZCorr+" ZCorr slices, current number of stations is "+getNumStations()+
", skipping loading zCorr data (per-station pattern Z-correction from the average Z)");
}
}
if (this.debugLevel>0){
System.out.println("Loading photometric data: "+(getNumStations()*getNumViews())+" slices "+
" ("+getNumStations()+" stations, "+getNumViews()+" vies )");
}
this.photometricByView=new double [this.numStations][this.numberOfViews][getNumPhotometricChannels()][length]; // r,g,b,a
for (int numStation=0;numStation<this.numStations;numStation++) {
int useNumStation=numStation;
......@@ -444,9 +444,9 @@ import com.elphel.imagej.jp4.JP46_Reader_camera;
}
}
}
}
}
}
//getNumPhotometricChannels()
//getNumPhotometricChannels()
public ImagePlus getGridAsImageStack(String title){
if (this.gridGeometry==null){
String msg="Grid geometry does not exist, nothing to convert";
......@@ -470,7 +470,7 @@ import com.elphel.imagej.jp4.JP46_Reader_camera;
String [] zCorrTitles=new String [numZCorr];
for (int i=0;i<numZCorr;i++) zCorrTitles[i]="dZ"+i;
String [] photometricTitles={"red","green","blue","alpha"};
int index=0;
for (int v=0;v<height;v++) for (int u=0;u<width;u++){
for (int n=0;n<getNumGeometricChannels();n++) { // should be 4==numGeometricChannels
......@@ -513,7 +513,7 @@ import com.elphel.imagej.jp4.JP46_Reader_camera;
imp.getProcessor().resetMinAndMax();
return imp;
}
public void applyGridCorrection(double [][] gridCorr){
applyGridCorrection(gridCorr, 1.0);
}
......@@ -542,7 +542,7 @@ import com.elphel.imagej.jp4.JP46_Reader_camera;
}
}
public void applyZGridCorrection(
double [][] gridZCorr3d,
double scale){
......@@ -562,7 +562,7 @@ import com.elphel.imagej.jp4.JP46_Reader_camera;
}
}
public void setProperties(String prefix,Properties properties){
properties.setProperty(prefix+"patternWidth",this.patternWidth+"");
properties.setProperty(prefix+"patternHeight",this.patternHeight+"");
......@@ -609,14 +609,16 @@ import com.elphel.imagej.jp4.JP46_Reader_camera;
GenericDialog gd = new GenericDialog("Initial Wall pattern parameters");
gd.addNumericField("Pattern full width", this.patternWidth, 1,6,"mm"); // pattern full width in mm
gd.addNumericField("Pattern full height", this.patternHeight, 1,6,"mm"); // pattern full width in mm
gd.addNumericField("Distance between opposite sign nodes",this.patternHalfPeriod, 4,8,"mm"); // istance between opposite sign nodes in mm
gd.addNumericField("Pattern tilt (clockwise)", this.patternTilt, 1,5,"degrees"); // pattern tilt (degrees) - U clockwise from X-right (V clockwise from Y-down)
gd.addNumericField("Distance between opposite sign nodes",this.patternHalfPeriod, 4,8,"mm"); // distance between opposite sign nodes in mm
gd.addNumericField("Pattern tilt (clockwise)", this.patternTilt, 3,8,"degrees"); // pattern tilt (degrees) - U clockwise from X-right (V clockwise from Y-down)
gd.addNumericField("Average grid RED (1.0 for white)", this.averageRGB[0], 3,5,"x"); //
gd.addNumericField("Average grid GREEN (1.0 for white)", this.averageRGB[1], 3,5,"x"); //
gd.addNumericField("Average grid BLUE (1.0 for white)", this.averageRGB[2], 3,5,"x"); //
gd.addNumericField("Number of sensors (>24 - two groups, 0 - do not change)",this.defaultNumberOfChannels,0); //
gd.addCheckbox("Reset to standard fine pitch pattern" , false);
gd.addCheckbox("Reset to standard LWIR pattern" , false);
gd.addMessage("Pressing OK will recalculate grid and clear current grid calibration");
gd.showDialog();
if (gd.wasCanceled()) return false;
......@@ -628,7 +630,28 @@ import com.elphel.imagej.jp4.JP46_Reader_camera;
this.averageRGB[1]= gd.getNextNumber();
this.averageRGB[2]= gd.getNextNumber();
int numberOfChannels= (int)gd.getNextNumber();
boolean use_fine_pattern = gd.getNextBoolean();
boolean use_lwir_pattern = gd.getNextBoolean();
if (use_fine_pattern) {
this.patternWidth= 7010.0;
this.patternHeight= 3073.0;
this.patternHalfPeriod= 41.57;
this.patternTilt= 5.0;
this.averageRGB[0]= 1.0;
this.averageRGB[1]= 1.0;
this.averageRGB[2]= 1.0;
} else if (use_lwir_pattern) {
this.patternWidth= 7010.0; // 7192.0
this.patternHeight= 2997.2;
this.patternHalfPeriod= 178.65;
this.patternTilt= 14.036;
this.averageRGB[0]= 1.0;
this.averageRGB[1]= 1.0;
this.averageRGB[2]= 1.0;
}
if (numberOfChannels>0){
initDefaultChannels(numberOfChannels);
// setPhotometric();
......@@ -642,7 +665,7 @@ import com.elphel.imagej.jp4.JP46_Reader_camera;
* @param resetAll - if true - reset all grid info, if false - only recalculate mask and reset flat field info, keep distortions
*/
public void calculateGridGeometryAndPhotometric(boolean resetAll){
// this.photometricByView should be initialized
// this.photometricByView should be initialized
int indexAlpha=3;
int indexMask=3;
double cosA=Math.cos(this.patternTilt/180*Math.PI);
......@@ -704,10 +727,10 @@ import com.elphel.imagej.jp4.JP46_Reader_camera;
}
}
index++;
}
}
}
public int [] uvIndicesToUV (int u1, int v1){
if ((v1<0) || (u1<0) ||
(v1 >= this.gridGeometry.length) ||
......@@ -732,7 +755,7 @@ import com.elphel.imagej.jp4.JP46_Reader_camera;
}
if (this.stationZCorr==null) return this.gridGeometry[v1][u1];
double [] result=this.gridGeometry[v1][u1].clone();
// use lower station if grid file does not have current
// use lower station if grid file does not have current
int useStation=(this.stationZCorr[v1][u1].length>station)?station:(this.stationZCorr[v1][u1].length-1);
result[2]+=this.stationZCorr[v1][u1][useStation];
return result;
......@@ -747,7 +770,7 @@ import com.elphel.imagej.jp4.JP46_Reader_camera;
}
return u1+this.gridGeometry[0].length*v1;
}
public double[] getXYZM(int u, int v, int station){ // u=0,v=0 - center!
int u1=u+this.U0;
int v1=v+this.V0;
......@@ -817,8 +840,8 @@ import com.elphel.imagej.jp4.JP46_Reader_camera;
return this.stationZCorr[v1][u1][station];
}
/**
* Return grid geometry and photometics: X,Y,Z,mask,R,G,B,Alpha
* @param u signed grid U (0 in the center)
......@@ -899,7 +922,7 @@ import com.elphel.imagej.jp4.JP46_Reader_camera;
System.out.println();
}
double [] result= { // null
double [] result= { // null
this.gridGeometry[v1][u1][0],
this.gridGeometry[v1][u1][1],
// this.gridGeometry[v1][u1][2]+((this.stationZCorr!=null)?this.stationZCorr[v1][u1][station]:0.0), // per-station correction
......@@ -913,8 +936,8 @@ import com.elphel.imagej.jp4.JP46_Reader_camera;
};
return result;
}
public double [][][] getGeometry(){return this.gridGeometry;}
public double [][][] getGeometry(){return this.gridGeometry;}
}
......@@ -12,7 +12,6 @@ import com.elphel.imagej.common.GenericJTabbedDialog;
import com.elphel.imagej.common.WindowTools;
import Jama.Matrix;
import ij.Prefs;
/*
**
** EyesisCameraParameters.java
......@@ -66,11 +65,12 @@ import ij.gui.GenericDialog;
public boolean isTripod= false; // when true - make goniometerHorizontal rotation around "vertical" axis and "goniometerAxial" - around
public boolean cartesian=false; //
// rotated horizontal.
public int sensorWidth= 2592;
public int sensorHeight= 1936;
private int defaultSensorWidth= 2592;
private int defaultSensorHeight= 1936;
private int defaultDecimateMasks= 1;
public int shrinkGridForMask=4; //2; //shrink detected grids by one point for/vert this number of times before calculating masks
public double maskBlurSigma= -3; //2.0; // blur sensor masks (>0 - pixels, <0 - in grid units)
public int decimateMasks= 1;
public double badNodeThreshold=0.1; // filter out grid nodes with difference from quadratically predicted from 8 neighbors in pixels
public int maxBadNeighb= 1; // maximal number of bad nodes around the corrected one to fix
public int minimalValidNodes=50; // do not use images with less than this number of non-zero nodes (after all applicable weight masks)
......@@ -459,11 +459,11 @@ import ij.gui.GenericDialog;
double entrancePupilForward, // common to all lenses - distance from the sensor to the lens entrance pupil
double centerAboveHorizontal, // camera center distance along camera axis above the closest point to horizontal rotation axis (adds to height of each
double [] GXYZ, // coordinates (in mm) of the goniometer horizontal axis closest to the moving one in target system
int sensorWidth,
int sensorHeight,
int defaultSensorWidth,
int defaultSensorHeight,
int shrinkGridForMask, //shrink detected grids by one point for/vert this number of times before calculating masks
double maskBlurSigma, // blur sensor masks (in grid units)
int decimateMasks, // reduce masks resolution
int defaultDecimateMasks, // reduce masks resolution
double badNodeThreshold, // filter out grid nodes with difference from quadratically predicted from 8 neighbors in pixels
int maxBadNeighb, // maximal number of bad nodes around the corrected one to fix
int minimalValidNodes,
......@@ -481,11 +481,11 @@ import ij.gui.GenericDialog;
this.numStations=numStations;
this.isTripod=isTripod;
this.cartesian = cartesian; // Need to set each subcamera?
this.sensorWidth=sensorWidth;
this.sensorHeight=sensorHeight;
this.defaultSensorWidth=defaultSensorWidth;
this.defaultSensorHeight=defaultSensorHeight;
this.shrinkGridForMask=shrinkGridForMask; //shrink detected grids by one point for/vert this number of times before calculating masks
this.maskBlurSigma=maskBlurSigma; // blur sensor masks (in grid units)
this.decimateMasks=decimateMasks;
this.defaultDecimateMasks=defaultDecimateMasks;
this.badNodeThreshold=badNodeThreshold; // filter out grid nodes with difference from quadratically predicted from 8 neighbors in pixels
this.maxBadNeighb=maxBadNeighb; // maximal number of bad nodes around the corrected one to fix
this.minimalValidNodes=minimalValidNodes;
......@@ -544,11 +544,11 @@ import ij.gui.GenericDialog;
EyesisCameraParameters destination) {
destination.numStations=newNumStations;
destination.isTripod=source.isTripod;
destination.sensorWidth=source.sensorWidth;
destination.sensorHeight=source.sensorHeight;
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
destination.maskBlurSigma=source.maskBlurSigma; // blur sensor masks (in grid units)
destination.decimateMasks=source.decimateMasks;
destination.defaultDecimateMasks=source.defaultDecimateMasks;
destination.badNodeThreshold=source.badNodeThreshold; // filter out grid nodes with difference from quadratically predicted from 8 neighbors in pixels
destination.maxBadNeighb=source.maxBadNeighb; // maximal number of bad nodes around the corrected one to fix
destination.minimalValidNodes=source.minimalValidNodes;
......@@ -600,11 +600,11 @@ import ij.gui.GenericDialog;
public void setProperties(String prefix,Properties properties){
properties.setProperty(prefix+"isTripod",this.isTripod+"");
properties.setProperty(prefix+"cartesian",this.cartesian+"");
properties.setProperty(prefix+"sensorWidth",this.sensorWidth+"");
properties.setProperty(prefix+"sensorHeight",this.sensorHeight+"");
properties.setProperty(prefix+"defaultSensorWidth",this.defaultSensorWidth+"");
properties.setProperty(prefix+"defaultSensorHeight",this.defaultSensorHeight+"");
properties.setProperty(prefix+"shrinkGridForMask",this.shrinkGridForMask+"");
properties.setProperty(prefix+"maskBlurSigma",this.maskBlurSigma+"");
properties.setProperty(prefix+"decimateMasks",this.decimateMasks+"");
properties.setProperty(prefix+"defaultDecimateMasks",this.defaultDecimateMasks+"");
properties.setProperty(prefix+"badNodeThreshold",this.badNodeThreshold+"");
properties.setProperty(prefix+"maxBadNeighb",this.maxBadNeighb+"");
properties.setProperty(prefix+"minimalValidNodes",this.minimalValidNodes+"");
......@@ -644,16 +644,25 @@ import ij.gui.GenericDialog;
this.isTripod=Boolean.parseBoolean(properties.getProperty(prefix+"isTripod"));
if (properties.getProperty(prefix+"cartesian")!=null)
this.cartesian=Boolean.parseBoolean(properties.getProperty(prefix+"cartesian"));
// For old compatibility
if (properties.getProperty(prefix+"decimateMasks")!=null)
this.defaultDecimateMasks=Integer.parseInt(properties.getProperty(prefix+"decimateMasks"));
if (properties.getProperty(prefix+"sensorWidth")!=null)
this.sensorWidth=Integer.parseInt(properties.getProperty(prefix+"sensorWidth"));
this.defaultSensorWidth=Integer.parseInt(properties.getProperty(prefix+"sensorWidth"));
if (properties.getProperty(prefix+"sensorHeight")!=null)
this.sensorHeight=Integer.parseInt(properties.getProperty(prefix+"sensorHeight"));
this.defaultSensorHeight=Integer.parseInt(properties.getProperty(prefix+"sensorHeight"));
// New version
if (properties.getProperty(prefix+"defaultDecimateMasks")!=null)
this.defaultDecimateMasks=Integer.parseInt(properties.getProperty(prefix+"defaultDecimateMasks"));
if (properties.getProperty(prefix+"defaultSensorWidth")!=null)
this.defaultSensorWidth=Integer.parseInt(properties.getProperty(prefix+"defaultSensorWidth"));
if (properties.getProperty(prefix+"defaultSensorHeight")!=null)
this.defaultSensorHeight=Integer.parseInt(properties.getProperty(prefix+"defaultSensorHeight"));
if (properties.getProperty(prefix+"shrinkGridForMask")!=null)
this.shrinkGridForMask=Integer.parseInt(properties.getProperty(prefix+"shrinkGridForMask"));
if (properties.getProperty(prefix+"maskBlurSigma")!=null)
this.maskBlurSigma=Double.parseDouble(properties.getProperty(prefix+"maskBlurSigma"));
if (properties.getProperty(prefix+"decimateMasks")!=null)
this.decimateMasks=Integer.parseInt(properties.getProperty(prefix+"decimateMasks"));
if (properties.getProperty(prefix+"badNodeThreshold")!=null)
this.badNodeThreshold=Double.parseDouble(properties.getProperty(prefix+"badNodeThreshold"));
......@@ -824,11 +833,11 @@ import ij.gui.GenericDialog;
}
gd.addMessage("=== Other parameters ===");
gd.addNumericField("Image sensor width (maximal if different)", this.sensorWidth, 0,4,"pix");
gd.addNumericField("Image sensor height (maximal if different)", this.sensorHeight, 0,4,"pix");
gd.addNumericField("Image sensor width (maximal if different)", this.defaultSensorWidth, 0,4,"pix");
gd.addNumericField("Image sensor height (maximal if different)", this.defaultSensorHeight, 0,4,"pix");
gd.addNumericField("Shrink detected grid by this number of nodes (half/periods) for masks",this.shrinkGridForMask, 0,4,"grid nodes");
gd.addNumericField("Gaussian blur masks for the sensors (positive - pixels, negative - grid half-periods)", this.maskBlurSigma, 2,6,"pix");
gd.addNumericField("Reduce sensor resolution when calculating masks", this.decimateMasks, 0);
gd.addNumericField("Reduce sensor resolution when calculating masks", this.defaultDecimateMasks, 0);
gd.addNumericField("Filter out grid nodes with difference from quadratically predicted from 8 neighbors", this.badNodeThreshold, 2,6,"pix");
gd.addNumericField("Maximal number of bad nodes around the corrected one to fix", this.maxBadNeighb, 0);
......@@ -877,11 +886,11 @@ import ij.gui.GenericDialog;
this.GXYZ[numStation][1]= gd.getNextNumber();
this.GXYZ[numStation][2]= gd.getNextNumber();
}
this.sensorWidth= (int) gd.getNextNumber();
this.sensorHeight= (int) gd.getNextNumber();
this.defaultSensorWidth= (int) gd.getNextNumber();
this.defaultSensorHeight= (int) gd.getNextNumber();
this.shrinkGridForMask= (int) gd.getNextNumber();
this.maskBlurSigma= gd.getNextNumber();
this.decimateMasks= (int) gd.getNextNumber();
this.defaultDecimateMasks=(int) gd.getNextNumber();
this.badNodeThreshold= gd.getNextNumber();
this.maxBadNeighb= (int) gd.getNextNumber();
this.minimalValidNodes= (int) gd.getNextNumber();
......@@ -1263,10 +1272,41 @@ import ij.gui.GenericDialog;
public int getGoniometerHorizontalIndex(){return 6;}
public int getGoniometerAxialIndex(){return 7;}
public int getInterAxisAngleIndex(){return 9;}
public int getSensorWidth() { return this.sensorWidth;}
public int getSensorHeight() { return this.sensorHeight;}
public int getSensorWidth(int subCam) { return this.sensorWidth;} // for the future? different sensors
public int getSensorHeight(int subCam) { return this.sensorHeight;}// for the future? different sensors
public int getSensorWidth() { return this.defaultSensorWidth;}
public int getSensorHeight() { return this.defaultSensorHeight;}
public int getDecimateMasks() { return this.defaultDecimateMasks;}
public void setSensorWidth(int v) { this.defaultSensorWidth = v;}
public void setSensorHeight(int v) { this.defaultSensorHeight = v;}
public void setDecimateMasks(int v) { this.defaultDecimateMasks = v;}
public int getSensorWidth(int subCam) { return this.eyesisSubCameras[0][subCam].sensorWidth;} // for the future? different sensors
public int getSensorHeight(int subCam) { return this.eyesisSubCameras[0][subCam].sensorHeight;}// for the future? different sensors
public int getDecimateMasks(int subCam) { return this.eyesisSubCameras[0][subCam].decimateMasks;}// for the future? different sensors
public void setSensorWidth(int subCam, int v) { this.eyesisSubCameras[0][subCam].sensorWidth = v;}
public void setSensorHeight(int subCam, int v) { this.eyesisSubCameras[0][subCam].sensorHeight = v;}
public void setDecimateMasks(int subCam, int v) { this.eyesisSubCameras[0][subCam].decimateMasks = v;}
public int [] getSensorWidths() {
int [] v = new int [eyesisSubCameras[0].length];
for (int subCam = 0; subCam < v.length; subCam++) v[subCam] = getSensorWidth(subCam);
return v;
} // for the future? different sensors
public int [] getSensorHeights() {
int [] v = new int [eyesisSubCameras[0].length];
for (int subCam = 0; subCam < v.length; subCam++) v[subCam] = getSensorHeight(subCam);
return v;
}// for the future? different sensors
public int [] getAllMasks() {
int [] v = new int [eyesisSubCameras[0].length];
for (int subCam = 0; subCam < v.length; subCam++) v[subCam] = getDecimateMasks(subCam);
return v;
}// for the future? different sensors
public double getPixelSize(int subCamNumber){return this.eyesisSubCameras[0][subCamNumber].pixelSize;} // use station 0's pixel size
public double getDistortionRadius(int subCamNumber){return this.eyesisSubCameras[0][subCamNumber].distortionRadius;}
......@@ -1391,6 +1431,9 @@ import ij.gui.GenericDialog;
if (numSubCameras==3) {
this.cartesian = false; // change?
this.eyesisSubCameras[numStation][0]=new EyesisSubCameraParameters( //TODO: modify for lens adjustment defaults?
this.defaultSensorWidth,
this.defaultSensorHeight,
this.defaultDecimateMasks,
cartesian,
defaultLensDistortionModel,
true,
......@@ -1422,6 +1465,9 @@ import ij.gui.GenericDialog;
this.eyesisSubCameras[numStation][1]=new EyesisSubCameraParameters( //TODO: modify for lens adjustment defaults?
this.defaultSensorWidth,
this.defaultSensorHeight,
this.defaultDecimateMasks,
cartesian,
defaultLensDistortionModel,
true,
......@@ -1452,6 +1498,9 @@ import ij.gui.GenericDialog;
0); // public int subchannel
this.eyesisSubCameras[numStation][2]=new EyesisSubCameraParameters( //TODO: modify for lens adjustment defaults?
this.defaultSensorWidth,
this.defaultSensorHeight,
this.defaultDecimateMasks,
cartesian,
defaultLensDistortionModel,
true,
......@@ -1484,6 +1533,9 @@ import ij.gui.GenericDialog;
} else if (numSubCameras==1) {
this.cartesian = false;
this.eyesisSubCameras[numStation][0]=new EyesisSubCameraParameters( //TODO: modify for lens adjustment defaults?
this.defaultSensorWidth,
this.defaultSensorHeight,
this.defaultDecimateMasks,
this.cartesian,
defaultLensDistortionModel,
true,
......@@ -1519,6 +1571,9 @@ import ij.gui.GenericDialog;
//
this.cartesian = false; // change
this.eyesisSubCameras[numStation][0]=new EyesisSubCameraParameters( //TODO: modify for lens adjustment defaults?
this.defaultSensorWidth,
this.defaultSensorHeight,
this.defaultDecimateMasks,
this.cartesian,
defaultLensDistortionModel,
true,
......@@ -1549,6 +1604,9 @@ import ij.gui.GenericDialog;
0); // public int subchannel
this.eyesisSubCameras[numStation][1]=new EyesisSubCameraParameters( //TODO: modify for lens adjustment defaults?
this.defaultSensorWidth,
this.defaultSensorHeight,
this.defaultDecimateMasks,
this.cartesian,
defaultLensDistortionModel,
true,
......@@ -1579,6 +1637,9 @@ import ij.gui.GenericDialog;
0); // public int subchannel
this.eyesisSubCameras[numStation][2]=new EyesisSubCameraParameters( //TODO: modify for lens adjustment defaults?
this.defaultSensorWidth,
this.defaultSensorHeight,
this.defaultDecimateMasks,
this.cartesian,
defaultLensDistortionModel,
true,
......@@ -1609,6 +1670,9 @@ import ij.gui.GenericDialog;
0); // public int subchannel
this.eyesisSubCameras[numStation][3]=new EyesisSubCameraParameters( //TODO: modify for lens adjustment defaults?
this.defaultSensorWidth,
this.defaultSensorHeight,
this.defaultDecimateMasks,
this.cartesian,
defaultLensDistortionModel,
true,
......@@ -1639,6 +1703,9 @@ import ij.gui.GenericDialog;
0); // public int subchannel
this.eyesisSubCameras[numStation][4]=new EyesisSubCameraParameters( //TODO: modify for lens adjustment defaults?
this.defaultSensorWidth,
this.defaultSensorHeight,
this.defaultDecimateMasks,
this.cartesian,
defaultLensDistortionModel,
true,
......@@ -1669,6 +1736,9 @@ import ij.gui.GenericDialog;
0); // public int subchannel
this.eyesisSubCameras[numStation][5]=new EyesisSubCameraParameters( //TODO: modify for lens adjustment defaults?
this.defaultSensorWidth,
this.defaultSensorHeight,
this.defaultDecimateMasks,
this.cartesian,
defaultLensDistortionModel,
true,
......@@ -1699,6 +1769,9 @@ import ij.gui.GenericDialog;
0); // public int subchannel
this.eyesisSubCameras[numStation][6]=new EyesisSubCameraParameters( //TODO: modify for lens adjustment defaults?
this.defaultSensorWidth,
this.defaultSensorHeight,
this.defaultDecimateMasks,
this.cartesian,
defaultLensDistortionModel,
true,
......@@ -1729,6 +1802,9 @@ import ij.gui.GenericDialog;
0); // public int subchannel
this.eyesisSubCameras[numStation][7]=new EyesisSubCameraParameters( //TODO: modify for lens adjustment defaults?
this.defaultSensorWidth,
this.defaultSensorHeight,
this.defaultDecimateMasks,
this.cartesian,
defaultLensDistortionModel,
true,
......@@ -1759,6 +1835,9 @@ import ij.gui.GenericDialog;
0); // public int subchannel
this.eyesisSubCameras[numStation][8]=new EyesisSubCameraParameters( //TODO: modify for lens adjustment defaults?
this.defaultSensorWidth,
this.defaultSensorHeight,
this.defaultDecimateMasks,
this.cartesian,
defaultLensDistortionModel,
true,
......@@ -1789,6 +1868,9 @@ import ij.gui.GenericDialog;
0); // public int subchannel
this.eyesisSubCameras[numStation][9]=new EyesisSubCameraParameters( //TODO: modify for lens adjustment defaults?
this.defaultSensorWidth,
this.defaultSensorHeight,
this.defaultDecimateMasks,
this.cartesian,
defaultLensDistortionModel,
true,
......@@ -1819,6 +1901,9 @@ import ij.gui.GenericDialog;
0); // public int subchannel
this.eyesisSubCameras[numStation][10]=new EyesisSubCameraParameters( //TODO: modify for lens adjustment defaults?
this.defaultSensorWidth,
this.defaultSensorHeight,
this.defaultDecimateMasks,
this.cartesian,
defaultLensDistortionModel,
true,
......@@ -1849,6 +1934,9 @@ import ij.gui.GenericDialog;
0); // public int subchannel
this.eyesisSubCameras[numStation][11]=new EyesisSubCameraParameters( //TODO: modify for lens adjustment defaults?
this.defaultSensorWidth,
this.defaultSensorHeight,
this.defaultDecimateMasks,
this.cartesian,
defaultLensDistortionModel,
true,
......@@ -1879,6 +1967,9 @@ import ij.gui.GenericDialog;
0); // public int subchannel
this.eyesisSubCameras[numStation][12]=new EyesisSubCameraParameters( //TODO: modify for lens adjustment defaults?
this.defaultSensorWidth,
this.defaultSensorHeight,
this.defaultDecimateMasks,
this.cartesian,
defaultLensDistortionModel,
true,
......@@ -1909,6 +2000,9 @@ import ij.gui.GenericDialog;
0); // public int subchannel
this.eyesisSubCameras[numStation][13]=new EyesisSubCameraParameters( //TODO: modify for lens adjustment defaults?
this.defaultSensorWidth,
this.defaultSensorHeight,
this.defaultDecimateMasks,
this.cartesian,
defaultLensDistortionModel,
true,
......@@ -1939,6 +2033,9 @@ import ij.gui.GenericDialog;
0); // public int subchannel
this.eyesisSubCameras[numStation][14]=new EyesisSubCameraParameters( //TODO: modify for lens adjustment defaults?
this.defaultSensorWidth,
this.defaultSensorHeight,
this.defaultDecimateMasks,
this.cartesian,
defaultLensDistortionModel,
true,
......@@ -1969,6 +2066,9 @@ import ij.gui.GenericDialog;
0); // public int subchannel
this.eyesisSubCameras[numStation][15]=new EyesisSubCameraParameters( //TODO: modify for lens adjustment defaults?
this.defaultSensorWidth,
this.defaultSensorHeight,
this.defaultDecimateMasks,
this.cartesian,
defaultLensDistortionModel,
true,
......@@ -1999,6 +2099,9 @@ import ij.gui.GenericDialog;
0); // public int subchannel
this.eyesisSubCameras[numStation][16]=new EyesisSubCameraParameters( //TODO: modify for lens adjustment defaults?
this.defaultSensorWidth,
this.defaultSensorHeight,
this.defaultDecimateMasks,
this.cartesian,
defaultLensDistortionModel,
true,
......@@ -2029,6 +2132,9 @@ import ij.gui.GenericDialog;
0); // public int subchannel
this.eyesisSubCameras[numStation][17]=new EyesisSubCameraParameters( //TODO: modify for lens adjustment defaults?
this.defaultSensorWidth,
this.defaultSensorHeight,
this.defaultDecimateMasks,
this.cartesian,
defaultLensDistortionModel,
true,
......@@ -2059,6 +2165,9 @@ import ij.gui.GenericDialog;
0); // public int subchannel
this.eyesisSubCameras[numStation][18]=new EyesisSubCameraParameters( //TODO: modify for lens adjustment defaults?
this.defaultSensorWidth,
this.defaultSensorHeight,
this.defaultDecimateMasks,
this.cartesian,
defaultLensDistortionModel,
true,
......@@ -2089,6 +2198,9 @@ import ij.gui.GenericDialog;
0); // public int subchannel
this.eyesisSubCameras[numStation][19]=new EyesisSubCameraParameters( //TODO: modify for lens adjustment defaults?
this.defaultSensorWidth,
this.defaultSensorHeight,
this.defaultDecimateMasks,
this.cartesian,
defaultLensDistortionModel,
true,
......@@ -2119,6 +2231,9 @@ import ij.gui.GenericDialog;
0); // public int subchannel
this.eyesisSubCameras[numStation][20]=new EyesisSubCameraParameters( //TODO: modify for lens adjustment defaults?
this.defaultSensorWidth,
this.defaultSensorHeight,
this.defaultDecimateMasks,
this.cartesian,
defaultLensDistortionModel,
true,
......@@ -2154,6 +2269,9 @@ import ij.gui.GenericDialog;
} else {
// default setup for the 26 sub-cameras
for (int i=0;i<8;i++) if (i<numSubCameras) this.eyesisSubCameras[numStation][i]=new EyesisSubCameraParameters( // top 8 cameras
this.defaultSensorWidth,
this.defaultSensorHeight,
this.defaultDecimateMasks,
this.cartesian,
defaultLensDistortionModel,
true,
......@@ -2184,6 +2302,9 @@ import ij.gui.GenericDialog;
0); // public int subchannel
for (int i=8;i<16;i++) if (i<numSubCameras) this.eyesisSubCameras[numStation][i]=new EyesisSubCameraParameters( // middle 8 cameras
this.defaultSensorWidth,
this.defaultSensorHeight,
this.defaultDecimateMasks,
this.cartesian,
defaultLensDistortionModel,
true,
......@@ -2214,6 +2335,9 @@ import ij.gui.GenericDialog;
0); // public int subchannel
for (int i=16;i<24;i++) if (i<numSubCameras) this.eyesisSubCameras[numStation][i]=new EyesisSubCameraParameters( // bottom eight cameras
this.defaultSensorWidth,
this.defaultSensorHeight,
this.defaultDecimateMasks,
this.cartesian,
defaultLensDistortionModel,
true,
......@@ -2244,6 +2368,9 @@ import ij.gui.GenericDialog;
0); // public int subchannel
if (24<numSubCameras) this.eyesisSubCameras[numStation][24]=new EyesisSubCameraParameters(
this.defaultSensorWidth,
this.defaultSensorHeight,
this.defaultDecimateMasks,
this.cartesian,
defaultLensDistortionModel,
false,
......@@ -2274,6 +2401,9 @@ import ij.gui.GenericDialog;
0); // public int subchannel
if (25<numSubCameras) this.eyesisSubCameras[numStation][25]=new EyesisSubCameraParameters(
this.defaultSensorWidth,
this.defaultSensorHeight,
this.defaultDecimateMasks,
this.cartesian,
defaultLensDistortionModel,
false,
......@@ -2544,7 +2674,6 @@ import ij.gui.GenericDialog;
DistortionCalibrationData sub_distortionCalibrationData = null;
EyesisAberrations.AberrationParameters sub_aberrationParameters = null;
LensDistortionParameters sub_lensDistortionParameters = null;
// boolean update_sensor_files = subsystemOffsets.update_sensor_files;
// TODO: check sub_distortions != null
if (subsystemOffsets.update_sensor_files) {
sub_aberrationParameters=new EyesisAberrations.AberrationParameters();
......@@ -2554,17 +2683,12 @@ import ij.gui.GenericDialog;
sensors_path = sub_aberrationParameters.sensorsPath;
System.out.println("sensors_path = "+sensors_path);
String [][] stationFilenames = new String[sub_system.numStations][0];
/// String [][] stationFilenames = new String[sub_system.numStations][0];
sub_distortionCalibrationData = new DistortionCalibrationData(
// stationFilenames, // String [][] stationFilenames,
// null, // PatternParameters patternParameters,
sub_system // EyesisCameraParameters eyesisCameraParameters
// ,0 // debugLevel
);
// now read all sensor files
if ((sensors_path !=null) && (sensors_path != "")){ // load sensor
// if (sub_distortions.fittingStrategy==null) return false; // Why?
// if (DEBUG_LEVEL>0) System.out.println("Autoloading sensor calibration files "+configPaths[3]);
sub_distortions = new Distortions(
sub_lensDistortionParameters, // LensDistortionParameters lensDistortionParameters,
null, // PatternParameters patternParameters,
......@@ -2653,18 +2777,18 @@ import ij.gui.GenericDialog;
for (int i = 0; i < tmp_masks.length; i++ ) system_distortionCalibrationData.sensorMasks[i] = tmp_masks[i];
}
// now copy data over, update the path names?
String imported_name=sub_distortions.pathNames[0];
int last_sep = imported_name.lastIndexOf(Prefs.getFileSeparator());
if (last_sep>=0) imported_name = imported_name.substring(last_sep + 1);
int indexPeriod=imported_name.lastIndexOf('.');
int indexSuffix=indexPeriod;
String digits="0123456789";
for (int i=1;i<=2;i++) if (digits.indexOf(imported_name.charAt(indexSuffix-1))>=0) indexSuffix--; // remove 1 or 2 digits before period
boolean hadSuffix= (imported_name.charAt(indexSuffix-1)=='-');
/// String imported_name=sub_distortions.pathNames[0];
/// int last_sep = imported_name.lastIndexOf(Prefs.getFileSeparator());
/// if (last_sep>=0) imported_name = imported_name.substring(last_sep + 1);
/// int indexPeriod=imported_name.lastIndexOf('.');
/// int indexSuffix=indexPeriod;
/// String digits="0123456789";
/// for (int i=1;i<=2;i++) if (digits.indexOf(imported_name.charAt(indexSuffix-1))>=0) indexSuffix--; // remove 1 or 2 digits before period
/// boolean hadSuffix= (imported_name.charAt(indexSuffix-1)=='-');
for (int nc = 0; nc < sub_system.getNumChannels(); nc++) {
int chn = nc+subsystemOffsets.offset_channel;
systemDistortions.pathNames[chn]=calibration_directory+Prefs.getFileSeparator()+((hadSuffix?imported_name.substring(0,indexSuffix):(imported_name.substring(0,indexPeriod)+"-"))+
String.format("%02d",chn)+imported_name.substring(indexPeriod));
// systemDistortions.pathNames[chn]=calibration_directory+Prefs.getFileSeparator()+((hadSuffix?imported_name.substring(0,indexSuffix):(imported_name.substring(0,indexPeriod)+"-"))+
// String.format("%02d",chn)+imported_name.substring(indexPeriod));
systemDistortions.pixelCorrection[chn] = sub_distortions.pixelCorrection[nc];
system_distortionCalibrationData.sensorMasks[chn] = sub_distortionCalibrationData.sensorMasks[nc];
}
......@@ -2680,8 +2804,22 @@ import ij.gui.GenericDialog;
parFilter,
systemDistortions.getSensorPath(-1)); //String defaultPath
if ((pathname==null) || (pathname=="")) return true;
/// int last_sep = pathname.lastIndexOf(Prefs.getFileSeparator());
/// if (last_sep>=0) pathname = pathname.substring(last_sep + 1);
int indexPeriod=pathname.lastIndexOf('.');
int indexSuffix=indexPeriod;
String digits="0123456789";
for (int i=1;i<=2;i++) if (digits.indexOf(pathname.charAt(indexSuffix-1))>=0) indexSuffix--; // remove 1 or 2 digits before period
boolean hadSuffix= (pathname.charAt(indexSuffix-1)=='-');
for (int nc = 0; nc < sub_system.getNumChannels(); nc++) {
int chn = nc+subsystemOffsets.offset_channel;
// Make systemDistortions.pathNames[chn] from pathname replacing channel
systemDistortions.pathNames[chn]= // calibration_directory+Prefs.getFileSeparator()+
((hadSuffix?pathname.substring(0,indexSuffix):(pathname.substring(0,indexPeriod)+"-"))+
String.format("%02d",chn)+pathname.substring(indexPeriod));
systemDistortions.saveDistortionAsImageStack(
system_distortionCalibrationData,
null, // camerasInterface, // to save channel map
......
......@@ -25,6 +25,9 @@ package com.elphel.imagej.cameras;
import java.util.Properties;
public class EyesisSubCameraParameters{
public int sensorWidth= 2592; // moving here from the camera as a whole
public int sensorHeight= 1936;
public int decimateMasks= 1;
// origin is on the rotation axis of the tube body closest to the goniometer horizontal axis
public boolean cartesian = false; // cartesian coordinates mode (false - cylindrical)
public int lensDistortionModel=0;
......@@ -80,6 +83,9 @@ import java.util.Properties;
*/
public EyesisSubCameraParameters(
int sensorWidth,
int sensorHeight,
int decimateMasks,
boolean cartesian,
int lensDistortionModel,
boolean enableNoLaser,
......@@ -111,6 +117,9 @@ import java.util.Properties;
int sensor_port,
int subchannel
){
this.decimateMasks = decimateMasks;
this.sensorWidth= sensorWidth;
this.sensorHeight=sensorHeight;
this.cartesian = cartesian;
this.lensDistortionModel=lensDistortionModel;
this.enableNoLaser=enableNoLaser;
......@@ -156,6 +165,9 @@ import java.util.Properties;
@Override
public EyesisSubCameraParameters clone() {
return new EyesisSubCameraParameters(
this.sensorWidth,
this.sensorHeight,
this.decimateMasks,
this.cartesian,
this.lensDistortionModel,
this.enableNoLaser,
......@@ -196,6 +208,9 @@ import java.util.Properties;
}
// TODO: add/restore new properties
public void setProperties(String prefix,Properties properties){
properties.setProperty(prefix+"sensorWidth", this.sensorWidth+"");
properties.setProperty(prefix+"sensorHeight", this.sensorHeight+"");
properties.setProperty(prefix+"decimateMasks", this.decimateMasks+"");
properties.setProperty(prefix+"cartesian", this.cartesian+"");
properties.setProperty(prefix+"lensDistortionModel", this.lensDistortionModel+"");
properties.setProperty(prefix+"enableNoLaser", this.enableNoLaser+"");
......@@ -239,6 +254,12 @@ import java.util.Properties;
getProperties(prefix,properties, -1);
}
public void getProperties(String prefix,Properties properties, int channel){
if (properties.getProperty(prefix+"sensorWidth")!=null)
this.sensorWidth=Integer.parseInt(properties.getProperty(prefix+"sensorWidth"));
if (properties.getProperty(prefix+"sensorHeight")!=null)
this.sensorHeight=Integer.parseInt(properties.getProperty(prefix+"sensorHeight"));
if (properties.getProperty(prefix+"decimateMasks")!=null)
this.decimateMasks=Integer.parseInt(properties.getProperty(prefix+"decimateMasks"));
if (properties.getProperty(prefix+"cartesian")!=null)
this.cartesian=Boolean.parseBoolean(properties.getProperty(prefix+"cartesian"));
if (properties.getProperty(prefix+"lensDistortionModel")!=null)
......
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