Commit 782eb01a authored by Andrey Filippov's avatar Andrey Filippov

pending commits while working on LWIR16 calibration

parent 016b8b7c
......@@ -1041,6 +1041,8 @@ if (MORE_BUTTONS) {
addButton("Goniometer Move", panelLWIR,color_debug);
addButton("LWIR Goniometer", panelLWIR,color_conf_process);
addButton("LWIR grids", panelLWIR,color_process);
addButton("LWIR15 GEOM", panelLWIR,color_configure);
addButton("Import Subsystem", panelLWIR,color_configure);
addButton("Select LWIR grids", panelLWIR,color_configure);
addButton("Grid offset", panelLWIR,color_process);
......@@ -5822,7 +5824,7 @@ if (MORE_BUTTONS) {
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(
if (DEBUG_LEVEL>-1) System.out.println(
"Using:\n"+
"Distance from target: "+IJ.d2s(distanceToTarget,1)+" mm\n"+
" Taget width: "+IJ.d2s(patternWidth,1)+" mm\n"+
......@@ -9387,6 +9389,7 @@ if (MORE_BUTTONS) {
/* ======================================================================== */
if (label.equals("LWIR_ACQUIRE")) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
/*
ImagePlus [][] imps;
if (LWIR_PARAMETERS.isLwir16()) {
if (LWIR16_READER == null) {
......@@ -9403,6 +9406,49 @@ if (MORE_BUTTONS) {
LWIR_READER.acquire(DISTORTION_PROCESS_CONFIGURATION.sourceDirectory); // directory to save
// ImagePlus [] imps = LWIR_READER.acquire("attic/lwir_test_images"); // directory to save
}
*/
if ((GONIOMETER==null) || (LWIR_PARAMETERS.isLwir16()?(GONIOMETER.lwir16Reader == null):(GONIOMETER.lwirReader == null))) {
if (LWIR_PARAMETERS.isLwir16()) {
if (LWIR16_READER == null) {
LWIR16_READER = new Lwir16Reader(LWIR_PARAMETERS);
}
GONIOMETER= new Goniometer(
LWIR16_READER,
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);
LWIR16_READER.setMotorsPosition(GONIOMETER_PARAMETERS.goniometerMotors.getCurrentPositions()); // getTargetPositions()); // Used target, not current to prevent minor variations
} else {
if (LWIR_READER == null) {
LWIR_READER = new LwirReader(LWIR_PARAMETERS);
}
GONIOMETER= new Goniometer(
LWIR_READER,
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);
LWIR_READER.setMotorsPosition(GONIOMETER_PARAMETERS.goniometerMotors.getCurrentPositions()); // getTargetPositions()); // Used target, not current to prevent minor variations
}
if (DEBUG_LEVEL>1){
System.out.println("Initialized Goniometer class for "+LWIR_PARAMETERS.getCameraName());
}
} else if (DEBUG_LEVEL>1){
System.out.println("GONIOMETER was initialized for "+LWIR_PARAMETERS.getCameraName());
}
if (LWIR_PARAMETERS.isLwir16()) {
LWIR16_READER.acquire(DISTORTION_PROCESS_CONFIGURATION.sourceDirectory); // directory to save
} else {
LWIR_READER.acquire(DISTORTION_PROCESS_CONFIGURATION.sourceDirectory); // directory to save
}
return;
}
......@@ -9451,7 +9497,7 @@ if (MORE_BUTTONS) {
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(
if (DEBUG_LEVEL>-1) System.out.println(
"Using:\n"+
"Distance from target: "+IJ.d2s(distanceToTarget,1)+" mm\n"+
" Taget width: "+IJ.d2s(patternWidth,1)+" mm\n"+
......@@ -9475,6 +9521,12 @@ if (MORE_BUTTONS) {
calculateLwirGrids();
return;
}
/* ======================================================================== */
if (label.equals("LWIR15 GEOM")) {
EYESIS_CAMERA_PARAMETERS.setLwir16Geometry();
return;
}
/* ======================================================================== */
if (label.equals("Import Subsystem")) {
importSystem(null, "EYESIS_CAMERA_PARAMETERS.");
......@@ -9978,7 +10030,8 @@ if (MORE_BUTTONS) {
//DistortionProcessConfiguration
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
LENS_DISTORTIONS=new Distortions(LENS_DISTORTION_PARAMETERS,PATTERN_PARAMETERS,REFINE_PARAMETERS,this.SYNC_COMMAND.stopRequested);
int min_files = 8; // use folders that have all 8 files
// Maybe wrong ! Use folders that have at least all EO channels?
int min_files = lwirReaderParameters.getNumChannels();// 8; // use folders that have all 8 files
int lwir_chn0 = lwirReaderParameters.getLwirChn0();
int eo_chn0 = lwirReaderParameters.getEoChn0();
int numStations = 3;
......@@ -10011,7 +10064,7 @@ if (MORE_BUTTONS) {
for (int numStation=0;numStation<numStations;numStation++){
DirectoryChoser dc = new DirectoryChoser(
gridFilter,
min_files,
min_files, // not actually used
0,
null);
dc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
......@@ -10215,8 +10268,8 @@ if (MORE_BUTTONS) {
matchSimulatedPattern.invalidateFlatFieldForGrid(); //Reset Flat Field calibration - different image.
matchSimulatedPattern.invalidateFocusMask();
boolean is_lwir = LWIR_PARAMETERS.is_LWIR(imp_sel);
int numAbsolutePoints=matchSimulatedPattern.calculateDistortions(
boolean is_lwir = LWIR_PARAMETERS.is_LWIR(imp_sel); // Not used!
int numAbsolutePoints=matchSimulatedPattern.calculateDistortions( // matchSimulatedPattern.PATTERN_GRID already set
LWIR_PARAMETERS, // LwirReaderParameters lwirReaderParameters,
DISTORTION, //
PATTERN_DETECT,
......@@ -11543,7 +11596,7 @@ if (MORE_BUTTONS) {
} else {
System.out.println("No pattern grid file (ground gtruth) is provided");
}
if ((configPaths[3] !=null) && (configPaths[3] != "")){ // load sensor
if ((configPaths[3] !=null) && !configPaths[3].equals("")){ // load sensor
if (distortions.fittingStrategy==null) return false; // Why?
if (DEBUG_LEVEL>0) System.out.println("Autoloading sensor calibration files "+configPaths[3]);
distortions.setDistortionFromImageStack(
......@@ -25,6 +25,7 @@ package com.elphel.imagej.calibration;
import java.io.File;
import java.io.FilenameFilter;
import java.util.Arrays;
import java.util.Properties;
import com.elphel.imagej.common.WindowTools;
......@@ -223,8 +224,10 @@ import ij.gui.GenericDialog;
return new File(current, name).isDirectory();
}
});
// TODO:Sort set list
String [] sourceSets = new String[sourceFileSets.length];
for (int i=0;i<sourceSets.length;i++) sourceSets[i]=sourceFileSets[i].getPath();
Arrays.sort(sourceSets);
return sourceSets;
}
......
......@@ -520,6 +520,10 @@ public class Distortions {
/* double [] XYZM=patternParameters.getXYZM( // will throw if outside or masked out
fittingStrategy.distortionCalibrationData.gIP[imgNum].pixelsUV[pointNumber][0],
fittingStrategy.distortionCalibrationData.gIP[imgNum].pixelsUV[pointNumber][1]);*/
if ((targetXYZ[index]==null) || (XYZMP==null)) {
System.out.println("Null problem in imgNum="+imgNum+", point "+pointNumber);
continue;
}
this.targetXYZ[index][0]=XYZMP[0];
this.targetXYZ[index][1]=XYZMP[1];
this.targetXYZ[index][2]=XYZMP[2];
......@@ -3293,6 +3297,7 @@ For each point in the image
int global_debug_level, // DEBUG_LEVEL
int debug_level // debug level used inside loops
){
int debugThreshold0=0;
int debugThreshold=2;
MatchSimulatedPattern matchSimulatedPattern = new MatchSimulatedPattern(64); // new instance, all reset, FFTSize=64 will not be used
......@@ -3316,6 +3321,10 @@ For each point in the image
int numSuccess=0;
DistortionCalibrationData dcd=fittingStrategy.distortionCalibrationData;
for (int numGridImage=0;numGridImage<dcd.gIP.length;numGridImage++) {
if (numGridImage >= 1680) {
System.out.println("Processing debug image "+numGridImage);
System.out.println("Processing debug image "+numGridImage);
}
int set_number = dcd.gIP[numGridImage].getSetNumber();
if ((set_number >= start_set) &&
(set_number <= end_set) &&
......@@ -3338,6 +3347,17 @@ For each point in the image
}
}
}
if ((dcd.gIP[numGridImage].matchedPointers > 0) && !ignoreLaserPointers) { // just re-enable with the same shifts (will fail if pointers were just added, but it failed anyway)
if (!dcd.gIP[numGridImage].enabled) {
if (this.debugLevel>0) {
System.out.println("Re-enabling grid #"+numGridImage+" that has pointer(s) with the previously set UVShiftRot =={0,0,0}");
}
dcd.gIP[numGridImage].enabled = true;
dcd.gIP[numGridImage].newEnabled = true;
}
continue;
}
if (this.debugLevel>debugThreshold0) {
System.out.println("\n---- applyHintedGrids() image #"+numGridImage+" (imageNumber="+imageNumber+") "+
" dcd.gIP["+numGridImage+"].pixelsXY.length="+dcd.gIP[numGridImage].pixelsXY.length+
......@@ -3385,7 +3405,6 @@ For each point in the image
System.out.println("++++++ BUG: in applyHintedGrids() failed in createUV_INDEX()");
continue;
}
double [] goniometerTiltAxial=dcd.getImagesetTiltAxial(numGridImage);
if ((goniometerTiltAxial==null) || Double.isNaN(goniometerTiltAxial[0]) || Double.isNaN(goniometerTiltAxial[1])){
if (this.debugLevel>0) {
......@@ -3551,7 +3570,7 @@ For each point in the image
public int [][] getImageMarkers(int numGridImage){
String source_path=fittingStrategy.distortionCalibrationData.gIP[numGridImage].source_path;
if (source_path != null) {
final ImagePlus imp = new ImagePlus(source_path);
ImagePlus imp = new ImagePlus(source_path);
imp.show();
/*
Thread msg_box_thread = new Thread() {
......@@ -3580,6 +3599,25 @@ For each point in the image
System.out.println("This image does not have point marks - please mark it in "+source_path);
IJ.showMessage("This image does not have point marks - please mark it in "+source_path);
return null;
/*
boolean mark_and_continue = IJ.showMessageWithCancel("Mark and Continue", "This image does not have point marks - please mark it in "+source_path);
if (mark_and_continue) {
imp = new ImagePlus(source_path);
System.out.println("got it again!");
pointRoi = null;
if (imp.getRoi() instanceof PointRoi) {
pointRoi = (PointRoi) imp.getRoi();
} else {
System.out.println("This image does not have point marks - please mark it in "+source_path);
IJ.showMessage("This image does not have point marks - please mark it in "+source_path);
return null;
}
} else {
return null;
}
*/
}
Point [] points = pointRoi.getContainedPoints();
int [][] ipoints = new int [points.length][2];
......
......@@ -2016,6 +2016,9 @@ public class MatchSimulatedPattern {
ix = (interpolateXY[maxIndex][0] + j) % size;
for (int i = 0; i < 2; i++) {
iy = interpolateXY[maxIndex][1] + i; // next: OOB 2147483647
if (iy >= fft_complex.length) {
iy = fft_complex.length - 1; // was Index 17 out of bounds for length 17
}
interpolateAmplitudes[maxIndex][i][j] = Math.sqrt(fft_complex[iy][ix][0] * fft_complex[iy][ix][0]
+ fft_complex[iy][ix][1] * fft_complex[iy][ix][1]);
interpolatePhases[maxIndex][i][j] = Math.atan2(
......@@ -7688,7 +7691,7 @@ public class MatchSimulatedPattern {
int shiftSelect = (((shifts[0][0] - coeff[0][2]) * (shifts[0][0] - coeff[0][2]) + (shifts[0][1] - coeff[1][2])
* (shifts[0][1] - coeff[1][2])) > ((shifts[1][0] - coeff[0][2]) * (shifts[1][0] - coeff[0][2])
+ (shifts[1][1] - coeff[1][2]) * (shifts[1][1] - coeff[1][2]))) ? 1 : 0;
if (this.debugLevel > 1) {
if (this.debugLevel > 0) {
double d1 = Math.sqrt((shifts[0][0] - coeff[0][2]) * (shifts[0][0] - coeff[0][2])
+ (shifts[0][1] - coeff[1][2]) * (shifts[0][1] - coeff[1][2]));
double d2 = Math.sqrt((shifts[1][0] - coeff[0][2]) * (shifts[1][0] - coeff[0][2])
......@@ -8068,7 +8071,8 @@ public class MatchSimulatedPattern {
numCells++;
}
if (numCells > 0) {
setPatternGridArray(maxU - minU + 1, maxV - minV + 1);
// setPatternGridArray(maxU - minU + 1, maxV - minV + 1); // FIXME: Does nothing
this.PATTERN_GRID = setPatternGridArray(maxU - minU + 1, maxV - minV + 1); // FIXME: Does nothing
double[] xy = new double[2];
int[] uv = new int[2];
for (int i = 0; i < pixels[0].length; i++)
......
......@@ -2,6 +2,7 @@ package com.elphel.imagej.calibration;
import java.awt.Rectangle;
import java.util.Properties;
import com.elphel.imagej.common.PolynomialApproximation;
import com.elphel.imagej.jp4.JP46_Reader_camera;
/*
......@@ -743,6 +744,7 @@ import ij.io.Opener;
public double[] getXYZM(int u, int v, boolean verbose, int station){ // u=0,v=0 - center!
int u1=u+this.U0;
int v1=v+this.V0;
double r2 = 0.25;
if ((v1<0) || (u1<0) || (v1 >= this.gridGeometry.length) || (u1 >= this.gridGeometry[0].length) ||
(this.gridGeometry[v1][u1][3]==0)) {
if ((this.debugLevel>1) && verbose && ((v1<0) || (u1<0) || (v1 >= this.gridGeometry.length) || (u1 >= this.gridGeometry[0].length))){
......@@ -755,13 +757,68 @@ import ij.io.Opener;
return null;
}
if (this.stationZCorr==null) return this.gridGeometry[v1][u1];
double [] result=this.gridGeometry[v1][u1].clone();
double [] result = this.gridGeometry[v1][u1].clone();
// use lower station if grid file does not have current
int useStation=(this.stationZCorr[v1][u1].length>station)?station:(this.stationZCorr[v1][u1].length-1);
result[2]+=this.stationZCorr[v1][u1][useStation];
return result;
// return this.gridGeometry[v1][u1];
}
/**
* Use this for just initial orientation
* @param u
* @param v
* @param verbose
* @return {x,y,z}
*/
public double[] extrapolateXYZ(
double u,
double v,
boolean verbose){ // u=0,v=0 - center! No correction for stationZCorr - anyway it is not accurate outside
double u1 = u + this.U0;
double v1 = v + this.V0;
double r2 = 0.0001;
double [] result = null;
PolynomialApproximation pa = new PolynomialApproximation();
double [][][] data = new double[gridGeometry.length * gridGeometry[0].length][3][];
int di = 0;
for (int vg = 0; vg < gridGeometry.length; vg++) {
double dv2 = v1 - vg;
dv2 = dv2*dv2 + r2;;
for (int ug = 0; ug < gridGeometry[0].length; ug++) {
data[di][0] = new double[2];
data[di][0][0] = ug;
data[di][0][1] = vg;
data[di][1] = new double[3];
data[di][2] = new double[1];
if ((gridGeometry[vg][ug] != null) && (gridGeometry[vg][ug][3] > 0.0)){
data[di][1][0] = gridGeometry[vg][ug][0]; // x
data[di][1][1] = gridGeometry[vg][ug][1]; // y
data[di][1][2] = gridGeometry[vg][ug][2]; // z
double du = u1 - ug;
data[di][2][0] = gridGeometry[vg][ug][3] / (du*du + dv2);
}
di++;
}
}
double [][] coeff = pa.quadraticApproximation(
data,
true, // forceLinear, // use linear approximation
null); // damping,
if (coeff== null) return null;
result = new double[3]; // out of grid, so all but x,y,z are 0.0;
for (int i = 0; i < 3; i++) {
result[i] = coeff[i][0]*u1 + coeff[i][1]*v1 + coeff[i][2];
}
/*
if (this.stationZCorr==null) return result; // this.gridGeometry[v1][u1];
// use lower station if grid file does not have current
int useStation=(this.stationZCorr[v1][u1].length>station)?station:(this.stationZCorr[v1][u1].length-1);
result[2]+=this.stationZCorr[v1][u1][useStation];
*/
return result;
}
public double[] getXYZ(
double [] uv,
boolean verbose,
......@@ -776,8 +833,11 @@ import ij.io.Opener;
corn[2] = getXYZM(iu, iv + 1, verbose, station);
corn[3] = getXYZM(iu + 1, iv + 1, verbose, station);
if ((corn[0] == null) || (corn[1] == null) || (corn[2] == null) || (corn[3] == null)) {
System.out.println("Optical axis outside of the grid: TODO: modify getXYZM() to handle!");
return null;
if (verbose) {
System.out.println("Optical axis outside of the grid: TODO: modify getXYZM() to handle!");
}
return extrapolateXYZ (uv[0], uv[1], verbose);
// return null;
}
double [] rslt_xyz = new double[3];
rslt_xyz[0] = (1-fu) * (1-fv) * corn[0][0] + fu * (1-fv) * corn[1][0] + (1-fu) * fv * corn[2][0] + fu * fv * corn[3][0];
......@@ -915,7 +975,7 @@ import ij.io.Opener;
};
return result;
}
public double[] getXYZMPE(
public double[] getXYZMPE( // update this and other to interpolate
int u,
int v,
int station,
......
......@@ -68,7 +68,7 @@ import java.util.Properties;
public int subcamera = 0;
public int sensor_port = 0;
public int subchannel = 0;
public boolean lwir = false; // invert color for LWIR sensors
/*
Modifying to accommodate for eccentricity of different terms (2 parameters per term) and elliptical shape (another 2 terms). When all are
......@@ -115,7 +115,8 @@ import java.util.Properties;
double channelWeightDefault,
int subcamera,
int sensor_port,
int subchannel
int subchannel,
boolean lwir // LWIR camera with inverted color
){
this.decimateMasks = decimateMasks;
this.sensorWidth= sensorWidth;
......@@ -158,7 +159,7 @@ import java.util.Properties;
this.subcamera = subcamera;
this.sensor_port = sensor_port;
this.subchannel = subchannel;
this.lwir = lwir;
updateCartesian(); // set alternative
}
// defects are not cloned!
......@@ -197,7 +198,8 @@ import java.util.Properties;
this.channelWeightDefault,
this.subcamera,
this.sensor_port,
this.subchannel
this.subchannel,
this.lwir
);
}
public void setDefaultNonRadial(){
......@@ -247,8 +249,7 @@ import java.util.Properties;
properties.setProperty(prefix+"subcamera", this.subcamera+"");
properties.setProperty(prefix+"sensor_port", this.sensor_port+"");
properties.setProperty(prefix+"subchannel", this.subchannel+"");
properties.setProperty(prefix+"lwir", this.lwir+"");
}
public void getProperties(String prefix,Properties properties){
getProperties(prefix,properties, -1);
......@@ -333,7 +334,8 @@ import java.util.Properties;
this.sensor_port=Integer.parseInt(properties.getProperty(prefix+"sensor_port"));
if (properties.getProperty(prefix+"subchannel")!=null)
this.subchannel=Integer.parseInt(properties.getProperty(prefix+"subchannel"));
if (properties.getProperty(prefix+"lwir")!=null)
this.lwir=Boolean.parseBoolean(properties.getProperty(prefix+"lwir"));
}
public void setChannelWeightCurrent(
double weight){
......@@ -363,9 +365,14 @@ import java.util.Properties;
this.cartesian = cartesian;
}
public boolean isLWIR() {
return this.lwir;
}
public double getPixelSize() {
return this.pixelSize;
}
public double getDistortionRadius() {
return this.distortionRadius;
}
......
......@@ -88,7 +88,6 @@ public class Lwir16Reader {
public static final String SCRIPT_CAPTURE= "capture_range.php"; // capture synchronized images
public static final String SCRIPT_RESET= "reset_frames.php"; // Reset frame numbers
public static final String SCRIPT_WAIT= "wait_frame.php"; // wait for absolute frame (positive) or skip frames (nefative)
// will remove later
public static final String IMAGE_URL_FIRST="/towp/wait/img/save"; // next image name, same image number/time
public static final String SKIP_FRAME_URL= "/towp/wait/meta"; // Wait for the next frame, return meta data
......@@ -288,38 +287,6 @@ public class Lwir16Reader {
}
startAndJoin(threads);
/*
for (int chn = 0; chn < num_channels; chn++) {
int width = sets[0][chn].getWidth();
int height = sets[0][chn].getHeight();
String title = sets[0][chn].getTitle()+"_average"+num_frames;
float [] pixels_avg = (float []) sets[0][chn].getProcessor().getPixels(); //null pointer
for (int n = 1; n < num_frames; n++) {
float [] pixels = (float []) sets[n][chn].getProcessor().getPixels();
for (int i = 0; i < pixels_avg.length; i++) {
pixels_avg[i] += pixels[i];
}
}
double scale = 1.0/num_frames;
for (int i = 0; i < pixels_avg.length; i++) {
pixels_avg[i] *= scale;
}
ImageProcessor ip=new FloatProcessor(width,height);
ip.setPixels(pixels_avg);
ip.resetMinAndMax();
imps_avg[chn]= new ImagePlus(title, ip);
Properties properties0 = sets[0][chn].getProperties();
for (String key:properties0.stringPropertyNames()) {
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?
}
*/
return imps_avg;
}
......@@ -744,6 +711,7 @@ public class Lwir16Reader {
}
}
public double getFutureTimestamnp (String ip, double delay) { // delay in seconds from master
if (lwirReaderParameters.getDebugLevel() > 0) {
System.out.println("Increasing delay by 3.0s when there is some printing");
......@@ -797,22 +765,28 @@ public class Lwir16Reader {
* @param lrp
* @param delay
* @param duration -1 - start only, 0 - stop only, >0 - start+stop (LWIR cameras)
* @param duration_eo -1 - start only, 0 - stop only, >0 - start+stop (EO cameras)
* @param duration_eo -1 - start only, 0 - stop only, >0 - start+stop (EO cameras). If stop only - will wait for both masters
* @return <0 - error, >0 last frame of the master camera/port in sequence
*/
public int captureRange(LwirReaderParameters lrp, double delay, int duration, int duration_eo) {
boolean sync2eo = true;
int lwir_master_index = 0;
int num_lwir = lrp.getLwirIPs().length;
int eo_master_index = 4;
String [] all_ips = lrp.getAllIPs();
int num_lwir = lrp.getLwirIPs().length;
int [] port_masks= getPortMasks(lrp);
double target_ts = getFutureTimestamnp (lrp.getLwirIP(lwir_master_index), delay);
String master_ip = all_ips[sync2eo? eo_master_index : lwir_master_index];
double target_ts = getFutureTimestamnp (master_ip, delay);
if (Double.isNaN(target_ts)) {
return -1;
}
String [] all_ips = lrp.getAllIPs();
String [] urls = new String [all_ips.length];
for (int i = 0; i < urls.length; i++) {
int dur = (i>= num_lwir)?duration_eo:duration;
urls[i]=String.format("http://%s/%s?sensor_port=0&ts=%f&m=%d&d=%d", all_ips[i], SCRIPT_CAPTURE, target_ts, port_masks[i], dur);
if ((dur == 0) && ((i==lwir_master_index) || (i==eo_master_index))){
urls[i] += "&wait";
}
}
boolean OK = true;
Document [] docs = collectXmlResponses(urls);
......@@ -849,12 +823,19 @@ public class Lwir16Reader {
}
int master_frame = Integer.parseInt(((Node)
(((Node) docs[lwir_master_index].getDocumentElement().getElementsByTagName("frame").item(0)).getChildNodes().item(0))).getNodeValue());
if (lrp.getDebugLevel() > 0) System.out.println(String.format("master_frame=%d(0x%x)", master_frame,master_frame));
if ((lrp.getDebugLevel() > 0) && ((duration==0) || (duration_eo==0)) ) {
System.out.println(String.format("master_frame=%d(0x%x)", master_frame,master_frame));
for (int i = 0; i < urls.length; i++) {
System.out.println(i+": "+urls[i]);
}
}
// System.out.println("mater_frame = "+master_frame+", target_ts="+target_ts);
return master_frame;
}
public boolean startStopCompressor(LwirReaderParameters lrp, boolean start, double delay) {
if (lrp.getDebugLevel() > 0) System.out.println("startStopCompressor() start="+start);
// if (lrp.getDebugLevel() > 0) System.out.println("startStopCompressor() start="+start);
if (lrp.getDebugLevel() > -1) System.out.println("startStopCompressor() start="+start);
int duration = start? -1: 0;
int end_frame = captureRange(lrp, delay, duration, duration);
if (end_frame < 0) return false;
......@@ -1003,12 +984,13 @@ public class Lwir16Reader {
}
resetFrameBuffers(lrp); // actually only needed after stopping, here just in case
// start capturing frames into each camera buffer
int end_frame = captureRange(lrp, lrp.getAcquireDelay(), lrp.getAvgNumberLwir(),lrp.getAvgNumberEO());
// int end_frame =
captureRange(lrp, lrp.getAcquireDelay(), lrp.getAvgNumberLwir(),lrp.getAvgNumberEO());
// public static final String IMAGE_URL_NEXT= "/torp/next/wait/img/save"; // same image name, same image number/time
// public static final String IMAGE_URL_NEXT= "/torp/wait/img/next/save"; // same image name, same image number/time
int [] port_masks= getPortMasks(lrp);
String [] all_IPs = lrp.getAllIPs();
// int [] port_masks= getPortMasks(lrp);
// String [] all_IPs = lrp.getAllIPs();
final int num_lwir = lrp.getLwirIPs().length;
final int avg_lwir = lrp.getAvgNumberLwir();
final int avg_eo = lrp.getAvgNumberEO();
......@@ -1076,7 +1058,9 @@ public class Lwir16Reader {
public void run() {
for (int chn = indxAtomic.getAndIncrement(); chn < num_channels; chn = indxAtomic.getAndIncrement()) {
if (imgs[chn] != null) {
int num_frames = (chn < (num_lwir*IMGSRV_PORTS.length))? avg_lwir : avg_eo;
boolean is_lwir = chn < (num_lwir*IMGSRV_PORTS.length);
// int num_frames = (chn < (num_lwir*IMGSRV_PORTS.length))? avg_lwir : avg_eo;
int num_frames = is_lwir? avg_lwir : avg_eo;
if (num_frames > 0) {
float [] pixels_avg = (float []) imgs[chn].getProcessor().getPixels();
double scale = 1.0/num_frames;
......@@ -1090,6 +1074,9 @@ public class Lwir16Reader {
if (motorsPosition!=null) for (int m=0;m<motorsPosition.length;m++ ) {
imgs[chn].setProperty("MOTOR"+(m+1), ""+motorsPosition[m]);
}
imgs[chn].setProperty(
LwirReaderParameters.SENSOR_TYPE,
LwirReaderParameters.SENSOR_TYPES[is_lwir?1:0]);
ImagejJp4Tiff.encodeProperiesToInfo(imgs[chn]);
}
}
......@@ -1098,6 +1085,29 @@ public class Lwir16Reader {
};
}
startAndJoin(threads);
if (dirpath != null) {
File f_dir = new File(dirpath);
// get series path from the first channel file title
String first_name = imgs[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
LOGGER.warn("Saving image set to: "+set_dir.getAbsolutePath());
for (ImagePlus imp:imgs) {
String fname = imp.getTitle();
// fname = fname.substring(0, fname.lastIndexOf('_')) + ".tiff"; // remove _average
// fname = fname.substring(0, fname.lastIndexOf('.')) + ".tiff"; // remove _average
fname = fname + ".tiff"; // remove _average
FileSaver fs=new FileSaver(imp);
String path=set_path+Prefs.getFileSeparator()+fname;
IJ.showStatus("Saving "+path);
LOGGER.info("LWIR_ACQUIRE: 'Saving "+path );
fs.saveAsTiff(path);
}
}
if (lrp.isShowImages()) {
for (ImagePlus imp: imgs) {
imp.show();
......@@ -1159,7 +1169,9 @@ public class Lwir16Reader {
img_numbers[i] = -1;
}
img_names[i] = (String) imps[i].getProperty("CONTENT_FILENAME");
LOGGER.warn("Seconds for "+i+" - "+img_seconds[i]+", number"+img_numbers[i]+", name "+img_names[i]);
if (lrp.getDebugLevel() > 0) {
LOGGER.warn("Seconds for "+i+" - "+img_seconds[i]+", number"+img_numbers[i]+", name "+img_names[i]);
}
}
// Make a sparse array for all lwir+eo channels with nulls for channels that are not measured.
ImagePlus [] imps_all = new ImagePlus [all_IPs.length * IMGSRV_PORTS.length];
......@@ -1307,7 +1319,7 @@ public class Lwir16Reader {
}
}
}
skipMasterFrames(two_IPs, 4); // make sure all previous parameters are applied
skipMasterFrames(two_IPs, 4); // make sure all previous parameters are applied // waits for both LWIR and EO
// second reset after cameras running synchronously
OK &= resetAllFrames(lrp);
skipMasterFrames(two_IPs, 1);
......
......@@ -31,6 +31,7 @@ import java.io.FilenameFilter;
import java.util.Properties;
import com.elphel.imagej.common.GenericJTabbedDialog;
import com.elphel.imagej.readers.EyesisTiff;
import ij.ImagePlus;
import ij.Prefs;
......@@ -41,6 +42,8 @@ public class LwirReaderParameters {
public final static String [] CAMERA_NAMES= {NAME_TALON,NAME_LWIR16};
public final static int [] BOSON_FFC_FRAMES= {2,4,8,16};
public final static int [] FFC_GROUPS= {1,2,4};
public static final String [] SENSOR_TYPES = {"EO","LWIR"};
public static final String SENSOR_TYPE = "SENSOR_TYPE";
private boolean parameters_updated = false;
protected String camera_name = "Talon"; // "LWIR16";
......@@ -94,7 +97,7 @@ public class LwirReaderParameters {
protected boolean show_images = false;
protected int lwir_chn0 = 0; // not configurable
protected int eo_chn0 = 4; // not configurable
// protected int eo_chn0 = 4; // not configurable
public LwirReaderParameters() {
......@@ -104,7 +107,16 @@ public class LwirReaderParameters {
else if (NAME_LWIR16.equals(name)) camera_name = NAME_LWIR16;
}
public static boolean is_LWIR(String type) {
return ((type != null) && type.equals(SENSOR_TYPES[1]));
}
public static boolean is_EO(String type) {
return ((type != null) && type.equals(SENSOR_TYPES[1]));
}
public static String sensorName(boolean lwir) {
return SENSOR_TYPES[lwir?1:0];
}
// --- interface methods
public int getAvgNumberLwir() {
return avg_number;
.