Commit 695f5cda authored by Andrey Filippov's avatar Andrey Filippov

working on fine correction - not clear where mismatch comes form

parent 75365299
......@@ -1897,7 +1897,8 @@ public class EyesisCorrectionParameters {
public boolean correlate = true; // calculate correlation
public int corr_mask = 15; // bitmask of pairs to combine in the composite
public boolean corr_sym = false; // combine correlation with mirrored around disparity direction
public boolean corr_keep = true; // keep all partial correlations (otherwise - only combined one)
public boolean corr_keep = true; // keep all partial correlations (otherwise - only combined one)
public boolean corr_mismatch= false; // calculate per-pair X/Y variations of measured correlations
// TODO: what to do if some occlusion is present (only some channels correlate)
public double corr_offset = -1.0; //0.1; // add to pair correlation before multiplying by other pairs (between sum and product)
// negative - add, not mpy
......@@ -1935,6 +1936,25 @@ public class EyesisCorrectionParameters {
public boolean show_nonoverlap = true; // show result RGBA before overlap combined (first channels, then RGBA combined?)
public boolean show_overlap = true; // show result RGBA (first channels, then RGBA combined?)
public double disp_scan_start = 0.0; // disparity scan start value
public double disp_scan_step = 1.0; // disparity scan step
public int disp_scan_count = 10; // disparity scan number of measurements
public double fine_corr_x_0 = 0.0; // additionally shift image in port 0 in x direction
public double fine_corr_y_0 = 0.0; // additionally shift image in port 0 in y direction
public double fine_corr_x_1 = 0.0; // additionally shift image in port 1 in x direction
public double fine_corr_y_1 = 0.0; // additionally shift image in port 1 in y direction
public double fine_corr_x_2 = 0.0; // additionally shift image in port 2 in x direction
public double fine_corr_y_2 = 0.0; // additionally shift image in port 2 in y direction
public double fine_corr_x_3 = 0.0; // additionally shift image in port 3 in x direction
public double fine_corr_y_3 = 0.0; // additionally shift image in port 3 in y direction
public double fcorr_min_stength = 0.005; // minimal correlation strength to apply fine correction
public double fcorr_disp_diff = 3.0; // consider only tiles with absolute residual disparity lower than
public boolean fcorr_quadratic = true; // Use quadratic polynomial for fine correction (false - only linear)
......@@ -1969,6 +1989,7 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"corr_mask", this.corr_mask+"");
properties.setProperty(prefix+"corr_sym", this.corr_sym+"");
properties.setProperty(prefix+"corr_keep", this.corr_keep+"");
properties.setProperty(prefix+"corr_mismatch", this.corr_mismatch+"");
properties.setProperty(prefix+"corr_offset", this.corr_offset +"");
properties.setProperty(prefix+"corr_red", this.corr_red +"");
properties.setProperty(prefix+"corr_blue", this.corr_blue +"");
......@@ -1995,6 +2016,22 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"gen_chn_img", this.gen_chn_img+"");
properties.setProperty(prefix+"show_nonoverlap", this.show_nonoverlap+"");
properties.setProperty(prefix+"show_overlap", this.show_overlap+"");
properties.setProperty(prefix+"disp_scan_start", this.disp_scan_start +"");
properties.setProperty(prefix+"disp_scan_step", this.disp_scan_step +"");
properties.setProperty(prefix+"disp_scan_count", this.disp_scan_count+"");
properties.setProperty(prefix+"fine_corr_x_0", this.fine_corr_x_0 +"");
properties.setProperty(prefix+"fine_corr_y_0", this.fine_corr_y_0 +"");
properties.setProperty(prefix+"fine_corr_x_1", this.fine_corr_x_1 +"");
properties.setProperty(prefix+"fine_corr_y_1", this.fine_corr_y_1 +"");
properties.setProperty(prefix+"fine_corr_x_2", this.fine_corr_x_2 +"");
properties.setProperty(prefix+"fine_corr_y_2", this.fine_corr_y_2 +"");
properties.setProperty(prefix+"fine_corr_x_3", this.fine_corr_x_3 +"");
properties.setProperty(prefix+"fine_corr_y_3", this.fine_corr_y_3 +"");
properties.setProperty(prefix+"fcorr_min_stength",this.fcorr_min_stength +"");
properties.setProperty(prefix+"fcorr_disp_diff", this.fcorr_disp_diff +"");
properties.setProperty(prefix+"fcorr_quadratic", this.fcorr_quadratic+"");
}
public void getProperties(String prefix,Properties properties){
......@@ -2027,6 +2064,7 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"corr_mask")!=null) this.corr_mask=Integer.parseInt(properties.getProperty(prefix+"corr_mask"));
if (properties.getProperty(prefix+"corr_sym")!=null) this.corr_sym=Boolean.parseBoolean(properties.getProperty(prefix+"corr_sym"));
if (properties.getProperty(prefix+"corr_keep")!=null) this.corr_keep=Boolean.parseBoolean(properties.getProperty(prefix+"corr_keep"));
if (properties.getProperty(prefix+"corr_mismatch")!=null) this.corr_mismatch=Boolean.parseBoolean(properties.getProperty(prefix+"corr_mismatch"));
if (properties.getProperty(prefix+"corr_offset")!=null) this.corr_offset=Double.parseDouble(properties.getProperty(prefix+"corr_offset"));
if (properties.getProperty(prefix+"corr_red")!=null) this.corr_red=Double.parseDouble(properties.getProperty(prefix+"corr_red"));
if (properties.getProperty(prefix+"corr_blue")!=null) this.corr_blue=Double.parseDouble(properties.getProperty(prefix+"corr_blue"));
......@@ -2053,6 +2091,22 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"gen_chn_img")!=null) this.gen_chn_img=Boolean.parseBoolean(properties.getProperty(prefix+"gen_chn_img"));
if (properties.getProperty(prefix+"show_nonoverlap")!=null)this.show_nonoverlap=Boolean.parseBoolean(properties.getProperty(prefix+"show_nonoverlap"));
if (properties.getProperty(prefix+"show_overlap")!=null) this.show_overlap=Boolean.parseBoolean(properties.getProperty(prefix+"show_overlap"));
if (properties.getProperty(prefix+"disp_scan_start")!=null)this.disp_scan_start=Double.parseDouble(properties.getProperty(prefix+"disp_scan_start"));
if (properties.getProperty(prefix+"disp_scan_step")!=null) this.disp_scan_step=Double.parseDouble(properties.getProperty(prefix+"disp_scan_step"));
if (properties.getProperty(prefix+"disp_scan_count")!=null)this.disp_scan_count=Integer.parseInt(properties.getProperty(prefix+"disp_scan_count"));
if (properties.getProperty(prefix+"fine_corr_x_0")!=null) this.fine_corr_x_0=Double.parseDouble(properties.getProperty(prefix+"fine_corr_x_0"));
if (properties.getProperty(prefix+"fine_corr_y_0")!=null) this.fine_corr_y_0=Double.parseDouble(properties.getProperty(prefix+"fine_corr_y_0"));
if (properties.getProperty(prefix+"fine_corr_x_1")!=null) this.fine_corr_x_1=Double.parseDouble(properties.getProperty(prefix+"fine_corr_x_1"));
if (properties.getProperty(prefix+"fine_corr_y_1")!=null) this.fine_corr_y_1=Double.parseDouble(properties.getProperty(prefix+"fine_corr_y_1"));
if (properties.getProperty(prefix+"fine_corr_x_2")!=null) this.fine_corr_x_2=Double.parseDouble(properties.getProperty(prefix+"fine_corr_x_2"));
if (properties.getProperty(prefix+"fine_corr_y_2")!=null) this.fine_corr_y_2=Double.parseDouble(properties.getProperty(prefix+"fine_corr_y_2"));
if (properties.getProperty(prefix+"fine_corr_x_3")!=null) this.fine_corr_x_3=Double.parseDouble(properties.getProperty(prefix+"fine_corr_x_3"));
if (properties.getProperty(prefix+"fine_corr_y_3")!=null) this.fine_corr_y_3=Double.parseDouble(properties.getProperty(prefix+"fine_corr_y_3"));
if (properties.getProperty(prefix+"fcorr_min_stength")!=null) this.fcorr_min_stength=Double.parseDouble(properties.getProperty(prefix+"fcorr_min_stength"));
if (properties.getProperty(prefix+"fcorr_disp_diff")!=null) this.fcorr_disp_diff=Double.parseDouble(properties.getProperty(prefix+"fcorr_disp_diff"));
if (properties.getProperty(prefix+"fcorr_quadratic")!=null) this.fcorr_quadratic=Boolean.parseBoolean(properties.getProperty(prefix+"fcorr_quadratic"));
}
......@@ -2087,6 +2141,7 @@ public class EyesisCorrectionParameters {
gd.addNumericField("itmask of pairs to combine in the composite (top, bottom, left,righth)", this.corr_mask, 0);
gd.addCheckbox ("Combine correlation with mirrored around disparity direction", this.corr_sym);
gd.addCheckbox ("Keep all partial correlations (otherwise - only combined one)", this.corr_keep);
gd.addCheckbox ("Calculate per-pair X/Y variations of measured correlations ", this.corr_mismatch);
gd.addNumericField("Add to pair correlation before multiplying by other pairs (between sum and product)", this.corr_offset, 6);
gd.addNumericField("Red to green correlation weight", this.corr_red, 4);
gd.addNumericField("Blue to green correlation weight", this.corr_blue, 4);
......@@ -2116,7 +2171,24 @@ public class EyesisCorrectionParameters {
gd.addCheckbox ("Generate shifted channel images", this.gen_chn_img);
gd.addCheckbox ("Show result RGBA before overlap combined", this.show_nonoverlap);
gd.addCheckbox ("Show result RGBA ", this.show_overlap);
gd.addNumericField("Disparity scan start value", this.disp_scan_start, 2);
gd.addNumericField("Disparity scan step", this.disp_scan_step, 2);
gd.addNumericField("Disparity scan number of disparity values to scan", this.disp_scan_count, 0);
gd.addMessage("--- camera fine correction: X/Y for images 0..3 ---");
gd.addNumericField("X 0", this.fine_corr_x_0, 3);
gd.addNumericField("Y 0", this.fine_corr_y_0, 3);
gd.addNumericField("X 1", this.fine_corr_x_1, 3);
gd.addNumericField("Y 1", this.fine_corr_y_1, 3);
gd.addNumericField("X 2", this.fine_corr_x_2, 3);
gd.addNumericField("Y 2", this.fine_corr_y_2, 3);
gd.addNumericField("X 3", this.fine_corr_x_3, 3);
gd.addNumericField("Y 4", this.fine_corr_y_3, 3);
gd.addNumericField("Minimal correlation strength to apply fine correction", this.fcorr_min_stength, 3);
gd.addNumericField("Consider only tiles with absolute residual disparity lower than", this.fcorr_disp_diff, 3);
gd.addCheckbox ("Use quadratic polynomial for fine correction (false - only linear)", this.fcorr_quadratic);
WindowTools.addScrollBars(gd);
gd.showDialog();
......@@ -2150,6 +2222,7 @@ public class EyesisCorrectionParameters {
this.corr_mask= (int) gd.getNextNumber();
this.corr_sym= gd.getNextBoolean();
this.corr_keep= gd.getNextBoolean();
this.corr_mismatch= gd.getNextBoolean();
this.corr_offset= gd.getNextNumber();
this.corr_red= gd.getNextNumber();
this.corr_blue= gd.getNextNumber();
......@@ -2176,6 +2249,23 @@ public class EyesisCorrectionParameters {
this.gen_chn_img= gd.getNextBoolean();
this.show_nonoverlap= gd.getNextBoolean();
this.show_overlap= gd.getNextBoolean();
this.disp_scan_start= gd.getNextNumber();
this.disp_scan_step= gd.getNextNumber();
this.disp_scan_count= (int) gd.getNextNumber();
this.fine_corr_x_0= gd.getNextNumber();
this.fine_corr_y_0= gd.getNextNumber();
this.fine_corr_x_1= gd.getNextNumber();
this.fine_corr_y_1= gd.getNextNumber();
this.fine_corr_x_2= gd.getNextNumber();
this.fine_corr_y_2= gd.getNextNumber();
this.fine_corr_x_3= gd.getNextNumber();
this.fine_corr_y_3= gd.getNextNumber();
this.fcorr_min_stength= gd.getNextNumber();
this.fcorr_disp_diff= gd.getNextNumber();
this.fcorr_quadratic= gd.getNextBoolean();
return true;
}
}
......
......@@ -4763,9 +4763,7 @@ public class EyesisDCT {
}
}
}
public ImagePlus [] processCLTQuadCorr(
ImagePlus [] imp_quad, // should have properties "name"(base for saving results), "channel","path"
EyesisCorrectionParameters.CLTParameters clt_parameters,
......@@ -4853,7 +4851,8 @@ public class EyesisDCT {
//TODO: Add array of default disparity - use for combining images in force disparity mode (no correlation), when disparity is predicted from other tiles
double [][][][] clt_corr_combo = null;
double [][][][][] clt_corr_partial = null;
double [][][][][] clt_corr_partial = null; // [tilesY][tilesX][pair][color][(2*transform_size-1)*(2*transform_size-1)]
double [][] clt_mismatch = null; // [3*4][tilesY * tilesX] // transpose unapplied
double [][][][] texture_tiles = null; // [tilesY][tilesX]["RGBA".length()][]; // tiles will be 16x16, 2 visualizaion mode full 16 or overlapped
// undecided, so 2 modes of combining alpha - same as rgb, or use center tile only
if (clt_parameters.correlate){
......@@ -4874,16 +4873,26 @@ public class EyesisDCT {
}
}
}
if (clt_parameters.corr_mismatch){
clt_mismatch = new double [12][];
}
}
double [][] disparity_map = new double [8][]; //[0] -residual disparity, [1] - orthogonal (just for debugging)
double min_corr_selected = clt_parameters.corr_normalize? clt_parameters.min_corr_normalized: clt_parameters.min_corr;
double [][] shiftXY = {
{clt_parameters.fine_corr_x_0,clt_parameters.fine_corr_y_0},
{clt_parameters.fine_corr_x_1,clt_parameters.fine_corr_y_1},
{clt_parameters.fine_corr_x_2,clt_parameters.fine_corr_y_2},
{clt_parameters.fine_corr_x_3,clt_parameters.fine_corr_y_3}};
double [][][][][][] clt_data = image_dtt.clt_aberrations_quad_corr(
tile_op, // per-tile operation bit codes
clt_parameters.disparity, // final double disparity,
double_stacks, // final double [][][] imade_data, // first index - number of image in a quad
// correlation results - final and partial
clt_corr_combo, // [tilesY][tilesX][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate
clt_corr_partial, // [tilesY][tilesX][quad]color][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate
clt_corr_partial, // [tilesY][tilesX][pair][color][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate
clt_mismatch, // [12][tilesY * tilesX] // transpose unapplied. null - do not calculate
disparity_map, // [2][tilesY * tilesX]
texture_tiles, // [tilesY][tilesX]["RGBA".length()][];
imp_quad[0].getWidth(), // final int width,
......@@ -4911,6 +4920,7 @@ public class EyesisDCT {
clt_parameters.kernel_step,
clt_parameters.transform_size,
clt_parameters.clt_window,
shiftXY, //
clt_parameters.shift_x, // final int shiftX, // shift image horizontally (positive - right) - just for testing
clt_parameters.shift_y, // final int shiftY, // shift image vertically (positive - down)
clt_parameters.tileX, // final int debug_tileX,
......@@ -4984,6 +4994,19 @@ public class EyesisDCT {
}
}
if (clt_mismatch != null){
if (debugLevel > -1){
String [] disparity_titles = {"dx0", "dy0","strength0","dx1", "dy1","strength1","dx2", "dy2","strength2","dx3", "dy3","strength3"};
sdfa_instance.showArrays(
clt_mismatch,
tilesX,
tilesY,
true,
name+"-MISMATCH_XYW-D"+clt_parameters.disparity,
disparity_titles);
}
}
if (debugLevel > -1){
double [][] corr_rslt = new double [clt_corr_combo.length][];
......@@ -5006,7 +5029,7 @@ public class EyesisDCT {
titles );
}
if (debugLevel > 0){ // -1
if (debugLevel > -1){ // -1
if (clt_corr_partial!=null){
String [] allColorNames = {"red","blue","green","combo"};
String [] titles = new String[clt_corr_partial.length];
......@@ -5275,4 +5298,508 @@ public class EyesisDCT {
}
return results;
}
public void cltDisparityScans(
EyesisCorrectionParameters.CLTParameters clt_parameters,
EyesisCorrectionParameters.DebayerParameters debayerParameters,
EyesisCorrectionParameters.NonlinParameters nonlinParameters,
EyesisCorrectionParameters.ColorProcParameters colorProcParameters,
CorrectionColorProc.ColorGainsParameters channelGainParameters,
EyesisCorrectionParameters.RGBParameters rgbParameters,
EyesisCorrectionParameters.EquirectangularParameters equirectangularParameters,
int convolveFFTSize, // 128 - fft size, kernel size should be size/2
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
final int debugLevel)
{
this.startTime=System.nanoTime();
String [] sourceFiles=correctionsParameters.getSourcePaths();
boolean [] enabledFiles=new boolean[sourceFiles.length];
for (int i=0;i<enabledFiles.length;i++) enabledFiles[i]=false;
int numFilesToProcess=0;
int numImagesToProcess=0;
for (int nFile=0;nFile<enabledFiles.length;nFile++){
if ((sourceFiles[nFile]!=null) && (sourceFiles[nFile].length()>1)) {
int [] channels={correctionsParameters.getChannelFromSourceTiff(sourceFiles[nFile])};
if (correctionsParameters.isJP4()){
int subCamera= channels[0]- correctionsParameters.firstSubCamera; // to match those in the sensor files
// removeUnusedSensorData should be off!?
channels=this.eyesisCorrections.pixelMapping.channelsForSubCamera(subCamera);
}
if (channels!=null){
for (int i=0;i<channels.length;i++) if (eyesisCorrections.isChannelEnabled(channels[i])){
if (!enabledFiles[nFile]) numFilesToProcess++;
enabledFiles[nFile]=true;
numImagesToProcess++;
}
}
}
}
if (numFilesToProcess==0){
System.out.println("No files to process (of "+sourceFiles.length+")");
return;
} else {
if (debugLevel>0) System.out.println(numFilesToProcess+ " files to process (of "+sourceFiles.length+"), "+numImagesToProcess+" images to process");
}
double [] referenceExposures=eyesisCorrections.calcReferenceExposures(debugLevel); // multiply each image by this and divide by individual (if not NaN)
int [][] fileIndices=new int [numImagesToProcess][2]; // file index, channel number
int index=0;
for (int nFile=0;nFile<enabledFiles.length;nFile++){
if ((sourceFiles[nFile]!=null) && (sourceFiles[nFile].length()>1)) {
int [] channels={correctionsParameters.getChannelFromSourceTiff(sourceFiles[nFile])};
if (correctionsParameters.isJP4()){
int subCamera= channels[0]- correctionsParameters.firstSubCamera; // to match those in the sensor files
channels=eyesisCorrections.pixelMapping.channelsForSubCamera(subCamera);
}
if (channels!=null){
for (int i=0;i<channels.length;i++) if (eyesisCorrections.isChannelEnabled(channels[i])){
fileIndices[index ][0]=nFile;
fileIndices[index++][1]=channels[i];
}
}
}
}
ArrayList<String> setNames = new ArrayList<String>();
ArrayList<ArrayList<Integer>> setFiles = new ArrayList<ArrayList<Integer>>();
for (int iImage=0;iImage<fileIndices.length;iImage++){
int nFile=fileIndices[iImage][0];
String setName = correctionsParameters.getNameFromSourceTiff(sourceFiles[nFile]);
if (!setNames.contains(setName)) {
setNames.add(setName);
setFiles.add(new ArrayList<Integer>());
}
setFiles.get(setNames.indexOf(setName)).add(new Integer(nFile));
}
for (int nSet = 0; nSet < setNames.size(); nSet++){
int maxChn = 0;
for (int i = 0; i < setFiles.get(nSet).size(); i++){
int chn = fileIndices[setFiles.get(nSet).get(i)][1];
if (chn > maxChn) maxChn = chn;
}
int [] channelFiles = new int[maxChn+1];
for (int i =0; i < channelFiles.length; i++) channelFiles[i] = -1;
for (int i = 0; i < setFiles.get(nSet).size(); i++){
channelFiles[fileIndices[setFiles.get(nSet).get(i)][1]] = setFiles.get(nSet).get(i);
}
ImagePlus [] imp_srcs = new ImagePlus[channelFiles.length];
double [] scaleExposures = new double[channelFiles.length];
for (int srcChannel=0; srcChannel<channelFiles.length; srcChannel++){
int nFile=channelFiles[srcChannel];
imp_srcs[srcChannel]=null;
if (nFile >=0){
if (correctionsParameters.isJP4()){
int subchannel=eyesisCorrections.pixelMapping.getSubChannel(srcChannel);
if (this.correctionsParameters.swapSubchannels01) {
switch (subchannel){
case 0: subchannel=1; break;
case 1: subchannel=0; break;
}
}
if (debugLevel>0) System.out.println("Processing set " + setNames.get(nSet)+" channel "+srcChannel+" - subchannel "+subchannel+" of "+sourceFiles[nFile]);
ImagePlus imp_composite=eyesisCorrections.JP4_INSTANCE.open(
"", // path,
sourceFiles[nFile],
"", //arg - not used in JP46 reader
true, // un-apply camera color gains
null, // new window
false); // do not show
imp_srcs[srcChannel]=eyesisCorrections.JP4_INSTANCE.demuxImage(imp_composite, subchannel);
if (imp_srcs[srcChannel] == null) imp_srcs[srcChannel] = imp_composite; // not a composite image
// do we need to add any properties?
} else {
imp_srcs[srcChannel]=new ImagePlus(sourceFiles[nFile]);
// (new JP46_Reader_camera(false)).decodeProperiesFromInfo(imp_src); // decode existent properties from info
eyesisCorrections.JP4_INSTANCE.decodeProperiesFromInfo(imp_srcs[srcChannel]); // decode existent properties from info
if (debugLevel>0) System.out.println("Processing "+sourceFiles[nFile]);
}
scaleExposures[srcChannel] = 1.0;
if (!Double.isNaN(referenceExposures[nFile]) && (imp_srcs[srcChannel].getProperty("EXPOSURE")!=null)){
scaleExposures[srcChannel] = referenceExposures[nFile]/Double.parseDouble((String) imp_srcs[srcChannel].getProperty("EXPOSURE"));
if (debugLevel>0) System.out.println("Will scale intensity (to compensate for exposure) by "+scaleExposures[srcChannel]);
}
imp_srcs[srcChannel].setProperty("name", correctionsParameters.getNameFromSourceTiff(sourceFiles[nFile]));
imp_srcs[srcChannel].setProperty("channel", srcChannel); // it may already have channel
imp_srcs[srcChannel].setProperty("path", sourceFiles[nFile]); // it may already have channel
if (this.correctionsParameters.pixelDefects && (eyesisCorrections.defectsXY!=null)&& (eyesisCorrections.defectsXY[srcChannel]!=null)){
// apply pixel correction
int numApplied= eyesisCorrections.correctDefects(
imp_srcs[srcChannel],
srcChannel,
debugLevel);
if ((debugLevel>0) && (numApplied>0)) { // reduce verbosity after verified defect correction works
System.out.println("Corrected "+numApplied+" pixels in "+sourceFiles[nFile]);
}
}
if (this.correctionsParameters.vignetting){
if ((eyesisCorrections.channelVignettingCorrection==null) || (srcChannel<0) || (srcChannel>=eyesisCorrections.channelVignettingCorrection.length) || (eyesisCorrections.channelVignettingCorrection[srcChannel]==null)){
System.out.println("No vignetting data for channel "+srcChannel);
return;
}
float [] pixels=(float []) imp_srcs[srcChannel].getProcessor().getPixels();
if (pixels.length!=eyesisCorrections.channelVignettingCorrection[srcChannel].length){
System.out.println("Vignetting data for channel "+srcChannel+" has "+eyesisCorrections.channelVignettingCorrection[srcChannel].length+" pixels, image "+sourceFiles[nFile]+" has "+pixels.length);
return;
}
// TODO: Move to do it once:
double min_non_zero = 0.0;
for (int i=0;i<pixels.length;i++){
double d = eyesisCorrections.channelVignettingCorrection[srcChannel][i];
if ((d > 0.0) && ((min_non_zero == 0) || (min_non_zero > d))){
min_non_zero = d;
}
}
double max_vign_corr = clt_parameters.vignetting_range*min_non_zero;
System.out.println("Vignetting data: channel="+srcChannel+", min = "+min_non_zero);
for (int i=0;i<pixels.length;i++){
double d = eyesisCorrections.channelVignettingCorrection[srcChannel][i];
if (d > max_vign_corr) d = max_vign_corr;
pixels[i]*=d;
}
// Scale here, combine with vignetting later?
int width = imp_srcs[srcChannel].getWidth();
int height = imp_srcs[srcChannel].getHeight();
for (int y = 0; y < height-1; y+=2){
for (int x = 0; x < width-1; x+=2){
pixels[y*width+x ] *= clt_parameters.scale_g;
pixels[y*width+x+width+1] *= clt_parameters.scale_g;
pixels[y*width+x +1] *= clt_parameters.scale_r;
pixels[y*width+x+width ] *= clt_parameters.scale_b;
}
}
} else { // assuming GR/BG pattern
System.out.println("Applying fixed color gain correction parameters: Gr="+
clt_parameters.novignetting_r+", Gg="+clt_parameters.novignetting_g+", Gb="+clt_parameters.novignetting_b);
float [] pixels=(float []) imp_srcs[srcChannel].getProcessor().getPixels();
int width = imp_srcs[srcChannel].getWidth();
int height = imp_srcs[srcChannel].getHeight();
double kr = clt_parameters.scale_r/clt_parameters.novignetting_r;
double kg = clt_parameters.scale_g/clt_parameters.novignetting_g;
double kb = clt_parameters.scale_b/clt_parameters.novignetting_b;
for (int y = 0; y < height-1; y+=2){
for (int x = 0; x < width-1; x+=2){
pixels[y*width+x ] *= kg;
pixels[y*width+x+width+1] *= kg;
pixels[y*width+x +1] *= kr;
pixels[y*width+x+width ] *= kb;
}
}
}
}
}
// once per quad here
// may need to equalize gains between channels
if (clt_parameters.gain_equalize || clt_parameters.colors_equalize){
channelGainsEqualize(
clt_parameters.gain_equalize,
clt_parameters.colors_equalize,
channelFiles,
imp_srcs,
setNames.get(nSet), // just for debug messeges == setNames.get(nSet)
debugLevel);
}
// once per quad here
cltDisparityScan( // returns ImagePlus, but it already should be saved/shown
imp_srcs, // [srcChannel], // should have properties "name"(base for saving results), "channel","path"
clt_parameters,
debayerParameters,
nonlinParameters,
colorProcParameters,
channelGainParameters,
rgbParameters,
convolveFFTSize, // 128 - fft size, kernel size should be size/2
scaleExposures,
threadsMax, // maximal number of threads to launch
updateStatus,
debugLevel);
Runtime.getRuntime().gc();
if (debugLevel >-1) System.out.println("Processing set "+(nSet+1)+" (of "+fileIndices.length+") finished at "+
IJ.d2s(0.000000001*(System.nanoTime()-this.startTime),3)+" sec, --- Free memory="+Runtime.getRuntime().freeMemory()+" (of "+Runtime.getRuntime().totalMemory()+")");
if (eyesisCorrections.stopRequested.get()>0) {
System.out.println("User requested stop");
return;
}
}
System.out.println("Processing "+fileIndices.length+" files finished at "+
IJ.d2s(0.000000001*(System.nanoTime()-this.startTime),3)+" sec, --- Free memory="+Runtime.getRuntime().freeMemory()+" (of "+Runtime.getRuntime().totalMemory()+")");
}
public ImagePlus [] cltDisparityScan(
ImagePlus [] imp_quad, // should have properties "name"(base for saving results), "channel","path"
EyesisCorrectionParameters.CLTParameters clt_parameters,
EyesisCorrectionParameters.DebayerParameters debayerParameters,
EyesisCorrectionParameters.NonlinParameters nonlinParameters,
EyesisCorrectionParameters.ColorProcParameters colorProcParameters,
CorrectionColorProc.ColorGainsParameters channelGainParameters,
EyesisCorrectionParameters.RGBParameters rgbParameters,
int convolveFFTSize, // 128 - fft size, kernel size should be size/2
double [] scaleExposures, // probably not needed here
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
final int debugLevel){
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
// may use this.StartTime to report intermediate steps execution times
String name=(String) imp_quad[0].getProperty("name");
// int channel= Integer.parseInt((String) imp_src.getProperty("channel"));
String path= (String) imp_quad[0].getProperty("path");
ImagePlus [] results = new ImagePlus[imp_quad.length];
for (int i = 0; i < results.length; i++) {
results[i] = imp_quad[i];
results[i].setTitle(results[i].getTitle()+"RAW");
}
if (debugLevel>1) System.out.println("processing: "+path);
double [][][] double_stacks = new double [imp_quad.length][][];
for (int i = 0; i < double_stacks.length; i++){
double_stacks[i] = eyesisCorrections.bayerToDoubleStack(
imp_quad[i], // source Bayer image, linearized, 32-bit (float))
null); // no margins, no oversample
}
// =================
ImageDtt image_dtt = new ImageDtt();
for (int i = 0; i < double_stacks.length; i++){
for (int j =0 ; j < double_stacks[i][0].length; j++){
double_stacks[i][2][j]*=0.5; // Scale green 0.5 to compensate more pixels than R,B
}
}
int tilesY = imp_quad[0].getHeight()/clt_parameters.transform_size;
int tilesX = imp_quad[0].getWidth()/clt_parameters.transform_size;
// temporary setting up tile task file (one integer per tile, bitmask
// for testing defined for a window, later the tiles to process will be calculated based on previous passes results
int [][] tile_op = new int [tilesY][tilesX]; // all zero
int txl = clt_parameters.tile_task_wl;
int txr = txl + clt_parameters.tile_task_ww;
int tyt = clt_parameters.tile_task_wt;
int tyb = tyt + clt_parameters.tile_task_wh;
if (txl < 0) txl = 0;
else if (txl >= tilesX) txl = tilesX - 1;
if (txr <= txl) txr = txl + 1;
else if (txr > tilesX) txr = tilesX;
if (tyt < 0) tyt = 0;
else if (tyt >= tilesY) tyt = tilesY - 1;
if (tyb <= tyt) tyb = tyt + 1;
else if (tyb > tilesY) tyb = tilesY;
for (int i = tyt; i < tyb; i++) {
for (int j = txl; j < txr; j++) {
tile_op[i][j] = clt_parameters.tile_task_op;
}
}
if (debugLevel > -1){
System.out.println("clt_parameters.tile_task_wl="+clt_parameters.tile_task_wl );
System.out.println("clt_parameters.tile_task_wt="+clt_parameters.tile_task_wt );
System.out.println("clt_parameters.tile_task_ww="+clt_parameters.tile_task_ww );
System.out.println("clt_parameters.tile_task_wh="+clt_parameters.tile_task_wh );
System.out.println("tyt="+tyt+" tyb="+tyb+" txl="+txl+" txr="+txr );
}
//TODO: Add array of default disparity - use for combining images in force disparity mode (no correlation), when disparity is predicted from other tiles
// undecided, so 2 modes of combining alpha - same as rgb, or use center tile only
double [][][][] clt_corr_combo = new double [2][tilesY][tilesX][]; // will only be used inside?
double min_corr_selected = clt_parameters.corr_normalize? clt_parameters.min_corr_normalized: clt_parameters.min_corr;
double [][][] disparity_maps = new double [clt_parameters.disp_scan_count][8][]; //[0] -residual disparity, [1] - orthogonal (just for debugging)
for (int scan_step = 0; scan_step < clt_parameters.disp_scan_count; scan_step++) {
double disparity = clt_parameters.disp_scan_start + scan_step * clt_parameters.disp_scan_step;
double [][] shiftXY = {
{clt_parameters.fine_corr_x_0,clt_parameters.fine_corr_y_0},
{clt_parameters.fine_corr_x_1,clt_parameters.fine_corr_y_1},
{clt_parameters.fine_corr_x_2,clt_parameters.fine_corr_y_2},
{clt_parameters.fine_corr_x_3,clt_parameters.fine_corr_y_3}};
image_dtt.clt_aberrations_quad_corr(
tile_op, // per-tile operation bit codes
disparity, // clt_parameters.disparity, // final double disparity,
double_stacks, // final double [][][] imade_data, // first index - number of image in a quad
// correlation results - final and partial
clt_corr_combo, // [tilesY][tilesX][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate
null, // clt_corr_partial, // [tilesY][tilesX][quad]color][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate
null, // [tilesY][tilesX][pair]{dx,dy,weight}[(2*transform_size-1)*(2*transform_size-1)] // transpose unapplied. null - do not calculate
// Use it with disparity_maps[scan_step]? clt_mismatch, // [tilesY][tilesX][pair]{dx,dy,weight}[(2*transform_size-1)*(2*transform_size-1)] // transpose unapplied. null - do not calculate
disparity_maps[scan_step], // [2][tilesY * tilesX]
null, //texture_tiles, // [tilesY][tilesX]["RGBA".length()][];
imp_quad[0].getWidth(), // final int width,
clt_parameters.fat_zero, // add to denominator to modify phase correlation (same units as data1, data2). <0 - pure sum
clt_parameters.corr_sym,
clt_parameters.corr_offset,
clt_parameters.corr_red,
clt_parameters.corr_blue,
clt_parameters.corr_sigma,
clt_parameters.corr_normalize, // normalize correlation results by rms
min_corr_selected, // 0.0001; // minimal correlation value to consider valid
clt_parameters.max_corr_sigma,// 1.5; // weights of points around global max to find fractional
clt_parameters.max_corr_radius,
clt_parameters.corr_mode, // Correlation mode: 0 - integer max, 1 - center of mass, 2 - polynomial
clt_parameters.min_shot, // 10.0; // Do not adjust for shot noise if lower than
clt_parameters.scale_shot, // 3.0; // scale when dividing by sqrt ( <0 - disable correction)
clt_parameters.diff_sigma, // 5.0;//RMS difference from average to reduce weights (~ 1.0 - 1/255 full scale image)
clt_parameters.diff_threshold, // 5.0; // RMS difference from average to discard channel (~ 1.0 - 1/255 full scale image)
clt_parameters.diff_gauss, // true; // when averaging images, use gaussian around average as weight (false - sharp all/nothing)
clt_parameters.min_agree, // 3.0; // minimal number of channels to agree on a point (real number to work with fuzzy averages)
clt_parameters.keep_weights, // Add port weights to RGBA stack (debug feature)
geometryCorrection, // final GeometryCorrection geometryCorrection,
clt_kernels, // final double [][][][][][] clt_kernels, // [channel_in_quad][color][tileY][tileX][band][pixel] , size should match image (have 1 tile around)
clt_parameters.kernel_step,
clt_parameters.transform_size,
clt_parameters.clt_window,
shiftXY, //
clt_parameters.shift_x, // final int shiftX, // shift image horizontally (positive - right) - just for testing
clt_parameters.shift_y, // final int shiftY, // shift image vertically (positive - down)
clt_parameters.tileX, // final int debug_tileX,
clt_parameters.tileY, // final int debug_tileY,
(clt_parameters.dbg_mode & 64) != 0, // no fract shift
(clt_parameters.dbg_mode & 128) != 0, // no convolve
// (clt_parameters.dbg_mode & 256) != 0, // transpose convolve
threadsMax,
debugLevel);
}
// String [] disparity_titles = {"int_disparity", "int_disp_ortho","cm_disparity", "cm_disp_ortho","poly_disparity", "poly_disp_ortho",
// "strength", "variety"};
String [] disparity_titles = {"int_disparity","cm_disparity", "poly_disparity", "strength", "variety"};
int [] disp_indices = {0,2,4,6,7};
String [] disparities_titles = new String [disparity_titles.length * clt_parameters.disp_scan_count];
double [][] disparities_maps = new double [disparity_titles.length * clt_parameters.disp_scan_count][];
int indx = 0;
for (int scan_step = 0; scan_step < clt_parameters.disp_scan_count; scan_step++) {
double disparity = clt_parameters.disp_scan_start + scan_step * clt_parameters.disp_scan_step;
for (int i = 0; i < disparity_titles.length; i++){
disparities_titles[indx] = disparity_titles[i]+"_"+disparity;
disparities_maps[indx++] = disparity_maps[scan_step][disp_indices[i]];
}
}
ImageStack array_stack = sdfa_instance.makeStack(
disparities_maps,
tilesX,
tilesY,
disparities_titles);
ImagePlus imp_stack = new ImagePlus( name+"-DISP_MAPS", array_stack);
imp_stack.getProcessor().resetMinAndMax();
imp_stack.updateAndDraw();
//imp_stack.getProcessor().resetMinAndMax();
//imp_stack.show();
eyesisCorrections.saveAndShow(imp_stack, this.correctionsParameters);
// process scan results
double [][] scan_trends = process_disparity_scan(
disparities_maps,
clt_parameters.disp_scan_step,
clt_parameters.disp_scan_start,
0.0); // min_corr_selected); // all what is remaining
String [] trend_titles={"b_cm","b_poly","a_cm","a_poly","rms_cm","rms_poly","strength","samples"};
ImageStack trends_stack = sdfa_instance.makeStack(
scan_trends,
tilesX,
tilesY,
trend_titles);
ImagePlus imp_stack_trends = new ImagePlus( name+"-DISP_TRENDS", trends_stack);
imp_stack_trends.getProcessor().resetMinAndMax();
imp_stack_trends.updateAndDraw();
eyesisCorrections.saveAndShow(imp_stack_trends, this.correctionsParameters);
return results;
}
public double [][] process_disparity_scan(
double [][] disparities_maps,
double disp_step,
double disp_start,
double min_strength)
{
final int num_items = 5;
final int index_strength = 3;
final int index_cm = 1;
final int index_poly = 1;
final int ind_b_cm = 0;
final int ind_b_poly = 1;
final int ind_a_cm = 2;
final int ind_a_poly = 3;
final int ind_rms_cm = 4;
final int ind_rms_poly = 5;
final int ind_strength = 6;
final int ind_samples = 7;
final int num_steps = disparities_maps.length / num_items; // int, cm, poly, strength, variety
final int disp_len = disparities_maps[0].length;
double [][] rslt = new double [8][disp_len];
for (int i = 0; i < disp_len; i++){
double s0 = 0.0, sx = 0.0, sx2 = 0.0, sy_cm = 0.0, sxy_cm = 0.0, sy_poly = 0.0, sxy_poly = 0.0;
int samples = 0;
for (int step = 0; step < num_steps; step++ ){
double wi = disparities_maps[num_items*step + index_strength][i];
if (wi > min_strength) {
double xi = disp_start + step * disp_step;
double yi_cm = disparities_maps[num_items*step + index_cm][i];
double yi_poly = disparities_maps[num_items*step + index_poly][i];
if (Double.isNaN(yi_cm) || Double.isNaN(yi_poly)) continue;
s0 += wi;
sx += wi*xi;
sx2 += wi*xi*xi;
sy_cm += wi*yi_cm;
sxy_cm += wi*xi*yi_cm;
sy_poly += wi*yi_poly;
sxy_poly += wi*xi*yi_poly;
samples++;
}
}
double denom = (s0*sx2 - sx*sx);
rslt[ind_strength][i] = s0;
rslt[ind_samples][i] = samples;
if (denom != 0.0) {
rslt[ind_a_cm][i] = (s0*sxy_cm - sx*sy_cm) / denom;
rslt[ind_b_cm][i] = (sy_cm*sx2 - sx*sxy_cm) / denom;
rslt[ind_a_poly][i] = (s0*sxy_poly - sx*sy_poly) / denom;
rslt[ind_b_poly][i] = (sy_poly*sx2 - sx*sxy_poly) / denom;
rslt[ind_rms_cm][i] = 0.0;
rslt[ind_rms_poly][i] = 0.0;
for (int step = 0; step < num_steps; step++ ){
double wi = disparities_maps[num_items*step + index_strength][i];
if (wi > min_strength) {
double xi = disp_start + step * disp_step;
double yi_cm = disparities_maps[num_items*step + index_cm][i];
double yi_poly = disparities_maps[num_items*step + index_poly][i];
if (Double.isNaN(yi_cm) || Double.isNaN(yi_poly)) continue;
double d_cm = yi_cm - (rslt[ind_a_cm][i]*xi +rslt[ind_b_cm][i]);
double d_poly = yi_poly - (rslt[ind_a_poly][i]*xi +rslt[ind_b_poly][i]);
rslt[ind_rms_cm][i] += wi*d_cm*d_cm;
rslt[ind_rms_poly][i] += wi*d_poly*d_poly;
}
}
rslt[ind_rms_cm][i] = Math.sqrt(rslt[ind_rms_cm][i]/s0);
rslt[ind_rms_poly][i] = Math.sqrt(rslt[ind_rms_cm][i]/s0);
} else {
rslt[ind_a_cm][i] = Double.NaN;
rslt[ind_b_cm][i] = Double.NaN;
rslt[ind_a_poly][i] = Double.NaN;
rslt[ind_b_poly][i] = Double.NaN;
rslt[ind_rms_cm][i] = Double.NaN;
rslt[ind_rms_poly][i] = Double.NaN;
}
}
return rslt;
}
}
......@@ -497,6 +497,8 @@ private Panel panel1,
addButton("CLT process sets", panelClt1, color_process);
addButton("CLT process quads", panelClt1, color_process);
addButton("CLT process corr", panelClt1, color_process);
addButton("CLT disparity scan", panelClt1, color_conf_process);
add(panelClt1);
}
pack();
......@@ -4512,9 +4514,108 @@ private Panel panel1,
}
return;
} else if (label.equals("CLT disparity scan")) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
EYESIS_CORRECTIONS.setDebug(DEBUG_LEVEL);
if (EYESIS_DCT == null){
EYESIS_DCT = new EyesisDCT (
EYESIS_CORRECTIONS,
CORRECTION_PARAMETERS,
DCT_PARAMETERS);
if (DEBUG_LEVEL > 0){
System.out.println("Created new EyesisDCT instance, will need to read CLT kernels");
}
}
String configPath=null;
if (EYESIS_CORRECTIONS.correctionsParameters.saveSettings) {
configPath=EYESIS_CORRECTIONS.correctionsParameters.selectResultsDirectory(
true,
true);
if (configPath==null){
String msg="No results directory selected, command aborted";
System.out.println("Warning: "+msg);
IJ.showMessage("Warning",msg);
return;
}
configPath+=Prefs.getFileSeparator()+"autoconfig";
try {
saveTimestampedProperties(
configPath, // full path or null
null, // use as default directory if path==null
true,
PROPERTIES);
} catch (Exception e){
String msg="Failed to save configuration to "+configPath+", command aborted";
System.out.println("Error: "+msg);
IJ.showMessage("Error",msg);
return;
}
}
EYESIS_CORRECTIONS.initSensorFiles(DEBUG_LEVEL);
int numChannels=EYESIS_CORRECTIONS.getNumChannels();
NONLIN_PARAMETERS.modifyNumChannels(numChannels);
CHANNEL_GAINS_PARAMETERS.modifyNumChannels(numChannels);
if (!EYESIS_DCT.CLTKernelsAvailable()){
if (DEBUG_LEVEL > 0){
System.out.println("Reading CLT kernels");
}
EYESIS_DCT.readCLTKernels(
CLT_PARAMETERS,
THREADS_MAX,
UPDATE_STATUS, // update status info
DEBUG_LEVEL);
if (DEBUG_LEVEL > 1){
EYESIS_DCT.showCLTKernels(
THREADS_MAX,
UPDATE_STATUS, // update status info
DEBUG_LEVEL);
}
}
if (!EYESIS_DCT.geometryCorrectionAvailable()){
if (DEBUG_LEVEL > 0){
System.out.println("Calculating geometryCorrection");
}
if (!EYESIS_DCT.initGeometryCorrection(DEBUG_LEVEL+2)){
return;
}
}
///========================================
EYESIS_DCT.cltDisparityScans(
CLT_PARAMETERS, // EyesisCorrectionParameters.DCTParameters dct_parameters,
DEBAYER_PARAMETERS, //EyesisCorrectionParameters.DebayerParameters debayerParameters,
NONLIN_PARAMETERS, //EyesisCorrectionParameters.NonlinParameters nonlinParameters,
COLOR_PROC_PARAMETERS, //EyesisCorrectionParameters.ColorProcParameters colorProcParameters,
CHANNEL_GAINS_PARAMETERS, //CorrectionColorProc.ColorGainsParameters channelGainParameters,
RGB_PARAMETERS, //EyesisCorrectionParameters.RGBParameters rgbParameters,
EQUIRECTANGULAR_PARAMETERS, // EyesisCorrectionParameters.EquirectangularParameters equirectangularParameters,
CONVOLVE_FFT_SIZE, //int convolveFFTSize, // 128 - fft size, kernel size should be size/2
THREADS_MAX, //final int threadsMax, // maximal number of threads to launch
UPDATE_STATUS, //final boolean updateStatus,
DEBUG_LEVEL); //final int debugLevel);
if (configPath!=null) {
saveTimestampedProperties( // save config again
configPath, // full path or null
null, // use as default directory if path==null
true,
PROPERTIES);
}
return;
//
// End of buttons code
}
......
......@@ -311,7 +311,7 @@ public class GeometryCorrection {
}
/*
* Calculate pixel coordinates for each of numSensors images, for a given (px,py) of the idelaized "center" (still distorted) image
* Calculate pixel coordinates for each of numSensors images, for a given (px,py) of the idealized "center" (still distorted) image
* and generic diparity, measured in pixels
*/
......
......@@ -929,9 +929,11 @@ public class ImageDtt {
final double [][][][][] clt_corr_partial,// [tilesY][tilesX][quad]color][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate
// [tilesY][tilesX] should be set by caller
final double [][] clt_mismatch, // [12][tilesY * tilesX] // transpose unapplied. null - do not calculate
final double [][] disparity_map, // [8][tilesY][tilesX], only [6][] is needed on input or null - do nat calculate
// last 2 - contrast, avg/ "geometric average)
final double [][][][] texture_tiles, // [tilesY][tilesX]["RGBA".length()][];
final double [][][][] texture_tiles, // [tilesY][tilesX]["RGBA".length()][]; null - will skip images combining
final int width,
final double corr_fat_zero, // add to denominator to modify phase correlation (same units as data1, data2). <0 - pure sum
......@@ -958,6 +960,7 @@ public class ImageDtt {
final int kernel_step,
final int transform_size,
final int window_type,
final double [][] shiftXY, // [port]{shiftX,shiftY}
final double shiftX, // shift image horizontally (positive - right) - just for testing
final double shiftY, // shift image vertically (positive - down)
final int debug_tileX,
......@@ -994,8 +997,8 @@ public class ImageDtt {
}
}
if (globalDebugLevel > -1) {
System.out.println("clt_aberrations(): width="+width+" height="+height+" transform_size="+transform_size+
if (globalDebugLevel > 0) {
System.out.println("clt_aberrations_quad_corr(): width="+width+" height="+height+" transform_size="+transform_size+
" debug_tileX="+debug_tileX+" debug_tileY="+debug_tileY+" globalDebugLevel="+globalDebugLevel);
}
final int [][] zi =
......@@ -1051,11 +1054,13 @@ public class ImageDtt {
// prepare disparity maps and weights
final int max_search_radius = (int) Math.abs(max_corr_radius); // use negative max_corr_radius for squares instead of circles?
final int max_search_radius_poly = 1;
if (globalDebugLevel > -1){
System.out.println("max_corr_radius= "+max_corr_radius);
System.out.println("max_search_radius="+max_search_radius);
if (globalDebugLevel > 0){
System.out.println("max_corr_radius= "+max_corr_radius);
System.out.println("max_search_radius= "+max_search_radius);
System.out.println("max_search_radius_poly="+max_search_radius_poly);
System.out.println("corr_fat_zero= "+corr_fat_zero);
System.out.println("corr_fat_zero= "+corr_fat_zero);
System.out.println("disparity= "+ disparity);
}
if (disparity_map != null){
......@@ -1063,6 +1068,11 @@ public class ImageDtt {
disparity_map[i] = new double [tilesY*tilesX];
}
}
if (clt_mismatch != null){
for (int i = 0; i<clt_mismatch.length;i++){
clt_mismatch[i] = new double [tilesY*tilesX]; // will use only "center of mass" centers
}
}
// final double [] corr_max_weights =(((max_corr_sigma > 0) && (disparity_map != null))?
// setMaxXYWeights(max_corr_sigma,max_search_radius): null); // here use square anyway
final double [] corr_max_weights_poly =(((max_corr_sigma > 0) && (disparity_map != null))?
......@@ -1117,15 +1127,37 @@ public class ImageDtt {
centerX,
centerY,
disparity);
if ((globalDebugLevel > 0) && (tileX >= debug_tileX - 2) && (tileX <= debug_tileX + 2) &&
(tileY >= debug_tileY - 2) && (tileY <= debug_tileY+2)) {
// if ((globalDebugLevel > 0) && (tileX >= debug_tileX - 2) && (tileX <= debug_tileX + 2) &&
// (tileY >= debug_tileY - 2) && (tileY <= debug_tileY+2)) {
if ((globalDebugLevel > 0) && (tileX == debug_tileX) && (tileY == debug_tileY)) {
for (int i = 0; i < quad; i++) {
System.out.println("clt_aberrations_quad(): color="+chn+", tileX="+tileX+", tileY="+tileY+
System.out.println("clt_aberrations_quad_corr(): color="+chn+", tileX="+tileX+", tileY="+tileY+
" centerX="+centerX+" centerY="+centerY+" disparity="+disparity+
" centersXY["+i+"][0]="+centersXY[i][0]+" centersXY["+i+"][1]="+centersXY[i][1]);
}
}
if ((globalDebugLevel > -1) && (tileX == debug_tileX) && (tileY == debug_tileY) && (chn == 2)) { // before correction
System.out.print(disparity+"\t"+
centersXY[0][0]+"\t"+centersXY[0][1]+"\t"+
centersXY[1][0]+"\t"+centersXY[1][1]+"\t"+
centersXY[2][0]+"\t"+centersXY[2][1]+"\t"+
centersXY[3][0]+"\t"+centersXY[3][1]+"\t");
}
for (int ip = 0; ip < centersXY.length; ip++){
centersXY[ip][0] -= shiftXY[ip][0];
centersXY[ip][1] -= shiftXY[ip][1];
}
if ((globalDebugLevel > -1) && (tileX == debug_tileX) && (tileY == debug_tileY) && (chn == 2)) {
System.out.print(disparity+"\t"+
centersXY[0][0]+"\t"+centersXY[0][1]+"\t"+
centersXY[1][0]+"\t"+centersXY[1][1]+"\t"+
centersXY[2][0]+"\t"+centersXY[2][1]+"\t"+
centersXY[3][0]+"\t"+centersXY[3][1]+"\t");
}
for (int i = 0; i < quad; i++) {
clt_data[i][chn][tileY][tileX] = new double [4][];
fract_shiftsXY[i] = extract_correct_tile( // return a pair of resudual offsets
......@@ -1139,10 +1171,14 @@ public class ImageDtt {
chn,
centersXY[i][0], // centerX, // center of aberration-corrected (common model) tile, X
centersXY[i][1], // centerY, //
(globalDebugLevel > 0) && (tileX == debug_tileX) && (tileY == debug_tileY) && (chn == 2), // external tile compare
((globalDebugLevel > -1) && (tileX == debug_tileX) && (tileY == debug_tileY) && (chn == 2)),
// (globalDebugLevel > 0) && (tileX == debug_tileX) && (tileY == debug_tileY) && (chn == 2), // external tile compare
no_deconvolution,
false); // transpose);
}
if ((globalDebugLevel > -1) && (tileX == debug_tileX) && (tileY == debug_tileY) && (chn == 2)) {
System.out.println();
}
if ((globalDebugLevel > 0) && (debug_tileX == tileX) && (debug_tileY == tileY) && (chn == 2)) {
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
String [] titles = {"CC0","SC0","CS0","SS0","CC1","SC1","CS1","SS1","CC2","SC2","CS2","SS2","CC3","SC3","CS3","SS3"};
......@@ -1260,7 +1296,7 @@ public class ImageDtt {
}
}
// make symmetrical around the disparity direction (horizontal) (here using just average, not mul/sum mixture)
if (corr_sym){
if (corr_sym && (clt_mismatch == null)){ // when measuring clt_mismatch symmetry should be off !
for (int chn = firstColor; chn <= numcol; chn++){
for (int i = 1 ; i < transform_size; i++){
int indx1 = (transform_size - 1 - i) * corr_size;
......@@ -1284,7 +1320,7 @@ public class ImageDtt {
}
double avScale = 0.0;
if (numPairs > 0) {
boolean debugMax = (globalDebugLevel > -1) && (tileX == debug_tileX) && (tileY == debug_tileY);
boolean debugMax = (globalDebugLevel > 0) && (tileX == debug_tileX) && (tileY == debug_tileY);
avScale = 1.0/numPairs;
if (debugMax) {
System.out.println("avScale="+avScale+", corr_offset="+corr_offset);
......@@ -1352,15 +1388,13 @@ public class ImageDtt {
if (clt_corr_partial != null){
clt_corr_partial[tileY][tileX] = tcorr_partial;
}
// calculate disparity map
if (disparity_map != null) {
int [] icorr_max =getMaxXYInt( // find integer pair or null if below threshold
tcorr_combo[0], // [data_size * data_size]
corr_size,
min_corr, // minimal value to consider (at integer location, not interpolated)
debugMax);
int max_index = -1;
if (icorr_max == null){
disparity_map[0][tileY*tilesX + tileX] = Double.NaN;
disparity_map[1][tileY*tilesX + tileX] = Double.NaN;
......@@ -1368,12 +1402,19 @@ public class ImageDtt {
disparity_map[3][tileY*tilesX + tileX] = Double.NaN;
disparity_map[4][tileY*tilesX + tileX] = Double.NaN;
disparity_map[5][tileY*tilesX + tileX] = Double.NaN;
if (clt_mismatch != null){
for (int pair = 0; pair < corr_pairs.length; pair++) if (((corr_mask >> pair) & 1) != 0){
clt_mismatch[3*pair + 0 ][tileY*tilesX + tileX] = Double.NaN;
clt_mismatch[3*pair + 1 ][tileY*tilesX + tileX] = Double.NaN;
clt_mismatch[3*pair + 2 ][tileY*tilesX + tileX] = Double.NaN;
}
}
} else {
double [] corr_max_XYi = {icorr_max[0],icorr_max[1]};
disparity_map[0][tileY*tilesX + tileX] = transform_size - 1 -corr_max_XYi[0];
disparity_map[1][tileY*tilesX + tileX] = transform_size - 1 -corr_max_XYi[1];
// for the integer maximum provide contrast and variety
int max_index = icorr_max[1]*corr_size + icorr_max[0];
max_index = icorr_max[1]*corr_size + icorr_max[0];
disparity_map[6][tileY*tilesX + tileX] = tcorr_combo[0][max_index]; // correlation combo value at the integer maximum
// undo scaling caused by optional normalization
disparity_map[7][tileY*tilesX + tileX] = (rms[1]*tcorr_combo[1][max_index])/(rms[0]*tcorr_combo[0][max_index]); // correlation combo value at the integer maximum
......@@ -1414,127 +1455,167 @@ public class ImageDtt {
else if (corr_mode == 1) extra_disparity = disparity_map[2][tileY*tilesX + tileX];
else if (corr_mode == 2) extra_disparity = disparity_map[4][tileY*tilesX + tileX];
if (Double.isNaN(extra_disparity)) extra_disparity = 0;
if (clt_mismatch != null){
for (int pair = 0; pair < corr_pairs.length; pair++) if (((corr_mask >> pair) & 1) != 0){
icorr_max =getMaxXYInt( // find integer pair or null if below threshold
tcorr_partial[pair][numcol], // [data_size * data_size]
corr_size,
min_corr, // minimal value to consider (at integer location, not interpolated)
debugMax);
if (icorr_max == null){
clt_mismatch[3*pair + 0 ][tileY*tilesX + tileX] = Double.NaN;
clt_mismatch[3*pair + 1 ][tileY*tilesX + tileX] = Double.NaN;
clt_mismatch[3*pair + 2 ][tileY*tilesX + tileX] = Double.NaN;
} else {
double [] corr_max_XYmp = getMaxXYCm( // get fractiona center as a "center of mass" inside circle/square from the integer max
tcorr_partial[pair][numcol], // [data_size * data_size]
corr_size,
icorr_max, // integer center coordinates (relative to top left)
max_corr_radius, // positive - within that distance, negative - within 2*(-radius)+1 square
debugMax); // should never return null
// Only use Y components for pairs 0,1 and X components - for pairs 2,3
double yp,xp;
if (corr_pairs[pair][2] > 0){ // transpose - switch x <-> y
yp = transform_size - 1 -corr_max_XYmp[0] - disparity_map[2][tileY*tilesX + tileX];
xp = transform_size - 1 -corr_max_XYmp[1]; // do not campare to average - it should be 0 anyway
} else {
xp = transform_size - 1 -corr_max_XYmp[0] - disparity_map[2][tileY*tilesX + tileX];
yp = transform_size - 1 -corr_max_XYmp[1]; // do not campare to average - it should be 0 anyway
}
double strength = tcorr_partial[pair][numcol][max_index]; // using the new location than for combined
clt_mismatch[3*pair + 0 ][tileY*tilesX + tileX] = xp;
clt_mismatch[3*pair + 1 ][tileY*tilesX + tileX] = yp;
clt_mismatch[3*pair + 2 ][tileY*tilesX + tileX] = strength;
}
}
}
}
}
}
} // end of if (clt_corr_combo != null)
if ((extra_disparity != 0) && (((1 << force_disparity_bit) & tile_op[tileY][tileX]) == 0)){ // 0 - adjust disparity, 1 - uase provided
// shift images by 0.5 * extra disparity in the diagonal direction
for (int chn = 0; chn <numcol; chn++) { // color
for (int i = 0; i < quad; i++) {
fract_shift( // fractional shift in transform domain. Currently uses sin/cos - change to tables with 2? rotations
clt_data[i][chn][tileY][tileX], // double [][] clt_tile,
transform_size,
extra_disparity * port_offsets[i][0], // double shiftX,
extra_disparity * port_offsets[i][1], // double shiftY,
// (globalDebugLevel > 0) && (tileX == debug_tileX) && (tileY == debug_tileY)); // external tile compare
((globalDebugLevel > 0) && (chn==0) && (tileX >= debug_tileX - 2) && (tileX <= debug_tileX + 2) &&
(tileY >= debug_tileY - 2) && (tileY <= debug_tileY+2)));
}
}
}
// lpf tiles (same as images before)
// iclt tiles
double [][][] iclt_tile = new double [quad][numcol][];
double [] clt_tile;
double scale = 0.25; // matching iclt_2d
for (int i = 0; i < quad; i++) {
for (int chn = 0; chn <numcol; chn++) { // color
// double [] clt_tile = new double [transform_size*transform_size];
for (int dct_mode = 0; dct_mode < 4; dct_mode++){
clt_tile = clt_data[i][chn][tileY][tileX][dct_mode].clone();
// lpf each of the 4 quadrants before idct
for (int j = 0; j < filter.length; j++){
clt_tile[j] *= scale*filter[j];
}
// IDCT-IV should be in reversed order: CC->CC, SC->CS, CS->SC, SS->SS
int idct_mode = ((dct_mode << 1) & 2) | ((dct_mode >> 1) & 1);
clt_tile = dtt.dttt_iv (clt_tile, idct_mode, transform_size);
// iclt_tile[i][chn] = dtt.dttt_iv (clt_data[i][chn][tileY][tileX][dct_mode], idct_mode, transform_size);
double [] tile_mdct = dtt.unfold_tile(clt_tile, transform_size, dct_mode); // mode=0 - DCCT 16x16
// accumulate partial mdct results
if (dct_mode == 0){
iclt_tile[i][chn] = tile_mdct;
} else{
for (int j = 0; j<tile_mdct.length; j++){
iclt_tile[i][chn][j] += tile_mdct[j]; // matching iclt_2d
}
if (texture_tiles !=null) {
if ((extra_disparity != 0) && (((1 << force_disparity_bit) & tile_op[tileY][tileX]) == 0)){ // 0 - adjust disparity, 1 - uase provided
// shift images by 0.5 * extra disparity in the diagonal direction
for (int chn = 0; chn <numcol; chn++) { // color
for (int i = 0; i < quad; i++) {
fract_shift( // fractional shift in transform domain. Currently uses sin/cos - change to tables with 2? rotations
clt_data[i][chn][tileY][tileX], // double [][] clt_tile,
transform_size,
extra_disparity * port_offsets[i][0], // double shiftX,
extra_disparity * port_offsets[i][1], // double shiftY,
// (globalDebugLevel > 0) && (tileX == debug_tileX) && (tileY == debug_tileY)); // external tile compare
((globalDebugLevel > 0) && (chn==0) && (tileX >= debug_tileX - 2) && (tileX <= debug_tileX + 2) &&
(tileY >= debug_tileY - 2) && (tileY <= debug_tileY+2)));
}
}
}
}
if ((globalDebugLevel > 0) && debugTile) {
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
String [] titles = {"red0","blue0","green0","red1","blue1","green1","red2","blue2","green2","red3","blue3","green3"};
double [][] dbg_tile = new double [quad*numcol][];
// lpf tiles (same as images before)
// iclt tiles
double [][][] iclt_tile = new double [quad][numcol][];
double [] clt_tile;
double scale = 0.25; // matching iclt_2d
for (int i = 0; i < quad; i++) {
for (int chn = 0; chn <numcol; chn++) { // color
dbg_tile[i * numcol + chn] = iclt_tile[i][chn];
// double [] clt_tile = new double [transform_size*transform_size];
for (int dct_mode = 0; dct_mode < 4; dct_mode++){
clt_tile = clt_data[i][chn][tileY][tileX][dct_mode].clone();
// lpf each of the 4 quadrants before idct
for (int j = 0; j < filter.length; j++){
clt_tile[j] *= scale*filter[j];
}
// IDCT-IV should be in reversed order: CC->CC, SC->CS, CS->SC, SS->SS
int idct_mode = ((dct_mode << 1) & 2) | ((dct_mode >> 1) & 1);
clt_tile = dtt.dttt_iv (clt_tile, idct_mode, transform_size);
// iclt_tile[i][chn] = dtt.dttt_iv (clt_data[i][chn][tileY][tileX][dct_mode], idct_mode, transform_size);
double [] tile_mdct = dtt.unfold_tile(clt_tile, transform_size, dct_mode); // mode=0 - DCCT 16x16
// accumulate partial mdct results
if (dct_mode == 0){
iclt_tile[i][chn] = tile_mdct;
} else{
for (int j = 0; j<tile_mdct.length; j++){
iclt_tile[i][chn][j] += tile_mdct[j]; // matching iclt_2d
}
}
}
}
}
sdfa_instance.showArrays(dbg_tile, 2* transform_size, 2* transform_size, true, "iclt_x"+tileX+"_y"+tileY, titles);
}
// "de-bayer" tiles for matching, use original data for output
double [][][] tiles_debayered = new double [quad][numcol][];
for (int i =0; i<quad; i++){
for (int chn = 0; chn < numcol; chn++){
// tiles_debayered[i][chn] = tile_debayer(
// (chn != 2), // red or blue (flase - green)
// iclt_tile[i][chn],
// 2 * transform_size);
tiles_debayered[i][chn] = tile_debayer_shot_corr(
(chn != 2), // red or blue (flase - green)
iclt_tile[i][chn],
2 * transform_size,
lt_window2, // squared lapping window
min_shot, // 10.0; // Do not adjust for shot noise if lower than
scale_shot, //3.0; // scale when dividing by sqrt
lt_window2); // re-apply window to the result
if ((globalDebugLevel > 0) && debugTile) {
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
String [] titles = {"red0","blue0","green0","red1","blue1","green1","red2","blue2","green2","red3","blue3","green3"};
double [][] dbg_tile = new double [quad*numcol][];
for (int i = 0; i < quad; i++) {
for (int chn = 0; chn <numcol; chn++) { // color
dbg_tile[i * numcol + chn] = iclt_tile[i][chn];
}
}
sdfa_instance.showArrays(dbg_tile, 2* transform_size, 2* transform_size, true, "iclt_x"+tileX+"_y"+tileY, titles);
}
}
if ((globalDebugLevel > 0) && debugTile) {
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
String [] titles = {"red0","blue0","green0","red1","blue1","green1","red2","blue2","green2","red3","blue3","green3"};
double [][] dbg_tile = new double [quad*numcol][];
for (int i = 0; i < quad; i++) {
for (int chn = 0; chn <numcol; chn++) { // color
dbg_tile[i * numcol + chn] = tiles_debayered[i][chn];
// "de-bayer" tiles for matching, use original data for output
double [][][] tiles_debayered = new double [quad][numcol][];
for (int i =0; i<quad; i++){
for (int chn = 0; chn < numcol; chn++){
// tiles_debayered[i][chn] = tile_debayer(
// (chn != 2), // red or blue (flase - green)
// iclt_tile[i][chn],
// 2 * transform_size);
tiles_debayered[i][chn] = tile_debayer_shot_corr(
(chn != 2), // red or blue (flase - green)
iclt_tile[i][chn],
2 * transform_size,
lt_window2, // squared lapping window
min_shot, // 10.0; // Do not adjust for shot noise if lower than
scale_shot, //3.0; // scale when dividing by sqrt
lt_window2); // re-apply window to the result
}
}
sdfa_instance.showArrays(dbg_tile, 2* transform_size, 2* transform_size, true, "tiles_debayered_x"+tileX+"_y"+tileY, titles);
}
texture_tiles[tileY][tileX] = tile_combine_rgba(
tiles_debayered, // iclt_tile, // [port][numcol][256]
lt_window2, // [256]
port_offsets, // [port]{x_off, y_off}
img_mask, // which port to use, 0xf - all 4 (will modify as local variable)
diff_sigma, // pixel value/pixel change
diff_threshold, // pixel value/pixel change
diff_gauss, // when averaging images, use gaussian around average as weight (false - sharp all/nothing)
min_agree, // minimal number of channels to agree on a point (real number to work with fuzzy averages)
col_weights, // color channel weights, sum == 1.0
keep_weights, // keep_weights); // return channel weights after A in RGBA
(globalDebugLevel > 0) && debugTile);
// mix RGB from iclt_tile, mix alpha with - what? correlation strength or 'don't care'? good correlation or all > min?
for (int i = 0; i < iclt_tile[0][0].length; i++ ) {
double sw = 0.0;
for (int ip = 0; ip < quad; ip++) {
sw += texture_tiles[tileY][tileX][numcol+1+ip][i];
if ((globalDebugLevel > 0) && debugTile) {
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
String [] titles = {"red0","blue0","green0","red1","blue1","green1","red2","blue2","green2","red3","blue3","green3"};
double [][] dbg_tile = new double [quad*numcol][];
for (int i = 0; i < quad; i++) {
for (int chn = 0; chn <numcol; chn++) { // color
dbg_tile[i * numcol + chn] = tiles_debayered[i][chn];
}
}
sdfa_instance.showArrays(dbg_tile, 2* transform_size, 2* transform_size, true, "tiles_debayered_x"+tileX+"_y"+tileY, titles);
}
if (sw != 0 ) sw = 1.0/sw;
for (int chn = 0; chn <numcol; chn++) { // color
texture_tiles[tileY][tileX][chn][i] = 0.0; //iclt[tileY][tileX][chn]
texture_tiles[tileY][tileX] = tile_combine_rgba(
tiles_debayered, // iclt_tile, // [port][numcol][256]
lt_window2, // [256]
port_offsets, // [port]{x_off, y_off}
img_mask, // which port to use, 0xf - all 4 (will modify as local variable)
diff_sigma, // pixel value/pixel change
diff_threshold, // pixel value/pixel change
diff_gauss, // when averaging images, use gaussian around average as weight (false - sharp all/nothing)
min_agree, // minimal number of channels to agree on a point (real number to work with fuzzy averages)
col_weights, // color channel weights, sum == 1.0
keep_weights, // keep_weights); // return channel weights after A in RGBA
(globalDebugLevel > 0) && debugTile);
// mix RGB from iclt_tile, mix alpha with - what? correlation strength or 'don't care'? good correlation or all > min?
for (int i = 0; i < iclt_tile[0][0].length; i++ ) {
double sw = 0.0;
for (int ip = 0; ip < quad; ip++) {
texture_tiles[tileY][tileX][chn][i] += sw * texture_tiles[tileY][tileX][numcol+1+ip][i] * iclt_tile[ip][chn][i];
sw += texture_tiles[tileY][tileX][numcol+1+ip][i];
}
if (sw != 0 ) sw = 1.0/sw;
for (int chn = 0; chn <numcol; chn++) { // color
texture_tiles[tileY][tileX][chn][i] = 0.0; //iclt[tileY][tileX][chn]
for (int ip = 0; ip < quad; ip++) {
texture_tiles[tileY][tileX][chn][i] += sw * texture_tiles[tileY][tileX][numcol+1+ip][i] * iclt_tile[ip][chn][i];
}
}
}
}
......@@ -3183,10 +3264,11 @@ public class ImageDtt {
int chn,
double centerX, // center of aberration-corrected (common model) tile, X
double centerY, //
boolean bdebug, // external tile compare
boolean bdebug0, // external tile compare
boolean dbg_no_deconvolution,
boolean dbg_transpose)
{
boolean bdebug = false;
double [] residual_shift = new double[2];
int height = image_data[0].length/width;
int transform_size2 = 2* transform_size;
......@@ -3208,6 +3290,11 @@ public class ImageDtt {
// same with extra shift
double px = centerX - transform_size - (ce.data_x + ce.dxc_dx * kdx + ce.dxc_dy * kdy) ; // fractional left corner
double py = centerY - transform_size - (ce.data_y + ce.dyc_dx * kdx + ce.dyc_dy * kdy) ; // fractional top corner
if (bdebug0){
System.out.print(px+"\t"+py+"\t");
}
int ctile_left = (int) Math.round(px);
int ctile_top = (int) Math.round(py);
residual_shift[0] = -(px - ctile_left);
......
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