Commit 53924b9e authored by Andrey Filippov's avatar Andrey Filippov

modified save/restore calibration state, bug fixes

parent 7a838c63
...@@ -606,6 +606,7 @@ public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSi ...@@ -606,6 +606,7 @@ public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSi
addButton("Select source directory", panelDirs); addButton("Select source directory", panelDirs);
addButton("Select intermediate directory",panelDirs); addButton("Select intermediate directory",panelDirs);
addButton("Select results directory", panelDirs); addButton("Select results directory", panelDirs);
addButton("View CSV file", panelDirs, color_report);
add(panelDirs); add(panelDirs);
...@@ -1092,13 +1093,15 @@ if (MORE_BUTTONS) { ...@@ -1092,13 +1093,15 @@ if (MORE_BUTTONS) {
selectedProperties.setProperty("selected", "true"); selectedProperties.setProperty("selected", "true");
saveProperties(null,PROCESS_PARAMETERS.kernelsDirectory, PROCESS_PARAMETERS.useXML, selectedProperties); saveProperties(null,PROCESS_PARAMETERS.kernelsDirectory, PROCESS_PARAMETERS.useXML, selectedProperties);
return; return;
/* ======================================================================== */ /* ======================================================================== */
} else if (label.equals("View CSV file")) {
viewCSVFile();
return;
/* ======================================================================== */
} else if (label.equals("Restore") || label.equals("Restore no autoload")) { } else if (label.equals("Restore") || label.equals("Restore no autoload")) {
boolean noAuto=label.equals("Restore no autoload"); boolean noAuto=label.equals("Restore no autoload");
ABERRATIONS_PARAMETERS.autoRestore=false; ABERRATIONS_PARAMETERS.autoRestore=false;
loadProperties(null,PROCESS_PARAMETERS.kernelsDirectory,PROCESS_PARAMETERS.useXML, PROPERTIES); String confPath=loadProperties(null,PROCESS_PARAMETERS.kernelsDirectory,PROCESS_PARAMETERS.useXML, PROPERTIES);
DEBUG_LEVEL=MASTER_DEBUG_LEVEL; DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
if (ABERRATIONS_PARAMETERS.autoRestore && !noAuto){ if (ABERRATIONS_PARAMETERS.autoRestore && !noAuto){
if (DEBUG_LEVEL>0)System.out.println("Auto-loading configuration files"); if (DEBUG_LEVEL>0)System.out.println("Auto-loading configuration files");
...@@ -1114,6 +1117,13 @@ if (MORE_BUTTONS) { ...@@ -1114,6 +1117,13 @@ if (MORE_BUTTONS) {
UPDATE_STATUS, UPDATE_STATUS,
DEBUG_LEVEL DEBUG_LEVEL
); );
/*// Not needed, controlled by parameters
if (ABERRATIONS_PARAMETERS.autoLoadPaths()[3]!=null) {
// Re-read configuration file to overwrite camera parameters restored with calibration files
if (DEBUG_LEVEL>0) System.out.println("Re-reading configuration to overwrite camera parameters restored from the sensor calibration files");
loadProperties(confPath,PROCESS_PARAMETERS.kernelsDirectory,PROCESS_PARAMETERS.useXML, PROPERTIES);
}
*/
if (dcdUpdated) DISTORTION_CALIBRATION_DATA=LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData; if (dcdUpdated) DISTORTION_CALIBRATION_DATA=LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData;
if (ABERRATIONS_PARAMETERS.autoReCalibrate){ if (ABERRATIONS_PARAMETERS.autoReCalibrate){
if (LENS_DISTORTIONS.fittingStrategy==null) { if (LENS_DISTORTIONS.fittingStrategy==null) {
...@@ -1169,6 +1179,7 @@ if (MORE_BUTTONS) { ...@@ -1169,6 +1179,7 @@ if (MORE_BUTTONS) {
} }
} }
restoreFocusingHistory(false); restoreFocusingHistory(false);
} }
return; return;
...@@ -2407,6 +2418,7 @@ if (MORE_BUTTONS) { ...@@ -2407,6 +2418,7 @@ if (MORE_BUTTONS) {
defaultPath, defaultPath,
PATTERN_PARAMETERS, PATTERN_PARAMETERS,
EYESIS_CAMERA_PARAMETERS, EYESIS_CAMERA_PARAMETERS,
ABERRATIONS_PARAMETERS,
null); // gridImages null - use specified files null); // gridImages null - use specified files
if (DISTORTION_CALIBRATION_DATA.pathName== null){ // failed to select/open the file if (DISTORTION_CALIBRATION_DATA.pathName== null){ // failed to select/open the file
DISTORTION_CALIBRATION_DATA=oldDISTORTION_CALIBRATION_DATA; DISTORTION_CALIBRATION_DATA=oldDISTORTION_CALIBRATION_DATA;
...@@ -3171,15 +3183,17 @@ if (MORE_BUTTONS) { ...@@ -3171,15 +3183,17 @@ if (MORE_BUTTONS) {
GenericDialog gd = new GenericDialog("Select sensor number"); GenericDialog gd = new GenericDialog("Select sensor number");
gd.addCheckbox("Restore all sensors", true); gd.addCheckbox("Restore all sensors", true);
gd.addNumericField("Number of sensor/channel to apply calibration (if \"all\" is not selected)", 0,0); gd.addNumericField("Number of sensor/channel to apply calibration (if \"all\" is not selected)", 0,0);
gd.addCheckbox("Overwrite SFE position/orientation from the sensor calibration data", true); gd.addCheckbox("Overwrite all SFE position/orientation from the sensor calibration data", true);
gd.addCheckbox("Overwrite SFE distortion from the sensor calibration data", true);
gd.showDialog(); gd.showDialog();
if (gd.wasCanceled()) return; if (gd.wasCanceled()) return;
boolean allFiles=gd.getNextBoolean(); boolean allFiles=gd.getNextBoolean();
int numSensor= (int) gd.getNextNumber(); int numSensor= (int) gd.getNextNumber();
if (allFiles) numSensor=-1; if (allFiles) numSensor=-1;
boolean overwriteExtrinsic=gd.getNextBoolean(); boolean overwriteExtrinsic=gd.getNextBoolean();
if (numSensor<0) LENS_DISTORTIONS.setDistortionFromImageStack(pathname,overwriteExtrinsic); // requires fitting strategy to be set? boolean overwriteDistortion=gd.getNextBoolean();
else LENS_DISTORTIONS.setDistortionFromImageStack(pathname, numSensor,true,overwriteExtrinsic); // report missing files if (numSensor<0) LENS_DISTORTIONS.setDistortionFromImageStack(pathname,overwriteExtrinsic,overwriteDistortion); // requires fitting strategy to be set?
else LENS_DISTORTIONS.setDistortionFromImageStack(pathname, numSensor,true,overwriteExtrinsic,overwriteDistortion); // report missing files
return; return;
} }
/* ======================================================================== */ /* ======================================================================== */
...@@ -3830,6 +3844,7 @@ if (MORE_BUTTONS) { ...@@ -3830,6 +3844,7 @@ if (MORE_BUTTONS) {
FOCUS_MEASUREMENT_PARAMETERS.initialCalibrationFile, FOCUS_MEASUREMENT_PARAMETERS.initialCalibrationFile,
PATTERN_PARAMETERS, PATTERN_PARAMETERS,
EYESIS_CAMERA_PARAMETERS, // is it null or 1? EYESIS_CAMERA_PARAMETERS, // is it null or 1?
ABERRATIONS_PARAMETERS,
imp_calibrated); // gridImages null - use specified files - single image imp_calibrated); // gridImages null - use specified files - single image
if (DISTORTION_CALIBRATION_DATA.pathName== null){ // failed to select/open the file if (DISTORTION_CALIBRATION_DATA.pathName== null){ // failed to select/open the file
DISTORTION_CALIBRATION_DATA=null; DISTORTION_CALIBRATION_DATA=null;
...@@ -9549,6 +9564,49 @@ if (MORE_BUTTONS) { ...@@ -9549,6 +9564,49 @@ if (MORE_BUTTONS) {
} }
/* ===== Other methods ==================================================== */ /* ===== Other methods ==================================================== */
public void viewCSVFile(){
String [] extensions={".csv","CSV"};
CalibrationFileManagement.MultipleExtensionsFileFilter parFilter = new CalibrationFileManagement.MultipleExtensionsFileFilter("",extensions,"CSV table *.csv files");
String pathname=CalibrationFileManagement.selectFile(
true, // smart,
false,
"Restore CSV file (table)",
"Restore",
parFilter,
""); // (defaultPath==null)?this.pathName:defaultPath); //String defaultPath
if (pathname==null) return;
BufferedReader reader=null;
try {
reader = new BufferedReader( new FileReader (pathname));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
System.out.println("Error opening "+pathname+" for reading");
return;
}
String header=null;
String line = null;
StringBuilder stringBuilder = new StringBuilder();
String ls = System.getProperty("line.separator");
try {
header = reader.readLine();
} catch (IOException e) {
System.out.println("Failed to read a header from "+pathname);
try {reader.close();} catch (IOException e1) {}
return;
}
try {
while( ( line = reader.readLine() ) != null ) {
stringBuilder.append( line );
stringBuilder.append( ls );
}
} catch (IOException e) {
System.out.println("Error reading from "+pathname);
try {reader.close();} catch (IOException e1) {}
}
new TextWindow(pathname, header, stringBuilder.toString(), 500,900);
try {reader.close();} catch (IOException e1) {}
}
public void checkDefects(){ public void checkDefects(){
imp_sel = WindowManager.getCurrentImage(); imp_sel = WindowManager.getCurrentImage();
if (imp_sel==null){ if (imp_sel==null){
...@@ -10195,6 +10253,7 @@ if (MORE_BUTTONS) { ...@@ -10195,6 +10253,7 @@ if (MORE_BUTTONS) {
configPaths[0], configPaths[0],
patternParameters, patternParameters,
eyesisCameraParameters, eyesisCameraParameters,
aberrationParameters,
null); // gridImages null - use specified files null); // gridImages null - use specified files
if (distortions.fittingStrategy!=null) { if (distortions.fittingStrategy!=null) {
distortions.fittingStrategy.distortionCalibrationData=dcd; distortions.fittingStrategy.distortionCalibrationData=dcd;
...@@ -10227,7 +10286,11 @@ if (MORE_BUTTONS) { ...@@ -10227,7 +10286,11 @@ if (MORE_BUTTONS) {
if (configPaths[3] !=null){ // load sensor if (configPaths[3] !=null){ // load sensor
if (distortions.fittingStrategy==null) return false; if (distortions.fittingStrategy==null) return false;
if (DEBUG_LEVEL>0) System.out.println("Autoloading sensor calibration files "+configPaths[3]); if (DEBUG_LEVEL>0) System.out.println("Autoloading sensor calibration files "+configPaths[3]);
distortions.setDistortionFromImageStack(configPaths[3],aberrationParameters.autoRestoreSensorOverwriteOrientation); distortions.setDistortionFromImageStack(
configPaths[3],
aberrationParameters.autoRestoreSensorOverwriteOrientation,
aberrationParameters.autoRestoreSensorOverwriteDistortion
);
} }
return true; return true;
} }
...@@ -14424,7 +14487,7 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) { ...@@ -14424,7 +14487,7 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) {
} }
/* ======================================================================== */ /* ======================================================================== */
public void loadProperties( public String loadProperties(
String path, String path,
String directory, String directory,
boolean useXML, boolean useXML,
...@@ -14445,13 +14508,13 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) { ...@@ -14445,13 +14508,13 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) {
path+=patterns[0]; path+=patterns[0];
} }
} }
if (path==null) return; if (path==null) return path;
InputStream is; InputStream is;
try { try {
is = new FileInputStream(path); is = new FileInputStream(path);
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
IJ.showMessage("Error","Failed to open configuration file: "+path); IJ.showMessage("Error","Failed to open configuration file: "+path);
return; return path;
} }
if (useXML) { if (useXML) {
...@@ -14460,14 +14523,14 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) { ...@@ -14460,14 +14523,14 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) {
} catch (IOException e) { } catch (IOException e) {
IJ.showMessage("Error","Failed to read XML configuration file: "+path); IJ.showMessage("Error","Failed to read XML configuration file: "+path);
return; return path;
} }
} else { } else {
try { try {
properties.load(is); properties.load(is);
} catch (IOException e) { } catch (IOException e) {
IJ.showMessage("Error","Failed to read configuration file: "+path); IJ.showMessage("Error","Failed to read configuration file: "+path);
return; return path;
} }
} }
try { try {
...@@ -14478,6 +14541,8 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) { ...@@ -14478,6 +14541,8 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) {
} }
getAllProperties(properties); getAllProperties(properties);
if (DEBUG_LEVEL>0) System.out.println("Configuration parameters are restored from "+path); if (DEBUG_LEVEL>0) System.out.println("Configuration parameters are restored from "+path);
return path;
} }
/* ======================================================================== */ /* ======================================================================== */
public void setAllProperties(Properties properties){ public void setAllProperties(Properties properties){
...@@ -16218,7 +16283,13 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) { ...@@ -16218,7 +16283,13 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) {
double over; double over;
// individual per-thread - will be needed when converted to doubleFHT // individual per-thread - will be needed when converted to doubleFHT
// MatchSimulatedPattern matchSimulatedPattern=new MatchSimulatedPattern(FFT_SIZE); // MatchSimulatedPattern matchSimulatedPattern=new MatchSimulatedPattern(FFT_SIZE);
MatchSimulatedPattern matchSimulatedPattern=commonMatchSimulatedPattern.clone(); MatchSimulatedPattern matchSimulatedPattern=commonMatchSimulatedPattern.cloneDeep(
false, // boolean clonePATTERN_GRID,
false, // boolean cloneTargetUV,
false, // boolean clonePixelsUV,
false, // boolean cloneFlatFieldForGrid,
false // boolean cloneFocusMask
);
matchSimulatedPattern.debugLevel=DEBUG_LEVEL; matchSimulatedPattern.debugLevel=DEBUG_LEVEL;
SimulationPattern simulationPattern= new SimulationPattern(bitmaskPattern); SimulationPattern simulationPattern= new SimulationPattern(bitmaskPattern);
simulationPattern.debugLevel=DEBUG_LEVEL; simulationPattern.debugLevel=DEBUG_LEVEL;
......
...@@ -107,11 +107,18 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -107,11 +107,18 @@ import org.apache.commons.configuration.XMLConfiguration;
public double gridPeriod=0.0; // average grid period, in pixels (to filter out (double-) reflected images public 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 boolean noUsefulPSFKernels=false; // used to mark images w/o good PSF data
public double diameter=0.0; public double diameter=0.0;
public int [] UVShiftRot={0,0,0}; // shift and rotation of the grid
final int contrastIndex=2; final int contrastIndex=2;
int getSetNumber(){return this.setNumber;} int getSetNumber(){return this.setNumber;}
public GridImageParameters(int index){ public GridImageParameters(int index){
this.imgNumber=index; this.imgNumber=index;
} }
public int [] getUVShiftRot(){
return this.UVShiftRot;
}
public void setUVShiftRot(int [] UVShiftRot){
this.UVShiftRot=UVShiftRot;
}
public int getStationNumber(){ // TODO: make only a single station number - in GridImageSet? public int getStationNumber(){ // TODO: make only a single station number - in GridImageSet?
return this.stationNumber; return this.stationNumber;
} }
...@@ -1504,6 +1511,7 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -1504,6 +1511,7 @@ import org.apache.commons.configuration.XMLConfiguration;
String defaultPath, String defaultPath,
PatternParameters patternParameters, PatternParameters patternParameters,
EyesisCameraParameters eyesisCameraParameters, EyesisCameraParameters eyesisCameraParameters,
EyesisAberrations.AberrationParameters aberrationParameters,
ImagePlus[] gridImages ){ // null - use specified files ImagePlus[] gridImages ){ // null - use specified files
String [] extensions={".dcal-xml","-distcal.xml"}; String [] extensions={".dcal-xml","-distcal.xml"};
CalibrationFileManagement.MultipleExtensionsFileFilter parFilter = new CalibrationFileManagement.MultipleExtensionsFileFilter("",extensions,"Distortion calibration *.dcal-xml files"); CalibrationFileManagement.MultipleExtensionsFileFilter parFilter = new CalibrationFileManagement.MultipleExtensionsFileFilter("",extensions,"Distortion calibration *.dcal-xml files");
...@@ -1520,7 +1528,8 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -1520,7 +1528,8 @@ import org.apache.commons.configuration.XMLConfiguration;
this.gIS=null; // So readAllGrids will create it this.gIS=null; // So readAllGrids will create it
setFromXML( setFromXML(
pathname, pathname,
eyesisCameraParameters); eyesisCameraParameters,
aberrationParameters);
if (gridImages!=null) { if (gridImages!=null) {
// this.pathName=""; // modified, keep the path anyway // this.pathName=""; // modified, keep the path anyway
// overwrite saved paths with the provided images, number of images{ should match // overwrite saved paths with the provided images, number of images{ should match
...@@ -1555,7 +1564,8 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -1555,7 +1564,8 @@ import org.apache.commons.configuration.XMLConfiguration;
} }
*/ */
public void setFromXML(String pathname, public void setFromXML(String pathname,
EyesisCameraParameters eyesisCameraParameters) { EyesisCameraParameters eyesisCameraParameters,
EyesisAberrations.AberrationParameters aberrationParameters) {
this.eyesisCameraParameters=eyesisCameraParameters; this.eyesisCameraParameters=eyesisCameraParameters;
XMLConfiguration hConfig=null; XMLConfiguration hConfig=null;
...@@ -1617,11 +1627,18 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -1617,11 +1627,18 @@ import org.apache.commons.configuration.XMLConfiguration;
else this.gIP[i].setStationNumber(0); else this.gIP[i].setStationNumber(0);
if (sub.getString("enabled")!=null) this.gIP[i].enabled=Boolean.parseBoolean(sub.getString("enabled")); if (sub.getString("enabled")!=null) this.gIP[i].enabled=Boolean.parseBoolean(sub.getString("enabled"));
if (sub.getString("noUsefulPSFKernels")!=null) this.gIP[i].noUsefulPSFKernels=Boolean.parseBoolean(sub.getString("noUsefulPSFKernels")); if (sub.getString("noUsefulPSFKernels")!=null) this.gIP[i].noUsefulPSFKernels=Boolean.parseBoolean(sub.getString("noUsefulPSFKernels"));
if (sub.getString("setNumber")!=null) { this.gIP[i].setNumber=sub.getInt("setNumber",-1);
this.gIP[i].setNumber=Integer.parseInt(sub.getString("setNumber")); // new
} else { this.gIP[i].hintedMatch=sub.getInt("hintedMatch",-1);
this.gIP[i].setNumber=-1; this.gIP[i].enabled=sub.getBoolean("enabled",false);
} // if (aberrationParameters.trustEnabled && this.gIP[i].enabled) this.gIP[i].hintedMatch=2; // trusted
if (aberrationParameters.trustEnabled) this.gIP[i].hintedMatch= this.gIP[i].enabled?2:-1; // trusted and only trusted to enabled
// if (sub.getString("setNumber")!=null) {
// this.gIP[i].setNumber=Integer.parseInt(sub.getString("setNumber"));
// } else {
// this.gIP[i].setNumber=-1;
// }
for (int j=0;j<this.parameterDescriptions.length;j++){ for (int j=0;j<this.parameterDescriptions.length;j++){
if (sub.getString(parameterDescriptions[j][0])!=null) if (sub.getString(parameterDescriptions[j][0])!=null)
this.pars[i][j] = Double.parseDouble(sub.getString(parameterDescriptions[j][0])); this.pars[i][j] = Double.parseDouble(sub.getString(parameterDescriptions[j][0]));
...@@ -1632,6 +1649,12 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -1632,6 +1649,12 @@ import org.apache.commons.configuration.XMLConfiguration;
this.pars[i][j] = Double.NaN; this.pars[i][j] = Double.NaN;
} }
} }
int [] shiftRot={
sub.getInt("gridShiftX", 0),
sub.getInt("gridShiftY", 0),
sub.getInt("gridRotate", 0)};
this.gIP[i].setUVShiftRot(shiftRot);
// getInt(String key, int defaultValue)
} }
if (this.gIS!=null){ if (this.gIS!=null){
System.out.println("Using stored image set data"); System.out.println("Using stored image set data");
...@@ -1721,10 +1744,15 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -1721,10 +1744,15 @@ import org.apache.commons.configuration.XMLConfiguration;
hConfig.addProperty("file.setNumber",this.gIP[i].setNumber); hConfig.addProperty("file.setNumber",this.gIP[i].setNumber);
hConfig.addProperty("file.name",this.gIP[i].path); hConfig.addProperty("file.name",this.gIP[i].path);
hConfig.addProperty("file.enabled",this.gIP[i].enabled); hConfig.addProperty("file.enabled",this.gIP[i].enabled);
hConfig.addProperty("file.hintedMatch",this.gIP[i].hintedMatch); // new
hConfig.addProperty("file.timestamp",IJ.d2s(this.gIP[i].timestamp,6)); hConfig.addProperty("file.timestamp",IJ.d2s(this.gIP[i].timestamp,6));
hConfig.addProperty("file.channel",this.gIP[i].channel); hConfig.addProperty("file.channel",this.gIP[i].channel);
hConfig.addProperty("file.stationNumber",this.gIP[i].getStationNumber()); hConfig.addProperty("file.stationNumber",this.gIP[i].getStationNumber());
hConfig.addProperty("file.noUsefulPSFKernels",this.gIP[i].noUsefulPSFKernels); hConfig.addProperty("file.noUsefulPSFKernels",this.gIP[i].noUsefulPSFKernels);
int [] UVShiftRot=this.gIP[i].getUVShiftRot();
hConfig.addProperty("file.gridShiftX",UVShiftRot[0]);
hConfig.addProperty("file.gridShiftY",UVShiftRot[1]);
hConfig.addProperty("file.gridRotate",UVShiftRot[2]);
for (int j=0;j<this.parameterDescriptions.length;j++){ for (int j=0;j<this.parameterDescriptions.length;j++){
hConfig.addProperty("file."+parameterDescriptions[j][0],this.pars[i][j]); hConfig.addProperty("file."+parameterDescriptions[j][0],this.pars[i][j]);
} }
...@@ -1793,6 +1821,85 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -1793,6 +1821,85 @@ import org.apache.commons.configuration.XMLConfiguration;
} }
public int [] setGridsWithRemap(
int fileNumber,
int [][] reMap,
float [][] pixels,
PatternParameters patternParameters){
// boolean disableNoFlatfield=false; // true only for processing transitional images - mixture of ff/ no-ff
int sensorWidth=this.eyesisCameraParameters.getSensorWidth(this.gIP[fileNumber].channel);
int sensorHeight=this.eyesisCameraParameters.getSensorHeight(this.gIP[fileNumber].channel);
int station=this.gIP[fileNumber].getStationNumber();
int size=0;
int size_extra=0;
// int numOfGridNodes=0;
// int numOfGridNodes_extra=0;
for (int i=0;i<pixels[0].length;i++) if ((pixels[0][i]>=0) && (pixels[1][i]>=0) && (pixels[0][i]<sensorWidth) && (pixels[1][i]<sensorHeight)){
int u=(int) Math.round(pixels[2][i]);
int v=(int) Math.round(pixels[3][i]);
int u1= reMap[0][0]*u + reMap[0][1]*v + reMap[0][2]; // u
int v1= reMap[1][0]*u + reMap[1][1]*v + reMap[1][2]; // v;
// if (patternParameters.getXYZM(u,v,this.debugLevel>1)!=null) size++;
if (patternParameters.getXYZM(u1,v1,false,station)!=null) size++; // already assumes correct uv?
else size_extra++;
}
this.gIP[fileNumber].resetMask();
this.gIP[fileNumber].pixelsXY=new double [size][6];
this.gIP[fileNumber].pixelsUV=new int [size][2];
this.gIP[fileNumber].pixelsXY_extra=new double [size_extra][6];
this.gIP[fileNumber].pixelsUV_extra=new int [size_extra][2];
// numOfGridNodes+=size;
// numOfGridNodes_extra+=size_extra;
int index=0;
int index_extra=0;
// boolean vignettingAvailable=pixels.length>=8;
// this.gIP[fileNumber].flatFieldAvailable=pixels.length>=8;
// if (disableNoFlatfield && !this.gIP[fileNumber].flatFieldAvailable) this.gIP[fileNumber].enabled=false; // just to use old mixed data
for (int i=0;i<pixels[0].length;i++) if ((pixels[0][i]>=0) && (pixels[1][i]>=0) && (pixels[0][i]<sensorWidth) && (pixels[1][i]<sensorHeight)) {
int u=(int) Math.round(pixels[2][i]);
int v=(int) Math.round(pixels[3][i]);
int u1= reMap[0][0]*u + reMap[0][1]*v + reMap[0][2]; // u
int v1= reMap[1][0]*u + reMap[1][1]*v + reMap[1][2]; // v;
// if (patternParameters.getXYZM(u,v,this.debugLevel>1)!=null) {
if (patternParameters.getXYZM(u1,v1,false,station)!=null) {
this.gIP[fileNumber].pixelsXY[index][0]=pixels[0][i];
this.gIP[fileNumber].pixelsXY[index][1]=pixels[1][i];
this.gIP[fileNumber].pixelsUV[index][0]= u1; // u
this.gIP[fileNumber].pixelsUV[index][1]= v1; // v;
if (this.gIP[fileNumber].flatFieldAvailable){
this.gIP[fileNumber].pixelsXY[index][2]=pixels[4][i];
for (int n=0;n<3;n++) this.gIP[fileNumber].pixelsXY[index][n+3]=pixels[n+5][i]/this.gIP[fileNumber].intensityRange[n];
} else {
for (int n=0;n<4;n++)this.gIP[fileNumber].pixelsXY[index][n+2]=1.0;
}
index++;
} else {
this.gIP[fileNumber].pixelsXY_extra[index_extra][0]=pixels[0][i];
this.gIP[fileNumber].pixelsXY_extra[index_extra][1]=pixels[1][i];
this.gIP[fileNumber].pixelsUV_extra[index_extra][0]= u1; // u
this.gIP[fileNumber].pixelsUV_extra[index_extra][1]= v1; // v;
if (this.gIP[fileNumber].flatFieldAvailable){
this.gIP[fileNumber].pixelsXY_extra[index_extra][2]=pixels[4][i];
for (int n=0;n<3;n++){
this.gIP[fileNumber].pixelsXY_extra[index_extra][n+3]=pixels[n+5][i]/this.gIP[fileNumber].intensityRange[n];
}
} else {
for (int n=0;n<4;n++)this.gIP[fileNumber].pixelsXY_extra[index_extra][n+2]=1.0;
}
index_extra++;
}
}
int [] result = {size,size_extra};
return result;
}
public boolean readAllGrids(PatternParameters patternParameters){ public boolean readAllGrids(PatternParameters patternParameters){
boolean disableNoFlatfield=false; // true only for processing transitional images - mixture of ff/ no-ff boolean disableNoFlatfield=false; // true only for processing transitional images - mixture of ff/ no-ff
System.out.println("readAllGrids(), this.debugLevel="+this.debugLevel+" this.gIS is "+((this.gIS==null)?"null":"not null")); System.out.println("readAllGrids(), this.debugLevel="+this.debugLevel+" this.gIS is "+((this.gIS==null)?"null":"not null"));
...@@ -1829,7 +1936,7 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -1829,7 +1936,7 @@ import org.apache.commons.configuration.XMLConfiguration;
this.gIP[fileNumber].motors=getMotorPositions(imp_grid, this.numMotors); this.gIP[fileNumber].motors=getMotorPositions(imp_grid, this.numMotors);
this.gIP[fileNumber].matchedPointers=getUsedPonters(imp_grid); this.gIP[fileNumber].matchedPointers=getUsedPonters(imp_grid);
// this.gIP[fileNumber].enabled=true; // will filter separately // this.gIP[fileNumber].enabled=true; // will filter separately
this.gIP[fileNumber].hintedMatch=-1; // unknown yet // this.gIP[fileNumber].hintedMatch=-1; // unknown yet - now read from the calibration file
double [] saturations=new double [4]; double [] saturations=new double [4];
for (int i=0;i<saturations.length;i++) { for (int i=0;i<saturations.length;i++) {
...@@ -1852,6 +1959,7 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -1852,6 +1959,7 @@ import org.apache.commons.configuration.XMLConfiguration;
} }
float [][] pixels=new float[stack.getSize()][]; // now - 8 (x,y,u,v,contrast, vignR,vignG,vignB float [][] pixels=new float[stack.getSize()][]; // now - 8 (x,y,u,v,contrast, vignR,vignG,vignB
for (int i=0;i<pixels.length;i++) pixels[i]= (float[]) stack.getPixels(i+1); // pixel X : negative - no grid here for (int i=0;i<pixels.length;i++) pixels[i]= (float[]) stack.getPixels(i+1); // pixel X : negative - no grid here
if (this.eyesisCameraParameters.badNodeThreshold>0.0){ if (this.eyesisCameraParameters.badNodeThreshold>0.0){
boolean thisDebug =false; boolean thisDebug =false;
...@@ -1876,10 +1984,29 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -1876,10 +1984,29 @@ import org.apache.commons.configuration.XMLConfiguration;
if (this.debugLevel>1) { if (this.debugLevel>1) {
if (numBadNodes>0) if (numBadNodes>0)
System.out.print(" -- replaced "+numBadNodes+" bad grid nodes"); System.out.print(" -- replaced "+numBadNodes+" bad grid nodes");
System.out.println(); int [] uvrot=this.gIP[fileNumber].getUVShiftRot();
System.out.println(" shift:rot="+uvrot[0]+"/"+uvrot[1]+":"+uvrot[2]+
" enabled="+this.gIP[fileNumber].enabled+" hintedMatch="+this.gIP[fileNumber].hintedMatch);
} }
} }
this.gIP[fileNumber].flatFieldAvailable=pixels.length>=8;
if (disableNoFlatfield && !this.gIP[fileNumber].flatFieldAvailable) this.gIP[fileNumber].enabled=false; // just to use old mixed data
// start new code:
/*
this.gIP[i].UVShiftRot[0]=sub.getInt("gridShiftX", 0);
this.gIP[i].UVShiftRot[1]=sub.getInt("gridShiftY", 0);
this.gIP[i].UVShiftRot[2]=sub.getInt("gridRotate", 0);
*/
int [][] shiftRotMatrix= (new MatchSimulatedPattern()).getRemapMatrix(this.gIP[fileNumber].getUVShiftRot());
int [] sizeSizeExtra=setGridsWithRemap(
fileNumber,
shiftRotMatrix, // int [][] reMap,
pixels,
patternParameters);
numOfGridNodes+=sizeSizeExtra[0];
numOfGridNodes_extra+=sizeSizeExtra[1];
/*
int sensorWidth=this.eyesisCameraParameters.getSensorWidth(this.gIP[fileNumber].channel); int sensorWidth=this.eyesisCameraParameters.getSensorWidth(this.gIP[fileNumber].channel);
int sensorHeight=this.eyesisCameraParameters.getSensorHeight(this.gIP[fileNumber].channel); int sensorHeight=this.eyesisCameraParameters.getSensorHeight(this.gIP[fileNumber].channel);
...@@ -1890,7 +2017,7 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -1890,7 +2017,7 @@ import org.apache.commons.configuration.XMLConfiguration;
int u=(int) Math.round(pixels[2][i]); int u=(int) Math.round(pixels[2][i]);
int v=(int) Math.round(pixels[3][i]); int v=(int) Math.round(pixels[3][i]);
// if (patternParameters.getXYZM(u,v,this.debugLevel>1)!=null) size++; // if (patternParameters.getXYZM(u,v,this.debugLevel>1)!=null) size++;
if (patternParameters.getXYZM(u,v,false,station)!=null) size++; if (patternParameters.getXYZM(u,v,false,station)!=null) size++; // already assumes correct uv?
else size_extra++; else size_extra++;
} }
this.gIP[fileNumber].resetMask(); this.gIP[fileNumber].resetMask();
...@@ -1905,9 +2032,12 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -1905,9 +2032,12 @@ import org.apache.commons.configuration.XMLConfiguration;
int index=0; int index=0;
int index_extra=0; int index_extra=0;
// boolean vignettingAvailable=pixels.length>=8; // boolean vignettingAvailable=pixels.length>=8;
this.gIP[fileNumber].flatFieldAvailable=pixels.length>=8; // this.gIP[fileNumber].flatFieldAvailable=pixels.length>=8;
if (disableNoFlatfield && !this.gIP[fileNumber].flatFieldAvailable) this.gIP[fileNumber].enabled=false; // just to use old mixed data // if (disableNoFlatfield && !this.gIP[fileNumber].flatFieldAvailable) this.gIP[fileNumber].enabled=false; // just to use old mixed data
for (int i=0;i<pixels[0].length;i++) if ((pixels[0][i]>=0) && (pixels[1][i]>=0) && (pixels[0][i]<sensorWidth) && (pixels[1][i]<sensorHeight)) { for (int i=0;i<pixels[0].length;i++) if ((pixels[0][i]>=0) && (pixels[1][i]>=0) && (pixels[0][i]<sensorWidth) && (pixels[1][i]<sensorHeight)) {
int u=(int) Math.round(pixels[2][i]); int u=(int) Math.round(pixels[2][i]);
int v=(int) Math.round(pixels[3][i]); int v=(int) Math.round(pixels[3][i]);
...@@ -1940,7 +2070,7 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -1940,7 +2070,7 @@ import org.apache.commons.configuration.XMLConfiguration;
index_extra++; index_extra++;
} }
} }
*/
calcGridPeriod(fileNumber); // will be used to filter out reflections calcGridPeriod(fileNumber); // will be used to filter out reflections
//System.out.println ("pixelsXY["+fileNumber+"]length="+pixelsXY[fileNumber].length); //System.out.println ("pixelsXY["+fileNumber+"]length="+pixelsXY[fileNumber].length);
...@@ -2366,6 +2496,13 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -2366,6 +2496,13 @@ import org.apache.commons.configuration.XMLConfiguration;
if (this.gIP[numImg].gridImageSet!=null) this.gIP[numImg].gridImageSet.updateParameterVectorFromSet(parameters); if (this.gIP[numImg].gridImageSet!=null) this.gIP[numImg].gridImageSet.updateParameterVectorFromSet(parameters);
return parameters; return parameters;
} }
public int [] getUVShiftRot(int numImg){
return this.gIP[numImg].getUVShiftRot();
}
public GridImageParameters getGridImageParameters(int numImg){
return this.gIP[numImg];
}
public double [] getAzEl(int imgNum){ // get sensor azimuth and elevation DANGEROUS - absolute indices of parameters public double [] getAzEl(int imgNum){ // get sensor azimuth and elevation DANGEROUS - absolute indices of parameters
if ((imgNum<0) || (imgNum>=this.pars.length)) { if ((imgNum<0) || (imgNum>=this.pars.length)) {
String msg="There are only "+this.pars.length+" images defined, requested #"+imgNum; String msg="There are only "+this.pars.length+" images defined, requested #"+imgNum;
......
...@@ -33,7 +33,7 @@ import ij.text.TextWindow; ...@@ -33,7 +33,7 @@ import ij.text.TextWindow;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.geom.Point2D; import java.awt.geom.Point2D;
import java.util.Arrays; //import java.util.Arrays;
//import java.io.StringWriter; //import java.io.StringWriter;
import java.util.List; import java.util.List;
import java.util.ArrayList; import java.util.ArrayList;
...@@ -2602,7 +2602,9 @@ For each point in the image ...@@ -2602,7 +2602,9 @@ For each point in the image
System.out.println("\n---- applyHintedGrids() image #"+numGridImage+" (imageNumber="+imageNumber+") "+ System.out.println("\n---- applyHintedGrids() image #"+numGridImage+" (imageNumber="+imageNumber+") "+
" dcd.gIP["+numGridImage+"].pixelsXY.length="+dcd.gIP[numGridImage].pixelsXY.length+ " dcd.gIP["+numGridImage+"].pixelsXY.length="+dcd.gIP[numGridImage].pixelsXY.length+
" dcd.gIP["+numGridImage+"].pixelsXY_extra.length="+dcd.gIP[numGridImage].pixelsXY_extra.length+ " dcd.gIP["+numGridImage+"].pixelsXY_extra.length="+dcd.gIP[numGridImage].pixelsXY_extra.length+
" grid period="+dcd.gIP[numGridImage].gridPeriod " grid period="+dcd.gIP[numGridImage].gridPeriod+
" enabled="+dcd.gIP[numGridImage].enabled+
" hintedMatch="+dcd.gIP[numGridImage].hintedMatch
); );
if (this.debugLevel>(debugThreshold)){ if (this.debugLevel>(debugThreshold)){
for (int i=0;i<dcd.gIP[numGridImage].pixelsXY.length;i++){ for (int i=0;i<dcd.gIP[numGridImage].pixelsXY.length;i++){
...@@ -2626,7 +2628,7 @@ For each point in the image ...@@ -2626,7 +2628,7 @@ For each point in the image
int [][][] pixelsUVSet={ int [][][] pixelsUVSet={
dcd.gIP[numGridImage].pixelsUV, dcd.gIP[numGridImage].pixelsUV,
dcd.gIP[numGridImage].pixelsUV_extra}; dcd.gIP[numGridImage].pixelsUV_extra};
// shifts pixelsUV to have minimal u,v of 0 (stores shift in this.minUV), sets PATTERN_GRID
matchSimulatedPattern.restorePatternGridFromGridList( matchSimulatedPattern.restorePatternGridFromGridList(
pixelsXYSet, //double [][] pixelsXY, pixelsXYSet, //double [][] pixelsXY,
pixelsUVSet, // int [][] pixelsUV, pixelsUVSet, // int [][] pixelsUV,
...@@ -2702,10 +2704,10 @@ For each point in the image ...@@ -2702,10 +2704,10 @@ For each point in the image
/* System.out.println("v="+v+", u="+u); /* System.out.println("v="+v+", u="+u);
System.out.println(" matchSimulatedPattern.targetUV[v][u] is "+((matchSimulatedPattern.targetUV[v][u]==null)?"null":"not null")); System.out.println(" matchSimulatedPattern.targetUV[v][u] is "+((matchSimulatedPattern.targetUV[v][u]==null)?"null":"not null"));
System.out.println(" matchSimulatedPattern.pixelsUV[v][u] is "+((matchSimulatedPattern.pixelsUV[v][u]==null)?"null":"not null"));*/ System.out.println(" matchSimulatedPattern.pixelsUV[v][u] is "+((matchSimulatedPattern.pixelsUV[v][u]==null)?"null":"not null"));*/
if ((matchSimulatedPattern.targetUV[v][u]!=null) && (matchSimulatedPattern.pixelsUV [v][u]!=null)){ if ((matchSimulatedPattern.targetUV[v][u]!=null) && (matchSimulatedPattern.pXYUV [v][u]!=null)){
if ((matchSimulatedPattern.targetUV[v][u]!=null) && (matchSimulatedPattern.pixelsUV [v][u]!=null) && if ((matchSimulatedPattern.targetUV[v][u]!=null) && (matchSimulatedPattern.pXYUV [v][u]!=null) &&
(matchSimulatedPattern.pixelsUV[v][u][0]>=0.0) || (matchSimulatedPattern.pixelsUV[v][u][1]>=0.0)) { // disregard negative sensor pixels (matchSimulatedPattern.pXYUV[v][u][0]>=0.0) || (matchSimulatedPattern.pXYUV[v][u][1]>=0.0)) { // disregard negative sensor pixels
// System.out.println(" matchSimulatedPattern.targetUV[v][u] is "+((matchSimulatedPattern.targetUV[v][u]==null)?"null":"not null")); // System.out.println(" matchSimulatedPattern.targetUV[v][u] is "+((matchSimulatedPattern.targetUV[v][u]==null)?"null":"not null"));
// System.out.println(" matchSimulatedPattern.targetUV[v][u][0]= "+matchSimulatedPattern.targetUV[v][u][0]); // System.out.println(" matchSimulatedPattern.targetUV[v][u][0]= "+matchSimulatedPattern.targetUV[v][u][0]);
// System.out.println(" matchSimulatedPattern.targetUV[v][u][1]= "+matchSimulatedPattern.targetUV[v][u][1]); //******** // System.out.println(" matchSimulatedPattern.targetUV[v][u][1]= "+matchSimulatedPattern.targetUV[v][u][1]); //********
...@@ -2721,6 +2723,7 @@ For each point in the image ...@@ -2721,6 +2723,7 @@ For each point in the image
} }
} }
} }
// Move to DCD?
dcd.gIP[numGridImage].resetMask(); dcd.gIP[numGridImage].resetMask();
dcd.gIP[numGridImage].pixelsXY=new double [size][6]; dcd.gIP[numGridImage].pixelsXY=new double [size][6];
dcd.gIP[numGridImage].pixelsUV=new int [size][2]; dcd.gIP[numGridImage].pixelsUV=new int [size][2];
...@@ -2732,11 +2735,11 @@ For each point in the image ...@@ -2732,11 +2735,11 @@ For each point in the image
/* System.out.println("+ v="+v+", u="+u); /* System.out.println("+ v="+v+", u="+u);
System.out.println(" + matchSimulatedPattern.targetUV[v][u] is "+((matchSimulatedPattern.targetUV[v][u]==null)?"null":"not null")); System.out.println(" + matchSimulatedPattern.targetUV[v][u] is "+((matchSimulatedPattern.targetUV[v][u]==null)?"null":"not null"));
System.out.println(" + matchSimulatedPattern.pixelsUV[v][u] is "+((matchSimulatedPattern.pixelsUV[v][u]==null)?"null":"not null"));*/ System.out.println(" + matchSimulatedPattern.pixelsUV[v][u] is "+((matchSimulatedPattern.pixelsUV[v][u]==null)?"null":"not null"));*/
if ((matchSimulatedPattern.targetUV[v][u]!=null) &&(matchSimulatedPattern.pixelsUV[v][u]!=null) ) { if ((matchSimulatedPattern.targetUV[v][u]!=null) &&(matchSimulatedPattern.pXYUV[v][u]!=null) ) {
// System.out.println("++ v="+v+", u="+u+" index="+index+" ("+size+"), index_extra="+index_extra+" ("+size_extra+")"); // System.out.println("++ v="+v+", u="+u+" index="+index+" ("+size+"), index_extra="+index_extra+" ("+size_extra+")");
if ((matchSimulatedPattern.targetUV[v][u]!=null) &&(matchSimulatedPattern.pixelsUV[v][u]!=null) && if ((matchSimulatedPattern.targetUV[v][u]!=null) &&(matchSimulatedPattern.pXYUV[v][u]!=null) &&
(matchSimulatedPattern.pixelsUV[v][u][0]>=0.0) || (matchSimulatedPattern.pixelsUV[v][u][1]>=0.0)) { // disregard negative sensor pixels (matchSimulatedPattern.pXYUV[v][u][0]>=0.0) || (matchSimulatedPattern.pXYUV[v][u][1]>=0.0)) { // disregard negative sensor pixels
if ( if (
(v>=matchSimulatedPattern.gridContrastBrightness[0].length) || (v>=matchSimulatedPattern.gridContrastBrightness[0].length) ||
(u>=matchSimulatedPattern.gridContrastBrightness[0][0].length)){ (u>=matchSimulatedPattern.gridContrastBrightness[0][0].length)){
...@@ -2746,10 +2749,10 @@ For each point in the image ...@@ -2746,10 +2749,10 @@ For each point in the image
" v="+v+" u="+u); " v="+v+" u="+u);
} }
} }
// setting dcd.gIP[numGridImage].pixelsUV[index] with rotated/shifted
if (patternParameters.getXYZM(matchSimulatedPattern.targetUV[v][u][0],matchSimulatedPattern.targetUV[v][u][1],false,station)!=null) { if (patternParameters.getXYZM(matchSimulatedPattern.targetUV[v][u][0],matchSimulatedPattern.targetUV[v][u][1],false,station)!=null) {
dcd.gIP[numGridImage].pixelsXY[index][0]=matchSimulatedPattern.pixelsUV[v][u][0]; dcd.gIP[numGridImage].pixelsXY[index][0]=matchSimulatedPattern.pXYUV[v][u][0];
dcd.gIP[numGridImage].pixelsXY[index][1]=matchSimulatedPattern.pixelsUV[v][u][1]; dcd.gIP[numGridImage].pixelsXY[index][1]=matchSimulatedPattern.pXYUV[v][u][1];
dcd.gIP[numGridImage].pixelsUV[index][0]=matchSimulatedPattern.targetUV[v][u][0]; dcd.gIP[numGridImage].pixelsUV[index][0]=matchSimulatedPattern.targetUV[v][u][0];
dcd.gIP[numGridImage].pixelsUV[index][1]=matchSimulatedPattern.targetUV[v][u][1]; dcd.gIP[numGridImage].pixelsUV[index][1]=matchSimulatedPattern.targetUV[v][u][1];
dcd.gIP[numGridImage].pixelsXY[index][2]=matchSimulatedPattern.gridContrastBrightness[0][v][u]; // grid contrast dcd.gIP[numGridImage].pixelsXY[index][2]=matchSimulatedPattern.gridContrastBrightness[0][v][u]; // grid contrast
...@@ -2758,8 +2761,8 @@ For each point in the image ...@@ -2758,8 +2761,8 @@ For each point in the image
dcd.gIP[numGridImage].pixelsXY[index][5]=matchSimulatedPattern.gridContrastBrightness[3][v][u]/dcd.gIP[numGridImage].intensityRange[2]; // blue dcd.gIP[numGridImage].pixelsXY[index][5]=matchSimulatedPattern.gridContrastBrightness[3][v][u]/dcd.gIP[numGridImage].intensityRange[2]; // blue
index++; index++;
} else { } else {
dcd.gIP[numGridImage].pixelsXY_extra[index_extra][0]=matchSimulatedPattern.pixelsUV[v][u][0]; dcd.gIP[numGridImage].pixelsXY_extra[index_extra][0]=matchSimulatedPattern.pXYUV[v][u][0];
dcd.gIP[numGridImage].pixelsXY_extra[index_extra][1]=matchSimulatedPattern.pixelsUV[v][u][1]; dcd.gIP[numGridImage].pixelsXY_extra[index_extra][1]=matchSimulatedPattern.pXYUV[v][u][1];
dcd.gIP[numGridImage].pixelsUV_extra[index_extra][0]=matchSimulatedPattern.targetUV[v][u][0]; dcd.gIP[numGridImage].pixelsUV_extra[index_extra][0]=matchSimulatedPattern.targetUV[v][u][0];
dcd.gIP[numGridImage].pixelsUV_extra[index_extra][1]=matchSimulatedPattern.targetUV[v][u][1]; dcd.gIP[numGridImage].pixelsUV_extra[index_extra][1]=matchSimulatedPattern.targetUV[v][u][1];
dcd.gIP[numGridImage].pixelsXY_extra[index_extra][2]=matchSimulatedPattern.gridContrastBrightness[0][v][u]; // grid contrast dcd.gIP[numGridImage].pixelsXY_extra[index_extra][2]=matchSimulatedPattern.gridContrastBrightness[0][v][u]; // grid contrast
...@@ -2773,8 +2776,21 @@ For each point in the image ...@@ -2773,8 +2776,21 @@ For each point in the image
dcd.gIP[numGridImage].hintedMatch =(hintGridTolerance>0.0)?2:1; // orientation or both orientation and translation dcd.gIP[numGridImage].hintedMatch =(hintGridTolerance>0.0)?2:1; // orientation or both orientation and translation
dcd.gIP[numGridImage].matchedPointers=rslt; // update number of matched pointers dcd.gIP[numGridImage].matchedPointers=rslt; // update number of matched pointers
if ((dcd.gIP[numGridImage].hintedMatch>1) || (dcd.gIP[numGridImage].matchedPointers>0)) numSuccess++; if ((dcd.gIP[numGridImage].hintedMatch>1) || (dcd.gIP[numGridImage].matchedPointers>0)) numSuccess++;
// Update rotation/shift
//matchSimulatedPattern
int [] fileUVShiftRot=dcd.gIP[numGridImage].getUVShiftRot();
int [] extraUVShiftRot=matchSimulatedPattern.getUVShiftRot(true); // last shift/rotation during matching pattern, correct for zero shift
int [] extraDbg=matchSimulatedPattern.getUVShiftRot(false);
int [] combinedUVShiftRot=matchSimulatedPattern.combineUVShiftRot(fileUVShiftRot,extraUVShiftRot);
dcd.gIP[numGridImage].setUVShiftRot(combinedUVShiftRot);
System.out.println("applyHintedGrids(): dcd.gIP["+numGridImage+"].hintedMatch="+dcd.gIP[numGridImage].hintedMatch+ System.out.println("applyHintedGrids(): dcd.gIP["+numGridImage+"].hintedMatch="+dcd.gIP[numGridImage].hintedMatch+
" dcd.gIP["+numGridImage+"].matchedPointers="+dcd.gIP[numGridImage].matchedPointers+ " points:"+index+" extra points:"+index_extra); " dcd.gIP["+numGridImage+"].matchedPointers="+dcd.gIP[numGridImage].matchedPointers+ " points:"+index+" extra points:"+index_extra);
// testing rot/shift:
String nonzero=((extraUVShiftRot[0]==0)&&(extraUVShiftRot[1]==0)&&(extraUVShiftRot[2]==0))?" ":"*";
System.out.println("applyHintedGrids(): fileUVShiftRot= "+fileUVShiftRot[0]+"/"+fileUVShiftRot[1]+":"+fileUVShiftRot[2]);
System.out.println(" "+nonzero+"extraUVShiftRot= "+extraUVShiftRot[0]+"/"+extraUVShiftRot[1]+":"+extraUVShiftRot[2]);
System.out.println(" combinedUVShiftRot="+combinedUVShiftRot[0]+"/"+combinedUVShiftRot[1]+":"+combinedUVShiftRot[2]);
System.out.println(" extraDbg="+extraDbg[0]+"/"+extraDbg[1]+":"+extraDbg[2]);
} }
} }
} }
...@@ -3664,6 +3680,7 @@ List calibration ...@@ -3664,6 +3680,7 @@ List calibration
errors, errors,
numPairs, numPairs,
this.showIndex, this.showIndex,
true, // grid match
this.showRMS, this.showRMS,
this.showPoints, this.showPoints,
this.showLensLocation, this.showLensLocation,
...@@ -4055,6 +4072,7 @@ List calibration ...@@ -4055,6 +4072,7 @@ List calibration
double [] errors, double [] errors,
int [] numPairs, int [] numPairs,
boolean showIndex, boolean showIndex,
boolean showGridMatch,
boolean showErrors, boolean showErrors,
boolean showPoints, boolean showPoints,
boolean showLensCoordinates, boolean showLensCoordinates,
...@@ -4104,6 +4122,32 @@ List calibration ...@@ -4104,6 +4122,32 @@ List calibration
} }
sb.append("\n"); sb.append("\n");
}
if (showGridMatch){
sb.append("Grid Match"+"\tX/Y:ROT");
for (int imgIndex=0;imgIndex<numImages;imgIndex++){
int imgNum=imgIndices[imgIndex]; // image number
int [] shiftRot=fittingStrategy.distortionCalibrationData.getUVShiftRot(imgNum);
sb.append("\t"+shiftRot[0]+"/"+shiftRot[1]+":"+shiftRot[2]);
}
sb.append("\n");
sb.append("Lasers(matched)"+"\t");
for (int imgIndex=0;imgIndex<numImages;imgIndex++){
int imgNum=imgIndices[imgIndex]; // image number
int numPointers=0; // count number of laser pointers
DistortionCalibrationData.GridImageParameters gip=fittingStrategy.distortionCalibrationData.getGridImageParameters(imgNum);
if (gip.laserPixelCoordinates!=null){
for (int j=0;j<gip.laserPixelCoordinates.length;j++) if (gip.laserPixelCoordinates[j]!=null) numPointers++;
}
sb.append("\t");
if (!gip.enabled) sb.append("(");
sb.append(numPointers+"("+gip.matchedPointers+"):"+gip.hintedMatch +
" "+IJ.d2s(gip.gridPeriod,1));
if (!gip.enabled) sb.append(")");
}
sb.append("\n");
} }
if (showErrors) { if (showErrors) {
sb.append("--- RMS "+IJ.d2s(rms,3+extraDecimals)+"\tpix"); sb.append("--- RMS "+IJ.d2s(rms,3+extraDecimals)+"\tpix");
...@@ -4996,7 +5040,7 @@ List calibration ...@@ -4996,7 +5040,7 @@ List calibration
" ("+IJ.d2s(this.currentRMSPure,8)+")"+ " ("+IJ.d2s(this.currentRMSPure,8)+")"+
". Calculating next Jacobian. Points:"+this.Y.length+" Parameters:"+this.currentVector.length); ". Calculating next Jacobian. Points:"+this.Y.length+" Parameters:"+this.currentVector.length);
} }
if (this.debugLevel>1) { if ((this.debugLevel>0) && ((this.debugLevel>1) || ((System.nanoTime()-this.startTime)>10000000000.0))) {
System.out.println(this.seriesNumber+": initial RMS="+IJ.d2s(this.currentRMS,8)+ System.out.println(this.seriesNumber+": initial RMS="+IJ.d2s(this.currentRMS,8)+
" ("+IJ.d2s(this.currentRMSPure,8)+")"+ " ("+IJ.d2s(this.currentRMSPure,8)+")"+
". Calculating next Jacobian. Points:"+this.Y.length+" Parameters:"+this.currentVector.length); ". Calculating next Jacobian. Points:"+this.Y.length+" Parameters:"+this.currentVector.length);
...@@ -5945,13 +5989,16 @@ List calibration ...@@ -5945,13 +5989,16 @@ List calibration
} }
public void setDistortionFromImageStack(String path, boolean overwriteExtrinsic){ public void setDistortionFromImageStack(
String path,
boolean overwriteExtrinsic,
boolean overwriteDistortion){
int indexPeriod=path.indexOf('.',path.lastIndexOf(Prefs.getFileSeparator())); int indexPeriod=path.indexOf('.',path.lastIndexOf(Prefs.getFileSeparator()));
int numSubCameras=fittingStrategy.distortionCalibrationData.eyesisCameraParameters.eyesisSubCameras[0].length; int numSubCameras=fittingStrategy.distortionCalibrationData.eyesisCameraParameters.eyesisSubCameras[0].length;
for (int chNum=0;chNum<numSubCameras;chNum++){ for (int chNum=0;chNum<numSubCameras;chNum++){
String channelPath=path.substring(0,indexPeriod-2)+String.format("%02d",chNum)+path.substring(indexPeriod); String channelPath=path.substring(0,indexPeriod-2)+String.format("%02d",chNum)+path.substring(indexPeriod);
try { // disable here for now try { // disable here for now
setDistortionFromImageStack(channelPath, chNum, false, overwriteExtrinsic); setDistortionFromImageStack(channelPath, chNum, false, overwriteExtrinsic, overwriteDistortion);
} catch (Exception e) { } catch (Exception e) {
System.out.println("setDistortionFromImageStack(): " + e.toString()); System.out.println("setDistortionFromImageStack(): " + e.toString());
e.printStackTrace(); e.printStackTrace();
...@@ -5959,7 +6006,12 @@ List calibration ...@@ -5959,7 +6006,12 @@ List calibration
} }
} }
public void setDistortionFromImageStack(String path, int numSensor, boolean reportProblems, boolean overwriteExtrinsic){ public void setDistortionFromImageStack(
String path,
int numSensor,
boolean reportProblems,
boolean overwriteExtrinsic,
boolean overwriteDistortion){
Opener opener=new Opener(); Opener opener=new Opener();
ImagePlus imp=opener.openImage("", path); ImagePlus imp=opener.openImage("", path);
if (imp==null) { if (imp==null) {
...@@ -5971,12 +6023,16 @@ List calibration ...@@ -5971,12 +6023,16 @@ List calibration
} }
if (this.debugLevel>0) System.out.println("Read "+path+" as a sensor calibration data"); if (this.debugLevel>0) System.out.println("Read "+path+" as a sensor calibration data");
(new JP46_Reader_camera(false)).decodeProperiesFromInfo(imp); (new JP46_Reader_camera(false)).decodeProperiesFromInfo(imp);
setDistortionFromImageStack(imp, numSensor, overwriteExtrinsic); setDistortionFromImageStack(imp, numSensor, overwriteExtrinsic, overwriteDistortion);
this.pathNames[numSensor]=path; this.pathNames[numSensor]=path;
} }
//TODO: look more after testing. Currently all station parameters are set from the sensor images, may be minor differences //TODO: look more after testing. Currently all station parameters are set from the sensor images, may be minor differences
public void setDistortionFromImageStack(ImagePlus imp, int numSensor, boolean overwriteExtrinsic){ public void setDistortionFromImageStack(
ImagePlus imp,
int numSensor,
boolean overwriteExtrinsic,
boolean overwriteDistortion){
// int corrX=0,corrY=1, // int corrX=0,corrY=1,
int corrMask=2; int corrMask=2;
if (numSensor<0) { if (numSensor<0) {
...@@ -6104,8 +6160,8 @@ List calibration ...@@ -6104,8 +6160,8 @@ List calibration
if (imageSubCam==numSensor){ if (imageSubCam==numSensor){
// vector from the data we just set // vector from the data we just set
double [] parVector=fittingStrategy.distortionCalibrationData.eyesisCameraParameters.getParametersVector(stationNumber,imageSubCam); double [] parVector=fittingStrategy.distortionCalibrationData.eyesisCameraParameters.getParametersVector(stationNumber,imageSubCam);
if (overwriteExtrinsic) fittingStrategy.distortionCalibrationData.setSubcameraParameters(parVector,imgNum); if (overwriteExtrinsic) fittingStrategy.distortionCalibrationData.setSubcameraParameters(parVector,imgNum);
else fittingStrategy.distortionCalibrationData.setIntrinsicParameters(parVector,imgNum); else if (overwriteDistortion) fittingStrategy.distortionCalibrationData.setIntrinsicParameters(parVector,imgNum);
} }
} }
...@@ -9987,6 +10043,7 @@ M * V = B ...@@ -9987,6 +10043,7 @@ M * V = B
boolean [] selectedImagesDebug=null; boolean [] selectedImagesDebug=null;
boolean debugThis=false; boolean debugThis=false;
int maxDebugImages=10; int maxDebugImages=10;
if (this.debugLevel>0) System.out.println("updateCameraParametersFromCalculated("+allImages+")");
if (this.debugLevel>2){ if (this.debugLevel>2){
int numSel=0; int numSel=0;
for (int i=0;i<selectedImages.length;i++) if (selectedImages[i]) numSel++; for (int i=0;i<selectedImages.length;i++) if (selectedImages[i]) numSel++;
......
...@@ -2304,7 +2304,14 @@ public class EyesisAberrations { ...@@ -2304,7 +2304,14 @@ public class EyesisAberrations {
// double [] sum_kern_el=new double[6]; // just testing // double [] sum_kern_el=new double[6]; // just testing
int x0,y0,nTX,nTY,nChn; int x0,y0,nTX,nTY,nChn;
double [][] kernels; double [][] kernels;
MatchSimulatedPattern matchSimulatedPattern=commonMatchSimulatedPattern.clone(); // change to true (first 2 only?) to separate memory arrays for threads
MatchSimulatedPattern matchSimulatedPattern=commonMatchSimulatedPattern.cloneDeep(
false, // boolean clonePATTERN_GRID,
false, // boolean cloneTargetUV,
false, // boolean clonePixelsUV,
false, // boolean cloneFlatFieldForGrid,
false // boolean cloneFocusMask
);
matchSimulatedPattern.debugLevel=globalDebugLevel; matchSimulatedPattern.debugLevel=globalDebugLevel;
SimulationPattern simulationPattern= new SimulationPattern(bitmaskPattern); SimulationPattern simulationPattern= new SimulationPattern(bitmaskPattern);
simulationPattern.debugLevel=globalDebugLevel; simulationPattern.debugLevel=globalDebugLevel;
...@@ -4478,10 +4485,12 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4478,10 +4485,12 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
public String strategyPath=""; public String strategyPath="";
public String gridPath=""; public String gridPath="";
public String sensorsPath=""; public String sensorsPath="";
public boolean autoRestoreSensorOverwriteOrientation=true; // overwrite camera parameters from sensor calibration files public boolean autoRestoreSensorOverwriteOrientation=false; // dangerous! true; // overwrite camera parameters from sensor calibration files
public boolean autoRestoreSensorOverwriteDistortion= false; // dangerous! true; // overwrite camera parameters from sensor calibration files
public boolean autoReCalibrate=true; // Re-calibrate grids on autoload public boolean autoReCalibrate=true; // Re-calibrate grids on autoload
public boolean autoReCalibrateIgnoreLaser=false; // "Ignore laser pointers on recalibrate" public boolean autoReCalibrateIgnoreLaser=false; // "Ignore laser pointers on recalibrate"
public boolean autoFilter=true; public boolean autoFilter=false; // true;
public boolean trustEnabled= true; // mark all enabled images as hintedMatch=2 on Read Calibration
public boolean noMessageBoxes=true; public boolean noMessageBoxes=true;
public boolean overwriteResultFiles=false; public boolean overwriteResultFiles=false;
public boolean partialToReprojected=true; // Use reprojected grid for partial kernel calculation (false - use extracted) public boolean partialToReprojected=true; // Use reprojected grid for partial kernel calculation (false - use extracted)
...@@ -4514,9 +4523,11 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4514,9 +4523,11 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
properties.setProperty(prefix+"gridPath",this.gridPath); properties.setProperty(prefix+"gridPath",this.gridPath);
properties.setProperty(prefix+"sensorsPath",this.sensorsPath); properties.setProperty(prefix+"sensorsPath",this.sensorsPath);
properties.setProperty(prefix+"autoRestoreSensorOverwriteOrientation",this.autoRestoreSensorOverwriteOrientation+""); properties.setProperty(prefix+"autoRestoreSensorOverwriteOrientation",this.autoRestoreSensorOverwriteOrientation+"");
properties.setProperty(prefix+"autoRestoreSensorOverwriteDistortion",this.autoRestoreSensorOverwriteDistortion+"");
properties.setProperty(prefix+"autoReCalibrate",this.autoReCalibrate+""); properties.setProperty(prefix+"autoReCalibrate",this.autoReCalibrate+"");
properties.setProperty(prefix+"autoReCalibrateIgnoreLaser",this.autoReCalibrateIgnoreLaser+""); properties.setProperty(prefix+"autoReCalibrateIgnoreLaser",this.autoReCalibrateIgnoreLaser+"");
properties.setProperty(prefix+"autoFilter",this.autoFilter+""); properties.setProperty(prefix+"autoFilter",this.autoFilter+"");
properties.setProperty(prefix+"trustEnabled",this.trustEnabled+"");
properties.setProperty(prefix+"noMessageBoxes",this.noMessageBoxes+""); properties.setProperty(prefix+"noMessageBoxes",this.noMessageBoxes+"");
properties.setProperty(prefix+"overwriteResultFiles",this.overwriteResultFiles+""); properties.setProperty(prefix+"overwriteResultFiles",this.overwriteResultFiles+"");
properties.setProperty(prefix+"partialToReprojected",this.partialToReprojected+""); properties.setProperty(prefix+"partialToReprojected",this.partialToReprojected+"");
...@@ -4557,11 +4568,13 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4557,11 +4568,13 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
if (properties.getProperty(prefix+"sensorsPath")!=null) this.sensorsPath=properties.getProperty(prefix+"sensorsPath"); if (properties.getProperty(prefix+"sensorsPath")!=null) this.sensorsPath=properties.getProperty(prefix+"sensorsPath");
if (properties.getProperty(prefix+"autoRestoreSensorOverwriteOrientation")!=null) if (properties.getProperty(prefix+"autoRestoreSensorOverwriteOrientation")!=null)
this.autoRestoreSensorOverwriteOrientation=Boolean.parseBoolean(properties.getProperty(prefix+"autoRestoreSensorOverwriteOrientation")); this.autoRestoreSensorOverwriteOrientation=Boolean.parseBoolean(properties.getProperty(prefix+"autoRestoreSensorOverwriteOrientation"));
if (properties.getProperty(prefix+"autoRestoreSensorOverwriteDistortion")!=null)
this.autoRestoreSensorOverwriteDistortion=Boolean.parseBoolean(properties.getProperty(prefix+"autoRestoreSensorOverwriteDistortion"));
if (properties.getProperty(prefix+"autoReCalibrate")!=null) this.autoReCalibrate=Boolean.parseBoolean(properties.getProperty(prefix+"autoReCalibrate")); if (properties.getProperty(prefix+"autoReCalibrate")!=null) this.autoReCalibrate=Boolean.parseBoolean(properties.getProperty(prefix+"autoReCalibrate"));
if (properties.getProperty(prefix+"autoReCalibrateIgnoreLaser")!=null) this.autoReCalibrateIgnoreLaser=Boolean.parseBoolean(properties.getProperty(prefix+"autoReCalibrateIgnoreLaser")); if (properties.getProperty(prefix+"autoReCalibrateIgnoreLaser")!=null) this.autoReCalibrateIgnoreLaser=Boolean.parseBoolean(properties.getProperty(prefix+"autoReCalibrateIgnoreLaser"));
if (properties.getProperty(prefix+"autoFilter")!=null) this.autoFilter=Boolean.parseBoolean(properties.getProperty(prefix+"autoFilter")); if (properties.getProperty(prefix+"autoFilter")!=null) this.autoFilter=Boolean.parseBoolean(properties.getProperty(prefix+"autoFilter"));
if (properties.getProperty(prefix+"trustEnabled")!=null) this.trustEnabled=Boolean.parseBoolean(properties.getProperty(prefix+"trustEnabled"));
if (properties.getProperty(prefix+"noMessageBoxes")!=null) this.noMessageBoxes=Boolean.parseBoolean(properties.getProperty(prefix+"noMessageBoxes")); if (properties.getProperty(prefix+"noMessageBoxes")!=null) this.noMessageBoxes=Boolean.parseBoolean(properties.getProperty(prefix+"noMessageBoxes"));
if (properties.getProperty(prefix+"overwriteResultFiles")!=null) this.overwriteResultFiles=Boolean.parseBoolean(properties.getProperty(prefix+"overwriteResultFiles")); if (properties.getProperty(prefix+"overwriteResultFiles")!=null) this.overwriteResultFiles=Boolean.parseBoolean(properties.getProperty(prefix+"overwriteResultFiles"));
if (properties.getProperty(prefix+"partialToReprojected")!=null) this.partialToReprojected=Boolean.parseBoolean(properties.getProperty(prefix+"partialToReprojected")); if (properties.getProperty(prefix+"partialToReprojected")!=null) this.partialToReprojected=Boolean.parseBoolean(properties.getProperty(prefix+"partialToReprojected"));
...@@ -4706,10 +4719,13 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4706,10 +4719,13 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
gd.addCheckbox("Process all enabled image files (false - use selected fitting series)", this.allImages); gd.addCheckbox("Process all enabled image files (false - use selected fitting series)", this.allImages);
gd.addMessage("===== Autoload options (when restoring configuration) ====="); gd.addMessage("===== Autoload options (when restoring configuration) =====");
gd.addCheckbox("Autoload additional files on \"Restore\"", this.autoRestore); gd.addCheckbox("Autoload additional files on \"Restore\"", this.autoRestore);
gd.addCheckbox("Overwrite SFE parameters from the sensor calibration files (at auto-load)", this.autoRestoreSensorOverwriteOrientation); gd.addCheckbox("Overwrite all (including position/orientation) SFE parameters from the sensor calibration files (at auto-load) DANGEROUS!", this.autoRestoreSensorOverwriteOrientation);
gd.addCheckbox("Overwrite SFE distortion parameters from the sensor calibration files (at auto-load) DANGEROUS!", this.autoRestoreSensorOverwriteDistortion);
gd.addCheckbox("Re-calibrate grids on autoload", this.autoReCalibrate); gd.addCheckbox("Re-calibrate grids on autoload", this.autoReCalibrate);
gd.addCheckbox("Ignore laser pointers on recalibrate", this.autoReCalibrateIgnoreLaser); gd.addCheckbox("Ignore laser pointers on recalibrate", this.autoReCalibrateIgnoreLaser);
gd.addCheckbox("Filter grids after restore", this.autoFilter); gd.addCheckbox("Filter grids after restore", this.autoFilter);
gd.addCheckbox("Trust enabled images on input (mark as hintedGrid=2)", this.trustEnabled);
gd.addMessage("Calibration: "+(((this.calibrationPath==null) || (this.calibrationPath.length()==0))?"not configured ":(this.calibrationPath+" "))+ gd.addMessage("Calibration: "+(((this.calibrationPath==null) || (this.calibrationPath.length()==0))?"not configured ":(this.calibrationPath+" "))+
((currentConfigs[0]!=null)?("(current: "+currentConfigs[0]+")"):("") )); ((currentConfigs[0]!=null)?("(current: "+currentConfigs[0]+")"):("") ));
...@@ -4753,10 +4769,12 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4753,10 +4769,12 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
this.allImages= gd.getNextBoolean(); this.allImages= gd.getNextBoolean();
this.autoRestore= gd.getNextBoolean(); this.autoRestore= gd.getNextBoolean();
this.autoRestoreSensorOverwriteOrientation= gd.getNextBoolean(); this.autoRestoreSensorOverwriteOrientation= gd.getNextBoolean();
this.autoRestoreSensorOverwriteDistortion= gd.getNextBoolean();
this.autoReCalibrate= gd.getNextBoolean(); this.autoReCalibrate= gd.getNextBoolean();
this.autoReCalibrateIgnoreLaser=gd.getNextBoolean(); this.autoReCalibrateIgnoreLaser=gd.getNextBoolean();
this.autoFilter= gd.getNextBoolean(); this.autoFilter= gd.getNextBoolean();
this.trustEnabled= gd.getNextBoolean();
if (gd.getNextBoolean()) { if (gd.getNextBoolean()) {
if (currentConfigs[0]!=null) this.calibrationPath=currentConfigs[0]; if (currentConfigs[0]!=null) this.calibrationPath=currentConfigs[0];
if (currentConfigs[1]!=null) this.strategyPath= currentConfigs[1]; if (currentConfigs[1]!=null) this.strategyPath= currentConfigs[1];
......
...@@ -1588,15 +1588,17 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit ...@@ -1588,15 +1588,17 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
if (numEstimated>0) selectEstimated=gd.getNextBoolean(); if (numEstimated>0) selectEstimated=gd.getNextBoolean();
boolean selectNewEnabled=false; boolean selectNewEnabled=false;
if (numNewEnabled>0) selectNewEnabled=gd.getNextBoolean(); if (numNewEnabled>0) selectNewEnabled=gd.getNextBoolean();
if (selectNewEnabled) {
this.selectedImages[numSeries]=this.distortionCalibrationData.selectNewEnabled();
return numSeries; // caller will repeat with the same series
}
if (this.distortionCalibrationData.eyesisCameraParameters.numStations>1){ if (this.distortionCalibrationData.eyesisCameraParameters.numStations>1){
// boolean removeUnselectedStations=gd.getNextBoolean(); // boolean removeUnselectedStations=gd.getNextBoolean();
for (int i=0;i<constrainByStation.length; i++) constrainByStation[i]=gd.getNextBoolean(); for (int i=0;i<constrainByStation.length; i++) constrainByStation[i]=gd.getNextBoolean();
} }
if (selectNewEnabled) {
this.selectedImages[numSeries]=this.distortionCalibrationData.selectNewEnabled();
for (int i =0; i<this.distortionCalibrationData.getNumImages();i++){
this.selectedImages[numSeries][i]&=constrainByStation[this.distortionCalibrationData.gIP[i].getStationNumber()];
}
return numSeries; // caller will repeat with the same series
}
if (selectEstimated) { if (selectEstimated) {
this.selectedImages[numSeries]=this.distortionCalibrationData.selectEstimated(true); //(boolean enabledOnly this.selectedImages[numSeries]=this.distortionCalibrationData.selectEstimated(true); //(boolean enabledOnly
...@@ -1613,6 +1615,9 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit ...@@ -1613,6 +1615,9 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
} else { } else {
System.out.println("Could not copy from invalid series "+sourceSeries); System.out.println("Could not copy from invalid series "+sourceSeries);
} }
for (int i =0; i<this.distortionCalibrationData.getNumImages();i++){
this.selectedImages[numSeries][i]&=constrainByStation[this.distortionCalibrationData.gIP[i].getStationNumber()];
}
return numSeries; // caller will repeat with the same series return numSeries; // caller will repeat with the same series
} }
if (removeAllImages || selectAllImages) { if (removeAllImages || selectAllImages) {
......
...@@ -923,6 +923,7 @@ dPXmmc/dphi= ...@@ -923,6 +923,7 @@ dPXmmc/dphi=
double zp, // target point horizontal, positive - away from camera, mm double zp, // target point horizontal, positive - away from camera, mm
boolean calculateAll){ // calculate derivatives, false - values only boolean calculateAll){ // calculate derivatives, false - values only
// this.cummulativeCorrection=false; // just debugging // this.cummulativeCorrection=false; // just debugging
final double maxRelativeRadius=2.0; // make configurable?
// TODO - add reduced calculations for less terms? // TODO - add reduced calculations for less terms?
// final int numDerivatives=44; // 18+6*2+7*2; // 18 for radial and 26 more for non-radial // final int numDerivatives=44; // 18+6*2+7*2; // 18 for radial and 26 more for non-radial
...@@ -1190,9 +1191,9 @@ dPXmmc/dphi= ...@@ -1190,9 +1191,9 @@ dPXmmc/dphi=
partDeriv[0][0]= 1000.0/this.pixelSize*xyDist[0] + this.px0; partDeriv[0][0]= 1000.0/this.pixelSize*xyDist[0] + this.px0;
partDeriv[0][1]= -1000.0/this.pixelSize*xyDist[1] + this.py0; partDeriv[0][1]= -1000.0/this.pixelSize*xyDist[1] + this.py0;
if (!calculateAll) { if (!calculateAll) { // TODO: how to deal with it when calculating Jacobian???
// TODO: Looking away from the target, trying only with no dervatives. Do the same for derivatives too? // TODO: Looking away from the target, trying only with no dervatives. Do the same for derivatives too?
if (XeYeZe[2]<0.0) { if ((XeYeZe[2]<0.0) || ((xmmc*xmmc+ymmc*ymmc)>maxRelativeRadius*maxRelativeRadius)){ // non-distorted too far from the axis
partDeriv[0][0]=Double.NaN; partDeriv[0][0]=Double.NaN;
partDeriv[0][1]=Double.NaN; partDeriv[0][1]=Double.NaN;
} }
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
** MatchSimulatedPattern.java - Determine simulation pattern parameters to match ** MatchSimulatedPattern.java - Determine simulation pattern parameters to match
** the acquired image ** the acquired image
** **
** Copyright (C) 2010-2011 Elphel, Inc. ** Copyright (C) 2010-2014 Elphel, Inc.
** **
** -----------------------------------------------------------------------------** ** -----------------------------------------------------------------------------**
** **
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
import java.awt.Rectangle; import java.awt.Rectangle;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Properties; import java.util.Properties;
import java.util.Queue; import java.util.Queue;
...@@ -51,9 +52,12 @@ public class MatchSimulatedPattern { ...@@ -51,9 +52,12 @@ public class MatchSimulatedPattern {
public int debugLevel=2; public int debugLevel=2;
public int FFT_SIZE=256; public int FFT_SIZE=256;
public double [][][][] PATTERN_GRID=null; // global to be used with threads? TODO: Same as DIST_ARRAY - merge? public double [][][][] PATTERN_GRID=null; // global to be used with threads? TODO: Same as DIST_ARRAY - merge?
public int [][] reMap=null; // maps grid coordinates from laser pointers to PATTERN_GRID u,v (2x3 - rotation + translation) public int [] minUV={0,0};
public int [][] reMap=null; // maps grid coordinates from laser pointers to PATTERN_GRID u,v (2x3 - rotation + translation) - SEEMS NOT USED!
public int [] UVShiftRot={0,0,0}; // {shift U, shift V, rot (1 of 8 - 4 non-mirrored, 4 - mirrored}
public int [][][] targetUV=null; // maps PATTERN_GRID cells to the target (absolute) UV public int [][][] targetUV=null; // maps PATTERN_GRID cells to the target (absolute) UV
public double [][][] pixelsUV=null; // made of PATTERN_GRID, but does not have any wave vectors. Calculated during laser calibration // public double [][][] pixelsUV=null; // made of PATTERN_GRID, but does not have any wave vectors. Calculated during laser calibration
public double [][][] pXYUV=null; // made of PATTERN_GRID, but does not have any wave vectors. Calculated during laser calibration
public double [][][] gridContrastBrightness=null; //{grid contrast, grid intensity red, grid intensity green, grid intensity blue}[v][u] public double [][][] gridContrastBrightness=null; //{grid contrast, grid intensity red, grid intensity green, grid intensity blue}[v][u]
public Rectangle DIST_SELECTION=null; public Rectangle DIST_SELECTION=null;
public int [] UV_INDEX=null; // array containing index of the pattern UV (scanline order, U first), or -1 for the areas with no pattern public int [] UV_INDEX=null; // array containing index of the pattern UV (scanline order, U first), or -1 for the areas with no pattern
...@@ -64,6 +68,36 @@ public class MatchSimulatedPattern { ...@@ -64,6 +68,36 @@ public class MatchSimulatedPattern {
public double [] gridFFCorr=null; // array matching greens with the flat field correction for the grid (zero outside of detected grid?) public double [] gridFFCorr=null; // array matching greens with the flat field correction for the grid (zero outside of detected grid?)
public double [] flatFieldForGrid=null; // array matching image pixels, divide the input pixels by these values (if not null) public double [] flatFieldForGrid=null; // array matching image pixels, divide the input pixels by these values (if not null)
public boolean [] focusMask=null; // array matching image pixels, used with focusing (false outside sample areas) public boolean [] focusMask=null; // array matching image pixels, used with focusing (false outside sample areas)
final private int [][][] rotations={
{{ 1, 0},{ 0, 1}}, // not mirrored
{{ 0, 1},{-1, 0}},
{{-1, 0},{ 0,-1}},
{{ 0,-1},{ 1, 0}},
{{ 1, 0},{ 0,-1}}, // mirrored
{{ 0, 1},{ 1, 0}},
{{-1, 0},{ 0, 1}},
{{ 0,-1},{-1, 0}}};
// shifts when rotating around unknown center (make it white)
final private int [][] dfltShifts={
{0,0},
{0,1},
{0,0},
{1,0},
{0,1},
{0,0},
{1,0},
{0,0}};
final private int [][] combinedRotations={
{0, 1, 2, 3, 4, 5, 6, 7},
{1, 2, 3, 0, 7, 4, 5, 6},
{2, 3, 0, 1, 6, 7, 4, 5},
{3, 0, 1, 2, 5, 6, 7, 4},
{4, 5, 6, 7, 0, 1, 2, 3},
{5, 6, 7, 4, 3, 0, 1, 2},
{6, 7, 4, 5, 2, 3, 0, 1},
{7, 4, 5, 6, 1, 2, 3, 0}};
public MatchSimulatedPattern (){ } public MatchSimulatedPattern (){ }
public MatchSimulatedPattern (int fft_size){ public MatchSimulatedPattern (int fft_size){
this.FFT_SIZE=fft_size; this.FFT_SIZE=fft_size;
...@@ -79,12 +113,121 @@ public class MatchSimulatedPattern { ...@@ -79,12 +113,121 @@ public class MatchSimulatedPattern {
msp.UV_INDEX=this.UV_INDEX; // array containing index of the pattern UV (scanline order, U first), or -1 for the areas with no pattern msp.UV_INDEX=this.UV_INDEX; // array containing index of the pattern UV (scanline order, U first), or -1 for the areas with no pattern
msp.UV_INDEX_WIDTH=this.UV_INDEX_WIDTH; msp.UV_INDEX_WIDTH=this.UV_INDEX_WIDTH;
msp.reMap=this.reMap; msp.reMap=this.reMap;
msp.targetUV=this.targetUV; msp.UVShiftRot=this.UVShiftRot.clone();
msp.pixelsUV=this.pixelsUV; // public int [] UVShiftRot={0,0,0}; // {shift U, shift V, rot (1 of 8 - 4 non-mirrored, 4 - mirrored}
msp.targetUV=this.targetUV; //
msp.pXYUV=this.pXYUV;
msp.flatFieldForGrid=this.flatFieldForGrid; msp.flatFieldForGrid=this.flatFieldForGrid;
msp.focusMask=this.focusMask; msp.focusMask=this.focusMask;
return msp; return msp;
} }
public MatchSimulatedPattern cloneDeep(
boolean clonePATTERN_GRID,
boolean cloneTargetUV,
boolean clonePixelsUV,
boolean cloneFlatFieldForGrid,
boolean cloneFocusMask
){ // used in createPSFMap when creating threads
MatchSimulatedPattern msp=new MatchSimulatedPattern (this.FFT_SIZE);
// cloning should be thread safe, when using DoubleFHT - use individual instances
msp.debugLevel=this.debugLevel;
// msp.PATTERN_GRID=this.PATTERN_GRID; // global to be used with threads? TODO: Same as DIST_ARRAY - merge?
if ( clonePATTERN_GRID && (msp.PATTERN_GRID!=null)){
msp.PATTERN_GRID=new double [this.PATTERN_GRID.length][this.PATTERN_GRID[0].length][][];
for (int i=0;i<this.PATTERN_GRID.length;i++) for (int j=0;j<this.PATTERN_GRID[i].length;j++) {
if (this.PATTERN_GRID[i][j]!=null){
msp.PATTERN_GRID[i][j]=new double [this.PATTERN_GRID[i][j].length][];
for (int k=0;k<this.PATTERN_GRID[i][j].length;k++){
if (this.PATTERN_GRID[i][j][k]!=null) msp.PATTERN_GRID[i][j][k]=this.PATTERN_GRID[i][j][k].clone();
else msp.PATTERN_GRID[i][j][k]=null;
}
} else msp.PATTERN_GRID[i][j]=null;
}
} else msp.PATTERN_GRID=this.PATTERN_GRID;
// msp.DIST_ARRAY=this.DIST_ARRAY;
if (this.DIST_SELECTION!=null) msp.DIST_SELECTION=new Rectangle(this.DIST_SELECTION);
else msp.DIST_SELECTION=null;
if (this.UV_INDEX!=null) msp.UV_INDEX=this.UV_INDEX.clone(); // array containing index of the pattern UV (scanline order, U first), or -1 for the areas with no pattern
else msp.UV_INDEX=null;
msp.UV_INDEX_WIDTH=this.UV_INDEX_WIDTH;
if (this.reMap!=null) { // probably not used
msp.reMap=new int [2][];
msp.reMap[0]=this.reMap[0].clone();
msp.reMap[1]=this.reMap[1].clone();
} else msp.reMap=null;
msp.UVShiftRot=this.UVShiftRot.clone();
// public int [] UVShiftRot={0,0,0}; // {shift U, shift V, rot (1 of 8 - 4 non-mirrored, 4 - mirrored}
// msp.targetUV=this.targetUV;
if (cloneTargetUV && (this.targetUV != null)) {
msp.targetUV=new int [this.targetUV.length][this.targetUV[0].length][];
for (int i=0;i<this.targetUV.length;i++) for (int j=0;j<this.targetUV[i].length;j++){
if (this.targetUV[i][j]!=null) msp.targetUV[i][j]=this.targetUV[i][j].clone();
else msp.targetUV[i][j]=null;
}
} else msp.targetUV=this.targetUV;
// msp.pixelsUV=this.pixelsUV;
if (clonePixelsUV && (this.pXYUV != null)) {
msp.pXYUV=new double [this.pXYUV.length][this.pXYUV[0].length][];
for (int i=0;i<this.pXYUV.length;i++) for (int j=0;j<this.pXYUV[i].length;j++){
if (this.pXYUV[i][j]!=null) msp.pXYUV[i][j]=this.pXYUV[i][j].clone();
else msp.pXYUV[i][j]=null;
}
} else msp.targetUV=this.targetUV;
// msp.flatFieldForGrid=this.flatFieldForGrid;
if (cloneFlatFieldForGrid && (this.flatFieldForGrid!=null)) msp.flatFieldForGrid=this.flatFieldForGrid.clone();
else msp.flatFieldForGrid=this.flatFieldForGrid;
// msp.focusMask=this.focusMask;
if (cloneFocusMask && (this.focusMask!=null)) msp.focusMask=this.focusMask.clone();
else msp.focusMask=this.focusMask;
return msp;
}
public int [] getUVShiftRot(boolean shift){
if (!shift) return this.UVShiftRot;
int [][] reReMap=getRemapMatrix(this.UVShiftRot);
int [] UVShiftRotCorr=this.UVShiftRot.clone();
UVShiftRotCorr[0]-=reReMap[0][0]*this.minUV[0]+reReMap[0][1]*this.minUV[1];
UVShiftRotCorr[1]-=reReMap[1][0]*this.minUV[0]+reReMap[1][1]*this.minUV[1];
System.out.println("getUVShiftRot(true): minUV[0]="+minUV[0]+" minUV[1]="+minUV[1]);
return UVShiftRotCorr;
}
public int [][] getRemapMatrix(
int [] UVShiftRot){
/* int [][] reReMap={
{rotations[UVShiftRot[2]][0][0],rotations[UVShiftRot[2]][0][1],
-(rotations[UVShiftRot[2]][0][0]*UVShiftRot[0] +rotations[UVShiftRot[2]][0][1]*UVShiftRot[1])},
{rotations[UVShiftRot[2]][1][0],rotations[UVShiftRot[2]][1][1],
-(rotations[UVShiftRot[2]][1][0]*UVShiftRot[0] +rotations[UVShiftRot[2]][1][1]*UVShiftRot[1])}};
*/
// Moved shift calculation to calibrateGrid(), here just a regular R,T 2x3 matix
int [][] reReMap={
{rotations[UVShiftRot[2]][0][0],rotations[UVShiftRot[2]][0][1], UVShiftRot[0]},
{rotations[UVShiftRot[2]][1][0],rotations[UVShiftRot[2]][1][1], UVShiftRot[1]}};
return reReMap;
}
public int [] combineUVShiftRot(
int [] UVShiftRotA,
int [] UVShiftRotB){
int [][] reReMapA=getRemapMatrix(UVShiftRotA);
int [][] reReMapB=getRemapMatrix(UVShiftRotB);
int [] UVShiftRot=new int [3];
UVShiftRot[0] = reReMapB[0][0]*reReMapA[0][2]+ reReMapB[0][1]*reReMapA[1][2] + reReMapB[0][2];
UVShiftRot[1] = reReMapB[1][0]*reReMapA[0][2]+ reReMapB[1][1]*reReMapA[1][2] + reReMapB[1][2];
UVShiftRot[2] = combinedRotations[UVShiftRotA[2]][UVShiftRotB[2]];
return UVShiftRot;
}
public double focusQualityOld( public double focusQualityOld(
ImagePlus imp, ImagePlus imp,
...@@ -6688,7 +6831,7 @@ y=xy0[1] + dU*deltaUV[0]*(xy1[1]-xy0[1])+dV*deltaUV[1]*(xy2[1]-xy0[1]) ...@@ -6688,7 +6831,7 @@ y=xy0[1] + dU*deltaUV[0]*(xy1[1]-xy0[1])+dV*deltaUV[1]*(xy2[1]-xy0[1])
private void invalidateCalibration(){ private void invalidateCalibration(){
this.reMap=null; // invalidate if any this.reMap=null; // invalidate if any
this.targetUV=null; // invalidate if any this.targetUV=null; // invalidate if any
this.pixelsUV=null; // invalidate if any this.pXYUV=null; // invalidate if any
this.passNumber=1; this.passNumber=1;
resetCorrelationSizesUsed(); // reset which FFT sizes where used in correlation resetCorrelationSizesUsed(); // reset which FFT sizes where used in correlation
} }
...@@ -6702,12 +6845,12 @@ y=xy0[1] + dU*deltaUV[0]*(xy1[1]-xy0[1])+dV*deltaUV[1]*(xy2[1]-xy0[1]) ...@@ -6702,12 +6845,12 @@ y=xy0[1] + dU*deltaUV[0]*(xy1[1]-xy0[1])+dV*deltaUV[1]*(xy2[1]-xy0[1])
/* get height and width of the measured pattern array applies to PATTERN_GRID, targetUV and pixelsUV */ /* get height and width of the measured pattern array applies to PATTERN_GRID, targetUV and pixelsUV */
public int getHeight(){ public int getHeight(){
if (this.pixelsUV==null) return 0; if (this.pXYUV==null) return 0;
return this.pixelsUV.length; return this.pXYUV.length;
} }
public int getWidth(){ public int getWidth(){
if (this.pixelsUV==null) return 0; if (this.pXYUV==null) return 0;
return this.pixelsUV[0].length; return this.pXYUV[0].length;
} }
/* Get physical target UV pair from measured pattern. Requires absolute mapping (by laser spots) /* Get physical target UV pair from measured pattern. Requires absolute mapping (by laser spots)
* Pair may be null if no pattern is detected for this node in the image * Pair may be null if no pattern is detected for this node in the image
...@@ -6718,8 +6861,8 @@ y=xy0[1] + dU*deltaUV[0]*(xy1[1]-xy0[1])+dV*deltaUV[1]*(xy2[1]-xy0[1]) ...@@ -6718,8 +6861,8 @@ y=xy0[1] + dU*deltaUV[0]*(xy1[1]-xy0[1])+dV*deltaUV[1]*(xy2[1]-xy0[1])
/* Get pixel X,Y pair for each node in the measured pattern. Calculated during absolute mapping (by laser spots) /* Get pixel X,Y pair for each node in the measured pattern. Calculated during absolute mapping (by laser spots)
* Pair may be null if no pattern is detected for this node in the image * Pair may be null if no pattern is detected for this node in the image
*/ */
public double [][][] getPixelsUV(){ public double [][][] getPXYUV(){
return this.pixelsUV; return this.pXYUV;
} }
public int restorePatternGridFromGridList( public int restorePatternGridFromGridList(
...@@ -6778,9 +6921,14 @@ y=xy0[1] + dU*deltaUV[0]*(xy1[1]-xy0[1])+dV*deltaUV[1]*(xy2[1]-xy0[1]) ...@@ -6778,9 +6921,14 @@ y=xy0[1] + dU*deltaUV[0]*(xy1[1]-xy0[1])+dV*deltaUV[1]*(xy2[1]-xy0[1])
// do not break black/white correspondence, always move by even number of cells // do not break black/white correspondence, always move by even number of cells
if ((minU & 1)!=0 )minU--; if ((minU & 1)!=0 )minU--;
if ((minV & 1)!=0 )minV--; if ((minV & 1)!=0 )minV--;
this.minUV[0]=minU;
this.minUV[1]=minV; // save shift to restore later
this.PATTERN_GRID=setPatternGridArray(maxU-minU+1,maxV-minV+1); this.PATTERN_GRID=setPatternGridArray(maxU-minU+1,maxV-minV+1);
this.gridContrastBrightness=new double[4][this.PATTERN_GRID.length][this.PATTERN_GRID[0].length]; //{grid contrast, grid intensity red, grid intensity green, grid intensity blue}[v][u] this.gridContrastBrightness=new double[4][this.PATTERN_GRID.length][this.PATTERN_GRID[0].length]; //{grid contrast, grid intensity red, grid intensity green, grid intensity blue}[v][u]
for (int n=0;n<4;n++) for (int v=0;v<this.gridContrastBrightness[0].length;v++) for (int u=0;u<this.gridContrastBrightness[0][0].length;u++) this.gridContrastBrightness[n][v][u]=0.0; for (int n=0;n<4;n++)
for (int v=0;v<this.gridContrastBrightness[0].length;v++)
for (int u=0;u<this.gridContrastBrightness[0][0].length;u++)
this.gridContrastBrightness[n][v][u]=0.0;
for (int n=0;n<pixelsXYSet.length;n++) for (int n=0;n<pixelsXYSet.length;n++)
for (int i=0;i<pixelsXYSet[n].length;i++) if ((pixelsXYSet[n][i]!=null)&&(pixelsUVSet[n][i]!=null)) { for (int i=0;i<pixelsXYSet[n].length;i++) if ((pixelsXYSet[n][i]!=null)&&(pixelsUVSet[n][i]!=null)) {
...@@ -7090,8 +7238,8 @@ y=xy0[1] + dU*deltaUV[0]*(xy1[1]-xy0[1])+dV*deltaUV[1]*(xy2[1]-xy0[1]) ...@@ -7090,8 +7238,8 @@ y=xy0[1] + dU*deltaUV[0]*(xy1[1]-xy0[1])+dV*deltaUV[1]*(xy2[1]-xy0[1])
* eighth slice - blue intensity of the grid (avaraged around the grid node) * eighth slice - blue intensity of the grid (avaraged around the grid node)
*/ */
public ImagePlus getCalibratedPatternAsImage(String title, int numUsedPointers){ public ImagePlus getCalibratedPatternAsImage(String title, int numUsedPointers){
if ((this.targetUV==null) ||(this.pixelsUV==null)) { if ((this.targetUV==null) ||(this.pXYUV==null)) {
System.out.println("getCalibratedPatternAsImage(): this.targetUV="+((this.targetUV==null)?"null":"not null")+", this.pixelsUV="+((this.pixelsUV==null)?"null":"not null")); System.out.println("getCalibratedPatternAsImage(): this.targetUV="+((this.targetUV==null)?"null":"not null")+", this.pixelsUV="+((this.pXYUV==null)?"null":"not null"));
return null; return null;
} }
int numSlices=(this.gridContrastBrightness==null)?4:8; int numSlices=(this.gridContrastBrightness==null)?4:8;
...@@ -7099,8 +7247,8 @@ y=xy0[1] + dU*deltaUV[0]*(xy1[1]-xy0[1])+dV*deltaUV[1]*(xy2[1]-xy0[1]) ...@@ -7099,8 +7247,8 @@ y=xy0[1] + dU*deltaUV[0]*(xy1[1]-xy0[1])+dV*deltaUV[1]*(xy2[1]-xy0[1])
ImageStack stack=new ImageStack(getWidth(),getHeight()); ImageStack stack=new ImageStack(getWidth(),getHeight());
int index=0; int index=0;
for (int v=0;v<getHeight();v++) for (int u=0;u<getWidth();u++) { for (int v=0;v<getHeight();v++) for (int u=0;u<getWidth();u++) {
if ((this.targetUV[v][u]==null) ||(this.pixelsUV[v][u]==null)|| if ((this.targetUV[v][u]==null) ||(this.pXYUV[v][u]==null)||
(this.pixelsUV[v][u][0]<0.0) || (this.pixelsUV[v][u][1]<0.0)) { // disregard negative sensor pixels (this.pXYUV[v][u][0]<0.0) || (this.pXYUV[v][u][1]<0.0)) { // disregard negative sensor pixels
pixels [0][index]=-1.0f; pixels [0][index]=-1.0f;
pixels [1][index]=-1.0f; pixels [1][index]=-1.0f;
pixels [2][index]= 0.0f; pixels [2][index]= 0.0f;
...@@ -7113,8 +7261,8 @@ y=xy0[1] + dU*deltaUV[0]*(xy1[1]-xy0[1])+dV*deltaUV[1]*(xy2[1]-xy0[1]) ...@@ -7113,8 +7261,8 @@ y=xy0[1] + dU*deltaUV[0]*(xy1[1]-xy0[1])+dV*deltaUV[1]*(xy2[1]-xy0[1])
} }
} else { } else {
pixels [0][index]=(float) this.pixelsUV[v][u][0]; pixels [0][index]=(float) this.pXYUV[v][u][0];
pixels [1][index]=(float) this.pixelsUV[v][u][1]; pixels [1][index]=(float) this.pXYUV[v][u][1];
pixels [2][index]=(float) this.targetUV[v][u][0]; pixels [2][index]=(float) this.targetUV[v][u][0];
pixels [3][index]=(float) this.targetUV[v][u][1]; pixels [3][index]=(float) this.targetUV[v][u][1];
if (numSlices>4){ if (numSlices>4){
...@@ -7144,8 +7292,8 @@ y=xy0[1] + dU*deltaUV[0]*(xy1[1]-xy0[1])+dV*deltaUV[1]*(xy2[1]-xy0[1]) ...@@ -7144,8 +7292,8 @@ y=xy0[1] + dU*deltaUV[0]*(xy1[1]-xy0[1])+dV*deltaUV[1]*(xy2[1]-xy0[1])
} }
// searching for single-pixel errors (program bug) // searching for single-pixel errors (program bug)
public ImagePlus getCalibratedPatternCurvatureAsImage(String title){ public ImagePlus getCalibratedPatternCurvatureAsImage(String title){
if ((this.targetUV==null) ||(this.pixelsUV==null)) { if ((this.targetUV==null) ||(this.pXYUV==null)) {
String msg="this.targetUV="+((this.targetUV==null)?"null":"not null")+", this.pixelsUV="+((this.pixelsUV==null)?"null":"not null"); String msg="this.targetUV="+((this.targetUV==null)?"null":"not null")+", this.pixelsUV="+((this.pXYUV==null)?"null":"not null");
IJ.showMessage("Error",msg); IJ.showMessage("Error",msg);
throw new IllegalArgumentException (msg); throw new IllegalArgumentException (msg);
} }
...@@ -7171,13 +7319,13 @@ y=xy0[1] + dU*deltaUV[0]*(xy1[1]-xy0[1])+dV*deltaUV[1]*(xy2[1]-xy0[1]) ...@@ -7171,13 +7319,13 @@ y=xy0[1] + dU*deltaUV[0]*(xy1[1]-xy0[1])+dV*deltaUV[1]*(xy2[1]-xy0[1])
for (int d=0;d<dirs.length;d++){ for (int d=0;d<dirs.length;d++){
int u1=u+dirs[d][0]; int u1=u+dirs[d][0];
int v1=v+dirs[d][1]; int v1=v+dirs[d][1];
if ((this.targetUV[v1][u1]==null) ||(this.pixelsUV[v1][u1]==null)|| if ((this.targetUV[v1][u1]==null) ||(this.pXYUV[v1][u1]==null)||
(this.pixelsUV[v1][u1][0]<0.0) || (this.pixelsUV[v1][u1][0]<0.0)) { // disregard negative sensor pixels (this.pXYUV[v1][u1][0]<0.0) || (this.pXYUV[v1][u1][0]<0.0)) { // disregard negative sensor pixels
valid=false; valid=false;
break; break;
} else { } else {
avrg[0]+=weights[d]*this.pixelsUV[v1][u1][0]; avrg[0]+=weights[d]*this.pXYUV[v1][u1][0];
avrg[1]+=weights[d]*this.pixelsUV[v1][u1][1]; avrg[1]+=weights[d]*this.pXYUV[v1][u1][1];
} }
} }
if (valid) { if (valid) {
...@@ -7297,23 +7445,25 @@ y=xy0[1] + dU*deltaUV[0]*(xy1[1]-xy0[1])+dV*deltaUV[1]*(xy2[1]-xy0[1]) ...@@ -7297,23 +7445,25 @@ y=xy0[1] + dU*deltaUV[0]*(xy1[1]-xy0[1])+dV*deltaUV[1]*(xy2[1]-xy0[1])
// //
// move elsewhere? // move elsewhere?
/** /**
* Create this.targetUV and this.pixelsUV for th grid that does not have any laser pointer references * Create this.targetUV and this.pixelsUV for the grid that does not have any laser pointer references
*/ */
public void unCalibrateGrid(){ public void unCalibrateGrid(){
// calculate targetUV that maps PATTERN_GRID cells to the target (absolute) UV // calculate targetUV that maps PATTERN_GRID cells to the target (absolute) UV
this.targetUV=new int [this.PATTERN_GRID.length][this.PATTERN_GRID[0].length][]; this.targetUV=new int [this.PATTERN_GRID.length][this.PATTERN_GRID[0].length][];
this.pixelsUV=new double [this.PATTERN_GRID.length][this.PATTERN_GRID[0].length][]; this.pXYUV=new double [this.PATTERN_GRID.length][this.PATTERN_GRID[0].length][];
// Or set it back to original 9do not touch, rotate/shift in the end?
Arrays.fill(this.UVShiftRot, 0);
for (int v=0;v<this.PATTERN_GRID.length;v++) for (int u=0;u<this.PATTERN_GRID[v].length;u++){ for (int v=0;v<this.PATTERN_GRID.length;v++) for (int u=0;u<this.PATTERN_GRID[v].length;u++){
if ((this.PATTERN_GRID[v][u]==null) || (this.PATTERN_GRID[v][u][0]==null)) { if ((this.PATTERN_GRID[v][u]==null) || (this.PATTERN_GRID[v][u][0]==null)) {
this.targetUV[v][u]=null; this.targetUV[v][u]=null;
this.pixelsUV[v][u]=null; this.pXYUV[v][u]=null;
} else { } else {
this.targetUV[v][u]=new int [2]; this.targetUV[v][u]=new int [2];
this.targetUV[v][u][0]=u; this.targetUV[v][u][0]=u;
this.targetUV[v][u][1]=v; this.targetUV[v][u][1]=v;
this.pixelsUV[v][u]=new double [2]; this.pXYUV[v][u]=new double [2];
this.pixelsUV[v][u][0]=PATTERN_GRID[v][u][0][0]; this.pXYUV[v][u][0]=PATTERN_GRID[v][u][0][0];
this.pixelsUV[v][u][1]=PATTERN_GRID[v][u][0][1]; this.pXYUV[v][u][1]=PATTERN_GRID[v][u][0][1];
} }
} }
...@@ -7364,7 +7514,7 @@ y=xy0[1] + dU*deltaUV[0]*(xy1[1]-xy0[1])+dV*deltaUV[1]*(xy2[1]-xy0[1]) ...@@ -7364,7 +7514,7 @@ y=xy0[1] + dU*deltaUV[0]*(xy1[1]-xy0[1])+dV*deltaUV[1]*(xy2[1]-xy0[1])
} }
// Later some pointers may be removed even if they are used to determine orientation/shift. But that should not lead // Later some pointers may be removed even if they are used to determine orientation/shift. But that should not lead
// to white/black confusion // to white/black confusion
/*
int [][][] rotations={ int [][][] rotations={
{{ 1, 0},{ 0, 1}}, // not mirrored {{ 1, 0},{ 0, 1}}, // not mirrored
{{ 0, 1},{-1, 0}}, {{ 0, 1},{-1, 0}},
...@@ -7385,7 +7535,7 @@ y=xy0[1] + dU*deltaUV[0]*(xy1[1]-xy0[1])+dV*deltaUV[1]*(xy2[1]-xy0[1]) ...@@ -7385,7 +7535,7 @@ y=xy0[1] + dU*deltaUV[0]*(xy1[1]-xy0[1])+dV*deltaUV[1]*(xy2[1]-xy0[1])
{0,0}, {0,0},
{1,0}, {1,0},
{0,0}}; {0,0}};
*/
boolean [] possibleRotations={true,true,true,true,true,true,true,true}; boolean [] possibleRotations={true,true,true,true,true,true,true,true};
// If orientation is hinted, remove all other ones from the list of possible ones // If orientation is hinted, remove all other ones from the list of possible ones
if (hintRotation>=0){ // defind from the hintGrid if (hintRotation>=0){ // defind from the hintGrid
...@@ -7558,7 +7708,7 @@ y=xy0[1] + dU*deltaUV[0]*(xy1[1]-xy0[1])+dV*deltaUV[1]*(xy2[1]-xy0[1]) ...@@ -7558,7 +7708,7 @@ y=xy0[1] + dU*deltaUV[0]*(xy1[1]-xy0[1])+dV*deltaUV[1]*(xy2[1]-xy0[1])
} }
} }
// calculate remap array (rotation+translation) from the target UV to the measured grid UV. // calculate remap array (rotation+translation) from the target UV to the measured grid UV.
this.reMap=new int[2][3]; this.reMap=new int[2][3]; // seems it is never used?
this.reMap[0][0]= rotations[rotation][0][0]; this.reMap[0][0]= rotations[rotation][0][0];
this.reMap[0][1]= rotations[rotation][0][1]; this.reMap[0][1]= rotations[rotation][0][1];
this.reMap[0][2]= uvShift[0]; this.reMap[0][2]= uvShift[0];
...@@ -7567,6 +7717,17 @@ y=xy0[1] + dU*deltaUV[0]*(xy1[1]-xy0[1])+dV*deltaUV[1]*(xy2[1]-xy0[1]) ...@@ -7567,6 +7717,17 @@ y=xy0[1] + dU*deltaUV[0]*(xy1[1]-xy0[1])+dV*deltaUV[1]*(xy2[1]-xy0[1])
this.reMap[1][2]= uvShift[1]; this.reMap[1][2]= uvShift[1];
// calculate reverse remap array (rotation+translation) from the the measured grid UV to the target UV // calculate reverse remap array (rotation+translation) from the the measured grid UV to the target UV
int reRot=(rotation>=4)?rotation:((4-rotation) & 3); // number of reverse mirror-rotation int reRot=(rotation>=4)?rotation:((4-rotation) & 3); // number of reverse mirror-rotation
// int [] UVRot={uvShift[0],uvShift[1],reRot};
int [] UVRot={
-(rotations[reRot][0][0]*uvShift[0] +rotations[reRot][0][1]*uvShift[1]),
-(rotations[reRot][1][0]*uvShift[0] +rotations[reRot][1][1]*uvShift[1]),
reRot};
return applyUVShiftRot(
UVRot, // int [] UVShiftRot,
uv, // double [][]uv,
laserPointer,
noMessageBoxes);
/*
int [][] reReMap={ int [][] reReMap={
{rotations[reRot][0][0],rotations[reRot][0][1], {rotations[reRot][0][0],rotations[reRot][0][1],
-(rotations[reRot][0][0]*uvShift[0] +rotations[reRot][0][1]*uvShift[1])}, -(rotations[reRot][0][0]*uvShift[0] +rotations[reRot][0][1]*uvShift[1])},
...@@ -7581,11 +7742,11 @@ y=xy0[1] + dU*deltaUV[0]*(xy1[1]-xy0[1])+dV*deltaUV[1]*(xy2[1]-xy0[1]) ...@@ -7581,11 +7742,11 @@ y=xy0[1] + dU*deltaUV[0]*(xy1[1]-xy0[1])+dV*deltaUV[1]*(xy2[1]-xy0[1])
} }
// calculate targetUV that maps PATTERN_GRID cells to the target (absolute) UV // calculate targetUV that maps PATTERN_GRID cells to the target (absolute) UV
this.targetUV=new int [this.PATTERN_GRID.length][this.PATTERN_GRID[0].length][]; this.targetUV=new int [this.PATTERN_GRID.length][this.PATTERN_GRID[0].length][];
this.pixelsUV=new double [this.PATTERN_GRID.length][this.PATTERN_GRID[0].length][]; this.pXYUV=new double [this.PATTERN_GRID.length][this.PATTERN_GRID[0].length][];
for (int v=0;v<this.PATTERN_GRID.length;v++) for (int u=0;u<this.PATTERN_GRID[v].length;u++){ for (int v=0;v<this.PATTERN_GRID.length;v++) for (int u=0;u<this.PATTERN_GRID[v].length;u++){
if ((this.PATTERN_GRID[v][u]==null) || (this.PATTERN_GRID[v][u][0]==null)) { if ((this.PATTERN_GRID[v][u]==null) || (this.PATTERN_GRID[v][u][0]==null)) {
this.targetUV[v][u]=null; this.targetUV[v][u]=null;
this.pixelsUV[v][u]=null; this.pXYUV[v][u]=null;
} else { } else {
this.targetUV[v][u]=new int [2]; this.targetUV[v][u]=new int [2];
this.targetUV[v][u][0]=reReMap[0][0]*u+reReMap[0][1]*v+reReMap[0][2]; this.targetUV[v][u][0]=reReMap[0][0]*u+reReMap[0][1]*v+reReMap[0][2];
...@@ -7593,9 +7754,9 @@ y=xy0[1] + dU*deltaUV[0]*(xy1[1]-xy0[1])+dV*deltaUV[1]*(xy2[1]-xy0[1]) ...@@ -7593,9 +7754,9 @@ y=xy0[1] + dU*deltaUV[0]*(xy1[1]-xy0[1])+dV*deltaUV[1]*(xy2[1]-xy0[1])
// System.out.println("v="+v+", u="+u+", PATTERN_GRID.length="+PATTERN_GRID.length+", PATTERN_GRID[v].length="+PATTERN_GRID[v].length); // System.out.println("v="+v+", u="+u+", PATTERN_GRID.length="+PATTERN_GRID.length+", PATTERN_GRID[v].length="+PATTERN_GRID[v].length);
// System.out.println("this.pixelsUV.length="+this.pixelsUV.length); // System.out.println("this.pixelsUV.length="+this.pixelsUV.length);
// System.out.println("this.pixelsUV["+v+"].length="+this.pixelsUV[v].length); // System.out.println("this.pixelsUV["+v+"].length="+this.pixelsUV[v].length);
this.pixelsUV[v][u]=new double [2]; this.pXYUV[v][u]=new double [2];
this.pixelsUV[v][u][0]=PATTERN_GRID[v][u][0][0]; this.pXYUV[v][u][0]=PATTERN_GRID[v][u][0][0];
this.pixelsUV[v][u][1]=PATTERN_GRID[v][u][0][1]; this.pXYUV[v][u][1]=PATTERN_GRID[v][u][0][1];
} }
} }
int numGood=0; int numGood=0;
...@@ -7625,9 +7786,83 @@ y=xy0[1] + dU*deltaUV[0]*(xy1[1]-xy0[1])+dV*deltaUV[1]*(xy2[1]-xy0[1]) ...@@ -7625,9 +7786,83 @@ y=xy0[1] + dU*deltaUV[0]*(xy1[1]-xy0[1])+dV*deltaUV[1]*(xy2[1]-xy0[1])
if ((debugLevel>0) && (numBad>0)){ if ((debugLevel>0) && (numBad>0)){
System.out.println("Removed "+numBad+" pointers that are too far from the predicted locations"); System.out.println("Removed "+numBad+" pointers that are too far from the predicted locations");
} }
return numGood;
*/
}
public int applyUVShiftRot(
int [] UVShiftRot,
double [][]uv,
LaserPointer laserPointer,
boolean noMessageBoxes
){
if (UVShiftRot!=null) this.UVShiftRot=UVShiftRot.clone();
// int reRot=(rotation>=4)?rotation:((4-rotation) & 3); // number of reverse mirror-rotation
/* int [][] reReMap={
{rotations[UVShiftRot[2]][0][0],rotations[UVShiftRot[2]][0][1],
-(rotations[UVShiftRot[2]][0][0]*UVShiftRot[0] +rotations[UVShiftRot[2]][0][1]*UVShiftRot[1])},
{rotations[UVShiftRot[2]][1][0],rotations[UVShiftRot[2]][1][1],
-(rotations[UVShiftRot[2]][1][0]*UVShiftRot[0] +rotations[UVShiftRot[2]][1][1]*UVShiftRot[1])}}; */
int [][] reReMap=getRemapMatrix(UVShiftRot);
if (debugLevel>1){
// System.out.println("rotation="+rotation+", reMap= [["+this.reMap[0][0]+","+this.reMap[0][1]+","+this.reMap[0][2]+"]["+
// +this.reMap[1][0]+","+this.reMap[1][1]+","+this.reMap[1][2]+"]]");
System.out.println("reRot="+ UVShiftRot[2]+", reReMap= [["+reReMap[0][0]+","+reReMap[0][1]+","+reReMap[0][2]+"]["+
+reReMap[1][0]+","+reReMap[1][1]+","+reReMap[1][2]+"]]");
}
// calculate targetUV that maps PATTERN_GRID cells to the target (absolute) UV
this.targetUV=new int [this.PATTERN_GRID.length][this.PATTERN_GRID[0].length][];
this.pXYUV=new double [this.PATTERN_GRID.length][this.PATTERN_GRID[0].length][];
for (int v=0;v<this.PATTERN_GRID.length;v++) for (int u=0;u<this.PATTERN_GRID[v].length;u++){
if ((this.PATTERN_GRID[v][u]==null) || (this.PATTERN_GRID[v][u][0]==null)) {
this.targetUV[v][u]=null;
this.pXYUV[v][u]=null;
} else {
this.targetUV[v][u]=new int [2];
this.targetUV[v][u][0]=reReMap[0][0]*u+reReMap[0][1]*v+reReMap[0][2];
this.targetUV[v][u][1]=reReMap[1][0]*u+reReMap[1][1]*v+reReMap[1][2];
// System.out.println("v="+v+", u="+u+", PATTERN_GRID.length="+PATTERN_GRID.length+", PATTERN_GRID[v].length="+PATTERN_GRID[v].length);
// System.out.println("this.pixelsUV.length="+this.pixelsUV.length);
// System.out.println("this.pixelsUV["+v+"].length="+this.pixelsUV[v].length);
this.pXYUV[v][u]=new double [2];
this.pXYUV[v][u][0]=PATTERN_GRID[v][u][0][0];
this.pXYUV[v][u][1]=PATTERN_GRID[v][u][0][1];
}
}
int numGood=0;
int numBad=0;
double [] distUV=new double[2];
double dist;
if (laserPointer!=null) {
for (int i=0;i<uv.length;i++) if (uv[i]!=null) { //laserPointer == null > uv={}
// Verify that laser spots are inside specified distance from the cell centers
distUV[0]=reReMap[0][0]*uv[i][0]+reReMap[0][1]*uv[i][1]+reReMap[0][2]-laserPointer.laserUVMap[i][0];
distUV[1]=reReMap[1][0]*uv[i][0]+reReMap[1][1]*uv[i][1]+reReMap[1][2]-laserPointer.laserUVMap[i][1];
dist=Math.sqrt(distUV[0]*distUV[0]+distUV[1]*distUV[1]);
if (debugLevel>1){
System.out.println("Laser spot #"+i+", distance from predicted ="+ IJ.d2s(dist,3)+" ("+IJ.d2s(200*dist,3)+
"% of cell radius), du="+IJ.d2s(distUV[0],3)+", dv="+IJ.d2s(distUV[1],3));
}
if ((2*dist)> laserPointer.maxOffsetFromCenter){
String msg="Laser point "+(i+1)+"(of "+uv.length+") is too far from the specified location, and this check is enforced in the configuration\n"+
"measured distance is "+ IJ.d2s(200*dist,1)+"% of the cell radius, specified is "+ IJ.d2s(100*laserPointer.maxOffsetFromCenter,1)+"%";
System.out.println("Warning:"+msg);
if (!noMessageBoxes) IJ.showMessage("Warning",msg);
numBad++;
uv[i]=null;
continue;
}
numGood++;
}
}
if ((debugLevel>0) && (numBad>0)){
System.out.println("Removed "+numBad+" pointers that are too far from the predicted locations");
}
return numGood; return numGood;
} }
/** /**
* Rotate/flip PATTERN_GRID to match expected * Rotate/flip PATTERN_GRID to match expected
* @param hintGrid [v][u][0 - pixel X, 1 - pixel Y, 2 - targetU, 3 - targetV * @param hintGrid [v][u][0 - pixel X, 1 - pixel Y, 2 - targetU, 3 - targetV
......
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