Loading src/main/java/EyesisCorrectionParameters.java +34 −8 Original line number Original line Diff line number Diff line Loading @@ -1805,10 +1805,18 @@ public class EyesisCorrectionParameters { public double vignetting_range = 5.0; // do not try to correct vignetting less than vignetting_max/vignetting_range public double vignetting_range = 5.0; // do not try to correct vignetting less than vignetting_max/vignetting_range public boolean color_DCT = true; // false - use old color processing mode public boolean color_DCT = true; // false - use old color processing mode public double sigma_rb = 0.5; // additional (to G) blur for R and B public double sigma_rb = 0.9; // additional (to G) blur for R and B public double sigma_y = 0.5; // blur for G contribution to Y public double sigma_y = 0.7; // blur for G contribution to Y public double sigma_color = 1.0; // blur for Pb and Pr in addition to that of 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 public double line_thershold = 1.0; // line detection amplitude to apply line enhancement - not used? 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 DCTParameters(){} public DCTParameters( public DCTParameters( int dct_size, int dct_size, Loading Loading @@ -1863,13 +1871,17 @@ public class EyesisCorrectionParameters { properties.setProperty(prefix+"convolve_direct", this.convolve_direct+""); properties.setProperty(prefix+"convolve_direct", this.convolve_direct+""); properties.setProperty(prefix+"vignetting_max", this.vignetting_max+""); properties.setProperty(prefix+"vignetting_max", this.vignetting_max+""); properties.setProperty(prefix+"vignetting_range", this.vignetting_range+""); properties.setProperty(prefix+"vignetting_range", this.vignetting_range+""); properties.setProperty(prefix+"color_DCT", this.color_DCT+""); properties.setProperty(prefix+"color_DCT", this.color_DCT+""); properties.setProperty(prefix+"sigma_rb", this.sigma_rb+""); properties.setProperty(prefix+"sigma_rb", this.sigma_rb+""); properties.setProperty(prefix+"sigma_y", this.sigma_y+""); properties.setProperty(prefix+"sigma_y", this.sigma_y+""); properties.setProperty(prefix+"sigma_color", this.sigma_color+""); properties.setProperty(prefix+"sigma_color", this.sigma_color+""); properties.setProperty(prefix+"line_thershold", this.line_thershold+""); properties.setProperty(prefix+"line_thershold", this.line_thershold+""); 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+""); } } public void getProperties(String prefix,Properties properties){ public void getProperties(String prefix,Properties properties){ if (properties.getProperty(prefix+"dct_size")!=null) this.dct_size=Integer.parseInt(properties.getProperty(prefix+"dct_size")); if (properties.getProperty(prefix+"dct_size")!=null) this.dct_size=Integer.parseInt(properties.getProperty(prefix+"dct_size")); Loading Loading @@ -1912,6 +1924,11 @@ public class EyesisCorrectionParameters { if (properties.getProperty(prefix+"sigma_color")!=null) this.sigma_color=Double.parseDouble(properties.getProperty(prefix+"sigma_color")); 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+"line_thershold")!=null) this.line_thershold=Double.parseDouble(properties.getProperty(prefix+"line_thershold")); 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")); } } public boolean showDialog() { public boolean showDialog() { GenericDialog gd = new GenericDialog("Set DCT parameters"); GenericDialog gd = new GenericDialog("Set DCT parameters"); Loading Loading @@ -1949,12 +1966,17 @@ public class EyesisCorrectionParameters { gd.addCheckbox ("Convolve directly with symmetrical kernel (debug feature) ", this.convolve_direct); gd.addCheckbox ("Convolve directly with symmetrical kernel (debug feature) ", this.convolve_direct); gd.addNumericField("Value (max) in vignetting data to correspond to 1x in the kernel",this.vignetting_max, 3); gd.addNumericField("Value (max) in vignetting data to correspond to 1x in the kernel",this.vignetting_max, 3); gd.addNumericField("Do not try to correct vignetting smaller than this fraction of max",this.vignetting_range, 3); gd.addNumericField("Do not try to correct vignetting smaller than this fraction of max",this.vignetting_range, 3); gd.addCheckbox ("Use DCT-base color conversion", this.color_DCT ); gd.addCheckbox ("Use DCT-base color conversion", this.color_DCT ); gd.addNumericField("Gaussian sigma to apply to R and B (in addition to G), pix", this.sigma_rb, 3); gd.addNumericField("Gaussian sigma to apply to R and B (in addition to G), pix", this.sigma_rb, 3); gd.addNumericField("Gaussian sigma to apply to Y in the MDCT domain, pix", this.sigma_y, 3); gd.addNumericField("Gaussian sigma to apply to Y in the MDCT domain, pix", this.sigma_y, 3); gd.addNumericField("Gaussian sigma to apply to Pr and Pb in the MDCT domain, pix", this.sigma_color, 3); 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", this.line_thershold, 3); gd.addNumericField("Threshold for line detection (not yet used)", this.line_thershold, 3); 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); WindowTools.addScrollBars(gd); WindowTools.addScrollBars(gd); gd.showDialog(); gd.showDialog(); Loading Loading @@ -1994,13 +2016,17 @@ public class EyesisCorrectionParameters { this.convolve_direct= gd.getNextBoolean(); this.convolve_direct= gd.getNextBoolean(); this.vignetting_max= gd.getNextNumber(); this.vignetting_max= gd.getNextNumber(); this.vignetting_range= gd.getNextNumber(); this.vignetting_range= gd.getNextNumber(); this.color_DCT= gd.getNextBoolean(); this.color_DCT= gd.getNextBoolean(); this.sigma_rb= gd.getNextNumber(); this.sigma_rb= gd.getNextNumber(); this.sigma_y= gd.getNextNumber(); this.sigma_y= gd.getNextNumber(); this.sigma_color= gd.getNextNumber(); this.sigma_color= gd.getNextNumber(); this.line_thershold= gd.getNextNumber(); this.line_thershold= gd.getNextNumber(); 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(); // MASTER_DEBUG_LEVEL= (int) gd.getNextNumber(); // MASTER_DEBUG_LEVEL= (int) gd.getNextNumber(); return true; return true; } } Loading src/main/java/EyesisDCT.java +182 −1 Original line number Original line Diff line number Diff line Loading @@ -1200,11 +1200,34 @@ public class EyesisDCT { debugLevel); debugLevel); } } if (dct_parameters.color_DCT){ // convert RBG -> YPrPb if (dct_parameters.color_DCT){ // convert RBG -> YPrPb sdfa_instance.showArrays(idct_data, sdfa_instance.showArrays( idct_data, (tilesX + 1) * dct_parameters.dct_size, (tilesX + 1) * dct_parameters.dct_size, (tilesY + 1) * dct_parameters.dct_size, (tilesY + 1) * dct_parameters.dct_size, true, true, result.getTitle()+"-IDCTDC-YPrPb"); result.getTitle()+"-IDCTDC-YPrPb"); if ((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( idct_data, // final double [][] yPrPb, (tilesX + 1) * dct_parameters.dct_size, // final int width, dct_parameters.dct_size, // final int step, //(does not need to be this) // just for multi-threading efficiency? dct_parameters.nonlin_max_y, // final double nonlin_max_y = 1.0; // maximal amount of nonlinear line/edge emphasis for Y component dct_parameters.nonlin_max_c, // final double nonlin_max_c = 1.0; // maximal amount of nonlinear line/edge emphasis for C component 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 threadsMax, // final int threadsMax, // maximal number of threads to launch debugLevel); // final int globalDebugLevel) sdfa_instance.showArrays( idct_data, (tilesX + 1) * dct_parameters.dct_size, (tilesY + 1) * dct_parameters.dct_size, true, result.getTitle()+"-EMPH-"+dct_parameters.nonlin_y+"_"+dct_parameters.nonlin_c+"_"+dct_parameters.nonlin_corn); } // temporary convert back to RGB // temporary convert back to RGB idct_data = YPrPbToRBG(idct_data, idct_data = YPrPbToRBG(idct_data, colorProcParameters.kr, // 0.299; colorProcParameters.kr, // 0.299; Loading Loading @@ -1467,4 +1490,162 @@ public class EyesisDCT { return rbg; return rbg; } } public double [][] edge_emphasis( final double [][] yPrPb, final int width, final int step, // just for multi-threading efficiency? final double nonlin_max_y, // = 1.0; // maximal amount of nonlinear line/edge emphasis for Y component final double nonlin_max_c, // = 1.0; // maximal amount of nonlinear line/edge emphasis for C component 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 int threadsMax, // maximal number of threads to launch final int globalDebugLevel) { final double [][] yPrPb_new = new double [yPrPb.length][yPrPb[0].length]; final int height = yPrPb[0].length/width; final int tilesY = (height + step - 1) / step; final int tilesX = (width + step - 1) / step; final int nTiles=tilesX*tilesY; final int [][] probes = {{1,7},{3,5},{2,6},{0,8}}; // indices in [012/345/678] 3x3 square to calculate squared sums of differences final int [][] kerns = {{ 1, 3, 5, 7}, {1, 3, 5, 7}, {0, 2, 6, 8}, {0, 2, 6, 8}}; // indices in [012/345/678] 3x3 square to convolve data final double [][] kernsw = {{-1.0,1.0,1.0,-1.0},{1.0,-1.0,-1.0,1.0},{1.0,-1.0,-1.0,1.0},{-1.0,1.0,1.0,-1.0}}; // weights of kern elements 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][]; for (int n = 0; n < kernsw.length; n++){ kernsw_y[n] = new double [kernsw[n].length]; kernsw_c[n] = new double [kernsw[n].length]; for (int i = 0; i < kernsw[n].length; i++){ double dy = nonlin_y * ((n>=2)? nonlin_corn: 1.0); double dc = nonlin_c * ((n>=2)? nonlin_corn: 1.0); kernsw_y[n][i] = kernsw[n][i] * dy* dy; kernsw_c[n][i] = kernsw[n][i] * dc* dc; } } if (globalDebugLevel > 0){ System.out.println("edge_emphasis(): nonlin_y="+nonlin_y+ ", nonlin_c="+nonlin_c+", nonlin_corn="+nonlin_corn); for (int n=0; n<kernsw_y.length; n++){ System.out.print("kernsw_y["+n+"={"); for (int i = 0; i < kernsw_y[n].length; i++){ System.out.print(kernsw_y[n][i]); if (i == (kernsw_y[n].length - 1)){ System.out.println("}"); } else { System.out.print(", "); } } } for (int n=0; n<kernsw_c.length; n++){ System.out.print("kernsw_c["+n+"={"); for (int i = 0; i < kernsw_c[n].length; i++){ System.out.print(kernsw_c[n][i]); if (i == (kernsw_c[n].length - 1)){ System.out.println("}"); } else { System.out.print(", "); } } } } final Thread[] threads = ImageDtt.newThreadArray(threadsMax); final AtomicInteger ai = new AtomicInteger(0); for (int ithread = 0; ithread < threads.length; ithread++) { threads[ithread] = new Thread() { public void run() { int tileY,tileX; double [] neibs = new double[9]; // pixels around current, first Y, then each color diff double [] kern_y = new double[9]; // weights of neighbors to add to the current for Y double [] kern_c = new double[9]; // weights of neighbors to add to the current for colors diffs int center_index = 4; for (int nTile = ai.getAndIncrement(); nTile < nTiles; nTile = ai.getAndIncrement()) { tileY = nTile/tilesX; tileX = nTile - tileY * tilesX; int y1 = (tileY +1) * step; if (y1 > height) y1 = height; int x1 = (tileX +1) * step; if (x1 > width) x1 = width; for (int y = tileY * step; y < y1; y++) { for (int x = tileX * step; x < x1; x++) { int indx = y*width + x; for (int n = 0; n < yPrPb.length; n++) { yPrPb_new[n][indx] = yPrPb[n][indx]; // default - just copy old value } if ((y > 0) && (y < (height - 1)) && (x > 0) && (x < (width - 1))) { // only correct those not on the edge // read Y pixels around current for (int i = 0; i < neibs.length; i++){ neibs[i] = yPrPb[0][indx+neib_indices[i]]; } for (int i = 0; i < kern_y.length; i++){ kern_y[i] = 0.0; kern_c[i] = 0.0; } // calculate amount of each pattern for (int n = 0; n < probes.length; n++){ double squared=0.0; for (int i = 0; i < probes[n].length; i++){ squared += neibs[probes[n][i]]; } squared -= probes[n].length * neibs[center_index]; squared *= squared; // Now it a square of the sum of differences from the center for (int i = 0; i < kernsw[n].length; i++){ int ni = kerns[n][i]; kern_y[ni]+= squared*kernsw_y[n][i]; kern_c[ni]+= squared*kernsw_c[n][i]; } } if (nonlin_max_y != 0){ double sum = 0; for (int i = 0; i < kern_y.length; i++){ sum += Math.abs(kern_y[i]); } if (sum > nonlin_max_y){ sum = nonlin_max_y/sum; for (int i = 0; i < kern_y.length; i++){ kern_y[i] *= sum; } } } if (nonlin_max_c != 0){ double sum = 0; for (int i = 0; i < kern_c.length; i++){ sum += Math.abs(kern_c[i]); } if (sum > nonlin_max_c){ sum = nonlin_max_c/sum; for (int i = 0; i < kern_c.length; i++){ kern_c[i] *= sum; } } } for (int i = 0; i<kern_y.length; i++){ yPrPb_new[0][indx] += neibs[i]*kern_y[i]; } for (int n = 1;n < 3; n++){ //color components for (int i = 0; i < neibs.length; i++){ yPrPb_new[n][indx] += yPrPb[0][indx+neib_indices[i]]*kern_c[i]; } } } } } } } }; } ImageDtt.startAndJoin(threads); return yPrPb_new; } } } Loading
src/main/java/EyesisCorrectionParameters.java +34 −8 Original line number Original line Diff line number Diff line Loading @@ -1805,10 +1805,18 @@ public class EyesisCorrectionParameters { public double vignetting_range = 5.0; // do not try to correct vignetting less than vignetting_max/vignetting_range public double vignetting_range = 5.0; // do not try to correct vignetting less than vignetting_max/vignetting_range public boolean color_DCT = true; // false - use old color processing mode public boolean color_DCT = true; // false - use old color processing mode public double sigma_rb = 0.5; // additional (to G) blur for R and B public double sigma_rb = 0.9; // additional (to G) blur for R and B public double sigma_y = 0.5; // blur for G contribution to Y public double sigma_y = 0.7; // blur for G contribution to Y public double sigma_color = 1.0; // blur for Pb and Pr in addition to that of 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 public double line_thershold = 1.0; // line detection amplitude to apply line enhancement - not used? 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 DCTParameters(){} public DCTParameters( public DCTParameters( int dct_size, int dct_size, Loading Loading @@ -1863,13 +1871,17 @@ public class EyesisCorrectionParameters { properties.setProperty(prefix+"convolve_direct", this.convolve_direct+""); properties.setProperty(prefix+"convolve_direct", this.convolve_direct+""); properties.setProperty(prefix+"vignetting_max", this.vignetting_max+""); properties.setProperty(prefix+"vignetting_max", this.vignetting_max+""); properties.setProperty(prefix+"vignetting_range", this.vignetting_range+""); properties.setProperty(prefix+"vignetting_range", this.vignetting_range+""); properties.setProperty(prefix+"color_DCT", this.color_DCT+""); properties.setProperty(prefix+"color_DCT", this.color_DCT+""); properties.setProperty(prefix+"sigma_rb", this.sigma_rb+""); properties.setProperty(prefix+"sigma_rb", this.sigma_rb+""); properties.setProperty(prefix+"sigma_y", this.sigma_y+""); properties.setProperty(prefix+"sigma_y", this.sigma_y+""); properties.setProperty(prefix+"sigma_color", this.sigma_color+""); properties.setProperty(prefix+"sigma_color", this.sigma_color+""); properties.setProperty(prefix+"line_thershold", this.line_thershold+""); properties.setProperty(prefix+"line_thershold", this.line_thershold+""); 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+""); } } public void getProperties(String prefix,Properties properties){ public void getProperties(String prefix,Properties properties){ if (properties.getProperty(prefix+"dct_size")!=null) this.dct_size=Integer.parseInt(properties.getProperty(prefix+"dct_size")); if (properties.getProperty(prefix+"dct_size")!=null) this.dct_size=Integer.parseInt(properties.getProperty(prefix+"dct_size")); Loading Loading @@ -1912,6 +1924,11 @@ public class EyesisCorrectionParameters { if (properties.getProperty(prefix+"sigma_color")!=null) this.sigma_color=Double.parseDouble(properties.getProperty(prefix+"sigma_color")); 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+"line_thershold")!=null) this.line_thershold=Double.parseDouble(properties.getProperty(prefix+"line_thershold")); 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")); } } public boolean showDialog() { public boolean showDialog() { GenericDialog gd = new GenericDialog("Set DCT parameters"); GenericDialog gd = new GenericDialog("Set DCT parameters"); Loading Loading @@ -1949,12 +1966,17 @@ public class EyesisCorrectionParameters { gd.addCheckbox ("Convolve directly with symmetrical kernel (debug feature) ", this.convolve_direct); gd.addCheckbox ("Convolve directly with symmetrical kernel (debug feature) ", this.convolve_direct); gd.addNumericField("Value (max) in vignetting data to correspond to 1x in the kernel",this.vignetting_max, 3); gd.addNumericField("Value (max) in vignetting data to correspond to 1x in the kernel",this.vignetting_max, 3); gd.addNumericField("Do not try to correct vignetting smaller than this fraction of max",this.vignetting_range, 3); gd.addNumericField("Do not try to correct vignetting smaller than this fraction of max",this.vignetting_range, 3); gd.addCheckbox ("Use DCT-base color conversion", this.color_DCT ); gd.addCheckbox ("Use DCT-base color conversion", this.color_DCT ); gd.addNumericField("Gaussian sigma to apply to R and B (in addition to G), pix", this.sigma_rb, 3); gd.addNumericField("Gaussian sigma to apply to R and B (in addition to G), pix", this.sigma_rb, 3); gd.addNumericField("Gaussian sigma to apply to Y in the MDCT domain, pix", this.sigma_y, 3); gd.addNumericField("Gaussian sigma to apply to Y in the MDCT domain, pix", this.sigma_y, 3); gd.addNumericField("Gaussian sigma to apply to Pr and Pb in the MDCT domain, pix", this.sigma_color, 3); 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", this.line_thershold, 3); gd.addNumericField("Threshold for line detection (not yet used)", this.line_thershold, 3); 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); WindowTools.addScrollBars(gd); WindowTools.addScrollBars(gd); gd.showDialog(); gd.showDialog(); Loading Loading @@ -1994,13 +2016,17 @@ public class EyesisCorrectionParameters { this.convolve_direct= gd.getNextBoolean(); this.convolve_direct= gd.getNextBoolean(); this.vignetting_max= gd.getNextNumber(); this.vignetting_max= gd.getNextNumber(); this.vignetting_range= gd.getNextNumber(); this.vignetting_range= gd.getNextNumber(); this.color_DCT= gd.getNextBoolean(); this.color_DCT= gd.getNextBoolean(); this.sigma_rb= gd.getNextNumber(); this.sigma_rb= gd.getNextNumber(); this.sigma_y= gd.getNextNumber(); this.sigma_y= gd.getNextNumber(); this.sigma_color= gd.getNextNumber(); this.sigma_color= gd.getNextNumber(); this.line_thershold= gd.getNextNumber(); this.line_thershold= gd.getNextNumber(); 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(); // MASTER_DEBUG_LEVEL= (int) gd.getNextNumber(); // MASTER_DEBUG_LEVEL= (int) gd.getNextNumber(); return true; return true; } } Loading
src/main/java/EyesisDCT.java +182 −1 Original line number Original line Diff line number Diff line Loading @@ -1200,11 +1200,34 @@ public class EyesisDCT { debugLevel); debugLevel); } } if (dct_parameters.color_DCT){ // convert RBG -> YPrPb if (dct_parameters.color_DCT){ // convert RBG -> YPrPb sdfa_instance.showArrays(idct_data, sdfa_instance.showArrays( idct_data, (tilesX + 1) * dct_parameters.dct_size, (tilesX + 1) * dct_parameters.dct_size, (tilesY + 1) * dct_parameters.dct_size, (tilesY + 1) * dct_parameters.dct_size, true, true, result.getTitle()+"-IDCTDC-YPrPb"); result.getTitle()+"-IDCTDC-YPrPb"); if ((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( idct_data, // final double [][] yPrPb, (tilesX + 1) * dct_parameters.dct_size, // final int width, dct_parameters.dct_size, // final int step, //(does not need to be this) // just for multi-threading efficiency? dct_parameters.nonlin_max_y, // final double nonlin_max_y = 1.0; // maximal amount of nonlinear line/edge emphasis for Y component dct_parameters.nonlin_max_c, // final double nonlin_max_c = 1.0; // maximal amount of nonlinear line/edge emphasis for C component 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 threadsMax, // final int threadsMax, // maximal number of threads to launch debugLevel); // final int globalDebugLevel) sdfa_instance.showArrays( idct_data, (tilesX + 1) * dct_parameters.dct_size, (tilesY + 1) * dct_parameters.dct_size, true, result.getTitle()+"-EMPH-"+dct_parameters.nonlin_y+"_"+dct_parameters.nonlin_c+"_"+dct_parameters.nonlin_corn); } // temporary convert back to RGB // temporary convert back to RGB idct_data = YPrPbToRBG(idct_data, idct_data = YPrPbToRBG(idct_data, colorProcParameters.kr, // 0.299; colorProcParameters.kr, // 0.299; Loading Loading @@ -1467,4 +1490,162 @@ public class EyesisDCT { return rbg; return rbg; } } public double [][] edge_emphasis( final double [][] yPrPb, final int width, final int step, // just for multi-threading efficiency? final double nonlin_max_y, // = 1.0; // maximal amount of nonlinear line/edge emphasis for Y component final double nonlin_max_c, // = 1.0; // maximal amount of nonlinear line/edge emphasis for C component 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 int threadsMax, // maximal number of threads to launch final int globalDebugLevel) { final double [][] yPrPb_new = new double [yPrPb.length][yPrPb[0].length]; final int height = yPrPb[0].length/width; final int tilesY = (height + step - 1) / step; final int tilesX = (width + step - 1) / step; final int nTiles=tilesX*tilesY; final int [][] probes = {{1,7},{3,5},{2,6},{0,8}}; // indices in [012/345/678] 3x3 square to calculate squared sums of differences final int [][] kerns = {{ 1, 3, 5, 7}, {1, 3, 5, 7}, {0, 2, 6, 8}, {0, 2, 6, 8}}; // indices in [012/345/678] 3x3 square to convolve data final double [][] kernsw = {{-1.0,1.0,1.0,-1.0},{1.0,-1.0,-1.0,1.0},{1.0,-1.0,-1.0,1.0},{-1.0,1.0,1.0,-1.0}}; // weights of kern elements 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][]; for (int n = 0; n < kernsw.length; n++){ kernsw_y[n] = new double [kernsw[n].length]; kernsw_c[n] = new double [kernsw[n].length]; for (int i = 0; i < kernsw[n].length; i++){ double dy = nonlin_y * ((n>=2)? nonlin_corn: 1.0); double dc = nonlin_c * ((n>=2)? nonlin_corn: 1.0); kernsw_y[n][i] = kernsw[n][i] * dy* dy; kernsw_c[n][i] = kernsw[n][i] * dc* dc; } } if (globalDebugLevel > 0){ System.out.println("edge_emphasis(): nonlin_y="+nonlin_y+ ", nonlin_c="+nonlin_c+", nonlin_corn="+nonlin_corn); for (int n=0; n<kernsw_y.length; n++){ System.out.print("kernsw_y["+n+"={"); for (int i = 0; i < kernsw_y[n].length; i++){ System.out.print(kernsw_y[n][i]); if (i == (kernsw_y[n].length - 1)){ System.out.println("}"); } else { System.out.print(", "); } } } for (int n=0; n<kernsw_c.length; n++){ System.out.print("kernsw_c["+n+"={"); for (int i = 0; i < kernsw_c[n].length; i++){ System.out.print(kernsw_c[n][i]); if (i == (kernsw_c[n].length - 1)){ System.out.println("}"); } else { System.out.print(", "); } } } } final Thread[] threads = ImageDtt.newThreadArray(threadsMax); final AtomicInteger ai = new AtomicInteger(0); for (int ithread = 0; ithread < threads.length; ithread++) { threads[ithread] = new Thread() { public void run() { int tileY,tileX; double [] neibs = new double[9]; // pixels around current, first Y, then each color diff double [] kern_y = new double[9]; // weights of neighbors to add to the current for Y double [] kern_c = new double[9]; // weights of neighbors to add to the current for colors diffs int center_index = 4; for (int nTile = ai.getAndIncrement(); nTile < nTiles; nTile = ai.getAndIncrement()) { tileY = nTile/tilesX; tileX = nTile - tileY * tilesX; int y1 = (tileY +1) * step; if (y1 > height) y1 = height; int x1 = (tileX +1) * step; if (x1 > width) x1 = width; for (int y = tileY * step; y < y1; y++) { for (int x = tileX * step; x < x1; x++) { int indx = y*width + x; for (int n = 0; n < yPrPb.length; n++) { yPrPb_new[n][indx] = yPrPb[n][indx]; // default - just copy old value } if ((y > 0) && (y < (height - 1)) && (x > 0) && (x < (width - 1))) { // only correct those not on the edge // read Y pixels around current for (int i = 0; i < neibs.length; i++){ neibs[i] = yPrPb[0][indx+neib_indices[i]]; } for (int i = 0; i < kern_y.length; i++){ kern_y[i] = 0.0; kern_c[i] = 0.0; } // calculate amount of each pattern for (int n = 0; n < probes.length; n++){ double squared=0.0; for (int i = 0; i < probes[n].length; i++){ squared += neibs[probes[n][i]]; } squared -= probes[n].length * neibs[center_index]; squared *= squared; // Now it a square of the sum of differences from the center for (int i = 0; i < kernsw[n].length; i++){ int ni = kerns[n][i]; kern_y[ni]+= squared*kernsw_y[n][i]; kern_c[ni]+= squared*kernsw_c[n][i]; } } if (nonlin_max_y != 0){ double sum = 0; for (int i = 0; i < kern_y.length; i++){ sum += Math.abs(kern_y[i]); } if (sum > nonlin_max_y){ sum = nonlin_max_y/sum; for (int i = 0; i < kern_y.length; i++){ kern_y[i] *= sum; } } } if (nonlin_max_c != 0){ double sum = 0; for (int i = 0; i < kern_c.length; i++){ sum += Math.abs(kern_c[i]); } if (sum > nonlin_max_c){ sum = nonlin_max_c/sum; for (int i = 0; i < kern_c.length; i++){ kern_c[i] *= sum; } } } for (int i = 0; i<kern_y.length; i++){ yPrPb_new[0][indx] += neibs[i]*kern_y[i]; } for (int n = 1;n < 3; n++){ //color components for (int i = 0; i < neibs.length; i++){ yPrPb_new[n][indx] += yPrPb[0][indx+neib_indices[i]]*kern_c[i]; } } } } } } } }; } ImageDtt.startAndJoin(threads); return yPrPb_new; } } }