Commit ada64adb authored by Andrey Filippov's avatar Andrey Filippov

implementing non-radial corrections to lens polynomial model

parent ab077ab1
......@@ -403,7 +403,9 @@ public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSi
2360,// double distance// distance from the lens input pupil to the pattern plane along the camera axis, mm
1296.0, // double px0 // lens axis from sensor, horizontal, from left (pixels)
968.0, // double py0 // lens axis from sensor, vertical, from top (pixels)
true// boolean flipVertical // acquired image is mirrored vertically (mirror used)
true, // boolean flipVertical // acquired image is mirrored vertically (mirror used)
null, // double [][] r_xy,
null // double [][] r_od
);
// public static double [] defaultGoniometerPosition={0.0, 0.0, 2360};
public static EyesisCameraParameters EYESIS_CAMERA_PARAMETERS=new EyesisCameraParameters(
......
......@@ -264,7 +264,7 @@ import org.apache.commons.configuration.XMLConfiguration;
}
}
public class GridImageSet{
private int numPars=27;
private int numPars=53; // 27;
private int thisParsStartIndex=6;
public int stationNumber=0; // changes when camera/goniometer is moved to new position
......@@ -465,12 +465,48 @@ import org.apache.commons.configuration.XMLConfiguration;
{"subcamDistortionA5", "Distortion A5(r^5)","relative","S","I"}, //23 (21)
{"subcamDistortionA", "Distortion A (r^4)","relative","S","I"}, //24 (22)
{"subcamDistortionB", "Distortion B (r^3)","relative","S","I"}, //25 (23)
{"subcamDistortionC", "Distortion C (r^2)","relative","S","I"} //26 (24)
{"subcamDistortionC", "Distortion C (r^2)","relative","S","I"}, //26 (24)
{"subcamElong_C_o", "Orthogonal elongation for r^2","relative","S","I"}, // 27 39 (37)
{"subcamElong_C_d", "Diagonal elongation for r^2","relative","S","I"}, // 28 40 (38)
{"subcamEccen_B_x", "Distortion center shift X for r^3","relative","S","I"}, // 29 27 (25)
{"subcamEccen_B_y", "Distortion center shift Y for r^3","relative","S","I"}, // 30 28 (26)
{"subcamElong_B_o", "Orthogonal elongation for r^3","relative","S","I"}, // 31 41 (39)
{"subcamElong_B_d", "Diagonal elongation for r^3","relative","S","I"}, // 32 42 (40)
{"subcamEccen_A_x", "Distortion center shift X for r^4","relative","S","I"}, // 33 29 (27)
{"subcamEccen_A_y", "Distortion center shift Y for r^4","relative","S","I"}, // 34 30 (28)
{"subcamElong_A_o", "Orthogonal elongation for r^4","relative","S","I"}, // 35 43 (41)
{"subcamElong_A_d", "Diagonal elongation for r^4","relative","S","I"}, // 36 44 (42)
{"subcamEccen_A5_x", "Distortion center shift X for r^5","relative","S","I"}, // 37 31 (29)
{"subcamEccen_A5_y", "Distortion center shift Y for r^5","relative","S","I"}, // 38 32 (30)
{"subcamElong_A5_o", "Orthogonal elongation for r^5","relative","S","I"}, // 39 45 (43)
{"subcamElong_A5_d", "Diagonal elongation for r^5","relative","S","I"}, // 40 46 (44)
{"subcamEccen_A6_x", "Distortion center shift X for r^6","relative","S","I"}, // 41 33 (31)
{"subcamEccen_A6_y", "Distortion center shift Y for r^6","relative","S","I"}, // 42 34 (32)
{"subcamElong_A6_o", "Orthogonal elongation for r^6","relative","S","I"}, // 43 47 (45)
{"subcamElong_A6_d", "Diagonal elongation for r^6","relative","S","I"}, // 44 48 (46)
{"subcamEccen_A7_x", "Distortion center shift X for r^7","relative","S","I"}, // 45 35 (33)
{"subcamEccen_A7_y", "Distortion center shift Y for r^7","relative","S","I"}, // 46 36 (34)
{"subcamElong_A7_o", "Orthogonal elongation for r^7","relative","S","I"}, // 47 49 (47)
{"subcamElong_A7_d", "Diagonal elongation for r^7","relative","S","I"}, // 48 50 (48)
{"subcamEccen_A8_x", "Distortion center shift X for r^8","relative","S","I"}, // 49 37 (35)
{"subcamEccen_A8_y", "Distortion center shift Y for r^8","relative","S","I"}, // 50 38 (36)
{"subcamElong_A8_o", "Orthogonal elongation for r^8","relative","S","I"}, // 51 51 (49)
{"subcamElong_A8_d", "Diagonal elongation for r^8","relative","S","I"} // 52 52 (50)
};
public String [] channelSuffixes={ // natural order (same as array indices, may be modified to camera/subcamera
"00","01","02","03","04","05","06","07","08","09",
"10","11","12","13","14","15","16","17","18","19",
"20","21","22","23","24","25","26","27","28","29"};
public boolean isNonRadial(int index){
return parameterDescriptions[index][0].startsWith("subcamEccen_") || parameterDescriptions[index][0].startsWith("subcamElong_");
}
public int getParameterIndexByName(String name){
for (int i=0;i<this.parameterDescriptions.length;i++) if (this.parameterDescriptions[i][0].equals(name)){
return i;
......@@ -1550,7 +1586,7 @@ import org.apache.commons.configuration.XMLConfiguration;
int minIndex= this.gIS[index].getMinIndex();
int maxIndexPlusOne=this.gIS[index].getMaxIndexPlusOne();
for (int j=minIndex;j<maxIndexPlusOne;j++) if (sub.getString(parameterDescriptions[j][0])!=null) {
this.gIS[index].setParameterValue(j,Double.parseDouble((sub.getString(parameterDescriptions[j][0]))), false);
this.gIS[index].setParameterValue(j,Double.parseDouble(sub.getString(parameterDescriptions[j][0])), false);
}
if (sub.getString("orientationEstimated")!=null) {
this.gIS[i].orientationEstimated=Boolean.parseBoolean(sub.getString("orientationEstimated"));
......@@ -1590,9 +1626,13 @@ import org.apache.commons.configuration.XMLConfiguration;
if (sub.getString(parameterDescriptions[j][0])!=null)
this.pars[i][j] = Double.parseDouble(sub.getString(parameterDescriptions[j][0]));
else
if (isNonRadial(j)){
this.pars[i][j] = 0.0; // old calibration files without non-radial parameters
} else {
this.pars[i][j] = Double.NaN;
}
}
}
if (this.gIS!=null){
System.out.println("Using stored image set data");
for (int is=0;is<this.gIS.length;is++){
......
This diff is collapsed.
This diff is collapsed.
......@@ -47,6 +47,24 @@ import java.util.Properties;
public double channelWeightCurrent=1.0;
public int [][] defectsXY=null; // pixel defects coordinates list (starting with worst)
public double [] defectsDiff=null; // pixel defects value (diff from average of neighbors), matching defectsXY
final private double [][] r_xy_dflt={{0.0,0.0},{0.0,0.0},{0.0,0.0},{0.0,0.0},{0.0,0.0},{0.0,0.0}}; // only 6, as for the first term delta x, delta y ==0
final private double [][] r_od_dflt= {{0.0,0.0},{0.0,0.0},{0.0,0.0},{0.0,0.0},{0.0,0.0},{0.0,0.0},{0.0,0.0}}; // ortho
public double [][] r_xy=null; // only 6, as for the first term delta x, delta y ==0
public double [][] r_od=null; // ortho
/*
Modifying to accommodate for eccentricity of different terms (2 parameters per term) and elliptical shape (another 2 terms). When all are
zeroes, the old parameters are in effect:
Rdist/R=A8*R^7+A7*R^6+A6*R^5+A5*R^4+A*R^3+B*R^2+C*R+(1-A6-A7-A6-A5-A-B-C)");
Rdist/R=A8*R6^7+A7*R5^6+A6*R4^5+A5*R3^4+A*R2^3+B*R1^2+C*R0+(1-A6-A7-A6-A5-A-B-C)");
R[i] depends on px,py and r_xy[i][], r_o[i] (positive - "landscape", negative - "portrait"), r_d (positive - along y=x, negative - along y=-x)
R[i] = r0[i]*(1+ (r_od[i][0]*(y[i]**2-x[i]**2)+ 2*r_od[i][1]*x[i]*y[i])/r0[i]**2;
r0[i]=sqrt(x[i]**2+y[2]**2)
x[i]=pixel_x-px0-((i>0)?r_xy[i-1][0]:0)
y[i]=pixel_y-py0-((i>0)?r_xy[i-1][1]:0)
*/
public EyesisSubCameraParameters(
double azimuth, // azimuth of the lens entrance pupil center, degrees, clockwise looking from top
double radius, // mm, distance from the rotation axis
......@@ -66,6 +84,8 @@ import java.util.Properties;
double distortionC, // r^2
double px0, // center of the lens on the sensor, pixels
double py0, // center of the lens on the sensor, pixels
double [][] r_xy, // eccentricity for b,a,a5,a6,a7,a8
double [][] r_od, // elongation for c,b,a,a5,a6,a7,a8
double channelWeightDefault
){
this.azimuth=azimuth;
......@@ -86,6 +106,12 @@ import java.util.Properties;
this.distortionC=distortionC; // r^2
this.px0=px0;
this.py0=py0;
if (r_xy==null) r_xy=r_xy_dflt;
if (r_od==null) r_od=r_od_dflt;
this.r_xy=new double [r_xy.length][2];
for (int i=0;i<r_xy.length;i++)this.r_xy[i]=r_xy[i].clone();
this.r_od=new double [r_od.length][2];
for (int i=0;i<r_od.length;i++)this.r_od[i]=r_od[i].clone();
this.channelWeightDefault=channelWeightDefault;
this.channelWeightCurrent=this.channelWeightDefault;
this.defectsXY=null; // pixel defects coordinates list (starting with worst)
......@@ -113,10 +139,18 @@ import java.util.Properties;
this.distortionC,
this.px0,
this.py0,
this.r_xy,
this.r_od,
this.channelWeightDefault
);
}
public void setDefaultNonRadial(){
r_od=new double [r_od_dflt.length][2];
for (int i=0;i<r_od.length;i++) r_od[i]=r_od_dflt[i].clone();
r_xy=new double [r_xy_dflt.length][2];
for (int i=0;i<r_xy.length;i++) r_xy[i]=r_xy_dflt[i].clone();
}
// TODO: add/restore new properties
public void setProperties(String prefix,Properties properties){
properties.setProperty(prefix+"azimuth",this.azimuth+"");
properties.setProperty(prefix+"radius",this.radius+"");
......@@ -136,6 +170,14 @@ import java.util.Properties;
properties.setProperty(prefix+"distortionC",this.distortionC+"");
properties.setProperty(prefix+"px0",this.px0+"");
properties.setProperty(prefix+"py0",this.py0+"");
for (int i=0;i<this.r_xy.length;i++){
properties.setProperty(prefix+"r_xy_"+i+"_x",this.r_xy[i][0]+"");
properties.setProperty(prefix+"r_xy_"+i+"_y",this.r_xy[i][1]+"");
}
for (int i=0;i<this.r_od.length;i++){
properties.setProperty(prefix+"r_od_"+i+"_o",this.r_od[i][0]+"");
properties.setProperty(prefix+"r_od_"+i+"_d",this.r_od[i][1]+"");
}
properties.setProperty(prefix+"channelWeightDefault",this.channelWeightDefault+"");
}
public void getProperties(String prefix,Properties properties){
......@@ -175,6 +217,16 @@ import java.util.Properties;
this.px0=Double.parseDouble(properties.getProperty(prefix+"px0"));
if (properties.getProperty(prefix+"py0")!=null)
this.py0=Double.parseDouble(properties.getProperty(prefix+"py0"));
setDefaultNonRadial();
for (int i=0;i<this.r_xy.length;i++){
if (properties.getProperty(prefix+"r_xy_"+i+"_x")!=null) this.r_xy[i][0]=Double.parseDouble(properties.getProperty(prefix+"r_xy_"+i+"_x"));
if (properties.getProperty(prefix+"r_xy_"+i+"_y")!=null) this.r_xy[i][1]=Double.parseDouble(properties.getProperty(prefix+"r_xy_"+i+"_y"));
}
for (int i=0;i<this.r_od.length;i++){
if (properties.getProperty(prefix+"r_od_"+i+"_o")!=null) this.r_od[i][0]=Double.parseDouble(properties.getProperty(prefix+"r_od_"+i+"_o"));
if (properties.getProperty(prefix+"r_od_"+i+"_d")!=null) this.r_od[i][1]=Double.parseDouble(properties.getProperty(prefix+"r_od_"+i+"_d"));
}
if (properties.getProperty(prefix+"channelWeightDefault")!=null) {
this.channelWeightDefault=Double.parseDouble(properties.getProperty(prefix+"channelWeightDefault"));
this.channelWeightCurrent=this.channelWeightDefault;
......@@ -190,5 +242,4 @@ import java.util.Properties;
public double getChannelWeightDefault(){
return this.channelWeightDefault;
}
}
......@@ -422,6 +422,34 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
this.pathName=pathname;
return true;
}
public int findLastValidSeries(int numSeries){
for (;numSeries>=0;numSeries--) if (isSeriesValid(numSeries)) return numSeries;
return -1; // none valid
}
public boolean copySeries(int sourceSeries, int numSeries){
if (isSeriesValid(sourceSeries)){
invalidateSelectedImages(numSeries); // just in case -= will be recalculated
for (int i =0; i<this.distortionCalibrationData.getNumImages();i++){
this.selectedImages[numSeries][i]=this.selectedImages[sourceSeries][i]; // copy for all, not only enabled
}
for (int i =0; i<this.parameterEnable.length;i++) if (this.parameterEnable[i]){
this.parameterMode[numSeries][i]=this.parameterMode[sourceSeries][i];
this.parameterGroups[numSeries][i]=(this.parameterGroups[sourceSeries][i]==null)?null:this.parameterGroups[sourceSeries][i].clone();
}
this.masterImages[numSeries]=this.masterImages[sourceSeries];
this.lambdas[numSeries]=this.lambdas[sourceSeries];
this.stepDone[numSeries]=this.stepDone[sourceSeries];
this.stopAfterThis[numSeries]=this.stopAfterThis[sourceSeries];
this.varianceModes[numSeries]=this.varianceModes[sourceSeries];
this.zGroups[numSeries]=(this.zGroups[sourceSeries]!=null)?this.zGroups[sourceSeries].clone():null;
return true;
} else {
return false;
}
}
/**
* Verifies that series exists and is not empty (valid for LMA)
* @param num - series to verify
......@@ -1406,31 +1434,13 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
sNumNewEnabledPerStation+=numNewEnabledPerStation[i];
}
if (!isSeriesValid(numSeries)){
int sourceSeries=-1;
for (int i=numSeries-1;i>=0;i--) if (isSeriesValid(i)){
sourceSeries=i;
break;
}
if (sourceSeries>=0){
invalidateSelectedImages(numSeries); // just in case -= will be recalculated
for (int i =0; i<this.distortionCalibrationData.getNumImages();i++){
this.selectedImages[numSeries][i]=this.selectedImages[sourceSeries][i]; // copy for all, not only enabled
}
for (int i =0; i<this.parameterEnable.length;i++) if (this.parameterEnable[i]){
this.parameterMode[numSeries][i]=this.parameterMode[sourceSeries][i];
this.parameterGroups[numSeries][i]=(this.parameterGroups[sourceSeries][i]==null)?null:this.parameterGroups[sourceSeries][i].clone();
}
this.masterImages[numSeries]=this.masterImages[sourceSeries];
this.lambdas[numSeries]=this.lambdas[sourceSeries];
this.stepDone[numSeries]=this.stepDone[sourceSeries];
this.stopAfterThis[numSeries]=this.stopAfterThis[sourceSeries];
this.varianceModes[numSeries]=this.varianceModes[sourceSeries];
this.zGroups[numSeries]=(this.zGroups[sourceSeries]!=null)?this.zGroups[sourceSeries].clone():null;
}
int sourceSeries= findLastValidSeries(numSeries);
if (sourceSeries>=0) copySeries(sourceSeries, numSeries);
}
GenericDialog gd = new GenericDialog("Fitting Strategy Step Configuration, step "+numSeries+" number of enabled images="+this.distortionCalibrationData.getNumEnabled());
gd.addCheckbox("Copy all from previous series (ignore all other fields)", false);
gd.addCheckbox("Copy all from the series below, ignore all other fields", false);
gd.addNumericField("Source series to copy from", (numSeries>0)?(numSeries-1):(numSeries+1), 0, 3, "");
gd.addCheckbox("Remove all (but first) images, reopen dialog", false); // remove all will be invalid, copied from the previous
gd.addCheckbox("Select all images, reopen dialog", false);
if (numEstimated>0){
......@@ -1571,6 +1581,7 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
gd.showDialog();
if (gd.wasCanceled()) return -2;
boolean copyFromPrevious=gd.getNextBoolean();
int sourceStrategy= (int) gd.getNextNumber();
boolean removeAllImages=gd.getNextBoolean();
boolean selectAllImages=gd.getNextBoolean();
boolean selectEstimated=false;
......@@ -1595,7 +1606,17 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
return numSeries; // caller will repeat with the same series
}
if (copyFromPrevious || removeAllImages || selectAllImages) {
if (copyFromPrevious){
int sourceSeries= findLastValidSeries(sourceStrategy);
if (sourceSeries>=0) {
copySeries(sourceSeries, numSeries);
} else {
System.out.println("Could not copy from invalid series "+sourceSeries);
}
return numSeries; // caller will repeat with the same series
}
if (removeAllImages || selectAllImages) {
//
for (int i =0; i<this.distortionCalibrationData.getNumImages();i++){
// this.selectedImages[numSeries][i]=false; // invalidate - all, regardless of .enabled
this.selectedImages[numSeries][i]=selectAllImages || ((i==0) && removeAllImages); // invalidate - all, regardless of .enabled
......@@ -1777,7 +1798,7 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
}
public boolean selectStrategy(int startSerNumber){
int defaultLength=20;
int defaultLength=30;
boolean selectImages= false;
boolean allImages= false;
boolean selectParameters=true;
......
This diff is collapsed.
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