Commit d811fafa authored by Andrey Filippov's avatar Andrey Filippov

implemented distorrtion model selection, image selection editor, different...

implemented distorrtion model selection, image selection editor, different maximal radius for grid match and adjustment
parent ae245e9a
...@@ -404,6 +404,7 @@ public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSi ...@@ -404,6 +404,7 @@ public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSi
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)
-1, // lensDistortionModel (use default)
null, // double [][] r_xy, null, // double [][] r_xy,
null // double [][] r_od null // double [][] r_od
); );
...@@ -1169,7 +1170,8 @@ if (MORE_BUTTONS) { ...@@ -1169,7 +1170,8 @@ if (MORE_BUTTONS) {
System.out.println("Number of enabled grid images: "+numImages[0]+ System.out.println("Number of enabled grid images: "+numImages[0]+
", of them new: "+numImages[1]+ ", of them new: "+numImages[1]+
", disabled without vignetting info: "+numImages[2]+ ", disabled without vignetting info: "+numImages[2]+
", disabled having less than "+minGridsNoPointer+" nodes and no matched pointers: "+numImages[3]); ", disabled having less than "+minGridsNoPointer+" nodes and no matched pointers: "+numImages[3]+
", disabled with no lasers and enableNoLaser==false (like 2 bottom cameras):" +numImages[4]);
if (DISTORTION_CALIBRATION_DATA.gIS==null) { if (DISTORTION_CALIBRATION_DATA.gIS==null) {
int numImageSets=DISTORTION_CALIBRATION_DATA.buildImageSets(false); // from scratch int numImageSets=DISTORTION_CALIBRATION_DATA.buildImageSets(false); // from scratch
...@@ -6062,7 +6064,7 @@ if (MORE_BUTTONS) { ...@@ -6062,7 +6064,7 @@ if (MORE_BUTTONS) {
gd.addNumericField("Minimal registered grid period as a fraction of maximal (to filter reflections)", 0.4,2); //was 0.7 gd.addNumericField("Minimal registered grid period as a fraction of maximal (to filter reflections)", 0.4,2); //was 0.7
gd.addCheckbox ("Reset orientation from the image with most pointers (false - only if it was not set yet)", overwriteAll); gd.addCheckbox ("Reset orientation from the image with most pointers (false - only if it was not set yet)", overwriteAll);
gd.addCheckbox ("Disable (old) images without vignetting information", true); gd.addCheckbox ("Disable (old) images without vignetting information", true);
gd.addNumericField("Minimal number of grids in no-pointer images and estimated orientation", 1000,0); gd.addNumericField("Minimal number of grid nodes in no-pointer images and estimated orientation", 1000,0);
gd.showDialog(); gd.showDialog();
if (gd.wasCanceled()) return; if (gd.wasCanceled()) return;
boolean resetHinted= gd.getNextBoolean(); boolean resetHinted= gd.getNextBoolean();
...@@ -6081,7 +6083,8 @@ if (MORE_BUTTONS) { ...@@ -6081,7 +6083,8 @@ if (MORE_BUTTONS) {
System.out.println("Number of enabled grid images: "+numImages[0]+ System.out.println("Number of enabled grid images: "+numImages[0]+
", of them new: "+numImages[1]+ ", of them new: "+numImages[1]+
", disabled without vignetting info: "+numImages[2]+ ", disabled without vignetting info: "+numImages[2]+
", disabled having less than "+minGridsNoPointer+" nodes and no matched pointers: "+numImages[3]); ", disabled having less than "+minGridsNoPointer+" nodes and no matched pointers: "+numImages[3]+
", disabled with no lasers and enableNoLaser==false (like 2 bottom cameras):" +numImages[4]);
if (DISTORTION_CALIBRATION_DATA.gIS==null) { if (DISTORTION_CALIBRATION_DATA.gIS==null) {
int numImageSets=DISTORTION_CALIBRATION_DATA.buildImageSets(false); // from scratch int numImageSets=DISTORTION_CALIBRATION_DATA.buildImageSets(false); // from scratch
if (DEBUG_LEVEL>0) System.out.println("Image set was empty, built a new one with "+numImageSets+" image sets (\"panoramas\"): "); if (DEBUG_LEVEL>0) System.out.println("Image set was empty, built a new one with "+numImageSets+" image sets (\"panoramas\"): ");
......
...@@ -38,6 +38,7 @@ import java.io.File; ...@@ -38,6 +38,7 @@ import java.io.File;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.ConfigurationException;
...@@ -679,7 +680,14 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -679,7 +680,14 @@ import org.apache.commons.configuration.XMLConfiguration;
if (this.eyesisCameraParameters.numStations>1){ if (this.eyesisCameraParameters.numStations>1){
sb.append("Station "+stationNumber+" W="+(100*this.eyesisCameraParameters.stationWeight[stationNumber])+"%"); for (int i=-1;i<numSubCameras;i++) sb.append("\t==="); sb.append("\n"); sb.append("Station "+stationNumber+" W="+(100*this.eyesisCameraParameters.stationWeight[stationNumber])+"%"); for (int i=-1;i<numSubCameras;i++) sb.append("\t==="); sb.append("\n");
} }
int [] lensDistortionModels=new int [numSubCameras];
for (int i=0;i<numSubCameras;i++) lensDistortionModels[i]=eyesisCameraParameters.getLensDistortionModel(stationNumber,i);
sb.append("Lens Distortion Model\t");
for (int i=0;i<numSubCameras;i++) sb.append("\t"+lensDistortionModels[i]);
sb.append("\n");
double [][] cameraPars=new double [numSubCameras][]; double [][] cameraPars=new double [numSubCameras][];
for (int i=0;i<numSubCameras;i++) cameraPars[i]=eyesisCameraParameters.getParametersVector(stationNumber,i); for (int i=0;i<numSubCameras;i++) cameraPars[i]=eyesisCameraParameters.getParametersVector(stationNumber,i);
// parameters same order as in this // parameters same order as in this
for (int n=0;n<cameraPars[0].length;n++) if (isSubcameraParameter(n) && isIntrinsicParameter(n)){ for (int n=0;n<cameraPars[0].length;n++) if (isSubcameraParameter(n) && isIntrinsicParameter(n)){
...@@ -935,8 +943,10 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -935,8 +943,10 @@ import org.apache.commons.configuration.XMLConfiguration;
} }
} }
int numNoVignetting=0; int numNoVignetting=0;
int disabledNoLaser=0;
for (int i=0;i<this.gIP.length;i++){ for (int i=0;i<this.gIP.length;i++){
int stationNumber=this.gIP[i].getStationNumber(); int stationNumber=this.gIP[i].getStationNumber();
boolean enableNoLaser=this.eyesisCameraParameters.getEnableNoLaser(stationNumber,this.gIP[i].channel);
boolean wasEnabled=this.gIP[i].enabled; boolean wasEnabled=this.gIP[i].enabled;
if (resetHinted) this.gIP[i].hintedMatch=-1; // undefined if (resetHinted) this.gIP[i].hintedMatch=-1; // undefined
if (Double.isNaN(this.gIP[i].gridPeriod) || if (Double.isNaN(this.gIP[i].gridPeriod) ||
...@@ -949,15 +959,17 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -949,15 +959,17 @@ import org.apache.commons.configuration.XMLConfiguration;
if ( if (
(this.gIP[i].matchedPointers>=minPointers) || (this.gIP[i].matchedPointers>=minPointers) ||
((this.gIP[i].matchedPointers>0) && (this.gIP[i].hintedMatch>0)) || // orientation and one pointer ((this.gIP[i].matchedPointers>0) && (this.gIP[i].hintedMatch>0)) || // orientation and one pointer
(this.gIP[i].hintedMatch>1)) { ((this.gIP[i].hintedMatch>1) && enableNoLaser)) { // do not use bottom images w/o matched pointers
// before enabling - copy orientation from gIS // before enabling - copy orientation from gIS
if (!this.gIP[i].enabled && (gIS_index[i]>=0)){ if (!this.gIP[i].enabled && (gIS_index[i]>=0)){
if (!Double.isNaN(this.gIS[gIS_index[i]].goniometerTilt)) setGH(i,this.gIS[gIS_index[i]].goniometerTilt ); if (!Double.isNaN(this.gIS[gIS_index[i]].goniometerTilt)) setGH(i,this.gIS[gIS_index[i]].goniometerTilt );
if (!Double.isNaN(this.gIS[gIS_index[i]].goniometerAxial)) setGA(i,this.gIS[gIS_index[i]].goniometerAxial ); if (!Double.isNaN(this.gIS[gIS_index[i]].goniometerAxial)) setGA(i,this.gIS[gIS_index[i]].goniometerAxial );
} }
this.gIP[i].enabled=true; this.gIP[i].enabled=true;
} else this.gIP[i].enabled=false;
if ((this.gIP[i].hintedMatch>1) && !enableNoLaser && (this.gIP[i].matchedPointers==0)){
disabledNoLaser++;
} }
else this.gIP[i].enabled=false;
} }
if (disableNoVignetting) { if (disableNoVignetting) {
...@@ -977,7 +989,7 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -977,7 +989,7 @@ import org.apache.commons.configuration.XMLConfiguration;
if (this.gIP[i].newEnabled) newEnabled++; if (this.gIP[i].newEnabled) newEnabled++;
} }
// may need buildImageSets // may need buildImageSets
int [] result={numEnabled,newEnabled,numNoVignetting,notEnoughNodes}; int [] result={numEnabled,newEnabled,numNoVignetting,notEnoughNodes,disabledNoLaser};
return result; return result;
} }
// TODO: // TODO:
...@@ -1277,7 +1289,26 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -1277,7 +1289,26 @@ import org.apache.commons.configuration.XMLConfiguration;
return numEnabled; return numEnabled;
} }
int [] getStations(){
int [] result = new int [this.gIP.length];
for (int i=0;i<result.length;i++) result[i]=(this.gIP[i]!=null)?this.gIP[i].stationNumber:-1;
return result;
}
int [] getChannels(){
int [] result = new int [this.gIP.length];
for (int i=0;i<result.length;i++) result[i]=(this.gIP[i]!=null)?this.gIP[i].channel:-1;
return result;
}
int [] getMatchedPointers(){
int [] result = new int [this.gIP.length];
for (int i=0;i<result.length;i++) result[i]=(this.gIP[i]!=null)?this.gIP[i].matchedPointers:0;
return result;
}
int [] getHintedMatch(){
int [] result = new int [this.gIP.length];
for (int i=0;i<result.length;i++) result[i]=(this.gIP[i]!=null)?this.gIP[i].hintedMatch:-1;
return result;
}
boolean [] selectNewEnabled () { boolean [] selectNewEnabled () {
boolean [] newEnabled=new boolean [this.gIP.length] ; boolean [] newEnabled=new boolean [this.gIP.length] ;
...@@ -1285,14 +1316,22 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -1285,14 +1316,22 @@ import org.apache.commons.configuration.XMLConfiguration;
return newEnabled; return newEnabled;
} }
boolean [] selectEnabled () {
boolean [] enabled=new boolean [this.gIP.length] ;
for (int i=0;i<this.gIP.length;i++) enabled[i]= (this.gIP[i]!=null) && this.gIP[i].enabled;
return enabled;
}
boolean [] selectEstimated (boolean enabledOnly) { boolean [] selectEstimated (boolean enabledOnly) {
boolean [] estimated=new boolean [getNumImages()];
if (this.gIS==null) { if (this.gIS==null) {
String msg="Image sets are not initialized"; String msg="Image sets are not initialized";
IJ.showMessage("Error",msg); IJ.showMessage("Error",msg);
throw new IllegalArgumentException (msg); // throw new IllegalArgumentException (msg);
Arrays.fill(estimated, true);
return estimated;
} }
boolean [] estimated=new boolean [getNumImages()];
for (int i=0;i<estimated.length;i++) estimated[i]=false; for (int i=0;i<estimated.length;i++) estimated[i]=false;
for (int i=0;i<this.gIS.length;i++) if (this.gIS[i].imageSet!=null){ for (int i=0;i<this.gIS.length;i++) if (this.gIS[i].imageSet!=null){
for (int j=0;j<this.gIS[i].imageSet.length;j++) if (this.gIS[i].imageSet[j]!=null) { for (int j=0;j<this.gIS[i].imageSet.length;j++) if (this.gIS[i].imageSet[j]!=null) {
......
...@@ -50,6 +50,7 @@ import Jama.Matrix; ...@@ -50,6 +50,7 @@ import Jama.Matrix;
// 1 - put commons-configuration-1.7.jar under ImageJ plugins directory (I used ImageJ-Elphel) // 1 - put commons-configuration-1.7.jar under ImageJ plugins directory (I used ImageJ-Elphel)
// 2 - in Eclipse project properties -> Build Path -> Libraries -> Add External jar // 2 - in Eclipse project properties -> Build Path -> Libraries -> Add External jar
public class Distortions { public class Distortions {
final public double hintedMaxRelativeRadius=1.2; // make adjustable?
private showDoubleFloatArrays SDFA_INSTANCE=new showDoubleFloatArrays(); // just for debugging? private showDoubleFloatArrays SDFA_INSTANCE=new showDoubleFloatArrays(); // just for debugging?
// int numInputs=27; // with A8...// 24; // parameters in subcamera+... // int numInputs=27; // with A8...// 24; // parameters in subcamera+...
// int numOutputs=16; // with A8...//13; // parameters in a single camera // int numOutputs=16; // with A8...//13; // parameters in a single camera
...@@ -3010,12 +3011,25 @@ For each point in the image ...@@ -3010,12 +3011,25 @@ For each point in the image
* @param v grid V (signed, 0 in the center) * @param v grid V (signed, 0 in the center)
* @return [7] {pX,pY,grid mask (binary), grid R, grid G, grid B, alpha} * @return [7] {pX,pY,grid mask (binary), grid R, grid G, grid B, alpha}
*/ */
public double [] reprojectGridNode( public double [] reprojectGridNode(
LensDistortionParameters lensDistortionParameters, LensDistortionParameters lensDistortionParameters,
int numImg, int numImg,
int u, // grid signed u,v int u, // grid signed u,v
int v int v){
double maxRelativeRadius=this.hintedMaxRelativeRadius; // make adjustable
return reprojectGridNode(
lensDistortionParameters,
numImg,
u, // grid signed u,v
v,
maxRelativeRadius);
}
public double [] reprojectGridNode(
LensDistortionParameters lensDistortionParameters,
int numImg,
int u, // grid signed u,v
int v,
double maxRelativeRadius //=2.0;
){ ){
int debugThreshold=1; int debugThreshold=1;
int nChn= this.fittingStrategy.distortionCalibrationData.gIP[numImg].channel; int nChn= this.fittingStrategy.distortionCalibrationData.gIP[numImg].channel;
...@@ -3035,6 +3049,7 @@ For each point in the image ...@@ -3035,6 +3049,7 @@ For each point in the image
XYZMP[0], // target point horizontal, positive - right, mm XYZMP[0], // target point horizontal, positive - right, mm
XYZMP[1], // target point vertical, positive - down, mm XYZMP[1], // target point vertical, positive - down, mm
XYZMP[2], // target point horizontal, positive - away from camera, mm XYZMP[2], // target point horizontal, positive - away from camera, mm
maxRelativeRadius, //
false); // calculate derivatives, false - values only (NaN for behind points - only when false here) false); // calculate derivatives, false - values only (NaN for behind points - only when false here)
if (Double.isNaN(pXY[0][0])) { if (Double.isNaN(pXY[0][0])) {
if (this.debugLevel>debugThreshold){ if (this.debugLevel>debugThreshold){
...@@ -3094,6 +3109,7 @@ For each point in the image ...@@ -3094,6 +3109,7 @@ For each point in the image
double goniometerAxial, // Axial double goniometerAxial, // Axial
int imageSet, int imageSet,
boolean filterBorder){ boolean filterBorder){
double maxRelativeRadius=this.hintedMaxRelativeRadius; // make adjustable
int debugThreshold=2; int debugThreshold=2;
// Get parameter vector (22) for the selected sensor, current Eyesisparameters and specified orientation angles // Get parameter vector (22) for the selected sensor, current Eyesisparameters and specified orientation angles
double [] parVector=fittingStrategy.distortionCalibrationData.eyesisCameraParameters.getParametersVector(stationNumber,subCamera); double [] parVector=fittingStrategy.distortionCalibrationData.eyesisCameraParameters.getParametersVector(stationNumber,subCamera);
...@@ -3155,6 +3171,7 @@ For each point in the image ...@@ -3155,6 +3171,7 @@ For each point in the image
XYZM[0], // target point horizontal, positive - right, mm XYZM[0], // target point horizontal, positive - right, mm
XYZM[1], // target point vertical, positive - down, mm XYZM[1], // target point vertical, positive - down, mm
XYZM[2], // target point horizontal, positive - away from camera, mm XYZM[2], // target point horizontal, positive - away from camera, mm
maxRelativeRadius,
false); // calculate derivatives, false - values only (NaN for behind points - only when false here) false); // calculate derivatives, false - values only (NaN for behind points - only when false here)
// verify the grid is inside the sensor area (may use sensor mask later too? probably not needed) // verify the grid is inside the sensor area (may use sensor mask later too? probably not needed)
// Now NaN if point is behind the sensor // Now NaN if point is behind the sensor
...@@ -5963,6 +5980,10 @@ List calibration ...@@ -5963,6 +5980,10 @@ 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");
imp.setProperty("comment_lensDistortionModel", "Integer specifying lens distrotion model (0 - radial)");
imp.setProperty("lensDistortionModel", ""+subCam.lensDistortionModel);
for (int i=0;i<subCam.r_xy.length;i++){ 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+"_x",subCam.r_xy[i][0]+"");
imp.setProperty("r_xy_"+i+"_y",subCam.r_xy[i][1]+""); imp.setProperty("r_xy_"+i+"_y",subCam.r_xy[i][1]+"");
...@@ -6144,6 +6165,7 @@ List calibration ...@@ -6144,6 +6165,7 @@ List calibration
subCam.defectsDiff=null; subCam.defectsDiff=null;
} }
// non-radial // non-radial
if (imp.getProperty("lensDistortionModel") !=null) subCam.lensDistortionModel= Integer.parseInt((String) imp.getProperty("lensDistortionModel"));
subCam.setDefaultNonRadial(); subCam.setDefaultNonRadial();
for (int i=0;i<subCam.r_xy.length;i++) { 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+"_x") !=null) subCam.r_xy[i][0]= Double.parseDouble((String) imp.getProperty("r_xy_"+i+"_x"));
...@@ -9555,6 +9577,7 @@ M * V = B ...@@ -9555,6 +9577,7 @@ 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));
System.out.println("this.lensDistortionParameters.lensDistortionModel="+this.lensDistortionParameters.lensDistortionModel);
for (int i=0;i<this.lensDistortionParameters.r_xy.length;i++){ 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+"][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)); System.out.println("this.lensDistortionParameters.r_xy["+i+"][1]="+IJ.d2s(this.lensDistortionParameters.r_xy[i][1], 5));
...@@ -9760,6 +9783,7 @@ M * V = B ...@@ -9760,6 +9783,7 @@ M * V = B
if (reCenterVertically){ if (reCenterVertically){
eyesisCameraParameters.recenterVertically(channelMask, stationMask); eyesisCameraParameters.recenterVertically(channelMask, stationMask);
for (int i=0;i<channelMask.length;i++) channelMask[i]= true; for (int i=0;i<channelMask.length;i++) channelMask[i]= true;
parameterMask[distortionCalibrationData.getParameterIndexByName("subcamHeight")] = true;
} }
......
...@@ -29,6 +29,14 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -29,6 +29,14 @@ import org.apache.commons.configuration.XMLConfiguration;
public class EyesisCameraParameters{ public class EyesisCameraParameters{
final public String [] distortionModelDescriptions= {
"Radial model",
"Non radial with shift/elongation, non cummulative",
"Non radial with shift/elongation, cummulative",
"With non-radial polynomial terms"
};
final int [] distortionModels={0,100,101,200};
public int defaultLensDistortionModel=200;
public double [] goniometerHorizontal; // goniometer rotation around "horizontal" axis (tilting from the target - positive) public double [] goniometerHorizontal; // goniometer rotation around "horizontal" axis (tilting from the target - positive)
public double [] goniometerAxial; // goniometer rotation around Eyesis axis (clockwise in plan - positive public double [] goniometerAxial; // goniometer rotation around Eyesis axis (clockwise in plan - positive
public EyesisSubCameraParameters [][] eyesisSubCameras=null; public EyesisSubCameraParameters [][] eyesisSubCameras=null;
...@@ -274,6 +282,13 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -274,6 +282,13 @@ import org.apache.commons.configuration.XMLConfiguration;
} }
public int getNumStations() {return this.numStations;} public int getNumStations() {return this.numStations;}
public int getNumChannels() {
return getNumChannels(0);
}
public int getNumChannels(int numStation) {
return this.eyesisSubCameras[numStation].length;
}
// this.eyesisSubCameras[numStation].length
public EyesisCameraParameters () {} // just create new instance, all parameters data will be provided additionally public EyesisCameraParameters () {} // just create new instance, all parameters data will be provided additionally
public EyesisCameraParameters ( public EyesisCameraParameters (
int numStations, int numStations,
...@@ -685,7 +700,7 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -685,7 +700,7 @@ import org.apache.commons.configuration.XMLConfiguration;
if (numSubCameras>0) { if (numSubCameras>0) {
initSubCameras(numStation, numSubCameras); // set array with default parameters initSubCameras(numStation, numSubCameras); // set array with default parameters
for (int i=0;i<numSubCameras;i++){ for (int i=0;i<numSubCameras;i++){
this.eyesisSubCameras[numStation][i].getProperties(prefix+numStation+"_subCamera_"+i+'.',properties); this.eyesisSubCameras[numStation][i].getProperties(prefix+numStation+"_subCamera_"+i+'.',properties,i);
} }
} }
} }
...@@ -742,6 +757,10 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -742,6 +757,10 @@ import org.apache.commons.configuration.XMLConfiguration;
// public double goniometerHorizontal; // goniometer rotation around "horizontal" axis (tilting from the target - positive) // public double goniometerHorizontal; // goniometer rotation around "horizontal" axis (tilting from the target - positive)
// public double goniometerAxial; // goniometer rotation around Eyesis axis (clockwise in plan - positive // public double goniometerAxial; // goniometer rotation around Eyesis axis (clockwise in plan - positive
//this.isTripod //this.isTripod
String [] modelChoice=new String [distortionModelDescriptions.length+1];
modelChoice[0]="--- keep current ---";
for (int i=0;i<distortionModelDescriptions.length;i++) modelChoice[i+1]=distortionModelDescriptions[i];
gd.addChoice("Change camera distortion model for all channels", modelChoice, modelChoice[0]);
gd.addCheckbox("Tripod mode (first vertical axis, then horizontal), changes meaning of the next 2 fields",this.isTripod); gd.addCheckbox("Tripod mode (first vertical axis, then horizontal), changes meaning of the next 2 fields",this.isTripod);
gd.addMessage("=== Camera parameters to be fitted ==="); gd.addMessage("=== Camera parameters to be fitted ===");
for (int numStation=0;numStation<this.numStations;numStation++) { for (int numStation=0;numStation<this.numStations;numStation++) {
...@@ -801,6 +820,15 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -801,6 +820,15 @@ import org.apache.commons.configuration.XMLConfiguration;
WindowTools.addScrollBars(gd); WindowTools.addScrollBars(gd);
gd.showDialog(); gd.showDialog();
if (gd.wasCanceled()) return -1; if (gd.wasCanceled()) return -1;
int modelIndex=gd.getNextChoiceIndex()-1;
if (modelIndex>=0){
for (EyesisSubCameraParameters [] esps:this.eyesisSubCameras){
for (EyesisSubCameraParameters esp:esps){
esp.lensDistortionModel=distortionModels[modelIndex];
}
}
}
this.isTripod= gd.getNextBoolean(); this.isTripod= gd.getNextBoolean();
for (int numStation=0;numStation<this.numStations;numStation++) { for (int numStation=0;numStation<this.numStations;numStation++) {
if (this.numStations>1){ if (this.numStations>1){
...@@ -861,6 +889,8 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -861,6 +889,8 @@ import org.apache.commons.configuration.XMLConfiguration;
gd.addNumericField("Channel "+numSubCam+" default weight", subCam.channelWeightDefault, 5,8,""); gd.addNumericField("Channel "+numSubCam+" default weight", subCam.channelWeightDefault, 5,8,"");
} }
if (this.numStations>1) gd.addMessage("--- Station number "+numStation+" ---"); if (this.numStations>1) gd.addMessage("--- Station number "+numStation+" ---");
gd.addNumericField("Subcamera lens distortion model", subCam.lensDistortionModel, 5,0,"");
gd.addCheckbox ("Enable matching w/o laser pointers", subCam.enableNoLaser);
gd.addNumericField("Subcamera azimuth", subCam.azimuth, 5,9,"degrees"); gd.addNumericField("Subcamera azimuth", subCam.azimuth, 5,9,"degrees");
gd.addNumericField("Subcamera distance from the axis", subCam.radius, 5,9,"mm"); gd.addNumericField("Subcamera distance from the axis", subCam.radius, 5,9,"mm");
gd.addNumericField("Subcamera height from the 'equator'", subCam.height, 5,9,"mm"); gd.addNumericField("Subcamera height from the 'equator'", subCam.height, 5,9,"mm");
...@@ -930,6 +960,8 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -930,6 +960,8 @@ import org.apache.commons.configuration.XMLConfiguration;
channelWeightDefault=gd.getNextNumber(); channelWeightDefault=gd.getNextNumber();
} }
subCam.channelWeightDefault= channelWeightDefault; // assign to all stations subCam.channelWeightDefault= channelWeightDefault; // assign to all stations
subCam.lensDistortionModel= (int) gd.getNextNumber();
subCam.enableNoLaser = gd.getNextBoolean();
subCam.azimuth= gd.getNextNumber(); subCam.azimuth= gd.getNextNumber();
subCam.radius= gd.getNextNumber(); subCam.radius= gd.getNextNumber();
subCam.height= gd.getNextNumber(); subCam.height= gd.getNextNumber();
...@@ -998,6 +1030,26 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -998,6 +1030,26 @@ import org.apache.commons.configuration.XMLConfiguration;
} }
return true; return true;
} }
public int getLensDistortionModel(int stationNumber,int subCamNumber){
if (
(this.eyesisSubCameras==null) ||
(this.numStations<=stationNumber) ||
(this.eyesisSubCameras.length<=stationNumber) ||
(this.eyesisSubCameras[stationNumber].length<=subCamNumber)) throw new IllegalArgumentException
("Nonexistent subcamera "+subCamNumber+ " and/or station number="+stationNumber+" this.numStations="+this.numStations+" this.eyesisSubCameras.length="+this.eyesisSubCameras.length);
EyesisSubCameraParameters subCam=this.eyesisSubCameras[stationNumber][subCamNumber];
return subCam.lensDistortionModel;
}
boolean getEnableNoLaser(int stationNumber,int subCamNumber){
if (
(this.eyesisSubCameras==null) ||
(this.numStations<=stationNumber) ||
(this.eyesisSubCameras.length<=stationNumber) ||
(this.eyesisSubCameras[stationNumber].length<=subCamNumber)) throw new IllegalArgumentException
("Nonexistent subcamera "+subCamNumber+ " and/or station number="+stationNumber+" this.numStations="+this.numStations+" this.eyesisSubCameras.length="+this.eyesisSubCameras.length);
EyesisSubCameraParameters subCam=this.eyesisSubCameras[stationNumber][subCamNumber];
return subCam.enableNoLaser;
}
/** /**
* *
* @param eyesisCameraParameters current parameters of the Eyesis camera, subcameras and goniometer * @param eyesisCameraParameters current parameters of the Eyesis camera, subcameras and goniometer
...@@ -1191,6 +1243,8 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -1191,6 +1243,8 @@ import org.apache.commons.configuration.XMLConfiguration;
for (int i=0;i<numSubCameras;i++) this.eyesisSubCameras[numStation][i]=null; for (int i=0;i<numSubCameras;i++) this.eyesisSubCameras[numStation][i]=null;
if (numSubCameras==3) { if (numSubCameras==3) {
this.eyesisSubCameras[numStation][0]=new EyesisSubCameraParameters( //TODO: modify for lens adjustment defaults? this.eyesisSubCameras[numStation][0]=new EyesisSubCameraParameters( //TODO: modify for lens adjustment defaults?
defaultLensDistortionModel,
true,
0.0, // double azimuth, // azimuth of the lens entrance pupil center, degrees, clockwise looking from top 0.0, // double azimuth, // azimuth of the lens entrance pupil center, degrees, clockwise looking from top
52.53, // double radius, // mm, distance from the rotation axis 52.53, // double radius, // mm, distance from the rotation axis
34.64, // double height, // mm, up (was downwards) - from the origin point 34.64, // double height, // mm, up (was downwards) - from the origin point
...@@ -1213,6 +1267,8 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -1213,6 +1267,8 @@ import org.apache.commons.configuration.XMLConfiguration;
null, // elongation for c,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?
defaultLensDistortionModel,
true,
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
60.0, // double radius, // mm, distance from the rotation axis 60.0, // double radius, // mm, distance from the rotation axis
-17.32, // double height, // mm, up (was downwards) - from the origin point -17.32, // double height, // mm, up (was downwards) - from the origin point
...@@ -1235,6 +1291,8 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -1235,6 +1291,8 @@ import org.apache.commons.configuration.XMLConfiguration;
null, // elongation for c,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?
defaultLensDistortionModel,
true,
-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
60.0, // double radius, // mm, distance from the rotation axis 60.0, // double radius, // mm, distance from the rotation axis
-17.32, // double height, // mm, up (was downwards) - from the origin point -17.32, // double height, // mm, up (was downwards) - from the origin point
...@@ -1258,6 +1316,8 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -1258,6 +1316,8 @@ import org.apache.commons.configuration.XMLConfiguration;
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?
defaultLensDistortionModel,
true,
0.0, // double azimuth, // azimuth of the lens entrance pupil center, degrees, clockwise looking from top 0.0, // double azimuth, // azimuth of the lens entrance pupil center, degrees, clockwise looking from top
0.0, // double radius, // mm, distance from the rotation axis 0.0, // double radius, // mm, distance from the rotation axis
0.0, // double height, // mm, up (was downwards) - from the origin point 0.0, // double height, // mm, up (was downwards) - from the origin point
...@@ -1282,6 +1342,8 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -1282,6 +1342,8 @@ import org.apache.commons.configuration.XMLConfiguration;
} else { } else {
// default setup for the 26 sub-cameras // default setup for the 26 sub-cameras
for (int i=0;i<8;i++) if (i<numSubCameras) this.eyesisSubCameras[numStation][i]=new EyesisSubCameraParameters( // top 8 cameras for (int i=0;i<8;i++) if (i<numSubCameras) this.eyesisSubCameras[numStation][i]=new EyesisSubCameraParameters( // top 8 cameras
defaultLensDistortionModel,
true,
45.0*i, // double azimuth, // azimuth of the lens entrance pupil center, degrees, clockwise looking from top 45.0*i, // double azimuth, // azimuth of the lens entrance pupil center, degrees, clockwise looking from top
41.540, // double radius, // mm, distance from the rotation axis 41.540, // double radius, // mm, distance from the rotation axis
42.883, // double height, // mm, up (was downwards?) - from the origin point 42.883, // double height, // mm, up (was downwards?) - from the origin point
...@@ -1304,6 +1366,8 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -1304,6 +1366,8 @@ import org.apache.commons.configuration.XMLConfiguration;
null, // elongation for c,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
defaultLensDistortionModel,
true,
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
54.525, // double radius, // mm, distance from the rotation axis 54.525, // double radius, // mm, distance from the rotation axis
0.0, // double height, // mm, up (was downwards) - from the origin point 0.0, // double height, // mm, up (was downwards) - from the origin point
...@@ -1326,6 +1390,8 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -1326,6 +1390,8 @@ import org.apache.commons.configuration.XMLConfiguration;
null, // elongation for c,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
defaultLensDistortionModel,
true,
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
41.540, // double radius, // mm, distance from the rotation axis 41.540, // double radius, // mm, distance from the rotation axis
-42.883, // double height, // mm, up (was downwards?) - from the origin point -42.883, // double height, // mm, up (was downwards?) - from the origin point
...@@ -1348,6 +1414,8 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -1348,6 +1414,8 @@ import org.apache.commons.configuration.XMLConfiguration;
null, // elongation for c,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(
defaultLensDistortionModel,
false,
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
12.025, // double radius, // mm, distance from the rotation axis 12.025, // double radius, // mm, distance from the rotation axis
-807.0, // double height, // mm, up - from the origin point -807.0, // double height, // mm, up - from the origin point
...@@ -1370,6 +1438,8 @@ import org.apache.commons.configuration.XMLConfiguration; ...@@ -1370,6 +1438,8 @@ import org.apache.commons.configuration.XMLConfiguration;
null, // elongation for c,b,a,a5,a6,a7,a8 null, // elongation for c,b,a,a5,a6,a7,a8
8.0); //channelWeightDefault (was 4) 8.0); //channelWeightDefault (was 4)
if (25<numSubCameras) this.eyesisSubCameras[numStation][25]=new EyesisSubCameraParameters( if (25<numSubCameras) this.eyesisSubCameras[numStation][25]=new EyesisSubCameraParameters(
defaultLensDistortionModel,
false,
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
12.025, // double radius, // mm, distance from the rotation axis 12.025, // double radius, // mm, distance from the rotation axis
-841.0, // double height, // mm, up - from the origin point -841.0, // double height, // mm, up - from the origin point
......
...@@ -25,6 +25,8 @@ import java.util.Properties; ...@@ -25,6 +25,8 @@ import java.util.Properties;
public class EyesisSubCameraParameters{ public class EyesisSubCameraParameters{
// origin is on the rotation axis of the tube body closest to the goniometer horizontal axis // origin is on the rotation axis of the tube body closest to the goniometer horizontal axis
public int lensDistortionModel=0;
public boolean enableNoLaser=true; // enable images for this channel w/o matched laser pointer
public double azimuth; // azimuth of the lens entrance pupil center, degrees, clockwise looking from top public double azimuth; // azimuth of the lens entrance pupil center, degrees, clockwise looking from top
public double radius; // mm, distance from the rotation axis public double radius; // mm, distance from the rotation axis
public double height; // mm, up - from the origin point public double height; // mm, up - from the origin point
...@@ -66,6 +68,8 @@ import java.util.Properties; ...@@ -66,6 +68,8 @@ import java.util.Properties;
*/ */
public EyesisSubCameraParameters( public EyesisSubCameraParameters(
int lensDistortionModel,
boolean enableNoLaser,
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
double height, // mm, up from the origin point double height, // mm, up from the origin point
...@@ -88,6 +92,8 @@ import java.util.Properties; ...@@ -88,6 +92,8 @@ import java.util.Properties;
double [][] r_od, // elongation for c,b,a,a5,a6,a7,a8 double [][] r_od, // elongation for c,b,a,a5,a6,a7,a8
double channelWeightDefault double channelWeightDefault
){ ){
this.lensDistortionModel=lensDistortionModel;
this.enableNoLaser=enableNoLaser;
this.azimuth=azimuth; this.azimuth=azimuth;
this.radius=radius; this.radius=radius;
this.height=height; this.height=height;
...@@ -121,6 +127,8 @@ import java.util.Properties; ...@@ -121,6 +127,8 @@ import java.util.Properties;
// defects are not cloned! // defects are not cloned!
public EyesisSubCameraParameters clone() { public EyesisSubCameraParameters clone() {
return new EyesisSubCameraParameters( return new EyesisSubCameraParameters(
this.lensDistortionModel,
this.enableNoLaser,
this.azimuth, this.azimuth,
this.radius, this.radius,
this.height, this.height,
...@@ -152,6 +160,8 @@ import java.util.Properties; ...@@ -152,6 +160,8 @@ import java.util.Properties;
} }
// TODO: add/restore new properties // TODO: add/restore new properties
public void setProperties(String prefix,Properties properties){ public void setProperties(String prefix,Properties properties){
properties.setProperty(prefix+"lensDistortionModel",this.lensDistortionModel+"");
properties.setProperty(prefix+"enableNoLaser",this.enableNoLaser+"");
properties.setProperty(prefix+"azimuth",this.azimuth+""); properties.setProperty(prefix+"azimuth",this.azimuth+"");
properties.setProperty(prefix+"radius",this.radius+""); properties.setProperty(prefix+"radius",this.radius+"");
properties.setProperty(prefix+"height",this.height+""); properties.setProperty(prefix+"height",this.height+"");
...@@ -181,6 +191,11 @@ import java.util.Properties; ...@@ -181,6 +191,11 @@ import java.util.Properties;
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){
getProperties(prefix,properties, -1);
}
public void getProperties(String prefix,Properties properties, int channel){
if (properties.getProperty(prefix+"lensDistortionModel")!=null)
this.lensDistortionModel=Integer.parseInt(properties.getProperty(prefix+"lensDistortionModel"));
if (properties.getProperty(prefix+"azimuth")!=null) if (properties.getProperty(prefix+"azimuth")!=null)
this.azimuth=Double.parseDouble(properties.getProperty(prefix+"azimuth")); this.azimuth=Double.parseDouble(properties.getProperty(prefix+"azimuth"));
if (properties.getProperty(prefix+"radius")!=null) if (properties.getProperty(prefix+"radius")!=null)
...@@ -231,6 +246,13 @@ import java.util.Properties; ...@@ -231,6 +246,13 @@ import java.util.Properties;
this.channelWeightDefault=Double.parseDouble(properties.getProperty(prefix+"channelWeightDefault")); this.channelWeightDefault=Double.parseDouble(properties.getProperty(prefix+"channelWeightDefault"));
this.channelWeightCurrent=this.channelWeightDefault; this.channelWeightCurrent=this.channelWeightDefault;
} }
// /enableNoLaser
if (properties.getProperty(prefix+"enableNoLaser")!=null) {
this.enableNoLaser=Boolean.parseBoolean(properties.getProperty(prefix+"enableNoLaser"));
} else {
this.enableNoLaser=(channel<24);
}
} }
public void setChannelWeightCurrent( public void setChannelWeightCurrent(
double weight){ double weight){
......
...@@ -30,7 +30,12 @@ import java.io.File; ...@@ -30,7 +30,12 @@ import java.io.File;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.XMLConfiguration; import org.apache.commons.configuration.XMLConfiguration;
...@@ -1394,6 +1399,448 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit ...@@ -1394,6 +1399,448 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
for (int i=0;i<this.parameterList.length;i++) if ((this.parameterList[i][0]==nSub) && (this.parameterList[i][1]==index)) return i; for (int i=0;i<this.parameterList.length;i++) if ((this.parameterList[i][0]==nSub) && (this.parameterList[i][1]==index)) return i;
return -1; return -1;
} }
private int [] arrayToSortedInt(int [] srcArray){
Set<Integer> set = new HashSet<Integer>();
for (Integer data:srcArray) set.add(data);
int [] array = new int [set.size()];
int i=0;
for (Integer val:set) array[i++]= val;
Arrays.sort(array);
return array;
}
public boolean selectIndividualImages(
boolean [] selection,
boolean allImages,
int startIndex,
int perPage){
boolean [] enabled= this.distortionCalibrationData.selectEnabled();
int [] hintedMatch=this.distortionCalibrationData.getHintedMatch();
if (selection.length!=enabled.length){
System.out.println("BUG: selectIndividualImages(): selection.length!=enabled.length!");
return false;
}
int endIndex=startIndex;
int numImg=0;
for (endIndex=startIndex; (endIndex<enabled.length) && (numImg<perPage);endIndex++) if (allImages || enabled[endIndex]) numImg++;
for (;(endIndex<enabled.length) && !allImages && !enabled[endIndex];endIndex++); // advance over disabled images
GenericDialog gd=new GenericDialog("Select images "+startIndex+"..."+(endIndex-1));
for (int i=startIndex;i<endIndex;i++) if (allImages || enabled[i]){
gd.addCheckbox (i+" - "+(this.distortionCalibrationData.gIP[i].enabled?"":"(disabled) ")+
IJ.d2s(this.distortionCalibrationData.gIP[i].timestamp,6)+
": "+this.distortionCalibrationData.gIP[i].channel+
" matched "+this.distortionCalibrationData.gIP[i].matchedPointers+" pointers"+
", hinted state: "+((hintedMatch[i]<0)?"undefined":((hintedMatch[i]==0)?"failed":((hintedMatch[i]==1)?"orientation":"orientation and translation"))),
selection[i]);
}
if (endIndex<enabled.length){
gd.enableYesNoCancel("Done", "Next");
}
WindowTools.addScrollBars(gd);
gd.showDialog();
if (gd.wasCanceled()) return false;
for (int i=startIndex;i<endIndex;i++) if (allImages || enabled[i]){
selection[i]=gd.getNextBoolean();
}
if (gd.wasOKed()) return true;
return selectIndividualImages(
selection,
allImages,
endIndex,
perPage);
}
public boolean selectImageSets(
boolean [] selection,
boolean allImages,
int startIndex,
int perPage){
boolean [] enabled= this.distortionCalibrationData.selectEnabled();
int [] imageStations=this.distortionCalibrationData.getStations();
int [] imageChannels=this.distortionCalibrationData.getChannels();
if (selection.length!=enabled.length){
System.out.println("BUG: selectIndividualImages(): selection.length!=enabled.length!");
return false;
}
int [][] imageSets=this.distortionCalibrationData.listImages(!allImages); // true - only enabled images
boolean [] enabledSets=new boolean [imageSets.length];
boolean [] selectedSets=new boolean [imageSets.length]; // at least one image selected in the series
for (int i=0;i<imageSets.length;i++){
enabledSets[i]=false;
selectedSets[i]=false;
if (imageSets[i]!=null) for (int j=0;j<imageSets[i].length;j++){
enabledSets[i] |= enabled[imageSets[i][j]];
selectedSets[i] |= selection[imageSets[i][j]];
}
}
int endIndex=startIndex;
int numSet=0;
for (endIndex=startIndex; (endIndex<enabledSets.length) && (numSet<perPage);endIndex++) if (enabledSets[endIndex]) numSet++;
for (;(endIndex<enabledSets.length) && !enabledSets[endIndex];endIndex++); // advance over disabled sets
GenericDialog gd=new GenericDialog("Select image Sets "+startIndex+"..."+(endIndex-1));
for (int i=startIndex;i<endIndex;i++) if (enabledSets[i]){
int station=-1;
String sImgList="";
int l=0;
for (int j=0;j<imageSets[i].length;j++) if (enabled[imageSets[i][j]]) {
station=imageStations[imageSets[i][j]];
int channel=imageChannels[imageSets[i][j]];
if (l > 0) sImgList+=", ";
sImgList+=imageSets[i][j]+" ["+channel+"] ";
l++;
}
gd.addCheckbox (i+" ("+sImgList+") === Station_"+(station+1), selectedSets[i]);
}
if (endIndex<enabledSets.length){
gd.enableYesNoCancel("Done", "Next");
}
WindowTools.addScrollBars(gd);
gd.showDialog();
if (gd.wasCanceled()) return false;
// Arrays.fill(selection, false);
for (int i=startIndex;i<endIndex;i++) if (enabledSets[i]){
selectedSets[i]=gd.getNextBoolean();
for (int j=0;j<imageSets[i].length;j++) {
selection[imageSets[i][j]]=selectedSets[i];
}
}
if (gd.wasOKed()) return true;
return selectImageSets(
selection,
allImages,
endIndex,
perPage);
}
/**
* Manage image selection for the current series
* @param numSeries series number to manage
* @return -1 - cancel, 0 - repeat again, 1 - Done,
*/
public int manageSelection(
int numSeries){
// String [] firstOperand= {"Current","Inverted current","None","All"};
// String [] SecondOperand={"Selection","Inverted selection","None","All"};
// String [] operation={"And","Or"};
String [] actions={
"Replace current with new selection",
"Add selection to current",
"Add inverted selection to current",
"And selection with current",
"Remove selection from current",
"Invert current selection, disregard other settings"};
String [] selectionType={
"Select from all enabled images", // 0
"Select from new enabled images", // 1
"Select from images with estimated orientation", // 2
"Individual images, start from empty selection", // 3
"Individual images, start from current selection",// 4
"Image sets, start from empty selection", // 5
"Image sets, start from current selection" // 6
};
int numStations=this.distortionCalibrationData.eyesisCameraParameters.getNumStations();
int numChannels=this.distortionCalibrationData.eyesisCameraParameters.getNumChannels(0); // for station 0
boolean [] selected= this.selectedImages[numSeries];
boolean [] enabled= this.distortionCalibrationData.selectEnabled();
boolean [] newEnabled= this.distortionCalibrationData.selectNewEnabled ();
boolean [] estimated= this.distortionCalibrationData.selectEstimated(true); //boolean enabledOnly);
boolean [] estimatedAll= this.distortionCalibrationData.selectEstimated(false); //boolean enabledOnly);
if (selected.length!=enabled.length){
System.out.println("WARNING: manageSelection(): lengths (strategy and images) mismatch selected.length="+selected.length+" available images: "+enabled.length);
boolean [] newSelection=new boolean[enabled.length];
for (int i=0;i<newSelection.length;i++) newSelection[i]=(i<enabled.length)?enabled[i]:false;
selected=newSelection;
this.selectedImages[numSeries]=selected;
}
int numSelected=0;
int [] numSelectedPerStation=new int [numStations];
Arrays.fill(numSelectedPerStation, 0);
int numEnabled = 0; // this.distortionCalibrationData.getNumEnabled();
int [] numEnabledPerStation=new int [numStations];
Arrays.fill(numEnabledPerStation, 0);
int [] totalPerStation=new int [numStations];
Arrays.fill(totalPerStation, 0);
int [] imageStations=this.distortionCalibrationData.getStations();
int [] imageChannels=this.distortionCalibrationData.getChannels();
int numNewEnabled=0;
int [] numNewEnabledPerStation=new int [numStations];
Arrays.fill(numNewEnabledPerStation, 0);
int numNewEnabledSelected=0;
int [] numNewEnabledSelectedPerStation=new int [numStations];
Arrays.fill(numNewEnabledSelectedPerStation, 0);
int numEstimatedSelected=0;
int [] numEstimatedSelectedPerStation=new int [numStations];
Arrays.fill(numEstimatedSelectedPerStation, 0);
int numEstimated=0;
int [] numEstimatedPerStation=new int [numStations];
Arrays.fill(numEstimatedPerStation, 0);
int numEstimatedAll=0;
int [] numEstimatedAllPerStation=new int [numStations];
Arrays.fill(numEstimatedAllPerStation, 0);
int [] matchedPointers=this.distortionCalibrationData.getMatchedPointers();
int [] matchedPointersIndex=arrayToSortedInt(matchedPointers);
int [] hintedMatch=this.distortionCalibrationData.getHintedMatch();
int [] hintedMatchIndex=arrayToSortedInt(hintedMatch);
Map <Integer,Integer> mapMP=new HashMap<Integer,Integer>();
Map <Integer,Integer> mapHM=new HashMap<Integer,Integer>();
for (Integer index=0;index<matchedPointersIndex.length;index++) mapMP.put(new Integer(matchedPointersIndex[index]),index);
for (Integer index=0;index<hintedMatchIndex.length;index++) mapHM.put(new Integer(hintedMatchIndex[index]),index);
int [] numMatchedPointers= new int [matchedPointersIndex.length];
int [] numMatchedPointersSelected=new int [matchedPointersIndex.length];
int [] numMatchedPointersEnabled= new int [matchedPointersIndex.length];
int [][] numMatchedPointersPerStation= new int [matchedPointersIndex.length][];
int [][] numMatchedPointersSelectedPerStation=new int [matchedPointersIndex.length][];
int [][] numMatchedPointersEnabledPerStation= new int [matchedPointersIndex.length][];
for (int n=0;n<numMatchedPointers.length;n++){
numMatchedPointers[n]=0;
numMatchedPointersSelected[n]=0;
numMatchedPointersEnabled[n]=0;
numMatchedPointersPerStation[n]=new int [numStations];
numMatchedPointersSelectedPerStation[n]=new int [numStations];
numMatchedPointersEnabledPerStation[n]=new int [numStations];
Arrays.fill(numMatchedPointersPerStation[n], 0);
Arrays.fill(numMatchedPointersSelectedPerStation[n], 0);
Arrays.fill(numMatchedPointersEnabledPerStation[n], 0);
}
int [] numHintedMatch= new int [matchedPointersIndex.length];
int [] numHintedMatchSelected=new int [matchedPointersIndex.length];
int [] numHintedMatchEnabled= new int [matchedPointersIndex.length];
int [][] numHintedMatchPerStation= new int [matchedPointersIndex.length][];
int [][] numHintedMatchSelectedPerStation=new int [matchedPointersIndex.length][];
int [][] numHintedMatchEnabledPerStation= new int [matchedPointersIndex.length][];
for (int n=0;n<numHintedMatch.length;n++){
numHintedMatch[n]=0;
numHintedMatchSelected[n]=0;
numHintedMatchEnabled[n]=0;
numHintedMatchPerStation[n]=new int [numStations];
numHintedMatchSelectedPerStation[n]=new int [numStations];
numHintedMatchEnabledPerStation[n]=new int [numStations];
Arrays.fill(numHintedMatchPerStation[n], 0);
Arrays.fill(numHintedMatchSelectedPerStation[n], 0);
Arrays.fill(numHintedMatchEnabledPerStation[n], 0);
}
for (int i=0;i<selected.length;i++) if (imageStations[i]>=0){
int mpi=mapMP.get(new Integer(matchedPointers[i]));
int hmi=mapHM.get(new Integer(hintedMatch[i]));
if (enabled[i]) {
numEnabledPerStation[imageStations[i]]++;
numEnabled++;
if (selected[i]) {
numSelectedPerStation[imageStations[i]]++;
numSelected++;
numMatchedPointersSelectedPerStation[mpi][imageStations[i]]++;
numMatchedPointersSelected[mpi]++;
numHintedMatchSelectedPerStation[hmi][imageStations[i]]++;
numHintedMatchSelected[hmi]++;
}
if (newEnabled[i]){
numNewEnabledPerStation[imageStations[i]]++;
numNewEnabled++;
if (selected[i]) {
numNewEnabledSelectedPerStation[imageStations[i]]++;
numNewEnabledSelected++;
}
}
if (estimated[i]){
numEstimatedPerStation[imageStations[i]]++;
numEstimated++;
if (selected[i]) {
numEstimatedSelectedPerStation[imageStations[i]]++;
numEstimatedSelected++;
}
}
numMatchedPointersEnabledPerStation[mpi][imageStations[i]]++;
numMatchedPointersEnabled[mpi]++;
numHintedMatchEnabledPerStation[hmi][imageStations[i]]++;
numHintedMatchEnabled[hmi]++;
}
if (estimatedAll[i]){
numEstimatedAllPerStation[imageStations[i]]++;
numEstimatedAll++;
}
numMatchedPointersPerStation[mpi][imageStations[i]]++;
numMatchedPointers[mpi]++;
numHintedMatchPerStation[hmi][imageStations[i]]++;
numHintedMatch[hmi]++;
totalPerStation[imageStations[i]]++;
}
String sAvailable="["+numSelected+"/"+numEnabled+"/"+selected.length+"] ";
String sNewEnabled="["+numNewEnabledSelected+"/"+numNewEnabled+"] ";
String sEstimated="["+numEstimatedSelected+"/"+numEstimated+"/"+numEstimatedAll+"] ";
String [] sMatchedPointers=new String [matchedPointersIndex.length];
String [] sHintedMatch=new String [hintedMatchIndex.length];
for (int n=0;n<sMatchedPointers.length;n++){
sMatchedPointers[n]="["+numMatchedPointersSelected[n]+"/"+numMatchedPointersEnabled[n]+"/"+numMatchedPointers[n]+"] ";
}
for (int n=0;n<sHintedMatch.length;n++){
sHintedMatch[n]="["+numHintedMatchSelected[n]+" / "+numHintedMatchEnabled[n]+" / "+numHintedMatch[n]+"] ";
}
if (numStations>1) for (int i=0;i<numStations;i++) {
sAvailable+= " station_"+(i+1)+": ["+numSelectedPerStation[i]+" / "+numEnabledPerStation[i]+" / "+totalPerStation[i]+"]";
sNewEnabled+=" station_"+(i+1)+": ["+numNewEnabledSelectedPerStation[i]+" / "+numNewEnabledPerStation[i]+"]";
sEstimated+=" station_"+(i+1)+": ["+numEstimatedSelectedPerStation[i]+" / "+numEstimatedPerStation[i]+" / "+numEstimatedAllPerStation[i]+"]";
for (int n=0;n<sMatchedPointers.length;n++){
sMatchedPointers[n]+=" station_"+(i+1)+": ["+numMatchedPointersSelectedPerStation[n][i]+" / "+
numMatchedPointersEnabledPerStation[n][i]+" / "+numMatchedPointersPerStation[n][i]+"]";
}
for (int n=0;n<sHintedMatch.length;n++){
sHintedMatch[n]+=" station_"+(i+1)+": ["+numHintedMatchSelectedPerStation[n][i]+" / "+
numHintedMatchEnabledPerStation[n][i]+" / "+numHintedMatchPerStation[n][i]+"]";
}
}
int operIndex=0,selectionTypeIndex=0;
// boolean selectEstimated=false;
// boolean selectNewEnabled=false;
boolean [] requiredMatchedPointers=new boolean [matchedPointersIndex.length];
boolean [] requiredHintedMatch=new boolean [hintedMatchIndex.length];
boolean [] requiredStations=new boolean [numStations];
boolean [] requiredChannels=new boolean [numChannels];
Arrays.fill(requiredMatchedPointers,true);
Arrays.fill(requiredHintedMatch,true);
Arrays.fill(requiredStations,true);
Arrays.fill(requiredChannels,true);
selectionType[0]+=" ("+numEnabled+")";
selectionType[1]+=" ("+numNewEnabled+")";
selectionType[2]+=" ("+numEstimated+")";
if (this.debugLevel>0){
System.out.println("Image statistics for series "+numSeries+": [currently selected/enabled/total]");
System.out.println("Grid images:"+sAvailable);
System.out.println("New enabled images: "+sNewEnabled);
System.out.println("Estimated orientation: "+sEstimated);
for (int n=0;n<sMatchedPointers.length;n++) System.out.println("Images with "+matchedPointersIndex[n]+" pointers: "+sMatchedPointers[n]);
for (int n=0;n<sHintedMatch.length;n++) System.out.println("Images with hinted match state=\""+hintedMatchIndex[n]+"\": "+sHintedMatch[n]);
System.out.println();
}
GenericDialog gd=new GenericDialog("Manage image selection for series "+numSeries);
gd.addMessage("Image statistics: [currently selected/enabled/total]");
gd.addMessage("Grid images:"+sAvailable);
gd.addMessage("New enabled images: "+sNewEnabled);
gd.addMessage("Estimated orientation: "+sEstimated);
for (int n=0;n<sMatchedPointers.length;n++) gd.addMessage("Images with "+matchedPointersIndex[n]+" pointers: "+sMatchedPointers[n]);
for (int n=0;n<sHintedMatch.length;n++) gd.addMessage("Images with hinted match state=\""+hintedMatchIndex[n]+"\": "+sHintedMatch[n]);
gd.addChoice("Operation on selection", actions, actions[operIndex]);
gd.addChoice("Selection type", selectionType, selectionType[selectionTypeIndex]);
//selectionType
// gd.addCheckbox("Select images with estimated orientation", selectEstimated);
// gd.addCheckbox("Select new enabled images", selectNewEnabled);
gd.addMessage("=== Filter selection by the number of matched laser pointers ===");
for (int i=0;i<matchedPointersIndex.length;i++){
gd.addCheckbox("Select images with "+matchedPointersIndex[i]+" pointers", requiredMatchedPointers[i]);
}
gd.addMessage("=== Filter selection by the hinted match state (-1 - none, 1 - orientation, 2 - position and orientation) ===");
for (int i=0;i<hintedMatchIndex.length;i++){
gd.addCheckbox("Select images hintedMatch="+hintedMatchIndex[i], requiredHintedMatch[i]);
}
gd.addMessage("=== Limit selection by the station ===");
for (int i=0;i<requiredStations.length;i++){
gd.addCheckbox("Select station "+(i+1), requiredStations[i]);
}
gd.addMessage("=== Limit selection by the channel ===");
for (int i=0;i<requiredChannels.length;i++){
gd.addCheckbox("Select channel "+i, requiredChannels[i]);
}
gd.enableYesNoCancel("OK", "More");
WindowTools.addScrollBars(gd);
gd.showDialog();
if (gd.wasCanceled()) return -1;
boolean more=!gd.wasOKed();
operIndex=gd.getNextChoiceIndex();
selectionTypeIndex=gd.getNextChoiceIndex(); // TODO:Implement!
// selectEstimated=gd.getNextBoolean();
// selectNewEnabled=gd.getNextBoolean();
for (int i=0;i<matchedPointersIndex.length;i++) requiredMatchedPointers[i]=gd.getNextBoolean();
for (int i=0;i<hintedMatchIndex.length;i++) requiredHintedMatch[i]= gd.getNextBoolean();
for (int i=0;i<requiredStations.length;i++) requiredStations[i]=gd.getNextBoolean();
for (int i=0;i<requiredChannels.length;i++) requiredChannels[i]=gd.getNextBoolean();
boolean [] selection=new boolean [enabled.length];
Arrays.fill(selection,false);
switch (selectionTypeIndex){
case 0:
selection=enabled.clone();
break;
case 1:
selection=newEnabled.clone();
break;
case 2:
selection=estimated.clone();
break;
case 4: // start from current selection
selection=selected.clone();
case 3: // start from empty selection
if (!selectIndividualImages(
selection,
false, // allImages,
0, // star iIndex
500)) return -1; //perPage))
case 6: // start from current selection
selection=selected.clone();
case 5: // start from empty selection
if (!selectImageSets(
selection,
false, // allImages,
0, // star iIndex
500)) return -1; //perPage))
}
for (int i=0;i<selection.length;i++) selection[i] &= requiredMatchedPointers[mapMP.get(new Integer(matchedPointers[i]))];
for (int i=0;i<selection.length;i++) selection[i] &= requiredHintedMatch[mapHM.get(new Integer(hintedMatch[i]))];
for (int i=0;i<selection.length;i++) if (imageStations[i]>=0) selection[i] &= requiredStations[imageStations[i]];
else selection[i] = false;
for (int i=0;i<selection.length;i++) if (imageChannels[i]>=0) selection[i] &= requiredChannels[imageChannels[i]];
else selection[i] = false;
// now combine new/old selections
switch (operIndex){
case 0: // keep new selection
break;
case 1:
for (int i=0;i<selection.length;i++) selection[i] |= selected[i]; // OR
break;
case 2:
for (int i=0;i<selection.length;i++) selection[i] = selected[i] | !selection[i]; // OR-NOT
break;
case 3:
for (int i=0;i<selection.length;i++) selection[i] = selected[i] && selection[i]; // AND
break;
case 4:
for (int i=0;i<selection.length;i++) selection[i] = selected[i] && !selection[i]; // AND-NOT
break;
case 5:
for (int i=0;i<selection.length;i++) selection[i]= !selected[i];
break;
}
// Remove disabled
for (int i=0;i<selection.length;i++) selection[i] &= enabled[i];
// replace current selection
this.selectedImages[numSeries]=selection;
return more?0:1;
}
/** /**
* *
...@@ -1402,7 +1849,7 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit ...@@ -1402,7 +1849,7 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
* @param fromToImages - limit number of checkboxes, otherwise window does not show the bottom ones * @param fromToImages - limit number of checkboxes, otherwise window does not show the bottom ones
* @param useParameters Select parameters for this series * @param useParameters Select parameters for this series
* @param askNextSeries Ask for next series number * @param askNextSeries Ask for next series number
* @param zeroAndOther use 2 channels 0 and "other", propagete settings for channel 1 to all the rest * @param zeroAndOther use 2 channels 0 and "other", propagate settings for channel 1 to all the rest
* @return -2 - cancel, -1, done, otherwise - number of step to edit * @return -2 - cancel, -1, done, otherwise - number of step to edit
*/ */
public int selectStrategyStep( public int selectStrategyStep(
...@@ -1417,6 +1864,7 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit ...@@ -1417,6 +1864,7 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
){ ){
boolean showDirectMap=false; boolean showDirectMap=false;
boolean showReverseMap=false; boolean showReverseMap=false;
boolean showAdvancedImageSelection=false;
// if current series is not valid (probably just started a new one) - look for the last valid (if any) // if current series is not valid (probably just started a new one) - look for the last valid (if any)
// and copy it; // and copy it;
int numEstimated=this.distortionCalibrationData.getNumberOfEstimated(true); //(boolean enabledOnly int numEstimated=this.distortionCalibrationData.getNumberOfEstimated(true); //(boolean enabledOnly
...@@ -1439,6 +1887,7 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit ...@@ -1439,6 +1887,7 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
} }
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("Advanced image selection (disregard other fields)", showAdvancedImageSelection);
gd.addCheckbox("Copy all from the series below, 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.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
...@@ -1465,8 +1914,8 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit ...@@ -1465,8 +1914,8 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
} }
if (useImages) { if (useImages) {
gd.addNumericField("Image sepection range, from", fromToImages[0], 0); gd.addNumericField("Image selection range, from", fromToImages[0], 0);
gd.addNumericField("Image sepection range, up to (inclufing)", fromToImages[1], 0); gd.addNumericField("Image selection range, up to (including)", fromToImages[1], 0);
gd.addMessage("Select files to include"); gd.addMessage("Select files to include");
for (int i =0; i<this.distortionCalibrationData.getNumImages();i++) for (int i =0; i<this.distortionCalibrationData.getNumImages();i++)
if ((allImages || this.distortionCalibrationData.gIP[i].enabled) && (i>=fromToImages[0]) && (i<=fromToImages[1])){ if ((allImages || this.distortionCalibrationData.gIP[i].enabled) && (i>=fromToImages[0]) && (i<=fromToImages[1])){
...@@ -1580,6 +2029,12 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit ...@@ -1580,6 +2029,12 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
WindowTools.addScrollBars(gd); WindowTools.addScrollBars(gd);
gd.showDialog(); gd.showDialog();
if (gd.wasCanceled()) return -2; if (gd.wasCanceled()) return -2;
showAdvancedImageSelection=gd.getNextBoolean();
if (showAdvancedImageSelection){
int rslt=0;
while (rslt==0) rslt=manageSelection(numSeries);
return (rslt<0)?-2:numSeries;
}
boolean copyFromPrevious=gd.getNextBoolean(); boolean copyFromPrevious=gd.getNextBoolean();
int sourceStrategy= (int) gd.getNextNumber(); int sourceStrategy= (int) gd.getNextNumber();
boolean removeAllImages=gd.getNextBoolean(); boolean removeAllImages=gd.getNextBoolean();
...@@ -1822,7 +2277,7 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit ...@@ -1822,7 +2277,7 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
// gd.addNumericField("Number of series in this strategy", (oldLength>0)?oldLength:1, 0); // // gd.addNumericField("Number of series in this strategy", (oldLength>0)?oldLength:1, 0); //
gd.addCheckbox ("Select images",selectImages); gd.addCheckbox ("Select images",selectImages);
gd.addNumericField("Show image checkboxes from", fromToImages[0], 0); gd.addNumericField("Show image checkboxes from", fromToImages[0], 0);
gd.addNumericField("Show image checkboxes up to (inclufing)", fromToImages[1], 0); gd.addNumericField("Show image checkboxes up to (including)", fromToImages[1], 0);
gd.addCheckbox ("Select from all images (false - only enabled)",allImages); gd.addCheckbox ("Select from all images (false - only enabled)",allImages);
gd.addCheckbox ("Select parameters",selectParameters); gd.addCheckbox ("Select parameters",selectParameters);
gd.addCheckbox ("Ask for initial lambda",askLambdas); gd.addCheckbox ("Ask for initial lambda",askLambdas);
......
...@@ -22,6 +22,9 @@ import Jama.Matrix; ...@@ -22,6 +22,9 @@ import Jama.Matrix;
final int numOutputs=42; //16; // with A8...//13; // parameters in a single camera final int numOutputs=42; //16; // with A8...//13; // parameters in a single camera
// final // final
// boolean cummulativeCorrection=true; // r_xy, r_od for higher terms are relative to lower ones // boolean cummulativeCorrection=true; // r_xy, r_od for higher terms are relative to lower ones
public int defaultLensDistortionModel=200;
public int lensDistortionModel=defaultLensDistortionModel;
public int lensDistortionModelType=0; // set from lensDistortionModel
boolean cummulativeCorrection=false; //true; // r_xy, r_od for higher terms are relative to lower ones boolean cummulativeCorrection=false; //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
...@@ -73,7 +76,22 @@ import Jama.Matrix; ...@@ -73,7 +76,22 @@ import Jama.Matrix;
// 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)
public void setDistortionModelParameters(){
if (lensDistortionModel<0){
System.out.println("BUG:setDistortionModelParameters() - lensDistortionModel<0");
lensDistortionModel=defaultLensDistortionModel;
}
this.cummulativeCorrection= (lensDistortionModel==101);
if (lensDistortionModel<100){
lensDistortionModelType=0;
} else if (lensDistortionModel<200){
lensDistortionModelType=1;
} else if (lensDistortionModel<300){
lensDistortionModelType=2;
} else {
lensDistortionModelType=0;
}
}
public LensDistortionParameters( public LensDistortionParameters(
// LensDistortionParameters lensDistortionParameters, // LensDistortionParameters lensDistortionParameters,
boolean isTripod, boolean isTripod,
...@@ -116,6 +134,7 @@ import Jama.Matrix; ...@@ -116,6 +134,7 @@ import Jama.Matrix;
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)
int lensDistortionModel,
double [][] r_xy, double [][] r_xy,
double [][] r_od double [][] r_od
){ ){
...@@ -140,6 +159,7 @@ import Jama.Matrix; ...@@ -140,6 +159,7 @@ import Jama.Matrix;
px0, px0,
py0, py0,
flipVertical, flipVertical,
lensDistortionModel,
r_xy, r_xy,
r_od); r_od);
} }
...@@ -166,6 +186,7 @@ import Jama.Matrix; ...@@ -166,6 +186,7 @@ import Jama.Matrix;
1296, // px0, 1296, // px0,
698, // py0, 698, // py0,
true, // flipVertical, true, // flipVertical,
-1, // lensDistortionModel
null, // r_xy, null, // r_xy,
null // r_od, null // r_od,
); );
...@@ -192,6 +213,7 @@ import Jama.Matrix; ...@@ -192,6 +213,7 @@ import Jama.Matrix;
this.px0, this.px0,
this.py0, this.py0,
this.flipVertical, this.flipVertical,
this.lensDistortionModel,
this.r_xy, this.r_xy,
this.r_od this.r_od
); );
...@@ -218,6 +240,7 @@ import Jama.Matrix; ...@@ -218,6 +240,7 @@ import Jama.Matrix;
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)
int lensDistortionModel,
double [][] r_xy, // per polynomial term center x,y correction only 6, as for the first term delta x, delta y ==0 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 double [][] r_od // per polynomial term orthogonal+diagonal elongation
){ ){
...@@ -241,6 +264,7 @@ import Jama.Matrix; ...@@ -241,6 +264,7 @@ import Jama.Matrix;
this.px0=px0; this.px0=px0;
this.py0=py0; this.py0=py0;
this.flipVertical=flipVertical; this.flipVertical=flipVertical;
this.lensDistortionModel=(lensDistortionModel>=0)?lensDistortionModel:defaultLensDistortionModel;
if (r_xy==null) r_xy=r_xy_dflt; if (r_xy==null) r_xy=r_xy_dflt;
if (r_od==null) r_od=r_od_dflt; if (r_od==null) r_od=r_od_dflt;
this.r_xy=new double [r_xy.length][2]; this.r_xy=new double [r_xy.length][2];
...@@ -273,6 +297,7 @@ import Jama.Matrix; ...@@ -273,6 +297,7 @@ import Jama.Matrix;
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.lensDistortionModel,
pars.r_xy, // do not exist yet! pars.r_xy, // do not exist yet!
pars.r_od // do not exist yet! pars.r_od // do not exist yet!
); );
...@@ -301,6 +326,7 @@ import Jama.Matrix; ...@@ -301,6 +326,7 @@ import Jama.Matrix;
ldp.px0, ldp.px0,
ldp.py0, ldp.py0,
ldp.flipVertical, ldp.flipVertical,
ldp.lensDistortionModel,
ldp.r_xy, ldp.r_xy,
ldp.r_od); ldp.r_od);
} }
...@@ -427,6 +453,7 @@ dPXmmc/dphi= ...@@ -427,6 +453,7 @@ dPXmmc/dphi=
this.r_xyod[0][1]=0.0; // this.py0; this.r_xyod[0][1]=0.0; // this.py0;
this.r_xyod[0][2]=this.r_od[0][0]; this.r_xyod[0][2]=this.r_od[0][0];
this.r_xyod[0][3]=this.r_od[0][1]; this.r_xyod[0][3]=this.r_od[0][1];
setDistortionModelParameters();
if (cummulativeCorrection){ if (cummulativeCorrection){
for (int i=1;i<this.r_xyod.length;i++){ 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][0]=this.r_xyod[i-1][0]+this.r_xy[i-1][0];
...@@ -911,13 +938,39 @@ dPXmmc/dphi= ...@@ -911,13 +938,39 @@ dPXmmc/dphi=
} }
} }
} }
public double [][] calcPartialDerivatives_old( public double [][] calcPartialDerivatives(
double xp, // target point horizontal, positive - right, mm
double yp, // target point vertical, positive - down, mm
double zp, // target point horizontal, positive - away from camera, mm
boolean calculateAll){ // calculate derivatives, false - values only
double maxRelativeRadius=2.0;
return calcPartialDerivatives(xp,yp,zp,maxRelativeRadius,calculateAll);
}
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
double maxRelativeRadius, // make configurable?
boolean calculateAll){ // calculate derivatives, false - values only
switch (this.lensDistortionModelType){
case 0:
case 1:
return calcPartialDerivatives_type1(xp,yp,zp,maxRelativeRadius,calculateAll);
case 2:
return calcPartialDerivatives_type2(xp,yp,zp,maxRelativeRadius,calculateAll);
default:
return calcPartialDerivatives_type1(xp,yp,zp,maxRelativeRadius,calculateAll);
}
}
public double [][] calcPartialDerivatives_type1(
double xp, // target point horizontal, positive - right, mm
double yp, // target point vertical, positive - down, mm
double zp, // target point horizontal, positive - away from camera, mm
double maxRelativeRadius,
boolean calculateAll){ // calculate derivatives, false - values only boolean calculateAll){ // calculate derivatives, false - values only
// this.cummulativeCorrection=false; // just debugging // this.cummulativeCorrection=false; // just debugging
final double maxRelativeRadius=2.0; // make configurable?
// TODO - add reduced calculations for less terms? // TODO - add reduced calculations for less terms?
// final int numDerivatives=44; // 18+6*2+7*2; // 18 for radial and 26 more for non-radial // final int numDerivatives=44; // 18+6*2+7*2; // 18 for radial and 26 more for non-radial
...@@ -1261,15 +1314,13 @@ dPXmmc/dphi= ...@@ -1261,15 +1314,13 @@ dPXmmc/dphi=
return partDeriv; return partDeriv;
} }
public double [][] calcPartialDerivatives_type2(
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
double maxRelativeRadius,
boolean calculateAll){ // calculate derivatives, false - values only boolean calculateAll){ // calculate derivatives, false - values only
// this.cummulativeCorrection=false; // just debugging // this.cummulativeCorrection=false; // just debugging
final double maxRelativeRadius=2.0; // make configurable?
// TODO - add reduced calculations for less terms? // TODO - add reduced calculations for less terms?
// final int numDerivatives=44; // 18+6*2+7*2; // 18 for radial and 26 more for non-radial // final int numDerivatives=44; // 18+6*2+7*2; // 18 for radial and 26 more for non-radial
......
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