Commit 4ffb8a32 authored by Andrey Filippov's avatar Andrey Filippov

working on calculating grids for low frequency pattern

parent 78aea970
...@@ -1413,9 +1413,13 @@ Exception in thread "Thread-3564" java.lang.ArrayIndexOutOfBoundsException: 8970 ...@@ -1413,9 +1413,13 @@ Exception in thread "Thread-3564" java.lang.ArrayIndexOutOfBoundsException: 8970
NodeList allNodes=doc.getDocumentElement().getElementsByTagName("*"); NodeList allNodes=doc.getDocumentElement().getElementsByTagName("*");
for (int i=0;i<allNodes.getLength();i++) { for (int i=0;i<allNodes.getLength();i++) {
String name= allNodes.item(i).getNodeName(); String name= allNodes.item(i).getNodeName();
String value=allNodes.item(i).getFirstChild().getNodeValue(); String value="";
imp.setProperty(name, value); try {
value=allNodes.item(i).getFirstChild().getNodeValue();
} catch(Exception e) {
}
imp.setProperty(name, value);
} }
return true; return true;
......
...@@ -6,7 +6,7 @@ package com.elphel.imagej.calibration; ...@@ -6,7 +6,7 @@ package com.elphel.imagej.calibration;
** Copyright (C) 2011-2014 Elphel, Inc. ** Copyright (C) 2011-2014 Elphel, Inc.
** **
** -----------------------------------------------------------------------------** ** -----------------------------------------------------------------------------**
** **
** DistortionProcessConfiguration.java is free software: you can redistribute it and/or modify ** DistortionProcessConfiguration.java is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by ** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or ** the Free Software Foundation, either version 3 of the License, or
...@@ -23,16 +23,17 @@ package com.elphel.imagej.calibration; ...@@ -23,16 +23,17 @@ package com.elphel.imagej.calibration;
** **
*/ */
import ij.IJ;
import ij.Prefs;
import ij.gui.GenericDialog;
import java.io.File; import java.io.File;
import java.io.FilenameFilter;
import java.util.Properties; import java.util.Properties;
import com.elphel.imagej.common.WindowTools; import com.elphel.imagej.common.WindowTools;
import ij.IJ;
import ij.Prefs;
import ij.gui.GenericDialog;
public class DistortionProcessConfiguration{ public class DistortionProcessConfiguration{
public String sourceDirectory=""; public String sourceDirectory="";
public String gridDirectory= ""; public String gridDirectory= "";
...@@ -50,7 +51,7 @@ import com.elphel.imagej.common.WindowTools; ...@@ -50,7 +51,7 @@ import com.elphel.imagej.common.WindowTools;
public String selectSourceDirectory(boolean smart, String defaultPath, boolean newAllowed) { public String selectSourceDirectory(boolean smart, String defaultPath, boolean newAllowed) {
String dir= CalibrationFileManagement.selectDirectory( String dir= CalibrationFileManagement.selectDirectory(
smart, smart,
newAllowed, // save newAllowed, // save
"Source (acquired from the camera) image directory", // title "Source (acquired from the camera) image directory", // title
"Select source directory", // button "Select source directory", // button
null, // filter null, // filter
...@@ -61,7 +62,7 @@ import com.elphel.imagej.common.WindowTools; ...@@ -61,7 +62,7 @@ import com.elphel.imagej.common.WindowTools;
public String selectGridFileDirectory(boolean smart, String defaultPath, boolean newAllowed) { public String selectGridFileDirectory(boolean smart, String defaultPath, boolean newAllowed) {
String dir= CalibrationFileManagement.selectDirectory( String dir= CalibrationFileManagement.selectDirectory(
smart, smart,
newAllowed, // save newAllowed, // save
"Grid files directory (grid patterns extracted from the images)", // title "Grid files directory (grid patterns extracted from the images)", // title
"Select grid files directory", // button "Select grid files directory", // button
null, // filter null, // filter
...@@ -69,7 +70,7 @@ import com.elphel.imagej.common.WindowTools; ...@@ -69,7 +70,7 @@ import com.elphel.imagej.common.WindowTools;
if (dir!=null) this.gridDirectory=dir; if (dir!=null) this.gridDirectory=dir;
return dir; return dir;
} }
public void setProperties(String prefix,Properties properties){ public void setProperties(String prefix,Properties properties){
properties.setProperty(prefix+"sourceDirectory", this.sourceDirectory); properties.setProperty(prefix+"sourceDirectory", this.sourceDirectory);
properties.setProperty(prefix+"gridDirectory", this.gridDirectory); properties.setProperty(prefix+"gridDirectory", this.gridDirectory);
...@@ -123,9 +124,9 @@ import com.elphel.imagej.common.WindowTools; ...@@ -123,9 +124,9 @@ import com.elphel.imagej.common.WindowTools;
gd.addCheckbox ("Show grid files as images", this.showGridImages); gd.addCheckbox ("Show grid files as images", this.showGridImages);
gd.addCheckbox ("Save grid files", this.saveGridImages); gd.addCheckbox ("Save grid files", this.saveGridImages);
gd.addCheckbox ("Overwrite existing result files", this.overwriteResultFiles); gd.addCheckbox ("Overwrite existing result files", this.overwriteResultFiles);
gd.addNumericField("Debug level", this.debugLevel,0); gd.addNumericField("Debug level", this.debugLevel,0);
WindowTools.addScrollBars(gd); WindowTools.addScrollBars(gd);
gd.showDialog(); gd.showDialog();
...@@ -144,7 +145,7 @@ import com.elphel.imagej.common.WindowTools; ...@@ -144,7 +145,7 @@ import com.elphel.imagej.common.WindowTools;
this.debugLevel= (int) gd.getNextNumber(); this.debugLevel= (int) gd.getNextNumber();
System.out.println("1.newSourceDirectory = "+newSourceDirectory); System.out.println("1.newSourceDirectory = "+newSourceDirectory);
System.out.println("1.newGridDirectory = "+ newGridDirectory); System.out.println("1.newGridDirectory = "+ newGridDirectory);
if ((newSourceDirectory.length()==0) || (newSourceDirectory.indexOf('?')>=0)) if ((newSourceDirectory.length()==0) || (newSourceDirectory.indexOf('?')>=0))
newSourceDirectory= selectSourceDirectory(false, this.sourceDirectory, true); newSourceDirectory= selectSourceDirectory(false, this.sourceDirectory, true);
else else
newSourceDirectory= selectSourceDirectory(true, newSourceDirectory, true); // if matches, no dialog newSourceDirectory= selectSourceDirectory(true, newSourceDirectory, true); // if matches, no dialog
...@@ -174,7 +175,7 @@ import com.elphel.imagej.common.WindowTools; ...@@ -174,7 +175,7 @@ import com.elphel.imagej.common.WindowTools;
if (this.sourceDirectory.length()==0){ if (this.sourceDirectory.length()==0){
defaultPaths[0]=""; defaultPaths[0]="";
} }
CalibrationFileManagement.MultipleExtensionsFileFilter sourceFilter = CalibrationFileManagement.MultipleExtensionsFileFilter sourceFilter =
new CalibrationFileManagement.MultipleExtensionsFileFilter("",extensions,"Source files"); new CalibrationFileManagement.MultipleExtensionsFileFilter("",extensions,"Source files");
String [] sourceFiles=null; String [] sourceFiles=null;
...@@ -206,5 +207,26 @@ import com.elphel.imagej.common.WindowTools; ...@@ -206,5 +207,26 @@ import com.elphel.imagej.common.WindowTools;
} }
return sourceFiles; return sourceFiles;
} }
public String[] selectSourceSets() {
File dir= new File (this.sourceDirectory);
if (this.debugLevel>1) System.out.println("selectSourceSets, dir="+this.sourceDirectory);
if (!dir.exists()) {
String error="Source directory "+this.sourceDirectory+" does not exist.";
IJ.showMessage("No files selected");
if (this.debugLevel>1) System.out.println("selectSourceFiles() ERROR:"+error);
return null;
}
File [] sourceFileSets = dir.listFiles(new FilenameFilter() {
@Override
public boolean accept(File current, String name) {
return new File(current, name).isDirectory();
}
});
String [] sourceSets = new String[sourceFileSets.length];
for (int i=0;i<sourceSets.length;i++) sourceSets[i]=sourceFileSets[i].getPath();
return sourceSets;
}
} }
...@@ -668,6 +668,8 @@ horizontal axis: ...@@ -668,6 +668,8 @@ horizontal axis:
// allow more of grid around pointers? // allow more of grid around pointers?
distortionParameters, // distortionParameters, //
this.patternDetectParameters, this.patternDetectParameters,
this.patternDetectParameters.minGridPeriod/2,
this.patternDetectParameters.maxGridPeriod/2,
simulParameters, simulParameters,
equalizeGreens, imp_eq, equalizeGreens, imp_eq,
this.laserPointers, // null, //LASER_POINTERS, // this.laserPointers, // null, //LASER_POINTERS, //
...@@ -841,6 +843,8 @@ horizontal axis: ...@@ -841,6 +843,8 @@ horizontal axis:
// allow more of grid around pointers? // allow more of grid around pointers?
distortionParameters, // distortionParameters, //
this.patternDetectParameters, this.patternDetectParameters,
this.patternDetectParameters.minGridPeriod/2,
this.patternDetectParameters.maxGridPeriod/2,
simulParameters, simulParameters,
equalizeGreens, imp_eq, equalizeGreens, imp_eq,
this.laserPointers, // null, //LASER_POINTERS, // this.laserPointers, // null, //LASER_POINTERS, //
......
...@@ -124,15 +124,7 @@ public class DoubleFHT { ...@@ -124,15 +124,7 @@ public class DoubleFHT {
public boolean transform(double [] data, boolean inverse) { public boolean transform(double [] data, boolean inverse) {
//IJ.log("transform: "+maxN+" "+inverse); //IJ.log("transform: "+maxN+" "+inverse);
updateMaxN(data); updateMaxN(data);
// maxN = (int) Math.sqrt(data.length);
// if ((S==null) || (S.length!=(maxN/4))) {
// makeSinCosTables(maxN);
// makeBitReverseTable(maxN);
// tempArr = new double[maxN];
// }
// float[] fht = (float[])getPixels();
rc2DFHT(data, inverse, this.maxN); rc2DFHT(data, inverse, this.maxN);
// isFrequencyDomain = !inverse;
return true; return true;
} }
...@@ -141,21 +133,15 @@ public class DoubleFHT { ...@@ -141,21 +133,15 @@ public class DoubleFHT {
double lowPass){ double lowPass){
return createFrequencyFilter(null,highPass,lowPass); return createFrequencyFilter(null,highPass,lowPass);
} }
/* public double []createFrequencyFilter(
double [] data, public double [] createFrequencyFilter(
double highPass,
double lowPass){
return createFrequencyFilter(data.length,highPass,lowPass);
}
*/
public double [] createFrequencyFilter(
double [] data, //int n, double [] data, //int n,
double highPass, double highPass,
double lowPass){ double lowPass){
if (data !=null) updateMaxN(data); if (data !=null) updateMaxN(data);
// int n; // int n;
if ((this.freqMask!=null) && (this.freqPass[0]==highPass) && (this.freqPass[0]==lowPass)) return this.freqMask; if ((this.freqMask!=null) && (this.freqPass[0]==highPass) && (this.freqPass[1]==lowPass)) return this.freqMask;
this.freqMask= new double [(this.maxN+1)*this.maxN/2+1]; this.freqMask= new double [(this.maxN+1)*this.maxN/2+1];
double [] lo=new double[this.maxN]; double [] lo=new double[this.maxN];
double [] hi=new double[this.maxN]; double [] hi=new double[this.maxN];
...@@ -177,12 +163,9 @@ public class DoubleFHT { ...@@ -177,12 +163,9 @@ public class DoubleFHT {
if (j>this.maxN/2) j=this.maxN-j; if (j>this.maxN/2) j=this.maxN-j;
this.freqMask[index]=(1.0-hi[i]*hi[j])*lo[i]*lo[j]; this.freqMask[index]=(1.0-hi[i]*hi[j])*lo[i]*lo[j];
} }
// this.freqMaskN=n;
this.freqPass=new double[2]; this.freqPass=new double[2];
this.freqPass[0]=highPass; this.freqPass[0]=highPass;
this.freqPass[1]=lowPass; this.freqPass[1]=lowPass;
// this.freqMask_cache[this.ln2]=this.freqMask;
// this.freqPass_cache[this.ln2]=this.freqPass;
return this.freqMask; return this.freqMask;
} }
/** /**
...@@ -195,49 +178,6 @@ public class DoubleFHT { ...@@ -195,49 +178,6 @@ public class DoubleFHT {
*/ */
public double [] shift(double [] data, double dx, double dy){ public double [] shift(double [] data, double dx, double dy){
return shift(data, 1, dx, dy); return shift(data, 1, dx, dy);
/*
updateMaxN(data);
double sX=2*Math.PI*dx/this.maxN;
double sY=2*Math.PI*dy/this.maxN;
int halfN=this.maxN/2;
double [] cosDX = new double[this.maxN];
double [] sinDX = new double[this.maxN];
double [] cosDY = new double[halfN+1];
double [] sinDY = new double[halfN+1];
for (int i=0;i<=halfN;i++){ // need less?
cosDX[i]=Math.cos(sX*i);
sinDX[i]=Math.sin(sX*i);
cosDY[i]=Math.cos(sY*i);
sinDY[i]=Math.sin(sY*i);
}
for (int i=1;i<halfN;i++){ // need less?
cosDX[this.maxN-i]= cosDX[i];
sinDX[this.maxN-i]=-sinDX[i];
}
swapQuadrants(data);
if (!transform(data,false)) return null; // direct FHT
for (int row =0; row<=halfN; row++) {
int rowMod = (this.maxN - row) % this.maxN;
int maxCol=(row<halfN)?(this.maxN-1):halfN;
for (int col=0; col<=maxCol; col++) {
int colMod = (this.maxN - col) % this.maxN;
int index= row * this.maxN + col;
int indexMod=rowMod * this.maxN + colMod;
double re=0.5*(data[index]+data[indexMod]);
double im=0.5*(data[index]-data[indexMod]);
if ((col==halfN) || (row==halfN)) im=0;
double cosDelta= cosDX[col]*cosDY[row] - sinDX[col]*sinDY[row]; // cos(deltaX)*cos(deltaY)-sin(deltaX)*sin(deltaY)
double sinDelta= sinDX[col]*cosDY[row] + cosDX[col]*sinDY[row]; // sin(deltaX)*cos(deltaY)+cos(deltaX)*sin(deltaY)
double reMod=re*cosDelta-im*sinDelta;
double imMod=re*sinDelta+im*cosDelta;
data[index]= reMod+imMod;
data[indexMod]=reMod-imMod;
}
}
if (!transform(data,true)) return null; // inverse FHT
swapQuadrants(data);
return data;
*/
} }
/** /**
* Upsample input array by padding in the frequency domain * Upsample input array by padding in the frequency domain
...@@ -247,30 +187,6 @@ public class DoubleFHT { ...@@ -247,30 +187,6 @@ public class DoubleFHT {
*/ */
public double [] upsample( double [] first, int scale){ public double [] upsample( double [] first, int scale){
return shift (first, scale, 0.0, 0.0); return shift (first, scale, 0.0, 0.0);
/*
if (scale <=1) return first.clone();
updateMaxN(first);
swapQuadrants(first);
if (!transform(first,false)) return null; // direct FHT
int halfN=this.maxN/2;
int shift=this.maxN*(scale-1);
int scaledN=this.maxN*scale;
double [] result =new double [first.length*scale*scale];
for (int i=0;i<result.length;i++) result [i]=0.0;
double scale2=scale*scale;
for (int i=0;i<first.length;i++){
int iy=i/this.maxN;
int ix=i%this.maxN;
if (ix>halfN) ix+=shift;
if (iy>halfN) iy+=shift;
result[scaledN*iy+ix]=scale2*first[i];
}
updateMaxN(result);
if (!transform(result,true)) return null; // inverse FHT
swapQuadrants(result);
return result;
*/
} }
/** /**
...@@ -408,6 +324,54 @@ public class DoubleFHT { ...@@ -408,6 +324,54 @@ public class DoubleFHT {
swapQuadrants(first); swapQuadrants(first);
return first; return first;
} }
public double [] phaseCorrelate (
double [] first,
double phaseCoeff,
double high_pass,
double low_pass) { // high/low pass filtering
return phaseCorrelate(first, phaseCoeff, high_pass, low_pass, null);
}
public double [] phaseCorrelate (
double [] first,
double phaseCoeff,
double high_pass,
double low_pass, // high/low pass filtering
double [] fht_save){ //null-OK
updateMaxN(first);
double [] filter = null;
if ((high_pass >0) || (low_pass > 0)) {
filter = createFrequencyFilter(high_pass, low_pass);
}
return phaseCorrelate(first, phaseCoeff, filter,fht_save);
}
public double [] phaseCorrelate (
double [] first,
double phaseCoeff,
double [] filter) { // high/low pass filtering
return phaseCorrelate(first, phaseCoeff, filter, null);
}
public double [] phaseCorrelate (
double [] first,
double phaseCoeff,
double [] filter, // high/low pass filtering
double [] fht_save){ //null-OK
updateMaxN(first);
swapQuadrants(first);
if (!transform(first,false)) return null; // direct FHT
if (fht_save != null) {
System.arraycopy(first, 0, fht_save, 0, first.length);
}
first= phaseMultiplyNorm(first, first, phaseCoeff); // correlation, not convolution
if (filter!=null) multiplyByReal(first, filter);
transform(first,true) ; // inverse transform
swapQuadrants(first);
return first;
}
//
public double [] applyFreqFilter( public double [] applyFreqFilter(
double [] first, double [] first,
double [] filter double [] filter
...@@ -2024,6 +1988,7 @@ public class DoubleFHT { ...@@ -2024,6 +1988,7 @@ public class DoubleFHT {
return product; return product;
} }
public double [] phaseMultiply(double [] h1, double [] h2, double phaseCoeff) { public double [] phaseMultiply(double [] h1, double [] h2, double phaseCoeff) {
int rowMod, colMod; int rowMod, colMod;
double h2e, h2o,d; double h2e, h2o,d;
...@@ -2041,6 +2006,54 @@ public class DoubleFHT { ...@@ -2041,6 +2006,54 @@ public class DoubleFHT {
return product; return product;
} }
public double [] phaseMultiplyNorm(double [] h1, double [] h2, double phaseCoeff) {
int size = maxN;
int size2 = size >> 1;
int size21 = size*size2;
int rowMod, colMod, base, baseMod;
double h2e, h2o;
double[] product = new double[size*size];
for (int r =0; r<size; r++) {
rowMod = (size - r) % size;
for (int c=0; c<size; c++) {
colMod = (size - c) % size;
h2e = (h2[r * size + c] + h2[rowMod * size + colMod]) / 2;
h2o = (h2[r * size + c] - h2[rowMod * size + colMod]) / 2;
product[r * size + c] = (h1[r * size + c] * h2e - h1[rowMod * size + colMod] * h2o);
}
}
double [] amplitude = calculateAmplitudeHalf(product);
double avg_ampl = 0.0;
for (int row = 1; row < size2; row++) {
base = row*size;
for (int col = 0; col < size; col++) {
avg_ampl += amplitude[col+base];
}
}
avg_ampl *= 2;
for (int col = 0; col < size; col++) {
avg_ampl += amplitude[col] + amplitude[col + size21];
}
avg_ampl /= size*size;
double aoffs = (1.0 - phaseCoeff) * avg_ampl;
double ampl;
for (int row = 0; row <= size2; row++) {
base = row*size;
rowMod = (size - row) % size;
baseMod = rowMod * size;
for (int col = 0; col < size; col++) {
ampl = phaseCoeff * amplitude[col+base] + aoffs;
product[col+base] /= ampl;
if ((row > 0) && (row < size2)) {
colMod = (size - col) % size;
product[colMod + baseMod] /= ampl;
}
}
}
return product;
}
// Multiply by real array (i.e. filtering in frequency domain). Array m length should be at least maxN*maxN/2+1 // Multiply by real array (i.e. filtering in frequency domain). Array m length should be at least maxN*maxN/2+1
public void multiplyByReal(double [] h, double [] m) { public void multiplyByReal(double [] h, double [] m) {
...@@ -2094,6 +2107,17 @@ public class DoubleFHT { ...@@ -2094,6 +2107,17 @@ public class DoubleFHT {
swapQuadrants(amp); swapQuadrants(amp);
return amp; return amp;
} }
public double [] calculateAmplitudeHalf(double [] fht) {
int size=(int) Math.sqrt(fht.length);
int size2 = (size >>1) +1;
double[] amp = new double[size* size2];
for (int row=0; row<size2; row++) {
amplitude(row, size, fht, amp);
}
return amp;
}
public double [] calculateAmplitude2(double [] fht) { public double [] calculateAmplitude2(double [] fht) {
int size=(int) Math.sqrt(fht.length); int size=(int) Math.sqrt(fht.length);
double[] amp = new double[size*size]; double[] amp = new double[size*size];
...@@ -2133,8 +2157,6 @@ public class DoubleFHT { ...@@ -2133,8 +2157,6 @@ public class DoubleFHT {
row2=(fftsize-row1) %fftsize; row2=(fftsize-row1) %fftsize;
for (col1=0;col1<fftsize;col1++) { for (col1=0;col1<fftsize;col1++) {
col2=(fftsize-col1) %fftsize; col2=(fftsize-col1) %fftsize;
// fftHalf[row1][col1]= complex( 0.5*(fht_pixels[row1*fftsize+col1] + fht_pixels[row2*fftsize+col2]),
// 0.5*(fht_pixels[row2*fftsize+col2] - fht_pixels[row1*fftsize+col1]));
fftHalf[row1][col1][0]= 0.5*(fht_pixels[row1*fftsize+col1] + fht_pixels[row2*fftsize+col2]); fftHalf[row1][col1][0]= 0.5*(fht_pixels[row1*fftsize+col1] + fht_pixels[row2*fftsize+col2]);
fftHalf[row1][col1][1]= 0.5*(fht_pixels[row2*fftsize+col2] - fht_pixels[row1*fftsize+col1]); fftHalf[row1][col1][1]= 0.5*(fht_pixels[row2*fftsize+col2] - fht_pixels[row1*fftsize+col1]);
} }
......
...@@ -112,6 +112,30 @@ import ij.process.ImageProcessor; ...@@ -112,6 +112,30 @@ import ij.process.ImageProcessor;
return; return;
} else showArrays(pixels, width, height, titles); } else showArrays(pixels, width, height, titles);
} }
public void showComplex(double[][][] cpixels, String title) {
int height = cpixels.length;
int width = cpixels[0].length;
double [][]pixels = new double [height*width][];
int indx = 0;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
pixels[indx++] = cpixels[y][x];
}
}
showComplex(pixels, width, title);
}
public void showComplex(double[][] cpixels, int width, String title) {
int height = cpixels.length/width;
double [][]pixels = new double [2][cpixels.length];
for (int i = 0; i< cpixels.length; i++) {
pixels[0][i]= cpixels[i][0];
pixels[1][i]= cpixels[i][1];
}
String [] titles = {"Re", "Im"};
showArrays(pixels, width, height, true, title, titles);
}
public void showArrays(float[][] pixels, int width, int height, boolean asStack, String title, String [] titles) { public void showArrays(float[][] pixels, int width, int height, boolean asStack, String title, String [] titles) {
int i,j; int i,j;
......
...@@ -1407,7 +1407,12 @@ Exception in thread "Thread-3564" java.lang.ArrayIndexOutOfBoundsException: 8970 ...@@ -1407,7 +1407,12 @@ Exception in thread "Thread-3564" java.lang.ArrayIndexOutOfBoundsException: 8970
NodeList allNodes=doc.getDocumentElement().getElementsByTagName("*"); NodeList allNodes=doc.getDocumentElement().getElementsByTagName("*");
for (int i=0;i<allNodes.getLength();i++) { for (int i=0;i<allNodes.getLength();i++) {
String name= allNodes.item(i).getNodeName(); String name= allNodes.item(i).getNodeName();
String value=allNodes.item(i).getFirstChild().getNodeValue(); String value="";
try {
value=allNodes.item(i).getFirstChild().getNodeValue();
} catch(Exception e) {
}
imp.setProperty(name, value); imp.setProperty(name, value);
} }
......
...@@ -26,10 +26,14 @@ ...@@ -26,10 +26,14 @@
*/ */
package com.elphel.imagej.lwir; package com.elphel.imagej.lwir;
import java.io.File;
import java.io.FilenameFilter;
import java.util.Properties; import java.util.Properties;
import com.elphel.imagej.common.GenericJTabbedDialog; import com.elphel.imagej.common.GenericJTabbedDialog;
import ij.Prefs;
public class LwirReaderParameters { public class LwirReaderParameters {
private boolean parameters_updated = false; private boolean parameters_updated = false;
protected int avg_number = 4; // number of measurements to average protected int avg_number = 4; // number of measurements to average
...@@ -49,6 +53,7 @@ public class LwirReaderParameters { ...@@ -49,6 +53,7 @@ public class LwirReaderParameters {
protected double vnir_gain_g = 2.0; protected double vnir_gain_g = 2.0;
protected double vnir_gain_rg = 0.7705; // 1.116; halogen/fluorescent protected double vnir_gain_rg = 0.7705; // 1.116; halogen/fluorescent
protected double vnir_gain_bg = 2.401; // 1.476; protected double vnir_gain_bg = 2.401; // 1.476;
protected boolean [] selected_channels = {true, true, true, true, true, true, true, true};
/* /*
protected double [] vnir_exp_corr = {1.0, 1.0, 1.0, 1.0}; protected double [] vnir_exp_corr = {1.0, 1.0, 1.0, 1.0};
...@@ -70,7 +75,7 @@ public class LwirReaderParameters { ...@@ -70,7 +75,7 @@ public class LwirReaderParameters {
protected int vnir_lag = 1; // frames protected int vnir_lag = 1; // frames
protected double max_mismatch_ms = 0.05; protected double max_mismatch_ms = 0.05;
protected int max_frame_diff = 1; // 2; protected int max_frame_diff = 1; // 2;
protected int debug_level = 0;//-3: OFF, -2:Fatal, -1:ERROR, 0:WARN, 1:INFO,2:DEBUG protected int debug_level = 0;//-3: OFF, -2:Fatal, -1:ERROR, 0:WARN, 1:INFO,2:DEBUG
// --- interface methods // --- interface methods
...@@ -106,6 +111,7 @@ public class LwirReaderParameters { ...@@ -106,6 +111,7 @@ public class LwirReaderParameters {
properties.setProperty(prefix+"max_mismatch_ms", this.max_mismatch_ms+""); properties.setProperty(prefix+"max_mismatch_ms", this.max_mismatch_ms+"");
properties.setProperty(prefix+"max_frame_diff", this.max_frame_diff+""); properties.setProperty(prefix+"max_frame_diff", this.max_frame_diff+"");
properties.setProperty(prefix+"debug_level", this.debug_level+""); properties.setProperty(prefix+"debug_level", this.debug_level+"");
properties.setProperty(prefix+"selected_channels", arr_to_str(this.selected_channels));
} }
...@@ -134,6 +140,7 @@ public class LwirReaderParameters { ...@@ -134,6 +140,7 @@ public class LwirReaderParameters {
if (properties.getProperty(prefix+"max_mismatch_ms")!=null) this.max_mismatch_ms=Double.parseDouble(properties.getProperty(prefix+"max_mismatch_ms")); if (properties.getProperty(prefix+"max_mismatch_ms")!=null) this.max_mismatch_ms=Double.parseDouble(properties.getProperty(prefix+"max_mismatch_ms"));
if (properties.getProperty(prefix+"max_frame_diff")!=null) this.max_frame_diff=Integer.parseInt(properties.getProperty(prefix+"max_frame_diff")); if (properties.getProperty(prefix+"max_frame_diff")!=null) this.max_frame_diff=Integer.parseInt(properties.getProperty(prefix+"max_frame_diff"));
if (properties.getProperty(prefix+"debug_level")!=null) this.debug_level=Integer.parseInt(properties.getProperty(prefix+"debug_level")); if (properties.getProperty(prefix+"debug_level")!=null) this.debug_level=Integer.parseInt(properties.getProperty(prefix+"debug_level"));
if (properties.getProperty(prefix+"selected_channels")!=null) this.selected_channels=str_to_barr(properties.getProperty(prefix+"selected_channels"));
parameters_updated = true; parameters_updated = true;
} }
@Override @Override
...@@ -163,6 +170,7 @@ public class LwirReaderParameters { ...@@ -163,6 +170,7 @@ public class LwirReaderParameters {
lrp.max_mismatch_ms= this.max_mismatch_ms; lrp.max_mismatch_ms= this.max_mismatch_ms;
lrp.max_frame_diff= this.max_frame_diff; lrp.max_frame_diff= this.max_frame_diff;
lrp.debug_level= this.debug_level; lrp.debug_level= this.debug_level;
lrp.selected_channels = this.selected_channels.clone();
return lrp; return lrp;
} }
...@@ -198,7 +206,8 @@ public class LwirReaderParameters { ...@@ -198,7 +206,8 @@ public class LwirReaderParameters {
(lrp.vnir_lag == this.vnir_lag) && (lrp.vnir_lag == this.vnir_lag) &&
(lrp.max_mismatch_ms == this.max_mismatch_ms) && (lrp.max_mismatch_ms == this.max_mismatch_ms) &&
(lrp.max_frame_diff == this.max_frame_diff) && (lrp.max_frame_diff == this.max_frame_diff) &&
(lrp.debug_level == this.debug_level); (lrp.debug_level == this.debug_level) &&
(java.util.Arrays.equals(lrp.selected_channels, this.selected_channels));
} }
@Override @Override
...@@ -225,6 +234,7 @@ public class LwirReaderParameters { ...@@ -225,6 +234,7 @@ public class LwirReaderParameters {
result = prime * result + arr_to_str(vnir_exp_corr).hashCode(); result = prime * result + arr_to_str(vnir_exp_corr).hashCode();
result = prime * result + arr_to_str(vnir_gcorr_rbgb).hashCode(); result = prime * result + arr_to_str(vnir_gcorr_rbgb).hashCode();
result = prime * result + (new Integer(lwir_trig_dly)).hashCode(); result = prime * result + (new Integer(lwir_trig_dly)).hashCode();
result = prime * result + arr_to_str(selected_channels).hashCode();
// next are not needed to be programmed to the cameras // next are not needed to be programmed to the cameras
// result = prime * result + (new Integer(vnir_lag)).hashCode(); // result = prime * result + (new Integer(vnir_lag)).hashCode();
// result = prime * result + (new Double(max_mismatch_ms)).hashCode(); // result = prime * result + (new Double(max_mismatch_ms)).hashCode();
...@@ -241,7 +251,7 @@ public class LwirReaderParameters { ...@@ -241,7 +251,7 @@ public class LwirReaderParameters {
gd.addStringField ("LWIR channels", arr_to_str(this.lwir_channels), 20, "Space-separated list of used LWIR camera channels, such as '0 1 2 3'"); gd.addStringField ("LWIR channels", arr_to_str(this.lwir_channels), 20, "Space-separated list of used LWIR camera channels, such as '0 1 2 3'");
gd.addStringField ("VNIR channels", arr_to_str(this.vnir_channels), 20, "Space-separated list of used visible range camera channels, such as '0 1 2 3'"); gd.addStringField ("VNIR channels", arr_to_str(this.vnir_channels), 20, "Space-separated list of used visible range camera channels, such as '0 1 2 3'");
gd.addCheckbox ("LWIR telemetry", this.lwir_telemetry, "Set LWIR sesnors to provide telemetry data in the last 2 lines (may become mandatory later)"); gd.addCheckbox ("LWIR telemetry", this.lwir_telemetry, "Set LWIR sesnors to provide telemetry data in the last 2 lines (may become mandatory later)");
gd.addNumericField("VNIR quality", this.vnir_quality, 3,6,"ms", "Visible range camera JPEG compression quality (all channels)"); gd.addNumericField("VNIR quality", this.vnir_quality, 3,6,"%", "Visible range camera JPEG compression quality (all channels)");
gd.addCheckbox ("VNIR undo white balance", this.vnir_scale, "Undo in-camera white balancing"); gd.addCheckbox ("VNIR undo white balance", this.vnir_scale, "Undo in-camera white balancing");
gd.addCheckbox ("VNIR autoexposure", this.vnir_autoexp, "Enable autoexposure for the visible range camera"); gd.addCheckbox ("VNIR autoexposure", this.vnir_autoexp, "Enable autoexposure for the visible range camera");
gd.addNumericField("VNIR vnir_max_autoexp_ms", this.vnir_max_autoexp_ms, 3,6,"ms", "Visible range camera maximal exposure in autoexposure mode"); gd.addNumericField("VNIR vnir_max_autoexp_ms", this.vnir_max_autoexp_ms, 3,6,"ms", "Visible range camera maximal exposure in autoexposure mode");
...@@ -256,12 +266,13 @@ public class LwirReaderParameters { ...@@ -256,12 +266,13 @@ public class LwirReaderParameters {
gd.addNumericField("VNIR lag", this.vnir_lag, 0,3,"","Visible camera lag (in frames) relative to LWIR one"); gd.addNumericField("VNIR lag", this.vnir_lag, 0,3,"","Visible camera lag (in frames) relative to LWIR one");
gd.addNumericField("Max mismatch", this.max_mismatch_ms, 3,6,"ms","Maximal mismatch between image timestamps. Larger mismatch requires LWIR sinsor reinitialization"); gd.addNumericField("Max mismatch", this.max_mismatch_ms, 3,6,"ms","Maximal mismatch between image timestamps. Larger mismatch requires LWIR sinsor reinitialization");
gd.addNumericField("Max frame diff",this.max_frame_diff, 0,3,"","Maximal difference in frames between simultaneously acquired channels as calculated from the timestamps"); gd.addNumericField("Max frame diff",this.max_frame_diff, 0,3,"","Maximal difference in frames between simultaneously acquired channels as calculated from the timestamps");
gd.addNumericField("Debug level", this.debug_level, 0,3,"","Image acquisition log level: -3: OFF, -2:FATAL, -1:ERROR, 0:WARN, 1:INFO, 2:DEBUG"); gd.addNumericField("Debug level", this.debug_level, 0,3,"","Image acquisition log level: -3: OFF, -2:FATAL, -1:ERROR, 0:WARN, 1:INFO, 2:DEBUG");
gd.addStringField ("Selected channels", arr_to_str(this.selected_channels), 20, "Space-separated channel selection (1 - selected, 0 - unselected)");
} }
public void dialogAnswers(GenericJTabbedDialog gd) { public void dialogAnswers(GenericJTabbedDialog gd) {
this.avg_number = (int) gd.getNextNumber(); this.avg_number = (int) gd.getNextNumber();
this.lwir_ffc = gd.getNextBoolean(); this.lwir_ffc = gd.getNextBoolean();
this.avg_all = gd.getNextBoolean(); this.avg_all = gd.getNextBoolean();
this.lwir_ip = gd.getNextString(); this.lwir_ip = gd.getNextString();
this.vnir_ip = gd.getNextString(); this.vnir_ip = gd.getNextString();
...@@ -284,6 +295,7 @@ public class LwirReaderParameters { ...@@ -284,6 +295,7 @@ public class LwirReaderParameters {
this.max_mismatch_ms = gd.getNextNumber(); this.max_mismatch_ms = gd.getNextNumber();
this.max_frame_diff = (int) gd.getNextNumber(); this.max_frame_diff = (int) gd.getNextNumber();
this.debug_level = (int) gd.getNextNumber(); this.debug_level = (int) gd.getNextNumber();
this.selected_channels = str_to_barr(gd.getNextString());
parameters_updated = true; parameters_updated = true;
} }
...@@ -307,6 +319,80 @@ public class LwirReaderParameters { ...@@ -307,6 +319,80 @@ public class LwirReaderParameters {
parameters_updated = false; parameters_updated = false;
} }
public boolean [] getSelected(){
return selected_channels;
}
public boolean [] getSelectedLwir(){
boolean [] sel = selected_channels.clone();
for (int i = lwir_channels.length; i < sel.length; i++ ) {
sel[i] = false;
}
return sel;
}
public boolean [] getSelectedVnir(){
boolean [] sel = selected_channels.clone();
for (int i = 0; i < lwir_channels.length; i++ ) {
sel[i] = false;
}
return sel;
}
public String [] getSourceFilesFlat(String [] sets, boolean[] channels) {
int num_sel = 0;
for (boolean s: channels) if (s) num_sel++;
String [] files = new String [sets.length * num_sel];
int indx = 0;
for (String set:sets) {
for (int i = 0; i < channels.length; i++) if (channels[i]) {
String file_base = set;
if (set.indexOf(Prefs.getFileSeparator()) >=0) {
file_base = set.substring(set.lastIndexOf(Prefs.getFileSeparator())+1);
}
files[indx++] =set + Prefs.getFileSeparator()+ file_base+"_"+i+".tiff";
}
}
return files;
}
// Image set may have different timestamps, only lwir0 matches
public String [][] getSourceFiles(String [] sets, boolean[] channels) {
String [][] files = new String [sets.length][channels.length];
for (int nset= 0; nset < sets.length; nset++) {
// read all files in the directory
File set_dir = new File(sets[nset]);
File [] channel_files = set_dir.listFiles(new FilenameFilter() {
@Override
public boolean accept(File current, String name) {
if (!(new File(current, name).isFile()) || !name.endsWith(".tiff")) return false;
String base = name.substring(0, name.lastIndexOf(".tiff"));
int undr = base.lastIndexOf("_");
if (undr < 0) return false;
int chn = -1;
try {
chn = Integer.parseInt(base.substring(undr + 1));
} catch (Exception e) {
}
return chn >= 0;
}
});
for (File f: channel_files) {
String base = f.getName().substring(0, f.getName().lastIndexOf(".tiff"));
int undr = base.lastIndexOf("_");
int chn = Integer.parseInt(base.substring(undr + 1));
if ((chn >= 0) && (chn < channels.length) && channels[chn]) {
files[nset][chn] = f.getPath();
}
}
}
return files;
}
// --- internal methods // --- internal methods
private String arr_to_str(int [] arr) { private String arr_to_str(int [] arr) {
...@@ -321,6 +407,23 @@ public class LwirReaderParameters { ...@@ -321,6 +407,23 @@ public class LwirReaderParameters {
return s.trim(); return s.trim();
} }
private String arr_to_str(boolean [] arr) {
String s = "";
for (boolean c:arr) s+= (c?1:0)+" ";
return s.trim();
}
private boolean [] str_to_barr(String s) {
int [] iarr = str_to_iarr(s);
if (iarr == null) return null;
boolean [] barr = new boolean [iarr.length];
for (int i = 0; i < barr.length; i++) {
barr[i] = iarr[i] != 0;
}
return barr;
}
private int [] str_to_iarr(String s) { private int [] str_to_iarr(String s) {
String [] sa; String [] sa;
if (s.indexOf(",") >= 0) { if (s.indexOf(",") >= 0) {
...@@ -349,4 +452,22 @@ public class LwirReaderParameters { ...@@ -349,4 +452,22 @@ public class LwirReaderParameters {
return darr; return darr;
} }
public boolean [] selectSourceChannels(){
return selectSourceChannels(selected_channels);
}
public boolean [] selectSourceChannels(boolean [] sel) {
GenericJTabbedDialog gd = new GenericJTabbedDialog("Set CLT parameters",300,500);
for (int i = 0; i < sel.length; i++) {
gd.addCheckbox ("Channel "+i, sel[i], "Enable processing camera channel "+i);
}
gd.showDialog();
if (gd.wasCanceled()) return null;
for (int i = 0; i < sel.length; i++) {
sel[i] = gd.getNextBoolean();
}
return sel;
}
} }
...@@ -640,7 +640,7 @@ the type of pixel data in this file getPixelType() ...@@ -640,7 +640,7 @@ the type of pixel data in this file getPixelType()
} }
// copied from JP46_Reader_camera.java // copied from JP46_Reader_camera.java
public ImagePlus encodeProperiesToInfo(ImagePlus imp){ public static ImagePlus encodeProperiesToInfo(ImagePlus imp){
String info="<?xml version=\"1.0\" encoding=\"UTF-8\"?><properties>"; String info="<?xml version=\"1.0\" encoding=\"UTF-8\"?><properties>";
Set<Object> jp4_set; Set<Object> jp4_set;
Properties jp4_prop; Properties jp4_prop;
...@@ -661,7 +661,7 @@ the type of pixel data in this file getPixelType() ...@@ -661,7 +661,7 @@ the type of pixel data in this file getPixelType()
return imp; return imp;
} }
public boolean decodeProperiesFromInfo(ImagePlus imp){ public static boolean decodeProperiesFromInfo(ImagePlus imp){
if (imp.getProperty("Info")==null) return false; if (imp.getProperty("Info")==null) return false;
String xml= (String) imp.getProperty("Info"); String xml= (String) imp.getProperty("Info");
...@@ -684,11 +684,15 @@ the type of pixel data in this file getPixelType() ...@@ -684,11 +684,15 @@ the type of pixel data in this file getPixelType()
NodeList allNodes=doc.getDocumentElement().getElementsByTagName("*"); NodeList allNodes=doc.getDocumentElement().getElementsByTagName("*");
for (int i=0;i<allNodes.getLength();i++) { for (int i=0;i<allNodes.getLength();i++) {
String name= allNodes.item(i).getNodeName(); String name= allNodes.item(i).getNodeName();
String value=allNodes.item(i).getFirstChild().getNodeValue(); // System.out.print(name+" -> ");
imp.setProperty(name, value); String value = "";
try {
value=allNodes.item(i).getFirstChild().getNodeValue();
} catch (Exception e) {
}
// System.out.println(value);
imp.setProperty(name, value);
} }
return true; return true;
} }
......
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