Commit e0cc40c3 authored by Andrey Filippov's avatar Andrey Filippov

extracting background

parent 695f5cda
......@@ -190,7 +190,9 @@ private Panel panel1,panel2,panel3,panel4,panel5,panel5a, panel6;
0.075, // b_min;
1.0, // r_max;
1.0, // g_max;
1.0 // b_max;
1.0, // b_max;
0.0, // alpha_min;
1.0 // alpha_max;
);
public static FilesParameters FILE_PARAMETERS= new FilesParameters (
......@@ -802,7 +804,8 @@ if (PROCESS_PARAMETERS.saveSettings) saveProperties(FILE_PARAMETERS.resultsDirec
imp_colorStack.getTitle()+"-RGB24",
0, 65536, // r range 0->0, 65536->256
0, 65536, // g range
0, 65536);// b range
0, 65536, // b range
0, 65536);// alpha range
imp_RGB24.setTitle(imp_colorStack.getTitle()+"rgb24");
imp_RGB24.show();
return;
......@@ -1177,26 +1180,30 @@ if (PROCESS_PARAMETERS.saveSettings) saveProperties(FILE_PARAMETERS.resultsDirec
int g_min,
int g_max,
int b_min,
int b_max){
int [] mins= {r_min,g_min,b_min};
int [] maxs= {r_max,g_max,b_max};
int b_max,
int alpha_min,
int alpha_max){
int [] mins= {r_min,g_min,b_min,alpha_min};
int [] maxs= {r_max,g_max,b_max,alpha_max};
int i;
int length=stack16.getWidth()*stack16.getHeight();
short [][] spixels=new short[3][];
int numSlices = stack16.getSize();
if (numSlices > 4) numSlices = 4;
short [][] spixels=new short[numSlices][];
int [] pixels=new int[length];
int c,d;
double [] scale=new double[3];
for (c=0;c<3;c++) {
double [] scale=new double[numSlices];
for (c = 0; c < numSlices; c++) {
scale[c]=256.0/(maxs[c]-mins[c]);
}
for (i=0;i<3;i++) spixels[i]= (short[])stack16.getPixels(i+1);
for (i=0;i<length;i++) {
for (i = 0; i < numSlices; i++) spixels[i]= (short[])stack16.getPixels(i+1);
for (i = 0; i < length; i++) {
pixels[i]=0;
for (c=0;c<3;c++) {
for (c=0;c < numSlices;c++) {
d=(int)(((spixels[c][i]& 0xffff)-mins[c])*scale[c]);
if (d>255) d=255;
else if (d<0) d=0;
pixels[i]= d | (pixels[i]<<8);
if (d > 255) d=255;
else if (d < 0) d=0;
pixels[i]= d | (pixels[i] << 8);
}
}
ColorProcessor cp=new ColorProcessor(stack16.getWidth(),stack16.getHeight());
......@@ -1976,7 +1983,8 @@ if (PROCESS_PARAMETERS.saveSettings) saveProperties(FILE_PARAMETERS.resultsDirec
title+"-RGB24",
0, 65536, // r range 0->0, 65536->256
0, 65536, // g range
0, 65536);// b range
0, 65536, // b range
0, 65536);// alpha range
if (processParameters.JPEG_scale!=1.0){
ImageProcessor ip=imp_RGB24.getProcessor();
ip.setInterpolationMethod(ImageProcessor.BICUBIC);
......@@ -3504,6 +3512,9 @@ G= Y +Pr*(- 2*Kr*(1-Kr))/Kg + Pb*(-2*Kb*(1-Kb))/Kg
gd.addNumericField("Red color white level", rgbParameters.r_max, 3);
gd.addNumericField("Green color white level", rgbParameters.g_max, 3);
gd.addNumericField("Blue color white level", rgbParameters.b_max, 3);
gd.addNumericField("Alpha channel min", rgbParameters.alpha_min, 3);
gd.addNumericField("Alpha channel max", rgbParameters.alpha_max, 3);
gd.showDialog();
if (gd.wasCanceled()) return false;
rgbParameters.r_min= gd.getNextNumber();
......@@ -3512,6 +3523,8 @@ G= Y +Pr*(- 2*Kr*(1-Kr))/Kg + Pb*(-2*Kb*(1-Kb))/Kg
rgbParameters.r_max= gd.getNextNumber();
rgbParameters.g_max= gd.getNextNumber();
rgbParameters.b_max= gd.getNextNumber();
rgbParameters.alpha_min= gd.getNextNumber();
rgbParameters.alpha_max= gd.getNextNumber();
return true;
}
......@@ -4233,13 +4246,15 @@ G= Y +Pr*(- 2*Kr*(1-Kr))/Kg + Pb*(-2*Kb*(1-Kb))/Kg
/* ======================================================================== */
public static class RGBParameters {
public double r_min;
public double g_min;
public double b_min;
public double r_max;
public double g_max;
public double b_max;
public double r_min = 0.075;
public double g_min = 0.075;
public double b_min = 0.075;
public double r_max = 1.0;
public double g_max = 1.0;
public double b_max = 1.0;
public double alpha_min = 0.0;
public double alpha_max = 1.0;
/*
public RGBParameters(double r_min, double g_min, double b_min, double r_max, double g_max, double b_max) {
this.r_min = r_min;
this.g_min = g_min;
......@@ -4248,6 +4263,18 @@ G= Y +Pr*(- 2*Kr*(1-Kr))/Kg + Pb*(-2*Kb*(1-Kb))/Kg
this.g_max = g_max;
this.b_max = b_max;
}
*/
public RGBParameters(double r_min, double g_min, double b_min, double r_max, double g_max, double b_max, double alpha_min, double alpha_max) {
this.r_min = r_min;
this.g_min = g_min;
this.b_min = b_min;
this.r_max = r_max;
this.g_max = g_max;
this.b_max = b_max;
this.alpha_min = alpha_min;
this.alpha_max = alpha_max;
}
public void setProperties(String prefix,Properties properties){
properties.setProperty(prefix+"r_min",this.r_min+"");
properties.setProperty(prefix+"g_min",this.g_min+"");
......@@ -4255,6 +4282,9 @@ G= Y +Pr*(- 2*Kr*(1-Kr))/Kg + Pb*(-2*Kb*(1-Kb))/Kg
properties.setProperty(prefix+"r_max",this.r_max+"");
properties.setProperty(prefix+"g_max",this.g_max+"");
properties.setProperty(prefix+"b_max",this.b_max+"");
properties.setProperty(prefix+"alpha_min",this.alpha_min+"");
properties.setProperty(prefix+"alpha_max",this.alpha_max+"");
}
public void getProperties(String prefix,Properties properties){
this.r_min=Double.parseDouble(properties.getProperty(prefix+"r_min"));
......@@ -4263,6 +4293,8 @@ G= Y +Pr*(- 2*Kr*(1-Kr))/Kg + Pb*(-2*Kb*(1-Kb))/Kg
this.r_max=Double.parseDouble(properties.getProperty(prefix+"r_max"));
this.g_max=Double.parseDouble(properties.getProperty(prefix+"g_max"));
this.b_max=Double.parseDouble(properties.getProperty(prefix+"b_max"));
if (properties.getProperty(prefix+"alpha_min")!=null) this.alpha_min=Double.parseDouble(properties.getProperty(prefix+"alpha_min"));
if (properties.getProperty(prefix+"alpha_max")!=null) this.alpha_max=Double.parseDouble(properties.getProperty(prefix+"alpha_max"));
}
}
......
......@@ -62,6 +62,7 @@ public class EyesisCorrectionParameters {
public boolean imageJTags= false; // encode ImageJ info data to the TIFF output header
public boolean jpeg = true; // convert to RGB and save JPEG (if save is true)
public boolean png = true; // use PNG instead of TIFF for 32-bit ARGB
public boolean save = true;
public boolean save16 = false; // save 16-bit tiff also if the end result is 8 bit
public boolean save32 = false; // save 32-bit tiff also if the end result is 8 or 16 bit
......@@ -137,6 +138,7 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"outputRangeFP",this.outputRangeFP+"");
properties.setProperty(prefix+"imageJTags",this.imageJTags+"");
properties.setProperty(prefix+"jpeg",this.jpeg+"");
properties.setProperty(prefix+"png",this.png+"");
properties.setProperty(prefix+"save",this.save+"");
properties.setProperty(prefix+"save16",this.save16+"");
properties.setProperty(prefix+"save32",this.save32+"");
......@@ -224,6 +226,7 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"outputRangeFP")!=null) this.outputRangeFP=Double.parseDouble(properties.getProperty(prefix+"outputRangeFP"));
if (properties.getProperty(prefix+"imageJTags")!=null) this.imageJTags=Boolean.parseBoolean(properties.getProperty(prefix+"imageJTags"));
if (properties.getProperty(prefix+"jpeg")!=null) this.jpeg=Boolean.parseBoolean(properties.getProperty(prefix+"jpeg")); // convert to RGB and save jpeg (if save is true)
if (properties.getProperty(prefix+"png")!=null) this.png=Boolean.parseBoolean(properties.getProperty(prefix+"png")); // convert to RGB and save jpeg (if save is true)
if (properties.getProperty(prefix+"save")!=null) this.save=Boolean.parseBoolean(properties.getProperty(prefix+"save"));
if (properties.getProperty(prefix+"save16")!=null) this.save16=Boolean.parseBoolean(properties.getProperty(prefix+"save16")); // save 16-bit tiff also if the end result is 8 bit
if (properties.getProperty(prefix+"save32")!=null) this.save32=Boolean.parseBoolean(properties.getProperty(prefix+"save32")); // save 32-bit tiff also if the end result is 8 or 16 bit
......@@ -330,6 +333,7 @@ public class EyesisCorrectionParameters {
gd.addCheckbox ("Convert to RGB48", this.toRGB);
gd.addCheckbox ("Convert to 8 bit RGB (and save JPEG if save is enabled)", this.jpeg);
gd.addCheckbox ("Use PNG instead of TIFF for 32 bit (8 per color) RGBA", this.png);
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);
......@@ -421,6 +425,7 @@ public class EyesisCorrectionParameters {
this.imageJTags= gd.getNextBoolean();
this.toRGB= gd.getNextBoolean();
this.jpeg= gd.getNextBoolean();
this.png= gd.getNextBoolean();
this.save= gd.getNextBoolean();
this.save16= gd.getNextBoolean();
this.save32= gd.getNextBoolean();
......@@ -1288,20 +1293,32 @@ public class EyesisCorrectionParameters {
/* ======================================================================== */
public static class RGBParameters {
public double r_min;
public double g_min;
public double b_min;
public double r_max;
public double g_max;
public double b_max;
public RGBParameters(double r_min, double g_min, double b_min, double r_max, double g_max, double b_max) {
public double r_min = 0.075;
public double g_min = 0.075;
public double b_min = 0.075;
public double r_max = 1.0;
public double g_max = 1.0;
public double b_max = 1.0;
public double alpha_min = 0.0;
public double alpha_max = 1.0;
/* public RGBParameters(double r_min, double g_min, double b_min, double r_max, double g_max, double b_max) {
this.r_min = r_min;
this.g_min = g_min;
this.b_min = b_min;
this.r_max = r_max;
this.g_max = g_max;
this.b_max = b_max;
} */
public RGBParameters(double r_min, double g_min, double b_min, double r_max, double g_max, double b_max, double alpha_min, double alpha_max) {
this.r_min = r_min;
this.g_min = g_min;
this.b_min = b_min;
this.r_max = r_max;
this.g_max = g_max;
this.b_max = b_max;
this.alpha_min = alpha_min;
this.alpha_max = alpha_max;
}
public void setProperties(String prefix,Properties properties){
properties.setProperty(prefix+"r_min",this.r_min+"");
......@@ -1310,6 +1327,8 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"r_max",this.r_max+"");
properties.setProperty(prefix+"g_max",this.g_max+"");
properties.setProperty(prefix+"b_max",this.b_max+"");
properties.setProperty(prefix+"alpha_min",this.alpha_min+"");
properties.setProperty(prefix+"alpha_max",this.alpha_max+"");
}
public void getProperties(String prefix,Properties properties){
this.r_min=Double.parseDouble(properties.getProperty(prefix+"r_min"));
......@@ -1318,6 +1337,8 @@ public class EyesisCorrectionParameters {
this.r_max=Double.parseDouble(properties.getProperty(prefix+"r_max"));
this.g_max=Double.parseDouble(properties.getProperty(prefix+"g_max"));
this.b_max=Double.parseDouble(properties.getProperty(prefix+"b_max"));
if (properties.getProperty(prefix+"alpha_min")!=null) this.alpha_min=Double.parseDouble(properties.getProperty(prefix+"alpha_min"));
if (properties.getProperty(prefix+"alpha_max")!=null) this.alpha_max=Double.parseDouble(properties.getProperty(prefix+"alpha_max"));
}
}
......@@ -1898,6 +1919,7 @@ public class EyesisCorrectionParameters {
public int corr_mask = 15; // bitmask of pairs to combine in the composite
public boolean corr_sym = false; // combine correlation with mirrored around disparity direction
public boolean corr_keep = true; // keep all partial correlations (otherwise - only combined one)
public boolean corr_show = false; // Show combined correlations
public boolean corr_mismatch= false; // calculate per-pair X/Y variations of measured correlations
// TODO: what to do if some occlusion is present (only some channels correlate)
public double corr_offset = -1.0; //0.1; // add to pair correlation before multiplying by other pairs (between sum and product)
......@@ -1929,12 +1951,19 @@ public class EyesisCorrectionParameters {
public double diff_threshold = 1.5; // RMS difference from average to discard channel (~ 1.0 - 1/255 full scale image)
public boolean diff_gauss = true; // when averaging images, use gaussian around average as weight (false - sharp all/nothing)
public double min_agree = 3.0; // minimal number of channels to agree on a point (real number to work with fuzzy averages)
public boolean dust_remove = true; // Do not reduce average weight when only one image differes much from the average
public boolean keep_weights = true; // add port weights to RGBA stack (debug feature)
public boolean sharp_alpha = false; // combining mode for alpha channel: false - treat as RGB, true - apply center 8x8 only
public boolean gen_chn_img = false; // generate shifted channel images
public double alpha0 = 0.6; // > .525 Alpha channel 0.0 thereshold (lower - transparent) (watch for far objects)
public double alpha1 = 0.8; // Alpha channel 1.0 threshold (higher - opaque) (watch for window dust)
public boolean gen_chn_stacks = false; // generate shifted channel rgb stacks
public boolean gen_chn_img = true; // generate shifted channel images
public boolean show_nonoverlap = true; // show result RGBA before overlap combined (first channels, then RGBA combined?)
public boolean show_overlap = true; // show result RGBA (first channels, then RGBA combined?)
public boolean show_rgba_color = true; // show combined color image
public boolean show_map = true; // show disparity maps
public double disp_scan_start = 0.0; // disparity scan start value
public double disp_scan_step = 1.0; // disparity scan step
......@@ -1952,7 +1981,20 @@ public class EyesisCorrectionParameters {
public double fcorr_min_stength = 0.005; // minimal correlation strength to apply fine correction
public double fcorr_disp_diff = 3.0; // consider only tiles with absolute residual disparity lower than
public boolean fcorr_quadratic = true; // Use quadratic polynomial for fine correction (false - only linear)
public boolean fcorr_ignore = false; // Ignore currently calculated fine correction
public double corr_magic_scale = 0.85; // reported correlation offset vs. actual one (not yet understood)
// 3d reconstruction
public double min_smth = 0.25; // minimal noise-normalized pixel difference in a channel to suspect something
public double sure_smth = 2.0; // reliable noise-normalized pixel difference in a channel to have something
public double bgnd_range = 0.3; // disparity range to be considered background
public double bgnd_sure = 0.02; // minimal strength to be considered definitely background
public double bgnd_maybe = 0.005; // maximal strength to ignore as non-background
public double bgnd_2diff = 0.005; // maximal strength to ignore as non-background
public int min_clstr_seed = 3; // number of tiles in a cluster to seed (just background?)
public int min_clstr_block = 3; // number of tiles in a cluster to block (just non-background?)
public int bgnd_grow = 2; // number of tiles to grow (1 - hor/vert, 2 - hor/vert/diagonal)
......@@ -1989,6 +2031,7 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"corr_mask", this.corr_mask+"");
properties.setProperty(prefix+"corr_sym", this.corr_sym+"");
properties.setProperty(prefix+"corr_keep", this.corr_keep+"");
properties.setProperty(prefix+"corr_show", this.corr_show+"");
properties.setProperty(prefix+"corr_mismatch", this.corr_mismatch+"");
properties.setProperty(prefix+"corr_offset", this.corr_offset +"");
properties.setProperty(prefix+"corr_red", this.corr_red +"");
......@@ -2011,11 +2054,19 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"diff_threshold", this.diff_threshold +"");
properties.setProperty(prefix+"diff_gauss", this.diff_gauss+"");
properties.setProperty(prefix+"min_agree", this.min_agree +"");
properties.setProperty(prefix+"dust_remove", this.dust_remove+"");
properties.setProperty(prefix+"keep_weights", this.keep_weights+"");
properties.setProperty(prefix+"sharp_alpha", this.sharp_alpha+"");
properties.setProperty(prefix+"alpha0", this.alpha0 +"");
properties.setProperty(prefix+"alpha1", this.alpha1 +"");
properties.setProperty(prefix+"gen_chn_stacks", this.gen_chn_stacks+"");
properties.setProperty(prefix+"gen_chn_img", this.gen_chn_img+"");
properties.setProperty(prefix+"show_nonoverlap", this.show_nonoverlap+"");
properties.setProperty(prefix+"show_overlap", this.show_overlap+"");
properties.setProperty(prefix+"show_rgba_color", this.show_rgba_color+"");
properties.setProperty(prefix+"show_map", this.show_map+"");
properties.setProperty(prefix+"disp_scan_start", this.disp_scan_start +"");
properties.setProperty(prefix+"disp_scan_step", this.disp_scan_step +"");
properties.setProperty(prefix+"disp_scan_count", this.disp_scan_count+"");
......@@ -2032,7 +2083,20 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"fcorr_min_stength",this.fcorr_min_stength +"");
properties.setProperty(prefix+"fcorr_disp_diff", this.fcorr_disp_diff +"");
properties.setProperty(prefix+"fcorr_quadratic", this.fcorr_quadratic+"");
properties.setProperty(prefix+"fcorr_ignore", this.fcorr_ignore+"");
properties.setProperty(prefix+"corr_magic_scale", this.corr_magic_scale +"");
properties.setProperty(prefix+"min_smth", this.min_smth +"");
properties.setProperty(prefix+"sure_smth", this.sure_smth +"");
properties.setProperty(prefix+"bgnd_range", this.bgnd_range +"");
properties.setProperty(prefix+"bgnd_sure", this.bgnd_sure +"");
properties.setProperty(prefix+"bgnd_maybe", this.bgnd_maybe +"");
properties.setProperty(prefix+"min_clstr_seed", this.min_clstr_seed+"");
properties.setProperty(prefix+"min_clstr_block", this.min_clstr_block+"");
properties.setProperty(prefix+"bgnd_grow", this.bgnd_grow+"");
}
public void getProperties(String prefix,Properties properties){
if (properties.getProperty(prefix+"transform_size")!=null) this.transform_size=Integer.parseInt(properties.getProperty(prefix+"transform_size"));
......@@ -2064,6 +2128,7 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"corr_mask")!=null) this.corr_mask=Integer.parseInt(properties.getProperty(prefix+"corr_mask"));
if (properties.getProperty(prefix+"corr_sym")!=null) this.corr_sym=Boolean.parseBoolean(properties.getProperty(prefix+"corr_sym"));
if (properties.getProperty(prefix+"corr_keep")!=null) this.corr_keep=Boolean.parseBoolean(properties.getProperty(prefix+"corr_keep"));
if (properties.getProperty(prefix+"corr_show")!=null) this.corr_show=Boolean.parseBoolean(properties.getProperty(prefix+"corr_show"));
if (properties.getProperty(prefix+"corr_mismatch")!=null) this.corr_mismatch=Boolean.parseBoolean(properties.getProperty(prefix+"corr_mismatch"));
if (properties.getProperty(prefix+"corr_offset")!=null) this.corr_offset=Double.parseDouble(properties.getProperty(prefix+"corr_offset"));
if (properties.getProperty(prefix+"corr_red")!=null) this.corr_red=Double.parseDouble(properties.getProperty(prefix+"corr_red"));
......@@ -2080,17 +2145,23 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"tile_task_wt")!=null) this.tile_task_wt=Integer.parseInt(properties.getProperty(prefix+"tile_task_wt"));
if (properties.getProperty(prefix+"tile_task_ww")!=null) this.tile_task_ww=Integer.parseInt(properties.getProperty(prefix+"tile_task_ww"));
if (properties.getProperty(prefix+"tile_task_wh")!=null) this.tile_task_wh=Integer.parseInt(properties.getProperty(prefix+"tile_task_wh"));
if (properties.getProperty(prefix+"min_shot")!=null) this.min_shot=Double.parseDouble(properties.getProperty(prefix+"min_shot"));
if (properties.getProperty(prefix+"min_shot")!=null) this.min_shot=Double.parseDouble(properties.getProperty(prefix+"min_shot"));
if (properties.getProperty(prefix+"scale_shot")!=null) this.scale_shot=Double.parseDouble(properties.getProperty(prefix+"scale_shot"));
if (properties.getProperty(prefix+"diff_sigma")!=null) this.diff_sigma=Double.parseDouble(properties.getProperty(prefix+"diff_sigma"));
if (properties.getProperty(prefix+"diff_threshold")!=null) this.diff_threshold=Double.parseDouble(properties.getProperty(prefix+"diff_threshold"));
if (properties.getProperty(prefix+"diff_gauss")!=null) this.diff_gauss=Boolean.parseBoolean(properties.getProperty(prefix+"diff_gauss"));
if (properties.getProperty(prefix+"min_agree")!=null) this.min_agree=Double.parseDouble(properties.getProperty(prefix+"min_agree"));
if (properties.getProperty(prefix+"dust_remove")!=null) this.dust_remove=Boolean.parseBoolean(properties.getProperty(prefix+"dust_remove"));
if (properties.getProperty(prefix+"keep_weights")!=null) this.keep_weights=Boolean.parseBoolean(properties.getProperty(prefix+"keep_weights"));
if (properties.getProperty(prefix+"sharp_alpha")!=null) this.sharp_alpha=Boolean.parseBoolean(properties.getProperty(prefix+"sharp_alpha"));
if (properties.getProperty(prefix+"alpha0")!=null) this.alpha0=Double.parseDouble(properties.getProperty(prefix+"alpha0"));
if (properties.getProperty(prefix+"alpha1")!=null) this.alpha1=Double.parseDouble(properties.getProperty(prefix+"alpha1"));
if (properties.getProperty(prefix+"gen_chn_stacks")!=null) this.gen_chn_stacks=Boolean.parseBoolean(properties.getProperty(prefix+"gen_chn_stacks"));
if (properties.getProperty(prefix+"gen_chn_img")!=null) this.gen_chn_img=Boolean.parseBoolean(properties.getProperty(prefix+"gen_chn_img"));
if (properties.getProperty(prefix+"show_nonoverlap")!=null)this.show_nonoverlap=Boolean.parseBoolean(properties.getProperty(prefix+"show_nonoverlap"));
if (properties.getProperty(prefix+"show_overlap")!=null) this.show_overlap=Boolean.parseBoolean(properties.getProperty(prefix+"show_overlap"));
if (properties.getProperty(prefix+"show_rgba_color")!=null)this.show_rgba_color=Boolean.parseBoolean(properties.getProperty(prefix+"show_rgba_color"));
if (properties.getProperty(prefix+"show_map")!=null) this.show_map=Boolean.parseBoolean(properties.getProperty(prefix+"show_map"));
if (properties.getProperty(prefix+"disp_scan_start")!=null)this.disp_scan_start=Double.parseDouble(properties.getProperty(prefix+"disp_scan_start"));
if (properties.getProperty(prefix+"disp_scan_step")!=null) this.disp_scan_step=Double.parseDouble(properties.getProperty(prefix+"disp_scan_step"));
if (properties.getProperty(prefix+"disp_scan_count")!=null)this.disp_scan_count=Integer.parseInt(properties.getProperty(prefix+"disp_scan_count"));
......@@ -2107,7 +2178,19 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"fcorr_min_stength")!=null) this.fcorr_min_stength=Double.parseDouble(properties.getProperty(prefix+"fcorr_min_stength"));
if (properties.getProperty(prefix+"fcorr_disp_diff")!=null) this.fcorr_disp_diff=Double.parseDouble(properties.getProperty(prefix+"fcorr_disp_diff"));
if (properties.getProperty(prefix+"fcorr_quadratic")!=null) this.fcorr_quadratic=Boolean.parseBoolean(properties.getProperty(prefix+"fcorr_quadratic"));
if (properties.getProperty(prefix+"fcorr_ignore")!=null) this.fcorr_ignore=Boolean.parseBoolean(properties.getProperty(prefix+"fcorr_ignore"));
if (properties.getProperty(prefix+"corr_magic_scale")!=null) this.corr_magic_scale=Double.parseDouble(properties.getProperty(prefix+"corr_magic_scale"));
if (properties.getProperty(prefix+"min_smth")!=null) this.min_smth=Double.parseDouble(properties.getProperty(prefix+"min_smth"));
if (properties.getProperty(prefix+"sure_smth")!=null) this.sure_smth=Double.parseDouble(properties.getProperty(prefix+"sure_smth"));
if (properties.getProperty(prefix+"bgnd_range")!=null) this.bgnd_range=Double.parseDouble(properties.getProperty(prefix+"bgnd_range"));
if (properties.getProperty(prefix+"bgnd_sure")!=null) this.bgnd_sure=Double.parseDouble(properties.getProperty(prefix+"bgnd_sure"));
if (properties.getProperty(prefix+"bgnd_maybe")!=null) this.bgnd_maybe=Double.parseDouble(properties.getProperty(prefix+"bgnd_maybe"));
if (properties.getProperty(prefix+"min_clstr_seed")!=null) this.min_clstr_seed=Integer.parseInt(properties.getProperty(prefix+"min_clstr_seed"));
if (properties.getProperty(prefix+"min_clstr_block")!=null) this.min_clstr_block=Integer.parseInt(properties.getProperty(prefix+"min_clstr_block"));
if (properties.getProperty(prefix+"bgnd_grow")!=null) this.bgnd_grow=Integer.parseInt(properties.getProperty(prefix+"bgnd_grow"));
}
public boolean showDialog() {
......@@ -2141,6 +2224,7 @@ public class EyesisCorrectionParameters {
gd.addNumericField("itmask of pairs to combine in the composite (top, bottom, left,righth)", this.corr_mask, 0);
gd.addCheckbox ("Combine correlation with mirrored around disparity direction", this.corr_sym);
gd.addCheckbox ("Keep all partial correlations (otherwise - only combined one)", this.corr_keep);
gd.addCheckbox ("Show combined correlations", this.corr_show);
gd.addCheckbox ("Calculate per-pair X/Y variations of measured correlations ", this.corr_mismatch);
gd.addNumericField("Add to pair correlation before multiplying by other pairs (between sum and product)", this.corr_offset, 6);
gd.addNumericField("Red to green correlation weight", this.corr_red, 4);
......@@ -2166,11 +2250,17 @@ public class EyesisCorrectionParameters {
gd.addNumericField("RMS difference from average in sigmas to discard channel", this.diff_threshold, 4);
gd.addCheckbox ("Gaussian as weight when averaging images (false - sharp all/nothing)", this.diff_gauss);
gd.addNumericField("Minimal number of channels to agree on a point (real number to work with fuzzy averages)", this.min_agree, 2);
gd.addCheckbox ("Do not reduce average weight when only one image differes much from the average", this.dust_remove);
gd.addCheckbox ("Add port weights to RGBA stack (debug feature)", this.keep_weights);
gd.addCheckbox ("Alpha channel: use center 8x8 (unchecked - treat same as RGB)", this.sharp_alpha);
gd.addCheckbox ("Generate shifted channel images", this.gen_chn_img);
gd.addNumericField("Alpha channel 0.0 thereshold (lower - transparent)", this.alpha0, 3);
gd.addNumericField("Alpha channel 1.0 threshold (higher - opaque)", this.alpha1, 3);
gd.addCheckbox ("Generate shifted channel linear RGB stacks", this.gen_chn_stacks);
gd.addCheckbox ("Generate shifted channel color image stack", this.gen_chn_img);
gd.addCheckbox ("Show result RGBA before overlap combined", this.show_nonoverlap);
gd.addCheckbox ("Show result RGBA ", this.show_overlap);
gd.addCheckbox ("Show result RGBA", this.show_overlap);
gd.addCheckbox ("Show result color", this.show_rgba_color);
gd.addCheckbox ("Show disparity maps", this.show_map);
gd.addNumericField("Disparity scan start value", this.disp_scan_start, 2);
gd.addNumericField("Disparity scan step", this.disp_scan_step, 2);
gd.addNumericField("Disparity scan number of disparity values to scan", this.disp_scan_count, 0);
......@@ -2188,7 +2278,19 @@ public class EyesisCorrectionParameters {
gd.addNumericField("Minimal correlation strength to apply fine correction", this.fcorr_min_stength, 3);
gd.addNumericField("Consider only tiles with absolute residual disparity lower than", this.fcorr_disp_diff, 3);
gd.addCheckbox ("Use quadratic polynomial for fine correction (false - only linear)", this.fcorr_quadratic);
gd.addCheckbox ("Ignore current calculated fine correction (use manual only)", this.fcorr_ignore);
gd.addNumericField("Calculated from correlation offset vs. actual one (not yet understood)", this.corr_magic_scale, 3);
gd.addNumericField("Minimal noise-normalized pixel difference in a channel to suspect something", this.min_smth, 3);
gd.addNumericField("Reliable noise-normalized pixel difference in a channel to have something ", this.sure_smth, 3);
gd.addNumericField("Disparity range to be considered background", this.bgnd_range, 3);
gd.addNumericField("Minimal strength to be considered definitely background", this.bgnd_sure, 3);
gd.addNumericField("Maximal strength to ignore as non-background", this.bgnd_maybe, 3);
gd.addNumericField("Number of tiles in a cluster to seed (just background?)", this.min_clstr_seed, 0);
gd.addNumericField("Number of tiles in a cluster to block (just non-background?)", this.min_clstr_block, 0);
gd.addNumericField("Number of tiles to grow tile selection (1 - hor/vert, 2 - hor/vert/diagonal)", this.bgnd_grow, 0);
WindowTools.addScrollBars(gd);
gd.showDialog();
......@@ -2222,6 +2324,7 @@ public class EyesisCorrectionParameters {
this.corr_mask= (int) gd.getNextNumber();
this.corr_sym= gd.getNextBoolean();
this.corr_keep= gd.getNextBoolean();
this.corr_show= gd.getNextBoolean();
this.corr_mismatch= gd.getNextBoolean();
this.corr_offset= gd.getNextNumber();
this.corr_red= gd.getNextNumber();
......@@ -2244,11 +2347,17 @@ public class EyesisCorrectionParameters {
this.diff_threshold= gd.getNextNumber();
this.diff_gauss= gd.getNextBoolean();
this.min_agree= gd.getNextNumber();
this.dust_remove= gd.getNextBoolean();
this.keep_weights= gd.getNextBoolean();
this.sharp_alpha= gd.getNextBoolean();
this.alpha0= gd.getNextNumber();
this.alpha1= gd.getNextNumber();
this.gen_chn_stacks= gd.getNextBoolean();
this.gen_chn_img= gd.getNextBoolean();
this.show_nonoverlap= gd.getNextBoolean();
this.show_overlap= gd.getNextBoolean();
this.show_rgba_color= gd.getNextBoolean();
this.show_map= gd.getNextBoolean();
this.disp_scan_start= gd.getNextNumber();
this.disp_scan_step= gd.getNextNumber();
this.disp_scan_count= (int) gd.getNextNumber();
......@@ -2265,6 +2374,17 @@ public class EyesisCorrectionParameters {
this.fcorr_min_stength= gd.getNextNumber();
this.fcorr_disp_diff= gd.getNextNumber();
this.fcorr_quadratic= gd.getNextBoolean();
this.fcorr_ignore= gd.getNextBoolean();
this.corr_magic_scale= gd.getNextNumber();
this.min_smth= gd.getNextNumber();
this.sure_smth= gd.getNextNumber();
this.bgnd_range= gd.getNextNumber();
this.bgnd_sure= gd.getNextNumber();
this.bgnd_maybe= gd.getNextNumber();
this.min_clstr_seed= (int) gd.getNextNumber();
this.min_clstr_block= (int) gd.getNextNumber();
this.bgnd_grow= (int) gd.getNextNumber();
return true;
}
......
......@@ -1285,7 +1285,8 @@ public class EyesisCorrections {
title+"-RGB24",
0, 65536, // r range 0->0, 65536->256
0, 65536, // g range
0, 65536);// b range
0, 65536,// b range
0, 65536);// alpha range
if (JPEG_scale!=1.0){
ImageProcessor ip=imp_RGB.getProcessor();
ip.setInterpolationMethod(ImageProcessor.BICUBIC);
......@@ -1524,7 +1525,6 @@ public class EyesisCorrections {
/* ======================================================================== */
public CompositeImage convertToComposite( ImagePlus imp) {
// if (imp.isComposite()) return imp;
if (imp.isComposite()) return null;
if (imp.getNChannels()>1) {
return null; // number of channels should be just 1
......@@ -1532,8 +1532,6 @@ public class EyesisCorrections {
int c = imp.getStackSize();
imp.setDimensions(c, 1, 1);
CompositeImage ci = new CompositeImage(imp, CompositeImage.COMPOSITE);
// ci.show();
// imp.hide();
return ci;
}
......@@ -1546,19 +1544,21 @@ public class EyesisCorrections {
int i,j;
float [] fpixels;
short [] spixels;
double [] mins= {rgbParameters.r_min,rgbParameters.g_min,rgbParameters.b_min};
double [] maxs= {rgbParameters.r_max,rgbParameters.g_max,rgbParameters.b_max};
if (stack32.getSize()<3) return null;
int numSlices = stack32.getSize();
if (numSlices > 4) numSlices = 4;
if (numSlices < 3) return null;
double [] mins= {rgbParameters.r_min, rgbParameters.g_min, rgbParameters.b_min, rgbParameters.alpha_min};
double [] maxs= {rgbParameters.r_max, rgbParameters.g_max, rgbParameters.b_max, rgbParameters.alpha_max};
double value;
double scale;
for (i=0;i<3;i++) {
fpixels= (float[])stack32.getPixels(i+1);
scale=65535.0/(maxs[i]-mins[i]);
for (i = 0; i < numSlices; i++) {
fpixels= (float[])stack32.getPixels(i + 1);
scale=65535.0 / (maxs[i] - mins[i]);
spixels=new short [length];
for (j=0;j<length;j++) {
for (j = 0; j < length; j++) {
value=(fpixels[j]-mins[i])*scale;
if (value<0.0) value=0.0;
else if (value>65535.0) value=65535.0;
if (value<0.0) value = 0.0;
else if (value>65535.0) value = 65535.0;
spixels[j]=(short)(value+0.5);
}
stack16.addSlice(stack32.getSliceLabel(i+1), spixels);
......@@ -1570,39 +1570,89 @@ public class EyesisCorrections {
public ImagePlus convertRGB48toRGB24(
ImageStack stack16,
String title,
int r_min,
int r_max,
int g_min,
int g_max,
int b_min,
int b_max,
int alpha_min,
int alpha_max){
int [] mins= {r_min,g_min,b_min,alpha_min};
int [] maxs= {r_max,g_max,b_max,alpha_max};
int i;
int length=stack16.getWidth()*stack16.getHeight();
int numSlices = stack16.getSize();
if (numSlices > 4) numSlices = 4;
short [][] spixels=new short[numSlices][];
int [] sliceSeq = new int [numSlices];
for (int j = 0; j < numSlices; j++) sliceSeq[j] = (j + ((numSlices > 3)? 3:0)) % 4;
int [] pixels=new int[length];
int c,d;
double [] scale=new double[numSlices];
for (c = 0; c < numSlices; c++) {
scale[c]=256.0/(maxs[c]-mins[c]);
}
for (i = 0; i < numSlices; i++) spixels[i]= (short[])stack16.getPixels(i+1);
for (i = 0; i < length; i++) {
pixels[i]=0;
for (int j=0; j < numSlices; j++) {
c = sliceSeq[j];
d=(int)(((spixels[c][i]& 0xffff)-mins[c])*scale[c]);
if (d > 255) d=255;
else if (d < 0) d=0;
pixels[i]= d | (pixels[i] << 8);
}
}
ColorProcessor cp=new ColorProcessor(stack16.getWidth(),stack16.getHeight());
cp.setPixels(pixels);
ImagePlus imp=new ImagePlus(title,cp);
return imp;
}
public ImageStack convertRGB48toRGBA24Stack(
ImageStack stack16,
double [] dalpha, // alpha pixel array 0..1.0 or null
// String title,
int r_min,
int r_max,
int g_min,
int g_max,
int b_min,
int b_max){
ImageStack stack8 = new ImageStack(stack16.getWidth(), stack16.getHeight());
int [] mins= {r_min,g_min,b_min};
int [] maxs= {r_max,g_max,b_max};
int i;
int length=stack16.getWidth()*stack16.getHeight();
short [][] spixels=new short[3][];
int [] pixels=new int[length];
byte [][] bpixels=new byte [(dalpha != null)? 4: 3][length];
int c,d;
double [] scale=new double[3];
for (c=0;c<3;c++) {
scale[c]=256.0/(maxs[c]-mins[c]);
}
for (i=0;i<3;i++) spixels[i]= (short[])stack16.getPixels(i+1);
for (i=0;i<length;i++) {
pixels[i]=0;
for (c=0;c<3;c++) {
for (i = 0; i <3; i++) spixels[i]= (short[])stack16.getPixels(i+1);
for (c = 0; c <3; c++) {
for (i = 0; i < length; i++){
d=(int)(((spixels[c][i]& 0xffff)-mins[c])*scale[c]);
if (d>255) d=255;
else if (d<0) d=0;
pixels[i]= d | (pixels[i]<<8);
bpixels[c][i]= (byte) d;
}
stack8.addSlice(stack16.getSliceLabel(c+1), bpixels[c]);
}
ColorProcessor cp=new ColorProcessor(stack16.getWidth(),stack16.getHeight());
cp.setPixels(pixels);
ImagePlus imp=new ImagePlus(title,cp);
return imp;
if (dalpha != null) {
for (i = 0; i < length; i++){
bpixels[3][i] = (byte) (255*dalpha[i]);
}
stack8.addSlice("alpha", bpixels[3]);
}
return stack8;
}
/* ======================================================================== */
public ImagePlus Image32toGreyRGB24(
ImagePlus imp){
......@@ -2272,22 +2322,22 @@ public class EyesisCorrections {
/* ======================================================================== */
// private void saveAndShow(
public void saveAndShow(
ImagePlus imp,
ImagePlus imp,
EyesisCorrectionParameters.CorrectionParameters correctionsParameters){
saveAndShowEnable( imp, correctionsParameters , true, true);
saveAndShowEnable( imp, correctionsParameters , true, true);
}
private void saveAndShowEnable(
ImagePlus imp,
EyesisCorrectionParameters.CorrectionParameters correctionsParameters,
boolean enableSave,
boolean enableShow){
saveAndShow(
imp,
correctionsParameters,
correctionsParameters.save && enableSave,
correctionsParameters.show && enableShow,
correctionsParameters.JPEG_quality);
ImagePlus imp,
EyesisCorrectionParameters.CorrectionParameters correctionsParameters,
boolean enableSave,
boolean enableShow){
saveAndShow(
imp,
correctionsParameters,
correctionsParameters.save && enableSave,
correctionsParameters.show && enableShow,
correctionsParameters.JPEG_quality);
}
void saveAndShow(
......@@ -2300,35 +2350,96 @@ public class EyesisCorrections {
}
void saveAndShow(
ImagePlus imp,
EyesisCorrectionParameters.CorrectionParameters correctionsParameters,
boolean save,
boolean show,
int jpegQuality){// <0 - keep current, 0 - force Tiff, >0 use for JPEG
String path=null;
if (save) path= correctionsParameters.selectResultsDirectory(
true, // smart,
true); //newAllowed, // save
if (path!=null) {
path+=Prefs.getFileSeparator()+imp.getTitle();
if (((imp.getStackSize()==1)) && (jpegQuality!=0) && ((imp.getFileInfo().fileType== FileInfo.RGB) || (jpegQuality>0))) {
if (this.debugLevel>0) System.out.println("Saving result to "+path+".jpeg");
FileSaver fs=new FileSaver(imp);
if (jpegQuality>0) FileSaver.setJpegQuality(jpegQuality);
fs.saveAsJpeg(path+".jpeg");
}
else {
if (this.debugLevel>0) System.out.println("Saving result to "+path+".tiff");
FileSaver fs=new FileSaver(imp);
if (imp.getStackSize()>1) fs.saveAsTiffStack(path+".tiff");
else fs.saveAsTiff(path+".tiff");
}
}
if (show) {
imp.getProcessor().resetMinAndMax(); // probably not needed
imp.show();
}
ImagePlus imp,
EyesisCorrectionParameters.CorrectionParameters correctionsParameters,
boolean save,
boolean show,
int jpegQuality){// <0 - keep current, 0 - force Tiff, >0 use for JPEG
String path=null;
if (save) path= correctionsParameters.selectResultsDirectory(
true, // smart,
true); //newAllowed, // save
if (path!=null) {
path+=Prefs.getFileSeparator()+imp.getTitle();
boolean hasAlphaHighByte = false;
if ((imp.getStackSize()==1) && (imp.getFileInfo().fileType== FileInfo.RGB)) {
int [] pixels = (int []) imp.getProcessor().getPixels();
for (int i = 0; i < pixels.length; i++){
if ((pixels[i] & 0xff000000) != 0){
hasAlphaHighByte = true;
break;
}
}
}
if (hasAlphaHighByte){
if (correctionsParameters.png){
if (this.debugLevel > 0) System.out.println("Saving RGBA result to "+path+".png");
(new EyesisTiff()).savePNG_ARGB32(
imp,
path+".png"
);
} else {
if (this.debugLevel > 0) System.out.println("Saving RGBA result to "+path+".tiff");
try {
(new EyesisTiff()).saveTiffARGB32(
imp,
path+".tiff",
false, // correctionsParameters.imageJTags,
debugLevel);
} catch (IOException e) {
e.printStackTrace();
} catch (FormatException e) {
e.printStackTrace();
} catch (ServiceException e) {
e.printStackTrace();
} catch (DependencyException e) {
e.printStackTrace();
}
}
} else if (((imp.getStackSize()==1)) && (jpegQuality!=0) && ((imp.getFileInfo().fileType== FileInfo.RGB) || (jpegQuality>0))) {
if (this.debugLevel>0) System.out.println("Saving result to "+path+".jpeg");
FileSaver fs=new FileSaver(imp);
if (jpegQuality>0) FileSaver.setJpegQuality(jpegQuality);
fs.saveAsJpeg(path+".jpeg");
} else {
if (this.debugLevel>0) System.out.println("Saving result to "+path+".tiff");
FileSaver fs=new FileSaver(imp);
// Save as RGBA if it is RGBA
int bytesPerPixel = imp.getBytesPerPixel();
int mode = 0;
if (bytesPerPixel > 1) mode = 1;
if (bytesPerPixel > 3) mode = 3;// float, mode 2 not supported
if ((imp.getStackSize() == 4) && imp.getStack().getSliceLabel(4).equals("alpha")){
try {
(new EyesisTiff()).saveTiff(
imp,
path+".tiff",
mode, //
1.0, // full scale, absolute
false, // correctionsParameters.imageJTags,
debugLevel);
} catch (IOException e) {
e.printStackTrace();
} catch (FormatException e) {
e.printStackTrace();
} catch (ServiceException e) {
e.printStackTrace();
} catch (DependencyException e) {
e.printStackTrace();
}
} else if (imp.getStackSize()>1) fs.saveAsTiffStack(path+".tiff");
else fs.saveAsTiff(path+".tiff");
}
}
if (show) {
imp.getProcessor().resetMinAndMax(); // probably not needed
imp.show();
}
}
/*
private void saveAndShow(
......
......@@ -23,17 +23,25 @@
*/
import java.util.ArrayList;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicInteger;
import ij.CompositeImage;
import ij.IJ;
import ij.ImagePlus;
import ij.ImageStack;
import ij.Prefs;
import ij.io.FileSaver;
import ij.process.ByteProcessor;
import ij.process.ColorProcessor;
import ij.process.ImageProcessor;
public class EyesisDCT {
static String [] fine_corr_coeff_names = {"A","B","C","D","E","F"};
static String [] fine_corr_dir_names = {"X","Y"};
static String prefix = "EYESIS_DCT.";
public Properties properties = null;
public EyesisCorrections eyesisCorrections = null;
public EyesisCorrectionParameters.CorrectionParameters correctionsParameters=null;
public EyesisCorrectionParameters.DCTParameters dctParameters = null;
......@@ -43,16 +51,56 @@ public class EyesisDCT {
public int extra_items = 8; // number of extra items saved with kernels (center offset (partial, full, derivatives)
public ImagePlus eyesisKernelImage = null;
public long startTime;
public double [][][] fine_corr = new double [4][2][6]; // per port, per x/y, set of 6 coefficient for fine geometric corrections
public ArrayList <CLTPass3d> clt_3d_passes = null;
public int tilesX;
public int tilesY;
static int DISPARITY_INDEX_CM = 2; // index of disparity value in disparity_map == 2 (0,2 or 4)
static int DISPARITY_INDEX_POLY = 4; // index of disparity value in disparity_map == 2 (0,2 or 4)
static int STRENGTH_INDEX = 6; // index of strength data in disparity map ==6
static int IMG_DIFF0_INDEX = 8; // index of noise- normalized image difference for port 0 in disparity map
public EyesisDCT(
EyesisCorrections eyesisCorrections,
Properties properties,
EyesisCorrections eyesisCorrections,
EyesisCorrectionParameters.CorrectionParameters correctionsParameters,
EyesisCorrectionParameters.DCTParameters dctParameters
EyesisCorrectionParameters.DCTParameters dctParameters
){
this.eyesisCorrections= eyesisCorrections;
this.eyesisCorrections= eyesisCorrections;
this.correctionsParameters = correctionsParameters;
this.dctParameters= dctParameters;
this.dctParameters= dctParameters;
this.properties = properties;
getProperties();
}
// TODO:Add saving just calibration
public void setProperties(){
for (int n = 0; n < fine_corr.length; n++){
for (int d = 0; d < fine_corr[n].length; d++){
for (int i = 0; i < fine_corr[n][d].length; i++){
String name = prefix+"fine_corr_"+n+fine_corr_dir_names[d]+fine_corr_coeff_names[i];
properties.setProperty(name, this.fine_corr[n][d][i]+"");
}
}
}
}
public void getProperties(){
for (int n = 0; n < fine_corr.length; n++){
for (int d = 0; d < fine_corr[n].length; d++){
for (int i = 0; i < fine_corr[n][d].length; i++){
String name = prefix+"fine_corr_"+n+fine_corr_dir_names[d]+fine_corr_coeff_names[i];
if (properties.getProperty(name)!=null) this.fine_corr[n][d][i]=Double.parseDouble(properties.getProperty(name));
}
}
}
}
public class DCTKernels{
// -- old --
public int size = 32; // kernel (DCT) size
......@@ -2156,7 +2204,8 @@ public class EyesisDCT {
title+"-RGB24",
0, 65536, // r range 0->0, 65536->256
0, 65536, // g range
0, 65536);// b range
0, 65536,// b range
0, 65536);// alpha range
if (JPEG_scale!=1.0){
ImageProcessor ip=imp_RGB.getProcessor();
ip.setInterpolationMethod(ImageProcessor.BICUBIC);
......@@ -3216,7 +3265,8 @@ public class EyesisDCT {
title+"-RGB24",
0, 65536, // r range 0->0, 65536->256
0, 65536, // g range
0, 65536);// b range
0, 65536,// b range
0, 65536);// alpha range
if (JPEG_scale!=1.0){
ImageProcessor ip=imp_RGB.getProcessor();
ip.setInterpolationMethod(ImageProcessor.BICUBIC);
......@@ -3911,7 +3961,8 @@ public class EyesisDCT {
title+"-RGB24",
0, 65536, // r range 0->0, 65536->256
0, 65536, // g range
0, 65536);// b range
0, 65536,// b range
0, 65536);// alpha range
if (JPEG_scale!=1.0){
ImageProcessor ip=imp_RGB.getProcessor();
ip.setInterpolationMethod(ImageProcessor.BICUBIC);
......@@ -4445,7 +4496,8 @@ public class EyesisDCT {
title+"-RGB24",
0, 65536, // r range 0->0, 65536->256
0, 65536, // g range
0, 65536);// b range
0, 65536,// b range
0, 65536);// alpha range
if (JPEG_scale!=1.0){
ImageProcessor ip=imp_RGB.getProcessor();
ip.setInterpolationMethod(ImageProcessor.BICUBIC);
......@@ -4473,6 +4525,7 @@ public class EyesisDCT {
EyesisCorrectionParameters.RGBParameters rgbParameters,
EyesisCorrectionParameters.EquirectangularParameters equirectangularParameters,
int convolveFFTSize, // 128 - fft size, kernel size should be size/2
final boolean apply_corr, // calculate and apply additional fine geometry correction
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
final int debugLevel)
......@@ -4549,7 +4602,7 @@ public class EyesisDCT {
}
ImagePlus [] imp_srcs = new ImagePlus[channelFiles.length];
double [] scaleExposures = new double[channelFiles.length];
double [] scaleExposures = new double[channelFiles.length]; //
for (int srcChannel=0; srcChannel<channelFiles.length; srcChannel++){
int nFile=channelFiles[srcChannel];
imp_srcs[srcChannel]=null;
......@@ -4679,6 +4732,7 @@ public class EyesisDCT {
rgbParameters,
convolveFFTSize, // 128 - fft size, kernel size should be size/2
scaleExposures,
apply_corr, // calculate and apply additional fine geometry correction
threadsMax, // maximal number of threads to launch
updateStatus,
debugLevel);
......@@ -4774,20 +4828,21 @@ public class EyesisDCT {
EyesisCorrectionParameters.RGBParameters rgbParameters,
int convolveFFTSize, // 128 - fft size, kernel size should be size/2
double [] scaleExposures, // probably not needed here
final boolean apply_corr, // calculate and apply additional fine geometry correction
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
final int debugLevel){
boolean advanced=this.correctionsParameters.zcorrect || this.correctionsParameters.equirectangular;
// boolean crop= advanced? true: this.correctionsParameters.crop;
boolean rotate= advanced? false: this.correctionsParameters.rotate;
double JPEG_scale= advanced? 1.0: this.correctionsParameters.JPEG_scale;
// boolean rotate= advanced? false: this.correctionsParameters.rotate;
// double JPEG_scale= advanced? 1.0: this.correctionsParameters.JPEG_scale;
boolean toRGB= advanced? true: this.correctionsParameters.toRGB;
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
// may use this.StartTime to report intermediate steps execution times
String name=(String) imp_quad[0].getProperty("name");
// int channel= Integer.parseInt((String) imp_src.getProperty("channel"));
int channel= (Integer) imp_quad[0].getProperty("channel");
// int channel= (Integer) imp_quad[0].getProperty("channel");
String path= (String) imp_quad[0].getProperty("path");
ImagePlus [] results = new ImagePlus[imp_quad.length];
......@@ -4804,7 +4859,7 @@ public class EyesisDCT {
}
// String [] rbg_titles = {"Red", "Blue", "Green"};
ImageStack stack;
// ImageStack stack;
// =================
ImageDtt image_dtt = new ImageDtt();
for (int i = 0; i < double_stacks.length; i++){
......@@ -4813,40 +4868,13 @@ public class EyesisDCT {
}
}
int tilesY = imp_quad[0].getHeight()/clt_parameters.transform_size;
int tilesX = imp_quad[0].getWidth()/clt_parameters.transform_size;
tilesY = imp_quad[0].getHeight()/clt_parameters.transform_size;
tilesX = imp_quad[0].getWidth()/clt_parameters.transform_size;
// temporary setting up tile task file (one integer per tile, bitmask
// for testing defined for a window, later the tiles to process will be calculated based on previous passes results
int [][] tile_op = new int [tilesY][tilesX]; // all zero
int txl = clt_parameters.tile_task_wl;
int txr = txl + clt_parameters.tile_task_ww;
int tyt = clt_parameters.tile_task_wt;
int tyb = tyt + clt_parameters.tile_task_wh;
if (txl < 0) txl = 0;
else if (txl >= tilesX) txl = tilesX - 1;
if (txr <= txl) txr = txl + 1;
else if (txr > tilesX) txr = tilesX;
if (tyt < 0) tyt = 0;
else if (tyt >= tilesY) tyt = tilesY - 1;
if (tyb <= tyt) tyb = tyt + 1;
else if (tyb > tilesY) tyb = tilesY;
for (int i = tyt; i < tyb; i++) {
for (int j = txl; j < txr; j++) {
tile_op[i][j] = clt_parameters.tile_task_op;
}
}
if (debugLevel > -1){
System.out.println("clt_parameters.tile_task_wl="+clt_parameters.tile_task_wl );
System.out.println("clt_parameters.tile_task_wt="+clt_parameters.tile_task_wt );
System.out.println("clt_parameters.tile_task_ww="+clt_parameters.tile_task_ww );
System.out.println("clt_parameters.tile_task_wh="+clt_parameters.tile_task_wh );
System.out.println("tyt="+tyt+" tyb="+tyb+" txl="+txl+" txr="+txr );
}
int [][] tile_op = setSameTileOp(clt_parameters, clt_parameters.tile_task_op, debugLevel);
double [][] disparity_array =setSameDisparity(0.0); // [tilesY][tilesX] - individual per-tile expected disparity
//TODO: Add array of default disparity - use for combining images in force disparity mode (no correlation), when disparity is predicted from other tiles
......@@ -4873,11 +4901,12 @@ public class EyesisDCT {
}
}
}
if (clt_parameters.corr_mismatch){
if (clt_parameters.corr_mismatch || apply_corr){
clt_mismatch = new double [12][];
}
}
double [][] disparity_map = new double [8][]; //[0] -residual disparity, [1] - orthogonal (just for debugging)
// double [][] disparity_map = new double [8][]; //[0] -residual disparity, [1] - orthogonal (just for debugging)
double [][] disparity_map = new double [12][]; //[0] -residual disparity, [1] - orthogonal (just for debugging) last 4 - max pixel differences
double min_corr_selected = clt_parameters.corr_normalize? clt_parameters.min_corr_normalized: clt_parameters.min_corr;
double [][] shiftXY = {
......@@ -4885,9 +4914,10 @@ public class EyesisDCT {
{clt_parameters.fine_corr_x_1,clt_parameters.fine_corr_y_1},
{clt_parameters.fine_corr_x_2,clt_parameters.fine_corr_y_2},
{clt_parameters.fine_corr_x_3,clt_parameters.fine_corr_y_3}};
double [][][][][][] clt_data = image_dtt.clt_aberrations_quad_corr(
tile_op, // per-tile operation bit codes
clt_parameters.disparity, // final double disparity,
disparity_array, // final double disparity,
double_stacks, // final double [][][] imade_data, // first index - number of image in a quad
// correlation results - final and partial
clt_corr_combo, // [tilesY][tilesX][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate
......@@ -4914,6 +4944,7 @@ public class EyesisDCT {
clt_parameters.diff_threshold, // 5.0; // RMS difference from average to discard channel (~ 1.0 - 1/255 full scale image)
clt_parameters.diff_gauss, // true; // when averaging images, use gaussian around average as weight (false - sharp all/nothing)
clt_parameters.min_agree, // 3.0; // minimal number of channels to agree on a point (real number to work with fuzzy averages)
clt_parameters.dust_remove, // Do not reduce average weight when only one image differes much from the average
clt_parameters.keep_weights, // Add port weights to RGBA stack (debug feature)
geometryCorrection, // final GeometryCorrection geometryCorrection,
clt_kernels, // final double [][][][][][] clt_kernels, // [channel_in_quad][color][tileY][tileX][band][pixel] , size should match image (have 1 tile around)
......@@ -4921,6 +4952,9 @@ public class EyesisDCT {
clt_parameters.transform_size,
clt_parameters.clt_window,
shiftXY, //
(clt_parameters.fcorr_ignore? null: this.fine_corr),
clt_parameters.corr_magic_scale, // stil not understood coefficent that reduces reported disparity value. Seems to be around 8.5
clt_parameters.shift_x, // final int shiftX, // shift image horizontally (positive - right) - just for testing
clt_parameters.shift_y, // final int shiftY, // shift image vertically (positive - down)
clt_parameters.tileX, // final int debug_tileX,
......@@ -4960,7 +4994,8 @@ public class EyesisDCT {
(clt_parameters.keep_weights?rgba_weights_titles:rgba_titles));
}
if (clt_parameters.show_overlap){
if (clt_parameters.show_overlap || clt_parameters.show_rgba_color){
int alpha_index = 3;
texture_overlap = image_dtt.combineRGBATiles(
texture_tiles, // array [tilesY][tilesX][4][4*transform_size] or [tilesY][tilesX]{null}
clt_parameters.transform_size,
......@@ -4968,22 +5003,55 @@ public class EyesisDCT {
clt_parameters.sharp_alpha, // combining mode for alpha channel: false - treat as RGB, true - apply center 8x8 only
threadsMax, // maximal number of threads to launch
debugLevel);
sdfa_instance.showArrays(
texture_overlap,
tilesX * clt_parameters.transform_size,
tilesY * clt_parameters.transform_size,
true,
name + "-TXTOL-D"+clt_parameters.disparity,
(clt_parameters.keep_weights?rgba_weights_titles:rgba_titles));
if (clt_parameters.alpha1 > 0){ // negative or 0 - keep alpha as it was
double scale = (clt_parameters.alpha1 > clt_parameters.alpha0) ? (1.0/(clt_parameters.alpha1 - clt_parameters.alpha0)) : 0.0;
for (int i = 0; i < texture_overlap[alpha_index].length; i++){
double d = texture_overlap[alpha_index][i];
if (d >=clt_parameters.alpha1) d = 1.0;
else if (d <=clt_parameters.alpha0) d = 0.0;
else d = scale * (d- clt_parameters.alpha0);
texture_overlap[alpha_index][i] = d;
}
}
if (clt_parameters.show_overlap) {
sdfa_instance.showArrays(
texture_overlap,
tilesX * clt_parameters.transform_size,
tilesY * clt_parameters.transform_size,
true,
name + "-TXTOL-D"+clt_parameters.disparity,
(clt_parameters.keep_weights?rgba_weights_titles:rgba_titles));
}
if (clt_parameters.show_rgba_color) {
// for now - use just RGB. Later add oprion for RGBA
double [][] texture_rgb = {texture_overlap[0],texture_overlap[1],texture_overlap[2]};
double [][] texture_rgba = {texture_overlap[0],texture_overlap[1],texture_overlap[2],texture_overlap[3]};
// ImagePlus img_texture =
linearStackToColor(
clt_parameters,
colorProcParameters,
rgbParameters,
name+"-texture", // String name,
"-D"+clt_parameters.disparity, //String suffix, // such as disparity=...
toRGB,
!this.correctionsParameters.jpeg, // boolean bpp16, // 16-bit per channel color mode for result
true, // boolean saveShowIntermediate, // save/show if set globally
true, // boolean saveShowFinal, // save/show result (color image?)
((clt_parameters.alpha1 > 0)? texture_rgba: texture_rgb),
tilesX,
tilesY,
1.0, // double scaleExposure, // is it needed?
debugLevel );
}
}
}
// visualize correlation results
if (clt_corr_combo!=null){
if (disparity_map != null){
if (debugLevel > -1){
if (clt_parameters.show_map){
String [] disparity_titles = {"int_disparity", "int_disp_ortho","cm_disparity", "cm_disp_ortho","poly_disparity", "poly_disp_ortho",
"strength", "variety"};
"strength", "variety","maxdiff0","maxdiff1","maxdiff2","maxdiff3"};
sdfa_instance.showArrays(
disparity_map,
tilesX,
......@@ -5004,11 +5072,24 @@ public class EyesisDCT {
true,
name+"-MISMATCH_XYW-D"+clt_parameters.disparity,
disparity_titles);
}
}
if (apply_corr && (disparity_map != null)){
System.out.println("=== applying geometry correction coefficients ===");
double [][][] new_corr = fine_geometry_correction(
clt_parameters,
disparity_map,
clt_mismatch,
tilesX,
clt_parameters.corr_magic_scale, // stil not understood coefficent that reduces reported disparity value. Seems to be around 8.5
debugLevel); // int debugLevel)
apply_fine_corr(
new_corr,
debugLevel + 1);
}
}
if (debugLevel > -1){
if (clt_parameters.corr_show){
double [][] corr_rslt = new double [clt_corr_combo.length][];
String [] titles = {"combo","sum"};
for (int i = 0; i<corr_rslt.length; i++) {
......@@ -5029,8 +5110,8 @@ public class EyesisDCT {
titles );
}
if (debugLevel > -1){ // -1
if (clt_corr_partial!=null){
if (clt_corr_partial!=null){
if (debugLevel > -1){ // -1
String [] allColorNames = {"red","blue","green","combo"};
String [] titles = new String[clt_corr_partial.length];
for (int i = 0; i < titles.length; i++){
......@@ -5055,12 +5136,12 @@ public class EyesisDCT {
}
}
if (clt_parameters.gen_chn_img) {
if (clt_parameters.gen_chn_img || clt_parameters.gen_chn_stacks) {
ImagePlus [] imps_RGB = new ImagePlus[clt_data.length];
for (int iQuad = 0; iQuad < clt_data.length; iQuad++){
String title=name+"-"+String.format("%02d", iQuad);
String titleFull=title+"-SPLIT-D"+clt_parameters.disparity;
// String titleFull=title+"-SPLIT-D"+clt_parameters.disparity;
if (clt_parameters.corr_sigma > 0){ // no filter at all
for (int chn = 0; chn < clt_data[iQuad].length; chn++) {
......@@ -5109,277 +5190,508 @@ public class EyesisDCT {
debugLevel);
}
if (debugLevel > -1) sdfa_instance.showArrays(iclt_data,
if (clt_parameters.gen_chn_stacks) sdfa_instance.showArrays(iclt_data,
(tilesX + 0) * clt_parameters.transform_size,
(tilesY + 0) * clt_parameters.transform_size,
true,
results[iQuad].getTitle()+"-ICLT-RGB-D"+clt_parameters.disparity);
// convert to ImageStack of 3 slices
String [] sliceNames = {"red", "blue", "green"};
stack = sdfa_instance.makeStack(
iclt_data,
(tilesX + 0) * clt_parameters.transform_size,
(tilesY + 0) * clt_parameters.transform_size,
sliceNames); // or use null to get chn-nn slice names
if (debugLevel > -1){
double [] chn_avg = {0.0,0.0,0.0};
float [] pixels;
int width = stack.getWidth();
int height = stack.getHeight();
for (int c = 0; c <3; c++){
pixels = (float[]) stack.getPixels(c+1);
for (int i = 0; i<pixels.length; i++){
chn_avg[c] += pixels[i];
}
}
chn_avg[0] /= width*height;
chn_avg[1] /= width*height;
chn_avg[2] /= width*height;
System.out.println("Processed channels averages: R="+chn_avg[0]+", G="+chn_avg[2]+", B="+chn_avg[1]);
}
if (!this.correctionsParameters.colorProc){
results[iQuad]= new ImagePlus(titleFull, stack);
eyesisCorrections.saveAndShow(
results[iQuad],
this.correctionsParameters);
continue; // return results;
}
if (debugLevel > 1) System.out.println("before colors.1");
//Processing colors - changing stack sequence to r-g-b (was r-b-g)
if (!eyesisCorrections.fixSliceSequence(
stack,
debugLevel)){
if (debugLevel > -1) System.out.println("fixSliceSequence() returned false");
return null;
}
if (debugLevel > 1) System.out.println("before colors.2");
if (debugLevel > 1){
ImagePlus imp_dbg=new ImagePlus(imp_quad[iQuad].getTitle()+"-"+channel+"-preColors",stack);
eyesisCorrections.saveAndShow(
imp_dbg,
this.correctionsParameters);
}
if (debugLevel > 1) System.out.println("before colors.3, scaleExposure="+scaleExposures[iQuad]+" scale = "+(255.0/eyesisCorrections.psfSubpixelShouldBe4/eyesisCorrections.psfSubpixelShouldBe4/scaleExposures[iQuad]));
CorrectionColorProc correctionColorProc=new CorrectionColorProc(eyesisCorrections.stopRequested);
double [][] yPrPb=new double [3][];
// if (dct_parameters.color_DCT){
// need to get YPbPr - not RGB here
// } else {
correctionColorProc.processColorsWeights(stack, // just gamma convert? TODO: Cleanup? Convert directly form the linear YPrPb
// 255.0/this.psfSubpixelShouldBe4/this.psfSubpixelShouldBe4, // double scale, // initial maximal pixel value (16))
// 255.0/eyesisCorrections.psfSubpixelShouldBe4/eyesisCorrections.psfSubpixelShouldBe4/scaleExposure, // double scale, // initial maximal pixel value (16))
// 255.0/2/2/scaleExposure, // double scale, // initial maximal pixel value (16))
255.0/scaleExposures[iQuad], // double scale, // initial maximal pixel value (16))
if (!clt_parameters.gen_chn_img) continue;
imps_RGB[iQuad] = linearStackToColor(
clt_parameters,
colorProcParameters,
channelGainParameters,
channel,
null, //correctionDenoise.getDenoiseMask(),
this.correctionsParameters.blueProc,
debugLevel);
if (debugLevel > 1) System.out.println("Processed colors to YPbPr, total number of slices="+stack.getSize());
if (debugLevel > 1) {
ImagePlus imp_dbg=new ImagePlus("procColors",stack);
eyesisCorrections.saveAndShow(
imp_dbg,
this.correctionsParameters);
}
float [] fpixels;
int [] slices_YPrPb = {8,6,7};
yPrPb=new double [3][];
for (int n = 0; n < slices_YPrPb.length; n++){
fpixels = (float[]) stack.getPixels(slices_YPrPb[n]);
yPrPb[n] = new double [fpixels.length];
for (int i = 0; i < fpixels.length; i++) yPrPb[n][i] = fpixels[i];
}
if (toRGB) {
System.out.println("correctionColorProc.YPrPbToRGB");
stack = YPrPbToRGB(yPrPb,
colorProcParameters.kr, // 0.299;
colorProcParameters.kb, // 0.114;
stack.getWidth());
title=titleFull; // including "-DECONV" or "-COMBO"
titleFull=title+"-RGB-float-D"+clt_parameters.disparity;
//Trim stack to just first 3 slices
if (debugLevel > 1){ // 2){
ImagePlus imp_dbg=new ImagePlus("YPrPbToRGB",stack);
eyesisCorrections.saveAndShow(
imp_dbg,
this.correctionsParameters);
rgbParameters,
title, // String name,
"-D"+clt_parameters.disparity, //String suffix, // such as disparity=...
toRGB,
!this.correctionsParameters.jpeg, // boolean bpp16, // 16-bit per channel color mode for result
true, // boolean saveShowIntermediate, // save/show if set globally
false, // boolean saveShowFinal, // save/show result (color image?)
iclt_data,
tilesX,
tilesY,
scaleExposures[iQuad], // double scaleExposure, // is it needed?
debugLevel );
} // end of generating shifted channel images
if (clt_parameters.gen_chn_img) {
// combine to a sliced color image
int [] slice_seq = {0,1,3,2}; //clockwise
int width = imps_RGB[0].getWidth();
int height = imps_RGB[0].getHeight();
ImageStack array_stack=new ImageStack(width,height);
for (int i = 0; i<slice_seq.length; i++){
if (imps_RGB[slice_seq[i]] != null) {
array_stack.addSlice("port_"+slice_seq[i], imps_RGB[slice_seq[i]].getProcessor().getPixels());
} else {
array_stack.addSlice("port_"+slice_seq[i], results[slice_seq[i]].getProcessor().getPixels());
}
while (stack.getSize() > 3) stack.deleteLastSlice();
if (debugLevel > 1) System.out.println("Trimming color stack");
} else {
title=titleFull; // including "-DECONV" or "-COMBO"
titleFull=title+"-YPrPb-D"+clt_parameters.disparity; // including "-DECONV" or "-COMBO"
if (debugLevel > 1) System.out.println("Using full stack, including YPbPr");
}
results[iQuad]= new ImagePlus(titleFull, stack);
// rotate the result
if (rotate){ // never rotate for equirectangular
stack=eyesisCorrections.rotateStack32CW(stack);
}
if (!toRGB && !this.correctionsParameters.jpeg){ // toRGB set for equirectangular
if (debugLevel > 1) System.out.println("!toRGB && !this.correctionsParameters.jpeg");
eyesisCorrections.saveAndShow(results[iQuad], this.correctionsParameters);
continue; // return result;
} else { // that's not the end result, save if required
if (debugLevel > 1) System.out.println("!toRGB && !this.correctionsParameters.jpeg - else");
eyesisCorrections.saveAndShow(results[iQuad],
eyesisCorrections.correctionsParameters,
eyesisCorrections.correctionsParameters.save32,
false,
eyesisCorrections.correctionsParameters.JPEG_quality); // save, no show
}
// convert to RGB48 (16 bits per color component)
// ImagePlus imp_RGB;
stack=eyesisCorrections.convertRGB32toRGB16Stack(
stack,
rgbParameters);
titleFull=title+"-RGB48-D"+clt_parameters.disparity;
results[iQuad]= new ImagePlus(titleFull, stack);
// ImagePlus imp_RGB24;
results[iQuad].updateAndDraw();
if (debugLevel > 1) System.out.println("result.updateAndDraw(), "+titleFull+"-RGB48");
CompositeImage compositeImage=eyesisCorrections.convertToComposite(results[iQuad]);
if (!this.correctionsParameters.jpeg && !advanced){ // RGB48 was the end result
if (debugLevel > 1) System.out.println("if (!this.correctionsParameters.jpeg && !advanced)");
eyesisCorrections.saveAndShow(compositeImage, this.correctionsParameters);
continue; // return result;
} else { // that's not the end result, save if required
if (debugLevel > 1) System.out.println("if (!this.correctionsParameters.jpeg && !advanced) - else");
eyesisCorrections.saveAndShow(compositeImage, this.correctionsParameters, this.correctionsParameters.save16, false); // save, no show
// eyesisCorrections.saveAndShow(compositeImage, this.correctionsParameters, this.correctionsParameters.save16, true); // save, no show
}
imps_RGB[iQuad]=eyesisCorrections.convertRGB48toRGB24(
stack,
title+"-RGB24-D"+clt_parameters.disparity,
0, 65536, // r range 0->0, 65536->256
0, 65536, // g range
0, 65536);// b range
if (JPEG_scale!=1.0){
ImageProcessor ip=imps_RGB[iQuad].getProcessor();
ip.setInterpolationMethod(ImageProcessor.BICUBIC);
ip=ip.resize((int)(ip.getWidth()*JPEG_scale),(int) (ip.getHeight()*JPEG_scale));
imps_RGB[iQuad]= new ImagePlus(imps_RGB[iQuad].getTitle(),ip);
imps_RGB[iQuad].updateAndDraw();
}
if (iQuad <0) eyesisCorrections.saveAndShow(imps_RGB[iQuad], this.correctionsParameters); // individual images (just commented out)
} // and generating shifted channle images
// combine to a sliced color image
int [] slice_seq = {0,1,3,2}; //clockwise
int width = imps_RGB[0].getWidth();
int height = imps_RGB[0].getHeight();
ImageStack array_stack=new ImageStack(width,height);
for (int i = 0; i<slice_seq.length; i++){
if (imps_RGB[slice_seq[i]] != null) {
array_stack.addSlice("port_"+slice_seq[i], imps_RGB[slice_seq[i]].getProcessor().getPixels());
} else {
array_stack.addSlice("port_"+slice_seq[i], results[slice_seq[i]].getProcessor().getPixels());
}
ImagePlus imp_stack = new ImagePlus(name+"-SHIFTED-D"+clt_parameters.disparity, array_stack);
imp_stack.getProcessor().resetMinAndMax();
imp_stack.updateAndDraw();
//imp_stack.getProcessor().resetMinAndMax();
//imp_stack.show();
eyesisCorrections.saveAndShow(imp_stack, this.correctionsParameters);
}
ImagePlus imp_stack = new ImagePlus(name+"-SHIFTED-D"+clt_parameters.disparity, array_stack);
imp_stack.getProcessor().resetMinAndMax();
imp_stack.updateAndDraw();
//imp_stack.getProcessor().resetMinAndMax();
//imp_stack.show();
eyesisCorrections.saveAndShow(imp_stack, this.correctionsParameters);
}
return results;
}
public void cltDisparityScans(
EyesisCorrectionParameters.CLTParameters clt_parameters,
EyesisCorrectionParameters.DebayerParameters debayerParameters,
EyesisCorrectionParameters.NonlinParameters nonlinParameters,
EyesisCorrectionParameters.ColorProcParameters colorProcParameters,
CorrectionColorProc.ColorGainsParameters channelGainParameters,
EyesisCorrectionParameters.RGBParameters rgbParameters,
EyesisCorrectionParameters.EquirectangularParameters equirectangularParameters,
int convolveFFTSize, // 128 - fft size, kernel size should be size/2
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
final int debugLevel)
public ImagePlus linearStackToColor(
EyesisCorrectionParameters.CLTParameters clt_parameters,
EyesisCorrectionParameters.ColorProcParameters colorProcParameters,
EyesisCorrectionParameters.RGBParameters rgbParameters,
String name,
String suffix, // such as disparity=...
boolean toRGB,
boolean bpp16, // 16-bit per channel color mode for result
boolean saveShowIntermediate, // save/show if set globally
boolean saveShowFinal, // save/show result (color image?)
double [][] iclt_data,
int tilesX,
int tilesY,
double scaleExposure,
int debugLevel
)
{
this.startTime=System.nanoTime();
String [] sourceFiles=correctionsParameters.getSourcePaths();
boolean [] enabledFiles=new boolean[sourceFiles.length];
for (int i=0;i<enabledFiles.length;i++) enabledFiles[i]=false;
int numFilesToProcess=0;
int numImagesToProcess=0;
for (int nFile=0;nFile<enabledFiles.length;nFile++){
if ((sourceFiles[nFile]!=null) && (sourceFiles[nFile].length()>1)) {
int [] channels={correctionsParameters.getChannelFromSourceTiff(sourceFiles[nFile])};
if (correctionsParameters.isJP4()){
int subCamera= channels[0]- correctionsParameters.firstSubCamera; // to match those in the sensor files
// removeUnusedSensorData should be off!?
channels=this.eyesisCorrections.pixelMapping.channelsForSubCamera(subCamera);
}
if (channels!=null){
for (int i=0;i<channels.length;i++) if (eyesisCorrections.isChannelEnabled(channels[i])){
if (!enabledFiles[nFile]) numFilesToProcess++;
enabledFiles[nFile]=true;
numImagesToProcess++;
}
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
// convert to ImageStack of 3 slices
String [] sliceNames = {"red", "blue", "green"};
double [] alpha = null; // (0..1.0)
double [][] rgb_in = {iclt_data[0],iclt_data[1],iclt_data[2]};
if (iclt_data.length > 3) alpha = iclt_data[3];
ImageStack stack = sdfa_instance.makeStack(
rgb_in, // iclt_data,
(tilesX + 0) * clt_parameters.transform_size,
(tilesY + 0) * clt_parameters.transform_size,
sliceNames); // or use null to get chn-nn slice names
if (debugLevel > -1){
double [] chn_avg = {0.0,0.0,0.0};
float [] pixels;
int width = stack.getWidth();
int height = stack.getHeight();
for (int c = 0; c <3; c++){
pixels = (float[]) stack.getPixels(c+1);
for (int i = 0; i<pixels.length; i++){
chn_avg[c] += pixels[i];
}
}
chn_avg[0] /= width*height;
chn_avg[1] /= width*height;
chn_avg[2] /= width*height;
System.out.println("Processed channels averages: R="+chn_avg[0]+", G="+chn_avg[2]+", B="+chn_avg[1]);
}
if (numFilesToProcess==0){
System.out.println("No files to process (of "+sourceFiles.length+")");
return;
if (debugLevel > 1) System.out.println("before colors.1");
//Processing colors - changing stack sequence to r-g-b (was r-b-g)
if (!eyesisCorrections.fixSliceSequence(
stack,
debugLevel)){
if (debugLevel > -1) System.out.println("fixSliceSequence() returned false");
return null;
}
if (debugLevel > 1) System.out.println("before colors.2");
if (saveShowIntermediate && (debugLevel > 1)){
ImagePlus imp_dbg=new ImagePlus(name+"-preColors",stack);
eyesisCorrections.saveAndShow(
imp_dbg,
this.correctionsParameters);
}
if (debugLevel > 1) System.out.println("before colors.3, scaleExposure="+scaleExposure+" scale = "+(255.0/eyesisCorrections.psfSubpixelShouldBe4/eyesisCorrections.psfSubpixelShouldBe4/scaleExposure));
CorrectionColorProc correctionColorProc=new CorrectionColorProc(eyesisCorrections.stopRequested);
double [][] yPrPb=new double [3][];
// if (dct_parameters.color_DCT){
// need to get YPbPr - not RGB here
// } else {
correctionColorProc.processColorsWeights(stack, // just gamma convert? TODO: Cleanup? Convert directly form the linear YPrPb
// 255.0/this.psfSubpixelShouldBe4/this.psfSubpixelShouldBe4, // double scale, // initial maximal pixel value (16))
// 255.0/eyesisCorrections.psfSubpixelShouldBe4/eyesisCorrections.psfSubpixelShouldBe4/scaleExposure, // double scale, // initial maximal pixel value (16))
// 255.0/2/2/scaleExposure, // double scale, // initial maximal pixel value (16))
255.0/scaleExposure, // double scale, // initial maximal pixel value (16))
colorProcParameters,
null, // channelGainParameters,
-1, // channel,
null, //correctionDenoise.getDenoiseMask(),
this.correctionsParameters.blueProc,
debugLevel);
if (debugLevel > 1) System.out.println("Processed colors to YPbPr, total number of slices="+stack.getSize());
if (saveShowIntermediate && (debugLevel > 1)) {
ImagePlus imp_dbg=new ImagePlus("procColors",stack);
eyesisCorrections.saveAndShow(
imp_dbg,
this.correctionsParameters);
}
float [] fpixels;
int [] slices_YPrPb = {8,6,7};
yPrPb=new double [3][];
for (int n = 0; n < slices_YPrPb.length; n++){
fpixels = (float[]) stack.getPixels(slices_YPrPb[n]);
yPrPb[n] = new double [fpixels.length];
for (int i = 0; i < fpixels.length; i++) yPrPb[n][i] = fpixels[i];
}
String titleFull = "";
if (toRGB) {
System.out.println("correctionColorProc.YPrPbToRGB");
stack = YPrPbToRGB(yPrPb,
colorProcParameters.kr, // 0.299;
colorProcParameters.kb, // 0.114;
stack.getWidth());
titleFull=name+"-RGB-float"+suffix;
//Trim stack to just first 3 slices
if (saveShowIntermediate && (debugLevel > 1)){ // 2){
ImagePlus imp_dbg=new ImagePlus("YPrPbToRGB",stack);
eyesisCorrections.saveAndShow(
imp_dbg,
this.correctionsParameters);
}
while (stack.getSize() > 3) stack.deleteLastSlice();
if (debugLevel > 1) System.out.println("Trimming color stack");
} else {
if (debugLevel>0) System.out.println(numFilesToProcess+ " files to process (of "+sourceFiles.length+"), "+numImagesToProcess+" images to process");
titleFull=name+"-YPrPb"+suffix;
if (debugLevel > 1) System.out.println("Using full stack, including YPbPr");
}
double [] referenceExposures=eyesisCorrections.calcReferenceExposures(debugLevel); // multiply each image by this and divide by individual (if not NaN)
int [][] fileIndices=new int [numImagesToProcess][2]; // file index, channel number
int index=0;
for (int nFile=0;nFile<enabledFiles.length;nFile++){
if ((sourceFiles[nFile]!=null) && (sourceFiles[nFile].length()>1)) {
int [] channels={correctionsParameters.getChannelFromSourceTiff(sourceFiles[nFile])};
if (correctionsParameters.isJP4()){
int subCamera= channels[0]- correctionsParameters.firstSubCamera; // to match those in the sensor files
channels=eyesisCorrections.pixelMapping.channelsForSubCamera(subCamera);
}
if (channels!=null){
for (int i=0;i<channels.length;i++) if (eyesisCorrections.isChannelEnabled(channels[i])){
fileIndices[index ][0]=nFile;
fileIndices[index++][1]=channels[i];
}
}
if (alpha != null){
float [] alpha_pixels = new float [alpha.length];
for (int i = 0; i <alpha.length; i++){
alpha_pixels[i] = (float) alpha[i];
}
stack.addSlice("alpha",alpha_pixels);
}
ArrayList<String> setNames = new ArrayList<String>();
ArrayList<ArrayList<Integer>> setFiles = new ArrayList<ArrayList<Integer>>();
ImagePlus result= new ImagePlus(titleFull, stack);
for (int iImage=0;iImage<fileIndices.length;iImage++){
int nFile=fileIndices[iImage][0];
String setName = correctionsParameters.getNameFromSourceTiff(sourceFiles[nFile]);
if (!setNames.contains(setName)) {
setNames.add(setName);
setFiles.add(new ArrayList<Integer>());
}
setFiles.get(setNames.indexOf(setName)).add(new Integer(nFile));
}
for (int nSet = 0; nSet < setNames.size(); nSet++){
int maxChn = 0;
for (int i = 0; i < setFiles.get(nSet).size(); i++){
int chn = fileIndices[setFiles.get(nSet).get(i)][1];
if (chn > maxChn) maxChn = chn;
}
int [] channelFiles = new int[maxChn+1];
for (int i =0; i < channelFiles.length; i++) channelFiles[i] = -1;
if (!toRGB && !this.correctionsParameters.jpeg){ // toRGB set for equirectangular
if (debugLevel > -1) System.out.println("!toRGB && !this.correctionsParameters.jpeg");
if (saveShowIntermediate) eyesisCorrections.saveAndShow(result, this.correctionsParameters);
return result;
} else { // that's not the end result, save if required
if (debugLevel > -1) System.out.println("!toRGB && !this.correctionsParameters.jpeg - else");
if (saveShowIntermediate) eyesisCorrections.saveAndShow(result, // saves OK with alpha - 32-bit float
eyesisCorrections.correctionsParameters,
eyesisCorrections.correctionsParameters.save32,
false, // true, // false,
eyesisCorrections.correctionsParameters.JPEG_quality); // save, no show
}
stack=eyesisCorrections.convertRGB32toRGB16Stack(
stack,
rgbParameters);
titleFull=name+"-RGB48"+suffix;
result= new ImagePlus(titleFull, stack);
result.updateAndDraw();
if (debugLevel > 1) System.out.println("result.updateAndDraw(), "+titleFull+"-RGB48");
CompositeImage compositeImage=eyesisCorrections.convertToComposite(result);
if (!this.correctionsParameters.jpeg && bpp16){ // RGB48 was the end result
if (debugLevel > 1) System.out.println("if (!this.correctionsParameters.jpeg && !advanced)");
if (saveShowIntermediate) eyesisCorrections.saveAndShow(compositeImage, this.correctionsParameters);
return compositeImage; // return result;
} else { // that's not the end result, save if required
if (debugLevel > 1) System.out.println("if (!this.correctionsParameters.jpeg && !advanced) - else");
if (saveShowIntermediate) eyesisCorrections.saveAndShow(compositeImage, this.correctionsParameters, this.correctionsParameters.save16, false); // save, no show
}
result = eyesisCorrections.convertRGB48toRGB24(
stack,
name+"-RGB24"+suffix,
0, 65536, // r range 0->0, 65536->256
0, 65536, // g range
0, 65536,// b range
0, 65536);// alpha range
// next will save either JPEG (if no alpha) or RGBA tiff (if alpha is present). ImageJ shows just RGB (no alpha)
if (saveShowFinal) eyesisCorrections.saveAndShow(result, this.correctionsParameters);
return result;
}
public double [][][] fine_geometry_correction(
EyesisCorrectionParameters.CLTParameters clt_parameters,
double [][] disparity_map,
double [][] clt_mismatch,
int tilesX,
double magic_coeff, // stil not understood coefficent that reduces reported disparity value. Seems to be around 8.5
int debugLevel)
{
// TODO: update the following indices when format of the arrays will change (removed unneeded data)
final int index_disparity = 2; // "cm_disparity"
final int index_strength = 6; // "strength"
final int [] indices_mismatch = {1,4,6,9}; // "dy0", "dy1", "dx2", "dx3"
final int numTiles = disparity_map[0].length;
final int tilesY = numTiles/tilesX;
int numUsed = 0;
for (int i = 0; i < numTiles; i++) {
if ((disparity_map[index_strength][i] >= clt_parameters.fcorr_min_stength) &&
(Math.abs(disparity_map[index_disparity][i]) <= clt_parameters.fcorr_disp_diff)) numUsed ++;
}
double [][][] mdata = new double[numUsed][3][];
int indx = 0;
for (int i = 0; i < numTiles; i++) {
if ((disparity_map[index_strength][i] >= clt_parameters.fcorr_min_stength) &&
(Math.abs(disparity_map[index_disparity][i]) <= clt_parameters.fcorr_disp_diff)) {
int tileX = i % tilesX;
int tileY = i / tilesX;
mdata[indx][0] = new double [2];
mdata[indx][0][0] = (2.0 * tileX)/tilesX - 1.0; // -1.0 to +1.0;
mdata[indx][0][1] = (2.0 * tileY)/tilesY - 1.0; // -1.0 to +1.0
mdata[indx][1] = new double [indices_mismatch.length]; // 4
for (int ip = 0; ip < indices_mismatch.length; ip++) {
mdata[indx][1][ip] = clt_mismatch[indices_mismatch[ip]][i];
}
mdata[indx][2] = new double [1];
mdata[indx][2][0] = disparity_map[index_strength][i];
indx ++;
}
}
PolynomialApproximation pa = new PolynomialApproximation();
double thresholdLin = 1.0E-20; // threshold ratio of matrix determinant to norm for linear approximation (det too low - fail)
double thresholdQuad = 1.0E-30; // threshold ratio of matrix determinant to norm for quadratic approximation (det too low - fail)
/*
* returns array of vectors or null
* each vector (one per each z component) is either 6-element- (A,B,C,D,E,F) if quadratic is possible and enabled
* or 3-element - (D,E,F) if linear is possible and quadratic is not possible or disabled
* returns null if not enough data even for the linear approximation
*/
double [][] coeffs = pa.quadraticApproximation(
mdata,
!clt_parameters.fcorr_quadratic, // boolean forceLinear, // use linear approximation
thresholdLin, // threshold ratio of matrix determinant to norm for linear approximation (det too low - fail)
thresholdQuad, // threshold ratio of matrix determinant to norm for quadratic approximation (det too low - fail)
debugLevel);
for (int i = 0; i < coeffs.length; i++){
if (coeffs[i] == null){
coeffs[i] = new double [6];
for (int j = 0; j < coeffs[i].length; i++) coeffs[i][j] = 0.0;
} else if (coeffs[i].length < 6){
double [] short_coeffs = coeffs[i];
coeffs[i] = new double [6];
for (int j = 0; j < coeffs[i].length; j++) {
if (j < (coeffs[i].length - short_coeffs.length)) coeffs[i][j] = 0.0;
else coeffs[i][j] = short_coeffs[j - (coeffs[i].length - short_coeffs.length)];
}
}
}
// convert to 8 sets of coefficient for px0, py0, px1, py1, ... py3.
double [][][] coeff_full = new double [4][2][6];
double scale = 0.5/magic_coeff;
for (int j = 0; j<6; j++){
coeff_full[0][0][j] = -coeffs[2][j] * scale;
coeff_full[0][1][j] = -coeffs[0][j] * scale;
coeff_full[1][0][j] = -coeffs[3][j] * scale;
coeff_full[1][1][j] = coeffs[0][j] * scale;
coeff_full[2][0][j] = coeffs[2][j] * scale;
coeff_full[2][1][j] = -coeffs[1][j] * scale;
coeff_full[3][0][j] = coeffs[3][j] * scale;
coeff_full[3][1][j] = coeffs[1][j] * scale;
}
if (debugLevel > -1){
int tilesX8 = (tilesX - 1) / 8 + 1;
int tilesY8 = (tilesY - 1) / 8 + 1;
int len8 = tilesX8*tilesY8;
double [][] mismatch_8 = new double[11][len8];
for (int i = 0; i < numTiles; i++) {
if ((disparity_map[index_strength][i] >= clt_parameters.fcorr_min_stength) &&
(Math.abs(disparity_map[index_disparity][i]) <= clt_parameters.fcorr_disp_diff)) {
int tileX = i % tilesX;
int tileY = i / tilesX;
int tX8 = tileX/8;
int tY8 = tileY/8;
int indx8 = tY8*tilesX8+tX8;
double tX = (2.0 * tileX)/tilesX - 1.0; // -1.0 to +1.0;
double tY = (2.0 * tileY)/tilesY - 1.0; // -1.0 to +1.0
double w = disparity_map[index_strength][i];
for (int ip = 0; ip < 4; ip++) {
mismatch_8[ip][indx8] += w * clt_mismatch[indices_mismatch[ip]][i];
}
mismatch_8[8][indx8] += w * tX;
mismatch_8[9][indx8] += w * tY;
mismatch_8[10][indx8] += w;
}
}
for (int i = 0; i < len8; i++) {
if (mismatch_8[10][i] > 0){
for (int n = 0; n<4; n++){
mismatch_8[n][i] /= mismatch_8[10][i];
}
mismatch_8[8][i] /= mismatch_8[10][i];
mismatch_8[9][i] /= mismatch_8[10][i];
} else {
for (int n = 0; n<4; n++){
mismatch_8[n][i] = Double.NaN;
}
mismatch_8[8][i] = Double.NaN;
mismatch_8[9][i] = Double.NaN;
}
for (int n = 0; n<4; n++){
double tX = mismatch_8[8][i];
double tY = mismatch_8[9][i];
//f(x,y)=A*x^2+B*y^2+C*x*y+D*x+E*y+F
mismatch_8[4+n][i] = (
coeffs[n][0]*tX*tX+
coeffs[n][1]*tY*tY+
coeffs[n][2]*tX*tY+
coeffs[n][3]*tX+
coeffs[n][4]*tY+
coeffs[n][5]);
}
}
String [] titles = {"dy0","dy1","dx2","dx3","cy0","cy1","cx2","cx3","tx","ty","w"};
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
sdfa_instance.showArrays(
mismatch_8,
tilesX8,
tilesY8,
true,
"mismatch_8",
titles);
}
return coeff_full;
}
public void apply_fine_corr(
double [][][] corr,
int debugLevel)
{
if (debugLevel > 1){
if (debugLevel > 1){
show_fine_corr( this.fine_corr, " was");
}
}
if (debugLevel > 1){
if (debugLevel > 1){
show_fine_corr(corr, "added");
}
}
for (int n = 0; n< corr.length; n++){
for (int i = 0; i< corr[n].length; i++){
for (int j = 0; j< corr[n][i].length; j++){
this.fine_corr[n][i][j]+=corr[n][i][j];
}
}
}
if (debugLevel > 0){
show_fine_corr( this.fine_corr, "");
}
}
public void show_fine_corr()
{
show_fine_corr( this.fine_corr, "");
}
public void show_fine_corr(
double [][][] corr,
String prefix)
{
String sadd = (prefix.length() > 0)?(prefix+" "):"";
for (int n = 0; n< corr.length; n++){
for (int i = 0; i< corr[n].length; i++){
System.out.print(sadd+"port"+n+": "+fine_corr_dir_names[i]+": ");
for (int j = 0; j< corr[n][i].length; j++){
System.out.print(fine_corr_coeff_names[j]+"="+corr[n][i][j]+" ");
}
System.out.println();
}
}
}
public void reset_fine_corr()
{
this.fine_corr = new double [4][2][6]; // reset all coefficients to 0
}
public void cltDisparityScans(
EyesisCorrectionParameters.CLTParameters clt_parameters,
EyesisCorrectionParameters.DebayerParameters debayerParameters,
EyesisCorrectionParameters.NonlinParameters nonlinParameters,
EyesisCorrectionParameters.ColorProcParameters colorProcParameters,
CorrectionColorProc.ColorGainsParameters channelGainParameters,
EyesisCorrectionParameters.RGBParameters rgbParameters,
EyesisCorrectionParameters.EquirectangularParameters equirectangularParameters,
int convolveFFTSize, // 128 - fft size, kernel size should be size/2
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
final int debugLevel)
{
this.startTime=System.nanoTime();
String [] sourceFiles=correctionsParameters.getSourcePaths();
boolean [] enabledFiles=new boolean[sourceFiles.length];
for (int i=0;i<enabledFiles.length;i++) enabledFiles[i]=false;
int numFilesToProcess=0;
int numImagesToProcess=0;
for (int nFile=0;nFile<enabledFiles.length;nFile++){
if ((sourceFiles[nFile]!=null) && (sourceFiles[nFile].length()>1)) {
int [] channels={correctionsParameters.getChannelFromSourceTiff(sourceFiles[nFile])};
if (correctionsParameters.isJP4()){
int subCamera= channels[0]- correctionsParameters.firstSubCamera; // to match those in the sensor files
// removeUnusedSensorData should be off!?
channels=this.eyesisCorrections.pixelMapping.channelsForSubCamera(subCamera);
}
if (channels!=null){
for (int i=0;i<channels.length;i++) if (eyesisCorrections.isChannelEnabled(channels[i])){
if (!enabledFiles[nFile]) numFilesToProcess++;
enabledFiles[nFile]=true;
numImagesToProcess++;
}
}
}
}
if (numFilesToProcess==0){
System.out.println("No files to process (of "+sourceFiles.length+")");
return;
} else {
if (debugLevel>0) System.out.println(numFilesToProcess+ " files to process (of "+sourceFiles.length+"), "+numImagesToProcess+" images to process");
}
double [] referenceExposures=eyesisCorrections.calcReferenceExposures(debugLevel); // multiply each image by this and divide by individual (if not NaN)
int [][] fileIndices=new int [numImagesToProcess][2]; // file index, channel number
int index=0;
for (int nFile=0;nFile<enabledFiles.length;nFile++){
if ((sourceFiles[nFile]!=null) && (sourceFiles[nFile].length()>1)) {
int [] channels={correctionsParameters.getChannelFromSourceTiff(sourceFiles[nFile])};
if (correctionsParameters.isJP4()){
int subCamera= channels[0]- correctionsParameters.firstSubCamera; // to match those in the sensor files
channels=eyesisCorrections.pixelMapping.channelsForSubCamera(subCamera);
}
if (channels!=null){
for (int i=0;i<channels.length;i++) if (eyesisCorrections.isChannelEnabled(channels[i])){
fileIndices[index ][0]=nFile;
fileIndices[index++][1]=channels[i];
}
}
}
}
ArrayList<String> setNames = new ArrayList<String>();
ArrayList<ArrayList<Integer>> setFiles = new ArrayList<ArrayList<Integer>>();
for (int iImage=0;iImage<fileIndices.length;iImage++){
int nFile=fileIndices[iImage][0];
String setName = correctionsParameters.getNameFromSourceTiff(sourceFiles[nFile]);
if (!setNames.contains(setName)) {
setNames.add(setName);
setFiles.add(new ArrayList<Integer>());
}
setFiles.get(setNames.indexOf(setName)).add(new Integer(nFile));
}
for (int nSet = 0; nSet < setNames.size(); nSet++){
int maxChn = 0;
for (int i = 0; i < setFiles.get(nSet).size(); i++){
int chn = fileIndices[setFiles.get(nSet).get(i)][1];
if (chn > maxChn) maxChn = chn;
}
int [] channelFiles = new int[maxChn+1];
for (int i =0; i < channelFiles.length; i++) channelFiles[i] = -1;
for (int i = 0; i < setFiles.get(nSet).size(); i++){
channelFiles[fileIndices[setFiles.get(nSet).get(i)][1]] = setFiles.get(nSet).get(i);
}
......@@ -5571,40 +5883,11 @@ public class EyesisDCT {
}
}
int tilesY = imp_quad[0].getHeight()/clt_parameters.transform_size;
int tilesX = imp_quad[0].getWidth()/clt_parameters.transform_size;
tilesY = imp_quad[0].getHeight()/clt_parameters.transform_size;
tilesX = imp_quad[0].getWidth()/clt_parameters.transform_size;
// temporary setting up tile task file (one integer per tile, bitmask
// for testing defined for a window, later the tiles to process will be calculated based on previous passes results
int [][] tile_op = new int [tilesY][tilesX]; // all zero
int txl = clt_parameters.tile_task_wl;
int txr = txl + clt_parameters.tile_task_ww;
int tyt = clt_parameters.tile_task_wt;
int tyb = tyt + clt_parameters.tile_task_wh;
if (txl < 0) txl = 0;
else if (txl >= tilesX) txl = tilesX - 1;
if (txr <= txl) txr = txl + 1;
else if (txr > tilesX) txr = tilesX;
if (tyt < 0) tyt = 0;
else if (tyt >= tilesY) tyt = tilesY - 1;
if (tyb <= tyt) tyb = tyt + 1;
else if (tyb > tilesY) tyb = tilesY;
for (int i = tyt; i < tyb; i++) {
for (int j = txl; j < txr; j++) {
tile_op[i][j] = clt_parameters.tile_task_op;
}
}
if (debugLevel > -1){
System.out.println("clt_parameters.tile_task_wl="+clt_parameters.tile_task_wl );
System.out.println("clt_parameters.tile_task_wt="+clt_parameters.tile_task_wt );
System.out.println("clt_parameters.tile_task_ww="+clt_parameters.tile_task_ww );
System.out.println("clt_parameters.tile_task_wh="+clt_parameters.tile_task_wh );
System.out.println("tyt="+tyt+" tyb="+tyb+" txl="+txl+" txr="+txr );
}
int [][] tile_op = setSameTileOp(clt_parameters, clt_parameters.tile_task_op, debugLevel);
//TODO: Add array of default disparity - use for combining images in force disparity mode (no correlation), when disparity is predicted from other tiles
......@@ -5616,6 +5899,8 @@ public class EyesisDCT {
for (int scan_step = 0; scan_step < clt_parameters.disp_scan_count; scan_step++) {
double disparity = clt_parameters.disp_scan_start + scan_step * clt_parameters.disp_scan_step;
double [][] disparity_array = setSameDisparity(disparity); // [tilesY][tilesX] - individual per-tile expected disparity
double [][] shiftXY = {
{clt_parameters.fine_corr_x_0,clt_parameters.fine_corr_y_0},
{clt_parameters.fine_corr_x_1,clt_parameters.fine_corr_y_1},
......@@ -5624,7 +5909,7 @@ public class EyesisDCT {
image_dtt.clt_aberrations_quad_corr(
tile_op, // per-tile operation bit codes
disparity, // clt_parameters.disparity, // final double disparity,
disparity_array, // clt_parameters.disparity, // final double disparity,
double_stacks, // final double [][][] imade_data, // first index - number of image in a quad
// correlation results - final and partial
clt_corr_combo, // [tilesY][tilesX][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate
......@@ -5651,6 +5936,7 @@ public class EyesisDCT {
clt_parameters.diff_threshold, // 5.0; // RMS difference from average to discard channel (~ 1.0 - 1/255 full scale image)
clt_parameters.diff_gauss, // true; // when averaging images, use gaussian around average as weight (false - sharp all/nothing)
clt_parameters.min_agree, // 3.0; // minimal number of channels to agree on a point (real number to work with fuzzy averages)
clt_parameters.dust_remove, // Do not reduce average weight when only one image differes much from the average
clt_parameters.keep_weights, // Add port weights to RGBA stack (debug feature)
geometryCorrection, // final GeometryCorrection geometryCorrection,
clt_kernels, // final double [][][][][][] clt_kernels, // [channel_in_quad][color][tileY][tileX][band][pixel] , size should match image (have 1 tile around)
......@@ -5658,6 +5944,8 @@ public class EyesisDCT {
clt_parameters.transform_size,
clt_parameters.clt_window,
shiftXY, //
(clt_parameters.fcorr_ignore? null: this.fine_corr),
clt_parameters.corr_magic_scale, // stil not understood coefficent that reduces reported disparity value. Seems to be around 8.5
clt_parameters.shift_x, // final int shiftX, // shift image horizontally (positive - right) - just for testing
clt_parameters.shift_y, // final int shiftY, // shift image vertically (positive - down)
clt_parameters.tileX, // final int debug_tileX,
......@@ -5797,9 +6085,815 @@ public class EyesisDCT {
}
return rslt;
}
// public ImagePlus [] cltDisparityScan(
public void processCLTQuads3d(
EyesisCorrectionParameters.CLTParameters clt_parameters,
EyesisCorrectionParameters.DebayerParameters debayerParameters,
EyesisCorrectionParameters.NonlinParameters nonlinParameters,
EyesisCorrectionParameters.ColorProcParameters colorProcParameters,
CorrectionColorProc.ColorGainsParameters channelGainParameters,
EyesisCorrectionParameters.RGBParameters rgbParameters,
EyesisCorrectionParameters.EquirectangularParameters equirectangularParameters,
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
final int debugLevel)
{
this.startTime=System.nanoTime();
String [] sourceFiles=correctionsParameters.getSourcePaths();
boolean [] enabledFiles=new boolean[sourceFiles.length];
for (int i=0;i<enabledFiles.length;i++) enabledFiles[i]=false;
int numFilesToProcess=0;
int numImagesToProcess=0;
for (int nFile=0;nFile<enabledFiles.length;nFile++){
if ((sourceFiles[nFile]!=null) && (sourceFiles[nFile].length()>1)) {
int [] channels={correctionsParameters.getChannelFromSourceTiff(sourceFiles[nFile])};
if (correctionsParameters.isJP4()){
int subCamera= channels[0]- correctionsParameters.firstSubCamera; // to match those in the sensor files
// removeUnusedSensorData should be off!?
channels=this.eyesisCorrections.pixelMapping.channelsForSubCamera(subCamera);
}
if (channels!=null){
for (int i=0;i<channels.length;i++) if (eyesisCorrections.isChannelEnabled(channels[i])){
if (!enabledFiles[nFile]) numFilesToProcess++;
enabledFiles[nFile]=true;
numImagesToProcess++;
}
}
}
}
if (numFilesToProcess==0){
System.out.println("No files to process (of "+sourceFiles.length+")");
return;
} else {
if (debugLevel>0) System.out.println(numFilesToProcess+ " files to process (of "+sourceFiles.length+"), "+numImagesToProcess+" images to process");
}
double [] referenceExposures=eyesisCorrections.calcReferenceExposures(debugLevel); // multiply each image by this and divide by individual (if not NaN)
int [][] fileIndices=new int [numImagesToProcess][2]; // file index, channel number
int index=0;
for (int nFile=0;nFile<enabledFiles.length;nFile++){
if ((sourceFiles[nFile]!=null) && (sourceFiles[nFile].length()>1)) {
int [] channels={correctionsParameters.getChannelFromSourceTiff(sourceFiles[nFile])};
if (correctionsParameters.isJP4()){
int subCamera= channels[0]- correctionsParameters.firstSubCamera; // to match those in the sensor files
channels=eyesisCorrections.pixelMapping.channelsForSubCamera(subCamera);
}
if (channels!=null){
for (int i=0;i<channels.length;i++) if (eyesisCorrections.isChannelEnabled(channels[i])){
fileIndices[index ][0]=nFile;
fileIndices[index++][1]=channels[i];
}
}
}
}
ArrayList<String> setNames = new ArrayList<String>();
ArrayList<ArrayList<Integer>> setFiles = new ArrayList<ArrayList<Integer>>();
for (int iImage=0;iImage<fileIndices.length;iImage++){
int nFile=fileIndices[iImage][0];
String setName = correctionsParameters.getNameFromSourceTiff(sourceFiles[nFile]);
if (!setNames.contains(setName)) {
setNames.add(setName);
setFiles.add(new ArrayList<Integer>());
}
setFiles.get(setNames.indexOf(setName)).add(new Integer(nFile));
}
for (int nSet = 0; nSet < setNames.size(); nSet++){
int maxChn = 0;
for (int i = 0; i < setFiles.get(nSet).size(); i++){
int chn = fileIndices[setFiles.get(nSet).get(i)][1];
if (chn > maxChn) maxChn = chn;
}
int [] channelFiles = new int[maxChn+1];
for (int i =0; i < channelFiles.length; i++) channelFiles[i] = -1;
for (int i = 0; i < setFiles.get(nSet).size(); i++){
channelFiles[fileIndices[setFiles.get(nSet).get(i)][1]] = setFiles.get(nSet).get(i);
}
ImagePlus [] imp_srcs = new ImagePlus[channelFiles.length];
double [] scaleExposures = new double[channelFiles.length];
for (int srcChannel=0; srcChannel<channelFiles.length; srcChannel++){
int nFile=channelFiles[srcChannel];
imp_srcs[srcChannel]=null;
if (nFile >=0){
if (correctionsParameters.isJP4()){
int subchannel=eyesisCorrections.pixelMapping.getSubChannel(srcChannel);
if (this.correctionsParameters.swapSubchannels01) {
switch (subchannel){
case 0: subchannel=1; break;
case 1: subchannel=0; break;
}
}
if (debugLevel>0) System.out.println("Processing set " + setNames.get(nSet)+" channel "+srcChannel+" - subchannel "+subchannel+" of "+sourceFiles[nFile]);
ImagePlus imp_composite=eyesisCorrections.JP4_INSTANCE.open(
"", // path,
sourceFiles[nFile],
"", //arg - not used in JP46 reader
true, // un-apply camera color gains
null, // new window
false); // do not show
imp_srcs[srcChannel]=eyesisCorrections.JP4_INSTANCE.demuxImage(imp_composite, subchannel);
if (imp_srcs[srcChannel] == null) imp_srcs[srcChannel] = imp_composite; // not a composite image
// do we need to add any properties?
} else {
imp_srcs[srcChannel]=new ImagePlus(sourceFiles[nFile]);
// (new JP46_Reader_camera(false)).decodeProperiesFromInfo(imp_src); // decode existent properties from info
eyesisCorrections.JP4_INSTANCE.decodeProperiesFromInfo(imp_srcs[srcChannel]); // decode existent properties from info
if (debugLevel>0) System.out.println("Processing "+sourceFiles[nFile]);
}
scaleExposures[srcChannel] = 1.0;
if (!Double.isNaN(referenceExposures[nFile]) && (imp_srcs[srcChannel].getProperty("EXPOSURE")!=null)){
scaleExposures[srcChannel] = referenceExposures[nFile]/Double.parseDouble((String) imp_srcs[srcChannel].getProperty("EXPOSURE"));
if (debugLevel>0) System.out.println("Will scale intensity (to compensate for exposure) by "+scaleExposures[srcChannel]);
}
imp_srcs[srcChannel].setProperty("name", correctionsParameters.getNameFromSourceTiff(sourceFiles[nFile]));
imp_srcs[srcChannel].setProperty("channel", srcChannel); // it may already have channel
imp_srcs[srcChannel].setProperty("path", sourceFiles[nFile]); // it may already have channel
if (this.correctionsParameters.pixelDefects && (eyesisCorrections.defectsXY!=null)&& (eyesisCorrections.defectsXY[srcChannel]!=null)){
// apply pixel correction
int numApplied= eyesisCorrections.correctDefects(
imp_srcs[srcChannel],
srcChannel,
debugLevel);
if ((debugLevel>0) && (numApplied>0)) { // reduce verbosity after verified defect correction works
System.out.println("Corrected "+numApplied+" pixels in "+sourceFiles[nFile]);
}
}
if (this.correctionsParameters.vignetting){
if ((eyesisCorrections.channelVignettingCorrection==null) || (srcChannel<0) || (srcChannel>=eyesisCorrections.channelVignettingCorrection.length) || (eyesisCorrections.channelVignettingCorrection[srcChannel]==null)){
System.out.println("No vignetting data for channel "+srcChannel);
return;
}
float [] pixels=(float []) imp_srcs[srcChannel].getProcessor().getPixels();
if (pixels.length!=eyesisCorrections.channelVignettingCorrection[srcChannel].length){
System.out.println("Vignetting data for channel "+srcChannel+" has "+eyesisCorrections.channelVignettingCorrection[srcChannel].length+" pixels, image "+sourceFiles[nFile]+" has "+pixels.length);
return;
}
// TODO: Move to do it once:
double min_non_zero = 0.0;
for (int i=0;i<pixels.length;i++){
double d = eyesisCorrections.channelVignettingCorrection[srcChannel][i];
if ((d > 0.0) && ((min_non_zero == 0) || (min_non_zero > d))){
min_non_zero = d;
}
}
double max_vign_corr = clt_parameters.vignetting_range*min_non_zero;
System.out.println("Vignetting data: channel="+srcChannel+", min = "+min_non_zero);
for (int i=0;i<pixels.length;i++){
double d = eyesisCorrections.channelVignettingCorrection[srcChannel][i];
if (d > max_vign_corr) d = max_vign_corr;
pixels[i]*=d;
}
// Scale here, combine with vignetting later?
int width = imp_srcs[srcChannel].getWidth();
int height = imp_srcs[srcChannel].getHeight();
for (int y = 0; y < height-1; y+=2){
for (int x = 0; x < width-1; x+=2){
pixels[y*width+x ] *= clt_parameters.scale_g;
pixels[y*width+x+width+1] *= clt_parameters.scale_g;
pixels[y*width+x +1] *= clt_parameters.scale_r;
pixels[y*width+x+width ] *= clt_parameters.scale_b;
}
}
} else { // assuming GR/BG pattern
System.out.println("Applying fixed color gain correction parameters: Gr="+
clt_parameters.novignetting_r+", Gg="+clt_parameters.novignetting_g+", Gb="+clt_parameters.novignetting_b);
float [] pixels=(float []) imp_srcs[srcChannel].getProcessor().getPixels();
int width = imp_srcs[srcChannel].getWidth();
int height = imp_srcs[srcChannel].getHeight();
double kr = clt_parameters.scale_r/clt_parameters.novignetting_r;
double kg = clt_parameters.scale_g/clt_parameters.novignetting_g;
double kb = clt_parameters.scale_b/clt_parameters.novignetting_b;
for (int y = 0; y < height-1; y+=2){
for (int x = 0; x < width-1; x+=2){
pixels[y*width+x ] *= kg;
pixels[y*width+x+width+1] *= kg;
pixels[y*width+x +1] *= kr;
pixels[y*width+x+width ] *= kb;
}
}
}
}
}
// once per quad here
// may need to equalize gains between channels
if (clt_parameters.gain_equalize || clt_parameters.colors_equalize){
channelGainsEqualize(
clt_parameters.gain_equalize,
clt_parameters.colors_equalize,
channelFiles,
imp_srcs,
setNames.get(nSet), // just for debug messeges == setNames.get(nSet)
debugLevel);
}
// once per quad here
processCLTQuad3d( // returns ImagePlus, but it already should be saved/shown
imp_srcs, // [srcChannel], // should have properties "name"(base for saving results), "channel","path"
clt_parameters,
debayerParameters,
nonlinParameters,
colorProcParameters,
channelGainParameters,
rgbParameters,
threadsMax, // maximal number of threads to launch
updateStatus,
debugLevel);
Runtime.getRuntime().gc();
if (debugLevel >-1) System.out.println("Processing set "+(nSet+1)+" (of "+fileIndices.length+") finished at "+
IJ.d2s(0.000000001*(System.nanoTime()-this.startTime),3)+" sec, --- Free memory="+Runtime.getRuntime().freeMemory()+" (of "+Runtime.getRuntime().totalMemory()+")");
if (eyesisCorrections.stopRequested.get()>0) {
System.out.println("User requested stop");
return;
}
}
System.out.println("Processing "+fileIndices.length+" files finished at "+
IJ.d2s(0.000000001*(System.nanoTime()-this.startTime),3)+" sec, --- Free memory="+Runtime.getRuntime().freeMemory()+" (of "+Runtime.getRuntime().totalMemory()+")");
}
public class CLTPass3d{
public double [][] disparity; // per-tile disparity set for the pass[tileY][tileX]
public int [][] tile_op; // what was done in the current pass
public double [][] disparity_map; // add 4 layers - worst difference for the port
public double [][][][] texture_tiles;
}
public void resetCLTPasses(){
clt_3d_passes = new ArrayList<CLTPass3d>();
}
public ImagePlus processCLTQuad3d(
ImagePlus [] imp_quad, // should have properties "name"(base for saving results), "channel","path"
EyesisCorrectionParameters.CLTParameters clt_parameters,
EyesisCorrectionParameters.DebayerParameters debayerParameters,
EyesisCorrectionParameters.NonlinParameters nonlinParameters,
EyesisCorrectionParameters.ColorProcParameters colorProcParameters,
CorrectionColorProc.ColorGainsParameters channelGainParameters,
EyesisCorrectionParameters.RGBParameters rgbParameters,
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
final int debugLevel){
double [][][] image_data = new double [imp_quad.length][][];
for (int i = 0; i < image_data.length; i++){
image_data[i] = eyesisCorrections.bayerToDoubleStack(
imp_quad[i], // source Bayer image, linearized, 32-bit (float))
null); // no margins, no oversample
}
for (int i = 0; i < image_data.length; i++){
for (int j =0 ; j < image_data[i][0].length; j++){
image_data[i][2][j]*=0.5; // Scale green 0.5 to compensate more pixels than R,B
}
}
resetCLTPasses();
set_tiles (imp_quad[0], // set global tilesX, tilesY
clt_parameters );
CLTPass3d bgnd_data = CLTBackgroundMeas( // measure background
image_data, //
clt_parameters,
threadsMax, // maximal number of threads to launch
updateStatus,
debugLevel);
clt_3d_passes.add(bgnd_data);
ImagePlus imp_bgnd = getBackgroundImage(
clt_parameters,
colorProcParameters,
rgbParameters,
(String) imp_quad[0].getProperty("name"), // .getTitle(), //String name=(String) imp_src.getProperty("name");
DISPARITY_INDEX_CM, // index of disparity value in disparity_map == 2 (0,2 or 4)
threadsMax, // maximal number of threads to launch
updateStatus,
debugLevel);
return imp_bgnd;
}
public ImagePlus getBackgroundImage(
EyesisCorrectionParameters.CLTParameters clt_parameters,
EyesisCorrectionParameters.ColorProcParameters colorProcParameters,
EyesisCorrectionParameters.RGBParameters rgbParameters,
String name,
int disparity_index, // index of disparity value in disparity_map == 2 (0,2 or 4)
// int strength_index, // index of strength data in disparity map ==6
int threadsMax, // maximal number of threads to launch
boolean updateStatus,
int debugLevel
)
{
showDoubleFloatArrays sdfa_instance = null;
if (debugLevel > -1) sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
CLTPass3d bgnd_data = clt_3d_passes.get(0);
double [][][][] texture_tiles = bgnd_data.texture_tiles;
boolean [] bgnd_tiles = getBackgroundMask( // which tiles do belong to the background
clt_parameters.bgnd_range, // disparity range to be considered background
clt_parameters.bgnd_sure, // minimal strength to be considered definitely background
clt_parameters.bgnd_maybe, // maximal strength to ignore as non-background
clt_parameters.sure_smth, // if 2-nd worst image difference (noise-normalized) exceeds this - do not propagate bgnd
clt_parameters.min_clstr_seed, // number of tiles in a cluster to seed (just background?)
clt_parameters.min_clstr_block,// number of tiles in a cluster to block (just non-background?)
disparity_index, // index of disparity value in disparity_map == 2 (0,2 or 4)
debugLevel);
boolean [] bgnd_strict = bgnd_tiles.clone(); // only these have non 0 alpha
growTiles(
clt_parameters.bgnd_grow, // grow tile selection by 1 over non-background tiles 1: 4 directions, 2 - 8 directions, 3 - 8 by 1, 4 by 1 more
bgnd_tiles);
boolean [] bgnd_tiles_grown = bgnd_tiles.clone(); // only these have non 0 alpha
growTiles(
2, // grow tile selection by 1 over non-background tiles 1: 4 directions, 2 - 8 directions, 3 - 8 by 1, 4 by 1 more
bgnd_tiles);
if (sdfa_instance!=null){
double [][] dbg_img = new double[3][tilesY * tilesX];
String [] titles = {"strict","grown","more_grown"};
for (int i = 0; i<dbg_img[0].length;i++){
dbg_img[0][i] = bgnd_strict[i]?1:0;
dbg_img[1][i] = bgnd_tiles_grown[i]?1:0;
dbg_img[2][i] = bgnd_tiles[i]?1:0;
}
sdfa_instance.showArrays(dbg_img, tilesX, tilesY, true, "strict_grown",titles);
}
double [][][][] texture_tiles_bgnd = new double[tilesY][tilesX][][];
double [] alpha_zero = new double [4*clt_parameters.transform_size*clt_parameters.transform_size];
int alpha_index = 3;
for (int i = 0; i < alpha_zero.length; i++) alpha_zero[i]=0.0;
for (int tileY = 0; tileY < tilesY; tileY++){
for (int tileX = 0; tileX < tilesX; tileX++){
texture_tiles_bgnd[tileY][tileX]= null;
if ((texture_tiles[tileY][tileX] != null) &&
bgnd_tiles[tileY * tilesX + tileX]) {
if (bgnd_tiles_grown[tileY * tilesX + tileX]) {
texture_tiles_bgnd[tileY][tileX]= texture_tiles[tileY][tileX];
}else{
texture_tiles_bgnd[tileY][tileX]= texture_tiles[tileY][tileX].clone();
texture_tiles_bgnd[tileY][tileX][alpha_index] = alpha_zero;
}
}
}
}
ImageDtt image_dtt = new ImageDtt();
double [][] texture_overlap = image_dtt.combineRGBATiles(
texture_tiles_bgnd, // texture_tiles, // array [tilesY][tilesX][4][4*transform_size] or [tilesY][tilesX]{null}
clt_parameters.transform_size,
true, // when false - output each tile as 16x16, true - overlap to make 8x8
clt_parameters.sharp_alpha, // combining mode for alpha channel: false - treat as RGB, true - apply center 8x8 only
threadsMax, // maximal number of threads to launch
debugLevel);
if (clt_parameters.alpha1 > 0){ // negative or 0 - keep alpha as it was
double scale = (clt_parameters.alpha1 > clt_parameters.alpha0) ? (1.0/(clt_parameters.alpha1 - clt_parameters.alpha0)) : 0.0;
for (int i = 0; i < texture_overlap[alpha_index].length; i++){
double d = texture_overlap[alpha_index][i];
if (d >=clt_parameters.alpha1) d = 1.0;
else if (d <=clt_parameters.alpha0) d = 0.0;
else d = scale * (d- clt_parameters.alpha0);
texture_overlap[alpha_index][i] = d;
}
}
// for now - use just RGB. Later add oprion for RGBA
double [][] texture_rgb = {texture_overlap[0],texture_overlap[1],texture_overlap[2]};
double [][] texture_rgba = {texture_overlap[0],texture_overlap[1],texture_overlap[2],texture_overlap[3]};
// ImagePlus img_texture =
ImagePlus result = linearStackToColor(
clt_parameters,
colorProcParameters,
rgbParameters,
name+"-bgnd-texture", // String name,
"", //String suffix, // such as disparity=...
true, // toRGB,
!this.correctionsParameters.jpeg, // boolean bpp16, // 16-bit per channel color mode for result
true, // boolean saveShowIntermediate, // save/show if set globally
true, // boolean saveShowFinal, // save/show result (color image?)
((clt_parameters.alpha1 > 0)? texture_rgba: texture_rgb),
tilesX,
tilesY,
1.0, // double scaleExposure, // is it needed?
debugLevel );
return result;
}
//[tilesY][tilesX]["RGBA".length()][]
//linearStackToColor
//sure_smth
public boolean [] getBackgroundMask( // which tiles do belong to the background
double bgnd_range, // disparity range to be considered background
double bgnd_sure, // minimal strength to be considered definitely background
double bgnd_maybe, // maximal strength to ignore as non-background
double sure_smth, // if 2-nd worst image difference (noise-normalized) exceeds this - do not propagate bgnd
int min_clstr_seed, // number of tiles in a cluster to seed (just background?)
int min_clstr_block, // number of tiles in a cluster to block (just non-background?)
int disparity_index, // index of disparity value in disparity_map == 2 (0,2 or 4)
int debugLevel
){
boolean [] bgnd_tiles = new boolean [tilesY * tilesX];
boolean [] nonbgnd_tiles = new boolean [tilesY * tilesX];
boolean [] block_propagate = new boolean [tilesY * tilesX];
int quad = 4;
showDoubleFloatArrays sdfa_instance = null;
if (debugLevel > -1) sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
// boolean [] new_tiles = new boolean [tilesY * tilesX]; // grow selection by 1 tile over non-background?
CLTPass3d bgnd_data = clt_3d_passes.get(0);
// double [][][][] texture_tiles = bgnd_data.texture_tiles;
double [][] disparity_map= bgnd_data.disparity_map;
for (int tileY = 0; tileY < tilesY; tileY++){
for (int tileX = 0; tileX < tilesX; tileX++){
int tindx = tileY * tilesX + tileX;
if (Math.abs(disparity_map[disparity_index][tindx]) < bgnd_range){
if (disparity_map[STRENGTH_INDEX][tindx] >= bgnd_sure){
bgnd_tiles[tindx] = true;
}
} else {
if (disparity_map[STRENGTH_INDEX][tindx] > bgnd_maybe){ // maybe non-bkgnd
if (disparity_map[disparity_index][tindx] > 0.0) { // disregard negative disparity points
nonbgnd_tiles[tindx] = true;
}
}
}
// see if the second worst variatoin exceeds sure_smth (like a window), really close object
int imax1 = 0;
for (int i = 1; i< quad; i++){
if (disparity_map[IMG_DIFF0_INDEX+i][tindx] > disparity_map[IMG_DIFF0_INDEX + imax1][tindx]) imax1 = i;
}
int imax2 = (imax1 == 0)? 1 : 0;
for (int i = 0; i< quad; i++) if (i != imax1) {
if (disparity_map[IMG_DIFF0_INDEX+i][tindx] > disparity_map[IMG_DIFF0_INDEX + imax2][tindx]) imax2 = i;
}
block_propagate[tindx] = (disparity_map[IMG_DIFF0_INDEX + imax2][tindx] > sure_smth);
}
}
if (min_clstr_seed > 1){
removeSmallClusters(
true, // boolean diag_en, // enable diagonal directions, false only up, dowm, right,left
bgnd_tiles, // boolean [] tiles_src, // selected tiles, will modified
null, // double [] weights_src, // or null
min_clstr_seed, // int min_area, // minimal number of pixels
0.0); // double min_weight // minimal total weight of the cluster
}
if (min_clstr_block > 1){
removeSmallClusters(
true, // boolean diag_en, // enable diagonal directions, false only up, dowm, right,left
nonbgnd_tiles, // boolean [] tiles_src, // selected tiles, will modified
null, // double [] weights_src, // or null
min_clstr_block, // int min_area, // minimal number of pixels
0.0); // double min_weight // minimal total weight of the cluster
}
if (sdfa_instance!=null){
String [] titles = {"bgnd","nonbgnd","block","strength","disparity"};
double [][] dbg_img = new double[titles.length][tilesY * tilesX];
for (int i = 0; i<dbg_img[0].length;i++){
dbg_img[0][i] = bgnd_tiles [i] ? 1 : 0;
dbg_img[1][i] = nonbgnd_tiles [i] ? 1 : 0;
dbg_img[2][i] = block_propagate[i] ? 1 : 0;
dbg_img[3][i] = disparity_map[STRENGTH_INDEX][i];
dbg_img[4][i] = disparity_map[disparity_index][i];
}
sdfa_instance.showArrays(dbg_img, tilesX, tilesY, true, "bgnd_nonbgnd",titles);
}
for (int gain = 1; gain > 0;){
gain = 0;
// extend to the right
for (int tileY = 0; tileY < tilesY; tileY++){
for (int tileX = 0; tileX < (tilesX - 1); tileX++){
int tindx = tileY * tilesX + tileX;
if (bgnd_tiles[tindx] && !bgnd_tiles[tindx + 1] && !nonbgnd_tiles[tindx + 1] && !block_propagate[tindx + 1]){
bgnd_tiles[tindx+1] = true;
gain++;
}
}
}
// extend to the left
for (int tileY = 0; tileY < tilesY; tileY++){
for (int tileX = tilesX - 1; tileX > 1; tileX--){
int tindx = tileY * tilesX + tileX;
if (bgnd_tiles[tindx] && !bgnd_tiles[tindx - 1] && !nonbgnd_tiles[tindx -1] && !block_propagate[tindx - 1]){
bgnd_tiles[tindx - 1] = true;
gain++;
}
}
}
// extend down
for (int tileX = 0; tileX < tilesX; tileX++){
for (int tileY = 0; tileY < (tilesY -1); tileY++){
int tindx = tileY * tilesX + tileX;
if (bgnd_tiles[tindx] && !bgnd_tiles[tindx + tilesX] && !nonbgnd_tiles[tindx + tilesX] && !block_propagate[tindx + tilesX]){
bgnd_tiles[tindx + tilesX] = true;
gain++;
}
}
}
// extend up
for (int tileX = 0; tileX < tilesX; tileX++){
for (int tileY = tilesY - 1; tileY > 1; tileY--){
int tindx = tileY * tilesX + tileX;
if (bgnd_tiles[tindx] && !bgnd_tiles[tindx - tilesX] && !nonbgnd_tiles[tindx - tilesX] && !block_propagate[tindx - tilesX]){
bgnd_tiles[tindx - tilesX] = true;
gain++;
}
}
}
if (debugLevel > -1) {
System.out.println("getBackgroundMask(), gain="+gain);
}
if (sdfa_instance!=null){
double [] dbg_img = new double[tilesY * tilesX];
for (int i = 0; i<dbg_img.length;i++){
dbg_img[i] = bgnd_tiles[i]?1:0;
}
sdfa_instance.showArrays(dbg_img, tilesX, tilesY, "tiles");
}
}
return bgnd_tiles;
}
public void growTiles(
int grow, // grow tile selection by 1 over non-background tiles 1: 4 directions, 2 - 8 directions, 3 - 8 by 1, 4 by 1 more
boolean [] tiles)
{
boolean [] src_tiles = tiles.clone(); // just in case
// grow
boolean hor = true;
for (; grow > 0; grow--){
boolean single = (grow ==1) && hor;
src_tiles = tiles.clone();
if (hor){
for (int tileY = 0; tileY < tilesY; tileY++){
for (int tileX = 0; tileX < (tilesX - 1); tileX++){
int tindx = tileY * tilesX + tileX;
tiles[tindx + 1] |= src_tiles[tindx];
}
for (int tileX = 1; tileX < tilesX; tileX++){
int tindx = tileY * tilesX + tileX;
tiles[tindx - 1] |= src_tiles[tindx];
}
}
}
if (!hor || single){ // do vertically, but from previous state
for (int tileX = 0; tileX < tilesX; tileX++){
for (int tileY = 0; tileY < (tilesY - 1); tileY++){
int tindx = tileY * tilesX + tileX;
tiles[tindx + tilesX] |= src_tiles[tindx];
}
for (int tileY = 1; tileY < tilesY; tileY++){
int tindx = tileY * tilesX + tileX;
tiles[tindx - tilesX] |= src_tiles[tindx];
}
}
}
}
}
public void removeSmallClusters(
boolean diag_en, // enable diagonal directions, false only up, dowm, right,left
boolean [] tiles_src, // selected tiles, will modified
double [] weights_src, // or null
int min_area, // minimal number of pixels
double min_weight // minimal total weight of the cluster
){
// adding 1-tile frame around to avoid checking fro the borders
int tilesX2 = tilesX+2;
int tilesY2 = tilesY+2;
boolean [] tiles = new boolean [tilesX2*tilesY2];
double [] weights = null;
for (int i = 0; i < tilesY2; i++) {
tiles[tilesX2 * 0 + i] = false;
tiles[tilesX2*(tilesY2-1) + i] = false;
tiles[tilesX2* i + 0] = false;
tiles[tilesX2* i + tilesX2 -1] = false;
}
for (int i = 0; i < tilesY; i++) {
for (int j = 0; j < tilesX; j++) {
tiles[(i+1)*tilesX2 + j + 1]= tiles_src[i * tilesX + j];
}
}
if (weights_src != null) {
weights = new double [tiles.length];
for (int i = 0; i < tilesY; i++) {
for (int j = 0; j < tilesX; j++) {
weights[(i+1)*tilesX2 + j + 1]= weights_src[i * tilesX + j];
}
}
}
int [] dirs4 = {-tilesX2, 1, tilesX2,-1};
int [] dirs8 = {-tilesX2, -tilesX2 + 1, 1, tilesX2 +1, tilesX2, tilesX2 - 1, -1, -tilesX2 - 1};
int [] dirs = diag_en? dirs8 : dirs4;
int [] waves = new int [tiles.length];
for (int i = 0; i < tiles.length; i++) waves[i] = tiles[i] ? 0: -1;
ArrayList<Integer> front = new ArrayList<Integer>();
for (int start_indx = 0; start_indx < tiles.length; start_indx++) if (waves[start_indx] == 0){ // found first pixel of a new cluster
Integer ipx = start_indx;
Integer ipx1;
front.clear();
int area = 1;
double weight = 0.0;
if (weights != null) weight += weights[ipx];
waves[ipx] = area;
front.add(ipx);
while (!front.isEmpty()) {
ipx = front.remove(0);// get oldest element
for (int d = 0; d < dirs.length; d++){
ipx1 = ipx + dirs[d];
if (waves[ipx1] == 0) {
area++;
if (weights != null) weight += weights[ipx1];
waves[ipx1] = area;
front.add(ipx1);
}
}
}
if ((area < min_area) ||((weights != null) && (weight < min_weight))){
waves[ipx] = -1;
tiles[ipx] = false;
front.add(ipx);
while (!front.isEmpty()) {
ipx = front.remove(0);// get oldest element
for (int d = 0; d < dirs.length; d++){
ipx1 = ipx + dirs[d];
if (waves[ipx1] > 0) {
waves[ipx1] = -1;
tiles[ipx1] = false;
front.add(ipx1);
}
}
}
}
}
// return to original dimensions
for (int i = 0; i < tilesY; i++) {
for (int j = 0; j < tilesX; j++) {
tiles_src[i * tilesX + j] =tiles[(i+1)*tilesX2 + j + 1];
}
}
}
public void set_tiles (ImagePlus imp, // set tilesX, tilesY
EyesisCorrectionParameters.CLTParameters clt_parameters
){
tilesY = imp.getHeight()/clt_parameters.transform_size;
tilesX = imp.getWidth()/clt_parameters.transform_size;
}
public int [][] setSameTileOp(
EyesisCorrectionParameters.CLTParameters clt_parameters,
int op,
int debugLevel
)
{
int [][] tile_op = new int [tilesY][tilesX]; // all zero
int txl = clt_parameters.tile_task_wl;
int txr = txl + clt_parameters.tile_task_ww;
int tyt = clt_parameters.tile_task_wt;
int tyb = tyt + clt_parameters.tile_task_wh;
if (txl < 0) txl = 0;
else if (txl >= tilesX) txl = tilesX - 1;
if (txr <= txl) txr = txl + 1;
else if (txr > tilesX) txr = tilesX;
if (tyt < 0) tyt = 0;
else if (tyt >= tilesY) tyt = tilesY - 1;
if (tyb <= tyt) tyb = tyt + 1;
else if (tyb > tilesY) tyb = tilesY;
for (int i = tyt; i < tyb; i++) {
for (int j = txl; j < txr; j++) {
tile_op[i][j] = op;
}
}
if (debugLevel > -1){
System.out.println("clt_parameters.tile_task_wl="+clt_parameters.tile_task_wl );
System.out.println("clt_parameters.tile_task_wt="+clt_parameters.tile_task_wt );
System.out.println("clt_parameters.tile_task_ww="+clt_parameters.tile_task_ww );
System.out.println("clt_parameters.tile_task_wh="+clt_parameters.tile_task_wh );
System.out.println("tyt="+tyt+" tyb="+tyb+" txl="+txl+" txr="+txr );
}
return tile_op;
}
public double [][] setSameDisparity(
double disparity)
{
double [][] disp_array = new double [tilesY][tilesX];
for (int i = 0; i< tilesY; i++){
for (int j = 0; j< tilesX; j++){
disp_array[i][j] = disparity;
}
}
return disp_array;
}
public CLTPass3d CLTBackgroundMeas( // measure background
// ImagePlus [] imp_quad, // should have properties "name"(base for saving results), "channel","path"
final double [][][] image_data, // first index - number of image in a quad
EyesisCorrectionParameters.CLTParameters clt_parameters,
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
final int debugLevel)
{
CLTPass3d scan_rslt = new CLTPass3d();
int [][] tile_op = setSameTileOp(clt_parameters, 0xff | (1 << ImageDtt.FORCE_DISPARITY_BIT), debugLevel);
double [][] disparity_array =setSameDisparity(0.0); // [tilesY][tilesX] - individual per-tile expected disparity
// undecided, so 2 modes of combining alpha - same as rgb, or use center tile only
double [][][][] clt_corr_combo = new double [2][tilesY][tilesX][]; // will only be used inside?
double min_corr_selected = clt_parameters.corr_normalize? clt_parameters.min_corr_normalized: clt_parameters.min_corr;
double [][] disparity_map = new double [12][]; //[0] -residual disparity, [1] - orthogonal (just for debugging)
double [][] shiftXY = {
{clt_parameters.fine_corr_x_0,clt_parameters.fine_corr_y_0},
{clt_parameters.fine_corr_x_1,clt_parameters.fine_corr_y_1},
{clt_parameters.fine_corr_x_2,clt_parameters.fine_corr_y_2},
{clt_parameters.fine_corr_x_3,clt_parameters.fine_corr_y_3}};
double [][][][] texture_tiles = new double [tilesY][tilesX][][]; // ["RGBA".length()][];
ImageDtt image_dtt = new ImageDtt();
image_dtt.clt_aberrations_quad_corr(
tile_op, // per-tile operation bit codes
disparity_array, // clt_parameters.disparity, // final double disparity,
image_data, // final double [][][] imade_data, // first index - number of image in a quad
// correlation results - final and partial
clt_corr_combo, // [tilesY][tilesX][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate
null, // clt_corr_partial, // [tilesY][tilesX][quad]color][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate
null, // [tilesY][tilesX][pair]{dx,dy,weight}[(2*transform_size-1)*(2*transform_size-1)] // transpose unapplied. null - do not calculate
// Use it with disparity_maps[scan_step]? clt_mismatch, // [tilesY][tilesX][pair]{dx,dy,weight}[(2*transform_size-1)*(2*transform_size-1)] // transpose unapplied. null - do not calculate
disparity_map, // [12][tilesY * tilesX]
texture_tiles, // [tilesY][tilesX]["RGBA".length()][];
tilesX * clt_parameters.transform_size, // imp_quad[0].getWidth(), // final int width,
clt_parameters.fat_zero, // add to denominator to modify phase correlation (same units as data1, data2). <0 - pure sum
clt_parameters.corr_sym,
clt_parameters.corr_offset,
clt_parameters.corr_red,
clt_parameters.corr_blue,
clt_parameters.corr_sigma,
clt_parameters.corr_normalize, // normalize correlation results by rms
min_corr_selected, // 0.0001; // minimal correlation value to consider valid
clt_parameters.max_corr_sigma,// 1.5; // weights of points around global max to find fractional
clt_parameters.max_corr_radius,
clt_parameters.corr_mode, // Correlation mode: 0 - integer max, 1 - center of mass, 2 - polynomial
clt_parameters.min_shot, // 10.0; // Do not adjust for shot noise if lower than
clt_parameters.scale_shot, // 3.0; // scale when dividing by sqrt ( <0 - disable correction)
clt_parameters.diff_sigma, // 5.0;//RMS difference from average to reduce weights (~ 1.0 - 1/255 full scale image)
clt_parameters.diff_threshold, // 5.0; // RMS difference from average to discard channel (~ 1.0 - 1/255 full scale image)
clt_parameters.diff_gauss, // true; // when averaging images, use gaussian around average as weight (false - sharp all/nothing)
clt_parameters.min_agree, // 3.0; // minimal number of channels to agree on a point (real number to work with fuzzy averages)
clt_parameters.dust_remove, // Do not reduce average weight when only one image differes much from the average
clt_parameters.keep_weights, // Add port weights to RGBA stack (debug feature)
geometryCorrection, // final GeometryCorrection geometryCorrection,
clt_kernels, // final double [][][][][][] clt_kernels, // [channel_in_quad][color][tileY][tileX][band][pixel] , size should match image (have 1 tile around)
clt_parameters.kernel_step,
clt_parameters.transform_size,
clt_parameters.clt_window,
shiftXY, //
(clt_parameters.fcorr_ignore? null: this.fine_corr),
clt_parameters.corr_magic_scale, // stil not understood coefficent that reduces reported disparity value. Seems to be around 8.5
clt_parameters.shift_x, // final int shiftX, // shift image horizontally (positive - right) - just for testing
clt_parameters.shift_y, // final int shiftY, // shift image vertically (positive - down)
clt_parameters.tileX, // final int debug_tileX,
clt_parameters.tileY, // final int debug_tileY,
(clt_parameters.dbg_mode & 64) != 0, // no fract shift
(clt_parameters.dbg_mode & 128) != 0, // no convolve
// (clt_parameters.dbg_mode & 256) != 0, // transpose convolve
threadsMax,
debugLevel);
scan_rslt.disparity = disparity_array;
scan_rslt.tile_op = tile_op;
scan_rslt.disparity_map = disparity_map;
scan_rslt.texture_tiles = texture_tiles;
return scan_rslt;
}
}
......@@ -26,12 +26,19 @@
**
*/
import java.awt.Frame;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.DataBufferInt;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Array;
import java.util.Arrays;
import javax.imageio.ImageIO;
//import org.apache.log4j.Logger;
import ij.IJ;
......@@ -49,13 +56,40 @@ import loci.formats.tiff.TiffRational;
import loci.formats.tiff.TiffSaver;
public class EyesisTiff {
// private static org.apache.log4j.Logger log= Logger.getLogger(EyesisTiff.class);
public EyesisTiff(){
// Please initialize the log4j system properly
// private static org.apache.log4j.Logger log= Logger.getLogger(EyesisTiff.class);
public EyesisTiff(){
// Please initialize the log4j system properly
}
public void savePNG_ARGB32(
ImagePlus imp,
String path
){
int width = imp.getWidth();
int height = imp.getHeight();
int [] pixels = (int []) imp.getProcessor().getPixels();
System.out.println("width="+width+", height="+height+" length="+pixels.length);
DataBufferInt buffer = new DataBufferInt(pixels, pixels.length);
int[] bandMasks = {0xFF0000, 0xFF00, 0xFF, 0xFF000000}; // ARGB (yes, ARGB, as the masks are R, G, B, A always) order
WritableRaster raster = Raster.createPackedRaster(buffer, width, height, width, bandMasks, null);
ColorModel cm = ColorModel.getRGBdefault();
BufferedImage bimage = new BufferedImage(cm, raster, cm.isAlphaPremultiplied(), null);
try{
(new File(path)).delete(); // Otherwise TiffSaver appends! - is it the same for PNG?
ImageIO.write(bimage, "PNG", (new File(path)));
}
catch(Exception e){
e.printStackTrace();
}
}
}
public void saveTiff(
ImagePlus imp,
String path,
......@@ -63,16 +97,16 @@ public EyesisTiff(){
double scale, // full scale, absolute
boolean imageJTags,
int debugLevel
) throws IOException, FormatException, ServiceException, DependencyException{
if (imp.getType()==ImagePlus.COLOR_RGB) {
if (debugLevel>1) System.out.println("Saving 8-bit TIFF with alpha-channel: "+path);
) throws IOException, FormatException, ServiceException, DependencyException{
if (imp.getType()==ImagePlus.COLOR_RGB) { // 4*8 bit - type = 0
if (debugLevel>1) System.out.println("Saving 8-bit TIFF with alpha-channel: "+path); // is it possible to just add alpha to high bytes?
saveTiffARGB32(imp, path, imageJTags, debugLevel);
return;
} else if (imp.getStackSize()==4) {
if (debugLevel>1) System.out.println("Saving 32-bit float TIFF with alpha-channel: "+path);
saveTiffARGB(imp, path, mode, scale, imageJTags,debugLevel);
return;
}
IJ.showMessage("Not yet implemented for this image type");
}
......@@ -84,142 +118,165 @@ public EyesisTiff(){
double scale, // full scale, absolute
boolean imageJTags,
int debugLevel
) throws IOException, FormatException, ServiceException, DependencyException{
) throws IOException, FormatException, ServiceException, DependencyException{
int IFDImageFullWidth= 0x8214; // not defined in loci.formats.tiff.IFD
int IFDImageFullLength=0x8215; // not defined in loci.formats.tiff.IFD
int IFDImageJByteCounts= 0xc696; // was array {12( if no slices, roi, etc.), bytes in info}
int IFDImageJInfo= 0xc697; // ImageJ info, starting with magic IJIJinfo,
byte [] ImageJInfoMagic={73,74,73,74,105,110,102,111,0,0,0,1};
int pixelsDenominator=1000;
String description=(imp.getProperty("description")!=null)?((String) imp.getProperty("description")):"Elphel Eyesis4pi";
// int [] iPixels= (int []) imp.getProcessor().getPixels();
// int [] iPixels= (int []) imp.getProcessor().getPixels();
final float [][] imagePixels= new float [4][];
for (int c=0;c<imagePixels.length;c++) imagePixels[c]= (float []) imp.getStack().getPixels(c+1); // bytes are little endian
try {
for (int c=0;c<imagePixels.length;c++){
imagePixels[c]= (float []) imp.getStack().getPixels(c+1); // bytes are little endian
}
} catch (ClassCastException e) {
try {
for (int c=0;c<imagePixels.length;c++) {
byte [] bpixels = (byte []) imp.getStack().getPixels(c+1); // bytes are little endian
imagePixels[c] = new float[bpixels.length];
for (int i = 0; i <bpixels.length; i++)
imagePixels[c][i]= ((float) bpixels[i])/255;
}
} catch (ClassCastException e1) {
for (int c=0;c<imagePixels.length;c++) {
short [] spixels = (short []) imp.getStack().getPixels(c+1); // bytes are little endian
imagePixels[c] = new float[spixels.length];
for (int i = 0; i < spixels.length; i++)
imagePixels[c][i]= ((float) spixels[i])/65535;
}
}
}
// for (int i = 0; i < imagePixels[3].length; i++){
// imagePixels[3][i] = 1.0f - imagePixels[3][i];
// }
int bw;
byte [] bytes;
int pIndex=0;
// double s;
int pixelType=0; //int pixelType:INT8, UINT8, INT16, UINT16, INT32, UINT32, FLOAT, BIT, DOUBLE, COMPLEX, DOUBLECOMPLEX; - used to find bpp
switch (mode){
case 0:
int maxVal= 0xff;
double [] s0 ={scale*maxVal,scale*maxVal,scale*maxVal,maxVal};
bw= 1;
pixelType=0; //1; //0; //3; // 0; // should it be 3?
bytes=new byte[imagePixels[0].length*4*bw];
for (int i=0;i<imagePixels[0].length;i++) for (int c=0;c<imagePixels.length;c++){ // r,g,b,alpha
int d= (int) (imagePixels[c][i]*s0[c]);
if (d<0) d=0;
else if (d>maxVal) d= maxVal;
bytes[pIndex++]=(byte) ((d>> 0 )& 0xff);
}
break;
case 1:
int iMaxVal= 0xffff;
double [] s1 ={scale*iMaxVal,scale*iMaxVal,scale*iMaxVal,iMaxVal};
bw= 2;
pixelType=2; //3; //4;
bytes=new byte[imagePixels[0].length*4*bw];
for (int i=0;i<imagePixels[0].length;i++) for (int c=0;c<imagePixels.length;c++){ // r,g,b,alpha
int d= (int) (imagePixels[c][i]*s1[c]);
if (d<0) d=0;
else if (d>iMaxVal) d= iMaxVal;
bytes[pIndex++]=(byte) ((d>> 8 )& 0xff);
bytes[pIndex++]=(byte) ((d>> 0 )& 0xff);
}
break;
case 2:
long lMaxVal= 0xffffffffL;
double [] s2 ={scale*lMaxVal,scale*lMaxVal,scale*lMaxVal,lMaxVal};
bw= 3; //4;
pixelType=5; // 2; //5;
bytes=new byte[imagePixels[0].length*4*bw];
for (int i=0;i<imagePixels[0].length;i++) for (int c=0;c<imagePixels.length;c++){ // r,g,b,alpha
long d= (long) (imagePixels[c][i]*s2[c]);
if (d<0) d=0;
else if (d>lMaxVal) d= lMaxVal;
bytes[pIndex++]=(byte) ((d>>24 )& 0xff);
bytes[pIndex++]=(byte) ((d>>16 )& 0xff);
bytes[pIndex++]=(byte) ((d>> 8 )& 0xff);
bytes[pIndex++]=(byte) ((d>> 0 )& 0xff);
}
break;
case 3:
bw= 4;
pixelType=6;
bytes=new byte[imagePixels[0].length*4*bw];
// what scale should be for alpha 0..1 or 0.. scale?
for (int i=0;i<imagePixels[0].length;i++) for (int c=0;c<imagePixels.length;c++){ // r,g,b,alpha
int d;
if (scale==1.0) d=Float.floatToIntBits(imagePixels[c][i]);
else d=Float.floatToIntBits((float) (imagePixels[c][i]*scale));
bytes[pIndex++]=(byte) ((d>>24 )& 0xff);
bytes[pIndex++]=(byte) ((d>>16 )& 0xff);
bytes[pIndex++]=(byte) ((d>> 8 )& 0xff);
bytes[pIndex++]=(byte) ((d>> 0 )& 0xff);
}
break;
default:
byte [] bytes;
int pIndex=0;
// double s;
int pixelType=0; //int pixelType:INT8, UINT8, INT16, UINT16, INT32, UINT32, FLOAT, BIT, DOUBLE, COMPLEX, DOUBLECOMPLEX; - used to find bpp
switch (mode){
case 0:
int maxVal= 0xff;
double [] s0 ={scale*maxVal,scale*maxVal,scale*maxVal,maxVal};
bw= 1;
pixelType=0; //1; //0; //3; // 0; // should it be 3?
bytes=new byte[imagePixels[0].length*4*bw];
for (int i=0;i<imagePixels[0].length;i++) for (int c=0;c<imagePixels.length;c++){ // r,g,b,alpha
int d= (int) (imagePixels[c][i]*s0[c]);
if (d<0) d=0;
else if (d>maxVal) d= maxVal;
bytes[pIndex++]=(byte) ((d>> 0 )& 0xff);
}
break;
case 1:
int iMaxVal= 0xffff;
double [] s1 ={scale*iMaxVal,scale*iMaxVal,scale*iMaxVal,iMaxVal};
bw= 2;
pixelType=2; //3; //4;
bytes=new byte[imagePixels[0].length*4*bw];
for (int i=0;i<imagePixels[0].length;i++) for (int c=0;c<imagePixels.length;c++){ // r,g,b,alpha
int d= (int) (imagePixels[c][i]*s1[c]);
if (d<0) d=0;
else if (d>iMaxVal) d= iMaxVal;
bytes[pIndex++]=(byte) ((d>> 8 )& 0xff);
bytes[pIndex++]=(byte) ((d>> 0 )& 0xff);
}
break;
case 2:
long lMaxVal= 0xffffffffL;
double [] s2 ={scale*lMaxVal,scale*lMaxVal,scale*lMaxVal,lMaxVal};
bw= 3; //4;
pixelType=5; // 2; //5;
bytes=new byte[imagePixels[0].length*4*bw];
for (int i=0;i<imagePixels[0].length;i++) for (int c=0;c<imagePixels.length;c++){ // r,g,b,alpha
long d= (long) (imagePixels[c][i]*s2[c]);
if (d<0) d=0;
else if (d>lMaxVal) d= lMaxVal;
bytes[pIndex++]=(byte) ((d>>24 )& 0xff);
bytes[pIndex++]=(byte) ((d>>16 )& 0xff);
bytes[pIndex++]=(byte) ((d>> 8 )& 0xff);
bytes[pIndex++]=(byte) ((d>> 0 )& 0xff);
}
break;
case 3:
bw= 4;
pixelType=6;
bytes=new byte[imagePixels[0].length*4*bw];
// what scale should be for alpha 0..1 or 0.. scale?
for (int i=0;i<imagePixels[0].length;i++) for (int c=0;c<imagePixels.length;c++){ // r,g,b,alpha
int d;
if (scale==1.0) d=Float.floatToIntBits(imagePixels[c][i]);
else d=Float.floatToIntBits((float) (imagePixels[c][i]*scale));
bytes[pIndex++]=(byte) ((d>>24 )& 0xff);
bytes[pIndex++]=(byte) ((d>>16 )& 0xff);
bytes[pIndex++]=(byte) ((d>> 8 )& 0xff);
bytes[pIndex++]=(byte) ((d>> 0 )& 0xff);
}
break;
default:
IJ.error("saveTiffARGBFloat32", "Unsupported output format mode ="+mode);
return;
}
// System.out.println("saveTiffARGBFloat32(): mode="+mode+" pixelType="+pixelType+" bw="+bw);
IFD ifd=new IFD();
ifd.put(new Integer(IFD.LITTLE_ENDIAN), new Boolean(false));
// ifd.put(new Integer(IFD.LITTLE_ENDIAN), new Boolean(true));
ifd.put(new Integer(IFD.IMAGE_WIDTH), imp.getWidth());
ifd.put(new Integer(IFD.IMAGE_LENGTH), imp.getHeight());
ifd.put(new Integer(IFD.SAMPLES_PER_PIXEL), 4);
ifd.putIFDValue(IFD.SOFTWARE, "Elphel Eyesis");
ifd.putIFDValue(IFD.IMAGE_DESCRIPTION, description);
// copy some other data?
ifd.putIFDValue(IFD.COMPRESSION, 1); //TiffCompression.UNCOMPRESSED);
ifd.putIFDValue(IFD.PHOTOMETRIC_INTERPRETATION,2); // RGB
ifd.putIFDValue(IFD.EXTRA_SAMPLES,2); // 0 = Unspecified data 1 = Associated alpha data (with pre-multiplied color) 2 = Unassociated alpha data
// int [] bpsArray={8,8,8,8};
// ifd.putIFDValue(IFD.BITS_PER_SAMPLE, bpsArray); // will be done automatically
if (imp.getProperty("XPosition")!=null) {
ifd.putIFDValue(IFD.X_POSITION,
new TiffRational((int) Math.round(pixelsDenominator*Double.parseDouble((String) imp.getProperty("XPosition"))) , pixelsDenominator));
}
if (imp.getProperty("YPosition")!=null) {
ifd.putIFDValue(IFD.Y_POSITION,
new TiffRational((int) Math.round(pixelsDenominator*Double.parseDouble((String) imp.getProperty("YPosition"))) , pixelsDenominator));
}
if (imp.getProperty("ImageFullWidth")!=null){
ifd.putIFDValue(IFDImageFullWidth, (long) Integer.parseInt((String) imp.getProperty("ImageFullWidth")));
}
if (imp.getProperty("ImageFullLength")!=null){
ifd.putIFDValue(IFDImageFullLength, (long) Integer.parseInt((String) imp.getProperty("ImageFullLength")));
}
//TODO: Seems to match ImageJ Info, but it is not recognized :-(
if (imageJTags && (imp.getProperty("Info")!=null) && (imp.getProperty("Info") instanceof String)){
int skipFirstBytes=2;
String info=(String) imp.getProperty("Info");
byte [] bInfoBody=info.getBytes("UTF-16");
int [] bInfo = new int [ImageJInfoMagic.length+bInfoBody.length-skipFirstBytes];
int index=0;
for (int i=0;i<ImageJInfoMagic.length;i++) bInfo[index++]=ImageJInfoMagic[i];
for (int i=skipFirstBytes;i<bInfoBody.length; i++) bInfo[index++]=bInfoBody[i]; // first 2 bytes {-2, -1} ???
long [] imageJcounts={12, bInfoBody.length-skipFirstBytes};
ifd.putIFDValue(IFDImageJByteCounts, imageJcounts);
ifd.putIFDValue(IFDImageJInfo, bInfo);
}
(new File(path)).delete(); // Otherwise TiffSaver appends!
TiffSaver tiffSaver = new TiffSaver(path);
tiffSaver.setWritingSequentially(true);
tiffSaver.setLittleEndian(false);
tiffSaver.writeHeader();
// tiffSaver.writeIFD(ifd,0); //* SHould not write here, some fields are calculated during writeImage, that writes IFD too
// System.out.println("bytes.length="+bytes.length);
tiffSaver.writeImage(bytes,
ifd,
0, //int no,
pixelType, // 0, //int pixelType:INT8, INT16, INT32, UINT8, UINT16, UINT32, FLOAT, BIT, DOUBLE, COMPLEX, DOUBLECOMPLEX; - used to find bpp
true); // boolean last)
}
// System.out.println("saveTiffARGBFloat32(): mode="+mode+" pixelType="+pixelType+" bw="+bw);
IFD ifd=new IFD();
ifd.put(new Integer(IFD.LITTLE_ENDIAN), new Boolean(false));
// ifd.put(new Integer(IFD.LITTLE_ENDIAN), new Boolean(true));
ifd.put(new Integer(IFD.IMAGE_WIDTH), imp.getWidth());
ifd.put(new Integer(IFD.IMAGE_LENGTH), imp.getHeight());
ifd.put(new Integer(IFD.SAMPLES_PER_PIXEL), 4);
ifd.putIFDValue(IFD.SOFTWARE, "Elphel Eyesis");
ifd.putIFDValue(IFD.IMAGE_DESCRIPTION, description);
// copy some other data?
ifd.putIFDValue(IFD.COMPRESSION, 1); //TiffCompression.UNCOMPRESSED);
ifd.putIFDValue(IFD.PHOTOMETRIC_INTERPRETATION,2); // RGB
ifd.putIFDValue(IFD.EXTRA_SAMPLES,2); // 0 = Unspecified data 1 = Associated alpha data (with pre-multiplied color) 2 = Unassociated alpha data
// int [] bpsArray={8,8,8,8};
// ifd.putIFDValue(IFD.BITS_PER_SAMPLE, bpsArray); // will be done automatically
if (imp.getProperty("XPosition")!=null) {
ifd.putIFDValue(IFD.X_POSITION,
new TiffRational((int) Math.round(pixelsDenominator*Double.parseDouble((String) imp.getProperty("XPosition"))) , pixelsDenominator));
}
if (imp.getProperty("YPosition")!=null) {
ifd.putIFDValue(IFD.Y_POSITION,
new TiffRational((int) Math.round(pixelsDenominator*Double.parseDouble((String) imp.getProperty("YPosition"))) , pixelsDenominator));
}
if (imp.getProperty("ImageFullWidth")!=null){
ifd.putIFDValue(IFDImageFullWidth, (long) Integer.parseInt((String) imp.getProperty("ImageFullWidth")));
}
if (imp.getProperty("ImageFullLength")!=null){
ifd.putIFDValue(IFDImageFullLength, (long) Integer.parseInt((String) imp.getProperty("ImageFullLength")));
}
//TODO: Seems to match ImageJ Info, but it is not recognized :-(
if (imageJTags && (imp.getProperty("Info")!=null) && (imp.getProperty("Info") instanceof String)){
int skipFirstBytes=2;
String info=(String) imp.getProperty("Info");
byte [] bInfoBody=info.getBytes("UTF-16");
int [] bInfo = new int [ImageJInfoMagic.length+bInfoBody.length-skipFirstBytes];
int index=0;
for (int i=0;i<ImageJInfoMagic.length;i++) bInfo[index++]=ImageJInfoMagic[i];
for (int i=skipFirstBytes;i<bInfoBody.length; i++) bInfo[index++]=bInfoBody[i]; // first 2 bytes {-2, -1} ???
long [] imageJcounts={12, bInfoBody.length-skipFirstBytes};
ifd.putIFDValue(IFDImageJByteCounts, imageJcounts);
ifd.putIFDValue(IFDImageJInfo, bInfo);
}
(new File(path)).delete(); // Otherwise TiffSaver appends!
TiffSaver tiffSaver = new TiffSaver(path);
tiffSaver.setWritingSequentially(true);
tiffSaver.setLittleEndian(false);
tiffSaver.writeHeader();
// tiffSaver.writeIFD(ifd,0); //* SHould not write here, some fields are calculated during writeImage, that writes IFD too
// System.out.println("bytes.length="+bytes.length);
tiffSaver.writeImage(bytes,
ifd,
0, //int no,
pixelType, // 0, //int pixelType:INT8, INT16, INT32, UINT8, UINT16, UINT32, FLOAT, BIT, DOUBLE, COMPLEX, DOUBLECOMPLEX; - used to find bpp
true); // boolean last)
}
public void saveTiffARGB32(
......@@ -227,66 +284,66 @@ public EyesisTiff(){
String path,
boolean imageJTags,
int debugLevel
) throws IOException, FormatException, ServiceException, DependencyException{
) throws IOException, FormatException, ServiceException, DependencyException{
int IFDImageFullWidth= 0x8214; // not defined in loci.formats.tiff.IFD
int IFDImageFullLength=0x8215; // not defined in loci.formats.tiff.IFD
// public static final int META_DATA_BYTE_COUNTS = 50838; // private tag registered with Adobe
// public static final int META_DATA = 50839; // private tag registered with Adobe
// public static final int META_DATA_BYTE_COUNTS = 50838; // private tag registered with Adobe
// public static final int META_DATA = 50839; // private tag registered with Adobe
int IFDImageJByteCounts= 0xc696; // was array {12( if no slices, roi, etc.), bytes in info}
int IFDImageJInfo= 0xc697; // ImageJ info, starting with magic IJIJinfo,
byte [] ImageJInfoMagic={73,74,73,74,105,110,102,111,0,0,0,1};
int pixelsDenominator=1000;
String description=(imp.getProperty("description")!=null)?((String) imp.getProperty("description")):"Elphel Eyesis4pi";
int [] iPixels= (int []) imp.getProcessor().getPixels();
byte [] bytes=new byte[iPixels.length*4];
int pIndex=0;
for (int i=0;i<iPixels.length;i++){
bytes[pIndex++]=(byte) ((iPixels[i]>>16)& 0xff); // R
bytes[pIndex++]=(byte) ((iPixels[i]>> 8)& 0xff); // G
bytes[pIndex++]=(byte) ((iPixels[i]>> 0)& 0xff); // B
bytes[pIndex++]=(byte) ((iPixels[i]>>24)& 0xff); // alpha
}
IFD ifd=new IFD();
ifd.put(new Integer(IFD.LITTLE_ENDIAN), new Boolean(false));
// ifd.put(new Integer(IFD.LITTLE_ENDIAN), new Boolean(true));
ifd.put(new Integer(IFD.IMAGE_WIDTH), imp.getWidth());
ifd.put(new Integer(IFD.IMAGE_LENGTH), imp.getHeight());
ifd.put(new Integer(IFD.SAMPLES_PER_PIXEL), 4);
ifd.putIFDValue(IFD.SOFTWARE, "Elphel Eyesis");
ifd.putIFDValue(IFD.IMAGE_DESCRIPTION, description);
// copy some other data?
ifd.putIFDValue(IFD.COMPRESSION, 1); //TiffCompression.UNCOMPRESSED);
ifd.putIFDValue(IFD.PHOTOMETRIC_INTERPRETATION,2); // RGB
ifd.putIFDValue(IFD.EXTRA_SAMPLES,2); // extra bytes (over 3) meaning Unassociated alpha data
byte [] bytes=new byte[iPixels.length*4];
int pIndex=0;
for (int i=0;i<iPixels.length;i++){
bytes[pIndex++]=(byte) ((iPixels[i]>>16)& 0xff); // R
bytes[pIndex++]=(byte) ((iPixels[i]>> 8)& 0xff); // G
bytes[pIndex++]=(byte) ((iPixels[i]>> 0)& 0xff); // B
bytes[pIndex++]=(byte) ((iPixels[i]>>24)& 0xff); // alpha
}
IFD ifd=new IFD();
ifd.put(new Integer(IFD.LITTLE_ENDIAN), new Boolean(false));
// ifd.put(new Integer(IFD.LITTLE_ENDIAN), new Boolean(true));
ifd.put(new Integer(IFD.IMAGE_WIDTH), imp.getWidth());
ifd.put(new Integer(IFD.IMAGE_LENGTH), imp.getHeight());
ifd.put(new Integer(IFD.SAMPLES_PER_PIXEL), 4);
ifd.putIFDValue(IFD.SOFTWARE, "Elphel Eyesis");
ifd.putIFDValue(IFD.IMAGE_DESCRIPTION, description);
// copy some other data?
ifd.putIFDValue(IFD.COMPRESSION, 1); //TiffCompression.UNCOMPRESSED);
ifd.putIFDValue(IFD.PHOTOMETRIC_INTERPRETATION,2); // RGB
ifd.putIFDValue(IFD.EXTRA_SAMPLES,2); // extra bytes (over 3) meaning Unassociated alpha data
// int [] bpsArray={8,8,8,8};
// ifd.putIFDValue(IFD.BITS_PER_SAMPLE, bpsArray); // will be done automatically
if (imp.getProperty("XPosition")!=null) {
ifd.putIFDValue(IFD.X_POSITION,
new TiffRational((int) Math.round(pixelsDenominator*Double.parseDouble((String) imp.getProperty("XPosition"))) , pixelsDenominator));
}
if (imp.getProperty("YPosition")!=null) {
ifd.putIFDValue(IFD.Y_POSITION,
new TiffRational((int) Math.round(pixelsDenominator*Double.parseDouble((String) imp.getProperty("YPosition"))) , pixelsDenominator));
}
if (imp.getProperty("ImageFullWidth")!=null){
ifd.putIFDValue(IFDImageFullWidth, (long) Integer.parseInt((String) imp.getProperty("ImageFullWidth")));
}
if (imp.getProperty("ImageFullLength")!=null){
ifd.putIFDValue(IFDImageFullLength, (long) Integer.parseInt((String) imp.getProperty("ImageFullLength")));
}
//TODO: Seems to match ImageJ Info, but it is not recognized :-(
if (imageJTags && (imp.getProperty("Info")!=null) && (imp.getProperty("Info") instanceof String)){
int skipFirstBytes=2;
String info=(String) imp.getProperty("Info");
byte [] bInfoBody=info.getBytes("UTF-16");
int [] bInfo = new int [ImageJInfoMagic.length+bInfoBody.length-skipFirstBytes];
int index=0;
for (int i=0;i<ImageJInfoMagic.length;i++) bInfo[index++]=ImageJInfoMagic[i];
for (int i=skipFirstBytes;i<bInfoBody.length; i++) bInfo[index++]=bInfoBody[i]; // first 2 bytes {-2, -1} ???
/*
// int [] bpsArray={8,8,8,8};
// ifd.putIFDValue(IFD.BITS_PER_SAMPLE, bpsArray); // will be done automatically
if (imp.getProperty("XPosition")!=null) {
ifd.putIFDValue(IFD.X_POSITION,
new TiffRational((int) Math.round(pixelsDenominator*Double.parseDouble((String) imp.getProperty("XPosition"))) , pixelsDenominator));
}
if (imp.getProperty("YPosition")!=null) {
ifd.putIFDValue(IFD.Y_POSITION,
new TiffRational((int) Math.round(pixelsDenominator*Double.parseDouble((String) imp.getProperty("YPosition"))) , pixelsDenominator));
}
if (imp.getProperty("ImageFullWidth")!=null){
ifd.putIFDValue(IFDImageFullWidth, (long) Integer.parseInt((String) imp.getProperty("ImageFullWidth")));
}
if (imp.getProperty("ImageFullLength")!=null){
ifd.putIFDValue(IFDImageFullLength, (long) Integer.parseInt((String) imp.getProperty("ImageFullLength")));
}
//TODO: Seems to match ImageJ Info, but it is not recognized :-(
if (imageJTags && (imp.getProperty("Info")!=null) && (imp.getProperty("Info") instanceof String)){
int skipFirstBytes=2;
String info=(String) imp.getProperty("Info");
byte [] bInfoBody=info.getBytes("UTF-16");
int [] bInfo = new int [ImageJInfoMagic.length+bInfoBody.length-skipFirstBytes];
int index=0;
for (int i=0;i<ImageJInfoMagic.length;i++) bInfo[index++]=ImageJInfoMagic[i];
for (int i=skipFirstBytes;i<bInfoBody.length; i++) bInfo[index++]=bInfoBody[i]; // first 2 bytes {-2, -1} ???
/*
StringBuffer sb=new StringBuffer("bInfo: ");
for (int i=0;i<bInfo.length;i++) sb.append(bInfo[i]+" ");
System.out.println(sb.toString());
......@@ -299,29 +356,29 @@ public EyesisTiff(){
System.out.println("info[0]="+info.charAt(0));
System.out.println("info[1]="+info.charAt(1));
System.out.println("info[2]="+info.charAt(2));
*/
long [] imageJcounts={12, bInfoBody.length-skipFirstBytes};
ifd.putIFDValue(IFDImageJByteCounts, imageJcounts);
ifd.putIFDValue(IFDImageJInfo, bInfo);
}
(new File(path)).delete(); // Otherwise TiffSaver appends!
TiffSaver tiffSaver = new TiffSaver(path);
tiffSaver.setWritingSequentially(true);
tiffSaver.setLittleEndian(false);
tiffSaver.writeHeader();
// tiffSaver.writeIFD(ifd,0); //* SHould not write here, some fields are calculated during writeImage, that writes IFD too
System.out.println("bytes.length="+bytes.length);
tiffSaver.writeImage(bytes,
ifd,
0, //int no,
0, //int pixelType:INT8, INT16, INT32, UINT8, UINT16, UINT32, FLOAT, BIT, DOUBLE, COMPLEX, DOUBLECOMPLEX; - used to find bpp
true); // boolean last)
*/
long [] imageJcounts={12, bInfoBody.length-skipFirstBytes};
ifd.putIFDValue(IFDImageJByteCounts, imageJcounts);
ifd.putIFDValue(IFDImageJInfo, bInfo);
}
(new File(path)).delete(); // Otherwise TiffSaver appends!
TiffSaver tiffSaver = new TiffSaver(path);
tiffSaver.setWritingSequentially(true);
tiffSaver.setLittleEndian(false);
tiffSaver.writeHeader();
// tiffSaver.writeIFD(ifd,0); //* SHould not write here, some fields are calculated during writeImage, that writes IFD too
System.out.println("bytes.length="+bytes.length);
tiffSaver.writeImage(bytes,
ifd,
0, //int no,
0, //int pixelType:INT8, INT16, INT32, UINT8, UINT16, UINT32, FLOAT, BIT, DOUBLE, COMPLEX, DOUBLECOMPLEX; - used to find bpp
true); // boolean last)
}
public void propertiesTiff(ImagePlus imp){
FileInfo fi = imp.getOriginalFileInfo();
if ((fi==null) ||(fi.directory==null) || (fi.fileFormat!=FileInfo.TIFF)) {
......@@ -340,55 +397,55 @@ public EyesisTiff(){
if (log!=null) log.toFront();
}
public static void dumpIFDs(String path) throws IOException {
IJ.showStatus("Parsing IFDs");
RandomAccessInputStream in = new RandomAccessInputStream(path);
//TiffParser parser = new TiffParser(in);
TiffParser parser = new TiffParser(in);
IFDList ifdList = parser.getIFDs();
IJ.showStatus("");
for (IFD ifd : ifdList) {
for (Integer key : ifd.keySet()) {
int k = key.intValue();
String name = IFD.getIFDTagName(k)+String.format("(%d [0x%x])", k,k);
String value = prettyValue(ifd.getIFDValue(k), 0);
IJ.log(name + " = " + value);
}
}
in.close();
}
private static String prettyValue(Object value, int indent) {
if (!value.getClass().isArray()) return value.toString()+" ("+value.getClass().toString()+")";
char[] spaceChars = new char[indent];
Arrays.fill(spaceChars, ' ');
String spaces = new String(spaceChars);
StringBuilder sb = new StringBuilder();
sb.append("{\n");
for (int i=0; i<Array.getLength(value); i++) {
sb.append(spaces);
sb.append(" ");
Object component = Array.get(value, i);
sb.append(prettyValue(component, indent + 2));
sb.append("\n");
}
sb.append(spaces);
sb.append("}");
byte [] bstring=new byte [Array.getLength(value)];
for (int i=0;i<bstring.length;i++) bstring[i]= (byte) Integer.parseInt(Array.get(value, i).toString());
public static void dumpIFDs(String path) throws IOException {
IJ.showStatus("Parsing IFDs");
RandomAccessInputStream in = new RandomAccessInputStream(path);
//TiffParser parser = new TiffParser(in);
TiffParser parser = new TiffParser(in);
IFDList ifdList = parser.getIFDs();
IJ.showStatus("");
for (IFD ifd : ifdList) {
for (Integer key : ifd.keySet()) {
int k = key.intValue();
String name = IFD.getIFDTagName(k)+String.format("(%d [0x%x])", k,k);
String value = prettyValue(ifd.getIFDValue(k), 0);
IJ.log(name + " = " + value);
}
}
in.close();
}
private static String prettyValue(Object value, int indent) {
if (!value.getClass().isArray()) return value.toString()+" ("+value.getClass().toString()+")";
char[] spaceChars = new char[indent];
Arrays.fill(spaceChars, ' ');
String spaces = new String(spaceChars);
StringBuilder sb = new StringBuilder();
sb.append("{\n");
for (int i=0; i<Array.getLength(value); i++) {
sb.append(spaces);
sb.append(" ");
Object component = Array.get(value, i);
sb.append(prettyValue(component, indent + 2));
sb.append("\n");
}
sb.append(spaces);
sb.append("}");
byte [] bstring=new byte [Array.getLength(value)];
for (int i=0;i<bstring.length;i++) bstring[i]= (byte) Integer.parseInt(Array.get(value, i).toString());
// String astring=new String((byte []) value);
String astring="";
String astring="";
try {
astring = new String(bstring,"UTF-16");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
sb.append("\n\""+astring+"\"");
return sb.toString();
}
sb.append("\n\""+astring+"\"");
return sb.toString();
}
}
......@@ -256,7 +256,9 @@ private Panel panel1,
0.075, // b_min;
1.0, // r_max;
1.0, // g_max;
1.0 // b_max;
1.0, // b_max;
0.0, // alpha_min;
1.0 // alpha_max;
);
public static EyesisCorrectionParameters.ProcessParameters PROCESS_PARAMETERS= new EyesisCorrectionParameters.ProcessParameters (
true, //eyesisMode
......@@ -498,6 +500,11 @@ private Panel panel1,
addButton("CLT process quads", panelClt1, color_process);
addButton("CLT process corr", panelClt1, color_process);
addButton("CLT disparity scan", panelClt1, color_conf_process);
addButton("CLT reset fine corr", panelClt1, color_stop);
addButton("CLT show fine corr", panelClt1, color_configure);
addButton("CLT apply fine corr", panelClt1, color_process);
addButton("CLT reset 3D", panelClt1, color_stop);
addButton("CLT 3D", panelClt1, color_conf_process);
add(panelClt1);
}
......@@ -1021,7 +1028,8 @@ private Panel panel1,
imp_colorStack.getTitle()+"-RGB24",
0, 65536, // r range 0->0, 65536->256
0, 65536, // g range
0, 65536);// b range
0, 65536,// b range
0, 65536);// alpha range
imp_RGB24.setTitle(imp_colorStack.getTitle()+"rgb24");
imp_RGB24.show();
return;
......@@ -2857,6 +2865,7 @@ private Panel panel1,
EYESIS_CORRECTIONS.setDebug(DEBUG_LEVEL);
if (EYESIS_DCT == null){
EYESIS_DCT = new EyesisDCT (
PROPERTIES,
EYESIS_CORRECTIONS,
CORRECTION_PARAMETERS,
DCT_PARAMETERS);
......@@ -3232,6 +3241,7 @@ private Panel panel1,
}
if (EYESIS_DCT == null){
EYESIS_DCT = new EyesisDCT (
PROPERTIES,
EYESIS_CORRECTIONS,
CORRECTION_PARAMETERS,
DCT_PARAMETERS);
......@@ -3377,6 +3387,7 @@ private Panel panel1,
}
if (EYESIS_DCT == null){
EYESIS_DCT = new EyesisDCT (
PROPERTIES,
EYESIS_CORRECTIONS,
CORRECTION_PARAMETERS,
DCT_PARAMETERS);
......@@ -3499,6 +3510,7 @@ private Panel panel1,
if (!DCT_PARAMETERS.showDialog()) return;
if (EYESIS_DCT == null){
EYESIS_DCT = new EyesisDCT (
PROPERTIES,
EYESIS_CORRECTIONS,
CORRECTION_PARAMETERS,
DCT_PARAMETERS);
......@@ -3514,6 +3526,7 @@ private Panel panel1,
if (!DCT_PARAMETERS.showDialog()) return;
if (EYESIS_DCT == null){
EYESIS_DCT = new EyesisDCT (
PROPERTIES,
EYESIS_CORRECTIONS,
CORRECTION_PARAMETERS,
DCT_PARAMETERS);
......@@ -3562,6 +3575,7 @@ private Panel panel1,
if (!DCT_PARAMETERS.showDialog()) return;
if (EYESIS_DCT == null){
EYESIS_DCT = new EyesisDCT (
PROPERTIES,
EYESIS_CORRECTIONS,
CORRECTION_PARAMETERS,
DCT_PARAMETERS);
......@@ -4046,6 +4060,7 @@ private Panel panel1,
if (!CLT_PARAMETERS.showDialog()) return;
if (EYESIS_DCT == null){
EYESIS_DCT = new EyesisDCT (
PROPERTIES,
EYESIS_CORRECTIONS,
CORRECTION_PARAMETERS,
DCT_PARAMETERS);
......@@ -4096,6 +4111,7 @@ private Panel panel1,
if (!CLT_PARAMETERS.showDialog()) return;
if (EYESIS_DCT == null){
EYESIS_DCT = new EyesisDCT (
PROPERTIES,
EYESIS_CORRECTIONS,
CORRECTION_PARAMETERS,
DCT_PARAMETERS);
......@@ -4147,6 +4163,7 @@ private Panel panel1,
EYESIS_CORRECTIONS.setDebug(DEBUG_LEVEL);
if (EYESIS_DCT == null){
EYESIS_DCT = new EyesisDCT (
PROPERTIES,
EYESIS_CORRECTIONS,
CORRECTION_PARAMETERS,
DCT_PARAMETERS);
......@@ -4233,6 +4250,7 @@ private Panel panel1,
EYESIS_CORRECTIONS.setDebug(DEBUG_LEVEL);
if (EYESIS_DCT == null){
EYESIS_DCT = new EyesisDCT (
PROPERTIES,
EYESIS_CORRECTIONS,
CORRECTION_PARAMETERS,
DCT_PARAMETERS);
......@@ -4328,6 +4346,7 @@ private Panel panel1,
EYESIS_CORRECTIONS.setDebug(DEBUG_LEVEL);
if (EYESIS_DCT == null){
EYESIS_DCT = new EyesisDCT (
PROPERTIES,
EYESIS_CORRECTIONS,
CORRECTION_PARAMETERS,
DCT_PARAMETERS);
......@@ -4419,11 +4438,13 @@ private Panel panel1,
return;
} else if (label.equals("CLT process corr")) {
} else if (label.equals("CLT process corr") || label.equals("CLT apply fine corr")) {
boolean apply_corr = label.equals("CLT apply fine corr");
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
EYESIS_CORRECTIONS.setDebug(DEBUG_LEVEL);
if (EYESIS_DCT == null){
EYESIS_DCT = new EyesisDCT (
PROPERTIES,
EYESIS_CORRECTIONS,
CORRECTION_PARAMETERS,
DCT_PARAMETERS);
......@@ -4501,6 +4522,7 @@ private Panel panel1,
RGB_PARAMETERS, //EyesisCorrectionParameters.RGBParameters rgbParameters,
EQUIRECTANGULAR_PARAMETERS, // EyesisCorrectionParameters.EquirectangularParameters equirectangularParameters,
CONVOLVE_FFT_SIZE, //int convolveFFTSize, // 128 - fft size, kernel size should be size/2
apply_corr,
THREADS_MAX, //final int threadsMax, // maximal number of threads to launch
UPDATE_STATUS, //final boolean updateStatus,
DEBUG_LEVEL); //final int debugLevel);
......@@ -4513,13 +4535,39 @@ private Panel panel1,
PROPERTIES);
}
return;
} else if (label.equals("CLT reset fine corr")) {
if (EYESIS_DCT == null){
EYESIS_DCT = new EyesisDCT (
PROPERTIES,
EYESIS_CORRECTIONS,
CORRECTION_PARAMETERS,
DCT_PARAMETERS);
if (DEBUG_LEVEL > 0){
System.out.println("Created new EyesisDCT instance, will need to read CLT kernels");
}
}
EYESIS_DCT.reset_fine_corr();
return;
} else if (label.equals("CLT show fine corr")) {
if (EYESIS_DCT == null){
EYESIS_DCT = new EyesisDCT (
PROPERTIES,
EYESIS_CORRECTIONS,
CORRECTION_PARAMETERS,
DCT_PARAMETERS);
if (DEBUG_LEVEL > 0){
System.out.println("Created new EyesisDCT instance, will need to read CLT kernels");
}
}
EYESIS_DCT.show_fine_corr();
return;
} else if (label.equals("CLT disparity scan")) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
EYESIS_CORRECTIONS.setDebug(DEBUG_LEVEL);
if (EYESIS_DCT == null){
EYESIS_DCT = new EyesisDCT (
PROPERTIES,
EYESIS_CORRECTIONS,
CORRECTION_PARAMETERS,
DCT_PARAMETERS);
......@@ -4610,7 +4658,117 @@ private Panel panel1,
}
return;
} else if (label.equals("CLT reset 3D")) {
if (EYESIS_DCT == null){
EYESIS_DCT = new EyesisDCT (
PROPERTIES,
EYESIS_CORRECTIONS,
CORRECTION_PARAMETERS,
DCT_PARAMETERS);
if (DEBUG_LEVEL > 0){
System.out.println("Created new EyesisDCT instance, will need to read CLT kernels");
}
}
EYESIS_DCT.resetCLTPasses();
return;
/// ============================================
} else if (label.equals("CLT 3D")) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
EYESIS_CORRECTIONS.setDebug(DEBUG_LEVEL);
if (EYESIS_DCT == null){
EYESIS_DCT = new EyesisDCT (
PROPERTIES,
EYESIS_CORRECTIONS,
CORRECTION_PARAMETERS,
DCT_PARAMETERS);
if (DEBUG_LEVEL > 0){
System.out.println("Created new EyesisDCT instance, will need to read CLT kernels");
}
}
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);
int numChannels=EYESIS_CORRECTIONS.getNumChannels();
NONLIN_PARAMETERS.modifyNumChannels(numChannels);
CHANNEL_GAINS_PARAMETERS.modifyNumChannels(numChannels);
if (!EYESIS_DCT.CLTKernelsAvailable()){
if (DEBUG_LEVEL > 0){
System.out.println("Reading CLT kernels");
}
EYESIS_DCT.readCLTKernels(
CLT_PARAMETERS,
THREADS_MAX,
UPDATE_STATUS, // update status info
DEBUG_LEVEL);
if (DEBUG_LEVEL > 1){
EYESIS_DCT.showCLTKernels(
THREADS_MAX,
UPDATE_STATUS, // update status info
DEBUG_LEVEL);
}
}
if (!EYESIS_DCT.geometryCorrectionAvailable()){
if (DEBUG_LEVEL > 0){
System.out.println("Calculating geometryCorrection");
}
if (!EYESIS_DCT.initGeometryCorrection(DEBUG_LEVEL+2)){
return;
}
}
EYESIS_DCT.processCLTQuads3d(
CLT_PARAMETERS, // EyesisCorrectionParameters.DCTParameters dct_parameters,
DEBAYER_PARAMETERS, //EyesisCorrectionParameters.DebayerParameters debayerParameters,
NONLIN_PARAMETERS, //EyesisCorrectionParameters.NonlinParameters nonlinParameters,
COLOR_PROC_PARAMETERS, //EyesisCorrectionParameters.ColorProcParameters colorProcParameters,
CHANNEL_GAINS_PARAMETERS, //CorrectionColorProc.ColorGainsParameters channelGainParameters,
RGB_PARAMETERS, //EyesisCorrectionParameters.RGBParameters rgbParameters,
EQUIRECTANGULAR_PARAMETERS, // EyesisCorrectionParameters.EquirectangularParameters equirectangularParameters,
// CONVOLVE_FFT_SIZE, //int convolveFFTSize, // 128 - fft size, kernel size should be size/2
THREADS_MAX, //final int threadsMax, // maximal number of threads to launch
UPDATE_STATUS, //final boolean updateStatus,
DEBUG_LEVEL); //final int debugLevel);
if (configPath!=null) {
saveTimestampedProperties( // save config again
configPath, // full path or null
null, // use as default directory if path==null
true,
PROPERTIES);
}
return;
......@@ -5003,19 +5161,21 @@ private Panel panel1,
int i,j;
float [] fpixels;
short [] spixels;
double [] mins= {rgbParameters.r_min,rgbParameters.g_min,rgbParameters.b_min};
double [] maxs= {rgbParameters.r_max,rgbParameters.g_max,rgbParameters.b_max};
if (stack32.getSize()<3) return null;
int numSlices = stack32.getSize();
if (numSlices > 4) numSlices = 4;
if (numSlices < 3) return null;
double [] mins= {rgbParameters.r_min, rgbParameters.g_min, rgbParameters.b_min, rgbParameters.alpha_min};
double [] maxs= {rgbParameters.r_max, rgbParameters.g_max, rgbParameters.b_max, rgbParameters.alpha_max};
double value;
double scale;
for (i=0;i<3;i++) {
fpixels= (float[])stack32.getPixels(i+1);
scale=65535.0/(maxs[i]-mins[i]);
for (i = 0; i < numSlices; i++) {
fpixels= (float[])stack32.getPixels(i + 1);
scale=65535.0 / (maxs[i] - mins[i]);
spixels=new short [length];
for (j=0;j<length;j++) {
for (j = 0; j < length; j++) {
value=(fpixels[j]-mins[i])*scale;
if (value<0.0) value=0.0;
else if (value>65535.0) value=65535.0;
if (value<0.0) value = 0.0;
else if (value>65535.0) value = 65535.0;
spixels[j]=(short)(value+0.5);
}
stack16.addSlice(stack32.getSliceLabel(i+1), spixels);
......@@ -5032,26 +5192,30 @@ private Panel panel1,
int g_min,
int g_max,
int b_min,
int b_max){
int [] mins= {r_min,g_min,b_min};
int [] maxs= {r_max,g_max,b_max};
int b_max,
int alpha_min,
int alpha_max){
int [] mins= {r_min,g_min,b_min,alpha_min};
int [] maxs= {r_max,g_max,b_max,alpha_max};
int i;
int length=stack16.getWidth()*stack16.getHeight();
short [][] spixels=new short[3][];
int numSlices = stack16.getSize();
if (numSlices > 4) numSlices = 4;
short [][] spixels=new short[numSlices][];
int [] pixels=new int[length];
int c,d;
double [] scale=new double[3];
for (c=0;c<3;c++) {
double [] scale=new double[numSlices];
for (c = 0; c < numSlices; c++) {
scale[c]=256.0/(maxs[c]-mins[c]);
}
for (i=0;i<3;i++) spixels[i]= (short[])stack16.getPixels(i+1);
for (i=0;i<length;i++) {
for (i = 0; i < numSlices; i++) spixels[i]= (short[])stack16.getPixels(i+1);
for (i = 0; i < length; i++) {
pixels[i]=0;
for (c=0;c<3;c++) {
for (c=0;c < numSlices;c++) {
d=(int)(((spixels[c][i]& 0xffff)-mins[c])*scale[c]);
if (d>255) d=255;
else if (d<0) d=0;
pixels[i]= d | (pixels[i]<<8);
if (d > 255) d=255;
else if (d < 0) d=0;
pixels[i]= d | (pixels[i] << 8);
}
}
ColorProcessor cp=new ColorProcessor(stack16.getWidth(),stack16.getHeight());
......@@ -5233,7 +5397,8 @@ private Panel panel1,
properties.setProperty("CONVOLVE_FFT_SIZE",CONVOLVE_FFT_SIZE+""); //128, FFT size for sliding convolution with kernel
properties.setProperty("THREADS_MAX",THREADS_MAX+""); // 100, testing multi-threading, limit maximal number of threads
properties.setProperty("GAUSS_WIDTH",GAUSS_WIDTH+""); // 0.4 (0 - use Hamming window)
properties.setProperty("PSF_SUBPIXEL_SHOULD_BE_4",PSF_SUBPIXEL_SHOULD_BE_4+""); // 4, sub-pixel decimation
properties.setProperty("PSF_SUBPIXEL_SHOULD_BE_4",PSF_SUBPIXEL_SHOULD_BE_4+""); // 4, sub-pixel decimation
if (EYESIS_DCT != null) EYESIS_DCT.setProperties();
}
/* ======================================================================== */
public void getAllProperties(Properties properties){
......@@ -5256,7 +5421,9 @@ private Panel panel1,
CONVOLVE_FFT_SIZE=Integer.parseInt(properties.getProperty("CONVOLVE_FFT_SIZE"));
THREADS_MAX=Integer.parseInt(properties.getProperty("THREADS_MAX"));
GAUSS_WIDTH=Double.parseDouble(properties.getProperty("GAUSS_WIDTH"));
PSF_SUBPIXEL_SHOULD_BE_4=Integer.parseInt(properties.getProperty("PSF_SUBPIXEL_SHOULD_BE_4"));
PSF_SUBPIXEL_SHOULD_BE_4=Integer.parseInt(properties.getProperty("PSF_SUBPIXEL_SHOULD_BE_4"));
if (EYESIS_DCT != null) EYESIS_DCT.getProperties();
}
/* ======================================================================== */
......@@ -5860,7 +6027,8 @@ private Panel panel1,
title+"-RGB24",
0, 65536, // r range 0->0, 65536->256
0, 65536, // g range
0, 65536);// b range
0, 65536,// b range
0, 65536);// alpha range
if (processParameters.JPEG_scale!=1.0){
ImageProcessor ip=imp_RGB24.getProcessor();
ip.setInterpolationMethod(ImageProcessor.BICUBIC);
......@@ -7267,6 +7435,8 @@ G= Y +Pr*(- 2*Kr*(1-Kr))/Kg + Pb*(-2*Kb*(1-Kb))/Kg
gd.addNumericField("Red color white level", rgbParameters.r_max, 3);
gd.addNumericField("Green color white level", rgbParameters.g_max, 3);
gd.addNumericField("Blue color white level", rgbParameters.b_max, 3);
gd.addNumericField("Alpha channel min", rgbParameters.alpha_min, 3);
gd.addNumericField("Alpha channel max", rgbParameters.alpha_max, 3);
gd.showDialog();
if (gd.wasCanceled()) return false;
rgbParameters.r_min= gd.getNextNumber();
......@@ -7275,6 +7445,8 @@ G= Y +Pr*(- 2*Kr*(1-Kr))/Kg + Pb*(-2*Kb*(1-Kb))/Kg
rgbParameters.r_max= gd.getNextNumber();
rgbParameters.g_max= gd.getNextNumber();
rgbParameters.b_max= gd.getNextNumber();
rgbParameters.alpha_min= gd.getNextNumber();
rgbParameters.alpha_max= gd.getNextNumber();
return true;
}
......
......@@ -47,6 +47,8 @@ public class ImageDtt {
{1,2,4,5}, // bottom left
{0,1,2,3,4,5}, // mottom middle
{0,1,3,4}}; // bottom right
public static int FORCE_DISPARITY_BIT = 8; // move to parameters?
public ImageDtt(){
......@@ -920,7 +922,8 @@ public class ImageDtt {
public double [][][][][][] clt_aberrations_quad_corr(
final int [][] tile_op, // [tilesY][tilesX] - what to do - 0 - nothing for this tile
final double disparity,
// final double disparity,
final double [][] disparity_array, // [tilesY][tilesX] - individual per-tile expected disparity
final double [][][] image_data, // first index - number of image in a quad
// correlation results - final and partial
final double [][][][] clt_corr_combo, // [type][tilesY][tilesX][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate
......@@ -931,7 +934,7 @@ public class ImageDtt {
// [tilesY][tilesX] should be set by caller
final double [][] clt_mismatch, // [12][tilesY * tilesX] // transpose unapplied. null - do not calculate
final double [][] disparity_map, // [8][tilesY][tilesX], only [6][] is needed on input or null - do nat calculate
final double [][] disparity_map, // [8][tilesY][tilesX], only [6][] is needed on input or null - do not calculate
// last 2 - contrast, avg/ "geometric average)
final double [][][][] texture_tiles, // [tilesY][tilesX]["RGBA".length()][]; null - will skip images combining
......@@ -954,6 +957,7 @@ public class ImageDtt {
final double diff_threshold, // 5.0; // RMS difference from average to discard channel (~ 1.0 - 1/255 full scale image)
final boolean diff_gauss, // true; // when averaging images, use gaussian around average as weight (false - sharp all/nothing)
final double min_agree, // 3.0; // minimal number of channels to agree on a point (real number to work with fuzzy averages)
final boolean dust_remove, // Do not reduce average weight when only one image differes much from the average
final boolean keep_weights, // Add port weights to RGBA stack (debug feature)
final GeometryCorrection geometryCorrection,
final double [][][][][][] clt_kernels, // [channel_in_quad][color][tileY][tileX][band][pixel] , size should match image (have 1 tile around)
......@@ -961,6 +965,8 @@ public class ImageDtt {
final int transform_size,
final int window_type,
final double [][] shiftXY, // [port]{shiftX,shiftY}
final double [][][] fine_corr, // quadratic cofficients for fine correction (or null)
final double corr_magic_scale, // stil not understood coefficent that reduces reported disparity value. Seems to be around 8.5
final double shiftX, // shift image horizontally (positive - right) - just for testing
final double shiftY, // shift image vertically (positive - down)
final int debug_tileX,
......@@ -973,7 +979,8 @@ public class ImageDtt {
{
final int quad = 4; // number of subcameras
final int numcol = 3; // number of colors
final int force_disparity_bit = 8; // move to parameters?
final int FORCE_DISPARITY_BIT = 8; // move to parameters?
final int disparity_maxdiff_index = 8;
final int nChn = image_data[0].length;
final int height=image_data[0][0].length/width;
final int tilesX=width/transform_size;
......@@ -1059,7 +1066,7 @@ public class ImageDtt {
System.out.println("max_search_radius= "+max_search_radius);
System.out.println("max_search_radius_poly="+max_search_radius_poly);
System.out.println("corr_fat_zero= "+corr_fat_zero);
System.out.println("disparity= "+ disparity);
System.out.println("disparity_array[0][0]= "+disparity_array[0][0]);
}
......@@ -1126,19 +1133,19 @@ public class ImageDtt {
double [][] centersXY = geometryCorrection.getPortsCoordinates(
centerX,
centerY,
disparity);
disparity_array[tileY][tileX]);
// if ((globalDebugLevel > 0) && (tileX >= debug_tileX - 2) && (tileX <= debug_tileX + 2) &&
// (tileY >= debug_tileY - 2) && (tileY <= debug_tileY+2)) {
if ((globalDebugLevel > 0) && (tileX == debug_tileX) && (tileY == debug_tileY)) {
for (int i = 0; i < quad; i++) {
System.out.println("clt_aberrations_quad_corr(): color="+chn+", tileX="+tileX+", tileY="+tileY+
" centerX="+centerX+" centerY="+centerY+" disparity="+disparity+
" centerX="+centerX+" centerY="+centerY+" disparity="+disparity_array[tileY][tileX]+
" centersXY["+i+"][0]="+centersXY[i][0]+" centersXY["+i+"][1]="+centersXY[i][1]);
}
}
if ((globalDebugLevel > -1) && (tileX == debug_tileX) && (tileY == debug_tileY) && (chn == 2)) { // before correction
System.out.print(disparity+"\t"+
System.out.print(disparity_array[tileY][tileX]+"\t"+
centersXY[0][0]+"\t"+centersXY[0][1]+"\t"+
centersXY[1][0]+"\t"+centersXY[1][1]+"\t"+
centersXY[2][0]+"\t"+centersXY[2][1]+"\t"+
......@@ -1149,9 +1156,25 @@ public class ImageDtt {
centersXY[ip][0] -= shiftXY[ip][0];
centersXY[ip][1] -= shiftXY[ip][1];
}
if (fine_corr != null){
double tX = (2.0 * tileX)/tilesX - 1.0; // -1.0 to +1.0
double tY = (2.0 * tileY)/tilesY - 1.0; // -1.0 to +1.0
for (int ip = 0; ip < centersXY.length; ip++){
//f(x,y)=A*x^2+B*y^2+C*x*y+D*x+E*y+F
for (int d = 0; d <2; d++)
centersXY[ip][d] -= (
fine_corr[ip][d][0]*tX*tX+
fine_corr[ip][d][1]*tY*tY+
fine_corr[ip][d][2]*tX*tY+
fine_corr[ip][d][3]*tX+
fine_corr[ip][d][4]*tY+
fine_corr[ip][d][5]);
}
}
if ((globalDebugLevel > -1) && (tileX == debug_tileX) && (tileY == debug_tileY) && (chn == 2)) {
System.out.print(disparity+"\t"+
System.out.print(disparity_array[tileY][tileX]+"\t"+
centersXY[0][0]+"\t"+centersXY[0][1]+"\t"+
centersXY[1][0]+"\t"+centersXY[1][1]+"\t"+
centersXY[2][0]+"\t"+centersXY[2][1]+"\t"+
......@@ -1499,15 +1522,15 @@ public class ImageDtt {
if (texture_tiles !=null) {
if ((extra_disparity != 0) && (((1 << force_disparity_bit) & tile_op[tileY][tileX]) == 0)){ // 0 - adjust disparity, 1 - uase provided
if ((extra_disparity != 0) && (((1 << FORCE_DISPARITY_BIT) & tile_op[tileY][tileX]) == 0)){ // 0 - adjust disparity, 1 - use provided
// shift images by 0.5 * extra disparity in the diagonal direction
for (int chn = 0; chn <numcol; chn++) { // color
for (int i = 0; i < quad; i++) {
fract_shift( // fractional shift in transform domain. Currently uses sin/cos - change to tables with 2? rotations
clt_data[i][chn][tileY][tileX], // double [][] clt_tile,
transform_size,
extra_disparity * port_offsets[i][0], // double shiftX,
extra_disparity * port_offsets[i][1], // double shiftY,
extra_disparity * port_offsets[i][0] / corr_magic_scale, // double shiftX,
extra_disparity * port_offsets[i][1] / corr_magic_scale, // double shiftY,
// (globalDebugLevel > 0) && (tileX == debug_tileX) && (tileY == debug_tileY)); // external tile compare
((globalDebugLevel > 0) && (chn==0) && (tileX >= debug_tileX - 2) && (tileX <= debug_tileX + 2) &&
(tileY >= debug_tileY - 2) && (tileY <= debug_tileY+2)));
......@@ -1587,21 +1610,24 @@ public class ImageDtt {
}
sdfa_instance.showArrays(dbg_tile, 2* transform_size, 2* transform_size, true, "tiles_debayered_x"+tileX+"_y"+tileY, titles);
}
double [] max_diff = null;
if ((disparity_map != null) && (disparity_map.length >= (disparity_maxdiff_index + quad))){
max_diff = new double[quad];
}
texture_tiles[tileY][tileX] = tile_combine_rgba(
tiles_debayered, // iclt_tile, // [port][numcol][256]
max_diff, // maximal (weighted) deviation of each channel from the average
lt_window2, // [256]
port_offsets, // [port]{x_off, y_off}
img_mask, // which port to use, 0xf - all 4 (will modify as local variable)
diff_sigma, // pixel value/pixel change
diff_threshold, // pixel value/pixel change
diff_gauss, // when averaging images, use gaussian around average as weight (false - sharp all/nothing)
min_agree, // minimal number of channels to agree on a point (real number to work with fuzzy averages)
col_weights, // color channel weights, sum == 1.0
keep_weights, // keep_weights); // return channel weights after A in RGBA
port_offsets, // [port]{x_off, y_off}
img_mask, // which port to use, 0xf - all 4 (will modify as local variable)
diff_sigma, // pixel value/pixel change
diff_threshold, // pixel value/pixel change
diff_gauss, // when averaging images, use gaussian around average as weight (false - sharp all/nothing)
min_agree, // minimal number of channels to agree on a point (real number to work with fuzzy averages)
col_weights, // color channel weights, sum == 1.0
dust_remove, // boolean dust_remove, // Do not reduce average weight when only one image differes much from the average
keep_weights, // keep_weights); // return channel weights after A in RGBA
(globalDebugLevel > 0) && debugTile);
// mix RGB from iclt_tile, mix alpha with - what? correlation strength or 'don't care'? good correlation or all > min?
......@@ -1618,6 +1644,11 @@ public class ImageDtt {
}
}
}
if ((disparity_map != null) && (disparity_map.length >= (disparity_maxdiff_index + quad))){
for (int i = 0; i < max_diff.length; i++){
disparity_map[disparity_maxdiff_index + i][tileY*tilesX + tileX] = max_diff[i];
}
}
}
}
}
......@@ -1630,14 +1661,16 @@ public class ImageDtt {
public double [][] tile_combine_rgba(
double [][][] iclt_tile, // [port][numcol][256]
double [] max_diff, // maximal (weighted) deviation of each channel from the average
double [] lt_window, // [256]
double [][] port_offsets, // [port]{x_off, y_off}
double [][] port_offsets, // [port]{x_off, y_off} - just to scale pixel value differences
int port_mask, // which port to use, 0xf - all 4 (will modify as local variable)
double diff_sigma, // pixel value/pixel change
double diff_threshold, // pixel value/pixel change
boolean diff_gauss, // when averaging images, use gaussian around average as weight (false - sharp all/nothing)
double min_agree, // minimal number of channels to agree on a point (real number to work with fuzzy averages)
double [] chn_weights, // color channel weights, sum == 1.0
double [] chn_weights, // color channel weights, sum == 1.0
boolean dust_remove, // Do not reduce average weight when only one image differes much from the average
boolean keep_weights, // return channel weights after A in RGBA
boolean debug)
{
......@@ -1793,21 +1826,62 @@ public class ImageDtt {
}
}
}
if (dust_remove && (usedPorts == 4)) {
dust_remove(port_weights);
}
// calculate alpha from channel weights. Start with just a sum of weights?
for (int i = 0; i < tile_len; i++){
alpha[i] = 0.0;
for (int ip = 0; ip < ports; ip++) if ((port_mask & ( 1 << ip)) != 0){
alpha[i]+= port_weights[ip][i];
}
alpha[i] *= lt_window[i]; // make it configurable?
alpha[i] *= lt_window[i]/usedPorts; // make it configurable?
}
for (int i = 0; i < numcol; i++) rgba[i] = color_avg[i];
rgba[numcol] = alpha;
for (int i = 0; i < ports; i++) rgba[numcol + 1 + i] = port_weights[i];
for (int i = 0; i < ports; i++) rgba[numcol + 1 + i] = port_weights[i];
if (max_diff != null){
for (int ip = 0; ip < ports; ip++){
max_diff[ip] = 0;
if ((port_mask & ( 1 << ip)) != 0) {
for (int i = 0; i < tile_len; i++){
double d2 = 0.0;
for (int chn = 0; chn < numcol; chn++){
double dc = (iclt_tile[ip][chn][i]-color_avg[chn][i]);
d2+=dc*dc*chn_weights[chn];
}
d2 *=lt_window[i];
if (d2 > max_diff[ip]) max_diff[ip] = d2;
}
}
max_diff[ip] = Math.sqrt(max_diff[ip]);
}
}
return rgba;
}
public void dust_remove( // redistribute weight between 3 best ports (use only when all 3 are enabled)
double [][] port_weights)
{
int np = port_weights.length;
for (int i = 0; i < port_weights[0].length; i++){
int wi = 0;
for (int ip = 1; ip < np; ip++) if (port_weights[ip][i] < port_weights[wi][i]) wi = ip;
double avg = 0;
for (int ip = 1; ip < np; ip++) if (ip != wi) avg += port_weights[ip][i];
avg /= (np -1);
double scale = 1.0 + (avg - port_weights[wi][i])/(avg * (np -1));
for (int ip = 1; ip < np; ip++) {
if (ip != wi) port_weights[ip][i] *= scale; // increase weight of non-worst, so if worst == 0.0 sum of 3 (all) ports will be scaled by 4/3, keeping average
}
port_weights[wi][i] *= port_weights[wi][i]/avg;
}
}
public double [] tile_debayer_shot_corr(
boolean rb,
double [] tile,
......
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