Commit 7e93745b authored by Andrey Filippov's avatar Andrey Filippov

more tests with dct-based processing

parent a1e7da7b
......@@ -148,8 +148,59 @@ public class DttRad2 {
fi[1][0],fi[1][1],fi[1][2], hwindow[fi[0][1]], hwindow[fi[1][1]]));
}
}
}
public double [][] get_fold_2d(
double scale_hor,
double scale_vert)
{
return get_fold_2d( this.N, scale_hor, scale_vert);
}
public double [][] get_fold_2d(
int n,
double scale_hor,
double scale_vert
){ // n - DCT and window size
// if ((fold_index != null) && (fold_index.length == n*n)) return;
// fold_index = new int[n*n][4];
double [] hwindow_h = new double[n];
double [] hwindow_v = new double[n];
double f = Math.PI/(2.0*n);
for (int i = 0; i < n; i++ ) {
double ah = f*scale_hor * (n-i-0.5);
double av = f*scale_vert * (n-i-0.5);
hwindow_h[i] = (ah > (Math.PI/2))? 0.0: Math.cos(ah);
hwindow_v[i] = (av > (Math.PI/2))? 0.0: Math.cos(av);
}
double [][] fold_sk = 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;
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_v[fi[0][1]];
vert_k[1] = fi[1][2] * hwindow_v[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_h[fi[0][1]];
hor_k[1] = fi[1][2] * hwindow_h[fi[1][1]];
int indx = n*i + j;
for (int k = 0; k<4;k++) {
fold_sk[indx][k] = vert_k[(k>>1) & 1] * hor_k[k & 1];
}
}
}
return fold_sk;
}
// 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){
......@@ -351,6 +402,22 @@ public class DttRad2 {
return fold_tile(x, 1 << (ilog2(x.length/4)/2));
}
public double [] fold_tile(double [] x, int n) { // x should be 2n*2n
return fold_tile(x,n,this.fold_k);
// double [] y = new double [n*n];
// for (int i = 0; i<y.length;i++) {
// y[i] = 0;
// for (int k = 0; k < 4; k++){
// y[i] += x[fold_index[i][k]] * fold_k[i][k];
// }
// }
// return y;
}
public double [] fold_tile(
double [] x,
int n,
double [][] fold_k
) { // x should be 2n*2n
double [] y = new double [n*n];
for (int i = 0; i<y.length;i++) {
y[i] = 0;
......@@ -360,7 +427,8 @@ public class DttRad2 {
}
return y;
}
public double [] unfold_tile(double [] x) { // x should be n*n
return unfold_tile(x, 1 << (ilog2(x.length)/2));
......
......@@ -1785,6 +1785,9 @@ public class EyesisCorrectionParameters {
public double dbg_x1 = -1.3;
public double dbg_y1 = 2.0;
public double dbg_sigma = 0.8;
public double dbg_src_size = 8.0; // trying to slightly scale in dct space. == dct = 1:1, dct+1.0 - shrink dct(dct+1.0)
public double dbg_scale = 1.0; // Should ==DCT_PARAMETERS.dct_size / DCT_PARAMETERS.dbg_src_size
public double dbg_fold_scale = 1.0; // Modifies window during MDCT->DCT-IV folding
public String dbg_mask = ".........:::::::::.........:::::::::......*..:::::*:::.........:::::::::.........";
public int dbg_mode = 1; // 0 - old LMA, 1 - new LMA - *** not used anymore ***
public int dbg_window_mode = 1; // 0 - none, 1 - square, 2 - sin 3 - sin^2 Now _should_ be square !!!
......@@ -1814,6 +1817,7 @@ public class EyesisCorrectionParameters {
public double vignetting_max = 0.4; // value in vignetting data to correspond to 1x in the kernel
public double vignetting_range = 5.0; // do not try to correct vignetting less than vignetting_max/vignetting_range
public boolean post_debayer = false; // perform de-bayer after aberrations in pixel domain
public boolean color_DCT = true; // false - use old color processing mode
public double sigma_rb = 0.9; // additional (to G) blur for R and B
public double sigma_y = 0.7; // blur for G contribution to Y
......@@ -1871,6 +1875,9 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"dbg_x1", this.dbg_x1+"");
properties.setProperty(prefix+"dbg_y1", this.dbg_y1+"");
properties.setProperty(prefix+"dbg_sigma", this.dbg_sigma+"");
properties.setProperty(prefix+"dbg_src_size",this.dbg_src_size+"");
properties.setProperty(prefix+"dbg_scale", this.dbg_scale+"");
properties.setProperty(prefix+"dbg_fold_scale", this.dbg_fold_scale+"");
properties.setProperty(prefix+"dbg_mask", this.dbg_mask+"");
properties.setProperty(prefix+"dbg_mode", this.dbg_mode+"");
properties.setProperty(prefix+"dbg_window_mode", this.dbg_window_mode+"");
......@@ -1886,32 +1893,26 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"antiwindow", this.antiwindow+"");
properties.setProperty(prefix+"skip_sym", this.skip_sym+"");
properties.setProperty(prefix+"convolve_direct", this.convolve_direct+"");
properties.setProperty(prefix+"novignetting_r", this.novignetting_r+"");
properties.setProperty(prefix+"novignetting_g", this.novignetting_g+"");
properties.setProperty(prefix+"novignetting_b", this.novignetting_b+"");
properties.setProperty(prefix+"scale_r", this.scale_r+"");
properties.setProperty(prefix+"scale_g", this.scale_g+"");
properties.setProperty(prefix+"scale_b", this.scale_b+"");
properties.setProperty(prefix+"vignetting_max", this.vignetting_max+"");
properties.setProperty(prefix+"vignetting_range", this.vignetting_range+"");
properties.setProperty(prefix+"post_debayer", this.post_debayer+"");
properties.setProperty(prefix+"color_DCT", this.color_DCT+"");
properties.setProperty(prefix+"sigma_rb", this.sigma_rb+"");
properties.setProperty(prefix+"sigma_y", this.sigma_y+"");
properties.setProperty(prefix+"sigma_color", this.sigma_color+"");
properties.setProperty(prefix+"line_thershold", this.line_thershold+"");
properties.setProperty(prefix+"nonlin", this.nonlin+"");
properties.setProperty(prefix+"nonlin_max_y", this.nonlin_max_y+"");
properties.setProperty(prefix+"nonlin_max_c", this.nonlin_max_c+"");
properties.setProperty(prefix+"nonlin_y", this.nonlin_y+"");
properties.setProperty(prefix+"nonlin_c", this.nonlin_c+"");
properties.setProperty(prefix+"nonlin_corn", this.nonlin_corn+"");
properties.setProperty(prefix+"denoise", this.denoise+"");
properties.setProperty(prefix+"denoise_y", this.denoise_y+"");
properties.setProperty(prefix+"denoise_c", this.denoise_c+"");
......@@ -1940,6 +1941,9 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"dbg_x1")!=null) this.dbg_x1=Double.parseDouble(properties.getProperty(prefix+"dbg_x1"));
if (properties.getProperty(prefix+"dbg_y1")!=null) this.dbg_y1=Double.parseDouble(properties.getProperty(prefix+"dbg_y1"));
if (properties.getProperty(prefix+"dbg_sigma")!=null) this.dbg_sigma=Double.parseDouble(properties.getProperty(prefix+"dbg_sigma"));
if (properties.getProperty(prefix+"dbg_src_size")!=null) this.dbg_src_size=Double.parseDouble(properties.getProperty(prefix+"dbg_src_size"));
if (properties.getProperty(prefix+"dbg_scale")!=null) this.dbg_scale=Double.parseDouble(properties.getProperty(prefix+"dbg_scale"));
if (properties.getProperty(prefix+"dbg_fold_scale")!=null) this.dbg_fold_scale=Double.parseDouble(properties.getProperty(prefix+"dbg_fold_scale"));
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+"centerWindowToTarget")!=null) this.centerWindowToTarget=Boolean.parseBoolean(properties.getProperty(prefix+"centerWindowToTarget"));
......@@ -1955,31 +1959,26 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"antiwindow")!=null) this.antiwindow=Boolean.parseBoolean(properties.getProperty(prefix+"antiwindow"));
if (properties.getProperty(prefix+"skip_sym")!=null) this.skip_sym=Boolean.parseBoolean(properties.getProperty(prefix+"skip_sym"));
if (properties.getProperty(prefix+"convolve_direct")!=null) this.convolve_direct=Boolean.parseBoolean(properties.getProperty(prefix+"convolve_direct"));
if (properties.getProperty(prefix+"novignetting_r")!=null) this.novignetting_r=Double.parseDouble(properties.getProperty(prefix+"novignetting_r"));
if (properties.getProperty(prefix+"novignetting_g")!=null) this.novignetting_g=Double.parseDouble(properties.getProperty(prefix+"novignetting_g"));
if (properties.getProperty(prefix+"novignetting_b")!=null) this.novignetting_b=Double.parseDouble(properties.getProperty(prefix+"novignetting_b"));
if (properties.getProperty(prefix+"scale_r")!=null) this.scale_r=Double.parseDouble(properties.getProperty(prefix+"scale_r"));
if (properties.getProperty(prefix+"scale_g")!=null) this.scale_g=Double.parseDouble(properties.getProperty(prefix+"scale_g"));
if (properties.getProperty(prefix+"scale_b")!=null) this.scale_b=Double.parseDouble(properties.getProperty(prefix+"scale_b"));
if (properties.getProperty(prefix+"vignetting_max")!=null) this.vignetting_max=Double.parseDouble(properties.getProperty(prefix+"vignetting_max"));
if (properties.getProperty(prefix+"vignetting_range")!=null) this.vignetting_range=Double.parseDouble(properties.getProperty(prefix+"vignetting_range"));
if (properties.getProperty(prefix+"post_debayer")!=null) this.post_debayer=Boolean.parseBoolean(properties.getProperty(prefix+"post_debayer"));
if (properties.getProperty(prefix+"color_DCT")!=null) this.color_DCT=Boolean.parseBoolean(properties.getProperty(prefix+"color_DCT"));
if (properties.getProperty(prefix+"sigma_rb")!=null) this.sigma_rb=Double.parseDouble(properties.getProperty(prefix+"sigma_rb"));
if (properties.getProperty(prefix+"sigma_y")!=null) this.sigma_y=Double.parseDouble(properties.getProperty(prefix+"sigma_y"));
if (properties.getProperty(prefix+"sigma_color")!=null) this.sigma_color=Double.parseDouble(properties.getProperty(prefix+"sigma_color"));
if (properties.getProperty(prefix+"line_thershold")!=null) this.line_thershold=Double.parseDouble(properties.getProperty(prefix+"line_thershold"));
if (properties.getProperty(prefix+"nonlin")!=null) this.nonlin=Boolean.parseBoolean(properties.getProperty(prefix+"nonlin"));
if (properties.getProperty(prefix+"nonlin_max_y")!=null) this.nonlin_max_y=Double.parseDouble(properties.getProperty(prefix+"nonlin_max_y"));
if (properties.getProperty(prefix+"nonlin_max_c")!=null) this.nonlin_max_c=Double.parseDouble(properties.getProperty(prefix+"nonlin_max_c"));
if (properties.getProperty(prefix+"nonlin_y")!=null) this.nonlin_y=Double.parseDouble(properties.getProperty(prefix+"nonlin_y"));
if (properties.getProperty(prefix+"nonlin_c")!=null) this.nonlin_c=Double.parseDouble(properties.getProperty(prefix+"nonlin_c"));
if (properties.getProperty(prefix+"nonlin_corn")!=null) this.nonlin_corn=Double.parseDouble(properties.getProperty(prefix+"nonlin_corn"));
if (properties.getProperty(prefix+"denoise")!=null) this.denoise=Boolean.parseBoolean(properties.getProperty(prefix+"denoise"));
if (properties.getProperty(prefix+"denoise_y")!=null) this.denoise_y=Double.parseDouble(properties.getProperty(prefix+"denoise_y"));
if (properties.getProperty(prefix+"denoise_c")!=null) this.denoise_c=Double.parseDouble(properties.getProperty(prefix+"denoise_c"));
......@@ -2007,7 +2006,10 @@ public class EyesisCorrectionParameters {
gd.addNumericField("dbg_x1", this.dbg_x1, 2);
gd.addNumericField("dbg_y1", this.dbg_y1, 2);
gd.addNumericField("dbg_sigma", this.dbg_sigma, 3);
gd.addStringField ("Debug mask (anything but * is false)", this.dbg_mask, 100);
gd.addNumericField("== dct_size = 1:1, dct+1.0 - shrink dct(dct+1.0)", this.dbg_src_size, 3);
gd.addNumericField("Should ==DCT_PARAMETERS.dct_size / DCT_PARAMETERS.dbg_src_size", this.dbg_scale, 3);
gd.addNumericField("Modifies window during MDCT->DCT-IV folding", this.dbg_fold_scale, 3);
gd.addStringField ("Debug mask (anything but * is false)", this.dbg_mask, 100);
gd.addNumericField("LMA implementation: 0 - old, 1 - new", this.dbg_mode, 0);
gd.addNumericField("Convolution window: 0 - none, [1 - square], 2 - sin, 3 - sin^2", this.dbg_window_mode, 0);
gd.addCheckbox ("Center convolution window around target kernel center", this.centerWindowToTarget);
......@@ -2022,17 +2024,15 @@ public class EyesisCorrectionParameters {
gd.addCheckbox ("Divide symmetrical kernel by a window function", this.antiwindow);
gd.addCheckbox ("Do not apply symmetrical (DCT) correction ", this.skip_sym);
gd.addCheckbox ("Convolve directly with symmetrical kernel (debug feature) ", this.convolve_direct);
gd.addNumericField("Reg gain in the center of sensor calibration R (instead of vignetting)",this.novignetting_r, 4);
gd.addNumericField("Green gain in the center of sensor calibration G (instead of vignetting)",this.novignetting_g, 4);
gd.addNumericField("Blue gain in the center of sensor calibration B (instead of vignetting)",this.novignetting_b, 4);
gd.addNumericField("Extra red correction to compensate for light temperature", this.scale_r, 4);
gd.addNumericField("Extra green correction to compensate for light temperature", this.scale_g, 4);
gd.addNumericField("Extra blue correction to compensate for light temperature", this.scale_b, 4);
gd.addNumericField("Value (max) in vignetting data to correspond to 1x in the kernel", this.vignetting_max, 3);
gd.addNumericField("Do not try to correct vignetting smaller than this fraction of max", this.vignetting_range, 3);
gd.addCheckbox ("Perform de-bayer after aberrations in pixel domain", this.post_debayer );
gd.addCheckbox ("Use DCT-based color conversion (false - just LPF RGB with dbg_sigma)",this.color_DCT );
gd.addNumericField("Gaussian sigma to apply to R and B (in addition to G), pix", this.sigma_rb, 3);
gd.addNumericField("Gaussian sigma to apply to Y in the MDCT domain, pix", this.sigma_y, 3);
......@@ -2073,7 +2073,10 @@ public class EyesisCorrectionParameters {
this.dbg_x1= gd.getNextNumber();
this.dbg_y1= gd.getNextNumber();
this.dbg_sigma= gd.getNextNumber();
this.dbg_mask= gd.getNextString();
this.dbg_src_size= gd.getNextNumber();
this.dbg_scale= gd.getNextNumber();
this.dbg_fold_scale= gd.getNextNumber();
this.dbg_mask= gd.getNextString();
this.dbg_mode= (int) gd.getNextNumber();
this.dbg_window_mode= (int) gd.getNextNumber();
this.centerWindowToTarget= gd.getNextBoolean();
......@@ -2099,6 +2102,7 @@ public class EyesisCorrectionParameters {
this.vignetting_max= gd.getNextNumber();
this.vignetting_range= gd.getNextNumber();
this.post_debayer= gd.getNextBoolean();
this.color_DCT= gd.getNextBoolean();
this.sigma_rb= gd.getNextNumber();
this.sigma_y= gd.getNextNumber();
......
......@@ -1211,12 +1211,14 @@ public class EyesisDCT {
threadsMax,
debugLevel);
} else { // just LPF RGB
for (int chn = 0; chn < dct_data.length; chn++) {
image_dtt.dct_lpf(
dct_parameters.dbg_sigma,
dct_data[chn],
threadsMax,
debugLevel);
if (dct_parameters.dbg_sigma > 0){ // no filter at all
for (int chn = 0; chn < dct_data.length; chn++) {
image_dtt.dct_lpf(
dct_parameters.dbg_sigma,
dct_data[chn],
threadsMax,
debugLevel);
}
}
}
......@@ -1274,7 +1276,7 @@ public class EyesisDCT {
(dct_parameters.denoise? dct_parameters.denoise_c:0.0), // final double denoise_c, // = 1.0; // maximal total smoothing of the color differences post-kernel (will compete with edge emphasis)
dct_parameters.denoise_y_corn, // final double denoise_y_corn, // = 0.5; // weight of the 4 corner pixels during denoise y (relative to 4 straight)
dct_parameters.denoise_c_corn, // final double denoise_c_corn, // = 0.5; // weight of the 4 corner pixels during denoise y (relative to 4 straight)
threadsMax, // final int threadsMax, // maximal number of threads to launch
dct_parameters.dct_size, //, // final int threadsMax, // maximal number of threads to launch
debugLevel); // final int globalDebugLevel)
if (debugLevel > 0) sdfa_instance.showArrays(
idct_data,
......@@ -1291,7 +1293,37 @@ public class EyesisDCT {
(tilesX + 1) * dct_parameters.dct_size);
} else {
if (debugLevel > 0) System.out.println("Bypassing nonlinear correction");
if (dct_parameters.post_debayer){ // post_debayer
if (debugLevel > -1) System.out.println("Applying post-debayer");
if (debugLevel > -1) sdfa_instance.showArrays(
idct_data,
(tilesX + 1) * dct_parameters.dct_size,
(tilesY + 1) * dct_parameters.dct_size,
true,
result.getTitle()+"-rbg_before");
idct_data = post_debayer( // debayer in pixel domain after aberration correction
idct_data, // final double [][] rbg, // yPrPb,
(tilesX + 1) * dct_parameters.dct_size, // final int width,
dct_parameters.dct_size, // final int step, // just for multi-threading efficiency?
dct_parameters.dct_size, // final int threadsMax, // maximal number of threads to launch
debugLevel); // final int globalDebugLevel)
// add here YPrPb conversion, then edge_emphasis
if (debugLevel > -1) sdfa_instance.showArrays(
idct_data,
(tilesX + 1) * dct_parameters.dct_size,
(tilesY + 1) * dct_parameters.dct_size,
true,
result.getTitle()+"-rbg_after");
} else {
if (debugLevel > -1) System.out.println("Applyed LPF, sigma = "+dct_parameters.dbg_sigma);
if (debugLevel > -1) sdfa_instance.showArrays(
idct_data,
(tilesX + 1) * dct_parameters.dct_size,
(tilesY + 1) * dct_parameters.dct_size,
true,
result.getTitle()+"-rbg_sigma");
}
}
if (debugLevel > 0) sdfa_instance.showArrays(idct_data,
......@@ -1554,6 +1586,69 @@ public class EyesisDCT {
}
public double [][] post_debayer( // debayer in pixel domain after aberration correction
final double [][] rbg, // yPrPb,
final int width,
final int step, // just for multi-threading efficiency?
final int threadsMax, // maximal number of threads to launch
final int globalDebugLevel)
{
final double [][] rbg_new = new double [rbg.length][rbg[0].length];
final int height = rbg[0].length/width;
final int tilesY = (height + step - 1) / step;
final int tilesX = (width + step - 1) / step;
final int nTiles=tilesX*tilesY;
final double [] kern_g={
0.0, 0.125, 0.0 ,
0.125, 0.5, 0.125,
0.0, 0.125, 0.0 };
final double [] kern_rb={
0.0625, 0.125, 0.0625,
0.125, 0.25, 0.125,
0.0625, 0.125, 0.0625};
final double [][] kerns = {kern_rb,kern_rb,kern_g};
final int [] neib_indices = {-width-1,-width,-width+1,-1,0,1,width-1,width,width+1};
final Thread[] threads = ImageDtt.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;
double [] neibs = new double[9]; // pixels around current, first Y, then each color diff
for (int nTile = ai.getAndIncrement(); nTile < nTiles; nTile = ai.getAndIncrement()) {
tileY = nTile/tilesX;
tileX = nTile - tileY * tilesX;
int y1 = (tileY +1) * step;
if (y1 > height) y1 = height;
int x1 = (tileX +1) * step;
if (x1 > width) x1 = width;
for (int y = tileY * step; y < y1; y++) {
for (int x = tileX * step; x < x1; x++) {
int indx = y*width + x;
for (int n = 0; n < rbg.length; n++) {
rbg_new[n][indx] = rbg[n][indx]; // default - just copy old value
}
if ((y > 0) && (y < (height - 1)) && (x > 0) && (x < (width - 1))) { // only correct those not on the edge
for (int n = 0; n < rbg.length; n++) {
rbg_new[n][indx] = 0.0;
for (int i = 0; i < neibs.length; i++){
rbg_new[n][indx] += kerns[n][i]*rbg[n][indx+neib_indices[i]];
}
}
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
return rbg_new;
}
public double [][] edge_emphasis(
final double [][] yPrPb,
final int width,
......@@ -1731,6 +1826,9 @@ public class EyesisDCT {
ImageDtt.startAndJoin(threads);
return yPrPb_new;
}
public void debayer_rbg(
ImageStack stack_rbg){
debayer_rbg(stack_rbg, 1.0);
......
......@@ -453,6 +453,7 @@ private Panel panel1,panel2,panel3,panel4,panel5,panel5a, panel6,panel7,panelPos
panelDct1.setLayout(new GridLayout(1, 0, 5, 5)); // rows, columns, vgap, hgap
addButton("DCT test 1", panelDct1, color_process);
addButton("select MDCT image", panelDct1, color_configure);
addButton("MDCT scale", panelDct1, color_process);
addButton("MDCT stack", panelDct1, color_process);
addButton("DCT test 3", panelDct1, color_process);
addButton("DCT test 4", panelDct1, color_process);
......@@ -2627,6 +2628,103 @@ private Panel panel1,panel2,panel3,panel4,panel5,panel5a, panel6,panel7,panelPos
DBG_IMP = imp_src;
}
/* ======================================================================== */
} else if (label.equals("MDCT scale")) {
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.mdctScale(
DBG_IMP.getStack(),
DCT_PARAMETERS.kernel_chn,
DCT_PARAMETERS,
THREADS_MAX, DEBUG_LEVEL, UPDATE_STATUS);
for (int chn = 0; chn < dctdc_data.length; chn++) {
image_dtt.dct_scale(
DCT_PARAMETERS.dbg_scale, // DCT_PARAMETERS.dct_size / DCT_PARAMETERS.dbg_src_size , //final double scale_hor, // < 1.0 - enlarge in dct domain (shrink in time/space)
DCT_PARAMETERS.dbg_scale, //DCT_PARAMETERS.dct_size / DCT_PARAMETERS.dbg_src_size, // final double scale_vert, // < 1.0 - enlarge in dct domain (shrink in time/space)
DCT_PARAMETERS.normalize, // final boolean normalize, // preserve weighted dct values
dctdc_data[chn], // final double [][][] dct_data,
DCT_PARAMETERS.tileX,
DCT_PARAMETERS.tileY,
THREADS_MAX, DEBUG_LEVEL);
}
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;
int tilesY = dctdc_data[0].length;
int tilesX = dctdc_data[0][0].length;
System.out.println("tilesX="+tilesX);
System.out.println("tilesY="+tilesY);
double [][] dct = new double [dctdc_data.length][];
for (int chn = 0; chn < dct.length; chn++) {
dct[chn] = image_dtt.lapped_dct_dbg(
dctdc_data [chn],
THREADS_MAX,
DEBUG_LEVEL);
}
// System.out.println("dct_dc.length="+dct_dc.length+" dct_ac.length="+dct_ac.length);
if (DEBUG_LEVEL > 0){
SDFA_INSTANCE.showArrays(dct,
tilesX*DCT_PARAMETERS.dct_size,
tilesY*DCT_PARAMETERS.dct_size,
true,
DBG_IMP.getTitle()+"-DCT");
}
double [][] idct_data = new double [dctdc_data.length][];
for (int chn=0; chn<idct_data.length;chn++){
idct_data[chn] = image_dtt.lapped_idct(
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("MDCT stack")) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
......
......@@ -658,6 +658,254 @@ public class ImageDtt {
return dpixels;
}
public double [][][][] mdctScale(
final ImageStack imageStack,
final int subcamera, //
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 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 */
// 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_scale(
dpixels,
imgWidth,
dctParameters.dct_size,
(int) Math.round(dctParameters.dbg_src_size),
dctParameters.dbg_fold_scale,
dctParameters.dbg_fold_scale,
0, // dct_mode, // 0: dct/dct, 1: dct/dst, 2: dst/dct, 3: dst/dst
dctParameters.dct_window, // final int window_type,
chn,
dctParameters.tileX,
dctParameters.tileY,
dctParameters.dbg_mode,
threadsMax, // maximal number of threads to launch
debugLevel);
}
return dct_data;
}
public double [][][] lapped_dct_scale( // scale image to 8/9 size in each direction
final double [] dpixels,
final int width,
final int dct_size,
final int src_size, // source step (== dct_size - no scale, == 9 - shrink, ==7 - expand
final double scale_hor,
final double scale_vert,
final int dct_mode, // 0: dct/dct, 1: dct/dst, 2: dst/dct, 3: dst/dst
final int window_type,
final int color,
final int debug_tileX,
final int debug_tileY,
final int debug_mode,
final int threadsMax, // maximal number of threads to launch
final int globalDebugLevel)
{
final int height=dpixels.length/width;
final int n2 = dct_size * 2;
final int tilesX = (width - n2) / src_size + 1;
final int tilesY = (height - n2) / src_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 tileY = 0; tileY < tilesY; tileY++){
for (int tileX = 0; tileX < tilesX; tileX++){
for (int i=0; i<dct_data[tileY][tileX].length;i++) dct_data[tileY][tileX][i]= 0.0; // actually not needed, Java initializes arrays
}
}
double [] dc = new double [dct_size*dct_size];
for (int i = 0; i<dc.length; i++) dc[i] = 1.0;
// DttRad2 dtt0 = new DttRad2(dct_size);
// dtt0.set_window(window_type);
// final double [] dciii = dtt0.dttt_iii (dc, dct_size);
// final double [] dciiie = dtt0.dttt_iiie (dc, dct_size);
if (globalDebugLevel > 0) {
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;
double [][] fold_k = dtt.get_fold_2d(
// int n,
scale_hor,
scale_vert
);
// double [] tile_out_copy = null;
// showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
for (int nTile = ai.getAndIncrement(); nTile < nTiles; nTile = ai.getAndIncrement()) {
tileY = nTile/tilesX;
tileX = nTile - tileY * tilesX;
//readDCTKernels() debugLevel = 1 kernels[0].size = 8 kernels[0].img_step = 16 kernels[0].asym_nonzero = 4 nColors = 3 numVert = 123 numHor = 164
// no aberration correction, just copy data
for (int i = 0; i < n2;i++){
System.arraycopy(dpixels, (tileY*width+tileX)*src_size + i*width, tile_in, i*n2, n2);
}
tile_folded=dtt.fold_tile(tile_in, dct_size, fold_k);
tile_out=dtt.dttt_iv (tile_folded, dct_mode, dct_size);
// if ((tileY == debug_tileY) && (tileX == debug_tileX) && (color == 2)) {
// tile_out_copy = tile_out.clone();
// }
System.arraycopy(tile_out, 0, dct_data[tileY][tileX], 0, tile_out.length);
}
}
};
}
startAndJoin(threads);
return dct_data;
}
public void dct_scale(
final double scale_hor, // < 1.0 - enlarge in dct domain (shrink in time/space)
final double scale_vert, // < 1.0 - enlarge in dct domain (shrink in time/space)
final boolean normalize, // preserve weighted dct values
final double [][][] dct_data,
final int debug_tileX,
final int debug_tileY,
final int threadsMax, // maximal number of threads to launch
final int globalDebugLevel)
{
final int tilesY=dct_data.length;
final int tilesX=dct_data[0].length;
final int nTiles=tilesX*tilesY;
final int dct_size = (int) Math.round(Math.sqrt(dct_data[0][0].length));
final int dct_len = dct_size*dct_size;
final double [] norm_sym_weights = new double [dct_size*dct_size];
for (int i = 0; i < dct_size; i++){
for (int j = 0; j < dct_size; j++){
double d = Math.cos(Math.PI*i/(2*dct_size))*Math.cos(Math.PI*j/(2*dct_size));
if (i > 0) d*= 2.0;
if (j > 0) d*= 2.0;
norm_sym_weights[i*dct_size+j] = d;
}
}
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;
double [] dct1 = new double [dct_size*dct_size];
double [] dct;
double [][] bidata = new double [2][2];
int dct_m1 = dct_size - 1;
int dct_m2 = dct_size - 2;
for (int nTile = ai.getAndIncrement(); nTile < nTiles; nTile = ai.getAndIncrement()) {
tileY = nTile/tilesX;
tileX = nTile - tileY * tilesX;
dct = dct_data[tileY][tileX];
double sum_orig=0;
if (normalize) {
for (int i = 0; i < dct_len; i++){
sum_orig += dct[i] *norm_sym_weights[i];
}
}
for (int i = 0; i < dct_size; i++){
double fi = i * scale_vert;
int i0 = (int) fi;
fi -= i0;
for (int j = 0; j < dct_size; j++){
double fj = j * scale_hor;
int j0 = (int) fj;
fj -= j0;
int indx = i0*dct_size+j0;
if ((i0 > dct_m1) || (j0 > dct_m1)){
bidata[0][0] = 0.0;
bidata[0][1] = 0.0;
bidata[1][0] = 0.0;
bidata[1][1] = 0.0;
} else {
bidata[0][0] = dct[indx];
if (i0 > dct_m2) {
bidata[1][0] = 0.0;
bidata[1][1] = 0.0;
if (j0 > dct_m2) {
bidata[0][1] = 0.0;
} else {
bidata[0][1] = dct[indx + 1];
}
} else {
bidata[1][0] = dct[indx+dct_size];
if (j0 > dct_m2) {
bidata[0][1] = 0.0;
bidata[1][1] = 0.0;
} else {
bidata[0][1] = dct[indx + 1];
bidata[1][1] = dct[indx + dct_size + 1];
}
}
}
// bilinear interpolation
dct1[i*dct_size+j] =
bidata[0][0] * (1.0-fi) * (1.0-fj) +
bidata[0][1] * (1.0-fi) * fj +
bidata[1][0] * fi * (1.0-fj) +
bidata[1][1] * fi * fj;
if ((globalDebugLevel > 0) && (tileY == debug_tileY) && (tileX == debug_tileX)) {
System.out.println(i+":"+j+" {"+bidata[0][0]+","+bidata[0][1]+","+bidata[1][0]+","+bidata[1][1]+"}, ["+fi+","+fj+"] "+bidata[1][1]);
}
}
}
if (normalize) {
double sum=0;
for (int i = 0; i < dct_len; i++){
sum += dct1[i] *norm_sym_weights[i];
}
if (sum >0.0) {
double k = sum_orig/sum;
for (int i = 0; i < dct_len; i++){
dct1[i] *= k;
}
}
}
// if ((tileY == debug_tileY) && (tileX == debug_tileX) && (color == 2)) {
if ((globalDebugLevel > 0) && (tileY == debug_tileY) && (tileX == debug_tileX)) {
double [][] scaled_tiles = {dct, dct1};
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
String [] titles = {"orig","scaled"};
sdfa_instance.showArrays(scaled_tiles, dct_size, dct_size, true, "scaled_tile", titles);
}
System.arraycopy(dct1, 0, dct, 0, dct_len); // replace original data
}
}
};
}
startAndJoin(threads);
}
......
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