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

working with color

parent 56b7ed16
......@@ -55,228 +55,228 @@ public class CorrectionColorProc {
double [] denoiseMask,
boolean blueProc,
int debugLevel
) {
double thisGain= colorProcParameters.gain;
double thisBalanceRed= colorProcParameters.balanceRed;
double thisBalanceBlue=colorProcParameters.balanceBlue;
if (channelGainParameters!=null) {
thisGain*= channelGainParameters.gain[channel];
thisBalanceRed*= channelGainParameters.balanceRed[channel];
thisBalanceBlue*=channelGainParameters.balanceBlue[channel];
}
float [] fpixels_r= (float[]) stack.getPixels(1);
float [] fpixels_g= (float[]) stack.getPixels(2);
float [] fpixels_b= (float[]) stack.getPixels(3);
boolean useWeights=(stack.getSize()>=5);
if (!useWeights) {
stack.addSlice("dummy1", fpixels_r);
stack.addSlice("dummy2", fpixels_g);
}
float [] fpixels_wr=(float[]) stack.getPixels(4);
float [] fpixels_wb=(float[]) stack.getPixels(5);
int length=fpixels_r.length;
int width= stack.getWidth();
int height=stack.getHeight();
/* Scale colors, gamma-convert */
int i;
double gain_red= thisBalanceRed* thisGain/scale;
double gain_blue=thisBalanceBlue*thisGain/scale;
double gain_green=thisGain/scale;
double gamma_a=Math.pow(colorProcParameters.minLin,colorProcParameters.gamma)*(1.0-colorProcParameters.gamma);
gamma_a=gamma_a/(1.0-gamma_a);
double gamma_linK=(1.0+gamma_a)*colorProcParameters.gamma*Math.pow(colorProcParameters.minLin,colorProcParameters.gamma)/colorProcParameters.minLin;
double Kg=1.0-colorProcParameters.kr-colorProcParameters.kb;
// Correct color saturation for gamma
double Ar=colorProcParameters.kr*gain_red;
double Ag=Kg*gain_green;
double Ab=colorProcParameters.kb*gain_blue;
if (debugLevel>1) {
System.out.println ( " processColorsWeights() Ar="+Ar+" Ag="+Ag+" Ab="+Ab);
System.out.println ( " processColorsWeights() colorProcParameters.saturationBlue="+colorProcParameters.saturationBlue+
" colorProcParameters.saturationRed="+colorProcParameters.saturationRed);
}
//public void showArrays(double[][] pixels, int width, int height, boolean asStack, String title) {
for (i=0;i<length;i++) {
double Y=Ar*fpixels_r[i]+Ag*fpixels_g[i]+Ab*fpixels_b[i];
Y=linGamma(colorProcParameters.gamma, gamma_a, gamma_linK, colorProcParameters.minLin, Y)/Y;
fpixels_r[i]*=Y*gain_red;
fpixels_g[i]*=Y*gain_green;
fpixels_b[i]*=Y*gain_blue;
}
if (colorProcParameters.corrBlueLeak && blueProc) {
double [][] blueLeakRgb =new double[3][length];
for (int px=0;px<length;px++){
blueLeakRgb[0][px]=fpixels_r[px];
blueLeakRgb[1][px]=fpixels_g[px];
blueLeakRgb[2][px]=fpixels_b[px];
}
BlueLeak blueLeak = new BlueLeak(
colorProcParameters,
blueLeakRgb,
width,
SDFA_INSTANCE,
null, // "blue_corr", //TODO: add normal generation/saving of the intermediate images
debugLevel); // debug level
double [][] blueRemovedRGB= blueLeak.process(); // will later return corrected RGB to use
for (int px=0;px<length;px++){
fpixels_r[px]=(float) blueRemovedRGB[0][px];
fpixels_g[px]=(float) blueRemovedRGB[1][px];
fpixels_b[px]=(float) blueRemovedRGB[2][px];
}
}
/* Convert to YPbPr */
double Y,Pb,Pr;
// 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;
/* coefficients to find Y from Pb, Pr and a color (R,G or B)
) {
double thisGain= colorProcParameters.gain;
double thisBalanceRed= colorProcParameters.balanceRed;
double thisBalanceBlue=colorProcParameters.balanceBlue;
if (channelGainParameters!=null) {
thisGain*= channelGainParameters.gain[channel];
thisBalanceRed*= channelGainParameters.balanceRed[channel];
thisBalanceBlue*=channelGainParameters.balanceBlue[channel];
}
float [] fpixels_r= (float[]) stack.getPixels(1);
float [] fpixels_g= (float[]) stack.getPixels(2);
float [] fpixels_b= (float[]) stack.getPixels(3);
boolean useWeights=(stack.getSize()>=5);
if (!useWeights) {
stack.addSlice("dummy1", fpixels_r);
stack.addSlice("dummy2", fpixels_g);
}
float [] fpixels_wr=(float[]) stack.getPixels(4);
float [] fpixels_wb=(float[]) stack.getPixels(5);
int length=fpixels_r.length;
int width= stack.getWidth();
int height=stack.getHeight();
/* Scale colors, gamma-convert */
int i;
double gain_red= thisBalanceRed* thisGain/scale;
double gain_blue=thisBalanceBlue*thisGain/scale;
double gain_green=thisGain/scale;
double gamma_a=Math.pow(colorProcParameters.minLin,colorProcParameters.gamma)*(1.0-colorProcParameters.gamma);
gamma_a=gamma_a/(1.0-gamma_a);
double gamma_linK=(1.0+gamma_a)*colorProcParameters.gamma*Math.pow(colorProcParameters.minLin,colorProcParameters.gamma)/colorProcParameters.minLin;
double Kg=1.0-colorProcParameters.kr-colorProcParameters.kb;
// Correct color saturation for gamma
double Ar=colorProcParameters.kr*gain_red;
double Ag=Kg*gain_green;
double Ab=colorProcParameters.kb*gain_blue;
if (debugLevel>1) {
System.out.println ( " processColorsWeights() Ar="+Ar+" Ag="+Ag+" Ab="+Ab);
System.out.println ( " processColorsWeights() colorProcParameters.saturationBlue="+colorProcParameters.saturationBlue+
" colorProcParameters.saturationRed="+colorProcParameters.saturationRed);
}
//public void showArrays(double[][] pixels, int width, int height, boolean asStack, String title) {
for (i=0;i<length;i++) {
double Y=Ar*fpixels_r[i]+Ag*fpixels_g[i]+Ab*fpixels_b[i];
Y=linGamma(colorProcParameters.gamma, gamma_a, gamma_linK, colorProcParameters.minLin, Y)/Y;
fpixels_r[i]*=Y*gain_red;
fpixels_g[i]*=Y*gain_green;
fpixels_b[i]*=Y*gain_blue;
}
if (colorProcParameters.corrBlueLeak && blueProc) {
double [][] blueLeakRgb =new double[3][length];
for (int px=0;px<length;px++){
blueLeakRgb[0][px]=fpixels_r[px];
blueLeakRgb[1][px]=fpixels_g[px];
blueLeakRgb[2][px]=fpixels_b[px];
}
BlueLeak blueLeak = new BlueLeak(
colorProcParameters,
blueLeakRgb,
width,
SDFA_INSTANCE,
null, // "blue_corr", //TODO: add normal generation/saving of the intermediate images
debugLevel); // debug level
double [][] blueRemovedRGB= blueLeak.process(); // will later return corrected RGB to use
for (int px=0;px<length;px++){
fpixels_r[px]=(float) blueRemovedRGB[0][px];
fpixels_g[px]=(float) blueRemovedRGB[1][px];
fpixels_b[px]=(float) blueRemovedRGB[2][px];
}
}
/* Convert to YPbPr */
double Y,Pb,Pr;
// 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;
/* coefficients to find Y from Pb, Pr and a color (R,G or B)
Yr = R- Pr*KPrR
Yb = B- Pb*KPbB
Yg = G+ Pr*KPrG + Pb*KPbG
*/
double KPrR= -(2.0*(1-colorProcParameters.kr))/colorProcParameters.saturationRed;
double KPbB= -(2.0*(1-colorProcParameters.kb))/colorProcParameters.saturationBlue;
double KPrG= 2.0*colorProcParameters.kr*(1-colorProcParameters.kr)/Kg/colorProcParameters.saturationRed;
double KPbG= 2.0*colorProcParameters.kb*(1-colorProcParameters.kb)/Kg/colorProcParameters.saturationBlue;
if (debugLevel>1) {
System.out.println ( " processColorsWeights() gain_red="+gain_red+" gain_green="+gain_green+" gain_blue="+gain_blue);
System.out.println ( " processColorsWeights() gamma="+colorProcParameters.gamma+ " minLin="+colorProcParameters.minLin+" gamma_a="+gamma_a+" gamma_linK="+gamma_linK);
System.out.println ( " processColorsWeights() Kr="+colorProcParameters.kr+" Kg="+Kg+" Kb="+colorProcParameters.kb+" Sr="+Sr+" Sb="+Sb);
System.out.println ( " processColorsWeights() KPrR="+KPrR+" KPbB="+KPbB+" KPrG="+KPrG+" KPbG="+KPbG);
}
float [] fpixels_pb= new float [length];
float [] fpixels_pr= new float [length];
float [] fpixels_y0= new float [length];
float [] fpixels_y= fpixels_y0;
float [] fpixels_yR=null;
float [] fpixels_yG=null;
float [] fpixels_yB=null;
if (debugLevel>2) {
fpixels_yR= new float [length];
fpixels_yG= new float [length];
fpixels_yB= new float [length];
}
for (i=0;i<length;i++) {
Y=colorProcParameters.kr*fpixels_r[i]+Kg*fpixels_g[i]+colorProcParameters.kb*fpixels_b[i];
fpixels_pb[i] = (float) (Sb*(fpixels_b[i]-Y));
fpixels_pr[i] = (float) (Sr*(fpixels_r[i]-Y));
fpixels_y0[i]=(float) Y;
}
/* calculate Y from weighted colors, weights derived from how good each color component predicts signal in each subpixel of Bayer pattern */
if (useWeights) {
fpixels_y= new float [length];
for (i=0;i<length;i++) {
Pb=fpixels_pb[i];
Pr=fpixels_pr[i];
Yr = fpixels_r[i]- Pr*KPrR;
Yb = fpixels_b[i]- Pb*KPbB;
Yg = fpixels_g[i]+ Pr*KPrG + Pb*KPbG;
Wr=fpixels_wr[i];
Wb=fpixels_wb[i];
Wg=1.0-Wr-Wb;
S=1.0/(Wr*(colorProcParameters.weightScaleR-1.0)+Wb*(colorProcParameters.weightScaleB-1.0)+1.0);
Wr*=S*colorProcParameters.weightScaleR;
Wb*=S*colorProcParameters.weightScaleB;
Wg*=S;
Y=Yr*Wr+Yg*Wg+Yb*Wb;
fpixels_y[i]=(float) Y;
if (debugLevel>2) {
fpixels_yR[i]= (float) Yr;
fpixels_yG[i]= (float) Yg;
fpixels_yB[i]= (float) Yb;
}
}
}
/* Low-pass filter Pb and Pr */
DoubleGaussianBlur gb=new DoubleGaussianBlur();
double [] dpixels_pr=new double[fpixels_pr.length];
double [] dpixels_pb=new double[fpixels_pb.length];
for (i=0;i<dpixels_pr.length;i++) {
dpixels_pr[i]=fpixels_pr[i];
dpixels_pb[i]=fpixels_pb[i];
}
if (colorProcParameters.maskMax>0.0) {
double [] dmask=new double[fpixels_y0.length];
for (i=0;i<dpixels_pr.length;i++) dmask[i]=fpixels_y0[i];
double [] dpixels_pr_dark=dpixels_pr.clone();
double [] dpixels_pb_dark=dpixels_pb.clone();
gb.blurDouble(dmask, width, height, colorProcParameters.maskSigma, colorProcParameters.maskSigma, 0.01);
gb.blurDouble(dpixels_pr, width, height, colorProcParameters.chromaBrightSigma, colorProcParameters.chromaBrightSigma, 0.01);
gb.blurDouble(dpixels_pb, width, height, colorProcParameters.chromaBrightSigma, colorProcParameters.chromaBrightSigma, 0.01);
gb.blurDouble(dpixels_pr_dark, width, height, colorProcParameters.chromaDarkSigma, colorProcParameters.chromaDarkSigma, 0.01);
gb.blurDouble(dpixels_pb_dark, width, height, colorProcParameters.chromaDarkSigma, colorProcParameters.chromaDarkSigma, 0.01);
if (debugLevel>2) {
SDFA_INSTANCE.showArrays(dmask, width, height,"dmask");
SDFA_INSTANCE.showArrays(dpixels_pr, width, height,"dpixels_pr");
SDFA_INSTANCE.showArrays(dpixels_pb, width, height,"dpixels_pb");
SDFA_INSTANCE.showArrays(dpixels_pr_dark, width, height,"dpixels_pr_dark");
SDFA_INSTANCE.showArrays(dpixels_pb_dark, width, height,"dpixels_pb_dark");
}
double mp;
double k =1.0/(colorProcParameters.maskMax-colorProcParameters.maskMin);
for (i=0;i<dmask.length;i++) {
mp=dmask[i];
if (mp < colorProcParameters.maskMin) {
dmask[i]=0.0;
} else if (mp< colorProcParameters.maskMax) {
dmask[i]= k*(mp-colorProcParameters.maskMin);
} else dmask[i]=1.0;
}
//TODO: null DENOISE_MASK if it is not calculated
if (colorProcParameters.combineWithSharpnessMask) {
if (denoiseMask==null) {
System.out.println ( "Can not combine masks as denoiseMask is null (i.e. no denoise was performed)");
} else if (denoiseMask.length!=dmask.length) {
System.out.println ( "Can not combine masks as denoiseMask length is different from that of dmask");
} else {
for (i=0;i<dmask.length;i++) {
dmask[i]+=denoiseMask[i];
if (dmask[i]>1.0) dmask[i]=1.0;
}
}
}
for (i=0;i<dmask.length;i++) {
mp=dmask[i];
dpixels_pb[i]= (1.0-mp)*dpixels_pb_dark[i]+ mp* dpixels_pb[i];
dpixels_pr[i]= (1.0-mp)*dpixels_pr_dark[i]+ mp* dpixels_pr[i];
}
this.denoiseMaskChroma=dmask; // (global, used to return denoise mask to save/show
this.denoiseMaskChromaWidth=width; // width of the this.denoiseMaskChroma image
} else {
gb.blurDouble(dpixels_pr, width, height, colorProcParameters.chromaBrightSigma, colorProcParameters.chromaBrightSigma, 0.01);
gb.blurDouble(dpixels_pb, width, height, colorProcParameters.chromaBrightSigma, colorProcParameters.chromaBrightSigma, 0.01);
this.denoiseMaskChroma=null; // (global, used to return denoise mask to save/show
}
for (i=0;i<dpixels_pr.length;i++) {
fpixels_pr[i]=(float) dpixels_pr[i];
fpixels_pb[i]=(float) dpixels_pb[i];
}
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)
if (debugLevel>2) {
stack.addSlice("Yr",fpixels_yR);
stack.addSlice("Yg",fpixels_yG);
stack.addSlice("Yb",fpixels_yB);
}
*/
double KPrR= -(2.0*(1-colorProcParameters.kr))/colorProcParameters.saturationRed;
double KPbB= -(2.0*(1-colorProcParameters.kb))/colorProcParameters.saturationBlue;
double KPrG= 2.0*colorProcParameters.kr*(1-colorProcParameters.kr)/Kg/colorProcParameters.saturationRed;
double KPbG= 2.0*colorProcParameters.kb*(1-colorProcParameters.kb)/Kg/colorProcParameters.saturationBlue;
if (debugLevel>1) {
System.out.println ( " processColorsWeights() gain_red="+gain_red+" gain_green="+gain_green+" gain_blue="+gain_blue);
System.out.println ( " processColorsWeights() gamma="+colorProcParameters.gamma+ " minLin="+colorProcParameters.minLin+" gamma_a="+gamma_a+" gamma_linK="+gamma_linK);
System.out.println ( " processColorsWeights() Kr="+colorProcParameters.kr+" Kg="+Kg+" Kb="+colorProcParameters.kb+" Sr="+Sr+" Sb="+Sb);
System.out.println ( " processColorsWeights() KPrR="+KPrR+" KPbB="+KPbB+" KPrG="+KPrG+" KPbG="+KPbG);
}
float [] fpixels_pb= new float [length];
float [] fpixels_pr= new float [length];
float [] fpixels_y0= new float [length];
float [] fpixels_y= fpixels_y0;
float [] fpixels_yR=null;
float [] fpixels_yG=null;
float [] fpixels_yB=null;
if (debugLevel>2) {
fpixels_yR= new float [length];
fpixels_yG= new float [length];
fpixels_yB= new float [length];
}
for (i=0;i<length;i++) {
Y=colorProcParameters.kr*fpixels_r[i]+Kg*fpixels_g[i]+colorProcParameters.kb*fpixels_b[i];
fpixels_pb[i] = (float) (Sb*(fpixels_b[i]-Y));
fpixels_pr[i] = (float) (Sr*(fpixels_r[i]-Y));
fpixels_y0[i]=(float) Y;
}
/* calculate Y from weighted colors, weights derived from how good each color component predicts signal in each subpixel of Bayer pattern */
if (useWeights) {
fpixels_y= new float [length];
for (i=0;i<length;i++) {
Pb=fpixels_pb[i];
Pr=fpixels_pr[i];
Yr = fpixels_r[i]- Pr*KPrR;
Yb = fpixels_b[i]- Pb*KPbB;
Yg = fpixels_g[i]+ Pr*KPrG + Pb*KPbG;
Wr=fpixels_wr[i];
Wb=fpixels_wb[i];
Wg=1.0-Wr-Wb;
S=1.0/(Wr*(colorProcParameters.weightScaleR-1.0)+Wb*(colorProcParameters.weightScaleB-1.0)+1.0);
Wr*=S*colorProcParameters.weightScaleR;
Wb*=S*colorProcParameters.weightScaleB;
Wg*=S;
Y=Yr*Wr+Yg*Wg+Yb*Wb;
fpixels_y[i]=(float) Y;
if (debugLevel>2) {
fpixels_yR[i]= (float) Yr;
fpixels_yG[i]= (float) Yg;
fpixels_yB[i]= (float) Yb;
}
}
}
/* Low-pass filter Pb and Pr */
DoubleGaussianBlur gb=new DoubleGaussianBlur();
double [] dpixels_pr=new double[fpixels_pr.length];
double [] dpixels_pb=new double[fpixels_pb.length];
for (i=0;i<dpixels_pr.length;i++) {
dpixels_pr[i]=fpixels_pr[i];
dpixels_pb[i]=fpixels_pb[i];
}
if (colorProcParameters.maskMax>0.0) {
double [] dmask=new double[fpixels_y0.length];
for (i=0;i<dpixels_pr.length;i++) dmask[i]=fpixels_y0[i];
double [] dpixels_pr_dark=dpixels_pr.clone();
double [] dpixels_pb_dark=dpixels_pb.clone();
gb.blurDouble(dmask, width, height, colorProcParameters.maskSigma, colorProcParameters.maskSigma, 0.01);
gb.blurDouble(dpixels_pr, width, height, colorProcParameters.chromaBrightSigma, colorProcParameters.chromaBrightSigma, 0.01);
gb.blurDouble(dpixels_pb, width, height, colorProcParameters.chromaBrightSigma, colorProcParameters.chromaBrightSigma, 0.01);
gb.blurDouble(dpixels_pr_dark, width, height, colorProcParameters.chromaDarkSigma, colorProcParameters.chromaDarkSigma, 0.01);
gb.blurDouble(dpixels_pb_dark, width, height, colorProcParameters.chromaDarkSigma, colorProcParameters.chromaDarkSigma, 0.01);
if (debugLevel>2) {
SDFA_INSTANCE.showArrays(dmask, width, height,"dmask");
SDFA_INSTANCE.showArrays(dpixels_pr, width, height,"dpixels_pr");
SDFA_INSTANCE.showArrays(dpixels_pb, width, height,"dpixels_pb");
SDFA_INSTANCE.showArrays(dpixels_pr_dark, width, height,"dpixels_pr_dark");
SDFA_INSTANCE.showArrays(dpixels_pb_dark, width, height,"dpixels_pb_dark");
}
double mp;
double k =1.0/(colorProcParameters.maskMax-colorProcParameters.maskMin);
for (i=0;i<dmask.length;i++) {
mp=dmask[i];
if (mp < colorProcParameters.maskMin) {
dmask[i]=0.0;
} else if (mp< colorProcParameters.maskMax) {
dmask[i]= k*(mp-colorProcParameters.maskMin);
} else dmask[i]=1.0;
}
//TODO: null DENOISE_MASK if it is not calculated
if (colorProcParameters.combineWithSharpnessMask) {
if (denoiseMask==null) {
System.out.println ( "Can not combine masks as denoiseMask is null (i.e. no denoise was performed)");
} else if (denoiseMask.length!=dmask.length) {
System.out.println ( "Can not combine masks as denoiseMask length is different from that of dmask");
} else {
for (i=0;i<dmask.length;i++) {
dmask[i]+=denoiseMask[i];
if (dmask[i]>1.0) dmask[i]=1.0;
}
}
}
for (i=0;i<dmask.length;i++) {
mp=dmask[i];
dpixels_pb[i]= (1.0-mp)*dpixels_pb_dark[i]+ mp* dpixels_pb[i];
dpixels_pr[i]= (1.0-mp)*dpixels_pr_dark[i]+ mp* dpixels_pr[i];
}
this.denoiseMaskChroma=dmask; // (global, used to return denoise mask to save/show
this.denoiseMaskChromaWidth=width; // width of the this.denoiseMaskChroma image
} else {
gb.blurDouble(dpixels_pr, width, height, colorProcParameters.chromaBrightSigma, colorProcParameters.chromaBrightSigma, 0.01);
gb.blurDouble(dpixels_pb, width, height, colorProcParameters.chromaBrightSigma, colorProcParameters.chromaBrightSigma, 0.01);
this.denoiseMaskChroma=null; // (global, used to return denoise mask to save/show
}
for (i=0;i<dpixels_pr.length;i++) {
fpixels_pr[i]=(float) dpixels_pr[i];
fpixels_pb[i]=(float) dpixels_pb[i];
}
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 comparison only)
if (debugLevel>2) {
stack.addSlice("Yr",fpixels_yR);
stack.addSlice("Yg",fpixels_yG);
stack.addSlice("Yb",fpixels_yB);
}
}
......
......@@ -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,
......@@ -1857,6 +1863,12 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"convolve_direct", this.convolve_direct+"");
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){
......@@ -1894,7 +1906,12 @@ 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() {
GenericDialog gd = new GenericDialog("Set DCT parameters");
......@@ -1931,9 +1948,15 @@ public class EyesisCorrectionParameters {
gd.addCheckbox ("Do not apply symmetrical (DCT) correction ", this.skip_sym);
gd.addCheckbox ("Convolve directly with symmetrical kernel (debug feature) ", this.convolve_direct);
gd.addNumericField("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);
WindowTools.addScrollBars(gd);
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();
if (gd.wasCanceled()) return false;
......@@ -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()+
" kernel_asym_stack.getHeight() = "+kernel_asym_stack.getHeight());
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,14 +677,15 @@ 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;
System.out.println("readDCTKernels() debugLevel = "+debugLevel+
" kernels["+chn+"].size = "+kernels[chn].size+
" kernels["+chn+"].img_step = "+kernels[chn].img_step+
" kernels["+chn+"].asym_nonzero = "+kernels[chn].asym_nonzero+
" nColors = "+ nColors+
" numVert = "+ numVert+
" numHor = "+ numHor);
if (debugLevel>0) {
System.out.println("readDCTKernels() debugLevel = "+debugLevel+
" kernels["+chn+"].size = "+kernels[chn].size+
" kernels["+chn+"].img_step = "+kernels[chn].img_step+
" kernels["+chn+"].asym_nonzero = "+kernels[chn].asym_nonzero+
" 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]);
......@@ -780,9 +787,11 @@ public class EyesisDCT {
// System.out.println("tileY="+tileY);
}
}
// Debug will be removed later, the
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]);
// 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
}
......@@ -847,12 +856,14 @@ public class EyesisDCT {
double [] asym_kernel = new double[asym_size*asym_size];
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];
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,15 +1131,27 @@ public class EyesisDCT {
threadsMax,
debugLevel,
updateStatus);
for (int chn = 0; chn < dctdc_data.length; chn++) {
image_dtt.dct_lpf(
dct_parameters.dbg_sigma,
dctdc_data[chn],
threadsMax,
debugLevel);
}
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,
dctdc_data[chn],
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++) {
dct_dc[chn] = image_dtt.lapped_dct_dcac(
false, // out_ac, // false - output DC, true - output AC
dctdc_data [chn],
threadsMax,
debugLevel);
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);
sdfa_instance.showArrays(dct_ac,
tilesX*dct_parameters.dct_size,
tilesY*dct_parameters.dct_size,
true,
result.getTitle()+"-DCT_AC");
sdfa_instance.showArrays(dct_dc,
tilesX,
tilesY,
true,
result.getTitle()+"-DCT_DC");
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);
}
sdfa_instance.showArrays(idct_data,
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-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()+"-IDCTDC");
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,16 +2758,18 @@ 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);
SDFA_INSTANCE.showArrays(dct_ac,
tilesX*DCT_PARAMETERS.dct_size,
tilesY*DCT_PARAMETERS.dct_size,
true,
DBG_IMP.getTitle()+"-DCT_AC");
SDFA_INSTANCE.showArrays(dct_dc,
tilesX,
tilesY,
true,
DBG_IMP.getTitle()+"-DCT_DC");
if (DEBUG_LEVEL > 0){
SDFA_INSTANCE.showArrays(dct_ac,
tilesX*DCT_PARAMETERS.dct_size,
tilesY*DCT_PARAMETERS.dct_size,
true,
DBG_IMP.getTitle()+"-DCT_AC");
SDFA_INSTANCE.showArrays(dct_dc,
tilesX,
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,18 +129,19 @@ 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;
System.out.println("lapped_idct():dct_width="+dct_width);
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);
double debug0 = 0.0;
for (int i=0;i<dct_data.length;i++){
debug0 +=dct_data[i]*dct_data[i];
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);
System.out.println("lapped_idct():width= "+width);
System.out.println("lapped_idct():height= "+height);
double debug0 = 0.0;
for (int i=0;i<dct_data.length;i++){
debug0 +=dct_data[i]*dct_data[i];
}
debug0 = Math.sqrt(debug0)/dct_data.length;
System.out.println("lapped_idct():debug0= "+debug0+" (dct_data.length= "+dct_data.length+")");
}
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);
*/
System.out.println("lapped_dctdc(): width="+width+" height="+height);
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);
......@@ -534,23 +492,25 @@ public class ImageDtt {
dct_kernels.st_direct[color][kernelTileY][kernelTileX],
dct_kernels.st_kernels[color][kernelTileY][kernelTileX],
tile_out_copy,
tile_out};
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);
double s0=0.0, s1=0.0, s2=0.0, s3=0.0;
for (int i=0;i<dct_size;i++){
double scale0 = (i>0)?2.0:1.0;
for (int j=0;j<dct_size;j++){
double scale = scale0*((j>0)?2.0:1.0);
int indx = i*dct_size+j;
s0+=scale*dct_kernels.st_direct[color][kernelTileY][kernelTileX][indx];
s1+=scale*dct_kernels.st_kernels[color][kernelTileY][kernelTileX][indx];
s2+= dct_kernels.st_kernels[color][kernelTileY][kernelTileX][indx];
s3+=dciii[indx]*dct_kernels.st_kernels[color][kernelTileY][kernelTileX][indx];
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);
double s0=0.0, s1=0.0, s2=0.0, s3=0.0;
for (int i=0;i<dct_size;i++){
double scale0 = (i>0)?2.0:1.0;
for (int j=0;j<dct_size;j++){
double scale = scale0*((j>0)?2.0:1.0);
int indx = i*dct_size+j;
s0+=scale*dct_kernels.st_direct[color][kernelTileY][kernelTileX][indx];
s1+=scale*dct_kernels.st_kernels[color][kernelTileY][kernelTileX][indx];
s2+= dct_kernels.st_kernels[color][kernelTileY][kernelTileX][indx];
s3+=dciii[indx]*dct_kernels.st_kernels[color][kernelTileY][kernelTileX][indx];
}
}
System.out.println("s0="+s0+" s1="+s1+" s2="+s2+" s3="+s3);
}
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;
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);
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