Commit 09416a86 authored by Andrey Filippov's avatar Andrey Filippov

working with actual images

parent 91616de2
......@@ -29,9 +29,9 @@
public class DttRad2 {
int N = 0;
double [][][] CII=null;
double [][][] CIV=null;
double [][][] SIV=null;
double [][][] CII= null;
double [][][] CIV= null;
double [][][] SIV= null;
double [][] CN1=null;
double [][] SN1=null;
double COSPI_1_8_SQRT2 = Math.cos(Math.PI/8)*Math.sqrt(2.0);
......@@ -137,7 +137,7 @@ public class DttRad2 {
}
}
}
if (n < 16) {
if (n < 8) {
for (int i = 0; i < n; i++ ){
fi = get_fold_indices(i,n);
System.out.println(i+"->"+String.format("[%2d % 2d % 2d] [%2d %2d %2d] %f %f",
......@@ -188,12 +188,12 @@ public class DttRad2 {
unfold_index[n2*i+j]=(index_vert+index_hor);
unfold_k[n2*i+j]=k_vert*k_hor;
if (n < 16) System.out.print(String.format("%4d", unfold_index[n2*i+j]));
if (n < 8) System.out.print(String.format("%4d", unfold_index[n2*i+j]));
}
if (n < 16) System.out.println();
if (n < 8) System.out.println();
}
if (n < 16) {
if (n < 8) {
for (int i = 0; i < 2*n; i++ ){
System.out.println(i+"->"+get_unfold_index(i,n));
}
......@@ -226,7 +226,7 @@ public class DttRad2 {
}
public double [] dttt_ii(double [] x){
return dttt_iv(x, 0, 1 << (ilog2(x.length)/2));
return dttt_ii(x, 1 << (ilog2(x.length)/2));
}
public double [] dttt_ii(double [] x, int n){
......@@ -247,6 +247,29 @@ public class DttRad2 {
return y;
}
public double [] dttt_iii(double [] x){
return dttt_iii(x, 1 << (ilog2(x.length)/2));
}
public double [] dttt_iii(double [] x, int n){
double [] y = new double [n*n];
double [] line = new double[n];
// first (horizontal) pass
for (int i = 0; i<n; i++){
System.arraycopy(x, n*i, line, 0, n);
line = dctiii_direct(line);
for (int j=0; j < n;j++) y[j*n+i] =line[j]; // transpose
}
// second (vertical) pass
for (int i = 0; i<n; i++){
System.arraycopy(y, n*i, line, 0, n);
line = dctiii_direct(line);
System.arraycopy(line, 0, y, n*i, n);
}
return y;
}
public void set_window(){
......@@ -259,15 +282,17 @@ public class DttRad2 {
hwindow = new double[len];
double f = Math.PI/(2.0*len);
double sqrt1_2=Math.sqrt(0.5);
if (mode < 0) mode =0;
else if (mode > 2) mode = 2;
if (mode ==0){
for (int i = 0; i < len; i++ ) hwindow[i] = sqrt1_2;
} else if (mode ==1){
for (int i = 0; i < len; i++ ) hwindow[i] = Math.sin(f*(i+0.5));
} else { // add more types?
} else if (mode ==2){
double s;
for (int i = 0; i < len; i++ ) {
s = Math.sin(f*(i+0.5));
hwindow[i] = Math.sin(Math.PI*s*s);
hwindow[i] = Math.sin(Math.PI*s*s/2);
}
}
set_fold_2d(len);
......@@ -317,6 +342,24 @@ public class DttRad2 {
}
return y;
}
public double [] dctiii_direct(double[] x){
// CIII=transp(CII)
int n = x.length;
int t = ilog2(n)-1;
if (CII==null){
setup_CII(N); // just full size
}
double [] y = new double[n];
for (int i = 0; i<n; i++) {
y[i] = 0.0;
for (int j = 0; j< n; j++){
y[i]+= CII[t][j][i]*x[j];
}
}
return y;
}
public double [] dctiv_direct(double[] x){
int n = x.length;
......@@ -388,7 +431,7 @@ public class DttRad2 {
}
}
}
private void setup_CIV(int maxN){
if (maxN > N) setup_arrays(maxN);
int l = ilog2(N);
......
......@@ -80,12 +80,17 @@ public class EyesisCorrectionParameters {
public String sensorDirectory="";
public String sensorPrefix="sensor-";
public String sensorSuffix=".calib-tiff"; // fixed in PixelMapping
public String sharpKernelDirectory="";
public String sharpKernelPrefix="sharpKernel-";
public String sharpKernelSuffix=".kernel-tiff";
public String smoothKernelDirectory="";
public String smoothKernelPrefix="smoothKernel-";
public String smoothKernelSuffix=".kernel-tiff";
public String dctKernelDirectory="";
public String dctKernelPrefix="dct-";
public String dctSymSuffix=".sym-tiff";
public String dctAsymSuffix=".asym-tiff";
public String equirectangularDirectory="";
public String equirectangularPrefix="";
public String equirectangularSuffix=".eqr-tiff";
......@@ -146,12 +151,20 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"sensorDirectory",this.sensorDirectory);
properties.setProperty(prefix+"sensorPrefix",this.sensorPrefix);
properties.setProperty(prefix+"sensorSuffix",this.sensorSuffix);
properties.setProperty(prefix+"sharpKernelDirectory",this.sharpKernelDirectory);
properties.setProperty(prefix+"sharpKernelPrefix",this.sharpKernelPrefix);
properties.setProperty(prefix+"sharpKernelSuffix",this.sharpKernelSuffix);
properties.setProperty(prefix+"smoothKernelDirectory",this.smoothKernelDirectory);
properties.setProperty(prefix+"smoothKernelPrefix",this.smoothKernelPrefix);
properties.setProperty(prefix+"smoothKernelSuffix",this.smoothKernelSuffix);
properties.setProperty(prefix+"dctKernelDirectory",this.dctKernelDirectory);
properties.setProperty(prefix+"dctKernelPrefix",this.dctKernelPrefix);
properties.setProperty(prefix+"dctSymSuffix",this.dctSymSuffix);
properties.setProperty(prefix+"dctAsymSuffix",this.dctAsymSuffix);
properties.setProperty(prefix+"equirectangularDirectory",this.equirectangularDirectory);
properties.setProperty(prefix+"equirectangularPrefix",this.equirectangularPrefix);
properties.setProperty(prefix+"equirectangularSuffix",this.equirectangularSuffix);
......@@ -219,6 +232,7 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"sensorDirectory")!= null) this.sensorDirectory=properties.getProperty(prefix+"sensorDirectory");
if (properties.getProperty(prefix+"sensorPrefix")!= null) this.sensorPrefix=properties.getProperty(prefix+"sensorPrefix");
if (properties.getProperty(prefix+"sensorSuffix")!= null) this.sensorSuffix=properties.getProperty(prefix+"sensorSuffix");
if (properties.getProperty(prefix+"sharpKernelDirectory")!= null) this.sharpKernelDirectory=properties.getProperty(prefix+"sharpKernelDirectory");
if (properties.getProperty(prefix+"sharpKernelPrefix")!= null) this.sharpKernelPrefix=properties.getProperty(prefix+"sharpKernelPrefix");
if (properties.getProperty(prefix+"sharpKernelSuffix")!= null) this.sharpKernelSuffix=properties.getProperty(prefix+"sharpKernelSuffix");
......@@ -226,6 +240,11 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"smoothKernelPrefix")!= null) this.smoothKernelPrefix=properties.getProperty(prefix+"smoothKernelPrefix");
if (properties.getProperty(prefix+"smoothKernelSuffix")!= null) this.smoothKernelSuffix=properties.getProperty(prefix+"smoothKernelSuffix");
if (properties.getProperty(prefix+"dctKernelDirectory")!= null) this.dctKernelDirectory=properties.getProperty(prefix+"dctKernelDirectory");
if (properties.getProperty(prefix+"dctKernelPrefix")!= null) this.dctKernelPrefix=properties.getProperty(prefix+"dctKernelPrefix");
if (properties.getProperty(prefix+"dctSymSuffix")!= null) this.dctSymSuffix=properties.getProperty(prefix+"dctSymSuffix");
if (properties.getProperty(prefix+"dctAsymSuffix")!= null) this.dctAsymSuffix=properties.getProperty(prefix+"dctAsymSuffix");
if (properties.getProperty(prefix+"equirectangularDirectory")!=null) this.equirectangularDirectory=properties.getProperty(prefix+"equirectangularDirectory");
if (properties.getProperty(prefix+"equirectangularPrefix")!=null) this.equirectangularPrefix=properties.getProperty(prefix+"equirectangularPrefix");
if (properties.getProperty(prefix+"equirectangularSuffix")!=null) this.equirectangularSuffix=properties.getProperty(prefix+"equirectangularSuffix");
......@@ -299,36 +318,45 @@ public class EyesisCorrectionParameters {
gd.addCheckbox ("Convert to 8 bit RGB (and save JPEG if save is enabled)", this.jpeg);
gd.addCheckbox ("Save the result to file system", this.save);
gd.addCheckbox ("Save 16-bit tiff if the result is 8 bit", this.save16);
gd.addCheckbox ("Save 32-bit tiff if the result is 8 or 16 bit", this.save32);
gd.addCheckbox ("Show the result image", this.show);
gd.addNumericField("JPEG quality (%)", this.JPEG_quality,0);
gd.addNumericField("JPEG scale (%)", 100* this.JPEG_scale,0);
gd.addCheckbox ("Warp results to equirectangular", this.equirectangular);
gd.addCheckbox ("Calculate distances in overlapping areas", this.zcorrect);
gd.addCheckbox ("Save current settings with results", this.saveSettings);
gd.addCheckbox ("Save 32-bit tiff if the result is 8 or 16 bit", this.save32);
gd.addCheckbox ("Show the result image", this.show);
gd.addNumericField("JPEG quality (%)", this.JPEG_quality,0);
gd.addNumericField("JPEG scale (%)", 100* this.JPEG_scale,0);
gd.addCheckbox ("Warp results to equirectangular", this.equirectangular);
gd.addCheckbox ("Calculate distances in overlapping areas", this.zcorrect);
gd.addCheckbox ("Save current settings with results", this.saveSettings);
gd.addStringField ("Source files directory", this.sourceDirectory, 60);
gd.addCheckbox ("Select source directory", false);
gd.addStringField ("Sensor calibration directory", this.sensorDirectory, 60);
gd.addCheckbox ("Select sensor calibration directory", false);
gd.addStringField ("Aberration kernels (sharp) directory", this.sharpKernelDirectory, 60);
gd.addCheckbox ("Select aberration kernels (sharp) directory", false);
gd.addStringField ("Aberration kernels (smooth) directory", this.smoothKernelDirectory, 60);
gd.addCheckbox ("Select aberration kernels (smooth) directory", false);
gd.addStringField ("Aberration kernels for DCT directory", this.dctKernelDirectory, 60);
gd.addCheckbox ("Select aberration kernels for DCT directory", false);
gd.addStringField("Source files directory", this.sourceDirectory, 60);
gd.addCheckbox("Select source directory", false);
gd.addStringField("Sensor calibration directory", this.sensorDirectory, 60);
gd.addCheckbox("Select sensor calibration directory", false);
gd.addStringField("Aberration kernels (sharp) directory", this.sharpKernelDirectory, 60);
gd.addCheckbox("Select aberration kernels (sharp) directory", false);
gd.addStringField("Aberration kernels (smooth) directory", this.smoothKernelDirectory, 60);
gd.addCheckbox("Select aberration kernels (smooth) directory", false);
gd.addStringField("Equirectangular maps directory (may be empty)", this.equirectangularDirectory, 60);
gd.addCheckbox("Select equirectangular maps directory", false);
gd.addStringField("Results directory", this.resultsDirectory, 40);
gd.addCheckbox("Select results directory", false);
gd.addStringField("Source files prefix", this.sourcePrefix, 40);
gd.addStringField("Source files suffix", this.sourceSuffix, 40);
gd.addNumericField("First subcamera (in the source filename)", this.firstSubCamera, 0);
gd.addStringField("Equirectangular maps directory (may be empty)", this.equirectangularDirectory, 60);
gd.addCheckbox("Select equirectangular maps directory", false);
gd.addStringField("Results directory", this.resultsDirectory, 40);
gd.addCheckbox("Select results directory", false);
gd.addStringField("Source files prefix", this.sourcePrefix, 40);
gd.addStringField("Source files suffix", this.sourceSuffix, 40);
gd.addNumericField("First subcamera (in the source filename)", this.firstSubCamera, 0);
gd.addStringField("Sensor files prefix", this.sensorPrefix, 40);
gd.addStringField("Sensor files suffix", this.sensorSuffix, 40);
gd.addStringField("Kernel files (sharp) prefix", this.sharpKernelPrefix, 40);
gd.addStringField("Kernel files (sharp) suffix", this.sharpKernelSuffix, 40);
gd.addStringField("Kernel files (smooth) prefix", this.smoothKernelPrefix, 40);
gd.addStringField("Kernel files (smooth) suffix", this.smoothKernelSuffix, 40);
gd.addStringField("DCT kernel files prefix", this.dctKernelPrefix, 40);
gd.addStringField("DCT symmetical kernel files", this.dctSymSuffix, 40);
gd.addStringField("DCT asymmetrical kernel files suffix", this.dctAsymSuffix, 40);
gd.addStringField("Sensor files prefix", this.sensorPrefix, 40);
gd.addStringField("Sensor files suffix", this.sensorSuffix, 40);
gd.addStringField("Kernel files (sharp) prefix", this.sharpKernelPrefix, 40);
gd.addStringField("Kernel files (sharp) suffix", this.sharpKernelSuffix, 40);
gd.addStringField("Kernel files (smooth) prefix", this.smoothKernelPrefix, 40);
gd.addStringField("Kernel files (smooth) suffix", this.smoothKernelSuffix, 40);
gd.addStringField("Equirectangular maps prefix", this.equirectangularPrefix, 40);
gd.addStringField("Equirectangular maps suffix", this.equirectangularSuffix, 40);
gd.addCheckbox("Cut rolling-over equirectangular images in two", this.equirectangularCut);
......@@ -387,7 +415,8 @@ public class EyesisCorrectionParameters {
this.sourceDirectory= gd.getNextString(); if (gd.getNextBoolean()) selectSourceDirectory(false, false);
this.sensorDirectory= gd.getNextString(); if (gd.getNextBoolean()) selectSensorDirectory(false, false);
this.sharpKernelDirectory= gd.getNextString(); if (gd.getNextBoolean()) selectSharpKernelDirectory(false, false);
this.smoothKernelDirectory= gd.getNextString(); if (gd.getNextBoolean()) selectSmoothKernelDirectory(false, true);
this.smoothKernelDirectory= gd.getNextString(); if (gd.getNextBoolean()) selectSmoothKernelDirectory(false, true);
this.dctKernelDirectory= gd.getNextString(); if (gd.getNextBoolean()) selectDCTKernelDirectory(false, true);
this.equirectangularDirectory= gd.getNextString(); if (gd.getNextBoolean()) selectEquirectangularDirectory(false, false);
this.resultsDirectory= gd.getNextString(); if (gd.getNextBoolean()) selectResultsDirectory(false, true);
this.sourcePrefix= gd.getNextString();
......@@ -399,6 +428,9 @@ public class EyesisCorrectionParameters {
this.sharpKernelSuffix= gd.getNextString();
this.smoothKernelPrefix= gd.getNextString();
this.smoothKernelSuffix= gd.getNextString();
this.dctKernelPrefix= gd.getNextString();
this.dctSymSuffix= gd.getNextString();
this.dctAsymSuffix= gd.getNextString();
this.equirectangularPrefix= gd.getNextString();
this.equirectangularSuffix= gd.getNextString();
this.equirectangularCut= gd.getNextBoolean();
......@@ -406,10 +438,7 @@ public class EyesisCorrectionParameters {
this.planeMapSuffix= gd.getNextString();
this.usePlaneProjection= gd.getNextBoolean();
this.planeAsJPEG= gd.getNextBoolean();
// this.equirectangularSuffixA= gd.getNextString();
this.removeUnusedSensorData= gd.getNextBoolean();
this.swapSubchannels01= gd.getNextBoolean();
return true;
......@@ -447,9 +476,12 @@ public class EyesisCorrectionParameters {
}
public int getChannelFromSourceTiff(String path){ return getChannelFromTiff(path, this.sourceSuffix); }
public String getNameFromSourceTiff(String path){ return getNameFromTiff(path, this.sourceSuffix); }
public int getChannelFromKernelTiff(String path, int type){return getChannelFromTiff(path, (type==0)?this.sharpKernelSuffix:this.smoothKernelSuffix);}
public String getNameFromKernelTiff(String path, int type){return getNameFromTiff(path, (type==0)?this.sharpKernelSuffix:this.smoothKernelSuffix);}
public int getChannelFromDCTTiff(String path, int type){return getChannelFromTiff(path, (type==0)?this.dctSymSuffix:this.dctAsymSuffix);}
public String getNameFromDCTTiff(String path, int type){return getNameFromTiff(path, (type==0)?this.dctSymSuffix:this.dctAsymSuffix);}
public boolean selectSourceFiles(boolean allFiles) {
......@@ -661,7 +693,7 @@ public class EyesisCorrectionParameters {
channelPaths[chn]=kernelFiles[fileNum];
} else {
if (debugLevel>0) System.out.println("Multiple kernel files for channel "+
chn+": "+channelPaths[chn]+" and "+kernelFiles[fileNum]+". Usimg "+channelPaths[chn]);
chn+": "+channelPaths[chn]+" and "+kernelFiles[fileNum]+". Using "+channelPaths[chn]);
}
}
}
......@@ -695,7 +727,7 @@ public class EyesisCorrectionParameters {
}
if ((fileList==null) || (fileList.length==0)){
kernelFiles=CalibrationFileManagement.selectFiles(false,
"Select"+((type==0)?"sharp":"smooth")+" kernel files files",
"Select"+((type==0)?"sharp":"smooth")+" kernel files",
"Select",
kernelFilter,
defaultPaths); // String [] defaultPaths); //this.sourceDirectory // null
......@@ -721,9 +753,82 @@ public class EyesisCorrectionParameters {
return kernelFiles;
}
public String [] selectDCTChannelFiles(
int numChannels, // number of channels
int debugLevel) { // will only open dialog if directory or files are not found
String [] kernelFiles= selectDCTFiles(
debugLevel);
if (kernelFiles==null) return null;
String [] channelPaths=new String[numChannels];
for (int i=0;i<channelPaths.length;i++)channelPaths[i]=null;
for (int fileNum=0;fileNum<kernelFiles.length;fileNum++){
int chn=getChannelFromDCTTiff(kernelFiles[fileNum], 0); // 1 for asym files
if ((chn>=0) && (chn<numChannels)){
if (channelPaths[chn]==null){ // use first file for channel if there are multiple
channelPaths[chn]=kernelFiles[fileNum];
} else {
if (debugLevel>0) System.out.println("Multiple kernel files for channel "+
chn+": "+channelPaths[chn]+" and "+kernelFiles[fileNum]+". Using "+channelPaths[chn]);
}
}
}
return channelPaths;
}
public String [] selectDCTFiles(
int debugLevel) { // will only open dialog if directory or files are not found
String []defaultPaths = new String[1];
String kernelDirectory=this.dctKernelDirectory;
if ((kernelDirectory==null) || (kernelDirectory.length()<=1)){ // empty or "/"
defaultPaths[0]="";
} else {
defaultPaths[0]=kernelDirectory+Prefs.getFileSeparator();
}
String [] extensions={this.dctSymSuffix};
String kernelPrefix= this.dctKernelPrefix;
CalibrationFileManagement.MultipleExtensionsFileFilter kernelFilter =
new CalibrationFileManagement.MultipleExtensionsFileFilter(kernelPrefix,extensions,kernelPrefix+
"*"+extensions[0]+" DCT symmetrical kernel files");
if (debugLevel>1) System.out.println("selectKernelFiles("+debugLevel+"): defaultPaths[0]="+defaultPaths[0]+" "+kernelPrefix+"*"+extensions[0]);
String [] kernelFiles=null;
// try reading all matching files
File dir= new File (kernelDirectory);
// if (debugLevel>1) System.out.println("selectSensorFiles, dir="+this.sensorDirectory);
File [] fileList=null;
if (dir.exists()) {
fileList=dir.listFiles(kernelFilter);
}
if ((fileList==null) || (fileList.length==0)){
kernelFiles=CalibrationFileManagement.selectFiles(false,
"Select DCT symmetrical kernel files",
"Select",
kernelFilter,
defaultPaths); // String [] defaultPaths); //this.sourceDirectory // null
if ((kernelFiles!=null) && (kernelFiles.length>0)){
kernelDirectory=kernelFiles[0].substring(0, kernelFiles[0].lastIndexOf(Prefs.getFileSeparator()));
dir= new File (kernelDirectory);
// if (debugLevel>1) System.out.println("selectSensorFiles, dir="+this.sensorDirectory);
fileList=dir.listFiles(kernelFilter);
this.dctKernelDirectory= kernelDirectory;
}
}
if ((fileList==null) || (fileList.length==0)) return null;
if (debugLevel>1) System.out.println("DCT kernel directory "+kernelDirectory+" has "+fileList.length+" matching files.");
kernelFiles = new String[fileList.length];
for (int i=0;i<kernelFiles.length;i++) kernelFiles[i]=fileList[i].getPath();
String directory=kernelFiles[0].substring(0, kernelFiles[0].lastIndexOf(Prefs.getFileSeparator()));
String prefix=kernelFiles[0].substring(directory.length()+1, kernelFiles[0].length()-extensions[0].length()-2); // all but NN
this.dctKernelDirectory=directory;
this.dctKernelPrefix=prefix;
return kernelFiles;
}
public String selectSourceDirectory(boolean smart, boolean newAllowed) { // normally newAllowed=false
String dir= CalibrationFileManagement.selectDirectory(
smart,
......@@ -757,6 +862,7 @@ public class EyesisCorrectionParameters {
if (dir!=null) this.sharpKernelDirectory=dir;
return dir;
}
public String selectSmoothKernelDirectory(boolean smart, boolean newAllowed) {
String dir= CalibrationFileManagement.selectDirectory(
smart,
......@@ -768,6 +874,19 @@ public class EyesisCorrectionParameters {
if (dir!=null) this.smoothKernelDirectory=dir;
return dir;
}
public String selectDCTKernelDirectory(boolean smart, boolean newAllowed) {
String dir= CalibrationFileManagement.selectDirectory(
smart,
newAllowed, // save
"DCT aberration kernels directory (sym and asym files)", // title
"Select DCT aberration kernelsdirectory", // button
null, // filter
this.dctKernelDirectory); //this.sourceDirectory);
if (dir!=null) this.dctKernelDirectory=dir;
return dir;
}
public String selectEquirectangularDirectory(boolean smart, boolean newAllowed) {
String dir= CalibrationFileManagement.selectDirectory(
smart,
......@@ -1674,7 +1793,10 @@ public class EyesisCorrectionParameters {
public double decimateSigma = 0.4; // what is the optimal value for each decimation?
public int tileX = 82; // number of kernel tile (0..163)
public int tileY = 62; // number of kernel tile (0..122)
public boolean subtract_dc = false;//subtract/restore dc
public int kernel_chn = -1; //camera channel calibration to use for aberration correction ( < 0 - no correction)
public boolean normalize = true; //normalize both sym and asym kernels (asym to have sum==1, sym to have sum = dct_size
public boolean skip_sym = false; // do not apply symmetrical correction
public DCTParameters(
int dct_size,
......@@ -1716,11 +1838,15 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"dbg_window_mode", this.dbg_window_mode+"");
properties.setProperty(prefix+"centerWindowToTarget", this.centerWindowToTarget+"");
properties.setProperty(prefix+"color_channel", this.color_channel+"");
properties.setProperty(prefix+"decimation", this.dbg_window_mode+"");
properties.setProperty(prefix+"decimation", this.decimation+"");
properties.setProperty(prefix+"decimateSigma", this.decimateSigma+"");
properties.setProperty(prefix+"tileX", this.tileX+"");
properties.setProperty(prefix+"tileY", this.tileY+"");
properties.setProperty(prefix+"subtract_dc", this.subtract_dc+"");
properties.setProperty(prefix+"kernel_chn", this.kernel_chn+"");
properties.setProperty(prefix+"normalize", this.normalize+"");
properties.setProperty(prefix+"skip_sym", this.skip_sym+"");
}
public void getProperties(String prefix,Properties properties){
if (properties.getProperty(prefix+"dct_size")!=null) this.dct_size=Integer.parseInt(properties.getProperty(prefix+"dct_size"));
......@@ -1741,15 +1867,17 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"dbg_sigma")!=null) this.dbg_sigma=Double.parseDouble(properties.getProperty(prefix+"dbg_sigma"));
if (properties.getProperty(prefix+"dbg_mask")!=null) this.dbg_mask=properties.getProperty(prefix+"dbg_mask");
if (properties.getProperty(prefix+"dbg_mode")!=null) this.dbg_mode=Integer.parseInt(properties.getProperty(prefix+"dbg_mode"));
if (properties.getProperty(prefix+"tileY")!=null) this.tileY=Integer.parseInt(properties.getProperty(prefix+"tileY"));
if (properties.getProperty(prefix+"centerWindowToTarget")!=null) this.centerWindowToTarget=Boolean.parseBoolean(properties.getProperty(prefix+"centerWindowToTarget"));
if (properties.getProperty(prefix+"color_channel")!=null) this.color_channel=Integer.parseInt(properties.getProperty(prefix+"color_channel"));
if (properties.getProperty(prefix+"decimation")!=null) this.decimation=Integer.parseInt(properties.getProperty(prefix+"decimation"));
if (properties.getProperty(prefix+"decimateSigma")!=null) this.decimateSigma=Double.parseDouble(properties.getProperty(prefix+"decimateSigma"));
if (properties.getProperty(prefix+"tileX")!=null) this.tileX=Integer.parseInt(properties.getProperty(prefix+"tileX"));
if (properties.getProperty(prefix+"tileY")!=null) this.tileY=Integer.parseInt(properties.getProperty(prefix+"tileY"));
if (properties.getProperty(prefix+"dbg_window_mode")!=null) this.dbg_window_mode=Integer.parseInt(properties.getProperty(prefix+"dbg_window_mode"));
if (properties.getProperty(prefix+"subtract_dc")!=null) this.subtract_dc=Boolean.parseBoolean(properties.getProperty(prefix+"subtract_dc"));
if (properties.getProperty(prefix+"kernel_chn")!=null) this.kernel_chn=Integer.parseInt(properties.getProperty(prefix+"kernel_chn"));
if (properties.getProperty(prefix+"normalize")!=null) this.normalize=Boolean.parseBoolean(properties.getProperty(prefix+"normalize"));
if (properties.getProperty(prefix+"skip_sym")!=null) this.skip_sym=Boolean.parseBoolean(properties.getProperty(prefix+"skip_sym"));
}
public boolean showDialog() {
......@@ -1779,6 +1907,11 @@ public class EyesisCorrectionParameters {
gd.addNumericField("Smooth convolution kernel before decimation", this.decimateSigma, 3);
gd.addNumericField("Tile X to extract (0..163)", this.tileX, 0);
gd.addNumericField("Tile Y to extract (0..122)", this.tileY, 0);
gd.addCheckbox ("Subtract avarege before dct, restore after idct", this.subtract_dc);
gd.addNumericField("Calibration channel to use for aberration ( <0 - no correction)",this.kernel_chn, 0);
gd.addCheckbox ("Normalize both sym and asym kernels ", this.normalize);
gd.addCheckbox ("Do not apply symmetrical (DCT) correction ", this.skip_sym);
gd.showDialog();
if (gd.wasCanceled()) return false;
......@@ -1807,7 +1940,10 @@ public class EyesisCorrectionParameters {
this.decimateSigma= gd.getNextNumber();
this.tileX= (int) gd.getNextNumber();
this.tileY= (int) gd.getNextNumber();
this.subtract_dc= gd.getNextBoolean();
this.kernel_chn= (int) gd.getNextNumber();
this.normalize= gd.getNextBoolean();
this.skip_sym= gd.getNextBoolean();
// MASTER_DEBUG_LEVEL= (int) gd.getNextNumber();
return true;
}
......
......@@ -26,6 +26,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import ij.IJ;
import ij.ImagePlus;
import ij.ImageStack;
import ij.Prefs;
public class EyesisDCT {
......@@ -50,12 +51,15 @@ public class EyesisDCT {
public double [][][] offsets = null; // per color, per kernel,per coord
public double [][] kern = null; // kernel image in linescan order
// -- new --
public int numHor = 164; // number of kernel tiles in a row
public int dct_size = 8; // DCT-II size, sym. kernel square side is 2*dct_size-1
public int asym_size = 15; // asymmetrical convolution limits, odd
public int asym_nonzdero = 4; // maximal number of non-zero elements in the asymmetrical kernels
public double [][] sym_kernels = null; // per-color channel, DCT kernels in linescan order
public double [][] asym_kernels = null; // per-color channel, asymmetrical kernels (all but asym_nonzdero elements are strictly 0)
public int numHor = 164; // number of kernel tiles in a row
public int dct_size = 8; // DCT-II size, sym. kernel square side is 2*dct_size-1
public int asym_size = 15; // asymmetrical convolution limits, odd
public int asym_nonzero = 4; // maximal number of non-zero elements in the asymmetrical kernels
public double [][] sym_kernels = null; // per-color channel, DCT kernels in linescan order
public double [][] asym_kernels = null; // per-color channel, asymmetrical kernels (all but asym_nonzero elements are strictly 0)
public double [][][][] st_kernels = null; // [color][tileY][tileX][pixel]
public double [][][][] asym_val = null; // [color][tileY][tileX][index] // value - asym kernel for elements
public int [][][][] asym_indx = null; // [color][tileY][tileX][index] // value - index of non-zero elements in the list
}
public void setKernelImageFile(ImagePlus img_kernels){
......@@ -116,10 +120,9 @@ public class EyesisDCT {
sdfa_instance.showArrays(kernels.asym_kernels, asym_width, asym_height, true, imp_kernel_sharp.getTitle()+"-asym");
}
}
return true;
}
public DCTKernels calculateDCTKernel (
final ImageStack kernelStack, // first stack with 3 colors/slices convolution kernels
......@@ -140,6 +143,7 @@ public class EyesisDCT {
dct_kernel.img_step = kernelSize/2/dct_parameters.decimation ; // May be wrong
dct_kernel.sym_kernels = new double [nChn][kernelNumHor*kernelNumVert*dct_parameters.dct_size * dct_parameters.dct_size];
dct_kernel.asym_kernels = new double [nChn][kernelNumHor*kernelNumVert*dct_parameters.asym_size * dct_parameters.asym_size];
dct_kernel.asym_nonzero = dct_parameters.asym_pixels;
// currently each 64x64 kernel corresponds to 16x16 original pixels tile, 2 tiles margin each side
final Thread[] threads = ImageDtt.newThreadArray(threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
......@@ -184,14 +188,22 @@ public class EyesisDCT {
tileX, // horizontal number of kernel to extract
tileY); // vertical number of kernel to extract
reformatKernel(
kernel, // will be blured in-place
target_kernel, // expand/crop, blur/decimate result
kernelSize,
targetSize,
dct_parameters.decimation,
dct_parameters.decimateSigma,
gb);
if ((dct_parameters.decimation == 2) && (dct_parameters.decimateSigma<0)) {
reformatKernel2( // averages by exactly 2 (decimate==2)
kernel, // will be blured in-place
target_kernel, // expand/crop, blur/decimate result
kernelSize,
targetSize);
} else {
reformatKernel(
kernel, // will be blured in-place
target_kernel, // expand/crop, blur/decimate result
kernelSize,
targetSize,
dct_parameters.decimation,
dct_parameters.decimateSigma,
gb);
}
// int numAsym =
factorConvKernel.calcKernels(
target_kernel,
......@@ -458,5 +470,317 @@ public class EyesisDCT {
}
}
}
public double []reformatKernel2( // averages by exactly 2 (decimate==2)
double [] src_kernel, //
int src_size,
int dst_size){
double [] dst_kernel = new double [dst_size*dst_size];
reformatKernel2(
src_kernel,
dst_kernel,
src_size,
dst_size);
return dst_kernel;
}
private void reformatKernel2( // averages by exactly 2 (decimate==2)
double [] src_kernel, //
double [] dst_kernel,
int src_size,
int dst_size)
{
int decimation = 2;
int [] indices = {0,-src_size,-1,1,src_size,-src_size-1,-src_size+1,src_size-1,src_size+1};
double [] weights = {0.25,0.125,0.125,0.125,0.125,0.0625,0.0625,0.0625,0.0625};
int src_center = src_size / 2; // 32
int dst_center = dst_size / 2; // 7
int src_len = src_size*src_size;
for (int i = 0; i< dst_size; i++){
int src_i = (i - dst_center)*decimation + src_center;
if ((src_i >= 0) && (src_i < src_size)) {
for (int j = 0; j< dst_size; j++) {
int src_j = (j - dst_center)*decimation + src_center;
int dst_index = i*dst_size + j;
dst_kernel[dst_index] = 0.0;
if ((src_j >= 0) && (src_j < src_size)) {
int src_index = src_i*src_size + src_j;
for (int k = 0; k < indices.length; k++){
int indx = src_index + indices[k]; // normally source kernel should be larger, these lines just to save from "out of bounds"
if (indx < 0) indx += src_len;
else if (indx >= src_len) indx -= src_len;
dst_kernel[dst_index] += weights[k]*src_kernel[indx];
}
}
}
} else {
for (int j = 0; j< dst_size; j++) dst_kernel[i*dst_size + j] = 0;
}
}
}
public boolean readDCTKernels(
EyesisCorrectionParameters.DCTParameters dct_parameters,
int srcKernelSize,
int threadsMax, // maximal number of threads to launch
boolean updateStatus,
int debugLevel
){
String [] symKernelPaths = correctionsParameters.selectDCTChannelFiles(
// 0, // 0 - sharp, 1 - smooth
eyesisCorrections.usedChannels.length, // numChannels, // number of channels
eyesisCorrections.debugLevel);
if (symKernelPaths==null) return false;
String [] asymKernelPaths = new String[symKernelPaths.length];
for (int chn = 0; chn <symKernelPaths.length; chn++ ) if (symKernelPaths[chn] != null){
int indexPeriod=symKernelPaths[chn].indexOf('.',symKernelPaths[chn].lastIndexOf(Prefs.getFileSeparator()));
asymKernelPaths[chn] = symKernelPaths[chn].substring(0, indexPeriod) + correctionsParameters.dctAsymSuffix;
}
for (int i=0;i<symKernelPaths.length;i++){
System.out.println(i+":"+symKernelPaths[i]+", "+asymKernelPaths[i]); // some may be null!
}
if (kernels == null){
kernels = new DCTKernels[eyesisCorrections.usedChannels.length];
for (int chn=0;chn<eyesisCorrections.usedChannels.length;chn++){
kernels[chn] = null;
}
}
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
DttRad2 dtt = new DttRad2(dct_parameters.dct_size);
for (int chn=0;chn<eyesisCorrections.usedChannels.length;chn++){
// if (eyesisCorrections.usedChannels[chn] && (symKernelPaths[chn]!=null) && (kernels[chn]==null)){
if (eyesisCorrections.usedChannels[chn] && (symKernelPaths[chn]!=null)){
ImagePlus imp_kernel_sym=new ImagePlus(symKernelPaths[chn]);
if (imp_kernel_sym.getStackSize()<3) {
System.out.println("Need a 3-layer stack with symmetrical DCT kernels");
symKernelPaths[chn]=null;
continue;
}
ImagePlus imp_kernel_asym=new ImagePlus(asymKernelPaths[chn]);
if (imp_kernel_sym.getStackSize()<3) {
System.out.println("Need a 3-layer stack with asymmetrical kernels");
asymKernelPaths[chn]=null;
continue;
}
ImageStack kernel_sym_stack= imp_kernel_sym.getStack();
ImageStack kernel_asym_stack= imp_kernel_asym.getStack();
System.out.println( " kernel_asym_stack.getWidth() = "+kernel_asym_stack.getWidth()+
" kernel_asym_stack.getHeight() = "+kernel_asym_stack.getHeight());
int nColors = kernel_sym_stack.getSize();
kernels[chn]= new DCTKernels();
kernels[chn].size = dct_parameters.dct_size;
kernels[chn].img_step = srcKernelSize/2/dct_parameters.decimation ; // May be wrong
kernels[chn].asym_nonzero = dct_parameters.asym_pixels;
kernels[chn].sym_kernels = new double [nColors][];
kernels[chn].asym_kernels = new double [nColors][];
for (int nc = 0; nc < nColors; nc++){
float [] pixels = (float[]) kernel_sym_stack.getPixels(nc + 1);
kernels[chn].sym_kernels[nc]= new double[pixels.length];
for (int i = 0; i<pixels.length; i++){
kernels[chn].sym_kernels[nc][i] = pixels[i];
}
pixels = (float[]) kernel_asym_stack.getPixels(nc + 1);
kernels[chn].asym_kernels[nc]= new double[pixels.length];
for (int i = 0; i<pixels.length; i++){
kernels[chn].asym_kernels[nc][i] = pixels[i];
}
}
int dct_size = kernels[chn].dct_size;
int asym_size= kernels[chn].asym_size;
int sym_width = kernels[chn].numHor * dct_size;
int sym_height = kernels[chn].sym_kernels[0].length /sym_width;
int asym_nonzero =kernels[chn].asym_nonzero;
// sdfa_instance.showArrays(kernels[chn].sym_kernels, sym_width, sym_height, true, symKernelPaths[chn]);
int asym_width = kernels[chn].numHor * kernels[chn].asym_size;
int asym_height = kernels[chn].asym_kernels[0].length /asym_width;
// sdfa_instance.showArrays(kernels[chn].asym_kernels, asym_width, asym_height, true, asymKernelPaths[chn]);
int numHor = kernels[chn].numHor;
int numVert = kernels[chn].sym_kernels[0].length / (dct_size * dct_size * numHor);
// public double [][][][] st_kernels = null; // [color][tileY][tileX][pixel]
// public double [][][][] asym_val = null; // [color][tileY][tileX][index] // value - asym kernel for elements
// public int [][][][] asym_indx = null; // [color][tileY][tileX][index] // value - index of non-zero elements in the list
kernels[chn].st_kernels = new double [nColors][numVert][numHor][dct_size * dct_size];
kernels[chn].asym_val = new double [nColors][numVert][numHor][asym_nonzero];
kernels[chn].asym_indx = new int [nColors][numVert][numHor][asym_nonzero];
int sym_kernel_inc_index = numHor * dct_size;
int asym_kernel_inc_index = numHor * asym_size;
System.out.println("readDCTKernels() debugLevel = "+debugLevel+
" kernels["+chn+"].size = "+kernels[chn].size+
" kernels["+chn+"].img_step = "+kernels[chn].img_step+
" kernels["+chn+"].asym_nonzero = "+kernels[chn].asym_nonzero+
" nColors = "+ nColors+
" numVert = "+ numVert+
" numHor = "+ numHor);
for (int nc = 0; nc < nColors; nc++){
for (int tileY = 0; tileY < numVert; tileY++){
for (int tileX = 0; tileX < numHor; tileX++){
// extract DCT (symmetrical) kernels
int sym_kernel_start_index = (sym_kernel_inc_index * tileY + tileX) * dct_size;
for (int i = 0; i < dct_size;i++){
System.arraycopy( // copy one kernel line
kernels[chn].sym_kernels[nc],
sym_kernel_start_index + i * sym_kernel_inc_index,
kernels[chn].st_kernels[nc][tileY][tileX],
i * dct_size,
dct_size);
}
double scale = dct_size;
if (dct_parameters.normalize) {
double sum = 0.0;
for (int i=0; i < dct_size;i++) {
for (int j=0; j < dct_size;j++) {
double d = kernels[chn].st_kernels[nc][tileY][tileX][i];
if (i > 0) d *= 2.0;
if (j > 0) d *= 2.0;
sum += d;
}
}
scale /= sum;
}
kernels[chn].st_kernels[nc][tileY][tileX]= dtt.dttt_iii(kernels[chn].st_kernels[nc][tileY][tileX]);
for (int i=0; i < kernels[chn].st_kernels[nc][tileY][tileX].length;i++) {
kernels[chn].st_kernels[nc][tileY][tileX][i] *= scale;
}
// extract asymmetrical kernel and convert it to list of values and indices (as arrays as the length is known)
int asym_kernel_start_index = (asym_kernel_inc_index * tileY + tileX)* asym_size;
int indx = 0;
for (int i = 0; (i < dct_parameters.asym_size) && (indx < asym_nonzero); i++){
for (int j = 0; (j < dct_parameters.asym_size) && (indx < asym_nonzero); j++){
double v = kernels[chn].asym_kernels[nc][asym_kernel_start_index + i * asym_kernel_inc_index +j];
if (v!=0.0){
if ((tileY==67) && (tileX==125)) {
System.out.println("i="+i+" j="+j+" v="+v+" indx="+indx+" i * asym_size + j="+(i * asym_size + j));
System.out.println("asym_kernel_start_index + i * asym_kernel_inc_index +j="+(asym_kernel_start_index + i * asym_kernel_inc_index +j));
}
kernels[chn].asym_val[nc][tileY][tileX][indx] = v;
kernels[chn].asym_indx[nc][tileY][tileX][indx++] = i * asym_size + j;
}
}
}
if ((tileY==67) && (tileX==125)) {
for (int i=0; i<kernels[chn].asym_indx[nc][tileY][tileX].length; i++){
System.out.println("kernels["+chn+"].asym_val["+nc+"]["+tileY+"]["+tileX+"]["+i+"]="+kernels[chn].asym_val[nc][tileY][tileX][i]);
System.out.println("kernels["+chn+"].asym_indx["+nc+"]["+tileY+"]["+tileX+"]["+i+"]="+kernels[chn].asym_indx[nc][tileY][tileX][i]);
}
}
if (dct_parameters.normalize) {
double sum = 0.0;
for (int i = 0; i < kernels[chn].asym_val[nc][tileY][tileX].length;i++){
sum += kernels[chn].asym_val[nc][tileY][tileX][i];
if ((tileY==67) && (tileX==125)) {
System.out.println("i="+i+", sum="+sum);
}
}
for (int i = 0; i < kernels[chn].asym_val[nc][tileY][tileX].length;i++){
kernels[chn].asym_val[nc][tileY][tileX][i] /= sum;
}
if ((tileY==67) && (tileX==125)) {
System.out.println("sum="+sum+", normalized:");
for (int i=0; i<kernels[chn].asym_indx[nc][tileY][tileX].length; i++){
System.out.println("kernels["+chn+"].asym_val["+nc+"]["+tileY+"]["+tileX+"]["+i+"]="+kernels[chn].asym_val[nc][tileY][tileX][i]);
System.out.println("kernels["+chn+"].asym_indx["+nc+"]["+tileY+"]["+tileX+"]["+i+"]="+kernels[chn].asym_indx[nc][tileY][tileX][i]);
}
}
}
}
// System.out.println("tileY="+tileY);
}
}
// Debug will be removed later, the
sdfa_instance.showArrays(kernels[chn].sym_kernels, sym_width, sym_height, true, symKernelPaths[chn]);
sdfa_instance.showArrays(kernels[chn].asym_kernels, asym_width, asym_height, true, asymKernelPaths[chn]);
kernels[chn].sym_kernels = null; // not needed anymore
kernels[chn].asym_kernels = null; // not needed anymore
}
}
return true;
}
public void showKernels(){
// System.out.println("showKernels(): kernels.length="+kernels.length);
for (int chn=0;chn < kernels.length; chn++){
if (kernels[chn]!=null){
// System.out.println("showKernels("+chn+")");
showKernels(chn);
}
}
}
public void showKernels(int chn){
int nColors = kernels[chn].st_kernels.length;
int numVert = kernels[chn].st_kernels[0].length;
int numHor = kernels[chn].st_kernels[0][0].length;
int dct_size = kernels[chn].dct_size;
int asym_size= kernels[chn].asym_size;
int sym_width = numHor * dct_size;
int sym_height = numVert * dct_size;
// int asym_nonzero =kernels[chn].asym_nonzero;
int asym_width = numHor * kernels[chn].asym_size;
int asym_height = numVert * kernels[chn].asym_size;
kernels[chn].sym_kernels = new double [nColors][sym_width*sym_height];
kernels[chn].asym_kernels = new double [nColors][asym_width*asym_height];
int sym_kernel_inc_index = numHor * dct_size;
int asym_kernel_inc_index = numHor * asym_size;
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
for (int nc = 0; nc < nColors; nc++){
for (int tileY = 0; tileY < numVert; tileY++){
for (int tileX = 0; tileX < numHor; tileX++){
// set DCT (symmetrical) kernels
int sym_kernel_start_index = (sym_kernel_inc_index * tileY + tileX) * dct_size;
for (int i = 0; i < dct_size;i++){
System.arraycopy( // copy one kernel line
kernels[chn].st_kernels[nc][tileY][tileX],
i * dct_size,
kernels[chn].sym_kernels[nc],
sym_kernel_start_index + i * sym_kernel_inc_index,
dct_size);
}
// set asymmetrical kernel from the list of values and indices
double [] asym_kernel = new double[asym_size*asym_size];
for (int i=0;i<asym_kernel.length; i++) asym_kernel[i] = 0.0;
for (int i = 0; i<kernels[chn].asym_indx[nc][tileY][tileX].length; i++){
asym_kernel[kernels[chn].asym_indx[nc][tileY][tileX][i]] = kernels[chn].asym_val[nc][tileY][tileX][i];
if ((tileY==67) && (tileX==125)) {
System.out.println("kernels["+chn+"].asym_val["+nc+"]["+tileY+"]["+tileX+"]["+i+"]="+kernels[chn].asym_val[nc][tileY][tileX][i]);
System.out.println("kernels["+chn+"].asym_indx["+nc+"]["+tileY+"]["+tileX+"]["+i+"]="+kernels[chn].asym_indx[nc][tileY][tileX][i]);
System.out.println("asym_kernel["+(kernels[chn].asym_indx[nc][tileY][tileX][i])+"]="+asym_kernel[kernels[chn].asym_indx[nc][tileY][tileX][i]]);
}
}
int asym_kernel_start_index = (asym_kernel_inc_index * tileY + tileX)* asym_size;
for (int i = 0; i < asym_size;i++){
System.arraycopy( // copy one kernel line
asym_kernel,
i * asym_size,
kernels[chn].asym_kernels[nc],
asym_kernel_start_index + i * asym_kernel_inc_index,
asym_size);
}
}
}
}
System.out.println("sym_width="+sym_width+" sym_height="+sym_height);
System.out.println("kernels["+chn+"].sym_kernels.length="+kernels[chn].sym_kernels.length);
System.out.println("kernels["+chn+"][0].sym_kernels.length="+kernels[chn].sym_kernels[0].length);
System.out.println("asym_width="+asym_width+" asym_height="+asym_height);
System.out.println("kernels["+chn+"].asym_kernels.length="+kernels[chn].asym_kernels.length);
System.out.println("kernels["+chn+"][0].asym_kernels.length="+kernels[chn].asym_kernels[0].length);
sdfa_instance.showArrays(kernels[chn].sym_kernels, sym_width, sym_height, true, "restored-sym-"+chn);
sdfa_instance.showArrays(kernels[chn].asym_kernels, asym_width, asym_height, true, "restored-asym-"+chn);
kernels[chn].sym_kernels = null; // not needed anymore
kernels[chn].asym_kernels = null; // not needed anymore
}
}
......@@ -318,6 +318,7 @@ private Panel panel1,panel2,panel3,panel4,panel5,panel5a, panel6,panel7,panelPos
public static boolean DCT_MODE=false; //true; // show all buttons
public static boolean MODE_3D=false; // 3D-related commands
public PixelMapping.InterSensor.DisparityTiles DISPARITY_TILES=null;
public ImagePlus DBG_IMP = null;
public class SyncCommand{
public boolean isRunning= false;
......@@ -451,13 +452,16 @@ private Panel panel1,panel2,panel3,panel4,panel5,panel5a, panel6,panel7,panelPos
panelDct1 = new Panel();
panelDct1.setLayout(new GridLayout(1, 0, 5, 5)); // rows, columns, vgap, hgap
addButton("DCT test 1", panelDct1, color_process);
addButton("DCT test 2", panelDct1, color_process);
addButton("select MDCT image", panelDct1, color_configure);
addButton("MDCT stack", panelDct1, color_process);
addButton("MDCT DC stack", panelDct1, color_process);
addButton("DCT test 3", panelDct1, color_process);
addButton("DCT test 4", panelDct1, color_process);
addButton("Test Kernel Factorization", panelDct1, color_process);
addButton("Min Kernel Factorization", panelDct1, color_process);
addButton("Select kernels image", panelDct1, color_configure);
addButton("Create DCT kernels", panelDct1, color_process);
addButton("Read DCT kernels", panelDct1, color_process);
add(panelDct1);
}
pack();
......@@ -2586,51 +2590,87 @@ private Panel panel1,panel2,panel3,panel4,panel5,panel5a, panel6,panel7,panelPos
plot.show();
return;
/* ======================================================================== */
// public ImagePlus DBG_IMP = null;
} else if (label.equals("select MDCT image")) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
// IJ.showMessage("DCT test 1");
if (!DCT_PARAMETERS.showDialog()) return;
// process selected image stack
ImagePlus imp_src = WindowManager.getCurrentImage();
if (imp_src==null){
IJ.showMessage("Error","JP4 image or Bayer image stack required");
return;
}
if (imp_src.getStackSize()<3){ // convert JP4 to image stack
EyesisCorrectionParameters.SplitParameters split_parameters = new EyesisCorrectionParameters.SplitParameters(
1, // oversample;
// Add just for mdct (N/2)
DCT_PARAMETERS.dct_size/2, // addLeft
DCT_PARAMETERS.dct_size/2, // addTop
DCT_PARAMETERS.dct_size/2, // addRight
DCT_PARAMETERS.dct_size/2 // addBottom
);
ImageStack sourceStack= bayerToStack(imp_src, // source Bayer image, linearized, 32-bit (float))
split_parameters);
DBG_IMP = new ImagePlus(imp_src.getTitle()+"-SPIT", sourceStack);
if (DEBUG_LEVEL > 1) {
DBG_IMP.getProcessor().resetMinAndMax();
DBG_IMP.show();
}
} else {
DBG_IMP = imp_src;
}
/* ======================================================================== */
} else if (label.equals("DCT test 2")) {
} else if (label.equals("MDCT stack")) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
// IJ.showMessage("DCT test 1");
if (!DCT_PARAMETERS.showDialog()) return;
// process selected image stack
ImagePlus imp_src = WindowManager.getCurrentImage();
if (imp_src==null){
IJ.showMessage("Error","JP4 image or Bayer image stack required");
return;
}
ImagePlus imp2;
if (imp_src.getStackSize()<3){ // convert JP4 to image stack
EyesisCorrectionParameters.SplitParameters split_parameters = new EyesisCorrectionParameters.SplitParameters(
1, // oversample;
// Add just for mdct (N/2)
DCT_PARAMETERS.dct_size/2, // addLeft
DCT_PARAMETERS.dct_size/2, // addTop
DCT_PARAMETERS.dct_size/2, // addRight
DCT_PARAMETERS.dct_size/2 // addBottom
);
ImageStack sourceStack= bayerToStack(imp_src, // source Bayer image, linearized, 32-bit (float))
split_parameters);
imp2 = new ImagePlus(imp_src.getTitle()+"-SPIT", sourceStack);
imp2.getProcessor().resetMinAndMax();
imp2.show();
} else {
imp2 = imp_src;
// process selected image stack
if (DBG_IMP == null) {
ImagePlus imp_src = WindowManager.getCurrentImage();
if (imp_src==null){
IJ.showMessage("Error","JP4 image or Bayer image stack required");
return;
}
// ImagePlus imp2;
if (imp_src.getStackSize()<3){ // convert JP4 to image stack
EyesisCorrectionParameters.SplitParameters split_parameters = new EyesisCorrectionParameters.SplitParameters(
1, // oversample;
// Add just for mdct (N/2)
DCT_PARAMETERS.dct_size/2, // addLeft
DCT_PARAMETERS.dct_size/2, // addTop
DCT_PARAMETERS.dct_size/2, // addRight
DCT_PARAMETERS.dct_size/2 // addBottom
);
ImageStack sourceStack= bayerToStack(imp_src, // source Bayer image, linearized, 32-bit (float))
split_parameters);
DBG_IMP = new ImagePlus(imp_src.getTitle()+"-SPIT", sourceStack);
DBG_IMP.getProcessor().resetMinAndMax();
DBG_IMP.show();
} else {
DBG_IMP = imp_src;
}
}
ImageDtt image_dtt = new ImageDtt();
double [][] dct_data = image_dtt.mdctStack(imp2.getStack(),
double [][] dct_data = image_dtt.mdctStack(DBG_IMP.getStack(),
DCT_PARAMETERS,
THREADS_MAX, DEBUG_LEVEL, UPDATE_STATUS);
int tilesY = imp2.getHeight()/DCT_PARAMETERS.dct_size - 1;
int tilesX = imp2.getWidth()/DCT_PARAMETERS.dct_size - 1;
int tilesY = DBG_IMP.getHeight()/DCT_PARAMETERS.dct_size - 1;
int tilesX = DBG_IMP.getWidth()/DCT_PARAMETERS.dct_size - 1;
System.out.println("tilesX="+tilesX);
System.out.println("tilesY="+tilesY);
SDFA_INSTANCE.showArrays(dct_data,
tilesX*DCT_PARAMETERS.dct_size,
tilesY*DCT_PARAMETERS.dct_size,
true,
imp_src.getTitle()+"-DCT");
DBG_IMP.getTitle()+"-DCT");
double [][] idct_data = new double [dct_data.length][];
for (int chn=0; chn<idct_data.length;chn++){
idct_data[chn] = image_dtt.lapped_idct(
......@@ -2645,11 +2685,104 @@ private Panel panel1,panel2,panel3,panel4,panel5,panel5a, panel6,panel7,panelPos
(tilesX + 1) * DCT_PARAMETERS.dct_size,
(tilesY + 1) * DCT_PARAMETERS.dct_size,
true,
imp_src.getTitle()+"-IDCT");
DBG_IMP.getTitle()+"-IDCT");
return;
/* ======================================================================== */
} else if (label.equals("MDCT DC stack")) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
// IJ.showMessage("DCT test 1");
if (!DCT_PARAMETERS.showDialog()) return;
// process selected image stack
if (DBG_IMP == null) {
ImagePlus imp_src = WindowManager.getCurrentImage();
if (imp_src==null){
IJ.showMessage("Error","JP4 image or Bayer image stack required");
return;
}
// ImagePlus imp2;
if (imp_src.getStackSize()<3){ // convert JP4 to image stack
EyesisCorrectionParameters.SplitParameters split_parameters = new EyesisCorrectionParameters.SplitParameters(
1, // oversample;
// Add just for mdct (N/2)
DCT_PARAMETERS.dct_size/2, // addLeft
DCT_PARAMETERS.dct_size/2, // addTop
DCT_PARAMETERS.dct_size/2, // addRight
DCT_PARAMETERS.dct_size/2 // addBottom
);
ImageStack sourceStack= bayerToStack(imp_src, // source Bayer image, linearized, 32-bit (float))
split_parameters);
DBG_IMP = new ImagePlus(imp_src.getTitle()+"-SPIT", sourceStack);
DBG_IMP.getProcessor().resetMinAndMax();
DBG_IMP.show();
} else {
DBG_IMP = imp_src;
}
}
ImageDtt image_dtt = new ImageDtt();
double [][][][] dctdc_data = image_dtt.mdctDcStack(
DBG_IMP.getStack(),
DCT_PARAMETERS,
EYESIS_DCT,
THREADS_MAX, DEBUG_LEVEL, UPDATE_STATUS);
for (int chn = 0; chn < dctdc_data.length; chn++) {
image_dtt.dct_lpf(
DCT_PARAMETERS.dbg_sigma,
dctdc_data[chn],
THREADS_MAX, DEBUG_LEVEL);
}
int tilesY = DBG_IMP.getHeight()/DCT_PARAMETERS.dct_size - 1;
int tilesX = DBG_IMP.getWidth()/DCT_PARAMETERS.dct_size - 1;
System.out.println("tilesX="+tilesX);
System.out.println("tilesY="+tilesY);
double [][] dct_dc = new double [dctdc_data.length][];
double [][] dct_ac = new double [dctdc_data.length][];
for (int chn = 0; chn < dct_dc.length; chn++) {
dct_dc[chn] = image_dtt.lapped_dct_dcac(
false, // out_ac, // false - output DC, true - output AC
dctdc_data [chn],
THREADS_MAX,
DEBUG_LEVEL);
dct_ac[chn] = image_dtt.lapped_dct_dcac(
true, // out_ac, // false - output DC, true - output AC
dctdc_data [chn],
THREADS_MAX,
DEBUG_LEVEL);
}
// System.out.println("dct_dc.length="+dct_dc.length+" dct_ac.length="+dct_ac.length);
SDFA_INSTANCE.showArrays(dct_ac,
tilesX*DCT_PARAMETERS.dct_size,
tilesY*DCT_PARAMETERS.dct_size,
true,
DBG_IMP.getTitle()+"-DCT_AC");
SDFA_INSTANCE.showArrays(dct_dc,
tilesX,
tilesY,
true,
DBG_IMP.getTitle()+"-DCT_DC");
double [][] idct_data = new double [dctdc_data.length][];
for (int chn=0; chn<idct_data.length;chn++){
idct_data[chn] = image_dtt.lapped_idctdc(
dctdc_data[chn], // scanline representation of dcd data, organized as dct_size x dct_size tiles
DCT_PARAMETERS.dct_size, // final int
DCT_PARAMETERS.dct_window, //window_type
THREADS_MAX, // maximal number of threads to launch
DEBUG_LEVEL); // globalDebugLevel)
}
SDFA_INSTANCE.showArrays(idct_data,
(tilesX + 1) * DCT_PARAMETERS.dct_size,
(tilesY + 1) * DCT_PARAMETERS.dct_size,
true,
DBG_IMP.getTitle()+"-IDCTDC");
return;
/* ======================================================================== */
/* ======================================================================== */
} else if (label.equals("DCT test 3")) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
int n = 32;
......@@ -2978,12 +3111,20 @@ private Panel panel1,panel2,panel3,panel4,panel5,panel5a, panel6,panel7,panelPos
DCT_PARAMETERS.color_channel, // 0..2
DCT_PARAMETERS.tileX, // horizontal number of kernel to extract
DCT_PARAMETERS.tileY); // vertical number of kernel to extract
if ((DCT_PARAMETERS.decimation==2)&& (DCT_PARAMETERS.decimateSigma < 0)){
target_expanded = EYESIS_DCT.reformatKernel2(
src_kernel,// will be blured in-place
CONVOLVE_FFT_SIZE/2, // typical 64
target_expanded_size); // typical 15
} else {
target_expanded = EYESIS_DCT.reformatKernel(
src_kernel,// will be blured in-place
CONVOLVE_FFT_SIZE/2, // typical 64
target_expanded_size, // typical 15
DCT_PARAMETERS.decimation,// typical 2
DCT_PARAMETERS.decimateSigma);
}
} else {
System.out.println("Using synthesized target kernel");
double [] target_kernel = new double [target_kernel_size * target_kernel_size];
......@@ -3058,16 +3199,6 @@ private Panel panel1,panel2,panel3,panel4,panel5,panel5a, panel6,panel7,panelPos
} else if (label.equals("DCT test 4")) {
/*
public int calcKernels(
double []target_kernel,
int asym_size,
int sym_radius,
double fact_precision,
int asym_pixels, // maximal number of non-zero pixels in asymmmetrical kernel
int asym_distance){ // how far to seed a new pixel
*/
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
EYESIS_CORRECTIONS.setDebug(DEBUG_LEVEL);
String configPath=null;
......@@ -3159,9 +3290,53 @@ private Panel panel1,panel2,panel3,panel4,panel5,panel5a, panel6,panel7,panelPos
THREADS_MAX,
UPDATE_STATUS, // update status info
DEBUG_LEVEL);
} else if (label.equals("Read DCT kernels")) {
if (!DCT_PARAMETERS.showDialog()) return;
if (EYESIS_DCT == null){
EYESIS_DCT = new EyesisDCT (
EYESIS_CORRECTIONS,
CORRECTION_PARAMETERS,
DCT_PARAMETERS);
}
String configPath=null;
if (EYESIS_CORRECTIONS.correctionsParameters.saveSettings) {
configPath=EYESIS_CORRECTIONS.correctionsParameters.selectResultsDirectory(
true,
true);
if (configPath==null){
String msg="No results directory selected, command aborted";
System.out.println("Warning: "+msg);
IJ.showMessage("Warning",msg);
return;
}
configPath+=Prefs.getFileSeparator()+"autoconfig";
try {
saveTimestampedProperties(
configPath, // full path or null
null, // use as default directory if path==null
true,
PROPERTIES);
} catch (Exception e){
String msg="Failed to save configuration to "+configPath+", command aborted";
System.out.println("Error: "+msg);
IJ.showMessage("Error",msg);
return;
}
}
EYESIS_CORRECTIONS.initSensorFiles(DEBUG_LEVEL);
EYESIS_DCT.readDCTKernels(
DCT_PARAMETERS,
CONVOLVE_FFT_SIZE/2,
THREADS_MAX,
UPDATE_STATUS, // update status info
DEBUG_LEVEL);
// EyesisCorrectionParameters.DCTParameters dCTParameters,
// int srcKernelSize,
EYESIS_DCT.showKernels(); // show restored kernels
}
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
......
......@@ -41,20 +41,11 @@ public class ImageDtt {
{
if (imageStack==null) return null;
final int imgWidth=imageStack.getWidth();
// final int imgHeight=imageStack.getHeight();
final int nChn=imageStack.getSize();
double [][] dct_data = new double [nChn][];
float [] fpixels;
int i,chn; //tileX,tileY;
/* find number of the green channel - should be called "green", if none - use last */
/*
i=nChn-1;
for (chn=0;chn<nChn;chn++) if (imageStack.getSliceLabel(chn+1).equals("green")){
i=chn;
break;
}
final int greenChn=i;
*/
// Extract float pixels from inage stack, convert each to double
for (chn=0;chn<nChn;chn++) {
......@@ -122,7 +113,10 @@ public class ImageDtt {
return dct_data;
}
public double [] lapped_idct(
final double [] dct_data, // scanline representation of dcd data, organized as dct_size x dct_size tiles
final int dct_width,
......@@ -203,6 +197,341 @@ public class ImageDtt {
return dpixels;
}
public double [][][][] mdctDcStack(
final ImageStack imageStack,
final EyesisCorrectionParameters.DCTParameters dctParameters, //
final EyesisDCT eyesisDCT,
final int threadsMax, // maximal step in pixels on the maxRadius for 1 angular step (i.e. 0.5)
final int debugLevel,
final boolean updateStatus) // update status info
{
if (imageStack==null) return null;
final int imgWidth=imageStack.getWidth();
final int nChn=imageStack.getSize();
double [][][][] dctdc_data = new double [nChn][][][];
float [] fpixels;
int i,chn; //tileX,tileY;
/* find number of the green channel - should be called "green", if none - use last */
// Extract float pixels from inage stack, convert each to double
EyesisDCT.DCTKernels dct_kernels = null;
if (dctParameters.kernel_chn >=0 ){
dct_kernels = eyesisDCT.kernels[dctParameters.kernel_chn];
}
for (chn=0;chn<nChn;chn++) {
fpixels= (float[]) imageStack.getPixels(chn+1);
double[] dpixels = new double[fpixels.length];
for (i = 0; i <fpixels.length;i++) dpixels[i] = fpixels[i];
// convert each to DCT tiles
dctdc_data[chn] =lapped_dctdc(
dpixels,
imgWidth,
dctParameters.dct_size,
dctParameters.subtract_dc,
0, // dct_mode, // 0: dct/dct, 1: dct/dst, 2: dst/dct, 3: dst/dst
dctParameters.dct_window, // final int window_type,
chn,
dct_kernels,
dctParameters.skip_sym,
threadsMax, // maximal number of threads to launch
debugLevel);
}
return dctdc_data;
}
// extract DC, result is an array [tilesY][tilesX][dct_size*dct_size+1] - last element is DC value
public double [][][] lapped_dctdc(
final double [] dpixels,
final int width,
final int dct_size,
final boolean subtract_dc,
final int dct_mode, // 0: dct/dct, 1: dct/dst, 2: dst/dct, 3: dst/dst
final int window_type,
final int color,
final EyesisDCT.DCTKernels dct_kernels,
final boolean skip_sym,
final int threadsMax, // maximal number of threads to launch
final int globalDebugLevel)
{
final int kernel_margin = 1; //move to parameters?
final int height=dpixels.length/width;
final int tilesX=width/dct_size-1;
final int tilesY=height/dct_size-1;
final int nTiles=tilesX*tilesY;
final double [][][] dctdc_data = new double[tilesY][tilesX][dct_size*dct_size+1];
final Thread[] threads = newThreadArray(threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
for (int tileY = 0; tileY < tilesY; tileY++){
for (int tileX = 0; tileX < tilesX; tileX++){
for (int i=0; i<dctdc_data[tileY][tileX].length;i++) dctdc_data[tileY][tileX][i]= 0.0; // actually not needed, Java initializes arrays
}
}
System.out.println("lapped_dctdc(): width="+width+" height="+height);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
DttRad2 dtt = new DttRad2(dct_size);
dtt.set_window(window_type);
double [] tile_in = new double[4*dct_size * dct_size];
double [] tile_folded;
double [] tile_out; // = new double[dct_size * dct_size];
int tileY,tileX;
int n2 = dct_size * 2;
double dc;
for (int nTile = ai.getAndIncrement(); nTile < nTiles; nTile = ai.getAndIncrement()) {
tileY = nTile/tilesX;
tileX = nTile - tileY * tilesX;
int kernelTileY=0;
int kernelTileX=0;
//readDCTKernels() debugLevel = 1 kernels[0].size = 8 kernels[0].img_step = 16 kernels[0].asym_nonzero = 4 nColors = 3 numVert = 123 numHor = 164
if (dct_kernels != null){ // convolve directly with asym_kernel
int asym_center = dct_kernels.asym_size/2; // 7 for 15
kernelTileY = kernel_margin + (tileY * dct_size) / dct_kernels.img_step;
kernelTileX = kernel_margin + (tileX * dct_size) / dct_kernels.img_step;
if ((tileY <2) && (tileX <2) && (color ==0)) {
System.out.println("kernelTileY="+kernelTileY+" kernelTileX="+kernelTileX+" width="+width);
}
for (int i = 0; i < n2; i++){
for (int j = 0; j < n2; j++){
tile_in[i*n2 + j] = 0.0;
// convolve list
int [] asym_indx = dct_kernels.asym_indx[color][kernelTileY][kernelTileX];
double [] asym_val = dct_kernels.asym_val[color][kernelTileY][kernelTileX];
for (int indx = 0; indx < asym_indx.length; indx++){
int xy = asym_indx[indx];
if ((tileY <2) && (tileX <2) && (color ==0)) {
System.out.println("i="+i+" j="+j+" indx="+indx+" xy="+xy);
}
if (xy >= 0) {
int dy = (xy / dct_kernels.asym_size) - asym_center;
int dx = (xy % dct_kernels.asym_size) - asym_center;
int y = tileY*dct_size - dy + i;
int x = tileX*dct_size - dx + j;
if (y < 0) y &= 1;
if (x < 0) x &= 1;
if (y >= height) y = (height - 2) + (y & 1);
if (x >= width) x = (width - 2) + (x & 1);
tile_in[i*n2 + j] += asym_val[indx] * dpixels[ y * width + x];
if ((tileY <2) && (tileX <2) && (color ==0)) {
System.out.println("dy= "+dy+" dx="+dx+" x = "+x+" y="+y+" y*width + x="+(y*width + x));
System.out.println("asym_val["+indx+"]="+asym_val[indx]+
" dpixels["+(y * width + x)+"]="+ dpixels[ y * width + x]+
"tile_in["+(i*n2 + j)+"]="+tile_in[i*n2 + j]);
}
}
}
}
}
} else { // no aberration correction, just copy data
for (int i = 0; i < n2;i++){
System.arraycopy(dpixels, (tileY*width+tileX)*dct_size + i*width, tile_in, i*n2, n2);
}
}
tile_folded=dtt.fold_tile(tile_in, dct_size);
dc = 0.0;
if (subtract_dc) {
for (int i = 0; i < tile_folded.length; i++) dc+=tile_folded[i];
dc /= tile_folded.length;
for (int i = 0; i < tile_folded.length; i++) tile_folded[i] -= dc;
}
tile_out=dtt.dttt_iv (tile_folded, dct_mode, dct_size);
if ((dct_kernels != null) && !skip_sym){ // convolve in frequency domain with sym_kernel
for (int i = 0; i < tile_out.length; i++){
tile_out[i] *=dct_kernels.st_kernels[color][kernelTileY][kernelTileX][i];
}
}
System.arraycopy(tile_out, 0, dctdc_data[tileY][tileX], 0, tile_out.length);
dctdc_data[tileY][tileX][tile_out.length] = dc;
}
}
};
}
startAndJoin(threads);
return dctdc_data;
}
// extract DC or AC components in linescan order (for visualization)
public double [] lapped_dct_dcac(
final boolean out_ac, // false - output DC, true - output AC
final double [][][] dctdc_data,
final int threadsMax, // maximal number of threads to launch
final int globalDebugLevel)
{
final int tilesY=dctdc_data.length;
final int tilesX=dctdc_data[0].length;
final int nTiles=tilesX*tilesY;
final int dct_size = (int) Math.round(Math.sqrt(dctdc_data[0][0].length-1));
final int dct_len = dct_size*dct_size;
final double [] dct_data = new double[tilesY*tilesX*(out_ac?dct_len:1)];
final Thread[] threads = newThreadArray(threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
for (int i=0; i<dct_data.length;i++) dct_data[i]= 0;
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
int tileY,tileX;
for (int nTile = ai.getAndIncrement(); nTile < nTiles; nTile = ai.getAndIncrement()) {
tileY = nTile/tilesX;
tileX = nTile - tileY * tilesX;
if (out_ac) {
for (int i = 0; i < dct_size;i++){
System.arraycopy(dctdc_data[tileY][tileX], dct_size* i, dct_data, ((tileY*dct_size + i) *tilesX + tileX)*dct_size , dct_size);
}
} else {
dct_data[tileY *tilesX + tileX] = dctdc_data[tileY][tileX][dct_len];
}
}
}
};
}
startAndJoin(threads);
return dct_data;
}
public void dct_lpf(
final double sigma,
final double [][][] dctdc_data,
final int threadsMax, // maximal number of threads to launch
final int globalDebugLevel)
{
final int tilesY=dctdc_data.length;
final int tilesX=dctdc_data[0].length;
final int nTiles=tilesX*tilesY;
final int dct_size = (int) Math.round(Math.sqrt(dctdc_data[0][0].length-1));
final int dct_len = dct_size*dct_size;
final double [] filter_direct= new double[dct_len];
if (sigma == 0) {
filter_direct[0] = 1.0;
for (int i= 1; i<filter_direct.length;i++) filter_direct[i] =0;
} else {
for (int i = 0; i < dct_size; i++){
for (int j = 0; j < dct_size; j++){
filter_direct[i*dct_size+j] = Math.exp(-(i*i+j*j)/(2*sigma));
}
}
}
if (globalDebugLevel>2) {
for (int i=0; i<filter_direct.length;i++){
System.out.println("dct_lpf_psf() "+i+": "+filter_direct[i]);
}
}
DttRad2 dtt = new DttRad2(dct_size);
final double [] filter= dtt.dttt_iii(filter_direct);
for (int i=0; i < filter.length;i++) filter[i] *= dct_size;
if (globalDebugLevel>2) {
for (int i=0; i<filter.length;i++){
System.out.println("dct_lpf_psf() "+i+": "+filter[i]);
}
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
double [][] ff = {filter_direct,filter};
sdfa_instance.showArrays(ff, dct_size,dct_size, true, "filter_lpf");
}
final Thread[] threads = newThreadArray(threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
int tileY,tileX;
for (int nTile = ai.getAndIncrement(); nTile < nTiles; nTile = ai.getAndIncrement()) {
tileY = nTile/tilesX;
tileX = nTile - tileY * tilesX;
for (int i = 0; i < filter.length; i++){
dctdc_data[tileY][tileX][i] *= filter[i];
}
}
}
};
}
startAndJoin(threads);
}
// Restore DC
public double [] lapped_idctdc(
final double [][][] dctdc_data, // array [tilesY][tilesX][dct_size*dct_size+1] - last element is DC value
final int dct_size,
final int window_type,
final int threadsMax, // maximal number of threads to launch
final int globalDebugLevel)
{
// final int tilesX=dct_width/dct_size;
// final int tilesY=dct_data.length/(dct_width*dct_size);
final int tilesY=dctdc_data.length;
final int tilesX=dctdc_data[0].length;
final int width= (tilesX+1)*dct_size;
final int height= (tilesY+1)*dct_size;
System.out.println("lapped_idct():tilesX= "+tilesX);
System.out.println("lapped_idct():tilesY= "+tilesY);
System.out.println("lapped_idct():width= "+width);
System.out.println("lapped_idct():height= "+height);
final double [] dpixels = new double[width*height];
final Thread[] threads = newThreadArray(threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
final AtomicInteger nser = new AtomicInteger(0);
final int [][][] tiles_list = new int[4][][];
for (int n=0; n<4; n++){
int nx = (tilesX + 1 - (n &1)) / 2;
int ny = (tilesY + 1 - ((n>>1) & 1)) / 2;
tiles_list[n] = new int [nx*ny][2];
int indx = 0;
for (int i = 0;i < ny; i++) for (int j = 0; j < nx; j++){
tiles_list[n][indx][0]=2*j+(n &1);
tiles_list[n][indx++][1]=2*i+((n>>1) & 1);
}
}
for (int i=0; i<dpixels.length;i++) dpixels[i]= 0;
for (int n=0; n<4; n++){
nser.set(n);
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
DttRad2 dtt = new DttRad2(dct_size);
dtt.set_window(window_type);
double [] tile_in = new double[dct_size * dct_size];
double [] tile_dct; // = new double[dct_size * dct_size];
double [] tile_out; // = new double[4*dct_size * dct_size];
int tileY,tileX;
int n2 = dct_size * 2;
for (int nTile = ai.getAndIncrement(); nTile < tiles_list[nser.get()].length; nTile = ai.getAndIncrement()) {
tileX = tiles_list[nser.get()][nTile][0];
tileY = tiles_list[nser.get()][nTile][1];
System.arraycopy(dctdc_data[tileY][tileX], 0, tile_in, 0, tile_in.length);
double dc = dctdc_data[tileY][tileX][tile_in.length];
tile_dct=dtt.dttt_iv (tile_in, 0, dct_size);
for (int i = 0; i<tile_dct.length; i++) tile_dct[i] += dc;
tile_out=dtt.unfold_tile(tile_dct, dct_size);
for (int i = 0; i < n2;i++){
int start_line = ((tileY*dct_size + i) *(tilesX+1) + tileX)*dct_size;
for (int j = 0; j<n2;j++) {
dpixels[start_line + j] += tile_out[n2 * i + j]; // +1.0;
}
}
}
}
};
}
startAndJoin(threads);
}
return dpixels;
}
/* Create a Thread[] array as large as the number of processors available.
* From Stephan Preibisch's Multithreading.java class. See:
......
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