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
1296.0, // double px0 // lens axis from sensor, horizontal, from left (pixels)
968.0, // double py0 // lens axis from sensor, vertical, from top (pixels)
true, // boolean flipVertical // acquired image is mirrored vertically (mirror used)
-1, // lensDistortionModel (use default)
null, // double [][] r_xy,
null // double [][] r_od
);
......@@ -1169,7 +1170,8 @@ if (MORE_BUTTONS) {
System.out.println("Number of enabled grid images: "+numImages[0]+
", of them new: "+numImages[1]+
", 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) {
int numImageSets=DISTORTION_CALIBRATION_DATA.buildImageSets(false); // from scratch
......@@ -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.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.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();
if (gd.wasCanceled()) return;
boolean resetHinted= gd.getNextBoolean();
......@@ -6081,7 +6083,8 @@ if (MORE_BUTTONS) {
System.out.println("Number of enabled grid images: "+numImages[0]+
", of them new: "+numImages[1]+
", 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) {
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\"): ");
......
......@@ -38,6 +38,7 @@ import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.configuration.ConfigurationException;
......@@ -679,7 +680,14 @@ import org.apache.commons.configuration.XMLConfiguration;
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");
}
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][];
for (int i=0;i<numSubCameras;i++) cameraPars[i]=eyesisCameraParameters.getParametersVector(stationNumber,i);
// parameters same order as in this
for (int n=0;n<cameraPars[0].length;n++) if (isSubcameraParameter(n) && isIntrinsicParameter(n)){
......@@ -935,8 +943,10 @@ import org.apache.commons.configuration.XMLConfiguration;
}
}
int numNoVignetting=0;
int disabledNoLaser=0;
for (int i=0;i<this.gIP.length;i++){
int stationNumber=this.gIP[i].getStationNumber();
boolean enableNoLaser=this.eyesisCameraParameters.getEnableNoLaser(stationNumber,this.gIP[i].channel);
boolean wasEnabled=this.gIP[i].enabled;
if (resetHinted) this.gIP[i].hintedMatch=-1; // undefined
if (Double.isNaN(this.gIP[i].gridPeriod) ||
......@@ -949,15 +959,17 @@ import org.apache.commons.configuration.XMLConfiguration;
if (
(this.gIP[i].matchedPointers>=minPointers) ||
((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
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]].goniometerAxial)) setGA(i,this.gIS[gIS_index[i]].goniometerAxial );
}
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) {
......@@ -977,7 +989,7 @@ import org.apache.commons.configuration.XMLConfiguration;
if (this.gIP[i].newEnabled) newEnabled++;
}
// may need buildImageSets
int [] result={numEnabled,newEnabled,numNoVignetting,notEnoughNodes};
int [] result={numEnabled,newEnabled,numNoVignetting,notEnoughNodes,disabledNoLaser};
return result;
}
// TODO:
......@@ -1277,7 +1289,26 @@ import org.apache.commons.configuration.XMLConfiguration;
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 [] newEnabled=new boolean [this.gIP.length] ;
......@@ -1285,14 +1316,22 @@ import org.apache.commons.configuration.XMLConfiguration;
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 [] estimated=new boolean [getNumImages()];
if (this.gIS==null) {
String msg="Image sets are not initialized";
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<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) {
......
......@@ -50,6 +50,7 @@ import Jama.Matrix;
// 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
public class Distortions {
final public double hintedMaxRelativeRadius=1.2; // make adjustable?
private showDoubleFloatArrays SDFA_INSTANCE=new showDoubleFloatArrays(); // just for debugging?
// int numInputs=27; // with A8...// 24; // parameters in subcamera+...
// int numOutputs=16; // with A8...//13; // parameters in a single camera
......@@ -3010,12 +3011,25 @@ For each point in the image
* @param v grid V (signed, 0 in the center)
* @return [7] {pX,pY,grid mask (binary), grid R, grid G, grid B, alpha}
*/
public double [] reprojectGridNode(
LensDistortionParameters lensDistortionParameters,
int numImg,
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 nChn= this.fittingStrategy.distortionCalibrationData.gIP[numImg].channel;
......@@ -3035,6 +3049,7 @@ For each point in the image
XYZMP[0], // target point horizontal, positive - right, mm
XYZMP[1], // target point vertical, positive - down, 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)
if (Double.isNaN(pXY[0][0])) {
if (this.debugLevel>debugThreshold){
......@@ -3094,6 +3109,7 @@ For each point in the image
double goniometerAxial, // Axial
int imageSet,
boolean filterBorder){
double maxRelativeRadius=this.hintedMaxRelativeRadius; // make adjustable
int debugThreshold=2;
// Get parameter vector (22) for the selected sensor, current Eyesisparameters and specified orientation angles
double [] parVector=fittingStrategy.distortionCalibrationData.eyesisCameraParameters.getParametersVector(stationNumber,subCamera);
......@@ -3155,6 +3171,7 @@ For each point in the image
XYZM[0], // target point horizontal, positive - right, mm
XYZM[1], // target point vertical, positive - down, 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)
// 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
......@@ -5963,6 +5980,10 @@ List calibration
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("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++){
imp.setProperty("r_xy_"+i+"_x",subCam.r_xy[i][0]+"");
imp.setProperty("r_xy_"+i+"_y",subCam.r_xy[i][1]+"");
......@@ -6144,6 +6165,7 @@ List calibration
subCam.defectsDiff=null;
}
// non-radial
if (imp.getProperty("lensDistortionModel") !=null) subCam.lensDistortionModel= Integer.parseInt((String) imp.getProperty("lensDistortionModel"));
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"));
......@@ -9555,6 +9577,7 @@ M * V = B
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.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++){
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));
......@@ -9760,6 +9783,7 @@ M * V = B
if (reCenterVertically){
eyesisCameraParameters.recenterVertically(channelMask, stationMask);
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;
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 [] goniometerAxial; // goniometer rotation around Eyesis axis (clockwise in plan - positive
public EyesisSubCameraParameters [][] eyesisSubCameras=null;
......@@ -274,6 +282,13 @@ import org.apache.commons.configuration.XMLConfiguration;
}
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 (
int numStations,
......@@ -685,7 +700,7 @@ import org.apache.commons.configuration.XMLConfiguration;
if (numSubCameras>0) {
initSubCameras(numStation, numSubCameras); // set array with default parameters
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;
// 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
//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.addMessage("=== Camera parameters to be fitted ===");
for (int numStation=0;numStation<this.numStations;numStation++) {
......@@ -801,6 +820,15 @@ import org.apache.commons.configuration.XMLConfiguration;
WindowTools.addScrollBars(gd);
gd.showDialog();
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();
for (int numStation=0;numStation<this.numStations;numStation++) {
if (this.numStations>1){
......@@ -861,6 +889,8 @@ import org.apache.commons.configuration.XMLConfiguration;
gd.addNumericField("Channel "+numSubCam+" default weight", subCam.channelWeightDefault, 5,8,"");
}
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 distance from the axis", subCam.radius, 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;
channelWeightDefault=gd.getNextNumber();
}
subCam.channelWeightDefault= channelWeightDefault; // assign to all stations
subCam.lensDistortionModel= (int) gd.getNextNumber();
subCam.enableNoLaser = gd.getNextBoolean();
subCam.azimuth= gd.getNextNumber();
subCam.radius= gd.getNextNumber();
subCam.height= gd.getNextNumber();
......@@ -998,6 +1030,26 @@ import org.apache.commons.configuration.XMLConfiguration;
}
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
......@@ -1191,6 +1243,8 @@ import org.apache.commons.configuration.XMLConfiguration;
for (int i=0;i<numSubCameras;i++) this.eyesisSubCameras[numStation][i]=null;
if (numSubCameras==3) {
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
52.53, // double radius, // mm, distance from the rotation axis
34.64, // double height, // mm, up (was downwards) - from the origin point
......@@ -1213,6 +1267,8 @@ import org.apache.commons.configuration.XMLConfiguration;
null, // elongation for c,b,a,a5,a6,a7,a8
1.0); //channelWeightDefault
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
60.0, // double radius, // mm, distance from the rotation axis
-17.32, // double height, // mm, up (was downwards) - from the origin point
......@@ -1235,6 +1291,8 @@ import org.apache.commons.configuration.XMLConfiguration;
null, // elongation for c,b,a,a5,a6,a7,a8
1.0); //channelWeightDefault
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
60.0, // double radius, // mm, distance from the rotation axis
-17.32, // double height, // mm, up (was downwards) - from the origin point
......@@ -1258,6 +1316,8 @@ import org.apache.commons.configuration.XMLConfiguration;
1.0); //channelWeightDefault
} else if (numSubCameras==1) {
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 radius, // mm, distance from the rotation axis
0.0, // double height, // mm, up (was downwards) - from the origin point
......@@ -1282,6 +1342,8 @@ import org.apache.commons.configuration.XMLConfiguration;
} else {
// default setup for the 26 sub-cameras
for (int i=0;i<8;i++) if (i<numSubCameras) this.eyesisSubCameras[numStation][i]=new EyesisSubCameraParameters( // top 8 cameras
defaultLensDistortionModel,
true,
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
42.883, // double height, // mm, up (was downwards?) - from the origin point
......@@ -1304,6 +1366,8 @@ import org.apache.commons.configuration.XMLConfiguration;
null, // elongation for c,b,a,a5,a6,a7,a8
1.0); //channelWeightDefault
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
54.525, // double radius, // mm, distance from the rotation axis
0.0, // double height, // mm, up (was downwards) - from the origin point
......@@ -1326,6 +1390,8 @@ import org.apache.commons.configuration.XMLConfiguration;
null, // elongation for c,b,a,a5,a6,a7,a8
1.0); //channelWeightDefault
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
41.540, // double radius, // mm, distance from the rotation axis
-42.883, // double height, // mm, up (was downwards?) - from the origin point
......@@ -1348,6 +1414,8 @@ import org.apache.commons.configuration.XMLConfiguration;
null, // elongation for c,b,a,a5,a6,a7,a8
1.0); //channelWeightDefault
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
12.025, // double radius, // mm, distance from the rotation axis
-807.0, // double height, // mm, up - from the origin point
......@@ -1370,6 +1438,8 @@ import org.apache.commons.configuration.XMLConfiguration;
null, // elongation for c,b,a,a5,a6,a7,a8
8.0); //channelWeightDefault (was 4)
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
12.025, // double radius, // mm, distance from the rotation axis
-841.0, // double height, // mm, up - from the origin point
......
......@@ -25,6 +25,8 @@ import java.util.Properties;
public class EyesisSubCameraParameters{
// 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 radius; // mm, distance from the rotation axis
public double height; // mm, up - from the origin point
......@@ -66,6 +68,8 @@ import java.util.Properties;
*/
public EyesisSubCameraParameters(
int lensDistortionModel,
boolean enableNoLaser,
double azimuth, // azimuth of the lens entrance pupil center, degrees, clockwise looking from top
double radius, // mm, distance from the rotation axis
double height, // mm, up from the origin point
......@@ -88,6 +92,8 @@ import java.util.Properties;
double [][] r_od, // elongation for c,b,a,a5,a6,a7,a8
double channelWeightDefault
){
this.lensDistortionModel=lensDistortionModel;
this.enableNoLaser=enableNoLaser;
this.azimuth=azimuth;
this.radius=radius;
this.height=height;
......@@ -121,6 +127,8 @@ import java.util.Properties;
// defects are not cloned!
public EyesisSubCameraParameters clone() {
return new EyesisSubCameraParameters(
this.lensDistortionModel,
this.enableNoLaser,
this.azimuth,
this.radius,
this.height,
......@@ -152,6 +160,8 @@ import java.util.Properties;
}
// TODO: add/restore new 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+"radius",this.radius+"");
properties.setProperty(prefix+"height",this.height+"");
......@@ -181,6 +191,11 @@ import java.util.Properties;
properties.setProperty(prefix+"channelWeightDefault",this.channelWeightDefault+"");
}
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)
this.azimuth=Double.parseDouble(properties.getProperty(prefix+"azimuth"));
if (properties.getProperty(prefix+"radius")!=null)
......@@ -231,6 +246,13 @@ import java.util.Properties;
this.channelWeightDefault=Double.parseDouble(properties.getProperty(prefix+"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(
double weight){
......
......@@ -30,7 +30,12 @@ import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.XMLConfiguration;
......@@ -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;
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
* @param fromToImages - limit number of checkboxes, otherwise window does not show the bottom ones
* @param useParameters Select parameters for this series
* @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
*/
public int selectStrategyStep(
......@@ -1417,6 +1864,7 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
){
boolean showDirectMap=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)
// and copy it;
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
}
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.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
......@@ -1465,8 +1914,8 @@ I* - special case when the subcamera is being adjusted/replaced. How to deal wit
}
if (useImages) {
gd.addNumericField("Image sepection range, from", fromToImages[0], 0);
gd.addNumericField("Image sepection range, up to (inclufing)", fromToImages[1], 0);
gd.addNumericField("Image selection range, from", fromToImages[0], 0);
gd.addNumericField("Image selection range, up to (including)", fromToImages[1], 0);
gd.addMessage("Select files to include");
for (int i =0; i<this.distortionCalibrationData.getNumImages();i++)
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
WindowTools.addScrollBars(gd);
gd.showDialog();
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();
int sourceStrategy= (int) gd.getNextNumber();
boolean removeAllImages=gd.getNextBoolean();
......@@ -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.addCheckbox ("Select images",selectImages);
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 parameters",selectParameters);
gd.addCheckbox ("Ask for initial lambda",askLambdas);
......
......@@ -22,6 +22,9 @@ import Jama.Matrix;
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 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
public double focalLength=4.5;
public double pixelSize= 2.2; //um
......@@ -73,7 +76,22 @@ import Jama.Matrix;
// intermediate values
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 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(
// LensDistortionParameters lensDistortionParameters,
boolean isTripod,
......@@ -116,6 +134,7 @@ import Jama.Matrix;
double px0, // 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)
int lensDistortionModel,
double [][] r_xy,
double [][] r_od
){
......@@ -140,6 +159,7 @@ import Jama.Matrix;
px0,
py0,
flipVertical,
lensDistortionModel,
r_xy,
r_od);
}
......@@ -166,6 +186,7 @@ import Jama.Matrix;
1296, // px0,
698, // py0,
true, // flipVertical,
-1, // lensDistortionModel
null, // r_xy,
null // r_od,
);
......@@ -192,6 +213,7 @@ import Jama.Matrix;
this.px0,
this.py0,
this.flipVertical,
this.lensDistortionModel,
this.r_xy,
this.r_od
);
......@@ -218,6 +240,7 @@ import Jama.Matrix;
double px0, // 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)
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_od // per polynomial term orthogonal+diagonal elongation
){
......@@ -241,6 +264,7 @@ import Jama.Matrix;
this.px0=px0;
this.py0=py0;
this.flipVertical=flipVertical;
this.lensDistortionModel=(lensDistortionModel>=0)?lensDistortionModel:defaultLensDistortionModel;
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];
......@@ -273,6 +297,7 @@ import Jama.Matrix;
pars.px0, // 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)
pars.lensDistortionModel,
pars.r_xy, // do not exist yet!
pars.r_od // do not exist yet!
);
......@@ -301,6 +326,7 @@ import Jama.Matrix;
ldp.px0,
ldp.py0,
ldp.flipVertical,
ldp.lensDistortionModel,
ldp.r_xy,
ldp.r_od);
}
......@@ -427,6 +453,7 @@ dPXmmc/dphi=
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];
setDistortionModelParameters();
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];
......@@ -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 yp, // target point vertical, positive - down, 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
// this.cummulativeCorrection=false; // just debugging
final double maxRelativeRadius=2.0; // make configurable?
// 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
......@@ -1261,15 +1314,13 @@ dPXmmc/dphi=
return partDeriv;
}
public double [][] calcPartialDerivatives(
public double [][] calcPartialDerivatives_type2(
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
// this.cummulativeCorrection=false; // just debugging
final double maxRelativeRadius=2.0; // make configurable?
// 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
......
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