Commit 4648e870 authored by Andrey Filippov's avatar Andrey Filippov

working with color

parent 56b7ed16
......@@ -100,7 +100,7 @@ public class CorrectionColorProc {
}
//public void showArrays(double[][] pixels, int width, int height, boolean asStack, String title) {
//public void showArrays(double[][] pixels, int width, int height, boolean asStack, String title) {
......@@ -138,7 +138,7 @@ public class CorrectionColorProc {
/* Convert to YPbPr */
double Y,Pb,Pr;
// double Kg=1.0-colorProcParameters.kr-colorProcParameters.kb;
// double Kg=1.0-colorProcParameters.kr-colorProcParameters.kb;
double Sb=0.5/(1.0-colorProcParameters.kb)*colorProcParameters.saturationBlue;
double Sr=0.5/(1.0-colorProcParameters.kr)*colorProcParameters.saturationRed;
double Yr,Yg,Yb,Wr,Wg,Wb,S;
......@@ -271,7 +271,7 @@ public class CorrectionColorProc {
stack.addSlice("Pr", fpixels_pr);
stack.addSlice("Pb", fpixels_pb);
stack.addSlice("Y", fpixels_y);
stack.addSlice("Y0", fpixels_y0); // not filtered by low-pass, preliminary (for comaprison only)
stack.addSlice("Y0", fpixels_y0); // not filtered by low-pass, preliminary (for comparison only)
if (debugLevel>2) {
stack.addSlice("Yr",fpixels_yR);
stack.addSlice("Yg",fpixels_yG);
......
......@@ -1802,7 +1802,13 @@ public class EyesisCorrectionParameters {
public boolean convolve_direct = false; // do not apply symmetrical correction
public double vignetting_max = 0.4; // value in vignetting data to correspond to 1x in the kernel
public double vignetting_range = 3.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 double sigma_rb = 0.5; // additional (to G) blur for R and B
public double sigma_y = 0.5; // 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 line_thershold = 1.0; // line detection amplitude to apply line enhancement
public DCTParameters(
int dct_size,
......@@ -1858,6 +1864,12 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"vignetting_max", this.vignetting_max+"");
properties.setProperty(prefix+"vignetting_range", this.vignetting_range+"");
properties.setProperty(prefix+"color_DCT", this.color_DCT+"");
properties.setProperty(prefix+"sigma_rb", this.sigma_rb+"");
properties.setProperty(prefix+"sigma_y", this.sigma_y+"");
properties.setProperty(prefix+"sigma_color", this.sigma_color+"");
properties.setProperty(prefix+"line_thershold", this.line_thershold+"");
}
public void getProperties(String prefix,Properties properties){
if (properties.getProperty(prefix+"dct_size")!=null) this.dct_size=Integer.parseInt(properties.getProperty(prefix+"dct_size"));
......@@ -1894,6 +1906,11 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"convolve_direct")!=null) this.convolve_direct=Boolean.parseBoolean(properties.getProperty(prefix+"convolve_direct"));
if (properties.getProperty(prefix+"vignetting_max")!=null) this.vignetting_max=Double.parseDouble(properties.getProperty(prefix+"vignetting_max"));
if (properties.getProperty(prefix+"vignetting_range")!=null) this.vignetting_range=Double.parseDouble(properties.getProperty(prefix+"vignetting_range"));
if (properties.getProperty(prefix+"color_DCT")!=null) this.color_DCT=Boolean.parseBoolean(properties.getProperty(prefix+"color_DCT"));
if (properties.getProperty(prefix+"sigma_rb")!=null) this.sigma_rb=Double.parseDouble(properties.getProperty(prefix+"sigma_rb"));
if (properties.getProperty(prefix+"sigma_y")!=null) this.sigma_y=Double.parseDouble(properties.getProperty(prefix+"sigma_y"));
if (properties.getProperty(prefix+"sigma_color")!=null) this.sigma_color=Double.parseDouble(properties.getProperty(prefix+"sigma_color"));
if (properties.getProperty(prefix+"line_thershold")!=null) this.line_thershold=Double.parseDouble(properties.getProperty(prefix+"line_thershold"));
}
public boolean showDialog() {
......@@ -1933,6 +1950,12 @@ public class EyesisCorrectionParameters {
gd.addNumericField("Value (max) in vignetting data to correspond to 1x in the kernel",this.vignetting_max, 3);
gd.addNumericField("Do not try to correct vignetting smaller than this fraction of max",this.vignetting_range, 3);
gd.addCheckbox ("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 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("Threshold for line detection", this.line_thershold, 3);
WindowTools.addScrollBars(gd);
gd.showDialog();
......@@ -1971,6 +1994,13 @@ public class EyesisCorrectionParameters {
this.convolve_direct= gd.getNextBoolean();
this.vignetting_max= gd.getNextNumber();
this.vignetting_range= gd.getNextNumber();
this.color_DCT= gd.getNextBoolean();
this.sigma_rb= gd.getNextNumber();
this.sigma_y= gd.getNextNumber();
this.sigma_color= gd.getNextNumber();
this.line_thershold= gd.getNextNumber();
// MASTER_DEBUG_LEVEL= (int) gd.getNextNumber();
return true;
}
......
......@@ -1390,7 +1390,8 @@ public class EyesisCorrections {
/* ======================================================================== */
private boolean fixSliceSequence (
// private boolean fixSliceSequence (
public boolean fixSliceSequence ( // for EyesisDCT
ImageStack stack,
int debugLevel){
int i,j;
......@@ -2254,7 +2255,7 @@ public class EyesisCorrections {
correctionsParameters.JPEG_quality);
}
private void saveAndShow(
void saveAndShow(
// public void saveAndShow(
ImagePlus imp,
EyesisCorrectionParameters.CorrectionParameters correctionsParameters,
......@@ -2263,7 +2264,7 @@ public class EyesisCorrections {
saveAndShow(imp, correctionsParameters, save, show, -1);
}
private void saveAndShow(
void saveAndShow(
ImagePlus imp,
EyesisCorrectionParameters.CorrectionParameters correctionsParameters,
boolean save,
......
......@@ -23,10 +23,14 @@
*/
import java.util.concurrent.atomic.AtomicInteger;
import ij.CompositeImage;
import ij.IJ;
import ij.ImagePlus;
import ij.ImageStack;
import ij.Prefs;
import ij.process.FloatProcessor;
import ij.process.ImageProcessor;
public class EyesisDCT {
......@@ -233,7 +237,6 @@ public class EyesisDCT {
factorConvKernel.setDCWeight (dct_parameters.dc_weight);
int chn,tileY,tileX;
double kscale;
// int chn0=-1;
// int i;
// double sum;
......@@ -241,7 +244,6 @@ public class EyesisDCT {
chn=nTile/numberOfKernelsInChn;
tileY =(nTile % numberOfKernelsInChn)/kernelNumHor;
tileX = nTile % kernelNumHor;
kscale = 1.0;
/*
if (vignetting != null){
int vh = vgn_left + vgn_step * tileX;
......@@ -255,7 +257,7 @@ public class EyesisDCT {
}
kscale = vgn_max/kscale * ((chn == chn_green)? 2:4);
*/
kscale = (chn == chn_green)? 2:4;
//// kscale = (chn == chn_green)? 2:4;
if (tileX==0) {
if (updateStatus) IJ.showStatus("Processing kernels, channel "+(chn+1)+" of "+nChn+", row "+(tileY+1)+" of "+kernelNumVert);
if (globalDebugLevel>2) System.out.println("Processing kernels, channel "+(chn+1)+" of "+nChn+", row "+(tileY+1)+" of "+kernelNumVert+" : "+IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
......@@ -291,7 +293,7 @@ public class EyesisDCT {
for (int i = 0; i < pre_target_kernel.length; i++){
s+=pre_target_kernel[i];
}
s = kscale/s;
s = 1.0 / s;
for (int i = 0; i < pre_target_kernel.length; i++){
pre_target_kernel[i] *= s;
}
......@@ -632,8 +634,10 @@ public class EyesisDCT {
ImageStack kernel_sym_stack= imp_kernel_sym.getStack();
ImageStack kernel_asym_stack= imp_kernel_asym.getStack();
System.out.println( " kernel_asym_stack.getWidth() = "+kernel_asym_stack.getWidth()+
if (debugLevel>0){
System.out.println(" kernel_asym_stack.getWidth() = "+kernel_asym_stack.getWidth()+
" kernel_asym_stack.getHeight() = "+kernel_asym_stack.getHeight());
}
int nColors = kernel_sym_stack.getSize();
kernels[chn]= new DCTKernels();
kernels[chn].size = dct_parameters.dct_size;
......@@ -673,6 +677,7 @@ public class EyesisDCT {
kernels[chn].asym_indx = new int [nColors][numVert][numHor][asym_nonzero];
int sym_kernel_inc_index = numHor * dct_size;
int asym_kernel_inc_index = numHor * asym_size;
if (debugLevel>0) {
System.out.println("readDCTKernels() debugLevel = "+debugLevel+
" kernels["+chn+"].size = "+kernels[chn].size+
" kernels["+chn+"].img_step = "+kernels[chn].img_step+
......@@ -680,7 +685,7 @@ public class EyesisDCT {
" nColors = "+ nColors+
" numVert = "+ numVert+
" numHor = "+ numHor);
}
for (int nc = 0; nc < nColors; nc++){
for (int tileY = 0; tileY < numVert; tileY++){
for (int tileX = 0; tileX < numHor; tileX++){
......@@ -691,7 +696,7 @@ public class EyesisDCT {
for (int j = 0; (j < dct_parameters.asym_size) && (indx < asym_nonzero); j++){
double v = kernels[chn].asym_kernels[nc][asym_kernel_start_index + i * asym_kernel_inc_index +j];
if (v!=0.0){
if ((tileY==67) && (tileX==125)) {
if ((debugLevel>0) && (tileY==67) && (tileX==125)) {
System.out.println("i="+i+" j="+j+" v="+v+" indx="+indx+" i * asym_size + j="+(i * asym_size + j));
System.out.println("asym_kernel_start_index + i * asym_kernel_inc_index +j="+(asym_kernel_start_index + i * asym_kernel_inc_index +j));
}
......@@ -701,7 +706,7 @@ public class EyesisDCT {
}
}
}
if ((tileY==67) && (tileX==125)) {
if ((debugLevel>0) && (tileY==67) && (tileX==125)) {
for (int i=0; i<kernels[chn].asym_indx[nc][tileY][tileX].length; i++){
System.out.println("kernels["+chn+"].asym_val["+nc+"]["+tileY+"]["+tileX+"]["+i+"]="+kernels[chn].asym_val[nc][tileY][tileX][i]);
System.out.println("kernels["+chn+"].asym_indx["+nc+"]["+tileY+"]["+tileX+"]["+i+"]="+kernels[chn].asym_indx[nc][tileY][tileX][i]);
......@@ -712,15 +717,17 @@ public class EyesisDCT {
if (dct_parameters.normalize) {
for (int i = 0; i < kernels[chn].asym_val[nc][tileY][tileX].length;i++){
scale_asym += kernels[chn].asym_val[nc][tileY][tileX][i];
if ((tileY==67) && (tileX==125)) {
if ((debugLevel>0) && (tileY==67) && (tileX==125)) {
System.out.println("i="+i+", sum="+scale_asym);
}
}
double k = ((nc == 2)? 1.0:2.0) / scale_asym;
for (int i = 0; i < kernels[chn].asym_val[nc][tileY][tileX].length;i++){
kernels[chn].asym_val[nc][tileY][tileX][i] /= scale_asym;
// kernels[chn].asym_val[nc][tileY][tileX][i] /= scale_asym;
kernels[chn].asym_val[nc][tileY][tileX][i] *= k; // includes correction for different number of pixels in r,b(1/4) and G (2/4)
}
if ((tileY==67) && (tileX==125)) {
System.out.println("sum="+scale_asym+", normalized:");
if ((debugLevel>0) && (tileY==67) && (tileX==125)) {
System.out.println("nc="+nc+" sum="+scale_asym+", normalized:");
for (int i=0; i<kernels[chn].asym_indx[nc][tileY][tileX].length; i++){
System.out.println("kernels["+chn+"].asym_val["+nc+"]["+tileY+"]["+tileX+"]["+i+"]="+kernels[chn].asym_val[nc][tileY][tileX][i]);
......@@ -781,8 +788,10 @@ public class EyesisDCT {
}
}
// Debug will be removed later, the
if (debugLevel > 0) {
sdfa_instance.showArrays(kernels[chn].sym_kernels, sym_width, sym_height, true, symKernelPaths[chn]);
sdfa_instance.showArrays(kernels[chn].asym_kernels, asym_width, asym_height, true, asymKernelPaths[chn]);
}
kernels[chn].sym_kernels = null; // not needed anymore
kernels[chn].asym_kernels = null; // not needed anymore
}
......@@ -848,11 +857,13 @@ public class EyesisDCT {
for (int i=0;i<asym_kernel.length; i++) asym_kernel[i] = 0.0;
for (int i = 0; i<kernels[chn].asym_indx[nc][tileY][tileX].length; i++){
asym_kernel[kernels[chn].asym_indx[nc][tileY][tileX][i]] = kernels[chn].asym_val[nc][tileY][tileX][i];
/*
if ((tileY==67) && (tileX==125)) {
System.out.println("kernels["+chn+"].asym_val["+nc+"]["+tileY+"]["+tileX+"]["+i+"]="+kernels[chn].asym_val[nc][tileY][tileX][i]);
System.out.println("kernels["+chn+"].asym_indx["+nc+"]["+tileY+"]["+tileX+"]["+i+"]="+kernels[chn].asym_indx[nc][tileY][tileX][i]);
System.out.println("asym_kernel["+(kernels[chn].asym_indx[nc][tileY][tileX][i])+"]="+asym_kernel[kernels[chn].asym_indx[nc][tileY][tileX][i]]);
}
*/
}
int asym_kernel_start_index = (asym_kernel_inc_index * tileY + tileX)* asym_size;
for (int i = 0; i < asym_size;i++){
......@@ -1064,9 +1075,23 @@ public class EyesisDCT {
System.out.println("Vignetting data for channel "+channel+" has "+eyesisCorrections.channelVignettingCorrection[channel].length+" pixels, image "+path+" has "+pixels.length);
return null;
}
// TODO: Move to do it once:
double min_non_zero = 0.0;
for (int i=0;i<pixels.length;i++){
pixels[i]*=eyesisCorrections.channelVignettingCorrection[channel][i];
double d = eyesisCorrections.channelVignettingCorrection[channel][i];
if ((d > 0.0) && ((min_non_zero == 0) || (min_non_zero > d))){
min_non_zero = d;
}
}
double max_vign_corr = dct_parameters.vignetting_range*min_non_zero;
System.out.println("Vignetting data: channel="+channel+", min = "+min_non_zero);
for (int i=0;i<pixels.length;i++){
double d = eyesisCorrections.channelVignettingCorrection[channel][i];
if (d > max_vign_corr) d = max_vign_corr;
pixels[i]*=d;
}
}
String title=name+"-"+String.format("%02d", channel);
ImagePlus result=imp_src;
......@@ -1106,7 +1131,19 @@ public class EyesisDCT {
threadsMax,
debugLevel,
updateStatus);
System.out.println("dctdc_data.length="+dctdc_data.length+" dctdc_data[0].length="+dctdc_data[0].length
+" dctdc_data[0][0].length="+dctdc_data[0][0].length+" dctdc_data[0][0][0].length="+dctdc_data[0][0][0].length);
if (dct_parameters.color_DCT){ // convert RBG -> YPrPb
dctdc_data = image_dtt.dct_color_convert(
dctdc_data,
colorProcParameters.kr,
colorProcParameters.kb,
dct_parameters.sigma_rb, // blur of channels 0,1 (r,b) in addition to 2 (g)
dct_parameters.sigma_y, // blur of Y from G
dct_parameters.sigma_color, // blur of Pr, Pb in addition to Y
threadsMax,
debugLevel);
} else { // just LPF RGB
for (int chn = 0; chn < dctdc_data.length; chn++) {
image_dtt.dct_lpf(
dct_parameters.dbg_sigma,
......@@ -1114,7 +1151,7 @@ public class EyesisDCT {
threadsMax,
debugLevel);
}
}
int tilesY = stack.getHeight()/dct_parameters.dct_size - 1;
int tilesX = stack.getWidth()/dct_parameters.dct_size - 1;
......@@ -1125,11 +1162,13 @@ public class EyesisDCT {
double [][] dct_dc = new double [dctdc_data.length][];
double [][] dct_ac = new double [dctdc_data.length][];
for (int chn = 0; chn < dct_dc.length; chn++) {
if (!dct_parameters.color_DCT){ // convert RBG -> YPrPb
dct_dc[chn] = image_dtt.lapped_dct_dcac(
false, // out_ac, // false - output DC, true - output AC
dctdc_data [chn],
threadsMax,
debugLevel);
}
dct_ac[chn] = image_dtt.lapped_dct_dcac(
true, // out_ac, // false - output DC, true - output AC
dctdc_data [chn],
......@@ -1137,16 +1176,20 @@ public class EyesisDCT {
debugLevel);
}
// 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,
tilesY*dct_parameters.dct_size,
true,
result.getTitle()+"-DCT_AC");
if (!dct_parameters.color_DCT){ // convert RBG -> YPrPb
sdfa_instance.showArrays(dct_dc,
tilesX,
tilesY,
true,
result.getTitle()+"-DCT_DC");
}
}
double [][] idct_data = new double [dctdc_data.length][];
for (int chn=0; chn<idct_data.length;chn++){
idct_data[chn] = image_dtt.lapped_idctdc(
......@@ -1156,15 +1199,272 @@ public class EyesisDCT {
threadsMax,
debugLevel);
}
if (dct_parameters.color_DCT){ // convert RBG -> YPrPb
sdfa_instance.showArrays(idct_data,
(tilesX + 1) * dct_parameters.dct_size,
(tilesY + 1) * dct_parameters.dct_size,
true,
result.getTitle()+"-IDCTDC");
result.getTitle()+"-IDCTDC-YPrPb");
// temporary convert back to RGB
idct_data = YPrPbToRBG(idct_data,
colorProcParameters.kr, // 0.299;
colorProcParameters.kb, // 0.114;
(tilesX + 1) * dct_parameters.dct_size);
}
sdfa_instance.showArrays(idct_data,
(tilesX + 1) * dct_parameters.dct_size,
(tilesY + 1) * dct_parameters.dct_size,
true,
result.getTitle()+"-IDCTDC-RGB");
// convert to ImageStack of 3 slices
String [] sliceNames = {"red", "blue", "green"};
stack = sdfa_instance.makeStack(
idct_data,
(tilesX + 1) * dct_parameters.dct_size,
(tilesY + 1) * dct_parameters.dct_size,
sliceNames); // or use null to get chn-nn slice names
if (!this.correctionsParameters.colorProc){
result= new ImagePlus(titleFull, stack);
eyesisCorrections.saveAndShow(
result,
this.correctionsParameters);
return result;
}
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;
}
System.out.println("before colors.2");
if (debugLevel > -1){
ImagePlus imp_dbg=new ImagePlus(imp_src.getTitle()+"-"+channel+"-preColors",stack);
eyesisCorrections.saveAndShow(
imp_dbg,
this.correctionsParameters);
}
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,
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 > 0){
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 [] slice_names_YPrPb={"Y","Pr","Pb"};
sdfa_instance.showArrays(idct_data,
stack.getWidth(), // (tilesX + 1) * dct_parameters.dct_size,
stack.getHeight(), // (tilesY + 1) * dct_parameters.dct_size,
true,
result.getTitle()+"-YPrPb",
slice_names_YPrPb);
if (toRGB) {
System.out.println("correctionColorProc.YPrPbToRGB");
stack = YPrPbToRGB(yPrPb,
colorProcParameters.kr, // 0.299;
colorProcParameters.kb, // 0.114;
stack.getWidth());
/*
correctionColorProc.YPrPbToRGB(stack,
colorProcParameters.kr, // 0.299;
colorProcParameters.kb, // 0.114;
colorProcParameters.useFirstY?9:8, // int sliceY,
6, // int slicePr,
7// int slicePb
);
*/
title=titleFull; // including "-DECONV" or "-COMBO"
titleFull=title+"-RGB-float";
//Trim stack to just first 3 slices
if (debugLevel > 0){ // 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 {
title=titleFull; // including "-DECONV" or "-COMBO"
titleFull=title+"-YPrPb"; // including "-DECONV" or "-COMBO"
if (debugLevel > -1) System.out.println("Using full stack, including YPbPr");
}
result= new ImagePlus(titleFull, stack);
// Crop image to match original one (scaled to oversampling)
if (crop){ // always crop if equirectangular
System.out.println("cropping");
stack = eyesisCorrections.cropStack32(stack,splitParameters);
if (debugLevel > -1) { // 2){
ImagePlus imp_dbg=new ImagePlus("cropped",stack);
eyesisCorrections.saveAndShow(
imp_dbg,
this.correctionsParameters);
}
}
// rotate the result
if (rotate){ // never rotate for equirectangular
stack=eyesisCorrections.rotateStack32CW(stack);
}
if (!toRGB && !this.correctionsParameters.jpeg){ // toRGB set for equirectangular
System.out.println("!toRGB && !this.correctionsParameters.jpeg");
eyesisCorrections.saveAndShow(result, this.correctionsParameters);
return result;
} else { // that's not the end result, save if required
System.out.println("!toRGB && !this.correctionsParameters.jpeg - else");
eyesisCorrections.saveAndShow(result,
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";
result= new ImagePlus(titleFull, stack);
// ImagePlus imp_RGB24;
result.updateAndDraw();
System.out.println("result.updateAndDraw(), "+titleFull+"-RGB48");
CompositeImage compositeImage=eyesisCorrections.convertToComposite(result);
if (!this.correctionsParameters.jpeg && !advanced){ // RGB48 was the end result
System.out.println("if (!this.correctionsParameters.jpeg && !advanced)");
eyesisCorrections.saveAndShow(compositeImage, this.correctionsParameters);
return result;
} else { // that's not the end result, save if required
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
}
imp_RGB=eyesisCorrections.convertRGB48toRGB24(
stack,
title+"-RGB24",
0, 65536, // r range 0->0, 65536->256
0, 65536, // g range
0, 65536);// b range
if (JPEG_scale!=1.0){
ImageProcessor ip=imp_RGB.getProcessor();
ip.setInterpolationMethod(ImageProcessor.BICUBIC);
ip=ip.resize((int)(ip.getWidth()*JPEG_scale),(int) (ip.getHeight()*JPEG_scale));
imp_RGB= new ImagePlus(imp_RGB.getTitle(),ip);
imp_RGB.updateAndDraw();
}
eyesisCorrections.saveAndShow(imp_RGB, this.correctionsParameters);
return result;
}
public ImageStack YPrPbToRGB(double [][] yPrPb,
double Kr, // 0.299;
double Kb, // 0.114;
int width
) {
int length = yPrPb[0].length;
int height = length/width;
float [] fpixels_r= new float [length];
float [] fpixels_g= new float [length];
float [] fpixels_b= new float [length];
double Kg=1.0-Kr-Kb;
int i;
/**
R= Y+ Pr*2.0*(1-Kr)
B= Y+ Pb*2.0*(1-Kb)
G= Y +Pr*(- 2*Kr*(1-Kr))/Kg + Pb*(-2*Kb*(1-Kb))/Kg
*/
double KPrR= 2.0*(1-Kr);
double KPbB= 2.0*(1-Kb);
double KPrG= -2.0*Kr*(1-Kr)/Kg;
double KPbG= -2.0*Kb*(1-Kb)/Kg;
double Y,Pr,Pb;
for (i=0;i<length;i++) {
Pb=yPrPb[2][i];
Pr=yPrPb[1][i];
Y =yPrPb[0][i];
fpixels_r[i]=(float) (Y+ Pr*KPrR);
fpixels_b[i]=(float) (Y+ Pb*KPbB);
fpixels_g[i]=(float) (Y+ Pr*KPrG + Pb*KPbG);
}
ImageStack stack=new ImageStack(width,height);
stack.addSlice("red", fpixels_r);
stack.addSlice("green", fpixels_g);
stack.addSlice("blue", fpixels_b);
return stack;
}
public double [][] YPrPbToRBG(double [][] yPrPb,
double Kr, // 0.299;
double Kb, // 0.114;
int width
) {
int length = yPrPb[0].length;
int height = length/width;
double [][]rbg = new double[3][length];
double Kg=1.0-Kr-Kb;
int i;
/**
R= Y+ Pr*2.0*(1-Kr)
B= Y+ Pb*2.0*(1-Kb)
G= Y +Pr*(- 2*Kr*(1-Kr))/Kg + Pb*(-2*Kb*(1-Kb))/Kg
*/
double KPrR= 2.0*(1-Kr);
double KPbB= 2.0*(1-Kb);
double KPrG= -2.0*Kr*(1-Kr)/Kg;
double KPbG= -2.0*Kb*(1-Kb)/Kg;
double Y,Pr,Pb;
for (i=0;i<length;i++) {
Pb=yPrPb[2][i];
Pr=yPrPb[1][i];
Y =yPrPb[0][i];
rbg[0][i]=(float) (Y+ Pr*KPrR);
rbg[1][i]=(float) (Y+ Pb*KPbB);
rbg[2][i]=(float) (Y+ Pr*KPrG + Pb*KPbG);
}
return rbg;
}
}
......@@ -2758,6 +2758,7 @@ private Panel panel1,panel2,panel3,panel4,panel5,panel5a, panel6,panel7,panelPos
DEBUG_LEVEL);
}
// System.out.println("dct_dc.length="+dct_dc.length+" dct_ac.length="+dct_ac.length);
if (DEBUG_LEVEL > 0){
SDFA_INSTANCE.showArrays(dct_ac,
tilesX*DCT_PARAMETERS.dct_size,
tilesY*DCT_PARAMETERS.dct_size,
......@@ -2768,6 +2769,7 @@ private Panel panel1,panel2,panel3,panel4,panel5,panel5a, panel6,panel7,panelPos
tilesY,
true,
DBG_IMP.getTitle()+"-DCT_DC");
}
double [][] idct_data = new double [dctdc_data.length][];
for (int chn=0; chn<idct_data.length;chn++){
idct_data[chn] = image_dtt.lapped_idctdc(
......
......@@ -129,7 +129,7 @@ public class ImageDtt {
final int tilesY=dct_data.length/(dct_width*dct_size);
final int width= (tilesX+1)*dct_size;
final int height= (tilesY+1)*dct_size;
if (globalDebugLevel > 0) {
System.out.println("lapped_idct():dct_width="+dct_width);
System.out.println("lapped_idct():tilesX= "+tilesX);
System.out.println("lapped_idct():tilesY= "+tilesY);
......@@ -141,6 +141,7 @@ public class ImageDtt {
}
debug0 = Math.sqrt(debug0)/dct_data.length;
System.out.println("lapped_idct():debug0= "+debug0+" (dct_data.length= "+dct_data.length+")");
}
final double [] dpixels = new double[width*height];
final Thread[] threads = newThreadArray(threadsMax);
......@@ -282,20 +283,16 @@ public class ImageDtt {
dtt0.set_window(window_type);
final double [] dciii = dtt0.dttt_iii (dc, dct_size);
final double [] dciiie = dtt0.dttt_iiie (dc, dct_size);
if (color ==2) {
if ((globalDebugLevel > 0) && (color ==2)) {
double [][]dcx = {dc,dciii,dciiie, dtt0.dttt_ii(dc, dct_size),dtt0.dttt_iie(dc, dct_size)};
showDoubleFloatArrays sdfa_instance0 = new showDoubleFloatArrays(); // just for debugging?
sdfa_instance0.showArrays(dcx, dct_size, dct_size, true, "dcx");
}
/*
tile_out=dtt.dttt_iv (tile_folded, dct_mode, dct_size);
*/
if (globalDebugLevel > 0) {
System.out.println("lapped_dctdc(): width="+width+" height="+height);
}
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
......@@ -325,7 +322,7 @@ public class ImageDtt {
int asym_center = dct_kernels.asym_size/2; // 7 for 15
kernelTileY = kernel_margin + (tileY * dct_size) / dct_kernels.img_step;
kernelTileX = kernel_margin + (tileX * dct_size) / dct_kernels.img_step;
if ((tileY == debug_tileY) && (tileX == debug_tileX) && (color == 2)) {
if ((globalDebugLevel > 0) && (tileY == debug_tileY) && (tileX == debug_tileX) && (color == 2)) {
System.out.println("kernelTileY="+kernelTileY+" kernelTileX="+kernelTileX+" width="+width);
}
for (int i = 0; i < n2; i++){
......@@ -336,7 +333,7 @@ public class ImageDtt {
double [] asym_val = dct_kernels.asym_val[color][kernelTileY][kernelTileX];
for (int indx = 0; indx < asym_indx.length; indx++){
int xy = asym_indx[indx];
if ((tileY == debug_tileY) && (tileX == debug_tileX) && (color == 2)) {
if ((globalDebugLevel > 0) && (tileY == debug_tileY) && (tileX == debug_tileX) && (color == 2)) {
System.out.println("i="+i+" j="+j+" indx="+indx+" xy="+xy);
}
if (xy >= 0) {
......@@ -349,7 +346,7 @@ public class ImageDtt {
if (y >= height) y = (height - 2) + (y & 1);
if (x >= width) x = (width - 2) + (x & 1);
tile_in[i*n2 + j] += asym_val[indx] * dpixels[ y * width + x];
if ((tileY == debug_tileY) && (tileX == debug_tileX) && (color == 2)) {
if ((globalDebugLevel > 0) && (tileY == debug_tileY) && (tileX == debug_tileX) && (color == 2)) {
System.out.println("dy= "+dy+" dx="+dx+" x = "+x+" y="+y+" y*width + x="+(y*width + x));
System.out.println("asym_val["+indx+"]="+asym_val[indx]+
" dpixels["+(y * width + x)+"]="+ dpixels[ y * width + x]+
......@@ -371,26 +368,6 @@ public class ImageDtt {
int ady = (dy>=0)?dy:-dy;
int sgny = 1;
int y = i - dy;
/*
if (y < 0){
y = -1 -y;
sgny = -sgny;
if (y < 0) {
y = 0;
sgny = 0;
}
}
if (y >= n2){
y = 2*n2 - y;
sgny = -sgny;
if (y >= n2) {
y = n2-1;
sgny = 0;
}
}
*/
if (y < 0){
y = -1 -y;
sgny = -sgny;
......@@ -403,25 +380,6 @@ public class ImageDtt {
int adx = (dx >= 0)? dx:-dx;
int sgn = sgny;
int x = j - dx;
/*
if (x < 0){
x = -1 -x;
sgn = -sgn;
if (x <0) {
x = 0;
sgn = 0;
}
}
if (x >= n2){
x = 2*n2 - x;
sgn = -sgn;
if (x >= n2) {
x = n2-1;
sgn = 0;
}
}
*/
if (x < 0){
x = -1 -x;
sgn = -sgn;
......@@ -432,7 +390,7 @@ public class ImageDtt {
}
sym_conv[indx] += sgn*dir_sym[ady * dct_size + adx] * tile_in[y * n2 + x];
s0+=dir_sym[ady * dct_size + adx];
if ((tileY == debug_tileY) && (tileX == debug_tileX) && (color == 2) &&
if ((globalDebugLevel > 0) && (tileY == debug_tileY) && (tileX == debug_tileX) && (color == 2) &&
(i == dct_size) && (j== dct_size)) {
System.out.println("i="+i+" j="+j+" dy="+dy+" dx="+dx+" ady="+ady+" adx="+adx+
" y="+y+" x="+x+" sgny="+sgny+" sgn="+sgn+
......@@ -447,7 +405,7 @@ public class ImageDtt {
}
if ((tileY == debug_tileY) && (tileX == debug_tileX) && (color == 2)) {
if ((globalDebugLevel > 0) && (tileY == debug_tileY) && (tileX == debug_tileX) && (color == 2)) {
// if ((tileY == debug_tileY) && (tileX == debug_tileX)) {
double [][] pair = {tile_in, sym_conv};
sdfa_instance.showArrays(pair, n2, n2, true, "dconv-X"+tileX+"Y"+tileY+"C"+color);
......@@ -535,6 +493,7 @@ public class ImageDtt {
dct_kernels.st_kernels[color][kernelTileY][kernelTileX],
tile_out_copy,
tile_out};
if (globalDebugLevel > 0){
sdfa_instance.showArrays(tile_in, n2, n2, "tile_in-X"+tileX+"Y"+tileY+"C"+color);
sdfa_instance.showArrays(dbg_tile, dct_size, dct_size, true, "dbg-X"+tileX+"Y"+tileY+"C"+color);
System.out.println("tileY="+tileY+" tileX="+tileX+" kernelTileY="+kernelTileY+" kernelTileX="+kernelTileX);
......@@ -552,6 +511,7 @@ public class ImageDtt {
}
System.out.println("s0="+s0+" s1="+s1+" s2="+s2+" s3="+s3);
}
}
System.arraycopy(tile_out, 0, dctdc_data[tileY][tileX], 0, tile_out.length);
dctdc_data[tileY][tileX][tile_out.length] = dc;
}
......@@ -623,7 +583,7 @@ public class ImageDtt {
}
}
}
if (globalDebugLevel>2) {
if (globalDebugLevel > -1) {
for (int i=0; i<filter_direct.length;i++){
System.out.println("dct_lpf_psf() "+i+": "+filter_direct[i]);
}
......@@ -633,7 +593,7 @@ public class ImageDtt {
final double [] filter= dtt.dttt_iiie(filter_direct);
for (int i=0; i < filter.length;i++) filter[i] *= dct_size;
if (globalDebugLevel>2) {
if (globalDebugLevel > -1) {
for (int i=0; i<filter.length;i++){
System.out.println("dct_lpf_psf() "+i+": "+filter[i]);
}
......@@ -662,6 +622,119 @@ public class ImageDtt {
startAndJoin(threads);
}
public double [][][][] dct_color_convert(
final double [][][][] dctdc_data,
final double kr,
final double kb,
final double sigma_rb, // blur of channels 0,1 (r,b) in addition to 2 (g)
final double sigma_y, // blur of Y from G
final double sigma_color, // blur of Pr, Pb in addition to Y
final int threadsMax, // maximal number of threads to launch
final int globalDebugLevel)
{
final int tilesY=dctdc_data[0].length;
final int tilesX=dctdc_data[0][0].length;
final int nTiles=tilesX*tilesY;
final int dct_size = (int) Math.round(Math.sqrt(dctdc_data[0][0][0].length-1));
final int dct_len = dct_size*dct_size;
final double [][][][] yPrPb = new double [3][tilesY][tilesX][dct_len];
final double [][][] filters = new double [3][3][dct_len];
final double kg = 1.0 - kr - kb;
final double [][] filters_proto_direct = new double[3][dct_len];
final double [][] filters_proto = new double[3][];
System.out.println("dct_color_convert(): kr="+kr+" kg="+kg+" kb="+kb);
final double [] sigmas = {sigma_rb,sigma_y,sigma_color};
for (int n = 0; n<3; n++) {
double s = 0.0;
for (int i = 0; i < dct_size; i++){
for (int j = 0; j < dct_size; j++){
double d;
if (sigmas[n] == 0.0) d = ((i == 0) && (j==0))? 1.0:0.0;
else d = Math.exp(-(i*i+j*j)/(2*sigmas[n]));
filters_proto_direct[n][i*dct_size+j] = d;
if (i > 0) d*=2;
if (j > 0) d*=2;
s += d;
}
}
System.out.println("dct_color_convert(): sigmas["+n+"]="+sigmas[n]+", sum="+s);
for (int i = 0; i < dct_len; i++){
filters_proto_direct[n][i] /=s;
}
}
DttRad2 dtt = new DttRad2(dct_size);
for (int i = 0; i < filters_proto.length; i++){
filters_proto[i] = dtt.dttt_iiie(filters_proto_direct[i]);
System.out.println("filters_proto.length="+filters_proto.length+" filters_proto["+i+"].length="+filters_proto[i].length+" dct_len="+dct_len+" dct_size="+dct_size);
for (int j=0; j < dct_len; j++) filters_proto[i][j] *= 2*dct_size;
}
if (globalDebugLevel > -1) {
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");
}
double [][] coeff_arr ={
{ kr, kb, kg }, // Y = R*Kr+G*Hg+B*Kb
{ 0.5, -kb/(2.0*(1-kr)), -kg/(2.0*(1-kr))}, // Pr = R* 0.5 - G* Kg/(2.0*(1-Kr)) - B *Kb/(2.0*(1-Kr))
{-kr/(2.0*(1-kb)), 0.5, -kg/(2.0*(1-kb))}}; // Pb = B* 0.5 - G* Kg/(2.0*(1-Kb)) - R *Kr/(2.0*(1-Kb))
for (int k = 0; k < dct_len; k++){
for (int i = 0; i < coeff_arr.length; i++){
for (int j = 0; j < coeff_arr.length; j++){
filters[i][j][k] = coeff_arr[i][j]* filters_proto[1][k]; // minimal blur - for all sigma_y
if (i > 0){
filters[i][j][k] *= filters_proto[2][k]; // for Pr, Pb sigma_color
}
if (j <2){ // all but green
filters[i][j][k] *= filters_proto[0][k]; // for R,B sigma_rb
}
}
}
}
if (globalDebugLevel > -1) {
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
double [][] ff = {
filters[0][0], filters[0][1], filters[0][2],
filters[1][0], filters[1][1], filters[1][2],
filters[2][0], filters[2][1], filters[2][2]};
sdfa_instance.showArrays(ff, dct_size,dct_size, true, "filters");
}
final Thread[] threads = newThreadArray(threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
int tileY,tileX;
for (int nTile = ai.getAndIncrement(); nTile < nTiles; nTile = ai.getAndIncrement()) {
tileY = nTile/tilesX;
tileX = nTile - tileY * tilesX;
for (int i = 0; i < filters.length; i++){
for (int k = 0; k <dct_len; k++){
yPrPb[i][tileY][tileX][k]=0.0;
for (int j = 0; j < filters[i].length; j++){
yPrPb[i][tileY][tileX][k] += filters[i][j][k] * dctdc_data[j][tileY][tileX][k];
// yPrPb[i][tileY][tileX][k] += filters[i][j][k] * dctdc_data[2][tileY][tileX][k]; // make it grey level (r=g=b)
}
}
}
}
}
};
}
startAndJoin(threads);
return yPrPb;
}
// Restore DC
......@@ -679,11 +752,12 @@ public class ImageDtt {
final int width= (tilesX+1)*dct_size;
final int height= (tilesY+1)*dct_size;
if (globalDebugLevel > 0) {
System.out.println("lapped_idct():tilesX= "+tilesX);
System.out.println("lapped_idct():tilesY= "+tilesY);
System.out.println("lapped_idct():width= "+width);
System.out.println("lapped_idct():height= "+height);
}
final double [] dpixels = new double[width*height];
final Thread[] threads = newThreadArray(threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
......@@ -718,7 +792,8 @@ public class ImageDtt {
tileX = tiles_list[nser.get()][nTile][0];
tileY = tiles_list[nser.get()][nTile][1];
System.arraycopy(dctdc_data[tileY][tileX], 0, tile_in, 0, tile_in.length);
double dc = dctdc_data[tileY][tileX][tile_in.length];
// will get rid of the DC eventually
double dc = (dctdc_data[tileY][tileX].length > tile_in.length)?dctdc_data[tileY][tileX][tile_in.length]:0.0;
tile_dct=dtt.dttt_iv (tile_in, 0, dct_size);
for (int i = 0; i<tile_dct.length; i++) tile_dct[i] += dc;
tile_out=dtt.unfold_tile(tile_dct, dct_size);
......
......@@ -175,7 +175,28 @@ import ij.process.*;
}
}
}
public ImageStack makeStack(double[][] pixels, int width, int height) {
return makeStack(pixels, width,height, null);
}
public ImageStack makeStack(double[][] pixels, int width, int height, String [] titles) {
float [] fpixels;
ImageStack array_stack=new ImageStack(width,height);
for (int i=0;i<pixels.length;i++) if (pixels[i]!=null) {
if (pixels[i].length!=(width*height)){
System.out.println("showArrays(): pixels["+i+"].length="+pixels[i].length+" != width (+"+width+") * height("+height+")="+(width*height));
return null;
}
fpixels=new float[pixels[i].length];
for (int j=0;j<fpixels.length;j++) fpixels[j]=(float)pixels[i][j];
if (titles!=null){
array_stack.addSlice(titles[i], fpixels);
} else {
array_stack.addSlice("chn-"+i, fpixels);
}
}
return array_stack;
}
public ImagePlus [] makeArrays(double[][] pixels, int width, int height, String title) {
int i,j;
......
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