Commit 79739c00 authored by Andrey Filippov's avatar Andrey Filippov

implemented and tested 2-d lapped dct back and forth

parent a41acf59
...@@ -39,6 +39,12 @@ public class DttRad2 { ...@@ -39,6 +39,12 @@ public class DttRad2 {
double sqrt2 = Math.sqrt(2.0); double sqrt2 = Math.sqrt(2.0);
double sqrt1_2 = 1/sqrt2; double sqrt1_2 = 1/sqrt2;
double [] hwindow = null; // half window double [] hwindow = null; // half window
int [][] fold_index = null; // index of the source item in 2nx2n array input to mdct_2d.
// First index (0..n^2-1) index in the folded array (dct-iV input)
// Second index(0..3) - item to add (2 vertiacl, 2 - horizontal)
double [][] fold_k = null; // Matching fold_index items. Each is a product of 2 window coefficients and sign
int [] unfold_index = null; // index for each element of idct(2nx2n)
double [] unfold_k = null; // Matching unfold_index items. Each is a product of 2 window coefficients and sign
public DttRad2 (int maxN){ // n - maximal public DttRad2 (int maxN){ // n - maximal
setup_arrays(maxN); // always setup arrays for fast calculations setup_arrays(maxN); // always setup arrays for fast calculations
...@@ -74,94 +80,126 @@ public class DttRad2 { ...@@ -74,94 +80,126 @@ public class DttRad2 {
return y; return y;
} }
public double [] mdct_fold (double [] x ) { // x is 2n long
int n = x.length/2;
int n1 = n/2;
int n3 = n+n1;
double [] x1 = new double [n];
for (int i=0; i<n1; i++){
x1[i]= -hwindow[n1 + i]* x[n3 -1 -i] - hwindow[n1 - i -1] * x[n3 + i];
x1[i+n1]= hwindow[ i]* x[ i] - hwindow[n - i -1] * x[n - 1 - i];
}
return x1;
}
public double [] mdct_unfold (double [] x) { // x is 2n long // For index in dct-iv input (0..n-1) get 2 variants of index in mdct input array (0..2*n-1)
int n = x.length; // second index : 0 - index in X array 2*n long
int n1 = n/2; // 1 - window index (0..n-1), [0] - minimal, [n-1] - max
int n3 = n+n1; // 2 - sign of the term
double [] x1 = new double [2*n]; private int [][] get_fold_indices(int x, int n){
for (int i=0; i<n1; i++){ int n1 = n>>1;
x1[i]= x[n1+i]; int [][] ind = new int[2][3];
x1[n - i - 1] = x1[i]; if (x <n1) {
x1[n3 + i]= -x[i]; ind[0][0] = n + n1 - x - 1; // -cR
x1[n1 - i - 1] =-x1[i]; ind[0][1] = n1 + x;
} ind[0][2] = -1;
return x1; ind[1][0] = n + n1 + x; // -d
ind[1][1] = n1 - x - 1;
ind[1][2] = -1;
} else {
x-=n1;
ind[0][0] = x; // +a
ind[0][1] = x;
ind[0][2] = 1;
ind[1][0] = n - x - 1; // -bR
ind[1][1] = n - x - 1;
ind[1][2] = -1;
}
return ind;
}
// is called when window is set
private void set_fold_2d(int n){ // n - DCT and window size
if ((fold_index != null) && (fold_index.length == n*n)) return;
fold_index = new int[n*n][4];
fold_k = new double[n*n][4];
int [] vert_ind = new int[2];
double [] vert_k = new double[2];
int [] hor_ind = new int[2];
double [] hor_k = new double[2];
int [][] fi;
int n2 = 2*n;
for (int i = 0; i < n; i++ ){
fi = get_fold_indices(i,n);
vert_ind[0] = fi[0][0];
vert_ind[1] = fi[1][0];
vert_k[0] = fi[0][2] * hwindow[fi[0][1]];
vert_k[1] = fi[1][2] * hwindow[fi[1][1]];
for (int j = 0; j < n; j++ ){
fi = get_fold_indices(j,n);
hor_ind[0] = fi[0][0];
hor_ind[1] = fi[1][0];
hor_k[0] = fi[0][2] * hwindow[fi[0][1]];
hor_k[1] = fi[1][2] * hwindow[fi[1][1]];
int indx = n*i + j;
for (int k = 0; k<4;k++) {
fold_index[indx][k] = n2 * vert_ind[(k>>1) & 1] + hor_ind[k & 1];
fold_k[indx][k] = vert_k[(k>>1) & 1] * hor_k[k & 1];
}
}
}
if (n < 16) {
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",
fi[0][0],fi[0][1],fi[0][2],
fi[1][0],fi[1][1],fi[1][2], hwindow[fi[0][1]], hwindow[fi[1][1]]));
}
}
}
// return index+1 and sign for 1-d imdct. x is index (0..2*n-1) of the imdct array, value is sign * (idct_index+1),
// where idct_index (0..n-1) is index in the dct-iv array
private int get_unfold_index(int x, int n){
int n1 = n>>1;
int segm = x / n1;
x = x % n1;
switch (segm){
case 0: return 1+ (x + n1);
case 1: return -(n - x);
case 2: return -(n1 - x);
case 3: return -(1 + x);
}
return 0; //should never happen
}
private void set_unfold_2d(int n){ // n - DCT size
if ((unfold_index != null) && (unfold_index.length == 4*n*n)) return;
unfold_index = new int[4*n*n];
unfold_k = new double[4*n*n];
int n2 = 2*n;
for (int i = 0; i < 2*n; i++ ){
int index_vert = get_unfold_index(i,n);
double k_vert = hwindow[(i < n)?i:n2 -i -1];
if (index_vert <0 ){
k_vert = -k_vert;
index_vert = -index_vert;
} }
index_vert --;
index_vert *= n;
for (int j = 0; j < 2*n; j++ ){
int index_hor = get_unfold_index(j,n);
public double [] mdct_2d(double [] x){ double k_hor = hwindow[(j < n)?j:n2 -j -1];
return mdct_2d(x, 0, 1 << (ilog2(x.length/4)/2)); if (index_hor <0 ){
k_hor = -k_hor;
index_hor = -index_hor;
} }
index_hor --; // pass 1 to next
// unfold_index1[n2*i+j]=sgn_vert*sgn_hor*(index_vert+index_hor); // should never be 0
unfold_index[n2*i+j]=(index_vert+index_hor);
unfold_k[n2*i+j]=k_vert*k_hor;
public double [] mdct_2d(double [] x, int mode){ if (n < 16) System.out.print(String.format("%4d", unfold_index[n2*i+j]));
return mdct_2d(x, mode, 1 << (ilog2(x.length/4)/2));
}
public double [] mdct_2d (double [] x, int mode, int n) { // x is 2n*2n long
// int n = 1 << (ilog2(x.length/4)/2);
int n2 = 2*n;
double [] transp = new double [2*n*n];
double [] y = new double [n*n];
double [] line2 = new double[n*2];
double [] line = new double[n*2];
// first (horizontal) pass
for (int i = 0; i < n2; i++){
System.arraycopy(x, n2*i, line2, 0, n2);
line = mdct_fold(line2);
line = ((mode & 1)!=0)? dst_iv(line):dct_iv(line);
for (int j=0; j < n;j++) transp[j*n2+i] =line[j]; // transpose
} }
// second (vertical) pass if (n < 16) System.out.println();
for (int i = 0; i < n2; i++){
System.arraycopy(transp, n2*i, line2, 0, n2);
line = mdct_fold(line2);
line = ((mode & 2)!=0)? dst_iv(line):dct_iv(line);
System.arraycopy(line, 0, y, n*i, n);
}
return y;
} }
if (n < 16) {
public double [] imdct_2d(double [] x){ for (int i = 0; i < 2*n; i++ ){
return imdct_2d(x, 1 << (ilog2(x.length)/2)); System.out.println(i+"->"+get_unfold_index(i,n));
}
public double [] imdct_2d (double [] x, int n) { // x is n*n long
int n2 = 2*n;
double [] transp = new double [2*n*n];
double [] y = new double [4*n*n];
double [] line2 = new double[n*2];
double [] line = new double[n*2];
// first (horizontal) pass
for (int i = 0; i < n2; i++){
System.arraycopy(x, n*i, line, 0, n);
line = dct_iv(line);
line2 = mdct_unfold(line);
for (int j=0; j < n2;j++) transp[j*n+i] =line2[j]; // transpose
} }
// second (vertical) pass
for (int i = 0; i < n2; i++){
System.arraycopy(transp, n*i, line, 0, n);
line = dct_iv(line);
line2 = mdct_unfold(line);
System.arraycopy(line2, 0, y, n2*i, n2);
} }
return y;
} }
public double [] dttt_iv(double [] x){ public double [] dttt_iv(double [] x){
return dttt_iv(x, 0, 1 << (ilog2(x.length)/2)); return dttt_iv(x, 0, 1 << (ilog2(x.length)/2));
} }
...@@ -196,8 +234,10 @@ public class DttRad2 { ...@@ -196,8 +234,10 @@ public class DttRad2 {
public void set_window(int mode, int len){ public void set_window(int mode, int len){
hwindow = new double[len]; hwindow = new double[len];
double f = Math.PI/(2.0*len); double f = Math.PI/(2.0*len);
double sqrt1_2=Math.sqrt(0.5);
if (mode ==0){ 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)); for (int i = 0; i < len; i++ ) hwindow[i] = Math.sin(f*(i+0.5));
} else { // add more types? } else { // add more types?
double s; double s;
...@@ -206,55 +246,34 @@ public class DttRad2 { ...@@ -206,55 +246,34 @@ public class DttRad2 {
hwindow[i] = Math.sin(Math.PI*s*s); hwindow[i] = Math.sin(Math.PI*s*s);
} }
} }
set_fold_2d(len);
set_unfold_2d(len);
} }
// Convert 2nx2n overlapping tile to n*n for dct-iv // Convert 2nx2n overlapping tile to n*n for dct-iv
public double [] fold_tile(double [] x) { // x should be 2n*2n public double [] fold_tile(double [] x) { // x should be 2n*2n
return fold_tile(x, 1 << (ilog2(x.length/4)/2)); return fold_tile(x, 1 << (ilog2(x.length/4)/2));
} }
public double [] fold_tile(double [] x, int n) { // x should be 2n*2n public double [] fold_tile(double [] x, int n) { // x should be 2n*2n
double [] y = new double [n*n]; double [] y = new double [n*n];
for (int i = 0; i<y.length;i++) y[i] = 0; for (int i = 0; i<y.length;i++) {
int n1 = n/2; y[i] = 0;
int n2 = 2*n; for (int k = 0; k < 4; k++){
for (int tile_y_v=0; tile_y_v<2; tile_y_v++){ // 2 rows of y tiles y[i] += x[fold_index[i][k]] * fold_k[i][k];
for (int tile_y_h=0; tile_y_h<2; tile_y_h++){ // 2 columns of y tiles
int start_y_addr = n*n1*tile_y_v + n1*tile_y_h; //atart address in the aoutput array
int start_x_tl_addr = (2*n*n) * (1 - tile_y_v) + n * (1 - tile_y_h); // address of the top left corner of a group of 4 tiles
for (int tile_x_v=0; tile_x_v<2; tile_x_v++){ // 2 rows of x tiles (contributing to the same y tile)
for (int tile_x_h=0; tile_x_h<2; tile_x_h++){ // 2 columns of x tiles (contributing to the same y tile)
int dir_x = ((tile_y_h ^ tile_x_h) !=0)? 1 : -1;
int dir_y = ((tile_y_v ^ tile_x_v) !=0)? 1 : -1;
int start_x_addr = start_x_tl_addr +
tile_x_v * n *n + // 2n * n/2
tile_x_h * n1 +
((dir_y < 0)?(n1-1)*2*n : 0)+
((dir_x < 0)?(n1-1) : 0);
int dir_window_vert = (tile_x_v > 0)? -1 : +1; // same for any tile_y_*
int dir_window_hor = (tile_x_h > 0)? -1 : +1;
int start_window_vert = (tile_y_v > 0)? ((tile_x_v > 0)? n-1: 0 ):((tile_x_v > 0)? n1-1: n1);
int start_window_hor = (tile_y_h > 0)? ((tile_x_h > 0)? n-1: 0 ):((tile_x_h > 0)? n1-1: n1);
for (int i = 0; i < n1; i++){ // n1 rows in each y tile
for (int j = 0; j < n1; j++){ // n1 columns in each y tile
y[start_y_addr+ n*i+j] += hwindow[start_window_vert + dir_window_vert * i] *
hwindow[start_window_hor + dir_window_hor * j] *
x[start_x_addr + n2 * dir_y * i + dir_x * j];
}
}
}
}
} }
} }
return y; return y;
} }
public double [] unfold_tile(double [] x) { // x should be n*n public double [] unfold_tile(double [] x) { // x should be n*n
return fold_tile(x, 1 << (ilog2(x.length)/2)); return unfold_tile(x, 1 << (ilog2(x.length)/2));
} }
public double [] unfold_tile(double [] x, int n) { // x should be 2n*2n public double [] unfold_tile(double [] x, int n) { // x should be 2n*2n
double [] y = new double [4*n*n]; double [] y = new double [4*n*n];
for (int i = 0; i<y.length;i++) {
y[i] = unfold_k[i]* x[unfold_index[i]];
}
return y; return y;
} }
...@@ -398,18 +417,8 @@ public class DttRad2 { ...@@ -398,18 +417,8 @@ public class DttRad2 {
private double [] _dctii_recurs(double[] x){ private double [] _dctii_recurs(double[] x){
int n = x.length; int n = x.length;
System.out.println("_dctii_recurs: n="+n);
if (n ==2) { if (n ==2) {
double [] y= {x[0]+x[1],x[0]-x[1]}; double [] y= {x[0]+x[1],x[0]-x[1]};
System.out.println("_dctii_recurs(2): ");
for (int j = 0; j< n; j++){
System.out.print("--x["+j+"]="+x[j]+" ");
}
System.out.println();
for (int j = 0; j< n; j++){
System.out.print("--y["+j+"]="+y[j]+" ");
}
System.out.println();
return y; return y;
} }
int n1 = n >> 1; int n1 = n >> 1;
...@@ -420,29 +429,13 @@ public class DttRad2 { ...@@ -420,29 +429,13 @@ public class DttRad2 {
u0[j]= (x[j] + x[n-j-1]); u0[j]= (x[j] + x[n-j-1]);
u1[j]= (x[j] - x[n-j-1]); u1[j]= (x[j] - x[n-j-1]);
} }
for (int j = 0; j< n1; j++){
System.out.println("u0["+j+"]="+u0[j]+", u1["+j+"]="+u1[j]);
}
double [] v0 = _dctii_recurs(u0); double [] v0 = _dctii_recurs(u0);
double [] v1 = _dctiv_recurs(u1); double [] v1 = _dctiv_recurs(u1);
for (int j = 0; j< n1; j++){
System.out.println("_dctii_recurs(): v0["+j+"]="+v0[j]+", v1["+j+"]="+v1[j]);
}
double [] y = new double[n]; double [] y = new double[n];
for (int j = 0; j< n1; j++){ for (int j = 0; j< n1; j++){
y[2*j] = v0[j]; y[2*j] = v0[j];
y[2*j+1] = v1[j]; y[2*j+1] = v1[j];
} }
for (int j = 0; j< n; j++){
System.out.println("_dctii_recurs(): y["+j+"]="+y[j]);
}
return y; return y;
} }
...@@ -486,4 +479,6 @@ public class DttRad2 { ...@@ -486,4 +479,6 @@ public class DttRad2 {
} }
return y; return y;
} }
} }
...@@ -1647,6 +1647,37 @@ public class EyesisCorrectionParameters { ...@@ -1647,6 +1647,37 @@ public class EyesisCorrectionParameters {
this.addBottom=Integer.parseInt(properties.getProperty(prefix+"addBottom")); this.addBottom=Integer.parseInt(properties.getProperty(prefix+"addBottom"));
} }
} }
public static class DCTParameters {
public int dct_size = 32;
public int dct_window = 0; // currently only 2 types of window - 0 and 1
public DCTParameters(int dct_size, int dct_window) {
this.dct_size = dct_size;
this.dct_window = dct_window;
}
public void setProperties(String prefix,Properties properties){
properties.setProperty(prefix+"dct_size",this.dct_size+"");
properties.setProperty(prefix+"dct_window", this.dct_window+"");
}
public void getProperties(String prefix,Properties properties){
this.dct_size=Integer.parseInt(properties.getProperty(prefix+"dct_size"));
this.dct_window=Integer.parseInt(properties.getProperty(prefix+"dct_window"));
}
public boolean showDialog() {
GenericDialog gd = new GenericDialog("Set DCT parameters");
gd.addNumericField("DCT size", this.dct_size, 0); //2
gd.addNumericField("MDCT window type (0,1,2)", this.dct_window, 0); //32
// gd.addNumericField("Debug Level:", MASTER_DEBUG_LEVEL, 0);
gd.showDialog();
if (gd.wasCanceled()) return false;
this.dct_size= (int) gd.getNextNumber();
this.dct_window= (int) gd.getNextNumber();
// MASTER_DEBUG_LEVEL= (int) gd.getNextNumber();
return true;
}
}
/* ======================================================================== */ /* ======================================================================== */
public static class DebayerParameters { public static class DebayerParameters {
public int size; public int size;
......
...@@ -83,6 +83,13 @@ private Panel panel1,panel2,panel3,panel4,panel5,panel5a, panel6,panel7,panelPos ...@@ -83,6 +83,13 @@ private Panel panel1,panel2,panel3,panel4,panel5,panel5a, panel6,panel7,panelPos
32, // addRight 32, // addRight
32 // addBottom 32 // addBottom
); );
public static EyesisCorrectionParameters.DCTParameters DCT_PARAMETERS = new EyesisCorrectionParameters.DCTParameters(
32, // dct_size
1 // dct_window
);
public static EyesisCorrectionParameters.DebayerParameters DEBAYER_PARAMETERS = new EyesisCorrectionParameters.DebayerParameters( public static EyesisCorrectionParameters.DebayerParameters DEBAYER_PARAMETERS = new EyesisCorrectionParameters.DebayerParameters(
64, // size //128; 64, // size //128;
0.5, // polarStep - size of largest polar cell to Cartesian one; 0.5, // polarStep - size of largest polar cell to Cartesian one;
...@@ -438,6 +445,8 @@ private Panel panel1,panel2,panel3,panel4,panel5,panel5a, panel6,panel7,panelPos ...@@ -438,6 +445,8 @@ private Panel panel1,panel2,panel3,panel4,panel5,panel5a, panel6,panel7,panelPos
panelDct1.setLayout(new GridLayout(1, 0, 5, 5)); // rows, columns, vgap, hgap panelDct1.setLayout(new GridLayout(1, 0, 5, 5)); // rows, columns, vgap, hgap
addButton("DCT test 1",panelDct1,color_process); addButton("DCT test 1",panelDct1,color_process);
addButton("DCT test 2",panelDct1,color_process); addButton("DCT test 2",panelDct1,color_process);
addButton("DCT test 3",panelDct1,color_process);
addButton("DCT test 4",panelDct1,color_process);
add(panelDct1); add(panelDct1);
} }
pack(); pack();
...@@ -2550,34 +2559,163 @@ private Panel panel1,panel2,panel3,panel4,panel5,panel5a, panel6,panel7,panelPos ...@@ -2550,34 +2559,163 @@ private Panel panel1,panel2,panel3,panel4,panel5,panel5a, panel6,panel7,panelPos
} else if (label.equals("DCT test 2")) { } else if (label.equals("DCT test 2")) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL; DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
// IJ.showMessage("DCT test 1"); // IJ.showMessage("DCT test 1");
float[] x = {0.1f, 0.25f, 0.35f, 0.5f, 0.61f,0.7f,0.85f,0.89f,0.95f}; // x-coordinates if (!DCT_PARAMETERS.showDialog()) return;
float[] y = {2f,5.6f,7.4f,9f,9.4f,8.7f,6.3f,4.5f,1f}; // x-coordinates // process selected image stack
float[] e = {.8f,.6f,.5f,.4f,.3f,.5f,.6f,.7f,.8f}; // error bars 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
PlotWindow.noGridLines = false; // draw grid lines EyesisCorrectionParameters.SplitParameters split_parameters = new EyesisCorrectionParameters.SplitParameters(
Plot plot = new Plot("Example Plot","X Axis","Y Axis",x,y); 1, // oversample;
plot.setLimits(0, 1, 0, 10); // Add just for mdct (N/2)
plot.setLineWidth(2); DCT_PARAMETERS.dct_size/2, // addLeft
plot.addErrorBars(e); DCT_PARAMETERS.dct_size/2, // addTop
DCT_PARAMETERS.dct_size/2, // addRight
// add a second curve DCT_PARAMETERS.dct_size/2 // addBottom
float x2[] = {.4f,.5f,.6f,.7f,.8f}; );
float y2[] = {4,3,3,4,5};
plot.setColor(Color.red);
plot.addPoints(x2,y2,PlotWindow.X);
plot.addPoints(x2,y2,PlotWindow.LINE);
// add label
plot.setColor(Color.black);
plot.changeFont(new Font("Helvetica", Font.PLAIN, 24));
plot.addLabel(0.15, 0.95, "This is a label");
plot.changeFont(new Font("Helvetica", Font.PLAIN, 16)); ImageStack sourceStack= bayerToStack(imp_src, // source Bayer image, linearized, 32-bit (float))
plot.setColor(Color.blue); split_parameters);
plot.show(); imp2 = new ImagePlus(imp_src.getTitle()+"-SPIT", sourceStack);
imp2.getProcessor().resetMinAndMax();
imp2.show();
} else {
imp2 = imp_src;
}
ImageDtt image_dtt = new ImageDtt();
double [][] dct_data = image_dtt.mdctStack(imp2.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;
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");
double [][] idct_data = new double [dct_data.length][];
for (int chn=0; chn<idct_data.length;chn++){
idct_data[chn] = image_dtt.lapped_idct(
dct_data[chn], // scanline representation of dcd data, organized as dct_size x dct_size tiles
tilesX*DCT_PARAMETERS.dct_size, // dct_width,
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,
imp_src.getTitle()+"-IDCT");
return; return;
/* ======================================================================== */ /* ======================================================================== */
} else if (label.equals("DCT test 3")) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
int n = 32;
int n2 = 2*n;
int window_type = 1; // 0;
int tilesY = 4;
int tilesX = 4;
int iw = (tilesX+1) * n;
int ih = (tilesY+1) * n;
DttRad2 dtt4 = new DttRad2(4);
dtt4.set_window(window_type);
DttRad2 dtt8 = new DttRad2(8);
dtt8.set_window(window_type);
DttRad2 dtt = new DttRad2(n);
dtt.set_window(window_type);
double [] x = new double[n*n];
for (int ii=0;ii<x.length;ii++) x[ii] = 0;
// x[5*n + 11] = 1.0; // shifted delta;
// x[17*n + 15] = 1.0; // shifted delta;
// x[10*n + 8] = 1.0; // shifted delta;
for (int ii=0;ii<n;ii++){
for (int jj=0;jj<n;jj++){
x[ii*n+jj] = Math.cos(2*Math.PI/(n*Math.sqrt(n))*(ii*ii+jj*jj));
}
}
SDFA_INSTANCE.showArrays(x, n, n, "x "+n+"x"+n);
double [] y = dtt.dttt_iv(x, 0, n);
SDFA_INSTANCE.showArrays(y, n, n, "y "+n+"x"+n);
double [] xr = dtt.dttt_iv(y, 0, n);
SDFA_INSTANCE.showArrays(xr, n, n, "xr "+n+"x"+n);
double [] mx = new double[iw*ih];
double [][] mxt = new double[tilesY*tilesX][];
double [][] mxtf = new double[tilesY*tilesX][]; // folded
double [][] mxtfu = new double[tilesY*tilesX][]; // folded/unfolded
double [][] my = new double[tilesY*tilesX][];
double [][] myt = new double[tilesY*tilesX][];
double [][] imyt = new double[tilesY*tilesX][];
double [] imy = new double[iw*ih];
for (int ii=0;ii<mx.length;ii++) mx[ii] = 0;
for (int ii=0;ii<imy.length;ii++) imy[ii] = 0;
for (int iy=0;iy<n;iy++) for (int ix=0;ix<n;ix++) mx[iw*(iy + n)+ (ix + n)] = x[n*iy+ix];
for (int iy=0;iy<n;iy++) for (int ix=0;ix<n;ix++) mx[iw*(iy + 2*n)+ (ix + n)] = x[n*(n-1-iy)+ix];
for (int iy=0;iy<n;iy++) for (int ix=0;ix<n;ix++) mx[iw*(iy + 3*n)+ (ix + n)] = x[n*iy+ (n -1 -ix)];
for (int iy=0;iy<n;iy++) for (int ix=0;ix<n;ix++) mx[iw*(iy + n)+ (ix + 2*n)] = x[n*(n-1-iy)+(n -1 -ix)];
for (int iy=0;iy<n;iy++) for (int ix=0;ix<n;ix++) mx[iw*(iy + 2*n)+ (ix + 2*n)] = x[n*iy+ix];
for (int iy=0;iy<n;iy++) for (int ix=0;ix<n;ix++) mx[iw*(iy + 3*n)+ (ix + 2*n)] = x[n*(n-1-iy)+ix];
for (int iy=0;iy<n;iy++) for (int ix=0;ix<n;ix++) mx[iw*(iy + n)+ (ix + 3*n)] = x[n*iy+ (n -1 -ix)];
for (int iy=0;iy<n;iy++) for (int ix=0;ix<n;ix++) mx[iw*(iy + 2*n)+ (ix + 3*n)] = x[n*(n-1-iy)+(n -1 -ix)];
for (int iy=0;iy<n;iy++) for (int ix=0;ix<n;ix++) mx[iw*(iy + 3*n)+ (ix + 3*n)] = x[n*iy+ix];
for (int ii = 0; ii<mx.length; ii++){
// if ((((ii % iw) ^ (ii / iw)) & 1) !=0) mx[ii] = 0;
}
SDFA_INSTANCE.showArrays(mx, iw, ih, "mx "+iw+"x"+ih);
for (int tileY = 0; tileY < tilesY; tileY++){
for (int tileX = 0; tileX < tilesX; tileX++){
double [] tile = new double [4*n*n];
int tileN = tileY*tilesX+tileX;
for (int iy=0;iy<n2;iy++){
for (int ix=0;ix<n2;ix++){
tile[n2*iy + ix] = mx[iw*(iy + n * tileY)+ (ix+ n*tileX)];
}
}
mxt[tileN] = tile.clone();
mxtf[tileN] = dtt.fold_tile (tile, n);
mxtfu[tileN] = dtt.unfold_tile (mxtf[tileN], n);
my [tileN] = dtt.dttt_iv (mxtf[tileN], 0, n);
myt[tileN] = dtt.dttt_iv (my [tileN], 0, n);
imyt[tileN] = dtt.unfold_tile (myt [tileN], n); // each tile - imdct
for (int iy=0;iy<n2;iy++){
for (int ix=0;ix<n2;ix++){
imy[iw*(iy + n * tileY)+ (ix+ n*tileX)] += imyt[tileN][n2*iy + ix] ;
// imy[iw*(iy + n * tileY)+ (ix+ n*tileX)] += mxtfu[tileN][n2*iy + ix] ;
}
}
}
}
SDFA_INSTANCE.showArrays(mxt, n2, n2, true, "mxt "+n2+"x"+n2);
SDFA_INSTANCE.showArrays(mxtf, n, n, true, "mxtf "+n+"x"+n);
SDFA_INSTANCE.showArrays(mxtfu,n2, n2, true, "mxtfu "+n2+"x"+n2);
SDFA_INSTANCE.showArrays(my, n, n, true, "my "+n+"x"+n);
SDFA_INSTANCE.showArrays(myt, n, n, true, "myt "+n+"x"+n);
SDFA_INSTANCE.showArrays(imyt, n2, n2, true, "imyt "+n2+"x"+n2);
SDFA_INSTANCE.showArrays(imy, iw, ih, "imy "+iw+"x"+ih);
return;
} }
DEBUG_LEVEL=MASTER_DEBUG_LEVEL; DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
} }
...@@ -2599,6 +2737,7 @@ private Panel panel1,panel2,panel3,panel4,panel5,panel5a, panel6,panel7,panelPos ...@@ -2599,6 +2737,7 @@ private Panel panel1,panel2,panel3,panel4,panel5,panel5a, panel6,panel7,panelPos
return false; return false;
} }
/* ======================================================================== */ /* ======================================================================== */
public String [] selectSourceFiles(String [] defaultPaths) { public String [] selectSourceFiles(String [] defaultPaths) {
String []patterns={".jp4",".jp46",".tiff",".tif"}; String []patterns={".jp4",".jp46",".tiff",".tif"};
return selectFiles(false, // save return selectFiles(false, // save
...@@ -5770,7 +5909,7 @@ G= Y +Pr*(- 2*Kr*(1-Kr))/Kg + Pb*(-2*Kb*(1-Kb))/Kg ...@@ -5770,7 +5909,7 @@ G= Y +Pr*(- 2*Kr*(1-Kr))/Kg + Pb*(-2*Kb*(1-Kb))/Kg
*/ */
public static void main(String[] args) { public static void main(String[] args) {
// set the plugins.dir property to make the plugin appear in the Plugins menu // set the plugins.dir property to make the plugin appear in the Plugins menu
Class<?> clazz = Aberration_Calibration.class; Class<?> clazz = Eyesis_Correction.class;
String url = clazz.getResource("/" + clazz.getName().replace('.', '/') + ".class").toString(); String url = clazz.getResource("/" + clazz.getName().replace('.', '/') + ".class").toString();
String pluginsDir = url.substring(5, url.length() - clazz.getName().length() - 6); String pluginsDir = url.substring(5, url.length() - clazz.getName().length() - 6);
System.setProperty("plugins.dir", pluginsDir); System.setProperty("plugins.dir", pluginsDir);
......
import java.util.concurrent.atomic.AtomicInteger;
import ij.ImageStack;
/**
**
** ImageDtt - Process images with DTT-based methods
**
** Copyright (C) 2016 Elphel, Inc.
**
** -----------------------------------------------------------------------------**
**
** ImageDtt.java is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
** -----------------------------------------------------------------------------**
**
*/
public class ImageDtt {
public ImageDtt(){
}
public double [][] mdctStack(
final ImageStack imageStack,
final EyesisCorrectionParameters.DCTParameters dctParameters, //
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 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++) {
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
dct_data[chn] =lapped_dct(
dpixels,
imgWidth,
dctParameters.dct_size,
0, // dct_mode, // 0: dct/dct, 1: dct/dst, 2: dst/dct, 3: dst/dst
dctParameters.dct_window, // final int window_type,
threadsMax, // maximal number of threads to launch
debugLevel);
}
return dct_data;
}
public double [] lapped_dct(
final double [] dpixels,
final int width,
final int dct_size,
final int dct_mode, // 0: dct/dct, 1: dct/dst, 2: dst/dct, 3: dst/dst
final int window_type,
final int threadsMax, // maximal number of threads to launch
final int globalDebugLevel)
{
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 [] dct_data = new double[tilesY*tilesX*dct_size*dct_size];
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() {
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;
for (int nTile = ai.getAndIncrement(); nTile < nTiles; nTile = ai.getAndIncrement()) {
tileY = nTile/tilesX;
tileX = nTile - tileY * tilesX;
for (int i = 0; i < n2;i++){
System.arraycopy(dpixels, (tileY*width+tileX)*dct_size + i*width, tile_in, i*n2, n2);
}
// tile_out=dtt.mdct_2d(tile_in, dct_mode, dct_size);
tile_folded=dtt.fold_tile(tile_in, dct_size);
tile_out=dtt.dttt_iv (tile_folded, dct_mode, dct_size);
for (int i = 0; i < dct_size;i++){
System.arraycopy(tile_out, dct_size* i, dct_data, ((tileY*dct_size + i) *tilesX + tileX)*dct_size , dct_size);
}
}
}
};
}
startAndJoin(threads);
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,
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 width= (tilesX+1)*dct_size;
final int height= (tilesY+1)*dct_size;
System.out.println("lapped_idct():dct_width="+dct_width);
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);
double debug0 = 0.0;
for (int i=0;i<dct_data.length;i++){
debug0 +=dct_data[i]*dct_data[i];
}
debug0 = Math.sqrt(debug0)/dct_data.length;
System.out.println("lapped_idct():debug0= "+debug0+" (dct_data.length= "+dct_data.length+")");
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];
for (int i = 0; i < dct_size;i++){
System.arraycopy(dct_data, (tileY*dct_width+tileX)*dct_size + i*dct_width, tile_in, dct_size*i, dct_size);
}
tile_dct=dtt.dttt_iv (tile_in, 0, dct_size);
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:
* http://repo.or.cz/w/trakem2.git?a=blob;f=mpi/fruitfly/general/MultiThreading.java;hb=HEAD
*/
private Thread[] newThreadArray(int maxCPUs) {
int n_cpus = Runtime.getRuntime().availableProcessors();
if (n_cpus>maxCPUs)n_cpus=maxCPUs;
return new Thread[n_cpus];
}
/* Start all given threads and wait on each of them until all are done.
* From Stephan Preibisch's Multithreading.java class. See:
* http://repo.or.cz/w/trakem2.git?a=blob;f=mpi/fruitfly/general/MultiThreading.java;hb=HEAD
*/
public static void startAndJoin(Thread[] threads)
{
for (int ithread = 0; ithread < threads.length; ++ithread)
{
threads[ithread].setPriority(Thread.NORM_PRIORITY);
threads[ithread].start();
}
try
{
for (int ithread = 0; ithread < threads.length; ++ithread)
threads[ithread].join();
} catch (InterruptedException ie)
{
throw new RuntimeException(ie);
}
}
}
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