Commit 50de1233 authored by Andrey Filippov's avatar Andrey Filippov

preparing for the goniometer with LWIR

parent 47b15645
......@@ -60,25 +60,16 @@ import java.util.regex.Pattern;
// TODO: modify methods that depend on it, use class CalibrationFileManagement
import javax.swing.JFileChooser;
import com.elphel.imagej.calibration.CalibrationFileManagement.MultipleExtensionsFileFilter;
import com.elphel.imagej.calibration.CalibrationHardwareInterface.CamerasInterface;
import com.elphel.imagej.calibration.CalibrationHardwareInterface.FocusingMotors;
import com.elphel.imagej.calibration.CalibrationHardwareInterface.GoniometerMotors;
import com.elphel.imagej.calibration.CalibrationHardwareInterface.LaserPointers;
import com.elphel.imagej.calibration.CalibrationHardwareInterface.PowerControl;
import com.elphel.imagej.calibration.CalibrationHardwareInterface.UVLEDandLasers;
import com.elphel.imagej.calibration.Distortions.RefineParameters;
import com.elphel.imagej.calibration.SimulationPattern.SimulParameters;
import com.elphel.imagej.cameras.EyesisCameraParameters;
import com.elphel.imagej.cameras.SFEPhases;
import com.elphel.imagej.cameras.SFEPhases.Defect;
import com.elphel.imagej.cameras.SFEPhases.SensorDefects;
import com.elphel.imagej.common.DoubleFHT;
import com.elphel.imagej.common.DoubleGaussianBlur;
import com.elphel.imagej.common.PolynomialApproximation;
import com.elphel.imagej.common.ShowDoubleFloatArrays;
import com.elphel.imagej.common.WindowTools;
import com.elphel.imagej.jp4.JP46_Reader_camera;
import com.elphel.imagej.lwir.LwirReader;
import com.elphel.imagej.lwir.LwirReaderParameters;
import Jama.Matrix; // Download here: http://math.nist.gov/javanumerics/jama/
import ij.IJ;
......@@ -110,6 +101,7 @@ public class Aberration_Calibration extends PlugInFrame implements ActionListene
private Panel panelCurvature;
private Panel panelGoniometer;
private Panel panelPixelMapping, panelStereo,panelStereo1;
private Panel panelLWIR;
private ShowDoubleFloatArrays SDFA_INSTANCE; // just for debugging?
JP46_Reader_camera JP4_INSTANCE;
......@@ -271,6 +263,9 @@ public class Aberration_Calibration extends PlugInFrame implements ActionListene
);
public static LwirReader LWIR_READER = null;
public static ProcessCalibrationFilesParameters PROCESS_PARAMETERS = new ProcessCalibrationFilesParameters(
"jp46", // sourceFileExtension,
"tiff", // kernelFileExtension,
......@@ -614,6 +609,11 @@ public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSi
public static EyesisAberrations EYESIS_ABERRATIONS; // need Distortions to be set up
public static Goniometer GONIOMETER=null;
public static LwirReaderParameters LWIR_PARAMETERS=new LwirReaderParameters();
// new CalibrationHardwareInterface.LaserPointers();
public class SyncCommand{
public boolean isRunning= false;
......@@ -634,7 +634,7 @@ public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSi
addKeyListener(IJ.getInstance());
// setLayout(new GridLayout(ADVANCED_MODE?8:5, 1));
// setLayout(new GridLayout(ADVANCED_MODE?9:6, 1));
setLayout(new GridLayout(ADVANCED_MODE?20:20, 1));
setLayout(new GridLayout(ADVANCED_MODE?21:21, 1));
Color color_configure= new Color(200, 200,160);
Color color_process= new Color(180, 180, 240);
Color color_conf_process= new Color(180, 240, 240);
......@@ -983,9 +983,19 @@ if (MORE_BUTTONS) {
addButton("Create Ambiguity",panelStereo1);
addButton("Initial Resolve",panelStereo1);
addButton("Ambiguity Resolve",panelStereo1);
add(panelStereo1);
panelLWIR= new Panel();
panelLWIR.setLayout(new GridLayout(1, 0, 5, 5)); // rows, columns, vgap, hgap
addButton("LWIR Configure", panelLWIR,color_configure);
addButton("LWIR_TEST", panelLWIR, color_conf_process);
addButton("LWIR_ACQUIRE", panelLWIR, color_conf_process);
addButton("Configure Goniometer", panelLWIR,color_configure);
addButton("Goniometer Move", panelLWIR,color_debug);
addButton("LWIR Goniometer", panelLWIR,color_conf_process);
add(panelLWIR);
pack();
GUI.center(this);
setVisible(true);
......@@ -1094,6 +1104,23 @@ if (MORE_BUTTONS) {
if (DEBUG_LEVEL>0) System.out.println("--- Free memory="+runtime.freeMemory()+" (of "+runtime.totalMemory()+")");
if (label==null) return;
String LOG_LEVEL;
switch (MASTER_DEBUG_LEVEL) {
case -2: LOG_LEVEL = "FATAL"; break;
case -1: LOG_LEVEL = "ERROR"; break;
case 0: LOG_LEVEL = "WARN"; break;
case 1: LOG_LEVEL = "INFO"; break;
case 2: LOG_LEVEL = "DEBUG"; break;
default: LOG_LEVEL = "OFF";
}
boolean LOG_LEVEL_SET = loci.common.DebugTools.enableLogging(LOG_LEVEL);
if (!LOG_LEVEL_SET) { // only first time true
loci.common.DebugTools.setRootLevel(LOG_LEVEL);
}
System.out.println("DEBUG_LEVEL = "+DEBUG_LEVEL+", MASTER_DEBUG_LEVEL = "+MASTER_DEBUG_LEVEL+
" LOG_LEVEL="+LOG_LEVEL+"LOG_LEVEL_SET="+LOG_LEVEL_SET);
if (FOCUSING_FIELD!=null) FOCUSING_FIELD.setThreads(THREADS_MAX);
/* ======================================================================== */
if (label.equals("Configure Globals")) {
......@@ -1172,145 +1199,79 @@ if (MORE_BUTTONS) {
return;
/* ======================================================================== */
} else if (label.equals("Restore") || label.equals("Restore no autoload")) {
boolean noAuto=label.equals("Restore no autoload");
ABERRATIONS_PARAMETERS.autoRestore=false;
String confPath=loadProperties(null,PROCESS_PARAMETERS.kernelsDirectory,PROCESS_PARAMETERS.useXML, PROPERTIES);
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
if (ABERRATIONS_PARAMETERS.autoRestore && !noAuto){
if (DEBUG_LEVEL>0)System.out.println("Auto-loading configuration files");
if (LENS_DISTORTIONS==null) {
LENS_DISTORTIONS=new Distortions(LENS_DISTORTION_PARAMETERS,PATTERN_PARAMETERS,REFINE_PARAMETERS,this.SYNC_COMMAND.stopRequested);
}
LENS_DISTORTIONS.debugLevel=DEBUG_LEVEL;
boolean dcdUpdated=autoLoadFiles(
ABERRATIONS_PARAMETERS,
LENS_DISTORTIONS, // should be initialized, after update DISTORTION_CALIBRATION_DATA from this
PATTERN_PARAMETERS,
EYESIS_CAMERA_PARAMETERS, //EyesisCameraParameters eyesisCameraParameters,
UPDATE_STATUS,
DEBUG_LEVEL
);
if (dcdUpdated) DISTORTION_CALIBRATION_DATA=LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData;
if (ABERRATIONS_PARAMETERS.autoReCalibrate){
if (LENS_DISTORTIONS.fittingStrategy==null) {
IJ.showMessage("Can not recalibrate grids - LENS_DISTORTION.fittingStrategy is not set");
restore(label.equals("Restore no autoload"));
return;
}
if (DEBUG_LEVEL>0)System.out.println("=== Re-calibrating grids ===");
int numMatched=LENS_DISTORTIONS.applyHintedGrids(
LASER_POINTERS, // MatchSimulatedPattern.LaserPointer laserPointer, // LaserPointer object that specifies actual laser poiners on the target
DISTORTION_PROCESS_CONFIGURATION.removeOutOfGridPointers, // boolean removeOutOfGridPointers,
5.0, //double hintGridTolerance, // alllowed mismatch (fraction of period) or 0 - orientation only
true, //boolean processAll, // if true - process all images, false - only disabeld
false, //?
false, //processBlind,
-1, // imageNumber,
true, // useSetData - use imageSets data if available (false - use camera data)
THREADS_MAX, //int threadsMax,
UPDATE_STATUS, // boolean updateStatus,
DISTORTION.loop_debug_level, // int mspDebugLevel,
MASTER_DEBUG_LEVEL, //int global_debug_level, // DEBUG_LEVEL
MASTER_DEBUG_LEVEL //int debug_level // debug level used inside loops
);
System.out.println("Number of matched images: "+numMatched);
LENS_DISTORTIONS.debugLevel=DEBUG_LEVEL;
LENS_DISTORTIONS.updateStatus=UPDATE_STATUS;
LENS_DISTORTIONS.fittingStrategy.debugLevel=DEBUG_LEVEL;
LENS_DISTORTIONS.markBadNodces(
-1,// series - all images
DEBUG_LEVEL);
}
if ((LENS_DISTORTIONS.fittingStrategy != null) && ABERRATIONS_PARAMETERS.autoFilter) { // trying to fix restore
if (DEBUG_LEVEL>0) System.out.println("LENS_DISTORTIONS.fittingStrategy != null -> Extra after loading");
int minGridsNoPointer=1000;
int [] numImages=DISTORTION_CALIBRATION_DATA.filterImages(
false, // resetHinted,
0, // 2, // minPointers,
0.4, // minGridPeriod,
true, // disableNoVignetting,
minGridsNoPointer); //minGridsNoPointer);
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 with no lasers and enableNoLaser==false (like 2 bottom cameras - check all stations):" +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\"): ");
DISTORTION_CALIBRATION_DATA.updateSetOrientation(null); // restore orientation from (enabled) image files
if (DEBUG_LEVEL>0) System.out.println("Setting sets orientation from per-grid image data");
}
}
restoreFocusingHistory(false);
/* ======================================================================== */
} else if (label.equals("Process Calibration Files")) {
processCalibrationFiles();
return;
/* ======================================================================== */
}
/* ======================================================================== */
} else if (label.equals("Configure")) {
if (!showConfigureDialog(OTF_FILTER, PATTERN_DETECT,COMPONENTS,INVERSE,MULTIFILE_PSF)) return;
return;
/* ======================================================================== */
} else if (label.equals("Configure Simul.")) {
if (!showSimulDialog(SIMUL)) return;
return;
/* ======================================================================== */
} else if (label.equals("Process Calibration Files")) {
if (!showProcessCalibrationFilesDialog(PROCESS_PARAMETERS)) return;
boolean noMessageBoxes=false; //TODO: move to configuration
long startTime=System.nanoTime();
long tmpTime;
String resultPath;
} else if (label.equals("Map PSF")) {
if (!showPSFDialog(PSF_PARS,INVERSE,OTF_FILTER,SIMUL)) return;
int loop_debug_level=DISTORTION.loop_debug_level;
// int loop_debug_level=1;
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
int loop_debug_level=1;
String [][][] filePaths=null;
int dirNum, fileNum;
ImageStack stack;
ImagePlus imp_psf;
File file;
String fileName;
if (PROCESS_PARAMETERS.processSourceImages) {
if ((PROCESS_PARAMETERS.sourceSuperDirectory==null) || (PROCESS_PARAMETERS.sourceSuperDirectory.length()==0)) {
fileName= selectSourceDirectory(PROCESS_PARAMETERS.sourceSuperDirectory);
if (fileName!=null) PROCESS_PARAMETERS.sourceSuperDirectory=fileName;
}
if ((PROCESS_PARAMETERS.partialKernelsSuperDirectory==null) || (PROCESS_PARAMETERS.partialKernelsSuperDirectory.length()==0)) {
fileName= selectPartialKernelsDirectory(PROCESS_PARAMETERS.partialKernelsSuperDirectory);
if (fileName!=null) PROCESS_PARAMETERS.partialKernelsSuperDirectory=fileName;
}
filePaths=prepareCalibrationFilesList(PROCESS_PARAMETERS);
if (filePaths==null) {
IJ.showMessage("Error","No files to process\nProcess canceled");
imp_sel = WindowManager.getCurrentImage();
if (imp_sel==null){
IJ.showMessage("Error","There are no images open\nProcess canceled");
return;
}
startTime=System.nanoTime(); // restart timer after possible interactive dialogs
for (dirNum=0;dirNum<filePaths.length; dirNum++) {
if (filePaths[dirNum]!=null){
if (DEBUG_LEVEL>1) System.out.println("======= directory number="+dirNum+", number of files="+filePaths[dirNum].length+" ========");
for (fileNum=0;fileNum<filePaths[dirNum].length; fileNum++) {
if (DEBUG_LEVEL>1) System.out.println(filePaths[dirNum][fileNum][0] +" ==> "+filePaths[dirNum][fileNum][1]);
imp_sel=JP4_INSTANCE.open(
"", // path,
filePaths[dirNum][fileNum][0],
"", //arg - not used in JP46 reader
true, // un-apply camera color gains
imp_sel); // reuse the same image window
// Remove for old method?
matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize);
// Updates global PSF_KERNEL_MAP
// update selected roi to include at least one PSF kernel
int psf_overlap_sensor=FFT_OVERLAP*PSF_SUBPIXEL/2;
int psf_fft_sensor= FFT_SIZE* PSF_SUBPIXEL/2;
Roi roi= imp_sel.getRoi();
Rectangle selection;
if (roi!=null){
selection=roi.getBounds();
int selectionCenterX=selection.x+selection.width/2;
int selectionCenterY=selection.y+selection.height/2;
// round selection width, height
selection.width=psf_overlap_sensor*((selection.width+psf_overlap_sensor/2)/psf_overlap_sensor);
selection.height=psf_overlap_sensor*((selection.height+psf_overlap_sensor/2)/psf_overlap_sensor);
// enforce minimal size
if (selection.width <psf_fft_sensor) selection.width=psf_fft_sensor;
if (selection.height<psf_fft_sensor) selection.height=psf_fft_sensor;
// recalculate center
selection.x=selectionCenterX-selection.width/2;
selection.y=selectionCenterY-selection.width/2;
if (selection.x<0) selection.x=0;
if (selection.y<0) selection.y=0;
// add half step for later rounding by truncating;
selection.x+=psf_overlap_sensor/2;
selection.y+=psf_overlap_sensor/2;
//limit by right and bottom edges
if ((selection.width+selection.x)>imp_sel.getWidth()) selection.x=imp_sel.getWidth()-selection.width;
if ((selection.height+selection.y)>imp_sel.getHeight()) selection.y=imp_sel.getHeight()-selection.height;
// round to the grid (already added psf_overlap_sensor/2, so just truncate)
selection.x=psf_overlap_sensor*(selection.x/psf_overlap_sensor);
selection.y=psf_overlap_sensor*(selection.y/psf_overlap_sensor);
matchSimulatedPattern.calculateDistortions(
DISTORTION, //
PATTERN_DETECT,
imp_sel.setRoi(selection);
}
/*
SIM_ARRAY= simulateGridAll (
imp_sel.getWidth(),
imp_sel.getHeight(),
matchSimulatedPattern.getDArray(),
2, // gridFrac, // number of grid steps per pattern full period
SIMUL,
COMPONENTS.equalizeGreens,
imp_sel,
null, // LaserPointer laserPointer, // LaserPointer object or null
true, // don't care -removeOutOfGridPointers
null, // double [][][] hintGrid, // predicted grid array (or null)
0, // double hintGridTolerance, // alllowed mismatch (fraction of period) or 0 - orientation only
THREADS_MAX,
UPDATE_STATUS,
DEBUG_LEVEL,
DISTORTION.loop_debug_level, // debug level
noMessageBoxes);
DISTORTION.loop_debug_level); // debug level
*/
SIM_ARRAY= (new SimulationPattern(SIMUL)).simulateGridAll (
imp_sel.getWidth(),
imp_sel.getHeight(),
......@@ -1322,16 +1283,19 @@ if (MORE_BUTTONS) {
DEBUG_LEVEL,
DISTORTION.loop_debug_level); // debug level
//(new showDoubleFloatArrays()).showArrays(kernels, "***kernels-"+nTX+"-"+nTY);
createPSFMap(
matchSimulatedPattern,
matchSimulatedPattern.applyFlatField (imp_sel), // if grid is flat-field calibrated, apply it
// imp_sel, // linearized Bayer mosaic image form the camera, GR/BG
null, // int [][][] sampleList, // optional (or null) 2-d array: list of coordinate pairs (2d - to match existent PSF_KERNEL_MAP structure)
MULTIFILE_PSF.overexposedMaxFraction,
SIMUL, //simulation parameters
SIMUL, // simulation parameters
MAP_FFT_SIZE, // scanImageForPatterns:FFT size
PATTERN_DETECT,
FFT_OVERLAP, // scanImageForPatterns:high-pass gaussian filter sigma when correlating power spectrum
FFT_SIZE, // maximal distance between maximum on spectrum and predicted maximum on autocorrelation of gamma(|spectrum|)
PATTERN_DETECT, // pattern detection parameters
FFT_OVERLAP,
FFT_SIZE,
COMPONENTS,
PSF_SUBPIXEL, // maximal iterations when looking for local maximum
OTF_FILTER,
......@@ -1341,223 +1305,117 @@ if (MORE_BUTTONS) {
THREADS_MAX,
UPDATE_STATUS,
loop_debug_level);// debug level used inside loops
//if (DEBUG_LEVEL>0) return;
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
stack=mergeKernelsToStack(PSF_KERNEL_MAP);
if (stack!=null) {
imp_psf = new ImagePlus(filePaths[dirNum][fileNum][1], stack);
// if (DEBUG_LEVEL>1) imp_psf.show();
if (DEBUG_LEVEL>1) System.out.println("Saving result to"+filePaths[dirNum][fileNum][1]+ " at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
FileSaver fs=new FileSaver(imp_psf);
fs.saveAsTiffStack(filePaths[dirNum][fileNum][1]);
} else {
System.out.println("File "+filePaths[dirNum][fileNum][1]+ " has no useful PSF kernels - at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
}
}
ImageStack mergedStack=mergeKernelsToStack(PSF_KERNEL_MAP);
if (mergedStack==null) {
IJ.showMessage("Error","No useful PSF kernels to show");
return;
}
ImagePlus imp_psf=SDFA_INSTANCE.showImageStack(mergedStack, imp_sel.getTitle()+"-PSF_KERNEL");
if (PSF_SAVE_FILE) {
String path=imp_sel.getOriginalFileInfo().directory+"PSF-"+imp_sel.getTitle();
if (DEBUG_LEVEL>1) {
System.out.println("Saving result to "+path);
}
IJ.saveAs(imp_psf,"tif",path);
}
if (PROCESS_PARAMETERS.combinePSFfiles) {
tmpTime=System.nanoTime();
if ((PROCESS_PARAMETERS.partialKernelsSuperDirectory==null) || (PROCESS_PARAMETERS.partialKernelsSuperDirectory.length()==0)) {
fileName= selectPartialKernelsDirectory(PROCESS_PARAMETERS.partialKernelsSuperDirectory);
if (fileName!=null) PROCESS_PARAMETERS.partialKernelsSuperDirectory=fileName;
return;
/* ======================================================================== */
// calculate a single PSF
/* ======================================================================== */
} else if (label.equals("Interpolate Stack")) {
// int loop_debug_level=1;
if (!showInterpolateKernelsDialog(INTERPOLATE)) return;
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
ImagePlus imp_kernels = WindowManager.getCurrentImage();
if (imp_kernels==null){
IJ.showMessage("Error","There is no kernel stack to process");
return;
}
filePaths=preparePartialKernelsFilesList(PROCESS_PARAMETERS);
startTime-=(System.nanoTime()-tmpTime); // do not count time used for selection of files
if (filePaths==null) {
IJ.showMessage("Error","No partila kernel files to process, finished in "+IJ.d2s(0.000000001*(System.nanoTime()-startTime),3)+ " seconds");
if (imp_kernels.getStackSize()<3) {
IJ.showMessage("Error","Need a 3-layer stack with kernels");
return;
}
String [] filenames;
for (dirNum=0;dirNum<filePaths.length; dirNum++) {
if ((filePaths[dirNum]!=null) && (filePaths[dirNum].length!=0)){
resultPath=filePaths[dirNum][0][1];
filenames=new String[filePaths[dirNum].length];
for (fileNum=0;fileNum<filenames.length;fileNum++) filenames[fileNum]=filePaths[dirNum][fileNum][0];
if (!combinePSFKernels (
INTERPOLATE,
MULTIFILE_PSF,
filenames,
resultPath,
SDFA_INSTANCE,
imp_sel, // re-use global
true, // saveResult,
false, // showResult,
UPDATE_STATUS,
DEBUG_LEVEL)) continue; // return; // no overlap, bad result kernel
}
}
}
if (PROCESS_PARAMETERS.interpolatePSFkernel) {
tmpTime=System.nanoTime();
if ((PROCESS_PARAMETERS.partialKernelsSuperDirectory==null) || (PROCESS_PARAMETERS.partialKernelsSuperDirectory.length()==0)) {
fileName= selectPartialKernelsDirectory(PROCESS_PARAMETERS.partialKernelsSuperDirectory);
if (fileName!=null) PROCESS_PARAMETERS.partialKernelsSuperDirectory=fileName;
}
IJ.showMessage("Notice","partialKernelsSuperDirectory="+PROCESS_PARAMETERS.partialKernelsSuperDirectory);
startTime-=(System.nanoTime()-tmpTime); // do not count time used for selection of files
filePaths=prepareInterpolateKernelsList(PROCESS_PARAMETERS);
for (fileNum=0;fileNum<filePaths.length;fileNum++) if ((filePaths[fileNum]!=null) && (filePaths[fileNum].length>0)) {
file=new File(filePaths[fileNum][0][0]);
if (!file.exists()) {
if (DEBUG_LEVEL>1) System.out.println("Raw PSF kernel stack file "+filePaths[fileNum][0][0]+" does not exist");
continue;
}
imp_psf=new ImagePlus(filePaths[fileNum][0][0]);
if (imp_psf.getStackSize()<3) {
System.out.println("Need a 3-layer stack with raw PSF kernels");
continue;
}
stack= interpolateKernelStack(imp_psf.getStack(), // Image stack, each slice consists of square kernels of one channel
ImageStack interpolatedStack= interpolateKernelStack(imp_kernels.getStack(), // Image stack, each slice consists of square kernels of one channel
INTERPOLATE,
UPDATE_STATUS); // update status info
imp_psf = new ImagePlus(filePaths[fileNum][0][1], stack);
if (DEBUG_LEVEL>2) {
imp_psf.getProcessor().resetMinAndMax(); // imp_psf will be reused
imp_psf.show();
}
if (DEBUG_LEVEL>1) System.out.println("Saving interpolation result to"+filePaths[fileNum][0][1]+ " at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
FileSaver fs=new FileSaver(imp_psf);
fs.saveAsTiffStack(filePaths[fileNum][0][1]);
}
}
if (PROCESS_PARAMETERS.invertKernels) {
tmpTime=System.nanoTime();
if ((PROCESS_PARAMETERS.partialKernelsSuperDirectory==null) || (PROCESS_PARAMETERS.partialKernelsSuperDirectory.length()==0)) {
fileName= selectPartialKernelsDirectory(PROCESS_PARAMETERS.partialKernelsSuperDirectory);
if (fileName!=null) PROCESS_PARAMETERS.partialKernelsSuperDirectory=fileName;
}
if ((PROCESS_PARAMETERS.kernelsDirectory==null) || (PROCESS_PARAMETERS.kernelsDirectory.length()==0)) {
fileName= selectKernelsDirectory(PROCESS_PARAMETERS.kernelsDirectory);
if (fileName!=null) PROCESS_PARAMETERS.kernelsDirectory=fileName;
}
startTime-=(System.nanoTime()-tmpTime); // do not count time used fro selection of files
filePaths=prepareInvertGaussianKernelsList(PROCESS_PARAMETERS, PROCESS_PARAMETERS.rpsfPrefix );
ImagePlus imp_interpolated_stack = new ImagePlus(imp_kernels.getTitle()+"-"+INTERPOLATE.step+ "X-interpolated", interpolatedStack);
imp_interpolated_stack.getProcessor().resetMinAndMax();
imp_interpolated_stack.show();
for (fileNum=0;fileNum<filePaths.length;fileNum++) if ((filePaths[fileNum]!=null) && (filePaths[fileNum].length>0)) {
file=new File(filePaths[fileNum][0][0]);
if (!file.exists()) {
if (DEBUG_LEVEL>0) System.out.println("Interpolated PSF kernel stack file "+filePaths[fileNum][0][0]+" does not exist");
continue;
}
imp_psf=new ImagePlus(filePaths[fileNum][0][0]);
if (imp_psf.getStackSize()<3) {
System.out.println("Need a 3-layer stack with interpolated PSF kernels");
continue;
}
stack= reversePSFKernelStack(imp_psf.getStack(), // stack of 3 32-bit (float) images, made of square kernels
INVERSE,
THREADS_MAX, // size (side of square) of reverse PSF kernel
UPDATE_STATUS); // update status info
imp_psf = new ImagePlus(filePaths[fileNum][0][1], stack);
if (DEBUG_LEVEL>2) {
imp_psf.getProcessor().resetMinAndMax(); // imp_psf will be reused
imp_psf.show();
}
if (DEBUG_LEVEL>0) System.out.println("Saving PSF inversion result to"+filePaths[fileNum][0][1]+ " at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
FileSaver fs=new FileSaver(imp_psf);
fs.saveAsTiffStack(filePaths[fileNum][0][1]);
}
}
if (PROCESS_PARAMETERS.gaussianKernels) {
tmpTime=System.nanoTime();
if ((PROCESS_PARAMETERS.partialKernelsSuperDirectory==null) || (PROCESS_PARAMETERS.partialKernelsSuperDirectory.length()==0)) {
fileName= selectPartialKernelsDirectory(PROCESS_PARAMETERS.partialKernelsSuperDirectory);
if (fileName!=null) PROCESS_PARAMETERS.partialKernelsSuperDirectory=fileName;
}
if ((PROCESS_PARAMETERS.kernelsDirectory==null) || (PROCESS_PARAMETERS.kernelsDirectory.length()==0)) {
fileName= selectKernelsDirectory(PROCESS_PARAMETERS.kernelsDirectory);
if (fileName!=null) PROCESS_PARAMETERS.kernelsDirectory=fileName;
}
startTime-=(System.nanoTime()-tmpTime); // do not count time used fro selection of files
filePaths=prepareInvertGaussianKernelsList(PROCESS_PARAMETERS, PROCESS_PARAMETERS.gaussianPrefix);
for (fileNum=0;fileNum<filePaths.length;fileNum++) if ((filePaths[fileNum]!=null) && (filePaths[fileNum].length>0)) {
file=new File(filePaths[fileNum][0][0]);
if (!file.exists()) {
if (DEBUG_LEVEL>0) System.out.println("Interpolated PSF kernel stack file "+filePaths[fileNum][0][0]+" does not exist");
continue;
}
imp_psf=new ImagePlus(filePaths[fileNum][0][0]);
if (imp_psf.getStackSize()<3) {
System.out.println("Need a 3-layer stack with interpolated PSF kernels");
continue;
}
stack= generateGaussianStackFromDirect(imp_psf.getStack(), // stack of 3 32-bit (float) images, made of square kernels
INVERSE,
UPDATE_STATUS); // update status info
imp_psf = new ImagePlus(filePaths[fileNum][0][1], stack);
if (DEBUG_LEVEL>2) {
imp_psf.getProcessor().resetMinAndMax(); // imp_psf will be reused
imp_psf.show();
}
if (DEBUG_LEVEL>0) System.out.println("Saving Gaussian kernels result to"+filePaths[fileNum][0][1]+ " at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
FileSaver fs=new FileSaver(imp_psf);
fs.saveAsTiffStack(filePaths[fileNum][0][1]);
String result_path=imp_kernels.getOriginalFileInfo().directory+imp_interpolated_stack.getTitle();
if (PSF_SAVE_FILE && (result_path!=null)) {
if (DEBUG_LEVEL>1) {
System.out.println("Saving result to "+result_path);
}
IJ.saveAs(imp_interpolated_stack,"tif",result_path);
}
System.out.println("Processing done in "+IJ.d2s(0.000000001*(System.nanoTime()-startTime),3)+ " seconds");
if (PROCESS_PARAMETERS.saveSettings) saveProperties(PROCESS_PARAMETERS.kernelsDirectory+Prefs.getFileSeparator()+"calibration_settings",null,PROCESS_PARAMETERS.useXML, PROPERTIES);
return;
/* ======================================================================== */
/* ======================================================================== */
} else if (label.equals("Configure")) {
if (!showConfigureDialog(OTF_FILTER, PATTERN_DETECT,COMPONENTS,INVERSE,MULTIFILE_PSF)) return;
return;
/* ======================================================================== */
} else if (label.equals("Configure Simul.")) {
if (!showSimulDialog(SIMUL)) return;
return;
/* ======================================================================== */
} else if (label.equals("Map PSF")) {
} else if (label.equals("Scan and Map")) {
boolean noMessageBoxes=false;
int loop_debug_level=1;
if (!showPSFDialog(PSF_PARS,INVERSE,OTF_FILTER,SIMUL)) return;
int loop_debug_level=DISTORTION.loop_debug_level;
// int loop_debug_level=1;
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
imp_sel = WindowManager.getCurrentImage();
if (imp_sel==null){
IJ.showMessage("Error","There are no images open\nProcess canceled");
JFileChooser fc= new JFileChooser();
fc.setMultiSelectionEnabled(true);
if (DIR==null) { // global
String sdir = OpenDialog.getDefaultDirectory();
if (sdir!=null)
DIR = new File(sdir);
}
if (DIR!=null)
fc.setCurrentDirectory(DIR);
int returnVal = fc.showOpenDialog(IJ.getInstance());
if (returnVal!=JFileChooser.APPROVE_OPTION)
return;
File[] files = fc.getSelectedFiles();
if (files.length==0) { // getSelectedFiles does not work on some JVMs
files = new File[1];
files[0] = fc.getSelectedFile();
}
// Updates global PSF_KERNEL_MAP
// update selected roi to include at least one PSF kernel
int psf_overlap_sensor=FFT_OVERLAP*PSF_SUBPIXEL/2;
int psf_fft_sensor= FFT_SIZE* PSF_SUBPIXEL/2;
Roi roi= imp_sel.getRoi();
Rectangle selection;
if (roi!=null){
selection=roi.getBounds();
int selectionCenterX=selection.x+selection.width/2;
int selectionCenterY=selection.y+selection.height/2;
// round selection width, height
selection.width=psf_overlap_sensor*((selection.width+psf_overlap_sensor/2)/psf_overlap_sensor);
selection.height=psf_overlap_sensor*((selection.height+psf_overlap_sensor/2)/psf_overlap_sensor);
// enforce minimal size
if (selection.width <psf_fft_sensor) selection.width=psf_fft_sensor;
if (selection.height<psf_fft_sensor) selection.height=psf_fft_sensor;
// recalculate center
selection.x=selectionCenterX-selection.width/2;
selection.y=selectionCenterY-selection.width/2;
if (selection.x<0) selection.x=0;
if (selection.y<0) selection.y=0;
// add half step for later rounding by truncating;
selection.x+=psf_overlap_sensor/2;
selection.y+=psf_overlap_sensor/2;
//limit by right and bottom edges
if ((selection.width+selection.x)>imp_sel.getWidth()) selection.x=imp_sel.getWidth()-selection.width;
if ((selection.height+selection.y)>imp_sel.getHeight()) selection.y=imp_sel.getHeight()-selection.height;
// round to the grid (already added psf_overlap_sensor/2, so just truncate)
selection.x=psf_overlap_sensor*(selection.x/psf_overlap_sensor);
selection.y=psf_overlap_sensor*(selection.y/psf_overlap_sensor);
long startTime = System.nanoTime();
imp_sel.setRoi(selection);
}
/*
String path = fc.getCurrentDirectory().getPath()+Prefs.getFileSeparator();
DIR = fc.getCurrentDirectory();
System.out.println("path= "+path+", files:");
String [] filenames=new String[files.length]; // global
int nFile;
ImageStack mergedStack;
ImagePlus imp_psf;
String outPath;
for (nFile=0;nFile<files.length;nFile++) {
filenames[nFile]= files[nFile].getName();
System.out.println(nFile+": "+filenames[nFile]);
imp_sel=JP4_INSTANCE.open(
"", // path,
path+filenames[nFile],
"", //arg - not used in JP46 reader
true, // un-apply camera color gains
imp_sel); // reuse the same image window
matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize);
// matchSimulatedPattern.invalidateFlatFieldForGrid(); //It is already reset, no need to do it again
// matchSimulatedPattern.invalidateFocusMask();
matchSimulatedPattern.calculateDistortions(
DISTORTION, //
PATTERN_DETECT,
SIMUL,
COMPONENTS.equalizeGreens,
imp_sel,
null, // LaserPointer laserPointer, // LaserPointer object or null
true, // don't care -removeOutOfGridPointers
null, // double [][][] hintGrid, // predicted grid array (or null)
0, // double hintGridTolerance, // alllowed mismatch (fraction of period) or 0 - orientation only
THREADS_MAX,
UPDATE_STATUS,
DEBUG_LEVEL,
DISTORTION.loop_debug_level, // debug level
noMessageBoxes);
/*
SIM_ARRAY= simulateGridAll (
imp_sel.getWidth(),
imp_sel.getHeight(),
......@@ -1567,7 +1425,7 @@ if (MORE_BUTTONS) {
THREADS_MAX,
UPDATE_STATUS,
DISTORTION.loop_debug_level); // debug level
*/
*/
SIM_ARRAY= (new SimulationPattern(SIMUL)).simulateGridAll (
imp_sel.getWidth(),
imp_sel.getHeight(),
......@@ -1579,171 +1437,17 @@ if (MORE_BUTTONS) {
DEBUG_LEVEL,
DISTORTION.loop_debug_level); // debug level
//(new showDoubleFloatArrays()).showArrays(kernels, "***kernels-"+nTX+"-"+nTY);
createPSFMap(
matchSimulatedPattern,
matchSimulatedPattern.applyFlatField (imp_sel), // if grid is flat-field calibrated, apply it
// imp_sel, // linearized Bayer mosaic image form the camera, GR/BG
null, // int [][][] sampleList, // optional (or null) 2-d array: list of coordinate pairs (2d - to match existent PSF_KERNEL_MAP structure)
MULTIFILE_PSF.overexposedMaxFraction,
SIMUL, // simulation parameters
SIMUL, //simulation parameters
MAP_FFT_SIZE, // scanImageForPatterns:FFT size
PATTERN_DETECT, // pattern detection parameters
FFT_OVERLAP,
FFT_SIZE,
COMPONENTS,
PSF_SUBPIXEL, // maximal iterations when looking for local maximum
OTF_FILTER,
PSF_PARS, // step of the new map (should be multiple of map step)
PSF_PARS.minDefinedArea,
INVERSE.dSize, // size of square used in the new map (should be multiple of map step)
THREADS_MAX,
UPDATE_STATUS,
loop_debug_level);// debug level used inside loops
//if (DEBUG_LEVEL>0) return;
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
ImageStack mergedStack=mergeKernelsToStack(PSF_KERNEL_MAP);
if (mergedStack==null) {
IJ.showMessage("Error","No useful PSF kernels to show");
return;
}
ImagePlus imp_psf=SDFA_INSTANCE.showImageStack(mergedStack, imp_sel.getTitle()+"-PSF_KERNEL");
if (PSF_SAVE_FILE) {
String path=imp_sel.getOriginalFileInfo().directory+"PSF-"+imp_sel.getTitle();
if (DEBUG_LEVEL>1) {
System.out.println("Saving result to "+path);
}
IJ.saveAs(imp_psf,"tif",path);
}
return;
/* ======================================================================== */
// calculate a single PSF
/* ======================================================================== */
} else if (label.equals("Interpolate Stack")) {
// int loop_debug_level=1;
if (!showInterpolateKernelsDialog(INTERPOLATE)) return;
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
ImagePlus imp_kernels = WindowManager.getCurrentImage();
if (imp_kernels==null){
IJ.showMessage("Error","There is no kernel stack to process");
return;
}
if (imp_kernels.getStackSize()<3) {
IJ.showMessage("Error","Need a 3-layer stack with kernels");
return;
}
ImageStack interpolatedStack= interpolateKernelStack(imp_kernels.getStack(), // Image stack, each slice consists of square kernels of one channel
INTERPOLATE,
UPDATE_STATUS); // update status info
ImagePlus imp_interpolated_stack = new ImagePlus(imp_kernels.getTitle()+"-"+INTERPOLATE.step+ "X-interpolated", interpolatedStack);
imp_interpolated_stack.getProcessor().resetMinAndMax();
imp_interpolated_stack.show();
String result_path=imp_kernels.getOriginalFileInfo().directory+imp_interpolated_stack.getTitle();
if (PSF_SAVE_FILE && (result_path!=null)) {
if (DEBUG_LEVEL>1) {
System.out.println("Saving result to "+result_path);
}
IJ.saveAs(imp_interpolated_stack,"tif",result_path);
}
return;
/* ======================================================================== */
} else if (label.equals("Scan and Map")) {
boolean noMessageBoxes=false;
int loop_debug_level=1;
if (!showPSFDialog(PSF_PARS,INVERSE,OTF_FILTER,SIMUL)) return;
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
JFileChooser fc= new JFileChooser();
fc.setMultiSelectionEnabled(true);
if (DIR==null) { // global
String sdir = OpenDialog.getDefaultDirectory();
if (sdir!=null)
DIR = new File(sdir);
}
if (DIR!=null)
fc.setCurrentDirectory(DIR);
int returnVal = fc.showOpenDialog(IJ.getInstance());
if (returnVal!=JFileChooser.APPROVE_OPTION)
return;
File[] files = fc.getSelectedFiles();
if (files.length==0) { // getSelectedFiles does not work on some JVMs
files = new File[1];
files[0] = fc.getSelectedFile();
}
long startTime = System.nanoTime();
String path = fc.getCurrentDirectory().getPath()+Prefs.getFileSeparator();
DIR = fc.getCurrentDirectory();
System.out.println("path= "+path+", files:");
String [] filenames=new String[files.length]; // global
int nFile;
ImageStack mergedStack;
ImagePlus imp_psf;
String outPath;
for (nFile=0;nFile<files.length;nFile++) {
filenames[nFile]= files[nFile].getName();
System.out.println(nFile+": "+filenames[nFile]);
imp_sel=JP4_INSTANCE.open(
"", // path,
path+filenames[nFile],
"", //arg - not used in JP46 reader
true, // un-apply camera color gains
imp_sel); // reuse the same image window
matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize);
// matchSimulatedPattern.invalidateFlatFieldForGrid(); //It is already reset, no need to do it again
// matchSimulatedPattern.invalidateFocusMask();
matchSimulatedPattern.calculateDistortions(
DISTORTION, //
PATTERN_DETECT,
SIMUL,
COMPONENTS.equalizeGreens,
imp_sel,
null, // LaserPointer laserPointer, // LaserPointer object or null
true, // don't care -removeOutOfGridPointers
null, // double [][][] hintGrid, // predicted grid array (or null)
0, // double hintGridTolerance, // alllowed mismatch (fraction of period) or 0 - orientation only
THREADS_MAX,
UPDATE_STATUS,
DEBUG_LEVEL,
DISTORTION.loop_debug_level, // debug level
noMessageBoxes);
/*
SIM_ARRAY= simulateGridAll (
imp_sel.getWidth(),
imp_sel.getHeight(),
matchSimulatedPattern.getDArray(),
2, // gridFrac, // number of grid steps per pattern full period
SIMUL,
THREADS_MAX,
UPDATE_STATUS,
DISTORTION.loop_debug_level); // debug level
*/
SIM_ARRAY= (new SimulationPattern(SIMUL)).simulateGridAll (
imp_sel.getWidth(),
imp_sel.getHeight(),
matchSimulatedPattern,
2, // gridFrac, // number of grid steps per pattern full period
SIMUL,
THREADS_MAX,
UPDATE_STATUS,
DEBUG_LEVEL,
DISTORTION.loop_debug_level); // debug level
createPSFMap(
matchSimulatedPattern,
matchSimulatedPattern.applyFlatField (imp_sel), // if grid is flat-field calibrated, apply it
// imp_sel, // linearized Bayer mosaic image form the camera, GR/BG
null, // int [][][] sampleList, // optional (or null) 2-d array: list of coordinate pairs (2d - to match existent PSF_KERNEL_MAP structure)
MULTIFILE_PSF.overexposedMaxFraction,
SIMUL, //simulation parameters
MAP_FFT_SIZE, // scanImageForPatterns:FFT size
PATTERN_DETECT,
FFT_OVERLAP, // scanImageForPatterns:high-pass gaussian filter sigma when correlating power spectrum
FFT_SIZE, // maximal distance between maximum on spectrum and predicted maximum on autocorrelation of gamma(|spectrum|)
PATTERN_DETECT,
FFT_OVERLAP, // scanImageForPatterns:high-pass gaussian filter sigma when correlating power spectrum
FFT_SIZE, // maximal distance between maximum on spectrum and predicted maximum on autocorrelation of gamma(|spectrum|)
COMPONENTS,
PSF_SUBPIXEL, // maximal iterations when looking for local maximum
OTF_FILTER,
......@@ -9697,6 +9401,110 @@ if (MORE_BUTTONS) {
}
return;
}
/* ======================================================================== */
if (label.equals("LWIR Configure")) {
LWIR_PARAMETERS.showJDialog();
return;
}
/* ======================================================================== */
//
if (label.equals("LWIR_TEST")) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
// public static LwirReader LWIR_READER = null;
if (LWIR_READER == null) {
LWIR_READER = new LwirReader(LWIR_PARAMETERS);
}
ImagePlus [][] imps = LWIR_READER.readAllMultiple(
10, // final int num_frames,
// true, // use LWIR telemetry
true, // final boolean show,
false); // true); // final boolean scale)
for (ImagePlus imp: imps[0]) {
imp.show();
}
System.out.println("LWIR_TEST: got "+imps.length+" image sets");
ImagePlus [][] imps_sync = LWIR_READER.matchSets(imps, 0.001, 3); // double max_mismatch)
if (imps_sync != null) {
ImagePlus [] imps_avg = LWIR_READER.averageMultiFrames(imps_sync);
for (ImagePlus imp: imps_avg) {
imp.show();
}
}
return;
}
/* ======================================================================== */
if (label.equals("LWIR_ACQUIRE")) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
// public static LwirReader LWIR_READER = null;
if (LWIR_READER == null) {
LWIR_READER = new LwirReader(LWIR_PARAMETERS);
}
ImagePlus [] imps = LWIR_READER.acquire("/data_ssd/imagej-elphel/attic/camera_img/test-calib"); // directory to save
if (imps != null) {
// for (ImagePlus imp: imps) {
// imp.show();
// }
}
return;
}
/* ======================================================================== */
if (label.equals("Goniometer LWIR")) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
// CAMERAS.setNumberOfThreads(THREADS_MAX);
// CAMERAS.debugLevel=DEBUG_LEVEL;
if (GONIOMETER==null) {
GONIOMETER= new Goniometer(
LWIR_READER,
// CAMERAS, // CalibrationHardwareInterface.CamerasInterface cameras,
DISTORTION, //MatchSimulatedPattern.DistortionParameters distortion,
PATTERN_DETECT, //MatchSimulatedPattern.PatternDetectParameters patternDetectParameters,
EYESIS_CAMERA_PARAMETERS, //EyesisCameraParameters eyesisCameraParameters,
LASER_POINTERS, // MatchSimulatedPattern.LaserPointer laserPointers
SIMUL, //SimulationPattern.SimulParameters simulParametersDefault,
GONIOMETER_PARAMETERS, //LensAdjustment.FocusMeasurementParameters focusMeasurementParameters,
DISTORTION_PROCESS_CONFIGURATION
);
if (DEBUG_LEVEL>1){
System.out.println("Initiaslizing Goniometer class");
}
} else if (DEBUG_LEVEL>1){
System.out.println("GONIOMETER was initialized");
}
// calculate angular size of the target as visible from the camera
double distanceToTarget=GONIOMETER_PARAMETERS.targetDistance;
double patternWidth= PATTERN_PARAMETERS.patternWidth;
double patternHeight=PATTERN_PARAMETERS.patternHeight;
double targetAngleHorizontal=360*Math.atan(patternWidth/2/distanceToTarget)/Math.PI;
double targetAngleVertical= 360*Math.atan(patternHeight/2/distanceToTarget)/Math.PI;
if (DEBUG_LEVEL>0) System.out.println(
"Using:\n"+
"Distance from target: "+IJ.d2s(distanceToTarget,1)+" mm\n"+
" Taget width: "+IJ.d2s(patternWidth,1)+" mm\n"+
" Taget height: "+IJ.d2s(patternHeight,1)+" mm\n"+
"Taget angular size horizontal: "+IJ.d2s(targetAngleHorizontal,1)+" degrees\n"+
"Taget angular size vertical: "+IJ.d2s(targetAngleVertical,1)+" degrees\n"
);
GONIOMETER.debugLevel=DEBUG_LEVEL;
/// POWER_CONTROL.lightsOnWithDelay();
boolean goniometerScanOK=GONIOMETER.scanAndAcquire(
targetAngleHorizontal,
targetAngleVertical,
this.SYNC_COMMAND.stopRequested,
UPDATE_STATUS);
System.out.println ("GONIOMETER.scanAndAcquireI() "+(goniometerScanOK?"finished OK":"failed"));
/// POWER_CONTROL.lightsOff();
return;
}
/* ======================================================================== */
......@@ -9706,6 +9514,347 @@ if (MORE_BUTTONS) {
}
/* ===== Other methods ==================================================== */
/* ======================================================================== */
/* ======================================================================== */
/* ======================================================================== */
/* ======================================================================== */
public void processCalibrationFiles() {
if (!showProcessCalibrationFilesDialog(PROCESS_PARAMETERS)) return;
boolean noMessageBoxes=false; //TODO: move to configuration
long startTime=System.nanoTime();
long tmpTime;
String resultPath;
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
int loop_debug_level=1;
String [][][] filePaths=null;
int dirNum, fileNum;
ImageStack stack;
ImagePlus imp_psf;
File file;
String fileName;
if (PROCESS_PARAMETERS.processSourceImages) {
if ((PROCESS_PARAMETERS.sourceSuperDirectory==null) || (PROCESS_PARAMETERS.sourceSuperDirectory.length()==0)) {
fileName= selectSourceDirectory(PROCESS_PARAMETERS.sourceSuperDirectory);
if (fileName!=null) PROCESS_PARAMETERS.sourceSuperDirectory=fileName;
}
if ((PROCESS_PARAMETERS.partialKernelsSuperDirectory==null) || (PROCESS_PARAMETERS.partialKernelsSuperDirectory.length()==0)) {
fileName= selectPartialKernelsDirectory(PROCESS_PARAMETERS.partialKernelsSuperDirectory);
if (fileName!=null) PROCESS_PARAMETERS.partialKernelsSuperDirectory=fileName;
}
filePaths=prepareCalibrationFilesList(PROCESS_PARAMETERS);
if (filePaths==null) {
IJ.showMessage("Error","No files to process\nProcess canceled");
return;
}
startTime=System.nanoTime(); // restart timer after possible interactive dialogs
for (dirNum=0;dirNum<filePaths.length; dirNum++) {
if (filePaths[dirNum]!=null){
if (DEBUG_LEVEL>1) System.out.println("======= directory number="+dirNum+", number of files="+filePaths[dirNum].length+" ========");
for (fileNum=0;fileNum<filePaths[dirNum].length; fileNum++) {
if (DEBUG_LEVEL>1) System.out.println(filePaths[dirNum][fileNum][0] +" ==> "+filePaths[dirNum][fileNum][1]);
imp_sel=JP4_INSTANCE.open(
"", // path,
filePaths[dirNum][fileNum][0],
"", //arg - not used in JP46 reader
true, // un-apply camera color gains
imp_sel); // reuse the same image window
//Remove for old method?
matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize);
matchSimulatedPattern.calculateDistortions(
DISTORTION, //
PATTERN_DETECT,
SIMUL,
COMPONENTS.equalizeGreens,
imp_sel,
null, // LaserPointer laserPointer, // LaserPointer object or null
true, // don't care -removeOutOfGridPointers
null, // double [][][] hintGrid, // predicted grid array (or null)
0, // double hintGridTolerance, // alllowed mismatch (fraction of period) or 0 - orientation only
THREADS_MAX,
UPDATE_STATUS,
DEBUG_LEVEL,
DISTORTION.loop_debug_level, // debug level
noMessageBoxes);
SIM_ARRAY= (new SimulationPattern(SIMUL)).simulateGridAll (
imp_sel.getWidth(),
imp_sel.getHeight(),
matchSimulatedPattern,
2, // gridFrac, // number of grid steps per pattern full period
SIMUL,
THREADS_MAX,
UPDATE_STATUS,
DEBUG_LEVEL,
DISTORTION.loop_debug_level); // debug level
createPSFMap(
matchSimulatedPattern,
matchSimulatedPattern.applyFlatField (imp_sel), // if grid is flat-field calibrated, apply it
null, // int [][][] sampleList, // optional (or null) 2-d array: list of coordinate pairs (2d - to match existent PSF_KERNEL_MAP structure)
MULTIFILE_PSF.overexposedMaxFraction,
SIMUL, //simulation parameters
MAP_FFT_SIZE, // scanImageForPatterns:FFT size
PATTERN_DETECT,
FFT_OVERLAP, // scanImageForPatterns:high-pass gaussian filter sigma when correlating power spectrum
FFT_SIZE, // maximal distance between maximum on spectrum and predicted maximum on autocorrelation of gamma(|spectrum|)
COMPONENTS,
PSF_SUBPIXEL, // maximal iterations when looking for local maximum
OTF_FILTER,
PSF_PARS, // step of the new map (should be multiple of map step)
PSF_PARS.minDefinedArea,
INVERSE.dSize, // size of square used in the new map (should be multiple of map step)
THREADS_MAX,
UPDATE_STATUS,
loop_debug_level);// debug level used inside loops
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
stack=mergeKernelsToStack(PSF_KERNEL_MAP);
if (stack!=null) {
imp_psf = new ImagePlus(filePaths[dirNum][fileNum][1], stack);
// if (DEBUG_LEVEL>1) imp_psf.show();
if (DEBUG_LEVEL>1) System.out.println("Saving result to"+filePaths[dirNum][fileNum][1]+ " at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
FileSaver fs=new FileSaver(imp_psf);
fs.saveAsTiffStack(filePaths[dirNum][fileNum][1]);
} else {
System.out.println("File "+filePaths[dirNum][fileNum][1]+ " has no useful PSF kernels - at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
}
}
}
}
}
if (PROCESS_PARAMETERS.combinePSFfiles) {
tmpTime=System.nanoTime();
if ((PROCESS_PARAMETERS.partialKernelsSuperDirectory==null) || (PROCESS_PARAMETERS.partialKernelsSuperDirectory.length()==0)) {
fileName= selectPartialKernelsDirectory(PROCESS_PARAMETERS.partialKernelsSuperDirectory);
if (fileName!=null) PROCESS_PARAMETERS.partialKernelsSuperDirectory=fileName;
}
filePaths=preparePartialKernelsFilesList(PROCESS_PARAMETERS);
startTime-=(System.nanoTime()-tmpTime); // do not count time used for selection of files
if (filePaths==null) {
IJ.showMessage("Error","No partila kernel files to process, finished in "+IJ.d2s(0.000000001*(System.nanoTime()-startTime),3)+ " seconds");
return;
}
String [] filenames;
for (dirNum=0;dirNum<filePaths.length; dirNum++) {
if ((filePaths[dirNum]!=null) && (filePaths[dirNum].length!=0)){
resultPath=filePaths[dirNum][0][1];
filenames=new String[filePaths[dirNum].length];
for (fileNum=0;fileNum<filenames.length;fileNum++) filenames[fileNum]=filePaths[dirNum][fileNum][0];
if (!combinePSFKernels (
INTERPOLATE,
MULTIFILE_PSF,
filenames,
resultPath,
SDFA_INSTANCE,
imp_sel, // re-use global
true, // saveResult,
false, // showResult,
UPDATE_STATUS,
DEBUG_LEVEL)) continue; // return; // no overlap, bad result kernel
}
}
}
if (PROCESS_PARAMETERS.interpolatePSFkernel) {
tmpTime=System.nanoTime();
if ((PROCESS_PARAMETERS.partialKernelsSuperDirectory==null) || (PROCESS_PARAMETERS.partialKernelsSuperDirectory.length()==0)) {
fileName= selectPartialKernelsDirectory(PROCESS_PARAMETERS.partialKernelsSuperDirectory);
if (fileName!=null) PROCESS_PARAMETERS.partialKernelsSuperDirectory=fileName;
}
IJ.showMessage("Notice","partialKernelsSuperDirectory="+PROCESS_PARAMETERS.partialKernelsSuperDirectory);
startTime-=(System.nanoTime()-tmpTime); // do not count time used for selection of files
filePaths=prepareInterpolateKernelsList(PROCESS_PARAMETERS);
for (fileNum=0;fileNum<filePaths.length;fileNum++) if ((filePaths[fileNum]!=null) && (filePaths[fileNum].length>0)) {
file=new File(filePaths[fileNum][0][0]);
if (!file.exists()) {
if (DEBUG_LEVEL>1) System.out.println("Raw PSF kernel stack file "+filePaths[fileNum][0][0]+" does not exist");
continue;
}
imp_psf=new ImagePlus(filePaths[fileNum][0][0]);
if (imp_psf.getStackSize()<3) {
System.out.println("Need a 3-layer stack with raw PSF kernels");
continue;
}
stack= interpolateKernelStack(imp_psf.getStack(), // Image stack, each slice consists of square kernels of one channel
INTERPOLATE,
UPDATE_STATUS); // update status info
imp_psf = new ImagePlus(filePaths[fileNum][0][1], stack);
if (DEBUG_LEVEL>2) {
imp_psf.getProcessor().resetMinAndMax(); // imp_psf will be reused
imp_psf.show();
}
if (DEBUG_LEVEL>1) System.out.println("Saving interpolation result to"+filePaths[fileNum][0][1]+ " at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
FileSaver fs=new FileSaver(imp_psf);
fs.saveAsTiffStack(filePaths[fileNum][0][1]);
}
}
if (PROCESS_PARAMETERS.invertKernels) {
tmpTime=System.nanoTime();
if ((PROCESS_PARAMETERS.partialKernelsSuperDirectory==null) || (PROCESS_PARAMETERS.partialKernelsSuperDirectory.length()==0)) {
fileName= selectPartialKernelsDirectory(PROCESS_PARAMETERS.partialKernelsSuperDirectory);
if (fileName!=null) PROCESS_PARAMETERS.partialKernelsSuperDirectory=fileName;
}
if ((PROCESS_PARAMETERS.kernelsDirectory==null) || (PROCESS_PARAMETERS.kernelsDirectory.length()==0)) {
fileName= selectKernelsDirectory(PROCESS_PARAMETERS.kernelsDirectory);
if (fileName!=null) PROCESS_PARAMETERS.kernelsDirectory=fileName;
}
startTime-=(System.nanoTime()-tmpTime); // do not count time used fro selection of files
filePaths=prepareInvertGaussianKernelsList(PROCESS_PARAMETERS, PROCESS_PARAMETERS.rpsfPrefix );
for (fileNum=0;fileNum<filePaths.length;fileNum++) if ((filePaths[fileNum]!=null) && (filePaths[fileNum].length>0)) {
file=new File(filePaths[fileNum][0][0]);
if (!file.exists()) {
if (DEBUG_LEVEL>0) System.out.println("Interpolated PSF kernel stack file "+filePaths[fileNum][0][0]+" does not exist");
continue;
}
imp_psf=new ImagePlus(filePaths[fileNum][0][0]);
if (imp_psf.getStackSize()<3) {
System.out.println("Need a 3-layer stack with interpolated PSF kernels");
continue;
}
stack= reversePSFKernelStack(imp_psf.getStack(), // stack of 3 32-bit (float) images, made of square kernels
INVERSE,
THREADS_MAX, // size (side of square) of reverse PSF kernel
UPDATE_STATUS); // update status info
imp_psf = new ImagePlus(filePaths[fileNum][0][1], stack);
if (DEBUG_LEVEL>2) {
imp_psf.getProcessor().resetMinAndMax(); // imp_psf will be reused
imp_psf.show();
}
if (DEBUG_LEVEL>0) System.out.println("Saving PSF inversion result to"+filePaths[fileNum][0][1]+ " at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
FileSaver fs=new FileSaver(imp_psf);
fs.saveAsTiffStack(filePaths[fileNum][0][1]);
}
}
if (PROCESS_PARAMETERS.gaussianKernels) {
tmpTime=System.nanoTime();
if ((PROCESS_PARAMETERS.partialKernelsSuperDirectory==null) || (PROCESS_PARAMETERS.partialKernelsSuperDirectory.length()==0)) {
fileName= selectPartialKernelsDirectory(PROCESS_PARAMETERS.partialKernelsSuperDirectory);
if (fileName!=null) PROCESS_PARAMETERS.partialKernelsSuperDirectory=fileName;
}
if ((PROCESS_PARAMETERS.kernelsDirectory==null) || (PROCESS_PARAMETERS.kernelsDirectory.length()==0)) {
fileName= selectKernelsDirectory(PROCESS_PARAMETERS.kernelsDirectory);
if (fileName!=null) PROCESS_PARAMETERS.kernelsDirectory=fileName;
}
startTime-=(System.nanoTime()-tmpTime); // do not count time used fro selection of files
filePaths=prepareInvertGaussianKernelsList(PROCESS_PARAMETERS, PROCESS_PARAMETERS.gaussianPrefix);
for (fileNum=0;fileNum<filePaths.length;fileNum++) if ((filePaths[fileNum]!=null) && (filePaths[fileNum].length>0)) {
file=new File(filePaths[fileNum][0][0]);
if (!file.exists()) {
if (DEBUG_LEVEL>0) System.out.println("Interpolated PSF kernel stack file "+filePaths[fileNum][0][0]+" does not exist");
continue;
}
imp_psf=new ImagePlus(filePaths[fileNum][0][0]);
if (imp_psf.getStackSize()<3) {
System.out.println("Need a 3-layer stack with interpolated PSF kernels");
continue;
}
stack= generateGaussianStackFromDirect(imp_psf.getStack(), // stack of 3 32-bit (float) images, made of square kernels
INVERSE,
UPDATE_STATUS); // update status info
imp_psf = new ImagePlus(filePaths[fileNum][0][1], stack);
if (DEBUG_LEVEL>2) {
imp_psf.getProcessor().resetMinAndMax(); // imp_psf will be reused
imp_psf.show();
}
if (DEBUG_LEVEL>0) System.out.println("Saving Gaussian kernels result to"+filePaths[fileNum][0][1]+ " at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
FileSaver fs=new FileSaver(imp_psf);
fs.saveAsTiffStack(filePaths[fileNum][0][1]);
}
}
System.out.println("Processing done in "+IJ.d2s(0.000000001*(System.nanoTime()-startTime),3)+ " seconds");
if (PROCESS_PARAMETERS.saveSettings) saveProperties(PROCESS_PARAMETERS.kernelsDirectory+Prefs.getFileSeparator()+"calibration_settings",null,PROCESS_PARAMETERS.useXML, PROPERTIES);
return;
}
public void restore(boolean noAuto)
{
// boolean noAuto=label.equals("Restore no autoload");
ABERRATIONS_PARAMETERS.autoRestore=false;
String confPath=loadProperties(null,PROCESS_PARAMETERS.kernelsDirectory,PROCESS_PARAMETERS.useXML, PROPERTIES);
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
if (ABERRATIONS_PARAMETERS.autoRestore && !noAuto){
if (DEBUG_LEVEL>0)System.out.println("Auto-loading configuration files");
if (LENS_DISTORTIONS==null) {
LENS_DISTORTIONS=new Distortions(LENS_DISTORTION_PARAMETERS,PATTERN_PARAMETERS,REFINE_PARAMETERS,this.SYNC_COMMAND.stopRequested);
}
LENS_DISTORTIONS.debugLevel=DEBUG_LEVEL;
boolean dcdUpdated=autoLoadFiles(
ABERRATIONS_PARAMETERS,
LENS_DISTORTIONS, // should be initialized, after update DISTORTION_CALIBRATION_DATA from this
PATTERN_PARAMETERS,
EYESIS_CAMERA_PARAMETERS, //EyesisCameraParameters eyesisCameraParameters,
UPDATE_STATUS,
DEBUG_LEVEL
);
if (dcdUpdated) DISTORTION_CALIBRATION_DATA=LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData;
if (ABERRATIONS_PARAMETERS.autoReCalibrate){
if (LENS_DISTORTIONS.fittingStrategy==null) {
IJ.showMessage("Can not recalibrate grids - LENS_DISTORTION.fittingStrategy is not set");
return;
}
if (DEBUG_LEVEL>0)System.out.println("=== Re-calibrating grids ===");
int numMatched=LENS_DISTORTIONS.applyHintedGrids(
LASER_POINTERS, // MatchSimulatedPattern.LaserPointer laserPointer, // LaserPointer object that specifies actual laser poiners on the target
DISTORTION_PROCESS_CONFIGURATION.removeOutOfGridPointers, // boolean removeOutOfGridPointers,
5.0, //double hintGridTolerance, // alllowed mismatch (fraction of period) or 0 - orientation only
true, //boolean processAll, // if true - process all images, false - only disabeld
false, //?
false, //processBlind,
-1, // imageNumber,
true, // useSetData - use imageSets data if available (false - use camera data)
THREADS_MAX, //int threadsMax,
UPDATE_STATUS, // boolean updateStatus,
DISTORTION.loop_debug_level, // int mspDebugLevel,
MASTER_DEBUG_LEVEL, //int global_debug_level, // DEBUG_LEVEL
MASTER_DEBUG_LEVEL //int debug_level // debug level used inside loops
);
System.out.println("Number of matched images: "+numMatched);
LENS_DISTORTIONS.debugLevel=DEBUG_LEVEL;
LENS_DISTORTIONS.updateStatus=UPDATE_STATUS;
LENS_DISTORTIONS.fittingStrategy.debugLevel=DEBUG_LEVEL;
LENS_DISTORTIONS.markBadNodces(
-1,// series - all images
DEBUG_LEVEL);
}
if ((LENS_DISTORTIONS.fittingStrategy != null) && ABERRATIONS_PARAMETERS.autoFilter) { // trying to fix restore
if (DEBUG_LEVEL>0) System.out.println("LENS_DISTORTIONS.fittingStrategy != null -> Extra after loading");
int minGridsNoPointer=1000;
int [] numImages=DISTORTION_CALIBRATION_DATA.filterImages(
false, // resetHinted,
0, // 2, // minPointers,
0.4, // minGridPeriod,
true, // disableNoVignetting,
minGridsNoPointer); //minGridsNoPointer);
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 with no lasers and enableNoLaser==false (like 2 bottom cameras - check all stations):" +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\"): ");
DISTORTION_CALIBRATION_DATA.updateSetOrientation(null); // restore orientation from (enabled) image files
if (DEBUG_LEVEL>0) System.out.println("Setting sets orientation from per-grid image data");
}
}
restoreFocusingHistory(false);
}
return;
}
public void viewCSVFile(){
String [] extensions={".csv","CSV"};
CalibrationFileManagement.MultipleExtensionsFileFilter parFilter = new CalibrationFileManagement.MultipleExtensionsFileFilter("",extensions,"CSV table *.csv files");
......@@ -14819,6 +14968,7 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) {
boolean select_ABERRATIONS_PARAMETERS=!select;
boolean select_FOCUSING_FIELD=!select;
boolean select_POWER_CONTROL=!select;
boolean select_LWIR=!select;
if (select) {
GenericDialog gd = new GenericDialog("Select parameters to save");
gd.addMessage("===== Individual parameters ======");
......@@ -14859,6 +15009,7 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) {
gd.addCheckbox("ABERRATIONS_PARAMETERS",select_ABERRATIONS_PARAMETERS);
gd.addCheckbox("FOCUSING_FIELD",select_FOCUSING_FIELD);
gd.addCheckbox("POWER_CONTROL",select_POWER_CONTROL);
gd.addCheckbox("LWIR",select_LWIR);
WindowTools.addScrollBars(gd);
gd.showDialog();
......@@ -14900,6 +15051,7 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) {
select_ABERRATIONS_PARAMETERS=gd.getNextBoolean();
select_FOCUSING_FIELD=gd.getNextBoolean();
select_POWER_CONTROL=gd.getNextBoolean();
select_LWIR=gd.getNextBoolean();
}
if (select_MASTER_DEBUG_LEVEL) properties.setProperty("MASTER_DEBUG_LEVEL", MASTER_DEBUG_LEVEL+"");
......@@ -14939,6 +15091,7 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) {
if (select_ABERRATIONS_PARAMETERS) ABERRATIONS_PARAMETERS.setProperties("ABERRATIONS_PARAMETERS.", properties);
if ((select_FOCUSING_FIELD) && (FOCUSING_FIELD!=null)) FOCUSING_FIELD.setProperties("FOCUSING_FIELD.", properties);
if (select_POWER_CONTROL) POWER_CONTROL.setProperties("POWER_CONTROL.", properties);
if (select_LWIR) LWIR_PARAMETERS.setProperties("LWIR.", properties);
if (select) properties.remove("selected");
}
......@@ -14981,6 +15134,7 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) {
ABERRATIONS_PARAMETERS.getProperties("ABERRATIONS_PARAMETERS.", properties);
if (FOCUSING_FIELD!=null) FOCUSING_FIELD.getProperties("FOCUSING_FIELD.", properties,false); // false -> overwrite distortions center
POWER_CONTROL.getProperties("POWER_CONTROL.", properties);
LWIR_PARAMETERS.getProperties("LWIR.", properties);
}
private String selectSourceDirectory(String defaultPath) {
......@@ -29,12 +29,10 @@ package com.elphel.imagej.calibration;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicInteger;
import com.elphel.imagej.calibration.CalibrationHardwareInterface.CamerasInterface;
import com.elphel.imagej.calibration.CalibrationHardwareInterface.GoniometerMotors;
import com.elphel.imagej.calibration.SimulationPattern.SimulParameters;
import com.elphel.imagej.cameras.EyesisCameraParameters;
import com.elphel.imagej.common.ShowDoubleFloatArrays;
import com.elphel.imagej.common.WindowTools;
import com.elphel.imagej.lwir.LwirReader;
import ij.IJ;
import ij.ImagePlus;
......@@ -53,6 +51,7 @@ horizontal axis:
// for
// debugging
public CalibrationHardwareInterface.CamerasInterface cameras = null;
LwirReader lwirReader = null;
// public CalibrationHardwareInterface.LaserPointers lasers = null;
// public static CalibrationHardwareInterface.FocusingMotors motorsS=null;
// public DistortionProcessConfiguration
......@@ -81,7 +80,6 @@ horizontal axis:
public Goniometer(CalibrationHardwareInterface.CamerasInterface cameras,
MatchSimulatedPattern.DistortionParameters distortionParametersDefault,
// MatchSimulatedPattern.DistortionParameters distortion,
MatchSimulatedPattern.PatternDetectParameters patternDetectParameters,
EyesisCameraParameters eyesisCameraParameters,
MatchSimulatedPattern.LaserPointer laserPointers,
......@@ -98,9 +96,34 @@ horizontal axis:
this.simulParametersDefault=simulParametersDefault;
this.goniometerParameters=goniometerParameters;
this.distortionProcessConfiguration=distortionProcessConfiguration;
}
public Goniometer(
LwirReader lwirReader,
// CalibrationHardwareInterface.CamerasInterface cameras,
MatchSimulatedPattern.DistortionParameters distortionParametersDefault,
MatchSimulatedPattern.PatternDetectParameters patternDetectParameters,
EyesisCameraParameters eyesisCameraParameters,
MatchSimulatedPattern.LaserPointer laserPointers,
SimulationPattern.SimulParameters simulParametersDefault,
Goniometer.GoniometerParameters goniometerParameters,
DistortionProcessConfiguration distortionProcessConfiguration
) {
this.lwirReader= lwirReader;
// this.cameras = cameras;
this.distortionParametersDefault = distortionParametersDefault;
// this.distortion = distortion;
this.patternDetectParameters=patternDetectParameters;
this.eyesisCameraParameters = eyesisCameraParameters;
this.laserPointers = laserPointers;
this.simulParametersDefault=simulParametersDefault;
this.goniometerParameters=goniometerParameters;
this.distortionProcessConfiguration=distortionProcessConfiguration;
}
//goniometerMotors
private enum MOT_ACT {
MOVE_SPEC,
......@@ -222,6 +245,8 @@ horizontal axis:
if (!OK) System.out.println("motorsMove()->false");
return true; // OK; // So will re-open dialog even after abort
}
public boolean scanAndAcquire(
double targetAngleHorizontal,
double targetAngleVertical,
......@@ -276,7 +301,6 @@ horizontal axis:
double cosMinAbsTilt=Math.cos(minAbsTilt*Math.PI/180.0);
if (this.debugLevel>2) System.out.println("tilt="+IJ.d2s(tilt,2)+"tiltL="+IJ.d2s(tiltL,2)+", tiltH="+IJ.d2s(tiltH,2)+
", minAbsTilt="+IJ.d2s(minAbsTilt,2)+", cosMinAbsTilt="+IJ.d2s(cosMinAbsTilt,2));
// double axialRange=
double scanStep=scanStepAxial;
double overlap=scanOverlapHorizontal;
int numAxialSteps=(int) Math.ceil((scanLimitAxialHigh-scanLimitAxialLow)*cosMinAbsTilt/scanStepAxial);
......@@ -296,8 +320,6 @@ horizontal axis:
// spread evenly
if (numAxialSteps>0){ // increase vertical overlap to make it same for all images
// scanStep=(scanLimitAxialHigh-scanLimitAxialLow)*cosMinAbsTilt/numAxialSteps;
// overlap=1.0-(scanStep/targetAngleHorizontal);
scanStep=(scanLimitAxialHigh-scanLimitAxialLow)/numAxialSteps;
overlap=1.0-(scanStep*cosMinAbsTilt/targetAngleHorizontal);
}
......@@ -322,14 +344,8 @@ horizontal axis:
System.out.println();
}
}
// return true;
// motorsSimultaneous
// show current tilt/axial
// double absTiltRange=Math.abs(this.goniometerParameters.scanLimitTiltStart-this.goniometerParameters.scanLimitTiltStart);
GenericDialog gd = new GenericDialog("Start scanning");
// this.serialNumber, // camera serial number string
gd.addMessage("About to start scanning and recording images, parameters are set in the \"Configure Goniometer\" dialog");
gd.addMessage("Please make sure goniometer motors are set that 0,0 corresponds to the camera in the initial position -");
gd.addMessage("vertical and cables are not entangled, camera exposure is set correctly.");
......@@ -389,7 +405,6 @@ horizontal axis:
if (this.debugLevel>0) System.out.println(status);
if (updateStatus) IJ.showStatus(status);
this.goniometerParameters.motorsSimultaneous=false; // not yet implemented
// if (!this.goniometerParameters.motorsSimultaneous){
OK= this.goniometerParameters.goniometerMotors.moveMotorSetETA(tiltMotor, tiltMotorPosition);
if (!OK) {
String msg="Could not set motor "+(tiltMotor+1)+" to move to "+tiltMotorPosition+" - may be out of limit";
......@@ -433,10 +448,19 @@ horizontal axis:
}
// update motor positions in the image properties, acquire and save images.
// TODO: Make acquisition/decoding/laser identification multi-threaded
if (cameras != null) {
this.cameras.setMotorsPosition(this.goniometerParameters.goniometerMotors.getTargetPositions()); // Used target, not current to prevent minor variations
this.cameras.reportTiming=debugTiming;
this.cameras.acquire(this.distortionProcessConfiguration.sourceDirectory,true, updateStatus); // true - use lasers, updateStatus - make false?
} else if (lwirReader != null) {
this.lwirReader.setMotorsPosition(this.goniometerParameters.goniometerMotors.getTargetPositions()); // Used target, not current to prevent minor variations
this.lwirReader.reportTiming=debugTiming;
this.lwirReader.acquire(this.distortionProcessConfiguration.sourceDirectory); // true - use lasers, updateStatus - make false?
} else {
System.out.println("Neignter traditional camera/rig, no LWIR rig are initialized, dry run");
}
this.lastScanStep++;
if (stopRequested.get()>1){
if (this.debugLevel>0) System.out.println("User interrupt");
......@@ -1185,6 +1209,7 @@ horizontal axis:
this.scanBidirectional=scanBidirectional;
this.motorsSimultaneous=motorsSimultaneous;
}
@Override
public GoniometerParameters clone(){
return new GoniometerParameters(
this.goniometerMotors,
......
......@@ -4873,10 +4873,10 @@ private Panel panel1,
if (LWIR_READER == null) {
LWIR_READER = new LwirReader(CLT_PARAMETERS.lwir);
}
ImagePlus [] imps = LWIR_READER.acquire();
ImagePlus [] imps = LWIR_READER.acquire("/data_ssd/imagej-elphel/attic/camera_img/test"); // directory to save
if (imps != null) {
for (ImagePlus imp: imps) {
imp.show();
// imp.show();
}
}
......
......@@ -26,6 +26,7 @@
*/
package com.elphel.imagej.lwir;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Properties;
......@@ -40,9 +41,13 @@ import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import com.elphel.imagej.readers.ImagejJp4Tiff;
import com.elphel.imagej.readers.ImagejJp4TiffMulti;
import ij.IJ;
import ij.ImagePlus;
import ij.Prefs;
import ij.io.FileSaver;
import ij.process.FloatProcessor;
import ij.process.ImageProcessor;
import loci.formats.FormatException;
......@@ -68,7 +73,7 @@ public class LwirReader {
public static final int LWIR_HEIGHT = 120;
public static final int LWIR_TELEMETRY_LINES = 2;
public static final int FRAMES_SKIP = 3;
public static final int FRAMES_SKIP = 4;
public static final int MAX_THREADS = 100; // combine from all classes?
/** Logger for this class. */
......@@ -82,6 +87,10 @@ public class LwirReader {
private LwirReaderParameters lwirReaderParameters = null;
private LwirReaderParameters last_programmed = null;
private int [] motorsPosition = null;
public boolean reportTiming=false;
// -- constructors
public LwirReader() {
......@@ -99,6 +108,15 @@ public class LwirReader {
}
public void setMotorsPosition (int [] position) {
this.motorsPosition=position;
}
public int [] getMotorsPosition() {
return this.motorsPosition; // may be null
}
// TODO: create
public boolean reSyncNeeded() {
return out_of_sync;
......@@ -220,6 +238,10 @@ public class LwirReader {
imps_avg[chn].setProperty(key, properties0.getProperty(key));
}
imps_avg[chn].setProperty("average", ""+num_frames);
if (motorsPosition!=null) for (int m=0;m<motorsPosition.length;m++ ) {
imps_avg[chn].setProperty("MOTOR"+(m+1), ""+motorsPosition[m]);
}
ImagejJp4Tiff.encodeProperiesToInfo(imps_avg[chn]);
// TODO: Overwrite some properties?
}
......@@ -333,10 +355,12 @@ public class LwirReader {
for (int c : lrp.lwir_channels) {
channels |= 1 << c;
}
String hex_chan = String.format("%x", channels);
String hex_chan = String.format("0x%x", channels);
String url = "http://"+lrp.lwir_ip+"/parsedit.php?immediate&sensor_port="+chn+
"&SENSOR_REGS67=0!"+hex_chan;
// String url = "http://"+lrp.lwir_ip+"/parsedit.php?immediate&sensor_port="+chn+
// "&SENSOR_REGS67=0&*SENSOR_REGS67="+hex_chan;
Document dom=null;
LOGGER.warn("calibrate(): Perform calibration (instead of 15 frames), url="+url);
try {
......@@ -415,12 +439,12 @@ public class LwirReader {
return true;
}
public ImagePlus [] acquire() {
return acquire(lwirReaderParameters);
public ImagePlus [] acquire(String dirpath) {
return acquire(lwirReaderParameters, dirpath);
}
public ImagePlus [] acquire(LwirReaderParameters lrp) {
public ImagePlus [] acquire(LwirReaderParameters lrp, String dirpath) {
if (!condProgramLWIRCamera(lrp)) {
LOGGER.error("acquire(): failed to program cameras");
return null;
......@@ -439,6 +463,20 @@ public class LwirReader {
return null;
}
LOGGER.debug("LWIR_ACQUIRE: got "+imps.length+" image sets");
// Verify fresh FFC for all channels
double [] after_ffc = new double [lrp.lwir_channels.length];
for (int chn = 0; chn < after_ffc.length; chn++) {
double uptime = Double.NaN, ffctime = Double.NaN;
try {
uptime = Double.parseDouble(((String) imps[0][chn].getProperty("TLM_UPTIME")));
ffctime = Double.parseDouble(((String) imps[0][chn].getProperty("TLM_FFC_TIME")));
after_ffc[chn] = uptime-ffctime;
} catch (Exception e) {
LOGGER.warn("acquire(): TLM_UPTIME and/or TLM_FFC_TIME properties are not available for"+imps[0][chn].getTitle());
}
LOGGER.warn(String.format("LWIR channel %d time from FFC: %.3f", chn, after_ffc[chn]));
}
int [] lags = new int [lrp.lwir_channels.length + lrp.vnir_channels.length];
for (int i = 0; i < lags.length; i++) {
lags[i] = (i >= lrp.lwir_channels.length) ? lrp.vnir_lag : 0;
......@@ -464,6 +502,27 @@ public class LwirReader {
}
}
ImagePlus [] imps_avg = averageMultiFrames(imps_sync);
if (dirpath != null) {
File f_dir = new File(dirpath);
// get series path from the first channel file title
String first_name = imps_sync[0][0].getTitle();
String set_name = first_name.substring(0, first_name.lastIndexOf('_'));
String set_path = dirpath+Prefs.getFileSeparator()+set_name;
File set_dir = new File(set_path);
set_dir.mkdirs(); // including parent
for (ImagePlus imp:imps_avg) {
String fname = imp.getTitle();
fname = fname.substring(0, fname.lastIndexOf('_')) + ".tiff"; // remove _average
FileSaver fs=new FileSaver(imp);
String path=set_path+Prefs.getFileSeparator()+fname;
IJ.showStatus("Saving "+path);
LOGGER.debug("LWIR_ACQUIRE: 'Saving "+path+ " (and other with the same timestamp)" );
fs.saveAsTiff(path);
}
}
return imps_avg;
}
......
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