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

added denoise, debugging window influence

parent 271830ae
......@@ -1809,11 +1809,17 @@ public class EyesisCorrectionParameters {
public double sigma_y = 0.7; // blur for G contribution to Y
public double sigma_color = 0.7; // blur for Pb and Pr in addition to that of Y
public double line_thershold = 1.0; // line detection amplitude to apply line enhancement - not used?
public boolean nonlin = true; // enable nonlinear processing (including denoise
public double nonlin_max_y = 1.0; // maximal amount of nonlinear line/edge emphasis for Y component
public double nonlin_max_c = 1.0; // maximal amount of nonlinear line/edge emphasis for C component
public double nonlin_y = 0.1; // amount of nonlinear line/edge emphasis for Y component
public double nonlin_c = 0.01; // amount of nonlinear line/edge emphasis for C component
public double nonlin_corn = 0.5; // relative weight for nonlinear corner elements
public boolean denoise = true; // suppress noise during nonlinear processing
public double denoise_y = 1.0; // maximal total smoothing of the Y post-kernel (will compete with edge emphasis)
public double denoise_c = 1.0; // maximal total smoothing of the color differences post-kernel (will compete with edge emphasis)
public double denoise_y_corn = 0.3; // weight of the 4 corner pixels during denoise y (straight - 1-denoise_y_corn)
public double denoise_c_corn = 0.3; // weight of the 4 corner pixels during denoise y (straight - 1-denoise_c_corn)
public DCTParameters(){}
......@@ -1877,11 +1883,21 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"sigma_color", this.sigma_color+"");
properties.setProperty(prefix+"line_thershold", this.line_thershold+"");
properties.setProperty(prefix+"nonlin", this.nonlin+"");
properties.setProperty(prefix+"nonlin_max_y", this.nonlin_max_y+"");
properties.setProperty(prefix+"nonlin_max_c", this.nonlin_max_c+"");
properties.setProperty(prefix+"nonlin_y", this.nonlin_y+"");
properties.setProperty(prefix+"nonlin_c", this.nonlin_c+"");
properties.setProperty(prefix+"nonlin_corn", this.nonlin_corn+"");
properties.setProperty(prefix+"denoise", this.denoise+"");
properties.setProperty(prefix+"denoise_y", this.denoise_y+"");
properties.setProperty(prefix+"denoise_c", this.denoise_c+"");
properties.setProperty(prefix+"denoise_y_corn", this.denoise_y_corn+"");
properties.setProperty(prefix+"denoise_c_corn", this.denoise_c_corn+"");
}
public void getProperties(String prefix,Properties properties){
if (properties.getProperty(prefix+"dct_size")!=null) this.dct_size=Integer.parseInt(properties.getProperty(prefix+"dct_size"));
......@@ -1924,11 +1940,19 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"sigma_color")!=null) this.sigma_color=Double.parseDouble(properties.getProperty(prefix+"sigma_color"));
if (properties.getProperty(prefix+"line_thershold")!=null) this.line_thershold=Double.parseDouble(properties.getProperty(prefix+"line_thershold"));
if (properties.getProperty(prefix+"nonlin")!=null) this.nonlin=Boolean.parseBoolean(properties.getProperty(prefix+"nonlin"));
if (properties.getProperty(prefix+"nonlin_max_y")!=null) this.nonlin_max_y=Double.parseDouble(properties.getProperty(prefix+"nonlin_max_y"));
if (properties.getProperty(prefix+"nonlin_max_c")!=null) this.nonlin_max_c=Double.parseDouble(properties.getProperty(prefix+"nonlin_max_c"));
if (properties.getProperty(prefix+"nonlin_y")!=null) this.nonlin_y=Double.parseDouble(properties.getProperty(prefix+"nonlin_y"));
if (properties.getProperty(prefix+"nonlin_c")!=null) this.nonlin_c=Double.parseDouble(properties.getProperty(prefix+"nonlin_c"));
if (properties.getProperty(prefix+"nonlin_corn")!=null) this.nonlin_corn=Double.parseDouble(properties.getProperty(prefix+"nonlin_corn"));
if (properties.getProperty(prefix+"denoise")!=null) this.denoise=Boolean.parseBoolean(properties.getProperty(prefix+"denoise"));
if (properties.getProperty(prefix+"denoise_y")!=null) this.denoise_y=Double.parseDouble(properties.getProperty(prefix+"denoise_y"));
if (properties.getProperty(prefix+"denoise_c")!=null) this.denoise_c=Double.parseDouble(properties.getProperty(prefix+"denoise_c"));
if (properties.getProperty(prefix+"denoise_y_corn")!=null) this.denoise_y_corn=Double.parseDouble(properties.getProperty(prefix+"denoise_y_corn"));
if (properties.getProperty(prefix+"denoise_c_corn")!=null) this.denoise_c_corn=Double.parseDouble(properties.getProperty(prefix+"denoise_c_corn"));
}
public boolean showDialog() {
GenericDialog gd = new GenericDialog("Set DCT parameters");
......@@ -1972,11 +1996,17 @@ public class EyesisCorrectionParameters {
gd.addNumericField("Gaussian sigma to apply to Pr and Pb in the MDCT domain, pix", this.sigma_color, 3);
gd.addNumericField("Threshold for line detection (not yet used)", this.line_thershold, 3);
gd.addCheckbox ("Use non-linear line emphasis and denoise", this.nonlin );
gd.addNumericField("Maximal amount of non-linear emphasis for linear edges for Y component", this.nonlin_max_y,3);
gd.addNumericField("Maximal amount of non-linear emphasis for linear edges for color diffs.", this.nonlin_max_c,3);
gd.addNumericField("Sensitivity of non-linear emphasis for linear edges for Y component", this.nonlin_y, 3);
gd.addNumericField("Sensitivity of non-linear emphasis for linear edges for color diffs.", this.nonlin_c, 3);
gd.addNumericField("Corretion for diagonal/corner emphasis elements", this.nonlin_corn, 3);
gd.addCheckbox ("Suppress noise during nonlinear processing", this.denoise );
gd.addNumericField("Maximal total smoothing of the Y post-kernel (will compete with edge emphasis)", this.denoise_y,3);
gd.addNumericField("Maximal total smoothing of the color differences post-kernel (will compete with edge emphasis)", this.denoise_c,3);
gd.addNumericField("Weight of the 4 corner pixels during denoising y (straight - 1.0-denoise_y_corn)", this.denoise_y_corn,3);
gd.addNumericField("Weight of the 4 corner pixels during denoising color ((straight - 1.0-denoise_c_corn))", this.denoise_c_corn,3);
WindowTools.addScrollBars(gd);
gd.showDialog();
......@@ -2022,11 +2052,19 @@ public class EyesisCorrectionParameters {
this.sigma_color= gd.getNextNumber();
this.line_thershold= gd.getNextNumber();
this.nonlin= gd.getNextBoolean();
this.nonlin_max_y= gd.getNextNumber();
this.nonlin_max_c= gd.getNextNumber();
this.nonlin_y= gd.getNextNumber();
this.nonlin_c= gd.getNextNumber();
this.nonlin_corn= gd.getNextNumber();
this.denoise= gd.getNextBoolean();
this.denoise_y= gd.getNextNumber();
this.denoise_c= gd.getNextNumber();
this.denoise_y_corn= gd.getNextNumber();
this.denoise_c_corn= gd.getNextNumber();
// MASTER_DEBUG_LEVEL= (int) gd.getNextNumber();
return true;
}
......
......@@ -1139,9 +1139,9 @@ public class EyesisDCT {
return result;
}
// =================
ImageDtt image_dtt = new ImageDtt();
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
if (this.correctionsParameters.deconvolve) { // process with DCT, otherwise use simple debayer
ImageDtt image_dtt = new ImageDtt();
double [][][][] dctdc_data = image_dtt.mdctDcStack(
stack,
dct_parameters,
......@@ -1193,7 +1193,7 @@ public class EyesisDCT {
threadsMax,
debugLevel);
}
// System.out.println("dct_dc.length="+dct_dc.length+" dct_ac.length="+dct_ac.length);
// System.out.println("dct_dc.length="+dct_dc.length+" dct_ac.length="+dct_ac.length);
if (debugLevel > 0){
sdfa_instance.showArrays(dct_ac,
tilesX*dct_parameters.dct_size,
......@@ -1224,7 +1224,7 @@ public class EyesisDCT {
(tilesY + 1) * dct_parameters.dct_size,
true,
result.getTitle()+"-IDCTDC-YPrPb");
if ((dct_parameters.nonlin_y != 0.0) || (dct_parameters.nonlin_c != 0.0)) {
if (dct_parameters.nonlin && ((dct_parameters.nonlin_y != 0.0) || (dct_parameters.nonlin_c != 0.0))) {
System.out.println("Applying edge emphasis, nonlin_y="+dct_parameters.nonlin_y+
", nonlin_c="+dct_parameters.nonlin_c+", nonlin_corn="+dct_parameters.nonlin_corn);
idct_data = edge_emphasis(
......@@ -1236,6 +1236,10 @@ public class EyesisDCT {
dct_parameters.nonlin_y, // final double nonlin_y, // = 0.01; // amount of nonlinear line/edge emphasis for Y component
dct_parameters.nonlin_c, // final double nonlin_c, // = 0.01; // amount of nonlinear line/edge emphasis for C component
dct_parameters.nonlin_corn, // final double nonlin_corn, // = 0.5; // relative weight for nonlinear corner elements
(dct_parameters.denoise? dct_parameters.denoise_y:0.0), // final double denoise_y, // = 1.0; // maximal total smoothing of the Y post-kernel (will compete with edge emphasis)
(dct_parameters.denoise? dct_parameters.denoise_c:0.0), // final double denoise_c, // = 1.0; // maximal total smoothing of the color differences post-kernel (will compete with edge emphasis)
dct_parameters.denoise_y_corn, // final double denoise_y_corn, // = 0.5; // weight of the 4 corner pixels during denoise y (relative to 4 straight)
dct_parameters.denoise_c_corn, // final double denoise_c_corn, // = 0.5; // weight of the 4 corner pixels during denoise y (relative to 4 straight)
threadsMax, // final int threadsMax, // maximal number of threads to launch
debugLevel); // final int globalDebugLevel)
sdfa_instance.showArrays(
......@@ -1252,7 +1256,10 @@ public class EyesisDCT {
colorProcParameters.kb, // 0.114;
(tilesX + 1) * dct_parameters.dct_size);
} else {
System.out.println("Bypassing nonlinear correction");
}
sdfa_instance.showArrays(idct_data,
(tilesX + 1) * dct_parameters.dct_size,
(tilesY + 1) * dct_parameters.dct_size,
......@@ -1266,6 +1273,13 @@ public class EyesisDCT {
(tilesX + 1) * dct_parameters.dct_size,
(tilesY + 1) * dct_parameters.dct_size,
sliceNames); // or use null to get chn-nn slice names
} else { // if (this.correctionsParameters.deconvolve) - here use a simple debayer
System.out.println("Bypassing DCTR-based aberration correction");
debayer_rbg(stack, 0.25); // simple standard 3x3 kernel debayer
}
if (!this.correctionsParameters.colorProc){
result= new ImagePlus(titleFull, stack);
eyesisCorrections.saveAndShow(
......@@ -1291,9 +1305,9 @@ public class EyesisDCT {
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 {
// 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))
......@@ -1320,7 +1334,8 @@ public class EyesisDCT {
yPrPb[n] = new double [fpixels.length];
for (int i = 0; i < fpixels.length; i++) yPrPb[n][i] = fpixels[i];
}
// }
// }
/*
String [] slice_names_YPrPb={"Y","Pr","Pb"};
sdfa_instance.showArrays(idct_data,
stack.getWidth(), // (tilesX + 1) * dct_parameters.dct_size,
......@@ -1328,6 +1343,7 @@ public class EyesisDCT {
true,
result.getTitle()+"-YPrPb",
slice_names_YPrPb);
*/
if (toRGB) {
......@@ -1481,7 +1497,7 @@ public class EyesisDCT {
int width
) {
int length = yPrPb[0].length;
int height = length/width;
// int height = length/width;
double [][]rbg = new double[3][length];
double Kg=1.0-Kr-Kb;
......@@ -1518,6 +1534,10 @@ public class EyesisDCT {
final double nonlin_y, // = 0.01; // amount of nonlinear line/edge emphasis for Y component
final double nonlin_c, // = 0.01; // amount of nonlinear line/edge emphasis for C component
final double nonlin_corn, // = 0.5; // relative weight for nonlinear corner elements
final double denoise_y, // = 1.0; // maximal total smoothing of the Y post-kernel (will compete with edge emphasis)
final double denoise_c, // = 1.0; // maximal total smoothing of the color differences post-kernel (will compete with edge emphasis)
final double denoise_y_corn, // = 0.3; // weight of the 4 corner pixels during denoise y (relative to 4 straight)
final double denoise_c_corn, // = 0.3; // weight of the 4 corner pixels during denoise y (relative to 4 straight)
final int threadsMax, // maximal number of threads to launch
final int globalDebugLevel)
{
......@@ -1532,6 +1552,15 @@ public class EyesisDCT {
final int [] neib_indices = {-width-1,-width,-width+1,-1,0,1,width-1,width,width+1};
final double [][] kernsw_y = new double [kernsw.length][];
final double [][] kernsw_c = new double [kernsw.length][];
final double [] denoise_kern_y = {
0.125*denoise_y*denoise_y_corn, 0.125*denoise_y*(1.0-denoise_y_corn), 0.125*denoise_y*denoise_y_corn,
0.125*denoise_y*(1.0-denoise_y_corn), -0.5* denoise_y, 0.125*denoise_y*(1.0-denoise_y_corn),
0.125*denoise_y*denoise_y_corn, 0.125*denoise_y*(1.0-denoise_y_corn), 0.125*denoise_y*denoise_y_corn};
final double [] denoise_kern_c = {
0.125*denoise_c*denoise_c_corn, 0.125*denoise_c*(1.0-denoise_c_corn), 0.125*denoise_c*denoise_c_corn,
0.125*denoise_c*(1.0-denoise_c_corn), -0.5* denoise_c, 0.125*denoise_c*(1.0-denoise_c_corn),
0.125*denoise_c*denoise_c_corn, 0.125*denoise_c*(1.0-denoise_c_corn), 0.125*denoise_c*denoise_c_corn};
for (int n = 0; n < kernsw.length; n++){
kernsw_y[n] = new double [kernsw[n].length];
kernsw_c[n] = new double [kernsw[n].length];
......@@ -1617,6 +1646,16 @@ public class EyesisDCT {
kern_c[ni]+= squared*kernsw_c[n][i];
}
}
if (denoise_y > 0.0){
for (int i = 0; i < kern_y.length; i++){
kern_y[i]+= denoise_kern_y[i];
}
}
if (denoise_c > 0.0){
for (int i = 0; i < kern_y.length; i++){
kern_c[i]+= denoise_kern_c[i];
}
}
if (nonlin_max_y != 0){
double sum = 0;
......@@ -1662,7 +1701,97 @@ public class EyesisDCT {
ImageDtt.startAndJoin(threads);
return yPrPb_new;
}
public void debayer_rbg(
ImageStack stack_rbg){
debayer_rbg(stack_rbg, 1.0);
}
// Simple in-place debayer by (bi) linear approximation, assumes [0R/00], [00/B0], [G0/0G] slices
public void debayer_rbg(
ImageStack stack_rbg,
double scale)
{
int width = stack_rbg.getWidth();
int height = stack_rbg.getHeight();
float [] fpixels_r = (float[]) stack_rbg.getPixels(1);
float [] fpixels_b = (float[]) stack_rbg.getPixels(2);
float [] fpixels_g = (float[]) stack_rbg.getPixels(3);
int [][][] av_row = {
{{1,1},{-1,1},{-1,-1}},
{{1,1},{-1,1},{-1,-1}},
{{1,1},{-1,1},{-1,-1}}};
int [][][] av_col = {
{{ width, width},{ width, width},{ width, width}},
{{-width, width},{-width, width},{-width, width}},
{{-width,-width},{-width,-width},{-width,-width}}};
int [][][] av_xcross = {
{{ width+1, width+1, width+1, width+1}, { width-1, width+1, width-1, width+1}, { width-1, width-1, width-1, width-1}},
{{-width+1, width+1,-width+1, width+1}, {-width-1,-width+1, width-1, width+1}, {-width-1,-width-1, width-1, width-1}},
{{-width+1,-width+1,-width+1,-width+1}, {-width-1,-width+1,-width-1,-width+1}, {-width-1,-width-1,-width-1,-width-1}}};
int [][][] av_plus = {
{{ width, 1, 1, width}, { width, -1, 1, width }, { width, -1, -1, width }},
{{-width, 1, 1, width}, {-width, -1, 1, width }, {-width, -1, -1, width }},
{{-width, 1, 1,-width}, {-width, -1, 1,-width }, {-width, -1, -1,-width }}};
for (int y = 0; y < height; y++){
boolean odd_row = (y & 1) != 0;
int row_type = (y==0)? 0: ((y==(height-1))?2:1);
for (int x = 0; x < width; x++){
int indx = y*width+x;
boolean odd_col = (x & 1) != 0;
int col_type = (x==0)? 0: ((x==(width-1))?2:1);
if (odd_row){
if (odd_col){ // GB site
fpixels_r[indx] = 0.5f*(
fpixels_r[indx+av_col[row_type][col_type][0]]+
fpixels_r[indx+av_col[row_type][col_type][1]]);
fpixels_b[indx] = 0.5f*(
fpixels_b[indx+av_row[row_type][col_type][0]]+
fpixels_b[indx+av_row[row_type][col_type][1]]);
} else { // !odd col // B site
fpixels_r[indx] = 0.25f*(
fpixels_r[indx+av_xcross[row_type][col_type][0]]+
fpixels_r[indx+av_xcross[row_type][col_type][1]]+
fpixels_r[indx+av_xcross[row_type][col_type][2]]+
fpixels_r[indx+av_xcross[row_type][col_type][3]]);
fpixels_g[indx] = 0.25f*(
fpixels_g[indx+av_plus[row_type][col_type][0]]+
fpixels_g[indx+av_plus[row_type][col_type][1]]+
fpixels_g[indx+av_plus[row_type][col_type][2]]+
fpixels_g[indx+av_plus[row_type][col_type][3]]);
}
} else { // !odd_row
if (odd_col){ // R site
fpixels_b[indx] = 0.25f*(
fpixels_b[indx+av_xcross[row_type][col_type][0]]+
fpixels_b[indx+av_xcross[row_type][col_type][1]]+
fpixels_b[indx+av_xcross[row_type][col_type][2]]+
fpixels_b[indx+av_xcross[row_type][col_type][3]]);
fpixels_g[indx] = 0.25f*(
fpixels_g[indx+av_plus[row_type][col_type][0]]+
fpixels_g[indx+av_plus[row_type][col_type][1]]+
fpixels_g[indx+av_plus[row_type][col_type][2]]+
fpixels_g[indx+av_plus[row_type][col_type][3]]);
} else { // !odd col // G site
fpixels_r[indx] = 0.5f*(
fpixels_r[indx+av_row[row_type][col_type][0]]+
fpixels_r[indx+av_row[row_type][col_type][1]]);
fpixels_b[indx] = 0.5f*(
fpixels_b[indx+av_col[row_type][col_type][0]]+
fpixels_b[indx+av_col[row_type][col_type][1]]);
}
}
}
}
if (scale !=1.0){
for (int i = 0; i< fpixels_r.length; i++){
fpixels_r[i] *= scale;
fpixels_b[i] *= scale;
fpixels_g[i] *= scale;
}
}
}
......
......@@ -583,6 +583,21 @@ public class ImageDtt {
}
}
}
// normalize
double sum = 0;
for (int i = 0; i < dct_size; i++){
for (int j = 0; j < dct_size; j++){
double d = filter_direct[i*dct_size+j];
d*=Math.cos(Math.PI*i/(2*dct_size))*Math.cos(Math.PI*j/(2*dct_size));
if (i > 0) d*= 2.0;
if (j > 0) d*= 2.0;
sum +=d;
}
}
for (int i = 0; i<filter_direct.length; i++){
filter_direct[i] /= sum;
}
if (globalDebugLevel > -1) {
for (int i=0; i<filter_direct.length;i++){
System.out.println("dct_lpf_psf() "+i+": "+filter_direct[i]);
......@@ -591,6 +606,8 @@ public class ImageDtt {
DttRad2 dtt = new DttRad2(dct_size);
// final double [] filter= dtt.dttt_iii(filter_direct);
final double [] filter= dtt.dttt_iiie(filter_direct);
final double [] dbg_filter= dtt.dttt_ii(filter);
for (int i=0; i < filter.length;i++) filter[i] *= dct_size;
if (globalDebugLevel > -1) {
......@@ -598,7 +615,7 @@ public class ImageDtt {
System.out.println("dct_lpf_psf() "+i+": "+filter[i]);
}
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
double [][] ff = {filter_direct,filter};
double [][] ff = {filter_direct,filter,dbg_filter};
sdfa_instance.showArrays(ff, dct_size,dct_size, true, "filter_lpf");
}
......@@ -671,7 +688,7 @@ public class ImageDtt {
for (int j=0; j < dct_len; j++) filters_proto[i][j] *= 2*dct_size;
}
if (globalDebugLevel > -1) {
if (globalDebugLevel > 0) {
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
double [][] ff = {filters_proto_direct[0],filters_proto_direct[1],filters_proto_direct[2],filters_proto[0],filters_proto[1],filters_proto[2]};
sdfa_instance.showArrays(ff, dct_size,dct_size, true, "filters_proto");
......@@ -695,7 +712,7 @@ public class ImageDtt {
}
}
}
if (globalDebugLevel > -1) {
if (globalDebugLevel > 0) {
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
double [][] ff = {
filters[0][0], filters[0][1], filters[0][2],
......
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