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 ...@@ -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 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) 1296.0, // double px0 // lens axis from sensor, horizontal, from left (pixels)
968.0, // double py0 // lens axis from sensor, vertical, from top (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 double [] defaultGoniometerPosition={0.0, 0.0, 2360};
public static EyesisCameraParameters EYESIS_CAMERA_PARAMETERS=new EyesisCameraParameters( public static EyesisCameraParameters EYESIS_CAMERA_PARAMETERS=new EyesisCameraParameters(
......
...@@ -264,7 +264,7 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -264,7 +264,7 @@ import org.apache.commons.configuration.XMLConfiguration;
} }
} }
public class GridImageSet{ public class GridImageSet{
private int numPars=27; private int numPars=53; // 27;
private int thisParsStartIndex=6; private int thisParsStartIndex=6;
public int stationNumber=0; // changes when camera/goniometer is moved to new position public int stationNumber=0; // changes when camera/goniometer is moved to new position
...@@ -465,12 +465,48 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -465,12 +465,48 @@ import org.apache.commons.configuration.XMLConfiguration;
{"subcamDistortionA5", "Distortion A5(r^5)","relative","S","I"}, //23 (21) {"subcamDistortionA5", "Distortion A5(r^5)","relative","S","I"}, //23 (21)
{"subcamDistortionA", "Distortion A (r^4)","relative","S","I"}, //24 (22) {"subcamDistortionA", "Distortion A (r^4)","relative","S","I"}, //24 (22)
{"subcamDistortionB", "Distortion B (r^3)","relative","S","I"}, //25 (23) {"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 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", "00","01","02","03","04","05","06","07","08","09",
"10","11","12","13","14","15","16","17","18","19", "10","11","12","13","14","15","16","17","18","19",
"20","21","22","23","24","25","26","27","28","29"}; "20","21","22","23","24","25","26","27","28","29"};
public boolean isNonRadial(int index){
return parameterDescriptions[index][0].startsWith("subcamEccen_") || parameterDescriptions[index][0].startsWith("subcamElong_");
}
public int getParameterIndexByName(String name){ public int getParameterIndexByName(String name){
for (int i=0;i<this.parameterDescriptions.length;i++) if (this.parameterDescriptions[i][0].equals(name)){ for (int i=0;i<this.parameterDescriptions.length;i++) if (this.parameterDescriptions[i][0].equals(name)){
return i; return i;
...@@ -1550,7 +1586,7 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -1550,7 +1586,7 @@ import org.apache.commons.configuration.XMLConfiguration;
int minIndex= this.gIS[index].getMinIndex(); int minIndex= this.gIS[index].getMinIndex();
int maxIndexPlusOne=this.gIS[index].getMaxIndexPlusOne(); int maxIndexPlusOne=this.gIS[index].getMaxIndexPlusOne();
for (int j=minIndex;j<maxIndexPlusOne;j++) if (sub.getString(parameterDescriptions[j][0])!=null) { 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) { if (sub.getString("orientationEstimated")!=null) {
this.gIS[i].orientationEstimated=Boolean.parseBoolean(sub.getString("orientationEstimated")); this.gIS[i].orientationEstimated=Boolean.parseBoolean(sub.getString("orientationEstimated"));
...@@ -1589,8 +1625,12 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -1589,8 +1625,12 @@ import org.apache.commons.configuration.XMLConfiguration;
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]));
else else
this.pars[i][j] = Double.NaN; 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){ if (this.gIS!=null){
......
...@@ -30,8 +30,10 @@ import ij.io.Opener; ...@@ -30,8 +30,10 @@ import ij.io.Opener;
import ij.process.FloatProcessor; import ij.process.FloatProcessor;
import ij.process.ImageProcessor; import ij.process.ImageProcessor;
import ij.text.TextWindow; 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.io.StringWriter; //import java.io.StringWriter;
import java.util.List; import java.util.List;
import java.util.ArrayList; import java.util.ArrayList;
...@@ -3299,7 +3301,7 @@ For each point in the image ...@@ -3299,7 +3301,7 @@ For each point in the image
double [] vectorFX=new double[doubleNumAllPoints]; double [] vectorFX=new double[doubleNumAllPoints];
// this.fX=new double[doubleNumAllPoints]; // this.fX=new double[doubleNumAllPoints];
if (this.debugLevel>2) { if (this.debugLevel>2) {
System.out.println("calculateFxAndJacobian(), calcJacobian="+calcJacobian); System.out.println("calculateFxAndJacobian(), calcJacobian="+calcJacobian+" D3304 + this.debugLevel="+this.debugLevel);
if (vector!=null) { if (vector!=null) {
for (int ii=0;ii<vector.length;ii++) System.out.println(ii+": "+vector[ii]); for (int ii=0;ii<vector.length;ii++) System.out.println(ii+": "+vector[ii]);
} else { } else {
...@@ -3331,8 +3333,9 @@ For each point in the image ...@@ -3331,8 +3333,9 @@ For each point in the image
// and this.interParameterDerivatives // and this.interParameterDerivatives
// if (this.debugLevel>1) { // if (this.debugLevel>1) {
if (this.debugLevel>2) { if (this.debugLevel>2) {
System.out.println("calculateFxAndJacobian(), imgNum="+imgNum+" calcInterParamers():"); System.out.println("calculateFxAndJacobian(), imgNum="+imgNum+" calcInterParamers(): (D3336)");
} }
this.lensDistortionParameters.debugLevel=this.debugLevel;
this.lensDistortionParameters.lensCalcInterParamers( this.lensDistortionParameters.lensCalcInterParamers(
this.lensDistortionParameters, this.lensDistortionParameters,
this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.isTripod, this.fittingStrategy.distortionCalibrationData.eyesisCameraParameters.isTripod,
...@@ -3359,7 +3362,7 @@ For each point in the image ...@@ -3359,7 +3362,7 @@ For each point in the image
IJ.d2s(targetXYZ[fullIndex][1],2)+","+ IJ.d2s(targetXYZ[fullIndex][1],2)+","+
IJ.d2s(targetXYZ[fullIndex][2],2)+" ("+calcJacobian+") -> "+ IJ.d2s(targetXYZ[fullIndex][2],2)+" ("+calcJacobian+") -> "+
IJ.d2s(derivatives15[0][0],2)+"/"+IJ.d2s(derivatives15[0][1],2)); IJ.d2s(derivatives15[0][0],2)+"/"+IJ.d2s(derivatives15[0][1],2));
String all="derivatives15:"; String all="derivatives15: D3365";
for (int ii=0;ii<derivatives15.length;ii++) all+=" "+ii+":"+IJ.d2s(derivatives15[ii][0],3)+"/"+IJ.d2s(derivatives15[ii][1],3); for (int ii=0;ii<derivatives15.length;ii++) all+=" "+ii+":"+IJ.d2s(derivatives15[ii][0],3)+"/"+IJ.d2s(derivatives15[ii][1],3);
System.out.println(all); System.out.println(all);
} }
...@@ -3470,7 +3473,7 @@ For each point in the image ...@@ -3470,7 +3473,7 @@ For each point in the image
IJ.d2s(patternXYZ[fullIndex][1],2)+","+ IJ.d2s(patternXYZ[fullIndex][1],2)+","+
IJ.d2s(patternXYZ[fullIndex][2],2)+" ("+calcJacobian+") -> "+ IJ.d2s(patternXYZ[fullIndex][2],2)+" ("+calcJacobian+") -> "+
IJ.d2s(derivatives15[0][0],2)+"/"+IJ.d2s(derivatives15[0][1],2)); IJ.d2s(derivatives15[0][0],2)+"/"+IJ.d2s(derivatives15[0][1],2));
String all="derivatives15:"; String all="derivatives15: D3476";
for (int ii=0;ii<derivatives15.length;ii++) all+=" "+ii+":"+IJ.d2s(derivatives15[ii][0],3)+"/"+IJ.d2s(derivatives15[ii][1],3); for (int ii=0;ii<derivatives15.length;ii++) all+=" "+ii+":"+IJ.d2s(derivatives15[ii][0],3)+"/"+IJ.d2s(derivatives15[ii][1],3);
System.out.println(all); System.out.println(all);
} }
...@@ -3557,7 +3560,7 @@ For each point in the image ...@@ -3557,7 +3560,7 @@ For each point in the image
IJ.d2s(targetXYZ[fullIndex][1],2)+","+ IJ.d2s(targetXYZ[fullIndex][1],2)+","+
IJ.d2s(targetXYZ[fullIndex][2],2)+" -> "+ IJ.d2s(targetXYZ[fullIndex][2],2)+" -> "+
IJ.d2s(derivatives15[0][0],2)+"/"+IJ.d2s(derivatives15[0][1],2)); IJ.d2s(derivatives15[0][0],2)+"/"+IJ.d2s(derivatives15[0][1],2));
String all="derivatives15:"; String all="derivatives15: D3563";
for (int ii=0;ii<derivatives15.length;ii++) all+=" "+ii+":"+IJ.d2s(derivatives15[ii][0],3)+"/"+IJ.d2s(derivatives15[ii][1],3); for (int ii=0;ii<derivatives15.length;ii++) all+=" "+ii+":"+IJ.d2s(derivatives15[ii][0],3)+"/"+IJ.d2s(derivatives15[ii][1],3);
System.out.println(all); System.out.println(all);
} }
...@@ -5916,6 +5919,14 @@ List calibration ...@@ -5916,6 +5919,14 @@ List calibration
imp.setProperty("comment_entrancePupilForward", "entrance pupil distance from the azimuth/radius/height, outwards in mm"); imp.setProperty("comment_entrancePupilForward", "entrance pupil distance from the azimuth/radius/height, outwards in mm");
imp.setProperty("entrancePupilForward", ""+entrancePupilForward); // currently global, decoders will use per-sensor imp.setProperty("entrancePupilForward", ""+entrancePupilForward); // currently global, decoders will use per-sensor
imp.setProperty("comment_defects", "Sensor hot/cold pixels list as x:y:difference"); imp.setProperty("comment_defects", "Sensor hot/cold pixels list as x:y:difference");
for (int i=0;i<subCam.r_xy.length;i++){
imp.setProperty("r_xy_"+i+"_x",subCam.r_xy[i][0]+"");
imp.setProperty("r_xy_"+i+"_y",subCam.r_xy[i][1]+"");
}
for (int i=0;i<subCam.r_od.length;i++){
imp.setProperty("r_od_"+i+"_o",subCam.r_od[i][0]+"");
imp.setProperty("r_od_"+i+"_d",subCam.r_od[i][1]+"");
}
if (subCam.defectsXY!=null){ if (subCam.defectsXY!=null){
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();
for (int i=0;i<subCam.defectsXY.length;i++){ for (int i=0;i<subCam.defectsXY.length;i++){
...@@ -6076,6 +6087,16 @@ List calibration ...@@ -6076,6 +6087,16 @@ List calibration
subCam.defectsXY=null; subCam.defectsXY=null;
subCam.defectsDiff=null; subCam.defectsDiff=null;
} }
// non-radial
subCam.setDefaultNonRadial();
for (int i=0;i<subCam.r_xy.length;i++) {
if (imp.getProperty("r_xy_"+i+"_x") !=null) subCam.r_xy[i][0]= Double.parseDouble((String) imp.getProperty("r_xy_"+i+"_x"));
if (imp.getProperty("r_xy_"+i+"_y") !=null) subCam.r_xy[i][1]= Double.parseDouble((String) imp.getProperty("r_xy_"+i+"_y"));
}
for (int i=0;i<subCam.r_od.length;i++) {
if (imp.getProperty("r_od_"+i+"_o") !=null) subCam.r_od[i][0]= Double.parseDouble((String) imp.getProperty("r_od_"+i+"_o"));
if (imp.getProperty("r_od_"+i+"_d") !=null) subCam.r_od[i][1]= Double.parseDouble((String) imp.getProperty("r_od_"+i+"_d"));
}
} }
for (int imgNum=0;imgNum<fittingStrategy.distortionCalibrationData.getNumImages();imgNum++){ for (int imgNum=0;imgNum<fittingStrategy.distortionCalibrationData.getNumImages();imgNum++){
int imageSubCam= fittingStrategy.distortionCalibrationData.getImageSubcamera(imgNum); int imageSubCam= fittingStrategy.distortionCalibrationData.getImageSubcamera(imgNum);
...@@ -9289,7 +9310,7 @@ M * V = B ...@@ -9289,7 +9310,7 @@ M * V = B
gd.addNumericField("Select parameter number (0.."+(parameterNames.length-1)+") from above", 0, 0); gd.addNumericField("Select parameter number (0.."+(parameterNames.length-1)+") from above", 0, 0);
} }
if (debugDerivatives) gd.addNumericField("Select delta to increment selected parameter", .01, 5); if (debugDerivatives) gd.addNumericField("Select delta to increment selected parameter", .001, 5);
if (debugDerivatives) gd.addCheckbox("Show inter-parameter derivatives matrix", true); if (debugDerivatives) gd.addCheckbox("Show inter-parameter derivatives matrix", true);
gd.showDialog(); gd.showDialog();
if (gd.wasCanceled()) return; if (gd.wasCanceled()) return;
...@@ -9304,7 +9325,7 @@ M * V = B ...@@ -9304,7 +9325,7 @@ M * V = B
String title; String title;
if (useActualParameters) { if (useActualParameters) {
this_currentfX=calculateFxAndJacobian(this.currentVector, true); // is it always true here (this.jacobian==null) this_currentfX=calculateFxAndJacobian(this.currentVector, true); // is it always true here (this.jacobian==null)
d_derivative=this.jacobian[selectedParameter].clone(); d_derivative=this.jacobian[selectedParameter].clone(); // wrong?
if (debugDerivatives) { if (debugDerivatives) {
double[] modVector=this.currentVector.clone(); double[] modVector=this.currentVector.clone();
modVector[selectedParameter]+=delta; modVector[selectedParameter]+=delta;
...@@ -9354,13 +9375,17 @@ M * V = B ...@@ -9354,13 +9375,17 @@ M * V = B
* @return rms * @return rms
*/ */
public double showCompareDerivatives(int imgNumber, double [] d_derivative, double [] d_delta, boolean applySensorMask, String title ){ public double showCompareDerivatives(int imgNumber, double [] d_derivative, double [] d_delta, boolean applySensorMask, String title ){
String [] titlesDebug={"dX-derivative","dY-derivative","abs-derivative","diff-X (should be 0)","diff-Y (should be 0)","dX-delta/delta","dY-delta/delta"}; String [] titlesDebug={"dX-derivative","dY-derivative","abs-derivative","diff-X (should be 0)","diff-Y (should be 0)","dX-delta/delta","dY-delta/delta","dX-delta","dY-delta"};
String [] titlesNoDebug={"dX-derivative","dY-derivative","abs-derivative"}; String [] titlesNoDebug={"dX-derivative","dY-derivative","abs-derivative"};
String [] titles= (d_delta==null)? titlesNoDebug:titlesDebug; String [] titles= (d_delta==null)? titlesNoDebug:titlesDebug;
double [] d_diff=new double [d_derivative.length]; double [] d_diff=new double [d_derivative.length];
double [] r_diff=new double [d_derivative.length];
double [] aDeriv=new double [d_derivative.length/2]; double [] aDeriv=new double [d_derivative.length/2];
if (d_delta!=null) for (int i=0;i<d_diff.length;i++) d_diff[i]=d_derivative[i]-d_delta[i]; if (d_delta!=null) for (int i=0;i<d_diff.length;i++){
d_diff[i]=d_derivative[i]-d_delta[i];
r_diff[i]=d_diff[i]/d_delta[i];
}
// find data range for the selected image // find data range for the selected image
int index=0; int index=0;
int numImg=fittingStrategy.distortionCalibrationData.getNumImages(); int numImg=fittingStrategy.distortionCalibrationData.getNumImages();
...@@ -9396,8 +9421,10 @@ M * V = B ...@@ -9396,8 +9421,10 @@ M * V = B
if (d_delta!=null) { if (d_delta!=null) {
imgData[3][vu]= d_diff[2*(index+i)]; imgData[3][vu]= d_diff[2*(index+i)];
imgData[4][vu]= d_diff[2*(index+i)+1]; imgData[4][vu]= d_diff[2*(index+i)+1];
imgData[5][vu]= d_delta[2*(index+i)]; imgData[5][vu]= r_diff[2*(index+i)];
imgData[6][vu]= d_delta[2*(index+i)+1]; imgData[6][vu]= r_diff[2*(index+i)+1];
imgData[7][vu]= d_delta[2*(index+i)];
imgData[8][vu]= d_delta[2*(index+i)+1];
} }
} }
this.SDFA_INSTANCE.showArrays(imgData, width, getGridHeight(), true, title, titles); this.SDFA_INSTANCE.showArrays(imgData, width, getGridHeight(), true, title, titles);
...@@ -9456,6 +9483,14 @@ M * V = B ...@@ -9456,6 +9483,14 @@ M * V = B
System.out.println("this.lensDistortionParameters.distortionA="+IJ.d2s(this.lensDistortionParameters.distortionA, 5)); System.out.println("this.lensDistortionParameters.distortionA="+IJ.d2s(this.lensDistortionParameters.distortionA, 5));
System.out.println("this.lensDistortionParameters.distortionB="+IJ.d2s(this.lensDistortionParameters.distortionB, 5)); System.out.println("this.lensDistortionParameters.distortionB="+IJ.d2s(this.lensDistortionParameters.distortionB, 5));
System.out.println("this.lensDistortionParameters.distortionC="+IJ.d2s(this.lensDistortionParameters.distortionC, 5)); System.out.println("this.lensDistortionParameters.distortionC="+IJ.d2s(this.lensDistortionParameters.distortionC, 5));
for (int i=0;i<this.lensDistortionParameters.r_xy.length;i++){
System.out.println("this.lensDistortionParameters.r_xy["+i+"][0]="+IJ.d2s(this.lensDistortionParameters.r_xy[i][0], 5));
System.out.println("this.lensDistortionParameters.r_xy["+i+"][1]="+IJ.d2s(this.lensDistortionParameters.r_xy[i][1], 5));
}
for (int i=0;i<this.lensDistortionParameters.r_od.length;i++){
System.out.println("this.lensDistortionParameters.r_od["+i+"][0]="+IJ.d2s(this.lensDistortionParameters.r_od[i][0], 5));
System.out.println("this.lensDistortionParameters.r_od["+i+"][1]="+IJ.d2s(this.lensDistortionParameters.r_od[i][1], 5));
}
} }
LensDistortionParameters ldp=this.lensDistortionParameters.clone(); LensDistortionParameters ldp=this.lensDistortionParameters.clone();
// public void setLensDistortionParameters(LensDistortionParameters ldp // public void setLensDistortionParameters(LensDistortionParameters ldp
...@@ -9612,6 +9647,7 @@ M * V = B ...@@ -9612,6 +9647,7 @@ M * V = B
DistortionCalibrationData distortionCalibrationData, DistortionCalibrationData distortionCalibrationData,
EyesisCameraParameters eyesisCameraParameters EyesisCameraParameters eyesisCameraParameters
){ ){
boolean resetParametersToZero=false;
boolean [] parameterMask= new boolean[distortionCalibrationData.getNumParameters()]; boolean [] parameterMask= new boolean[distortionCalibrationData.getNumParameters()];
boolean [] channelMask= new boolean[distortionCalibrationData.getNumSubCameras()]; boolean [] channelMask= new boolean[distortionCalibrationData.getNumSubCameras()];
boolean [] stationMask= new boolean[distortionCalibrationData.getNumStations()]; boolean [] stationMask= new boolean[distortionCalibrationData.getNumStations()];
...@@ -9619,7 +9655,9 @@ M * V = B ...@@ -9619,7 +9655,9 @@ M * V = B
for (int i=0;i<channelMask.length;i++) channelMask[i]= true; for (int i=0;i<channelMask.length;i++) channelMask[i]= true;
for (int i=0;i<stationMask.length;i++) stationMask[i]= true; for (int i=0;i<stationMask.length;i++) stationMask[i]= true;
GenericDialog gd=new GenericDialog("Update (new) image settings from known data"); GenericDialog gd=new GenericDialog("Update (new) image settings from known data");
gd.addMessage("Select which individual image parameters to be updated from the camera parameters"); //
gd.addCheckbox("Reset selected parameters to zero (false - update from camera parameters)", resetParametersToZero);
gd.addMessage("Select which individual image parameters to be updated from the camera parameters (or reset to 0)");
for (int i=0;i<parameterMask.length;i++) gd.addCheckbox(i+": "+distortionCalibrationData.getParameterName(i), parameterMask[i]); for (int i=0;i<parameterMask.length;i++) gd.addCheckbox(i+": "+distortionCalibrationData.getParameterName(i), parameterMask[i]);
gd.addMessage("----------"); gd.addMessage("----------");
gd.addMessage("Select which channels (sub-cameras) to update"); gd.addMessage("Select which channels (sub-cameras) to update");
...@@ -9637,6 +9675,7 @@ M * V = B ...@@ -9637,6 +9675,7 @@ M * V = B
WindowTools.addScrollBars(gd); WindowTools.addScrollBars(gd);
gd.showDialog(); gd.showDialog();
if (gd.wasCanceled()) return false; if (gd.wasCanceled()) return false;
resetParametersToZero=gd.getNextBoolean();
for (int i=0;i<parameterMask.length;i++) parameterMask[i]= gd.getNextBoolean(); for (int i=0;i<parameterMask.length;i++) parameterMask[i]= gd.getNextBoolean();
for (int i=0;i<channelMask.length;i++) channelMask[i]= gd.getNextBoolean(); for (int i=0;i<channelMask.length;i++) channelMask[i]= gd.getNextBoolean();
if (stationMask.length>1) { if (stationMask.length>1) {
...@@ -9653,6 +9692,7 @@ M * V = B ...@@ -9653,6 +9692,7 @@ M * V = B
// boolean updateDisabled= gd.getNextBoolean(); // boolean updateDisabled= gd.getNextBoolean();
updateImageSetFromCamera( updateImageSetFromCamera(
resetParametersToZero,
distortionCalibrationData, distortionCalibrationData,
eyesisCameraParameters, eyesisCameraParameters,
parameterMask, //boolean [] parameterMask, parameterMask, //boolean [] parameterMask,
...@@ -9741,6 +9781,7 @@ M * V = B ...@@ -9741,6 +9781,7 @@ M * V = B
} }
if (updateFromCamera) updateImageSetFromCamera( if (updateFromCamera) updateImageSetFromCamera(
false, //resetParametersToZero
distortionCalibrationData, distortionCalibrationData,
eyesisCameraParameters, eyesisCameraParameters,
parameterMask, //boolean [] parameterMask, parameterMask, //boolean [] parameterMask,
...@@ -9771,6 +9812,7 @@ M * V = B ...@@ -9771,6 +9812,7 @@ M * V = B
* @param copyOrientation copy 2 goniometer angles, normally should be false * @param copyOrientation copy 2 goniometer angles, normally should be false
*/ */
public void updateImageSetFromCamera( public void updateImageSetFromCamera(
boolean resetParametersToZero, // reset to 0 instead of camera parameters
DistortionCalibrationData distortionCalibrationData, DistortionCalibrationData distortionCalibrationData,
EyesisCameraParameters eyesisCameraParameters, EyesisCameraParameters eyesisCameraParameters,
boolean [] parameterMask, boolean [] parameterMask,
...@@ -9785,7 +9827,17 @@ M * V = B ...@@ -9785,7 +9827,17 @@ M * V = B
if ((stationMask!=null) && !stationMask[stationNumber]) continue; if ((stationMask!=null) && !stationMask[stationNumber]) continue;
double [] oldVector=distortionCalibrationData.getParameters(i); double [] oldVector=distortionCalibrationData.getParameters(i);
double [] newVector=eyesisCameraParameters.getParametersVector(stationNumber,subCam); double [] newVector=eyesisCameraParameters.getParametersVector(stationNumber,subCam);
for (int j=0;j<oldVector.length;j++) if (parameterMask[j]) oldVector[j]=newVector[j]; for (int j=0;j<oldVector.length;j++) if (parameterMask[j]){
if (resetParametersToZero) newVector[j]=0.0;
oldVector[j]=newVector[j];
}
if (resetParametersToZero){
eyesisCameraParameters.setParametersVector(
newVector,
parameterMask,
stationNumber,
subCam);
}
distortionCalibrationData.setParameters(oldVector, i); distortionCalibrationData.setParameters(oldVector, i);
this.lensDistortionParameters.pixelSize=eyesisCameraParameters.getPixelSize(subCam); this.lensDistortionParameters.pixelSize=eyesisCameraParameters.getPixelSize(subCam);
this.lensDistortionParameters.distortionRadius=eyesisCameraParameters.getDistortionRadius(subCam); this.lensDistortionParameters.distortionRadius=eyesisCameraParameters.getDistortionRadius(subCam);
......
...@@ -879,6 +879,42 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -879,6 +879,42 @@ import org.apache.commons.configuration.XMLConfiguration;
gd.addNumericField("Distortion C (r^2)", subCam.distortionC, 6,8,""); gd.addNumericField("Distortion C (r^2)", subCam.distortionC, 6,8,"");
gd.addNumericField("Lens axis on the sensor (horizontal, from left edge)", subCam.px0, 2,7,"pixels"); gd.addNumericField("Lens axis on the sensor (horizontal, from left edge)", subCam.px0, 2,7,"pixels");
gd.addNumericField("Lens axis on the sensor (vertical, from top edge)", subCam.py0, 2,7,"pixels"); gd.addNumericField("Lens axis on the sensor (vertical, from top edge)", subCam.py0, 2,7,"pixels");
gd.addMessage("=== non-radial model parameters ===");
gd.addMessage("For r^2 (Distortion C):");
gd.addNumericField("Orthogonal elongation for r^2", 100*subCam.r_od[0][0], 3,7,"%");
gd.addNumericField("Diagonal elongation for r^2", 100*subCam.r_od[0][1], 3,7,"%");
gd.addMessage("For r^3 (Distortion B):");
gd.addNumericField("Distortion center shift X for r^3", 100*subCam.r_xy[0][0], 1,6,"%");
gd.addNumericField("Distortion center shift Y for r^3", 100*subCam.r_xy[0][1], 1,6,"%");
gd.addNumericField("Orthogonal elongation for r^3", 100*subCam.r_od[1][0], 3,7,"%");
gd.addNumericField("Diagonal elongation for r^3", 100*subCam.r_od[1][1], 3,7,"%");
gd.addMessage("For r^4 (Distortion A):");
gd.addNumericField("Distortion center shift X for r^4", 100*subCam.r_xy[1][0], 1,6,"%");
gd.addNumericField("Distortion center shift Y for r^4", 100*subCam.r_xy[1][1], 1,6,"%");
gd.addNumericField("Orthogonal elongation for r^4", 100*subCam.r_od[2][0], 3,7,"%");
gd.addNumericField("Diagonal elongation for r^4", 100*subCam.r_od[2][1], 3,7,"%");
gd.addMessage("For r^5 (Distortion A5):");
gd.addNumericField("Distortion center shift X for r^5", 100*subCam.r_xy[2][0], 1,6,"%");
gd.addNumericField("Distortion center shift Y for r^5", 100*subCam.r_xy[2][1], 1,6,"%");
gd.addNumericField("Orthogonal elongation for r^5", 100*subCam.r_od[3][0], 3,7,"%");
gd.addNumericField("Diagonal elongation for r^5", 100*subCam.r_od[3][1], 3,7,"%");
gd.addMessage("For r^6 (Distortion A6:");
gd.addNumericField("Distortion center shift X for r^6", 100*subCam.r_xy[3][0], 1,6,"%");
gd.addNumericField("Distortion center shift Y for r^6", 100*subCam.r_xy[3][1], 1,6,"%");
gd.addNumericField("Orthogonal elongation for r^6", 100*subCam.r_od[4][0], 3,7,"%");
gd.addNumericField("Diagonal elongation for r^6", 100*subCam.r_od[4][1], 3,7,"%");
gd.addMessage("For r^7 (Distortion A7):");
gd.addNumericField("Distortion center shift X for r^7", 100*subCam.r_xy[4][0], 1,6,"%");
gd.addNumericField("Distortion center shift Y for r^7", 100*subCam.r_xy[4][1], 1,6,"%");
gd.addNumericField("Orthogonal elongation for r^7", 100*subCam.r_od[5][0], 3,7,"%");
gd.addNumericField("Diagonal elongation for r^7", 100*subCam.r_od[5][1], 3,7,"%");
gd.addMessage("For r^8 (Distortion A8):");
gd.addNumericField("Distortion center shift X for r^8", 100*subCam.r_xy[5][0], 1,6,"%");
gd.addNumericField("Distortion center shift Y for r^8", 100*subCam.r_xy[5][1], 1,6,"%");
gd.addNumericField("Orthogonal elongation for r^8", 100*subCam.r_od[6][0], 3,7,"%");
gd.addNumericField("Diagonal elongation for r^8", 100*subCam.r_od[6][1], 3,7,"%");
} }
} }
gd.enableYesNoCancel("OK", "Done"); gd.enableYesNoCancel("OK", "Done");
...@@ -912,6 +948,33 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -912,6 +948,33 @@ import org.apache.commons.configuration.XMLConfiguration;
subCam.distortionC= gd.getNextNumber(); subCam.distortionC= gd.getNextNumber();
subCam.px0= gd.getNextNumber(); subCam.px0= gd.getNextNumber();
subCam.py0= gd.getNextNumber(); subCam.py0= gd.getNextNumber();
subCam.r_od[0][0]= 0.01*gd.getNextNumber();
subCam.r_od[0][1]= 0.01*gd.getNextNumber();
subCam.r_xy[0][0]= 0.01*gd.getNextNumber();
subCam.r_xy[0][1]= 0.01*gd.getNextNumber();
subCam.r_od[1][0]= 0.01*gd.getNextNumber();
subCam.r_od[1][1]= 0.01*gd.getNextNumber();
subCam.r_xy[1][0]= 0.01*gd.getNextNumber();
subCam.r_xy[1][1]= 0.01*gd.getNextNumber();
subCam.r_od[2][0]= 0.01*gd.getNextNumber();
subCam.r_od[2][1]= 0.01*gd.getNextNumber();
subCam.r_xy[2][0]= 0.01*gd.getNextNumber();
subCam.r_xy[2][1]= 0.01*gd.getNextNumber();
subCam.r_od[3][0]= 0.01*gd.getNextNumber();
subCam.r_od[3][1]= 0.01*gd.getNextNumber();
subCam.r_xy[3][0]= 0.01*gd.getNextNumber();
subCam.r_xy[3][1]= 0.01*gd.getNextNumber();
subCam.r_od[4][0]= 0.01*gd.getNextNumber();
subCam.r_od[4][1]= 0.01*gd.getNextNumber();
subCam.r_xy[4][0]= 0.01*gd.getNextNumber();
subCam.r_xy[4][1]= 0.01*gd.getNextNumber();
subCam.r_od[5][0]= 0.01*gd.getNextNumber();
subCam.r_od[5][1]= 0.01*gd.getNextNumber();
subCam.r_xy[5][0]= 0.01*gd.getNextNumber();
subCam.r_xy[5][1]= 0.01*gd.getNextNumber();
subCam.r_od[6][0]= 0.01*gd.getNextNumber();
subCam.r_od[6][1]= 0.01*gd.getNextNumber();
} }
} }
return gd.wasOKed(); return gd.wasOKed();
...@@ -984,6 +1047,32 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -984,6 +1047,32 @@ import org.apache.commons.configuration.XMLConfiguration;
subCam.distortionA, //24 (22) r^4 (normalized to focal length or to sensor half width?) subCam.distortionA, //24 (22) r^4 (normalized to focal length or to sensor half width?)
subCam.distortionB, //25 (23) r^3 subCam.distortionB, //25 (23) r^3
subCam.distortionC, //26 (24) r^2 subCam.distortionC, //26 (24) r^2
subCam.r_od[0][0],
subCam.r_od[0][1],
subCam.r_xy[0][0],
subCam.r_xy[0][1],
subCam.r_od[1][0],
subCam.r_od[1][1],
subCam.r_xy[1][0],
subCam.r_xy[1][1],
subCam.r_od[2][0],
subCam.r_od[2][1],
subCam.r_xy[2][0],
subCam.r_xy[2][1],
subCam.r_od[3][0],
subCam.r_od[3][1],
subCam.r_xy[3][0],
subCam.r_xy[3][1],
subCam.r_od[4][0],
subCam.r_od[4][1],
subCam.r_xy[4][0],
subCam.r_xy[4][1],
subCam.r_od[5][0],
subCam.r_od[5][1],
subCam.r_xy[5][0],
subCam.r_xy[5][1],
subCam.r_od[6][0],
subCam.r_od[6][1]
}; };
// Global parameters, not adjusted - just copied once when camera is selected // Global parameters, not adjusted - just copied once when camera is selected
// or should they stay fixed and not copied at all? // or should they stay fixed and not copied at all?
...@@ -1030,15 +1119,14 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -1030,15 +1119,14 @@ import org.apache.commons.configuration.XMLConfiguration;
int stationNumber, int stationNumber,
int subCamNumber // int subCamNumber //
){ ){
if (parVect.length!=27) throw new IllegalArgumentException ("Wrong length of the parameters vector: "+parVect.length+"(should be 27)"); // if (parVect.length!=27) throw new IllegalArgumentException ("Wrong length of the parameters vector: "+parVect.length+"(should be 27)");
if (parVect.length!=53) throw new IllegalArgumentException ("Wrong length of the parameters vector: "+parVect.length+"(should be 53)");
if ( if (
(this.eyesisSubCameras==null) || (this.eyesisSubCameras==null) ||
(this.numStations<=stationNumber) || (this.numStations<=stationNumber) ||
(this.eyesisSubCameras.length<=stationNumber) || (this.eyesisSubCameras.length<=stationNumber) ||
(this.eyesisSubCameras[stationNumber].length<=subCamNumber)) throw new IllegalArgumentException (this.eyesisSubCameras[stationNumber].length<=subCamNumber)) throw new IllegalArgumentException
("Nonexistent subcamera "+subCamNumber+ " and/or station number="+stationNumber); ("Nonexistent subcamera "+subCamNumber+ " and/or station number="+stationNumber);
EyesisSubCameraParameters subCam=this.eyesisSubCameras[stationNumber][subCamNumber]; EyesisSubCameraParameters subCam=this.eyesisSubCameras[stationNumber][subCamNumber];
if (update[0]) subCam.azimuth=parVect[0]; // 0 azimuth of the lens entrance pupil center, degrees, clockwise looking from top if (update[0]) subCam.azimuth=parVect[0]; // 0 azimuth of the lens entrance pupil center, degrees, clockwise looking from top
if (update[1]) subCam.radius=parVect[1]; // 1 mm, distance from the rotation axis if (update[1]) subCam.radius=parVect[1]; // 1 mm, distance from the rotation axis
...@@ -1067,7 +1155,34 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -1067,7 +1155,34 @@ import org.apache.commons.configuration.XMLConfiguration;
if (update[24]) subCam.distortionA= parVect[24]; //24 r^4 (normalized to focal length or to sensor half width?) if (update[24]) subCam.distortionA= parVect[24]; //24 r^4 (normalized to focal length or to sensor half width?)
if (update[25]) subCam.distortionB= parVect[25]; //25 r^3 if (update[25]) subCam.distortionB= parVect[25]; //25 r^3
if (update[26]) subCam.distortionC= parVect[26]; //26 r^2 if (update[26]) subCam.distortionC= parVect[26]; //26 r^2
if (update[27]) subCam.r_od[0][0]= parVect[27];
if (update[28]) subCam.r_od[0][1]= parVect[28];
if (update[29]) subCam.r_xy[0][0]= parVect[29];
if (update[30]) subCam.r_xy[0][1]= parVect[30];
if (update[31]) subCam.r_od[1][0]= parVect[31];
if (update[32]) subCam.r_od[1][1]= parVect[32];
if (update[33]) subCam.r_xy[1][0]= parVect[33];
if (update[34]) subCam.r_xy[1][1]= parVect[34];
if (update[35]) subCam.r_od[2][0]= parVect[35];
if (update[36]) subCam.r_od[2][1]= parVect[36];
if (update[37]) subCam.r_xy[2][0]= parVect[37];
if (update[38]) subCam.r_xy[2][1]= parVect[38];
if (update[39]) subCam.r_od[3][0]= parVect[39];
if (update[40]) subCam.r_od[3][1]= parVect[40];
if (update[41]) subCam.r_xy[3][0]= parVect[41];
if (update[42]) subCam.r_xy[3][1]= parVect[42];
if (update[43]) subCam.r_od[4][0]= parVect[43];
if (update[44]) subCam.r_od[4][1]= parVect[44];
if (update[45]) subCam.r_xy[4][0]= parVect[45];
if (update[46]) subCam.r_xy[4][1]= parVect[46];
if (update[47]) subCam.r_od[5][0]= parVect[47];
if (update[48]) subCam.r_od[5][1]= parVect[48];
if (update[49]) subCam.r_xy[5][0]= parVect[49];
if (update[50]) subCam.r_xy[5][1]= parVect[50];
if (update[51]) subCam.r_od[6][0]= parVect[51];
if (update[52]) subCam.r_od[6][1]= parVect[52];
} }
public void initSubCameras( public void initSubCameras(
int numStation, int numStation,
int numSubCameras){ int numSubCameras){
...@@ -1094,6 +1209,8 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -1094,6 +1209,8 @@ import org.apache.commons.configuration.XMLConfiguration;
0.0, // double distortionC // r^2 0.0, // double distortionC // r^2
1296.0, // double px0=1296.0; // center of the lens on the sensor, pixels 1296.0, // double px0=1296.0; // center of the lens on the sensor, pixels
968.0, // double py0=968.0; // center of the lens on the sensor, pixels 968.0, // double py0=968.0; // center of the lens on the sensor, pixels
null, // eccentricity for b,a,a5,a6,a7,a8
null, // elongation for c,b,a,a5,a6,a7,a8
1.0); //channelWeightDefault 1.0); //channelWeightDefault
this.eyesisSubCameras[numStation][1]=new EyesisSubCameraParameters( //TODO: modify for lens adjustment defaults? this.eyesisSubCameras[numStation][1]=new EyesisSubCameraParameters( //TODO: modify for lens adjustment defaults?
30.0, // double azimuth, // azimuth of the lens entrance pupil center, degrees, clockwise looking from top 30.0, // double azimuth, // azimuth of the lens entrance pupil center, degrees, clockwise looking from top
...@@ -1114,6 +1231,8 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -1114,6 +1231,8 @@ import org.apache.commons.configuration.XMLConfiguration;
0.0, // double distortionC // r^2 0.0, // double distortionC // r^2
1296.0, // double px0=1296.0; // center of the lens on the sensor, pixels 1296.0, // double px0=1296.0; // center of the lens on the sensor, pixels
968.0, // double py0=968.0; // center of the lens on the sensor, pixels 968.0, // double py0=968.0; // center of the lens on the sensor, pixels
null, // eccentricity for b,a,a5,a6,a7,a8
null, // elongation for c,b,a,a5,a6,a7,a8
1.0); //channelWeightDefault 1.0); //channelWeightDefault
this.eyesisSubCameras[numStation][2]=new EyesisSubCameraParameters( //TODO: modify for lens adjustment defaults? this.eyesisSubCameras[numStation][2]=new EyesisSubCameraParameters( //TODO: modify for lens adjustment defaults?
-30.0, // double azimuth, // azimuth of the lens entrance pupil center, degrees, clockwise looking from top -30.0, // double azimuth, // azimuth of the lens entrance pupil center, degrees, clockwise looking from top
...@@ -1134,6 +1253,8 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -1134,6 +1253,8 @@ import org.apache.commons.configuration.XMLConfiguration;
0.0, // double distortionC // r^2 0.0, // double distortionC // r^2
1296.0, // double px0=1296.0; // center of the lens on the sensor, pixels 1296.0, // double px0=1296.0; // center of the lens on the sensor, pixels
968.0, // double py0=968.0; // center of the lens on the sensor, pixels 968.0, // double py0=968.0; // center of the lens on the sensor, pixels
null, // eccentricity for b,a,a5,a6,a7,a8
null, // elongation for c,b,a,a5,a6,a7,a8
1.0); //channelWeightDefault 1.0); //channelWeightDefault
} else if (numSubCameras==1) { } else if (numSubCameras==1) {
this.eyesisSubCameras[numStation][0]=new EyesisSubCameraParameters( //TODO: modify for lens adjustment defaults? this.eyesisSubCameras[numStation][0]=new EyesisSubCameraParameters( //TODO: modify for lens adjustment defaults?
...@@ -1155,6 +1276,8 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -1155,6 +1276,8 @@ import org.apache.commons.configuration.XMLConfiguration;
0.0, // double distortionC // r^2 0.0, // double distortionC // r^2
1296.0, // double px0=1296.0; // center of the lens on the sensor, pixels 1296.0, // double px0=1296.0; // center of the lens on the sensor, pixels
968.0, // double py0=968.0; // center of the lens on the sensor, pixels 968.0, // double py0=968.0; // center of the lens on the sensor, pixels
null, // eccentricity for b,a,a5,a6,a7,a8
null, // elongation for c,b,a,a5,a6,a7,a8
1.0); //channelWeightDefault 1.0); //channelWeightDefault
} else { } else {
// default setup for the 26 sub-cameras // default setup for the 26 sub-cameras
...@@ -1177,6 +1300,8 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -1177,6 +1300,8 @@ import org.apache.commons.configuration.XMLConfiguration;
0.0, // double distortionC // r^2 0.0, // double distortionC // r^2
1296.0, // double px0=1296.0; // center of the lens on the sensor, pixels 1296.0, // double px0=1296.0; // center of the lens on the sensor, pixels
968.0, // double py0=968.0; // center of the lens on the sensor, pixels 968.0, // double py0=968.0; // center of the lens on the sensor, pixels
null, // eccentricity for b,a,a5,a6,a7,a8
null, // elongation for c,b,a,a5,a6,a7,a8
1.0); //channelWeightDefault 1.0); //channelWeightDefault
for (int i=8;i<16;i++) if (i<numSubCameras) this.eyesisSubCameras[numStation][i]=new EyesisSubCameraParameters( // middle 8 cameras for (int i=8;i<16;i++) if (i<numSubCameras) this.eyesisSubCameras[numStation][i]=new EyesisSubCameraParameters( // middle 8 cameras
45.0*(i-8), // double azimuth, // azimuth of the lens entrance pupil center, degrees, clockwise looking from top 45.0*(i-8), // double azimuth, // azimuth of the lens entrance pupil center, degrees, clockwise looking from top
...@@ -1197,6 +1322,8 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -1197,6 +1322,8 @@ import org.apache.commons.configuration.XMLConfiguration;
0.0, // double distortionC // r^2 0.0, // double distortionC // r^2
1296.0, // double px0=1296.0; // center of the lens on the sensor, pixels 1296.0, // double px0=1296.0; // center of the lens on the sensor, pixels
968.0, // double py0=968.0; // center of the lens on the sensor, pixels 968.0, // double py0=968.0; // center of the lens on the sensor, pixels
null, // eccentricity for b,a,a5,a6,a7,a8
null, // elongation for c,b,a,a5,a6,a7,a8
1.0); //channelWeightDefault 1.0); //channelWeightDefault
for (int i=16;i<24;i++) if (i<numSubCameras) this.eyesisSubCameras[numStation][i]=new EyesisSubCameraParameters( // bottom eight cameras for (int i=16;i<24;i++) if (i<numSubCameras) this.eyesisSubCameras[numStation][i]=new EyesisSubCameraParameters( // bottom eight cameras
45.0*(i-16), // double azimuth, // azimuth of the lens entrance pupil center, degrees, clockwise looking from top 45.0*(i-16), // double azimuth, // azimuth of the lens entrance pupil center, degrees, clockwise looking from top
...@@ -1217,6 +1344,8 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -1217,6 +1344,8 @@ import org.apache.commons.configuration.XMLConfiguration;
0.0, // double distortionC // r^2 0.0, // double distortionC // r^2
1296.0, // double px0=1296.0; // center of the lens on the sensor, pixels 1296.0, // double px0=1296.0; // center of the lens on the sensor, pixels
968.0, // double py0=968.0; // center of the lens on the sensor, pixels 968.0, // double py0=968.0; // center of the lens on the sensor, pixels
null, // eccentricity for b,a,a5,a6,a7,a8
null, // elongation for c,b,a,a5,a6,a7,a8
1.0); //channelWeightDefault 1.0); //channelWeightDefault
if (24<numSubCameras) this.eyesisSubCameras[numStation][24]=new EyesisSubCameraParameters( if (24<numSubCameras) this.eyesisSubCameras[numStation][24]=new EyesisSubCameraParameters(
90, // double azimuth, // azimuth of the lens entrance pupil center, degrees, clockwise looking from top 90, // double azimuth, // azimuth of the lens entrance pupil center, degrees, clockwise looking from top
...@@ -1237,6 +1366,8 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -1237,6 +1366,8 @@ import org.apache.commons.configuration.XMLConfiguration;
0.0, // double distortionC // r^2 0.0, // double distortionC // r^2
1296.0, // double px0=1296.0; // center of the lens on the sensor, pixels 1296.0, // double px0=1296.0; // center of the lens on the sensor, pixels
968.0, // double py0=968.0; // center of the lens on the sensor, pixels 968.0, // double py0=968.0; // center of the lens on the sensor, pixels
null, // eccentricity for b,a,a5,a6,a7,a8
null, // elongation for c,b,a,a5,a6,a7,a8
4.0); //channelWeightDefault 4.0); //channelWeightDefault
if (25<numSubCameras) this.eyesisSubCameras[numStation][25]=new EyesisSubCameraParameters( if (25<numSubCameras) this.eyesisSubCameras[numStation][25]=new EyesisSubCameraParameters(
270, // double azimuth, // azimuth of the lens entrance pupil center, degrees, clockwise looking from top 270, // double azimuth, // azimuth of the lens entrance pupil center, degrees, clockwise looking from top
...@@ -1257,6 +1388,8 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -1257,6 +1388,8 @@ import org.apache.commons.configuration.XMLConfiguration;
0.0, // double distortionC // r^2 0.0, // double distortionC // r^2
1296.0, // double px0=1296.0; // center of the lens on the sensor, pixels 1296.0, // double px0=1296.0; // center of the lens on the sensor, pixels
968.0, // double py0=968.0; // center of the lens on the sensor, pixels 968.0, // double py0=968.0; // center of the lens on the sensor, pixels
null, // eccentricity for b,a,a5,a6,a7,a8
null, // elongation for c,b,a,a5,a6,a7,a8
4.0); //channelWeightDefault 4.0); //channelWeightDefault
} }
} }
...@@ -1322,8 +1455,6 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -1322,8 +1455,6 @@ import org.apache.commons.configuration.XMLConfiguration;
} }
} }
} }
} }
...@@ -47,6 +47,24 @@ import java.util.Properties; ...@@ -47,6 +47,24 @@ import java.util.Properties;
public double channelWeightCurrent=1.0; public double channelWeightCurrent=1.0;
public int [][] defectsXY=null; // pixel defects coordinates list (starting with worst) 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 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( public EyesisSubCameraParameters(
double azimuth, // azimuth of the lens entrance pupil center, degrees, clockwise looking from top double azimuth, // azimuth of the lens entrance pupil center, degrees, clockwise looking from top
double radius, // mm, distance from the rotation axis double radius, // mm, distance from the rotation axis
...@@ -66,6 +84,8 @@ import java.util.Properties; ...@@ -66,6 +84,8 @@ import java.util.Properties;
double distortionC, // r^2 double distortionC, // r^2
double px0, // center of the lens on the sensor, pixels double px0, // center of the lens on the sensor, pixels
double py0, // 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 double channelWeightDefault
){ ){
this.azimuth=azimuth; this.azimuth=azimuth;
...@@ -86,6 +106,12 @@ import java.util.Properties; ...@@ -86,6 +106,12 @@ import java.util.Properties;
this.distortionC=distortionC; // r^2 this.distortionC=distortionC; // r^2
this.px0=px0; this.px0=px0;
this.py0=py0; 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.channelWeightDefault=channelWeightDefault;
this.channelWeightCurrent=this.channelWeightDefault; this.channelWeightCurrent=this.channelWeightDefault;
this.defectsXY=null; // pixel defects coordinates list (starting with worst) this.defectsXY=null; // pixel defects coordinates list (starting with worst)
...@@ -113,10 +139,18 @@ import java.util.Properties; ...@@ -113,10 +139,18 @@ import java.util.Properties;
this.distortionC, this.distortionC,
this.px0, this.px0,
this.py0, this.py0,
this.r_xy,
this.r_od,
this.channelWeightDefault 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){ public void setProperties(String prefix,Properties properties){
properties.setProperty(prefix+"azimuth",this.azimuth+""); properties.setProperty(prefix+"azimuth",this.azimuth+"");
properties.setProperty(prefix+"radius",this.radius+""); properties.setProperty(prefix+"radius",this.radius+"");
...@@ -136,6 +170,14 @@ import java.util.Properties; ...@@ -136,6 +170,14 @@ import java.util.Properties;
properties.setProperty(prefix+"distortionC",this.distortionC+""); properties.setProperty(prefix+"distortionC",this.distortionC+"");
properties.setProperty(prefix+"px0",this.px0+""); properties.setProperty(prefix+"px0",this.px0+"");
properties.setProperty(prefix+"py0",this.py0+""); 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+""); properties.setProperty(prefix+"channelWeightDefault",this.channelWeightDefault+"");
} }
public void getProperties(String prefix,Properties properties){ public void getProperties(String prefix,Properties properties){
...@@ -175,9 +217,19 @@ import java.util.Properties; ...@@ -175,9 +217,19 @@ import java.util.Properties;
this.px0=Double.parseDouble(properties.getProperty(prefix+"px0")); this.px0=Double.parseDouble(properties.getProperty(prefix+"px0"));
if (properties.getProperty(prefix+"py0")!=null) if (properties.getProperty(prefix+"py0")!=null)
this.py0=Double.parseDouble(properties.getProperty(prefix+"py0")); 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) { if (properties.getProperty(prefix+"channelWeightDefault")!=null) {
this.channelWeightDefault=Double.parseDouble(properties.getProperty(prefix+"channelWeightDefault")); this.channelWeightDefault=Double.parseDouble(properties.getProperty(prefix+"channelWeightDefault"));
this.channelWeightCurrent=this.channelWeightDefault; this.channelWeightCurrent=this.channelWeightDefault;
} }
} }
public void setChannelWeightCurrent( public void setChannelWeightCurrent(
...@@ -190,5 +242,4 @@ import java.util.Properties; ...@@ -190,5 +242,4 @@ import java.util.Properties;
public double getChannelWeightDefault(){ public double getChannelWeightDefault(){
return this.channelWeightDefault; return this.channelWeightDefault;
} }
} }
...@@ -422,6 +422,34 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit ...@@ -422,6 +422,34 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
this.pathName=pathname; this.pathName=pathname;
return true; 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) * Verifies that series exists and is not empty (valid for LMA)
* @param num - series to verify * @param num - series to verify
...@@ -1406,31 +1434,13 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit ...@@ -1406,31 +1434,13 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
sNumNewEnabledPerStation+=numNewEnabledPerStation[i]; sNumNewEnabledPerStation+=numNewEnabledPerStation[i];
} }
if (!isSeriesValid(numSeries)){ if (!isSeriesValid(numSeries)){
int sourceSeries=-1; int sourceSeries= findLastValidSeries(numSeries);
for (int i=numSeries-1;i>=0;i--) if (isSeriesValid(i)){ if (sourceSeries>=0) copySeries(sourceSeries, numSeries);
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;
}
} }
GenericDialog gd = new GenericDialog("Fitting Strategy Step Configuration, step "+numSeries+" number of enabled images="+this.distortionCalibrationData.getNumEnabled()); 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("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); gd.addCheckbox("Select all images, reopen dialog", false);
if (numEstimated>0){ if (numEstimated>0){
...@@ -1571,6 +1581,7 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit ...@@ -1571,6 +1581,7 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
gd.showDialog(); gd.showDialog();
if (gd.wasCanceled()) return -2; if (gd.wasCanceled()) return -2;
boolean copyFromPrevious=gd.getNextBoolean(); boolean copyFromPrevious=gd.getNextBoolean();
int sourceStrategy= (int) gd.getNextNumber();
boolean removeAllImages=gd.getNextBoolean(); boolean removeAllImages=gd.getNextBoolean();
boolean selectAllImages=gd.getNextBoolean(); boolean selectAllImages=gd.getNextBoolean();
boolean selectEstimated=false; boolean selectEstimated=false;
...@@ -1595,7 +1606,17 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit ...@@ -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 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++){ for (int i =0; i<this.distortionCalibrationData.getNumImages();i++){
// this.selectedImages[numSeries][i]=false; // invalidate - all, regardless of .enabled // this.selectedImages[numSeries][i]=false; // invalidate - all, regardless of .enabled
this.selectedImages[numSeries][i]=selectAllImages || ((i==0) && removeAllImages); // invalidate - all, regardless of .enabled this.selectedImages[numSeries][i]=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 ...@@ -1777,7 +1798,7 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
} }
public boolean selectStrategy(int startSerNumber){ public boolean selectStrategy(int startSerNumber){
int defaultLength=20; int defaultLength=30;
boolean selectImages= false; boolean selectImages= false;
boolean allImages= false; boolean allImages= false;
boolean selectParameters=true; boolean selectParameters=true;
......
import java.util.Arrays;
import java.util.Properties; import java.util.Properties;
import ij.IJ; import ij.IJ;
...@@ -17,9 +18,10 @@ import Jama.Matrix; ...@@ -17,9 +18,10 @@ import Jama.Matrix;
*/ */
// lens parameters (add more later) // lens parameters (add more later)
final int numInputs=27; // with A8...// 24; // parameters in subcamera+... final int numInputs= 53; //27; // with A8...// 24; // parameters in subcamera+...
final int numOutputs=16; // with A8...//13; // parameters in a single camera final int numOutputs=42; //16; // with A8...//13; // parameters in a single camera
// final
boolean cummulativeCorrection=true; // r_xy, r_od for higher terms are relative to lower ones
public double focalLength=4.5; public double focalLength=4.5;
public double pixelSize= 2.2; //um public double pixelSize= 2.2; //um
public double distortionRadius= 2.8512; // mm - half width of the sensor public double distortionRadius= 2.8512; // mm - half width of the sensor
...@@ -41,8 +43,32 @@ import Jama.Matrix; ...@@ -41,8 +43,32 @@ import Jama.Matrix;
public double px0=1296.0; // center of the lens on the sensor, pixels public double px0=1296.0; // center of the lens on the sensor, pixels
public double py0=968.0; // center of the lens on the sensor, pixels public double py0=968.0; // center of the lens on the sensor, pixels
public boolean flipVertical; // acquired image is mirrored vertically (mirror used) public boolean flipVertical; // acquired image is mirrored vertically (mirror used)
public int debugLevel=1; // was 2
// new non-radial parameters
final private double [][] r_xy_dflt={{0.0,0.0},{0.0,0.0},{0.0,0.0},{0.0,0.0},{0.0,0.0},{0.0,0.0}}; // only 6, as for the first term delta x, delta y ==0
final private double [][] r_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
public double [][] r_xyod=null; //{x0,y0,ortho, diagonal}
// total number of new parameters = 6*2+7+7=26
public int debugLevel=1; // was 2
/*
Modifying to accommodate for eccentricity of different terms (2 parameters per term) and elliptical shape (another 2 terms). When all are
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)
*/
// intermediate values // intermediate values
public double phi, theta,psi,cPH,sPH,cTH,sTH,cPS,sPS; public double phi, theta,psi,cPH,sPH,cTH,sTH,cPS,sPS;
public double [][] rotMatrix=new double[3][3]; // includes mirroring for Y (target coordinates y- down, camera - y up) public double [][] rotMatrix=new double[3][3]; // includes mirroring for Y (target coordinates y- down, camera - y up)
...@@ -86,9 +112,11 @@ import Jama.Matrix; ...@@ -86,9 +112,11 @@ import Jama.Matrix;
double y0, // lens axis from pattern center, mm (down) double y0, // lens axis from pattern center, mm (down)
double z0, // lens axis from pattern center, mm (away from the camera) double z0, // lens axis from pattern center, mm (away from the camera)
double distance, // distance from the lens input pupil to the pattern plane along the camera axis, mm double distance, // distance from the lens input pupil to the pattern plane along the camera axis, mm
double px0, // center of the lens on the senosr, pixels double px0, // center of the lens on the sensor, pixels
double py0, // center of the lens on the senosr, pixels double py0, // center of the lens on the sensor, pixels
boolean flipVertical // acquired image is mirrored vertically (mirror used) boolean flipVertical, // acquired image is mirrored vertically (mirror used)
double [][] r_xy,
double [][] r_od
){ ){
setLensDistortionParameters( setLensDistortionParameters(
focalLength, focalLength,
...@@ -110,29 +138,36 @@ import Jama.Matrix; ...@@ -110,29 +138,36 @@ import Jama.Matrix;
distance, distance,
px0, px0,
py0, py0,
flipVertical); flipVertical,
r_xy,
r_od);
} }
public LensDistortionParameters(){ public LensDistortionParameters(){
this.focalLength=4.5; setLensDistortionParameters(
this.pixelSize=2.2; 4.5, // focalLength,
this.distortionRadius=2.8512; 2.2, // pixelSize,
this.distortionA8=0.0; 2.8512, // distortionRadius,
this.distortionA7=0.0; 0.0, // distortionA8,
this.distortionA6=0.0; 0.0, // distortionA7,
this.distortionA5=0.0; 0.0, // distortionA6,
this.distortionA=0.0; 0.0, // distortionA5,
this.distortionB=0.0; 0.0, // distortionA,
this.distortionC=0.0; 0.0, // distortionB,
this.yaw=0.0; 0.0, // distortionC,
this.pitch=0.0; 0.0, // yaw,
this.roll=0.0; 0.0, // pitch,
this.x0=0.0; 0.0, // roll,
this.y0=0.0; 0.0, // x0,
this.z0=0.0; 0.0, // y0,
this.distance=2360.0; 0.0, // z0,
this.px0=1296.0; 2360.0, // distance,
this.py0=968.0; 1296, // px0,
this.flipVertical=true; 698, // py0,
true, // flipVertical,
null, // r_xy,
null // r_od,
);
} }
public LensDistortionParameters clone() { public LensDistortionParameters clone() {
return new LensDistortionParameters( return new LensDistortionParameters(
...@@ -155,7 +190,9 @@ import Jama.Matrix; ...@@ -155,7 +190,9 @@ import Jama.Matrix;
this.distance, this.distance,
this.px0, this.px0,
this.py0, this.py0,
this.flipVertical this.flipVertical,
this.r_xy,
this.r_od
); );
} }
public void setLensDistortionParameters( public void setLensDistortionParameters(
...@@ -179,7 +216,9 @@ import Jama.Matrix; ...@@ -179,7 +216,9 @@ import Jama.Matrix;
double distance, // distance from the lens input pupil to the pattern plane along the camera axis, mm double distance, // distance from the lens input pupil to the pattern plane along the camera axis, mm
double px0, // center of the lens on the sensor, pixels double px0, // center of the lens on the sensor, pixels
double py0, // center of the lens on the sensor, pixels double py0, // center of the lens on the sensor, pixels
boolean flipVertical // acquired image is mirrored vertically (mirror used) boolean flipVertical, // acquired image is mirrored vertically (mirror used)
double [][] r_xy, // per polynomial term center x,y correction only 6, as for the first term delta x, delta y ==0
double [][] r_od // per polynomial term orthogonal+diagonal elongation
){ ){
this.focalLength=focalLength; this.focalLength=focalLength;
this.pixelSize=pixelSize; this.pixelSize=pixelSize;
...@@ -201,8 +240,15 @@ import Jama.Matrix; ...@@ -201,8 +240,15 @@ import Jama.Matrix;
this.px0=px0; this.px0=px0;
this.py0=py0; this.py0=py0;
this.flipVertical=flipVertical; this.flipVertical=flipVertical;
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();
recalcCommons(); recalcCommons();
} }
public void setIntrincicFromSubcamera(EyesisSubCameraParameters pars){ public void setIntrincicFromSubcamera(EyesisSubCameraParameters pars){
setLensDistortionParameters( setLensDistortionParameters(
pars.focalLength, pars.focalLength,
...@@ -225,40 +271,49 @@ import Jama.Matrix; ...@@ -225,40 +271,49 @@ import Jama.Matrix;
this.distance, // (keep) distance from the lens input pupil to the pattern plane along the camera axis, mm this.distance, // (keep) distance from the lens input pupil to the pattern plane along the camera axis, mm
pars.px0, // center of the lens on the sensor, pixels pars.px0, // center of the lens on the sensor, pixels
pars.py0, // center of the lens on the sensor, pixels pars.py0, // center of the lens on the sensor, pixels
this.flipVertical // (keep) acquired image is mirrored vertically (mirror used) this.flipVertical, // (keep) acquired image is mirrored vertically (mirror used)
pars.r_xy, // do not exist yet!
pars.r_od // do not exist yet!
); );
} }
public void setLensDistortionParameters(LensDistortionParameters ldp public void setLensDistortionParameters(LensDistortionParameters ldp
){ ){
this.focalLength=ldp.focalLength; setLensDistortionParameters(
this.pixelSize=ldp.pixelSize; ldp.focalLength,
this.distortionRadius=ldp.distortionRadius; ldp.pixelSize,
this.distortionA8=ldp.distortionA8; ldp.distortionRadius,
this.distortionA7=ldp.distortionA7; ldp.distortionA8,
this.distortionA6=ldp.distortionA6; ldp.distortionA7,
this.distortionA5=ldp.distortionA5; ldp.distortionA6,
this.distortionA=ldp.distortionA; ldp.distortionA5,
this.distortionB=ldp.distortionB; ldp.distortionA,
this.distortionC=ldp.distortionC; ldp.distortionB,
this.yaw=ldp.yaw; ldp.distortionC,
this.pitch=ldp.pitch; ldp.yaw,
this.roll=ldp.roll; ldp.pitch,
this.x0=ldp.x0; ldp.roll,
this.y0=ldp.y0; ldp.x0,
this.z0=ldp.z0; ldp.y0,
this.distance=ldp.distance; ldp.z0,
this.px0=ldp.px0; ldp.distance,
this.py0=ldp.py0; ldp.px0,
this.flipVertical=ldp.flipVertical; ldp.py0,
recalcCommons(); ldp.flipVertical,
ldp.r_xy,
ldp.r_od);
} }
// TODO: Fix for non-radial !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// just for debugging // just for debugging
public void setLensDistortionParameters(LensDistortionParameters ldp, public void setLensDistortionParameters(LensDistortionParameters ldp,
int index, // parameter to add delta, 1..13->14->17 int index, // parameter to add delta, 1..13->14->17
double delta double delta
){ ){
/*
this.focalLength=ldp.focalLength+((index==7)?delta:0); this.focalLength=ldp.focalLength+((index==7)?delta:0);
this.pixelSize=ldp.pixelSize; this.pixelSize=ldp.pixelSize;
this.distortionRadius=ldp.distortionRadius; this.distortionRadius=ldp.distortionRadius;
...@@ -279,11 +334,44 @@ import Jama.Matrix; ...@@ -279,11 +334,44 @@ import Jama.Matrix;
this.px0=ldp.px0+((index==16)?delta:0); this.px0=ldp.px0+((index==16)?delta:0);
this.py0=ldp.py0+((index==17)?delta:0); this.py0=ldp.py0+((index==17)?delta:0);
this.flipVertical=ldp.flipVertical; this.flipVertical=ldp.flipVertical;
*/
setLensDistortionParameters(ldp);
final int index_r_xy=18;
final int index_r_od=30;
final int index_end=44;
switch (index){
case 1: this.yaw+=delta; break;
case 2: this.pitch+=delta; break; //=ldp.pitch+((index==2)?delta:0);
case 3: this.roll+=delta; break; // =ldp.roll+((index==3)?delta:0);
case 4: this.x0+=delta; break; // =ldp.x0+((index==4)?delta:0);
case 5: this.y0+=delta; break; // =ldp.y0+((index==5)?delta:0);
case 6: this.z0+=delta; break; // =ldp.z0+((index==6)?delta:0);
case 7: this.focalLength+=delta; break; // =ldp.focalLength+((index==7)?delta:0);
case 8: this.distance+=delta; break; // =ldp.distance+((index==8)?delta:0);
case 9: this.distortionA8+=delta; break; // =ldp.distortionA8+((index==9)?delta:0);
case 10: this.distortionA7+=delta; break; // =ldp.distortionA7+((index==10)?delta:0);
case 11: this.distortionA6+=delta; break; // =ldp.distortionA6+((index==11)?delta:0);
case 12: this.distortionA5+=delta; break; // =ldp.distortionA5+((index==12)?delta:0);
case 13: this.distortionA+=delta; break; // =ldp.distortionA+((index==13)?delta:0);
case 14: this.distortionB+=delta; break; // =ldp.distortionB+((index==14)?delta:0);
case 15: this.distortionC+=delta; break; // =ldp.distortionC+((index==15)?delta:0);
case 16: this.px0+=delta; break; // =ldp.px0+((index==16)?delta:0);
case 17: this.py0+=delta; break; // =ldp.py0+((index==17)?delta:0);
default:
if ((index>=index_r_xy) && (index<index_r_od)){
this.r_xy[(index-index_r_xy)/2][(index-index_r_xy)%2]+=delta;
} else if ((index>=index_r_od) && (index<index_end)){
this.r_od[(index-index_r_od)/2][(index-index_r_od)%2]+=delta;
}
}
recalcCommons(); recalcCommons();
} }
// recalculate common (point-invariant) intermediate values (cos, sin, rotation matrix) // recalculate common (point-invariant) intermediate values (cos, sin, rotation matrix)
public void recalcCommons(){
public void recalcCommons(){
// this.cummulativeCorrection=false; // just debugging
// public double phi, theta,psi,cPH,sPH,cTH,sTH,cPS,sPS; // public double phi, theta,psi,cPH,sPH,cTH,sTH,cPS,sPS;
// public double [][] rotMatrix=new double[3][3]; // public double [][] rotMatrix=new double[3][3];
this.phi= this.yaw*Math.PI/180; this.phi= this.yaw*Math.PI/180;
...@@ -332,7 +420,27 @@ dPXmmc/dphi= ...@@ -332,7 +420,27 @@ dPXmmc/dphi=
System.out.println("recalcCommons():this.rotMatrix:"); System.out.println("recalcCommons():this.rotMatrix:");
(new Matrix(this.rotMatrix)).print(10, 5); (new Matrix(this.rotMatrix)).print(10, 5);
} }
//
this.r_xyod=new double [this.r_od.length][4]; //{x0,y0,ortho, diagonal}
this.r_xyod[0][0]=0.0; // this.px0; //
this.r_xyod[0][1]=0.0; // this.py0;
this.r_xyod[0][2]=this.r_od[0][0];
this.r_xyod[0][3]=this.r_od[0][1];
if (cummulativeCorrection){
for (int i=1;i<this.r_xyod.length;i++){
this.r_xyod[i][0]=this.r_xyod[i-1][0]+this.r_xy[i-1][0];
this.r_xyod[i][1]=this.r_xyod[i-1][1]+this.r_xy[i-1][1];
this.r_xyod[i][2]=this.r_xyod[i-1][2]+this.r_od[i][0];
this.r_xyod[i][3]=this.r_xyod[i-1][3]+this.r_od[i][1];
}
} else {
for (int i=1;i<this.r_xyod.length;i++){
this.r_xyod[i][0]=this.r_xy[i-1][0]; // this.px0+this.r_xy[i-1][0];
this.r_xyod[i][1]=this.r_xy[i-1][1]; // this.py0+this.r_xy[i-1][1];
this.r_xyod[i][2]=this.r_od[i][0];
this.r_xyod[i][3]=this.r_od[i][1];
}
}
} }
private String [][] descriptions= private String [][] descriptions=
...@@ -352,7 +460,39 @@ dPXmmc/dphi= ...@@ -352,7 +460,39 @@ dPXmmc/dphi=
{"distortionA5","Lens distortion coefficient for r^5 (r0=half sensor width)", "r0","i"}, {"distortionA5","Lens distortion coefficient for r^5 (r0=half sensor width)", "r0","i"},
{"distortionA", "Lens distortion coefficient for r^4 (r0=half sensor width)", "r0","i"}, {"distortionA", "Lens distortion coefficient for r^4 (r0=half sensor width)", "r0","i"},
{"distortionB", "Lens distortion coefficient for r^3 (r0=half sensor width)", "r0","i"}, {"distortionB", "Lens distortion coefficient for r^3 (r0=half sensor width)", "r0","i"},
{"distortionC", "Lens distortion coefficient for r^2 (r0=half sensor width)", "r0","i"} {"distortionC", "Lens distortion coefficient for r^2 (r0=half sensor width)", "r0","i"},
{"elong_C_o", "Orthogonal elongation for r^2", "rel","i"},
{"elong_C_d", "Diagonal elongation for r^2", "rel","i"},
{"eccen_B_x", "Distortion center shift X for r^3", "rel","i"},
{"eccen_B_y", "Distortion center shift Y for r^3", "rel","i"},
{"elong_B_o", "Orthogonal elongation for r^3", "rel","i"},
{"elong_B_d", "Diagonal elongation for r^3", "rel","i"},
{"eccen_A_x", "Distortion center shift X for r^4", "rel","i"},
{"eccen_A_y", "Distortion center shift Y for r^4", "rel","i"},
{"elong_A_o", "Orthogonal elongation for r^4", "rel","i"},
{"elong_A_d", "Diagonal elongation for r^4", "rel","i"},
{"eccen_A5_x", "Distortion center shift X for r^5", "rel","i"},
{"eccen_A5_y", "Distortion center shift Y for r^5", "rel","i"},
{"elong_A5_o", "Orthogonal elongation for r^5", "rel","i"},
{"elong_A5_d", "Diagonal elongation for r^5", "rel","i"},
{"eccen_A6_x", "Distortion center shift X for r^6", "rel","i"},
{"eccen_A6_y", "Distortion center shift Y for r^6", "rel","i"},
{"elong_A6_o", "Orthogonal elongation for r^6", "rel","i"},
{"elong_A6_d", "Diagonal elongation for r^6", "rel","i"},
{"eccen_A7_x", "Distortion center shift X for r^7", "rel","i"},
{"eccen_A7_y", "Distortion center shift Y for r^7", "rel","i"},
{"elong_A7_o", "Orthogonal elongation for r^7", "rel","i"},
{"elong_A7_d", "Diagonal elongation for r^7", "rel","i"},
{"eccen_A8_x", "Distortion center shift X for r^8", "rel","i"},
{"eccen_A8_y", "Distortion center shift Y for r^8", "rel","i"},
{"elong_A8_o", "Orthogonal elongation for r^8", "rel","i"},
{"elong_A8_d", "Diagonal elongation for r^8", "rel","i"}
}; };
private int numberIntExtrisic(String type){ private int numberIntExtrisic(String type){
int num=0; int num=0;
...@@ -361,7 +501,7 @@ dPXmmc/dphi= ...@@ -361,7 +501,7 @@ dPXmmc/dphi=
} }
/** /**
* Verifies that the camera is looking towards the target * Verifies that the camera is looking towards the target
* @return true if looking tio the target, false - if away * @return true if looking to the target, false - if away
*/ */
public boolean isTargetVisible(boolean verbose){ public boolean isTargetVisible(boolean verbose){
if (verbose) System.out.println("isTargetVisible(): this.distance="+this.distance+", this.yaw="+this.yaw+", this.pitch="+this.pitch); if (verbose) System.out.println("isTargetVisible(): this.distance="+this.distance+", this.yaw="+this.yaw+", this.pitch="+this.pitch);
...@@ -383,7 +523,7 @@ dPXmmc/dphi= ...@@ -383,7 +523,7 @@ dPXmmc/dphi=
return extVector; return extVector;
} }
public double [] getIntrinsicVector(){ public double [] getIntrinsicVector(){
double [] extVector = { double [] intVector = {
this.focalLength, this.focalLength,
this.px0, this.px0,
this.py0, this.py0,
...@@ -393,15 +533,47 @@ dPXmmc/dphi= ...@@ -393,15 +533,47 @@ dPXmmc/dphi=
this.distortionA5, this.distortionA5,
this.distortionA, this.distortionA,
this.distortionB, this.distortionB,
this.distortionC this.distortionC,
this.r_od[0][0],
this.r_od[0][1],
this.r_xy[0][0],
this.r_xy[0][1],
this.r_od[1][0],
this.r_od[1][1],
this.r_xy[1][0],
this.r_xy[1][1],
this.r_od[2][0],
this.r_od[2][1],
this.r_xy[2][0],
this.r_xy[2][1],
this.r_od[3][0],
this.r_od[3][1],
this.r_xy[3][0],
this.r_xy[3][1],
this.r_od[4][0],
this.r_od[4][1],
this.r_xy[4][0],
this.r_xy[4][1],
this.r_od[5][0],
this.r_od[5][1],
this.r_xy[5][0],
this.r_xy[5][1],
this.r_od[6][0],
this.r_od[6][1]
}; };
return extVector; return intVector;
} }
public double [] getAllVector(){ public double [] getAllVector(){
double [] allVector = new double[getExtrinsicVector().length+getIntrinsicVector().length];
int index=0;
double [] extVector=getExtrinsicVector(); double [] extVector=getExtrinsicVector();
double [] intVector=getIntrinsicVector(); double [] intVector=getIntrinsicVector();
double [] allVector = new double[extVector.length+intVector.length];
int index=0;
for (int i=0;i<extVector.length;i++) allVector[index++]= extVector[i]; for (int i=0;i<extVector.length;i++) allVector[index++]= extVector[i];
for (int i=0;i<intVector.length;i++) allVector[index++]= intVector[i]; for (int i=0;i<intVector.length;i++) allVector[index++]= intVector[i];
return allVector; return allVector;
...@@ -428,6 +600,25 @@ dPXmmc/dphi= ...@@ -428,6 +600,25 @@ dPXmmc/dphi=
this.distortionA= vector[13]; this.distortionA= vector[13];
this.distortionB= vector[14]; this.distortionB= vector[14];
this.distortionC= vector[15]; this.distortionC= vector[15];
int index=16;
for (int i=0;i<this.r_od.length;i++){
if (i>0) {
this.r_xy[i-1][0]=vector[index++];
this.r_xy[i-1][1]=vector[index++];
}
this.r_od[i][0]=vector[index++];
this.r_od[i][1]=vector[index++];
}
/*
for (int i=0;i<this.r_xy.length;i++){
this.r_xy[i][0]=vector[index++];
this.r_xy[i][1]=vector[index++];
}
for (int i=0;i<this.r_od.length;i++){
this.r_od[i][0]=vector[index++];
this.r_od[i][1]=vector[index++];
}
*/
recalcCommons(); recalcCommons();
} }
...@@ -518,7 +709,40 @@ dPXmmc/dphi= ...@@ -518,7 +709,40 @@ dPXmmc/dphi=
12, // 12 public double distortionA5=0.0; // r^5 (normalized to focal length or to sensor half width?) 12, // 12 public double distortionA5=0.0; // r^5 (normalized to focal length or to sensor half width?)
13, // 13 public double distortionA=0.0; // r^4 (normalized to focal length or to sensor half width?) 13, // 13 public double distortionA=0.0; // r^4 (normalized to focal length or to sensor half width?)
14, // 14 public double distortionB=0.0; // r^3 14, // 14 public double distortionB=0.0; // r^3
15 // 15 public double distortionC=0.0; // r^2 15, // 15 public double distortionC=0.0; // r^2
18, // 16 Orthogonal elongation for r^2"
19, // 17 Diagonal elongation for r^2"
20, // 18 Distortion center shift X for r^3"
21, // 19 Distortion center shift Y for r^3"
22, // 20 Orthogonal elongation for r^3"
23, // 21 Diagonal elongation for r^3"
24, // 22 Distortion center shift X for r^4"
25, // 23 Distortion center shift Y for r^4"
26, // 24 Orthogonal elongation for r^4"
27, // 25 Diagonal elongation for r^4"
28, // 26 Distortion center shift X for r^5"
29, // 27 Distortion center shift Y for r^5"
30, // 28 Orthogonal elongation for r^5"
31, // 29 Diagonal elongation for r^5"
32, // 30 Distortion center shift X for r^6"
33, // 31 Distortion center shift Y for r^6"
34, // 32 Orthogonal elongation for r^6"
35, // 33 Diagonal elongation for r^6"
36, // 34 Distortion center shift X for r^7"
37, // 35 Distortion center shift Y for r^7"
38, // 36 Orthogonal elongation for r^6"
39, // 37 Diagonal elongation for r^6"
40, // 38 Distortion center shift X for r^8"
41, // 29 Distortion center shift Y for r^8"
42, // 40 Orthogonal elongation for r^8"
43 // 41 Diagonal elongation for r^8"
}; };
double [][] result = new double [order.length][2]; double [][] result = new double [order.length][2];
for (int i=0; i<order.length;i++){ for (int i=0; i<order.length;i++){
...@@ -526,8 +750,15 @@ dPXmmc/dphi= ...@@ -526,8 +750,15 @@ dPXmmc/dphi=
result[i][1]=srcDerivatives[order[i]][1]; result[i][1]=srcDerivatives[order[i]][1];
} }
return result; return result;
} }
/*
* result = {{srcDerivatives[4][0],srcDerivatives[4][1]}, - X0
* {srcDerivatives[5][0],srcDerivatives[5][1]} - Y0
* {srcDerivatives[8][0],srcDerivatives[8][1]} - dist
* ...
*/
/** /**
* Reorder to match the sequence of names - seems to be different :-( * Reorder to match the sequence of names - seems to be different :-(
* @param srcDerivatives values and 15 derivatives for px, py * @param srcDerivatives values and 15 derivatives for px, py
...@@ -550,7 +781,40 @@ dPXmmc/dphi= ...@@ -550,7 +781,40 @@ dPXmmc/dphi=
12, // 12 public double distortionA5=0.0; // r^5 (normalized to focal length or to sensor half width?) 12, // 12 public double distortionA5=0.0; // r^5 (normalized to focal length or to sensor half width?)
13, // 13 public double distortionA=0.0; // r^4 (normalized to focal length or to sensor half width?) 13, // 13 public double distortionA=0.0; // r^4 (normalized to focal length or to sensor half width?)
14, // 14 public double distortionB=0.0; // r^3 14, // 14 public double distortionB=0.0; // r^3
15 // 15 public double distortionC=0.0; // r^2 15, // 15 public double distortionC=0.0; // r^2
18, // 16 Orthogonal elongation for r^2"
19, // 17 Diagonal elongation for r^2"
20, // 18 Distortion center shift X for r^3"
21, // 19 Distortion center shift Y for r^3"
22, // 20 Orthogonal elongation for r^3"
23, // 21 Diagonal elongation for r^3"
24, // 22 Distortion center shift X for r^4"
25, // 23 Distortion center shift Y for r^4"
26, // 24 Orthogonal elongation for r^4"
27, // 25 Diagonal elongation for r^4"
28, // 26 Distortion center shift X for r^5"
29, // 27 Distortion center shift Y for r^5"
30, // 28 Orthogonal elongation for r^5"
31, // 29 Diagonal elongation for r^5"
32, // 30 Distortion center shift X for r^6"
33, // 31 Distortion center shift Y for r^6"
34, // 32 Orthogonal elongation for r^6"
35, // 33 Diagonal elongation for r^6"
36, // 34 Distortion center shift X for r^7"
37, // 35 Distortion center shift Y for r^7"
38, // 36 Orthogonal elongation for r^6"
39, // 37 Diagonal elongation for r^6"
40, // 38 Distortion center shift X for r^8"
41, // 29 Distortion center shift Y for r^8"
42, // 40 Orthogonal elongation for r^8"
43 // 41 Diagonal elongation for r^8"
}; };
double [][] result = new double [order.length][2]; double [][] result = new double [order.length][2];
for (int i=0; i<order.length;i++){ for (int i=0; i<order.length;i++){
...@@ -558,7 +822,6 @@ dPXmmc/dphi= ...@@ -558,7 +822,6 @@ dPXmmc/dphi=
result[i][1]=srcDerivatives[order[i]][1]; result[i][1]=srcDerivatives[order[i]][1];
} }
return result; return result;
} }
/** /**
* Calculate lens center location in target coordinates * Calculate lens center location in target coordinates
...@@ -609,32 +872,324 @@ dPXmmc/dphi= ...@@ -609,32 +872,324 @@ dPXmmc/dphi=
* [*][15] - pixel x[or y] partial derivative for Dc (distortion coefficient for r^2) * [*][15] - pixel x[or y] partial derivative for Dc (distortion coefficient for r^2)
* [*][16] - pixel x[or y] partial derivative for PX0 (lens axis on the sensor, horizontal, right,in pixels) * [*][16] - pixel x[or y] partial derivative for PX0 (lens axis on the sensor, horizontal, right,in pixels)
* [*][17] - pixel x[or y] partial derivative for PY0 (lens axis on the sensor, vertical, down, in pixels) * [*][17] - pixel x[or y] partial derivative for PY0 (lens axis on the sensor, vertical, down, in pixels)
* [*][18] - Orthogonal elongation for r^2"
* [*][19] - Diagonal elongation for r^2"
* [*][20] - Distortion center shift X for r^3"
* [*][21] - Distortion center shift Y for r^3"
* [*][22] - Orthogonal elongation for r^3"
* [*][23] - Diagonal elongation for r^3"
* [*][24] - Distortion center shift X for r^4"
* [*][25] - Distortion center shift Y for r^4"
* [*][26] - Orthogonal elongation for r^4"
* [*][27] - Diagonal elongation for r^4"
* [*][28] - Distortion center shift X for r^5"
* [*][29] - Distortion center shift Y for r^5"
* [*][30] - Orthogonal elongation for r^5"
* [*][31] - Diagonal elongation for r^5"
* [*][32] - Distortion center shift X for r^6"
* [*][33] - Distortion center shift Y for r^6"
* [*][34] - Orthogonal elongation for r^6"
* [*][35] - Diagonal elongation for r^6"
* [*][36] - Distortion center shift X for r^7"
* [*][37] - Distortion center shift Y for r^7"
* [*][38] - Orthogonal elongation for r^7"
* [*][39] - Diagonal elongation for r^7"
* [*][40] - Distortion center shift X for r^8"
* [*][41] - Distortion center shift Y for r^8"
* [*][42] - Orthogonal elongation for r^8"
* [*][43] - Diagonal elongation for r^8"
*/ */
/* /*
* TODO: minimaize calculations for individual {xp,yp,zp} * TODO: minimaize calculations for individual {xp,yp,zp}
*/ */
public double ipow(double a, int b){
switch (b) {
case 1: return a;
case 2: return a*a;
case 3: return a*a*a;
case 0: return 1.0;
default:
if (b<0) {
return 1.0/ipow(a,-b);
} else {
int b1=b>>1;
return ipow(a,b1)*ipow(a,b-b1);
}
}
}
public double [][] calcPartialDerivatives( public double [][] calcPartialDerivatives(
double xp, // target point horizontal, positive - right, mm double xp, // target point horizontal, positive - right, mm
double yp, // target point vertical, positive - down, mm double yp, // target point vertical, positive - down, mm
double zp, // target point horizontal, positive - away from camera, mm double zp, // target point horizontal, positive - away from camera, mm
boolean calculateAll){ // calculate derivatives, false - values only boolean calculateAll){ // calculate derivatives, false - values only
double partDeriv[][] = new double [calculateAll?18:1][2]; // this.cummulativeCorrection=false; // just debugging
// 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 numRadialDerivatives=18;
final int numNonRadialDerivatives=26;
final int distortionCIndex=15; // a8->9, a7->10, a6->11, a5->12, a->13, b->14, c->15
double partDeriv[][] = new double [calculateAll?(numRadialDerivatives+numNonRadialDerivatives):1][2];
// double [] XYZ= {xp-this.x0, yp-this.y0, zp-this.z0}; // double [] XYZ= {xp-this.x0, yp-this.y0, zp-this.z0};
double [] XYZ= {xp-this.x0, yp+this.y0, zp-this.z0}; double [] XYZ= {xp-this.x0, yp+this.y0, zp-this.z0}; // Y - "down" (as in images), not up
double [] XeYeZe={ double [] XeYeZe={
this.rotMatrix[0][0]*XYZ[0] + this.rotMatrix[0][1]*XYZ[1] + this.rotMatrix[0][2]*XYZ[2], this.rotMatrix[0][0]*XYZ[0] + this.rotMatrix[0][1]*XYZ[1] + this.rotMatrix[0][2]*XYZ[2],
this.rotMatrix[1][0]*XYZ[0] + this.rotMatrix[1][1]*XYZ[1] + this.rotMatrix[1][2]*XYZ[2], this.rotMatrix[1][0]*XYZ[0] + this.rotMatrix[1][1]*XYZ[1] + this.rotMatrix[1][2]*XYZ[2],
this.rotMatrix[2][0]*XYZ[0] + this.rotMatrix[2][1]*XYZ[1] + this.rotMatrix[2][2]*XYZ[2]+this.distance this.rotMatrix[2][0]*XYZ[0] + this.rotMatrix[2][1]*XYZ[1] + this.rotMatrix[2][2]*XYZ[2]+this.distance
}; };
// PXYmmc - pinhole (non-distorted) projection coordinates. metric (in mm)
double [] PXYmmc={this.focalLength/XeYeZe[2]*XeYeZe[0],this.focalLength/XeYeZe[2]*XeYeZe[1]}; double [] PXYmmc={this.focalLength/XeYeZe[2]*XeYeZe[0],this.focalLength/XeYeZe[2]*XeYeZe[1]};
double r= Math.sqrt(PXYmmc[0]*PXYmmc[0]+PXYmmc[1]*PXYmmc[1]); // now each term has individual radius
double rr=r/this.distortionRadius; // double [] rr=new double [r_xyod.length];
// double kD=((this.distortionA*rr+this.distortionB)*rr+this.distortionC)*rr + 1.0-this.distortionA-this.distortionB-this.distortionC; // Geometric - get to pinhole coordinates on the sensor
double kD=((((((this.distortionA8*rr+this.distortionA7)*rr+ this.distortionA6)*rr+ this.distortionA5)*rr+this.distortionA)*rr+this.distortionB)*rr+this.distortionC)*rr + double [][] dXeYeZe=null; //[14];
1.0-this.distortionA8-this.distortionA7-this.distortionA6-this.distortionA5-this.distortionA-this.distortionB-this.distortionC; double [][] dPXYmmc=null;
double [] xyDist={kD*PXYmmc[0],kD*PXYmmc[1]};
/*
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)
*/
double [] a={this.distortionC,this.distortionB,this.distortionA,this.distortionA5,this.distortionA6,this.distortionA7,this.distortionA8};
double deltaX=0.0,deltaY=0.0; // difference between distorted and non-distorted as a fraction of this.distortionRadius
double xmmc=PXYmmc[0]/this.distortionRadius;
double ymmc=PXYmmc[1]/this.distortionRadius;
double dDeltaX_dxmmc=0.0, dDeltaX_dymmc=0.0, dDeltaY_dxmmc=0.0, dDeltaY_dymmc=0;
if (calculateAll){
for (double [] r:partDeriv) Arrays.fill(r, 0.0); // will fill the [0] (value) too, should be done before calculation of these 2 values
// Geometric - get to pinhole coordinates on the sensor
dXeYeZe=new double[9][3]; //[14];
// Geometric - get to pinhole coordinates on the sensor
dXeYeZe[0][0]=XeYeZe[0];
dXeYeZe[0][1]=XeYeZe[1];
dXeYeZe[0][2]=XeYeZe[2];
// /dphi
dXeYeZe[1][0]=(-cPS*sPH + sPS*sTH*cPH)*XYZ[0] +(-cPS*cPH-sPS*sTH*sPH)*XYZ[2];
dXeYeZe[1][1]=(-sPS*sPH-cPS*sTH*cPH) *XYZ[0] +(-sPS*cPH+cPS*sTH*sPH)*XYZ[2];
dXeYeZe[1][2]=(cTH*cPH)*XYZ[0] -cTH*sPH* XYZ[2];
// /dtheta
dXeYeZe[2][0]=(sPS*cTH*sPH)*XYZ[0] -sPS*sTH*XYZ[1] +(sPS*cTH*cPH)*XYZ[2];
dXeYeZe[2][1]=(-cPS*cTH*sPH)*XYZ[0] +cPS*sTH*XYZ[1] +(-cPS*cTH*cPH)*XYZ[2];
dXeYeZe[2][2]=(-sTH*sPH)*XYZ[0] -cTH*XYZ[1] -sTH*cPH* XYZ[2];
// /dpsi
dXeYeZe[3][0]=(-sPS*cPH+cPS*sTH*sPH)*XYZ[0] +cPS*cTH*XYZ[1] +(sPS*sPH+cPS*sTH*cPH)*XYZ[2];
dXeYeZe[3][1]=(cPS*cPH+ sPS*sTH*sPH)*XYZ[0] +sPS*cTH*XYZ[1] +(-cPS*sPH+sPS*sTH*cPH)*XYZ[2];
dXeYeZe[3][2]=0.0;
// /dX0
// dXeYeZe[4][0]=-cPS*cPH+sPS*sTH*sPH; // bad?
dXeYeZe[4][0]=-cPS*cPH-sPS*sTH*sPH; // bad?
dXeYeZe[4][1]=-sPS*cPH+cPS*sTH*sPH;
dXeYeZe[4][2]=-cTH*sPH;
// /dY0
// dXeYeZe[5][0]=-sPS*cTH;
// dXeYeZe[5][1]= cPS*cTH;
// dXeYeZe[5][2]= sTH;
dXeYeZe[5][0]=+sPS*cTH;
dXeYeZe[5][1]=-cPS*cTH;
dXeYeZe[5][2]=-sTH;
// /dZ0
// dXeYeZe[6][0]= cPS*sPH+sPS*sTH*cPH; //bad?
dXeYeZe[6][0]= cPS*sPH-sPS*sTH*cPH; //bad?
dXeYeZe[6][1]= sPS*sPH+cPS*sTH*cPH;
dXeYeZe[6][2]=-cTH*cPH;
// /df
dXeYeZe[7][0]=0.0;
dXeYeZe[7][1]=0.0;
dXeYeZe[7][2]=0.0;
// /ddist
dXeYeZe[8][0]=0.0;
dXeYeZe[8][1]=0.0;
dXeYeZe[8][2]=1.0;
dPXYmmc=new double[9][2]; //[14];
// TODO: move up
// double [][] dPXYmmc=new double[9][2]; //[14];
dPXYmmc[0][0]=PXYmmc[0]; // is it needed? probably not used
dPXYmmc[0][1]=PXYmmc[1];
//(4) PXmmc =f/Ze* Xe // mm, left from the lens axis intersection with the sensor
//dPXmmc/dphi = f/Ze * dXe/dphi - f*Xe/Ze^2 * dZe/dphi
dPXYmmc[1][0]=this.focalLength/dXeYeZe[0][2]*(dXeYeZe[1][0]-dXeYeZe[0][0]/dXeYeZe[0][2]*dXeYeZe[1][2]);
//dPXmmc/dtheta = f/Ze * dXe/dtheta - f*Xe/Ze^2 * dZe/dtheta
dPXYmmc[2][0]=this.focalLength/dXeYeZe[0][2]*(dXeYeZe[2][0]-dXeYeZe[0][0]/dXeYeZe[0][2]*dXeYeZe[2][2]);
//dPXmmc/dpsi = f/Ze * dXe/dpsi - f*Xe/Ze^2 * dZe/dpsi
dPXYmmc[3][0]=this.focalLength/dXeYeZe[0][2]*(dXeYeZe[3][0]-dXeYeZe[0][0]/dXeYeZe[0][2]*dXeYeZe[3][2]);
//dPXmmc/dX0 = f/Ze * dXe/dX0 - f*Xe/Ze^2 * dZe/dX0
dPXYmmc[4][0]=this.focalLength/dXeYeZe[0][2]*(dXeYeZe[4][0]-dXeYeZe[0][0]/dXeYeZe[0][2]*dXeYeZe[4][2]);
//dPXmmc/dY0 = f/Ze * dXe/dY0 - f*Xe/Ze^2 * dZe/dY0
dPXYmmc[5][0]=this.focalLength/dXeYeZe[0][2]*(dXeYeZe[5][0]-dXeYeZe[0][0]/dXeYeZe[0][2]*dXeYeZe[5][2]);
//dPXmmc/dZ0 = f/Ze * dXe/dZ0 - f*Xe/Ze^2 * dZe/dZ0
dPXYmmc[6][0]=this.focalLength/dXeYeZe[0][2]*(dXeYeZe[6][0]-dXeYeZe[0][0]/dXeYeZe[0][2]*dXeYeZe[6][2]); //bad?
//dPXmmc/df = Xe/Ze
dPXYmmc[7][0]=dXeYeZe[0][0]/dXeYeZe[0][2];
//dPXmmc/ddist = - f*Xe/Ze^2
dPXYmmc[8][0]=-this.focalLength*dXeYeZe[0][0]/(dXeYeZe[0][2]*dXeYeZe[0][2]);
//(5) PYmmc =f/Ze* Ye // mm, up from the lens axis intersection with the sensor
//dPYmmc/dphi = f/Ze * dYe/dphi - f*Ye/Ze^2 * dZe/dphi
dPXYmmc[1][1]=this.focalLength/dXeYeZe[0][2]*(dXeYeZe[1][1]-dXeYeZe[0][1]/dXeYeZe[0][2]*dXeYeZe[1][2]);
//dPYmmc/dtheta = f/Ze * dYe/dtheta - f*Ye/Ze^2 * dZe/dtheta
dPXYmmc[2][1]=this.focalLength/dXeYeZe[0][2]*(dXeYeZe[2][1]-dXeYeZe[0][1]/dXeYeZe[0][2]*dXeYeZe[2][2]);
//dPYmmc/dpsi = f/Ze * dYe/dpsi - f*Ye/Ze^2 * dZe/dpsi
dPXYmmc[3][1]=this.focalLength/dXeYeZe[0][2]*(dXeYeZe[3][1]-dXeYeZe[0][1]/dXeYeZe[0][2]*dXeYeZe[3][2]);
//dPYmmc/dX0 = f/Ze * dYe/dX0 - f*Ye/Ze^2 * dZe/dX0
dPXYmmc[4][1]=this.focalLength/dXeYeZe[0][2]*(dXeYeZe[4][1]-dXeYeZe[0][1]/dXeYeZe[0][2]*dXeYeZe[4][2]);
//dPYmmc/dY0 = f/Ze * dYe/dY0 - f*Ye/Ze^2 * dZe/dY0
dPXYmmc[5][1]=this.focalLength/dXeYeZe[0][2]*(dXeYeZe[5][1]-dXeYeZe[0][1]/dXeYeZe[0][2]*dXeYeZe[5][2]);
//dPYmmc/dZ0 = f/Ze * dYe/dZ0 - f*Ye/Ze^2 * dZe/dZ0
dPXYmmc[6][1]=this.focalLength/dXeYeZe[0][2]*(dXeYeZe[6][1]-dXeYeZe[0][1]/dXeYeZe[0][2]*dXeYeZe[6][2]); // good?
//dPYmmc/df = Ye/Ze
dPXYmmc[7][1]=dXeYeZe[0][1]/dXeYeZe[0][2];
//dPYmmc/ddist = - f*Ye/Ze^2
dPXYmmc[8][1]=-this.focalLength*dXeYeZe[0][1]/(dXeYeZe[0][2]*dXeYeZe[0][2]);
}
// conversion coefficient from relative (to distortionRadius) to pixels
// negate for y!
double rel_to_pix=this.distortionRadius*1000.0/this.pixelSize;
//TODO: seems that rr[i] can be just a single running variable, not an array
for (int i=0;i<r_xyod.length;i++){
double x=xmmc-r_xyod[i][0]; // relative X-shift of this term center
double y=ymmc-r_xyod[i][1]; // relative X-shift of this term center
double x2=x*x; // relative squared X-shift from this term center
double y2=y*y; // relative squared Y-shift from this term center
double r2=x2+y2; // relative squared distance from this term center
// effective distance from this term center corrected for elongation
double rr=Math.sqrt(r2+ r_xyod[i][2]*(y2-x2)+ 2.0*r_xyod[i][3]*x*y );
if (rr<0.00000001*this.distortionRadius) rr=0.00000001*this.distortionRadius; // avoid 1/0.0 -// Added 3 zeros (old comment)
double rr_pow_i=ipow(rr,i);
// double ki=a[i]*(Math.pow(rr,i+1)-1.0);
// double ki=a[i]*(ipow(rr,i+1)-1.0);
double ki=a[i]*(rr_pow_i*rr-1.0); // scaling of distorted distance from this term's center (does not include pinhole center shift itself)
deltaX+=x*ki; // relative distorted distance from the center
deltaY+=y*ki;
// if ((debugLevel>2) && ((r_xyod[i][0]!=0.0) || (r_xyod[i][0]!=0.0))){
// System.out.println ("i="+i+" r_xyod[i][0]="+r_xyod[i][0]+" r_xyod[i][1]="+r_xyod[i][1]+" a[0]="+a[0]+" a[1]="+a[1]+" a[2]="+a[2]+" a[3]="+a[3]);
// }
if (calculateAll) {
double csi=rel_to_pix*a[i]*(i+1)*rr_pow_i;
// double dx2_dxmmc=2*x, dy2_dymmc=2*y, dr2_dxmmc=2*x, dr2_dymmc=2*y;
// double drr_dxmmc=0.5/rr*(dr2_dxmmc+ r_xyod[i][2]*(-dx2_dxmmc)+2*r_xyod[i][3]*y)=0.5/rr*(2*x - 2*x*r_xyod[i][2]+2*r_xyod[i][3]*y)=
// = (x*(1.0-r_xyod[i][2])+y*r_xyod[i][3])/rr
// double drr_dymmc= (y*(1.0+r_xyod[i][2])+x*r_xyod[i][3])/rr
// double ki=a[i]*(rr^(i+1)-1.0);
// double dki_dxmmc=a[i]*(i+1)*rr^i*(x*(1.0-r_xyod[i][2])+y*r_xyod[i][3])/rr
// double dki_dymmc=a[i]*(i+1)*rr^i*(y*(1.0+r_xyod[i][2])+x*r_xyod[i][3])/rr
// double dki_dxmmc=a[i]*(i+1)*rr_pow_i*(x*(1.0-r_xyod[i][2])+y*r_xyod[i][3])/rr
// double dki_dymmc=a[i]*(i+1)*rr_pow_i*(y*(1.0+r_xyod[i][2])+x*r_xyod[i][3])/rr
double ai_iplus1_rr_pow_i= a[i]*(i+1)*rr_pow_i;
double dki_dxmmc= ai_iplus1_rr_pow_i*(x*(1.0-r_xyod[i][2])+y*r_xyod[i][3])/rr;
double dki_dymmc= ai_iplus1_rr_pow_i*(y*(1.0+r_xyod[i][2])+x*r_xyod[i][3])/rr;
// the following 4 shifts are "extra", on top of non-distorted (pinhole) - pinhole should be added to the per-term sum
double dDeltaXi_dxmmc = ki+x*dki_dxmmc; // here dDelta*_d*mmc are relative (both I/O are fractions of distortionRadius)
double dDeltaXi_dymmc = x*dki_dymmc;
double dDeltaYi_dxmmc = y*dki_dxmmc;
double dDeltaYi_dymmc = ki+y*dki_dymmc;
dDeltaX_dxmmc += dDeltaXi_dxmmc; // here dDelta*_d*mmc are relative (both I/O are fractions of distortionRadius)
dDeltaX_dymmc += dDeltaXi_dymmc;
dDeltaY_dxmmc += dDeltaYi_dxmmc;
dDeltaY_dymmc += dDeltaYi_dymmc;
// dependence on eccentricity
// dDeltaX_d_r_xyod0 = dDeltaXi_dxmmc * dxmmc_d_r_xyod0 = -dDeltaXi_dxmmc
// dDeltaY_d_r_xyod0 = dDeltaYi_dxmmc * dxmmc_d_r_xyod0 = -dDeltaYi_dxmmc
// dDeltaX_d_r_xyod1 = dDeltaXi_dymmc * dymmc_d_r_xyod1 = -dDeltaXi_dymmc
// dDeltaY_d_r_xyod1 = dDeltaYi_dymmc * dymmc_d_r_xyod1 = -dDeltaYi_dymmc
int index=numRadialDerivatives-2+4*i;
if (i>0){ // eccentricity is not applicabe to the first (C) term
partDeriv[index ][0]= -rel_to_pix*(dDeltaXi_dxmmc-0.0); // dPx_dr_xyod0
partDeriv[index ][1]= rel_to_pix* dDeltaYi_dxmmc; // dPy_dr_xyod0
partDeriv[index+1][0]= -rel_to_pix* dDeltaXi_dymmc; // dPx_dr_xyod1
partDeriv[index+1][1]= rel_to_pix*(dDeltaYi_dymmc-0.0); // dPy_dr_xyod1
}
// d/dai
// ki=a[i]*(rr_pow_i*rr-1.0);
// double dki_dai=(rr_pow_i*rr-1.0);
// double dpx_dai= rel_to_pix*x*(dki_dai)=rel_to_pix*x*(rr_pow_i*rr-1.0)
// double dpy_dai=-rel_to_pix*y*(dki_dai)=rel_to_pix*y*(rr_pow_i*rr-1.0)
// final int distortionCIndex=15; // a8->9, a7->10, a6->11, a5->12, a->13, b->14, c->15
index= distortionCIndex-i; // reverse order, // a8->9, a7->10, a6->11, a5->12, a->13, b->14, c->15
partDeriv[index][0]= rel_to_pix*x*(rr_pow_i*rr-1.0); // OK
partDeriv[index][1]=-rel_to_pix*y*(rr_pow_i*rr-1.0); // OK
// d/dr_xyod[0] (x shift of the center
// rr=Math.sqrt(r2+ r_xyod[i][2]*(y2-x2)+ 2.0*r_xyod[i][3]*x*y );
// ki=a[i]*(rr_pow_i*rr-1.0);
// dx_dr_xyod0=-1.0
// dy_dr_xyod1=-1.0
// dx2_dr_xyod0=-2*x
// dy2_dr_xyod1=-2*y
// dr2_dr_xyod0=-2*x
// dr2_dr_xyod1=-2*y
// dxy_dr_xyod0=-y
// dxy_dr_xyod1=-x
// dri_dr_xyod[0]=0.5*(dr2_dr_xyod0 -r_xyod[i][2]*dx2_dr_xyod0 + 2.0*r_xyod[i][3]*dxy_dr_xyod0)/rr=
// 0.5*(-2*x -r_xyod[i][2]*(-2*x) + 2.0*r_xyod[i][3]*(-y))/rr=
// (-x +r_xyod[i][2]*x -r_xyod[i][3]*y)/rr=
// (x*(r_xyod[i][2]-1.0) -r_xyod[i][3]*y)/rr
// double dri_dr_xyod0 = (x*(r_xyod[i][2]-1.0) -r_xyod[i][3]*y)/rr;
// dri_dr_xyod[1]=0.5*(dr2_dr_xyod1 -r_xyod[i][2]*dx2_dr_xyod1 + 2.0*r_xyod[i][3]*dxy_dr_xyod1)/rr=
// 0.5*(-2*y +r_xyod[i][2]*(-2*y) + 2.0*r_xyod[i][3]*(-x))/rr=
// (-y -r_xyod[i][2]*y -r_xyod[i][3]*x)/rr=
// (-y*(r_xyod[i][2]+1.0) -r_xyod[i][3]*x)/rr
// double dri_dr_xyod1 = (-y*(r_xyod[i][2]+1.0) -r_xyod[i][3]*x)/rr;
// dri_dr_xyod[2]=0.5*(y2-x2)/rr
double dri_dr_xyod2 = 0.5*(y2-x2)/rr;
// dri_dr_xyod[3]=(y*x)/rr
double dri_dr_xyod3 = (y*x)/rr;
//--------------------
// double ki=a[i]*(rr^(i+1)-1.0);
// double ki=a[i]*(rr_pow_i*rr-1.0);
// deltaX+=x*ki;
// deltaY+=y*ki;
// dki_dri=a[i]*(i+1)*rr^i = a[i]*(i+1)*rr_pow_i
// dDeltaX_dri=x*a[i]*(i+1)*rr_pow_i
// dDeltaY_dri=y*a[i]*(i+1)*rr_pow_i
// dPx_dri= rel_to_pix*x*a[i]*(i+1)*rr_pow_i = csi*x
// dPy_dri=-rel_to_pix*y*a[i]*(i+1)*rr_pow_i = -csi*y
// dPx_dr_xyod0= dPx_dri*dri_dr_xyod0= csi*x*dri_dr_xyod0;
// dPx_dr_xyod1= dPx_dri*dri_dr_xyod1= csi*x*dri_dr_xyod1;
// dPx_dr_xyod2= dPx_dri*dri_dr_xyod2= csi*x*dri_dr_xyod2;
// dPx_dr_xyod3= dPx_dri*dri_dr_xyod3= csi*x*dri_dr_xyod3;
// dPy_dr_xyod0= dPy_dri*dri_dr_xyod0=-csi*y*dri_dr_xyod0;
// dPy_dr_xyod1= dPy_dri*dri_dr_xyod1=-csi*y*dri_dr_xyod1;
// dPy_dr_xyod2= dPy_dri*dri_dr_xyod2=-csi*y*dri_dr_xyod2;
// dPy_dr_xyod3= dPy_dri*dri_dr_xyod3=-csi*y*dri_dr_xyod3;
index=numRadialDerivatives-2+4*i;
/*
if (i>0){ // eccentricity is not applicabe to the first (C) term
partDeriv[index ][0]= csi*x*dri_dr_xyod0; // dPx_dr_xyod0
partDeriv[index ][1]=-csi*y*dri_dr_xyod0; // dPy_dr_xyod0
partDeriv[index+1][0]= csi*x*dri_dr_xyod1; // dPx_dr_xyod1
partDeriv[index+1][1]=-csi*y*dri_dr_xyod1; // dPy_dr_xyod1
}
*/
partDeriv[index+2][0]= csi*x*dri_dr_xyod2; // dPx_dr_xyod2
partDeriv[index+2][1]=-csi*y*dri_dr_xyod2; // dPy_dr_xyod2
partDeriv[index+3][0]= csi*x*dri_dr_xyod3; // dPx_dr_xyod3
partDeriv[index+3][1]=-csi*y*dri_dr_xyod3; // dPy_dr_xyod3
}
}
double [] xyDist={PXYmmc[0]+this.distortionRadius*deltaX,PXYmmc[1]+this.distortionRadius*deltaY};
// convert to sensor pixels coordinates
partDeriv[0][0]= 1000.0/this.pixelSize*xyDist[0] + this.px0; partDeriv[0][0]= 1000.0/this.pixelSize*xyDist[0] + this.px0;
partDeriv[0][1]= -1000.0/this.pixelSize*xyDist[1] + this.py0; partDeriv[0][1]= -1000.0/this.pixelSize*xyDist[1] + this.py0;
if (!calculateAll) { if (!calculateAll) {
// 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) {
...@@ -643,259 +1198,63 @@ dPXmmc/dphi= ...@@ -643,259 +1198,63 @@ dPXmmc/dphi=
} }
return partDeriv; return partDeriv;
} }
// correct parameter derivatives to cumulative version
if (this.cummulativeCorrection){
for (int i=r_xyod.length-2;i>=0;i--){
int index=numRadialDerivatives-2+4*i;
if (i>0){ // eccentricity is not applicabe to the first (C) term
partDeriv[index ][0]+=partDeriv[index+4][0]; // oob=36
partDeriv[index ][1]+=partDeriv[index+4][1];
partDeriv[index+1][0]+=partDeriv[index+5][0];
partDeriv[index+1][1]+=partDeriv[index+5][1];
}
partDeriv[index+2][0]+=partDeriv[index+6][0];
partDeriv[index+2][1]+=partDeriv[index+6][1];
partDeriv[index+3][0]+=partDeriv[index+7][0];
partDeriv[index+3][1]+=partDeriv[index+7][1];
}
}
double [][] dXeYeZe=new double[9][3]; //[14]; // convert dDelta*_d*mmc from relative/relative to pix/mm (invert pixel Y direction)
dXeYeZe[0][0]=XeYeZe[0]; // added 1.0 to account for non-distorted (pinhole) shift
dXeYeZe[0][1]=XeYeZe[1]; double dPx_dPinholeX= (1.0+dDeltaX_dxmmc)*1000.0/this.pixelSize;
dXeYeZe[0][2]=XeYeZe[2]; double dPx_dPinholeY= dDeltaX_dymmc*1000.0/this.pixelSize;
// /dphi double dPy_dPinholeX= -dDeltaY_dxmmc*1000.0/this.pixelSize;
dXeYeZe[1][0]=(-cPS*sPH + sPS*sTH*cPH)*XYZ[0] +(-cPS*cPH-sPS*sTH*sPH)*XYZ[2]; double dPy_dPinholeY=-(1.0+dDeltaY_dymmc)*1000.0/this.pixelSize;
dXeYeZe[1][1]=(-sPS*sPH-cPS*sTH*cPH) *XYZ[0] +(-sPS*cPH+cPS*sTH*sPH)*XYZ[2]; if (this.debugLevel>2){
dXeYeZe[1][2]=(cTH*cPH)*XYZ[0] -cTH*sPH* XYZ[2]; System.out.println(" deltaX="+deltaX+" deltaY="+deltaY+" xyDist[0]="+xyDist[0]+" xyDist[1]="+xyDist[1]);
// /dtheta System.out.println(" PXYmmc[0]="+PXYmmc[0]+" PXYmmc[1]="+PXYmmc[1]+" xmmc="+xmmc+" ymmc"+ymmc);
dXeYeZe[2][0]=(sPS*cTH*sPH)*XYZ[0] -sPS*sTH*XYZ[1] +(sPS*cTH*cPH)*XYZ[2]; System.out.println(" dDeltaX_dxmmc="+dDeltaX_dxmmc+" dDeltaX_dymmc="+dDeltaX_dymmc+" dDeltaY_dxmmc="+dDeltaY_dxmmc+" dDeltaY_dymmc"+dDeltaY_dymmc);
dXeYeZe[2][1]=(-cPS*cTH*sPH)*XYZ[0] +cPS*sTH*XYZ[1] +(-cPS*cTH*cPH)*XYZ[2]; System.out.println(" dPx_dPinholeX="+dPx_dPinholeX+" dPx_dPinholeY="+dPx_dPinholeY+" dPy_dPinholeX="+dPy_dPinholeX+" dPy_dPinholeY"+dPy_dPinholeY);
dXeYeZe[2][2]=(-sTH*sPH)*XYZ[0] -cTH*XYZ[1] -sTH*cPH* XYZ[2]; }
// /dpsi
dXeYeZe[3][0]=(-sPS*cPH+cPS*sTH*sPH)*XYZ[0] +cPS*cTH*XYZ[1] +(sPS*sPH+cPS*sTH*cPH)*XYZ[2];
dXeYeZe[3][1]=(cPS*cPH+ sPS*sTH*sPH)*XYZ[0] +sPS*cTH*XYZ[1] +(-cPS*sPH+sPS*sTH*cPH)*XYZ[2];
dXeYeZe[3][2]=0.0;
// /dX0
// dXeYeZe[4][0]=-cPS*cPH+sPS*sTH*sPH; // bad?
dXeYeZe[4][0]=-cPS*cPH-sPS*sTH*sPH; // bad?
dXeYeZe[4][1]=-sPS*cPH+cPS*sTH*sPH;
dXeYeZe[4][2]=-cTH*sPH;
// /dY0
// dXeYeZe[5][0]=-sPS*cTH;
// dXeYeZe[5][1]= cPS*cTH;
// dXeYeZe[5][2]= sTH;
dXeYeZe[5][0]=+sPS*cTH;
dXeYeZe[5][1]=-cPS*cTH;
dXeYeZe[5][2]=-sTH;
// /dZ0
// dXeYeZe[6][0]= cPS*sPH+sPS*sTH*cPH; //bad?
dXeYeZe[6][0]= cPS*sPH-sPS*sTH*cPH; //bad?
dXeYeZe[6][1]= sPS*sPH+cPS*sTH*cPH;
dXeYeZe[6][2]=-cTH*cPH;
// /df
dXeYeZe[7][0]=0.0;
dXeYeZe[7][1]=0.0;
dXeYeZe[7][2]=0.0;
// /ddist
dXeYeZe[8][0]=0.0;
dXeYeZe[8][1]=0.0;
dXeYeZe[8][2]=1.0;
double [][] dPXYmmc=new double[9][2]; //[14];
dPXYmmc[0][0]=PXYmmc[0];
dPXYmmc[0][1]=PXYmmc[1];
//(4) PXmmc =f/Ze* Xe // mm, left from the lens axis intersection with the sensor
//dPXmmc/dphi = f/Ze * dXe/dphi - f*Xe/Ze^2 * dZe/dphi
dPXYmmc[1][0]=this.focalLength/dXeYeZe[0][2]*(dXeYeZe[1][0]-dXeYeZe[0][0]/dXeYeZe[0][2]*dXeYeZe[1][2]);
//dPXmmc/dtheta = f/Ze * dXe/dtheta - f*Xe/Ze^2 * dZe/dtheta
dPXYmmc[2][0]=this.focalLength/dXeYeZe[0][2]*(dXeYeZe[2][0]-dXeYeZe[0][0]/dXeYeZe[0][2]*dXeYeZe[2][2]);
//dPXmmc/dpsi = f/Ze * dXe/dpsi - f*Xe/Ze^2 * dZe/dpsi
dPXYmmc[3][0]=this.focalLength/dXeYeZe[0][2]*(dXeYeZe[3][0]-dXeYeZe[0][0]/dXeYeZe[0][2]*dXeYeZe[3][2]);
//dPXmmc/dX0 = f/Ze * dXe/dX0 - f*Xe/Ze^2 * dZe/dX0
dPXYmmc[4][0]=this.focalLength/dXeYeZe[0][2]*(dXeYeZe[4][0]-dXeYeZe[0][0]/dXeYeZe[0][2]*dXeYeZe[4][2]);
//dPXmmc/dY0 = f/Ze * dXe/dY0 - f*Xe/Ze^2 * dZe/dY0
dPXYmmc[5][0]=this.focalLength/dXeYeZe[0][2]*(dXeYeZe[5][0]-dXeYeZe[0][0]/dXeYeZe[0][2]*dXeYeZe[5][2]);
//dPXmmc/dZ0 = f/Ze * dXe/dZ0 - f*Xe/Ze^2 * dZe/dZ0
dPXYmmc[6][0]=this.focalLength/dXeYeZe[0][2]*(dXeYeZe[6][0]-dXeYeZe[0][0]/dXeYeZe[0][2]*dXeYeZe[6][2]); //bad?
//dPXmmc/df = Xe/Ze
dPXYmmc[7][0]=dXeYeZe[0][0]/dXeYeZe[0][2];
//dPXmmc/ddist = - f*Xe/Ze^2
dPXYmmc[8][0]=-this.focalLength*dXeYeZe[0][0]/(dXeYeZe[0][2]*dXeYeZe[0][2]);
//(5) PYmmc =f/Ze* Ye // mm, up from the lens axis intersection with the sensor
//dPYmmc/dphi = f/Ze * dYe/dphi - f*Ye/Ze^2 * dZe/dphi
dPXYmmc[1][1]=this.focalLength/dXeYeZe[0][2]*(dXeYeZe[1][1]-dXeYeZe[0][1]/dXeYeZe[0][2]*dXeYeZe[1][2]);
//dPYmmc/dtheta = f/Ze * dYe/dtheta - f*Ye/Ze^2 * dZe/dtheta
dPXYmmc[2][1]=this.focalLength/dXeYeZe[0][2]*(dXeYeZe[2][1]-dXeYeZe[0][1]/dXeYeZe[0][2]*dXeYeZe[2][2]);
//dPYmmc/dpsi = f/Ze * dYe/dpsi - f*Ye/Ze^2 * dZe/dpsi
dPXYmmc[3][1]=this.focalLength/dXeYeZe[0][2]*(dXeYeZe[3][1]-dXeYeZe[0][1]/dXeYeZe[0][2]*dXeYeZe[3][2]);
//dPYmmc/dX0 = f/Ze * dYe/dX0 - f*Ye/Ze^2 * dZe/dX0
dPXYmmc[4][1]=this.focalLength/dXeYeZe[0][2]*(dXeYeZe[4][1]-dXeYeZe[0][1]/dXeYeZe[0][2]*dXeYeZe[4][2]);
//dPYmmc/dY0 = f/Ze * dYe/dY0 - f*Ye/Ze^2 * dZe/dY0
dPXYmmc[5][1]=this.focalLength/dXeYeZe[0][2]*(dXeYeZe[5][1]-dXeYeZe[0][1]/dXeYeZe[0][2]*dXeYeZe[5][2]);
//dPYmmc/dZ0 = f/Ze * dYe/dZ0 - f*Ye/Ze^2 * dZe/dZ0
dPXYmmc[6][1]=this.focalLength/dXeYeZe[0][2]*(dXeYeZe[6][1]-dXeYeZe[0][1]/dXeYeZe[0][2]*dXeYeZe[6][2]); // good?
//dPYmmc/df = Ye/Ze
dPXYmmc[7][1]=dXeYeZe[0][1]/dXeYeZe[0][2];
//dPYmmc/ddist = - f*Ye/Ze^2
dPXYmmc[8][1]=-this.focalLength*dXeYeZe[0][1]/(dXeYeZe[0][2]*dXeYeZe[0][2]);
double[] dr=new double [9];
//(6) r=sqrt(PXmmc^2+PYmmc^2) // distance from the image point to the lens axis intersection with the sensor (pinhole model)
dr[0]=r;
// Added 3 zeros
if (dr[0]<0.00000001*this.distortionRadius) dr[0]=0.00000001*this.distortionRadius; // avoid 1/0.0
// dr/dphi = (PXmmc*dPXmmc/dphi+PYmmc*dPYmmc/dphi)/r
dr[1]=(PXYmmc[0]*dPXYmmc[1][0]+PXYmmc[1]*dPXYmmc[1][1])/dr[0];
// dr/dtheta = (PXmmc*dPXmmc/dtheta+PYmmc*dPYmmc/dtheta)/r
dr[2]=(PXYmmc[0]*dPXYmmc[2][0]+PXYmmc[1]*dPXYmmc[2][1])/dr[0];
// dr/dpsi = (PXmmc*dPXmmc/dpsi+PYmmc*dPYmmc/dpsi)/r
dr[3]=(PXYmmc[0]*dPXYmmc[3][0]+PXYmmc[1]*dPXYmmc[3][1])/dr[0];
// dr/dX0 = (PXmmc*dPXmmc/dX0+PYmmc*dPYmmc/dX0)/r
dr[4]=(PXYmmc[0]*dPXYmmc[4][0]+PXYmmc[1]*dPXYmmc[4][1])/dr[0];
// dr/dY0 = (PXmmc*dPXmmc/dY0+PYmmc*dPYmmc/dY0)/r
dr[5]=(PXYmmc[0]*dPXYmmc[5][0]+PXYmmc[1]*dPXYmmc[5][1])/dr[0];
// dr/dZ0 = (PXmmc*dPXmmc/dZ0+PYmmc*dPYmmc/dZ0)/r
dr[6]=(PXYmmc[0]*dPXYmmc[6][0]+PXYmmc[1]*dPXYmmc[6][1])/dr[0];
// dr/df = (PXmmc*dPXmmc/df+PYmmc*dPYmmc/df)/r
dr[7]=(PXYmmc[0]*dPXYmmc[7][0]+PXYmmc[1]*dPXYmmc[7][1])/dr[0];
// dr/ddist = (PXmmc*dPXmmc/ddist+PYmmc*dPYmmc/ddist)/r
dr[8]=(PXYmmc[0]*dPXYmmc[8][0]+PXYmmc[1]*dPXYmmc[8][1])/dr[0];
// double[] dkD=new double [12];
double[] dkD=new double [16];
// (7) kD=(Da*(r/r0)^3+Db*(r/r0)^2+Dc*(r/r0)^1+(1-Da-Db-Dc)) correction to the actual distance from the image point to the lens axis due to distortion
// (7) kD=(Da5*(r/r0)^4+(Da*(r/r0)^3+Db*(r/r0)^2+Dc*(r/r0)^1+(1-Da-Db-Dc-Da5)) correction to the actual distance from the image point to the lens axis due to distortion
dkD[0]=kD;
// dkD/dr= Da/r0^3 * 3*r^2 + Db/r0^2*2*r + Dc/r0
// dkD/dr= Da5/r0^4 * 4*r^3 + Da/r0^3 * 3*r^2 + Db/r0^2*2*r + Dc/r0
// dkD/dr= 1/r0*(3*Da*(r/r0)^2 + 2*Db*(r/r0) + Dc)
// dkD/dr= 1/r0*(4*Da5*(r/r0)^3 + 3*Da*(r/r0)^2 + 2*Db*(r/r0) + Dc)
double dkDdr=1.0/this.distortionRadius*((((((8*this.distortionA8*rr+6*this.distortionA7)*rr+5*this.distortionA6)*rr+4*this.distortionA5)*rr+3*this.distortionA)*rr+2*this.distortionB)*rr + this.distortionC);
// dkD/dphi = dkD/dr * dr/dphi
dkD[1]=dkDdr*dr[1];
// dkD/dtheta = dkD/dr * dr/dtheta
dkD[2]=dkDdr*dr[2];
// dkD/dpsi = dkD/dr * dr/dpsi
dkD[3]=dkDdr*dr[3];
// dkD/dX0 = dkD/dr * dr/dX0
dkD[4]=dkDdr*dr[4];
// dkD/dY0 = dkD/dr * dr/dY0
dkD[5]=dkDdr*dr[5];
// dkD/dZ0 = dkD/dr * dr/dZ0
dkD[6]=dkDdr*dr[6];
// dkD/df = dkD/dr * dr/df
dkD[7]=dkDdr*dr[7];
// dkD/ddist = dkD/dr * dr/ddist
dkD[8]=dkDdr*dr[8];
// dkD/dDa8 = (r/r0)^7 - 1
dkD[ 9]=rr*rr*rr*rr*rr*rr*rr-1.0;
// dkD/dDa7 = (r/r0)^6 - 1
dkD[10]=rr*rr*rr*rr*rr*rr-1.0;
// dkD/dDa6 = (r/r0)^5 - 1
dkD[11]=rr*rr*rr*rr*rr-1.0;
// dkD/dDa5 = (r/r0)^4 - 1
dkD[12]=rr*rr*rr*rr-1.0;
// dkD/dDa = (r/r0)^3 - 1
dkD[13]=rr*rr*rr-1.0;
// dkD/dDb = (r/r0)^2 - 1
dkD[14]=rr*rr-1.0;
// dkD/dDc = (r/r0) - 1
dkD[15]=rr-1.0;
// double[][] dxyDist=new double [12][2];
double[][] dxyDist=new double [16][2];
// (8) xDist = kD * PXmmc // horisontal distance (mm) from the lens axis on the sensor to the image point, mm (positive - right)
// (9) yDist = kD * PYmmc // vertical distance (mm) from the lens axis on the sensor to the image point, mm (positive - up)
dxyDist[0][0]=xyDist[0];
dxyDist[0][1]=xyDist[1];
// dxDist/dphi = dkD/dphi*PXmmc + kD*dPXmmc/dphi
// dyDist/dphi = dkD/dphi*PYmmc + kD*dPYmmc/dphi
dxyDist[ 1][0]=dkD[ 1]*dPXYmmc[0][0]+dkD[0]*dPXYmmc[ 1][0];
dxyDist[ 1][1]=dkD[ 1]*dPXYmmc[0][1]+dkD[0]*dPXYmmc[ 1][1];
// dxDist/dtheta = dkD/dtheta*PXmmc + kD*dPXmmc/dtheta
dxyDist[ 2][0]=dkD[ 2]*dPXYmmc[0][0]+dkD[0]*dPXYmmc[ 2][0];
dxyDist[ 2][1]=dkD[ 2]*dPXYmmc[0][1]+dkD[0]*dPXYmmc[ 2][1];
// dxDist/dpsi = dkD/dpsi*PXmmc + kD*dPXmmc/dpsi
dxyDist[ 3][0]=dkD[ 3]*dPXYmmc[0][0]+dkD[0]*dPXYmmc[ 3][0];
dxyDist[ 3][1]=dkD[ 3]*dPXYmmc[0][1]+dkD[0]*dPXYmmc[ 3][1];
// dxDist/dX0 = dkD/dX0*PXmmc + kD*dPXmmc/dX0
dxyDist[ 4][0]=dkD[ 4]*dPXYmmc[0][0]+dkD[0]*dPXYmmc[ 4][0]; // large error
dxyDist[ 4][1]=dkD[ 4]*dPXYmmc[0][1]+dkD[0]*dPXYmmc[ 4][1];
// dxDist/dY0 = dkD/dY0*PXmmc + kD*dPXmmc/dY0
dxyDist[ 5][0]=dkD[ 5]*dPXYmmc[0][0]+dkD[0]*dPXYmmc[ 5][0];
dxyDist[ 5][1]=dkD[ 5]*dPXYmmc[0][1]+dkD[0]*dPXYmmc[ 5][1];
// dxDist/dZ0 = dkD/dZ0*PXmmc + kD*dPXmmc/dZ0
dxyDist[ 6][0]=dkD[ 6]*dPXYmmc[0][0]+dkD[0]*dPXYmmc[ 6][0]; // large error
dxyDist[ 6][1]=dkD[ 6]*dPXYmmc[0][1]+dkD[0]*dPXYmmc[ 6][1];
// dxDist/df = dkD/df*PXmmc + kD*dPXmmc/df
dxyDist[ 7][0]=dkD[ 7]*dPXYmmc[0][0]+dkD[0]*dPXYmmc[ 7][0];
dxyDist[ 7][1]=dkD[ 7]*dPXYmmc[0][1]+dkD[0]*dPXYmmc[ 7][1];
// dxDist/ddist = dkD/ddist*PXmmc + kD*dPXmmc/ddist
dxyDist[ 8][0]=dkD[ 8]*dPXYmmc[0][0]+dkD[0]*dPXYmmc[ 8][0];
dxyDist[ 8][1]=dkD[ 8]*dPXYmmc[0][1]+dkD[0]*dPXYmmc[ 8][1];
// dxDist/dDa5 = dkD/dDa8*PXmmc
dxyDist[ 9][0]=dkD[ 9]*dPXYmmc[0][0];
dxyDist[ 9][1]=dkD[ 9]*dPXYmmc[0][1];
// dxDist/dDa5 = dkD/dDa7*PXmmc
dxyDist[10][0]=dkD[10]*dPXYmmc[0][0];
dxyDist[10][1]=dkD[10]*dPXYmmc[0][1];
// dxDist/dDa5 = dkD/dD6a*PXmmc
dxyDist[11][0]=dkD[11]*dPXYmmc[0][0];
dxyDist[11][1]=dkD[11]*dPXYmmc[0][1];
// dxDist/dDa5 = dkD/dDa5*PXmmc`
dxyDist[12][0]=dkD[12]*dPXYmmc[0][0];
dxyDist[12][1]=dkD[12]*dPXYmmc[0][1];
// dxDist/dDa = dkD/dDa*PXmmc
dxyDist[13][0]=dkD[13]*dPXYmmc[0][0];
dxyDist[13][1]=dkD[13]*dPXYmmc[0][1];
// dxDist/dDb = dkD/dDb*PXmmc
dxyDist[14][0]=dkD[14]*dPXYmmc[0][0];
dxyDist[14][1]=dkD[14]*dPXYmmc[0][1];
// dxDist/dDc = dkD/dDc*PXmmc
dxyDist[15][0]=dkD[15]*dPXYmmc[0][0];
dxyDist[15][1]=dkD[15]*dPXYmmc[0][1];
double K=Math.PI/180; // multiply all derivatives my angles double K=Math.PI/180; // multiply all derivatives my angles
// (10) PX = 1000/Psz*( xDist) + PX0 // horizontal pixel of the image (positive - right)
// dPX/dphi = 1000/Psz* dxDist/dphi // dPX/dphi = 1000/Psz* dxDist/dphi
partDeriv[ 1][0]= K*1000.0/this.pixelSize*dxyDist[ 1][0]; partDeriv[ 1][0]= K*(dPx_dPinholeX*dPXYmmc[1][0]+dPx_dPinholeY*dPXYmmc[1][1]);
partDeriv[ 1][1]= -K*1000.0/this.pixelSize*dxyDist[ 1][1]; partDeriv[ 1][1]= K*(dPy_dPinholeX*dPXYmmc[1][0]+dPy_dPinholeY*dPXYmmc[1][1]);
// dPX/dtheta = 1000/Psz* dxDist/dtheta // dPX/dtheta = 1000/Psz* dxDist/dtheta
partDeriv[ 2][0]= K*1000.0/this.pixelSize*dxyDist[ 2][0]; partDeriv[ 2][0]= K*(dPx_dPinholeX*dPXYmmc[2][0]+dPx_dPinholeY*dPXYmmc[2][1]);
partDeriv[ 2][1]= -K*1000.0/this.pixelSize*dxyDist[ 2][1]; partDeriv[ 2][1]= K*(dPy_dPinholeX*dPXYmmc[2][0]+dPy_dPinholeY*dPXYmmc[2][1]);
// dPX/dpsi = 1000/Psz* dxDist/dpsi // dPX/dpsi = 1000/Psz* dxDist/dpsi
partDeriv[ 3][0]= K*1000.0/this.pixelSize*dxyDist[ 3][0]; partDeriv[ 3][0]= K*(dPx_dPinholeX*dPXYmmc[3][0]+dPx_dPinholeY*dPXYmmc[3][1]);
partDeriv[ 3][1]= -K*1000.0/this.pixelSize*dxyDist[ 3][1]; partDeriv[ 3][1]= K*(dPy_dPinholeX*dPXYmmc[3][0]+dPy_dPinholeY*dPXYmmc[3][1]);
// dPX/dX0 = 1000/Psz* dxDist/dX0 // dPX/dX0 = 1000/Psz* dxDist/dX0
partDeriv[ 4][0]= 1000.0/this.pixelSize*dxyDist[ 4][0]; // large error partDeriv[ 4][0]= dPx_dPinholeX*dPXYmmc[4][0]+dPx_dPinholeY*dPXYmmc[4][1];
partDeriv[ 4][1]= -1000.0/this.pixelSize*dxyDist[ 4][1]; partDeriv[ 4][1]= dPy_dPinholeX*dPXYmmc[4][0]+dPy_dPinholeY*dPXYmmc[4][1];
// dPX/dY0 = 1000/Psz* dxDist/dY0 // dPX/dY0 = 1000/Psz* dxDist/dY0
partDeriv[ 5][0]= 1000.0/this.pixelSize*dxyDist[ 5][0]; partDeriv[ 5][0]= dPx_dPinholeX*dPXYmmc[5][0]+dPx_dPinholeY*dPXYmmc[5][1];
partDeriv[ 5][1]= -1000.0/this.pixelSize*dxyDist[ 5][1]; partDeriv[ 5][1]= dPy_dPinholeX*dPXYmmc[5][0]+dPy_dPinholeY*dPXYmmc[5][1];
// dPX/dZ0 = 1000/Psz* dxDist/dZ0 // dPX/dZ0 = 1000/Psz* dxDist/dZ0
partDeriv[ 6][0]= 1000.0/this.pixelSize*dxyDist[ 6][0]; // large error, including DC (sig -0.8..+0.5, err -0.2..-0.1 partDeriv[ 6][0]= dPx_dPinholeX*dPXYmmc[6][0]+dPx_dPinholeY*dPXYmmc[6][1];
partDeriv[ 6][1]= -1000.0/this.pixelSize*dxyDist[ 6][1]; partDeriv[ 6][1]= dPy_dPinholeX*dPXYmmc[6][0]+dPy_dPinholeY*dPXYmmc[6][1];
// dPX/df = 1000/Psz* dxDist/df // dPX/df = 1000/Psz* dxDist/df
partDeriv[ 7][0]= 1000.0/this.pixelSize*dxyDist[ 7][0]; partDeriv[ 7][0]= dPx_dPinholeX*dPXYmmc[7][0]+dPx_dPinholeY*dPXYmmc[7][1];
partDeriv[ 7][1]= -1000.0/this.pixelSize*dxyDist[ 7][1]; partDeriv[ 7][1]= dPy_dPinholeX*dPXYmmc[7][0]+dPy_dPinholeY*dPXYmmc[7][1];
// dPX/ddist = 1000/Psz* dxDist/ddist // dPX/ddist = 1000/Psz* dxDist/ddist
partDeriv[ 8][0]= 1000.0/this.pixelSize*dxyDist[ 8][0]; partDeriv[ 8][0]= dPx_dPinholeX*dPXYmmc[8][0]+dPx_dPinholeY*dPXYmmc[8][1];
partDeriv[ 8][1]= -1000.0/this.pixelSize*dxyDist[ 8][1]; partDeriv[ 8][1]= dPy_dPinholeX*dPXYmmc[8][0]+dPy_dPinholeY*dPXYmmc[8][1];
// dPX/dDa8 = 1000/Psz* dxDist/dDa5
partDeriv[ 9][0]= 1000.0/this.pixelSize*dxyDist[ 9][0];
partDeriv[ 9][1]= -1000.0/this.pixelSize*dxyDist[ 9][1];
// dPX/dDa7 = 1000/Psz* dxDist/dDa5
partDeriv[10][0]= 1000.0/this.pixelSize*dxyDist[10][0];
partDeriv[10][1]= -1000.0/this.pixelSize*dxyDist[10][1];
// dPX/dDa6 = 1000/Psz* dxDist/dDa5
partDeriv[11][0]= 1000.0/this.pixelSize*dxyDist[11][0];
partDeriv[11][1]= -1000.0/this.pixelSize*dxyDist[11][1];
// dPX/dDa5 = 1000/Psz* dxDist/dDa5
partDeriv[12][0]= 1000.0/this.pixelSize*dxyDist[12][0];
partDeriv[12][1]= -1000.0/this.pixelSize*dxyDist[12][1];
// dPX/dDa = 1000/Psz* dxDist/dDa
partDeriv[13][0]= 1000.0/this.pixelSize*dxyDist[13][0];
partDeriv[13][1]= -1000.0/this.pixelSize*dxyDist[13][1];
// dPX/dDb = 1000/Psz* dxDist/dDb
partDeriv[14][0]= 1000.0/this.pixelSize*dxyDist[14][0];
partDeriv[14][1]= -1000.0/this.pixelSize*dxyDist[14][1];
// dPX/dDc = 1000/Psz* dxDist/dDc
partDeriv[15][0]= 1000.0/this.pixelSize*dxyDist[15][0];
partDeriv[15][1]= -1000.0/this.pixelSize*dxyDist[15][1];
// dPX/dPX0 = 1 // dPX/dPX0 = 1
// dPY/dPX0 = 0 // dPY/dPX0 = 0
partDeriv[16][0]= 1.0; partDeriv[16][0]= 1.0;
...@@ -929,8 +1288,23 @@ dPXmmc/dphi= ...@@ -929,8 +1288,23 @@ dPXmmc/dphi=
properties.setProperty(prefix+"px0",this.px0+""); properties.setProperty(prefix+"px0",this.px0+"");
properties.setProperty(prefix+"py0",this.py0+""); properties.setProperty(prefix+"py0",this.py0+"");
properties.setProperty(prefix+"flipVertical",this.flipVertical+""); properties.setProperty(prefix+"flipVertical",this.flipVertical+"");
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]+"");
}
} }
public void getProperties(String prefix,Properties properties){ 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();
}
public void getProperties(String prefix,Properties properties){
if (properties.getProperty(prefix+"focalLength")!=null) if (properties.getProperty(prefix+"focalLength")!=null)
this.focalLength=Double.parseDouble(properties.getProperty(prefix+"focalLength")); this.focalLength=Double.parseDouble(properties.getProperty(prefix+"focalLength"));
if (properties.getProperty(prefix+"pixelSize")!=null) if (properties.getProperty(prefix+"pixelSize")!=null)
...@@ -971,6 +1345,16 @@ dPXmmc/dphi= ...@@ -971,6 +1345,16 @@ dPXmmc/dphi=
this.py0=Double.parseDouble(properties.getProperty(prefix+"py0")); this.py0=Double.parseDouble(properties.getProperty(prefix+"py0"));
if (properties.getProperty(prefix+"flipVertical")!=null) if (properties.getProperty(prefix+"flipVertical")!=null)
this.flipVertical=Boolean.parseBoolean(properties.getProperty(prefix+"flipVertical")); this.flipVertical=Boolean.parseBoolean(properties.getProperty(prefix+"flipVertical"));
setDefaultNonRadial();
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"));
}
recalcCommons(); recalcCommons();
} }
public boolean showDialog() { public boolean showDialog() {
...@@ -995,7 +1379,41 @@ dPXmmc/dphi= ...@@ -995,7 +1379,41 @@ dPXmmc/dphi=
gd.addNumericField("Lens axis on the sensor (horizontal, from left edge)", this.px0, 1,6,"pixels"); gd.addNumericField("Lens axis on the sensor (horizontal, from left edge)", this.px0, 1,6,"pixels");
gd.addNumericField("Lens axis on the sensor (vertical, from top edge)", this.py0, 1,6,"pixels"); gd.addNumericField("Lens axis on the sensor (vertical, from top edge)", this.py0, 1,6,"pixels");
gd.addCheckbox ("Camera looks through the mirror", this.flipVertical); gd.addCheckbox ("Camera looks through the mirror", this.flipVertical);
gd.addMessage("=== non-radial model parameters ===");
gd.addMessage("For r^2 (Distortion C):");
gd.addNumericField("Orthogonal elongation for r^2", 100*this.r_od[0][0], 3,7,"%");
gd.addNumericField("Diagonal elongation for r^2", 100*this.r_od[0][1], 3,7,"%");
gd.addMessage("For r^3 (Distortion B):");
gd.addNumericField("Distortion center shift X for r^3", 100*this.r_xy[0][0], 1,6,"%");
gd.addNumericField("Distortion center shift Y for r^3", 100*this.r_xy[0][1], 1,6,"%");
gd.addNumericField("Orthogonal elongation for r^3", 100*this.r_od[1][0], 3,7,"%");
gd.addNumericField("Diagonal elongation for r^3", 100*this.r_od[1][1], 3,7,"%");
gd.addMessage("For r^4 (Distortion A):");
gd.addNumericField("Distortion center shift X for r^4", 100*this.r_xy[1][0], 1,6,"%");
gd.addNumericField("Distortion center shift Y for r^4", 100*this.r_xy[1][1], 1,6,"%");
gd.addNumericField("Orthogonal elongation for r^4", 100*this.r_od[2][0], 3,7,"%");
gd.addNumericField("Diagonal elongation for r^4", 100*this.r_od[2][1], 3,7,"%");
gd.addMessage("For r^5 (Distortion A5):");
gd.addNumericField("Distortion center shift X for r^5", 100*this.r_xy[2][0], 1,6,"%");
gd.addNumericField("Distortion center shift Y for r^5", 100*this.r_xy[2][1], 1,6,"%");
gd.addNumericField("Orthogonal elongation for r^5", 100*this.r_od[3][0], 3,7,"%");
gd.addNumericField("Diagonal elongation for r^5", 100*this.r_od[3][1], 3,7,"%");
gd.addMessage("For r^6 (Distortion A6:");
gd.addNumericField("Distortion center shift X for r^6", 100*this.r_xy[3][0], 1,6,"%");
gd.addNumericField("Distortion center shift Y for r^6", 100*this.r_xy[3][1], 1,6,"%");
gd.addNumericField("Orthogonal elongation for r^6", 100*this.r_od[4][0], 3,7,"%");
gd.addNumericField("Diagonal elongation for r^6", 100*this.r_od[4][1], 3,7,"%");
gd.addMessage("For r^7 (Distortion A7):");
gd.addNumericField("Distortion center shift X for r^7", 100*this.r_xy[4][0], 1,6,"%");
gd.addNumericField("Distortion center shift Y for r^7", 100*this.r_xy[4][1], 1,6,"%");
gd.addNumericField("Orthogonal elongation for r^7", 100*this.r_od[5][0], 3,7,"%");
gd.addNumericField("Diagonal elongation for r^7", 100*this.r_od[5][1], 3,7,"%");
gd.addMessage("For r^8 (Distortion A8):");
gd.addNumericField("Distortion center shift X for r^8", 100*this.r_xy[5][0], 1,6,"%");
gd.addNumericField("Distortion center shift Y for r^8", 100*this.r_xy[5][1], 1,6,"%");
gd.addNumericField("Orthogonal elongation for r^8", 100*this.r_od[6][0], 3,7,"%");
gd.addNumericField("Diagonal elongation for r^8", 100*this.r_od[6][1], 3,7,"%");
WindowTools.addScrollBars(gd);
gd.showDialog(); gd.showDialog();
if (gd.wasCanceled()) return false; if (gd.wasCanceled()) return false;
this.focalLength= gd.getNextNumber(); this.focalLength= gd.getNextNumber();
...@@ -1017,12 +1435,39 @@ dPXmmc/dphi= ...@@ -1017,12 +1435,39 @@ dPXmmc/dphi=
this.distance= gd.getNextNumber(); this.distance= gd.getNextNumber();
this.px0= gd.getNextNumber(); this.px0= gd.getNextNumber();
this.py0= gd.getNextNumber(); this.py0= gd.getNextNumber();
this.flipVertical= gd.getNextBoolean(); this.flipVertical= gd.getNextBoolean();
this.r_od[0][0]= 0.01*gd.getNextNumber();
this.r_od[0][1]= 0.01*gd.getNextNumber();
this.r_xy[0][0]= 0.01*gd.getNextNumber();
this.r_xy[0][1]= 0.01*gd.getNextNumber();
this.r_od[1][0]= 0.01*gd.getNextNumber();
this.r_od[1][1]= 0.01*gd.getNextNumber();
this.r_xy[1][0]= 0.01*gd.getNextNumber();
this.r_xy[1][1]= 0.01*gd.getNextNumber();
this.r_od[2][0]= 0.01*gd.getNextNumber();
this.r_od[2][1]= 0.01*gd.getNextNumber();
this.r_xy[2][0]= 0.01*gd.getNextNumber();
this.r_xy[2][1]= 0.01*gd.getNextNumber();
this.r_od[3][0]= 0.01*gd.getNextNumber();
this.r_od[3][1]= 0.01*gd.getNextNumber();
this.r_xy[3][0]= 0.01*gd.getNextNumber();
this.r_xy[3][1]= 0.01*gd.getNextNumber();
this.r_od[4][0]= 0.01*gd.getNextNumber();
this.r_od[4][1]= 0.01*gd.getNextNumber();
this.r_xy[4][0]= 0.01*gd.getNextNumber();
this.r_xy[4][1]= 0.01*gd.getNextNumber();
this.r_od[5][0]= 0.01*gd.getNextNumber();
this.r_od[5][1]= 0.01*gd.getNextNumber();
this.r_xy[5][0]= 0.01*gd.getNextNumber();
this.r_xy[5][1]= 0.01*gd.getNextNumber();
this.r_od[6][0]= 0.01*gd.getNextNumber();
this.r_od[6][1]= 0.01*gd.getNextNumber();
return true; return true;
} }
/** /**
* Calculate/set this.lensDistortionParameters and this.interParameterDerivatives * Calculate/set this.lensDistortionParameters and this.interParameterDerivatives
* UPDATE - Modifies lensDistortionParameters, not "this" formulti-threaded * UPDATE - Modifies lensDistortionParameters, not "this" for multi-threaded
* @param parVect 21-element vector for eyesis sub-camera, including common and individual parameters * @param parVect 21-element vector for eyesis sub-camera, including common and individual parameters
* @param mask -mask - which partial derivatives are needed to be calculated (others will be null) * @param mask -mask - which partial derivatives are needed to be calculated (others will be null)
* @param calculateDerivatives calculate array of partial derivatives, if false - just the values * @param calculateDerivatives calculate array of partial derivatives, if false - just the values
...@@ -1241,9 +1686,36 @@ dPXmmc/dphi= ...@@ -1241,9 +1686,36 @@ dPXmmc/dphi=
lensDistortionParameters.distortionA=parVect[24]; //subCam.distortionA; lensDistortionParameters.distortionA=parVect[24]; //subCam.distortionA;
lensDistortionParameters.distortionB=parVect[25]; //subCam.distortionB; lensDistortionParameters.distortionB=parVect[25]; //subCam.distortionB;
lensDistortionParameters.distortionC=parVect[26]; //subCam.distortionC; lensDistortionParameters.distortionC=parVect[26]; //subCam.distortionC;
lensDistortionParameters.recalcCommons(); lensDistortionParameters.r_xy=new double [6][2];
lensDistortionParameters.r_od=new double [7][2];
// parVect here is o[0],d[0],{x[0],y[0],o[1],d[1]}, {} = same term
int index=27;
for (int i=0;i<lensDistortionParameters.r_od.length;i++){
if (i>0){
lensDistortionParameters.r_xy[i-1][0]=parVect[index++];
lensDistortionParameters.r_xy[i-1][1]=parVect[index++];
}
lensDistortionParameters.r_od[i][0]=parVect[index++];
lensDistortionParameters.r_od[i][1]=parVect[index++];
}
/*
for (double [] row :lensDistortionParameters.r_xy){
row[0]=parVect[index++];
row[1]=parVect[index++];
}
for (double [] row :lensDistortionParameters.r_od){
row[0]=parVect[index++];
row[1]=parVect[index++];
}
*/
///
// public double [][] r_xy=null; // only 6, as for the first term delta x, delta y ==0
// public double [][] r_od=null; // ortho
lensDistortionParameters.recalcCommons(); // uncliding lensDistortionParameters.r_xyod
if (this.debugLevel>2){ if (this.debugLevel>2){
...@@ -1265,6 +1737,15 @@ dPXmmc/dphi= ...@@ -1265,6 +1737,15 @@ dPXmmc/dphi=
System.out.println("lensDistortionParameters.distortionA="+IJ.d2s(lensDistortionParameters.distortionA, 5)); System.out.println("lensDistortionParameters.distortionA="+IJ.d2s(lensDistortionParameters.distortionA, 5));
System.out.println("lensDistortionParameters.distortionB="+IJ.d2s(lensDistortionParameters.distortionB, 5)); System.out.println("lensDistortionParameters.distortionB="+IJ.d2s(lensDistortionParameters.distortionB, 5));
System.out.println("lensDistortionParameters.distortionC="+IJ.d2s(lensDistortionParameters.distortionC, 5)); System.out.println("lensDistortionParameters.distortionC="+IJ.d2s(lensDistortionParameters.distortionC, 5));
for (int i=0;i<lensDistortionParameters.r_xy.length;i++){
System.out.println("lensDistortionParameters.r_xy["+i+"][0]"+IJ.d2s(lensDistortionParameters.r_xy[i][0], 5));
System.out.println("lensDistortionParameters.r_xy["+i+"][1]"+IJ.d2s(lensDistortionParameters.r_xy[i][1], 5));
}
for (int i=0;i<lensDistortionParameters.r_od.length;i++){
System.out.println("lensDistortionParameters.r_od["+i+"][0]"+IJ.d2s(lensDistortionParameters.r_od[i][0], 5));
System.out.println("lensDistortionParameters.r_od["+i+"][1]"+IJ.d2s(lensDistortionParameters.r_od[i][1], 5));
}
} }
if (!calculateDerivatives) return; if (!calculateDerivatives) return;
/* Calculate all derivativs as a matrix. /* Calculate all derivativs as a matrix.
...@@ -1297,6 +1778,32 @@ dPXmmc/dphi= ...@@ -1297,6 +1778,32 @@ dPXmmc/dphi=
24(22) public double distortionA=0.0; // r^4 (normalized to focal length or to sensor half width?) 24(22) public double distortionA=0.0; // r^4 (normalized to focal length or to sensor half width?)
25(23) public double distortionB=0.0; // r^3 25(23) public double distortionB=0.0; // r^3
26(24) public double distortionC=0.0; // r^2 26(24) public double distortionC=0.0; // r^2
27 Distortion center shift X for r^3"
28 Distortion center shift Y for r^3"
29 Distortion center shift X for r^4"
30 Distortion center shift Y for r^4"
31 Distortion center shift X for r^5"
32 Distortion center shift Y for r^5"
33 Distortion center shift X for r^6"
34 Distortion center shift Y for r^6"
35 Distortion center shift X for r^7"
36 Distortion center shift Y for r^7"
37 Distortion center shift X for r^8"
38 Distortion center shift Y for r^8"
39 Orthogonal elongation for r^2"
40 Diagonal elongation for r^2"
41 Orthogonal elongation for r^3"
42 Diagonal elongation for r^3"
43 Orthogonal elongation for r^4"
44 Diagonal elongation for r^4"
45 Orthogonal elongation for r^5"
46 Diagonal elongation for r^5"
47 Orthogonal elongation for r^6"
48 Diagonal elongation for r^6"
49 Orthogonal elongation for r^7"
50 Diagonal elongation for r^7"
51 Orthogonal elongation for r^8"
52 Diagonal elongation for r^8"
* Output parameters (rows): * Output parameters (rows):
0 public double x0=0; // lens axis from pattern center, mm (to the right) 0 public double x0=0; // lens axis from pattern center, mm (to the right)
...@@ -1316,7 +1823,33 @@ dPXmmc/dphi= ...@@ -1316,7 +1823,33 @@ dPXmmc/dphi=
13 public double distortionA=0.0; // r^4 (normalized to focal length or to sensor half width?) 13 public double distortionA=0.0; // r^4 (normalized to focal length or to sensor half width?)
14 public double distortionB=0.0; // r^3 14 public double distortionB=0.0; // r^3
15 public double distortionC=0.0; // r^2 15 public double distortionC=0.0; // r^2
*/ 16 Distortion center shift X for r^3"
17 Distortion center shift Y for r^3"
18 Distortion center shift X for r^4"
19 Distortion center shift Y for r^4"
20 Distortion center shift X for r^5"
21 Distortion center shift Y for r^5"
22 Distortion center shift X for r^6"
23 Distortion center shift Y for r^6"
24 Distortion center shift X for r^7"
25 Distortion center shift Y for r^7"
26 Distortion center shift X for r^8"
27 Distortion center shift Y for r^8"
28 Orthogonal elongation for r^2"
29 Diagonal elongation for r^2"
30 Orthogonal elongation for r^3"
31 Diagonal elongation for r^3"
32 Orthogonal elongation for r^4"
33 Diagonal elongation for r^4"
34 Orthogonal elongation for r^5"
35 Diagonal elongation for r^5"
36 Orthogonal elongation for r^6"
37 Diagonal elongation for r^6"
38 Orthogonal elongation for r^7"
39 Diagonal elongation for r^7"
40 Orthogonal elongation for r^8"
41 Diagonal elongation for r^8"
*/
// interParameterDerivatives=new double[getNumInputs()][]; //partial derivative matrix from subcamera-camera-goniometer to single camera (12x21) // interParameterDerivatives=new double[getNumInputs()][]; //partial derivative matrix from subcamera-camera-goniometer to single camera (12x21)
//calculate dMA_azimuth //calculate dMA_azimuth
...@@ -1682,9 +2215,10 @@ dPXmmc/dphi= ...@@ -1682,9 +2215,10 @@ dPXmmc/dphi=
//24 (22) public double distortionA=0.0; // r^4 (normalized to focal length or to sensor half width?) //24 (22) public double distortionA=0.0; // r^4 (normalized to focal length or to sensor half width?)
//25 (23) public double distortionB=0.0; // r^3 //25 (23) public double distortionB=0.0; // r^3
//26 (24) public double distortionC=0.0; // r^2 //26 (24) public double distortionC=0.0; // r^2
//27..52 - non-radial parameters
// for (int inpPar=15; inpPar<getNumInputs(); inpPar++){ // for (int inpPar=15; inpPar<getNumInputs(); inpPar++){
for (int inpPar=17; inpPar<getNumInputs(); inpPar++){ // OK with A8 for (int inpPar=17; inpPar<getNumInputs(); inpPar++){ // OK with A8. Should be OK with non-radial parameters ((27..52) also
if (mask[inpPar]){ if (mask[inpPar]){
interParameterDerivatives[inpPar]=new double[getNumOutputs()]; interParameterDerivatives[inpPar]=new double[getNumOutputs()];
for (int outPar=0; outPar<getNumOutputs(); outPar++){ for (int outPar=0; outPar<getNumOutputs(); outPar++){
...@@ -1762,8 +2296,9 @@ dPXmmc/dphi= ...@@ -1762,8 +2296,9 @@ dPXmmc/dphi=
* @return differentials of the {x0,y0,dist,phi,theta,psi} by that parameter * @return differentials of the {x0,y0,dist,phi,theta,psi} by that parameter
*/ */
public double [] d_parametersFromMAMB(Matrix d_MA, Matrix d_MB, Matrix MA, Matrix MB, boolean isAngle){ public double [] d_parametersFromMAMB(Matrix d_MA, Matrix d_MB, Matrix MA, Matrix MB, boolean isAngle){
double [] result= new double [getNumOutputs()]; // only first 6 are used double [] result= new double [getNumOutputs()]; // only first 6 are used, rest are 0
for (int i=6; i<getNumOutputs();i++) result[i]=0.0; Arrays.fill(result,6, result.length, 0.0);
// for (int i=6; i<getNumOutputs();i++) result[i]=0.0;
/* /*
0 public double x0=0; // lens axis from pattern center, mm (to the right) 0 public double x0=0; // lens axis from pattern center, mm (to the right)
1 public double y0=0; // lens axis from pattern center, mm (down) 1 public double y0=0; // lens axis from pattern center, mm (down)
...@@ -1862,8 +2397,5 @@ dPXmmc/dphi= ...@@ -1862,8 +2397,5 @@ dPXmmc/dphi=
public int getNumInputs(){return numInputs;} public int getNumInputs(){return numInputs;}
public int getNumOutputs(){return numOutputs;} public int getNumOutputs(){return numOutputs;}
} }
\ No newline at end of file
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