Commit 9d378818 authored by Andrey Filippov's avatar Andrey Filippov

added separate hor/vert correlation results to detect vertical/horizontal features

parent e0cc40c3
......@@ -111,6 +111,7 @@ public class EyesisCorrectionParameters {
public String cltKernelPrefix="clt-";
public String cltSuffix=".clt-tiff";
public String x3dDirectory="";
public void setProperties(String prefix,Properties properties){
properties.setProperty(prefix+"split",this.split+"");
......@@ -198,6 +199,8 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"cltKernelPrefix", this.cltKernelPrefix);
properties.setProperty(prefix+"cltSuffix", this.cltSuffix);
properties.setProperty(prefix+"x3dDirectory", this.x3dDirectory);
}
public void getProperties(String prefix,Properties properties){
......@@ -289,6 +292,7 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"cltKernelPrefix")!= null) this.cltKernelPrefix=properties.getProperty(prefix+"cltKernelPrefix");
if (properties.getProperty(prefix+"cltSuffix")!= null) this.cltSuffix=properties.getProperty(prefix+"cltSuffix");
if (properties.getProperty(prefix+"x3dDirectory")!= null) this.x3dDirectory=properties.getProperty(prefix+"x3dDirectory");
}
......@@ -359,6 +363,9 @@ public class EyesisCorrectionParameters {
gd.addStringField ("Aberration kernels for CLT directory", this.cltKernelDirectory, 60);
gd.addCheckbox ("Select aberration kernels for CLT directory", false);
gd.addStringField ("x3d output directory", this.x3dDirectory, 60);
gd.addCheckbox ("Select x3d output directory", false);
gd.addStringField("Equirectangular maps directory (may be empty)", this.equirectangularDirectory, 60);
gd.addCheckbox("Select equirectangular maps directory", false);
gd.addStringField("Results directory", this.resultsDirectory, 40);
......@@ -442,6 +449,7 @@ public class EyesisCorrectionParameters {
this.smoothKernelDirectory= gd.getNextString(); if (gd.getNextBoolean()) selectSmoothKernelDirectory(false, true);
this.dctKernelDirectory= gd.getNextString(); if (gd.getNextBoolean()) selectDCTKernelDirectory(false, true);
this.cltKernelDirectory= gd.getNextString(); if (gd.getNextBoolean()) selectCLTKernelDirectory(false, true);
this.x3dDirectory= gd.getNextString(); if (gd.getNextBoolean()) selectX3dDirectory(false, true);
this.equirectangularDirectory= gd.getNextString(); if (gd.getNextBoolean()) selectEquirectangularDirectory(false, false);
this.resultsDirectory= gd.getNextString(); if (gd.getNextBoolean()) selectResultsDirectory(false, true);
this.sourcePrefix= gd.getNextString();
......@@ -994,6 +1002,18 @@ public class EyesisCorrectionParameters {
return dir;
}
public String selectX3dDirectory(boolean smart, boolean newAllowed) {
String dir= CalibrationFileManagement.selectDirectory(
smart,
newAllowed, // save
"x3d output directory", // title
"Select x3d output directory", // button
null, // filter
this.x3dDirectory); //this.sourceDirectory);
if (dir!=null) this.x3dDirectory=dir;
return dir;
}
public String selectEquirectangularDirectory(boolean smart, boolean newAllowed) {
String dir= CalibrationFileManagement.selectDirectory(
smart,
......@@ -1931,7 +1951,12 @@ public class EyesisCorrectionParameters {
public double min_corr_normalized = 2.0; // minimal correlation value to consider valid when normalizing correlation results
public double max_corr_sigma = 1.5; // weights of points around global max to find fractional
// pixel location by quadratic approximation
public double max_corr_radius = 2.5; // maximal distance from int max to consider
public double max_corr_radius = 3.5; // maximal distance from int max to consider
public int enhortho_width = 2; // reduce weight of center correlation pixels from center (0 - none, 1 - center, 2 +/-1 from center)
public double enhortho_scale = 0.2; // multiply center correlation pixels (inside enhortho_width)
public boolean max_corr_double = false; // NOT USED double pass when masking center of mass to reduce preference for integer values
public int corr_mode = 2; // which correlation mode to use: 0 - integer max, 1 - center of mass, 2 - polynomial
// pixel location by quadratic approximation
......@@ -1986,12 +2011,16 @@ public class EyesisCorrectionParameters {
public double corr_magic_scale = 0.85; // reported correlation offset vs. actual one (not yet understood)
// 3d reconstruction
public double min_smth = 0.25; // minimal noise-normalized pixel difference in a channel to suspect something
public boolean show_textures = true; // show generated textures
public boolean debug_filters = false;// show intermediate results of filtering
public double min_smth = 0.5; // 0.25 minimal noise-normalized pixel difference in a channel to suspect something
public double sure_smth = 2.0; // reliable noise-normalized pixel difference in a channel to have something
public double bgnd_range = 0.3; // disparity range to be considered background
public double other_range = 2.0; // disparity difference from center (provided) disparity to trust
public double bgnd_sure = 0.02; // minimal strength to be considered definitely background
public double bgnd_maybe = 0.005; // maximal strength to ignore as non-background
public double bgnd_2diff = 0.005; // maximal strength to ignore as non-background
public double bgnd_maybe = 0.004; // maximal strength to ignore as non-background
// public double bgnd_2diff = 0.005; // maximal strength to ignore as non-background
public int min_clstr_seed = 3; // number of tiles in a cluster to seed (just background?)
public int min_clstr_block = 3; // number of tiles in a cluster to block (just non-background?)
public int bgnd_grow = 2; // number of tiles to grow (1 - hor/vert, 2 - hor/vert/diagonal)
......@@ -2041,6 +2070,12 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"min_corr_normalized",this.min_corr_normalized +"");
properties.setProperty(prefix+"max_corr_sigma", this.max_corr_sigma +"");
properties.setProperty(prefix+"max_corr_radius", this.max_corr_radius +"");
properties.setProperty(prefix+"enhortho_width", this.enhortho_width +"");
properties.setProperty(prefix+"enhortho_scale", this.enhortho_scale +"");
properties.setProperty(prefix+"max_corr_double", this.max_corr_double+"");
properties.setProperty(prefix+"corr_mode", this.corr_mode+"");
properties.setProperty(prefix+"corr_border_contrast", this.corr_border_contrast +"");
properties.setProperty(prefix+"tile_task_op", this.tile_task_op+"");
......@@ -2087,10 +2122,13 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"corr_magic_scale", this.corr_magic_scale +"");
properties.setProperty(prefix+"show_textures", this.show_textures+"");
properties.setProperty(prefix+"debug_filters", this.debug_filters+"");
properties.setProperty(prefix+"min_smth", this.min_smth +"");
properties.setProperty(prefix+"sure_smth", this.sure_smth +"");
properties.setProperty(prefix+"bgnd_range", this.bgnd_range +"");
properties.setProperty(prefix+"other_range", this.other_range +"");
properties.setProperty(prefix+"bgnd_sure", this.bgnd_sure +"");
properties.setProperty(prefix+"bgnd_maybe", this.bgnd_maybe +"");
......@@ -2137,7 +2175,12 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"min_corr")!=null) this.min_corr=Double.parseDouble(properties.getProperty(prefix+"min_corr"));
if (properties.getProperty(prefix+"min_corr_normalized")!=null)this.min_corr_normalized=Double.parseDouble(properties.getProperty(prefix+"min_corr_normalized"));
if (properties.getProperty(prefix+"max_corr_sigma")!=null) this.max_corr_sigma=Double.parseDouble(properties.getProperty(prefix+"max_corr_sigma"));
if (properties.getProperty(prefix+"max_corr_radius")!=null) this.max_corr_radius=Double.parseDouble(properties.getProperty(prefix+"max_corr_radius"));
if (properties.getProperty(prefix+"max_corr_radius")!=null)this.max_corr_radius=Double.parseDouble(properties.getProperty(prefix+"max_corr_radius"));
if (properties.getProperty(prefix+"enhortho_width")!=null) this.enhortho_width=Integer.parseInt(properties.getProperty(prefix+"enhortho_width"));
if (properties.getProperty(prefix+"enhortho_scale")!=null) this.enhortho_scale=Double.parseDouble(properties.getProperty(prefix+"enhortho_scale"));
if (properties.getProperty(prefix+"max_corr_double")!=null)this.max_corr_double=Boolean.parseBoolean(properties.getProperty(prefix+"max_corr_double"));
if (properties.getProperty(prefix+"corr_mode")!=null) this.corr_mode=Integer.parseInt(properties.getProperty(prefix+"corr_mode"));
if (properties.getProperty(prefix+"corr_border_contrast")!=null) this.corr_border_contrast=Double.parseDouble(properties.getProperty(prefix+"corr_border_contrast"));
if (properties.getProperty(prefix+"tile_task_op")!=null) this.tile_task_op=Integer.parseInt(properties.getProperty(prefix+"tile_task_op"));
......@@ -2181,9 +2224,13 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"fcorr_ignore")!=null) this.fcorr_ignore=Boolean.parseBoolean(properties.getProperty(prefix+"fcorr_ignore"));
if (properties.getProperty(prefix+"corr_magic_scale")!=null) this.corr_magic_scale=Double.parseDouble(properties.getProperty(prefix+"corr_magic_scale"));
if (properties.getProperty(prefix+"show_textures")!=null) this.show_textures=Boolean.parseBoolean(properties.getProperty(prefix+"show_textures"));
if (properties.getProperty(prefix+"debug_filters")!=null) this.debug_filters=Boolean.parseBoolean(properties.getProperty(prefix+"debug_filters"));
if (properties.getProperty(prefix+"min_smth")!=null) this.min_smth=Double.parseDouble(properties.getProperty(prefix+"min_smth"));
if (properties.getProperty(prefix+"sure_smth")!=null) this.sure_smth=Double.parseDouble(properties.getProperty(prefix+"sure_smth"));
if (properties.getProperty(prefix+"bgnd_range")!=null) this.bgnd_range=Double.parseDouble(properties.getProperty(prefix+"bgnd_range"));
if (properties.getProperty(prefix+"other_range")!=null) this.other_range=Double.parseDouble(properties.getProperty(prefix+"other_range"));
if (properties.getProperty(prefix+"bgnd_sure")!=null) this.bgnd_sure=Double.parseDouble(properties.getProperty(prefix+"bgnd_sure"));
if (properties.getProperty(prefix+"bgnd_maybe")!=null) this.bgnd_maybe=Double.parseDouble(properties.getProperty(prefix+"bgnd_maybe"));
......@@ -2194,7 +2241,7 @@ public class EyesisCorrectionParameters {
}
public boolean showDialog() {
GenericDialog gd = new GenericDialog("Set DCT parameters");
GenericDialog gd = new GenericDialog("Set CLT parameters");
gd.addNumericField("Transform size (default 8)", this.transform_size, 0);
gd.addNumericField("Lapped transform window type (0- rectangular, 1 - sinus)", this.clt_window, 0);
gd.addNumericField("shift_x", this.shift_x, 4);
......@@ -2234,10 +2281,22 @@ public class EyesisCorrectionParameters {
gd.addNumericField("Minimal correlation value to consider valid when normalizing results", this.min_corr_normalized, 6);
gd.addNumericField("Sigma for weights of points around global max to find fractional", this.max_corr_sigma, 3);
gd.addNumericField("Maximal distance from int max to consider", this.max_corr_radius, 3);
gd.addMessage("--- Enhance detection of horizontal/vertical features (when enh_ortho is enabled for tile ---");
gd.addNumericField("Reduce weight of center correlation pixels from center (0 - none, 1 - center, 2 +/-1 from center)", this.enhortho_width, 0);
gd.addNumericField("Multiply center correlation pixels (inside enhortho_width) (1.0 - disables enh_orttho)", this.enhortho_scale, 3);
gd.addCheckbox ("Double pass when masking center of mass to reduce preference for integer values", this.max_corr_double);
gd.addNumericField("Correlation mode: 0 - integer max, 1 - center of mass, 2 - polynomial", this.corr_mode, 0);
gd.addNumericField("Contrast of dotted border on correlation results", this.corr_border_contrast, 6);
gd.addMessage("--- tiles tasks ---");
gd.addNumericField("Tile operations bits: +(0..f) - images, +(00.f0) - process pairs +256, ... ", this.tile_task_op, 0);
gd.addMessage("--- tiles tasks (current tile_task_op = "+this.tile_task_op+") ---");
gd.addCheckbox ("Enhace ortho lines detection (enh_ortho)", ImageDtt.getOrthoLines(this.tile_task_op));
gd.addCheckbox ("Force disparity for image rendering (false - use folund by tile correlation)", ImageDtt.getForcedDisparity(this.tile_task_op));
gd.addNumericField("Bitmask of used images (1 - top left, 2 - top right, 4 - bottom left, 8 bottom right)", ImageDtt.getImgMask(this.tile_task_op), 0);
gd.addNumericField("Bitmask of used pairs (1 - top, 2 - bottom, 4 - left, 8 - right)", ImageDtt.getPairMask(this.tile_task_op), 0);
// gd.addNumericField("Tile operations bits: +(0..f) - images, +(00.f0) - process pairs +256, ... ", this.tile_task_op, 0);
gd.addNumericField("Tile operations window left (in 8x8 tiles)", this.tile_task_wl, 0);
gd.addNumericField("Tile operations window top", this.tile_task_wt, 0);
gd.addNumericField("Tile operations window width", this.tile_task_ww, 0);
......@@ -2281,9 +2340,14 @@ public class EyesisCorrectionParameters {
gd.addCheckbox ("Ignore current calculated fine correction (use manual only)", this.fcorr_ignore);
gd.addNumericField("Calculated from correlation offset vs. actual one (not yet understood)", this.corr_magic_scale, 3);
gd.addMessage ("--- 3D reconstruction ---");
gd.addCheckbox ("Show generated textures", this.show_textures);
gd.addCheckbox ("show intermediate results of filtering", this.debug_filters);
gd.addNumericField("Minimal noise-normalized pixel difference in a channel to suspect something", this.min_smth, 3);
gd.addNumericField("Reliable noise-normalized pixel difference in a channel to have something ", this.sure_smth, 3);
gd.addNumericField("Disparity range to be considered background", this.bgnd_range, 3);
gd.addNumericField("Disparity difference from the center (provided) disparity to trust", this.other_range, 3);
gd.addNumericField("Minimal strength to be considered definitely background", this.bgnd_sure, 3);
gd.addNumericField("Maximal strength to ignore as non-background", this.bgnd_maybe, 3);
......@@ -2334,9 +2398,20 @@ public class EyesisCorrectionParameters {
this.min_corr_normalized= gd.getNextNumber();
this.max_corr_sigma= gd.getNextNumber();
this.max_corr_radius= gd.getNextNumber();
this.enhortho_width= (int) gd.getNextNumber();
this.enhortho_scale= gd.getNextNumber();
this.max_corr_double= gd.getNextBoolean();
this.corr_mode= (int) gd.getNextNumber();
this.corr_border_contrast= gd.getNextNumber();
this.tile_task_op= (int) gd.getNextNumber();
// this.tile_task_op= (int) gd.getNextNumber();
this.tile_task_op = ImageDtt.setOrthoLines (this.tile_task_op, gd.getNextBoolean());
this.tile_task_op = ImageDtt.setForcedDisparity (this.tile_task_op, gd.getNextBoolean());
this.tile_task_op = ImageDtt.setImgMask (this.tile_task_op, (int) gd.getNextNumber());
this.tile_task_op = ImageDtt.setPairMask (this.tile_task_op, (int) gd.getNextNumber());
this.tile_task_wl= (int) gd.getNextNumber();
this.tile_task_wt= (int) gd.getNextNumber();
this.tile_task_ww= (int) gd.getNextNumber();
......@@ -2377,9 +2452,12 @@ public class EyesisCorrectionParameters {
this.fcorr_ignore= gd.getNextBoolean();
this.corr_magic_scale= gd.getNextNumber();
this.show_textures= gd.getNextBoolean();
this.debug_filters= gd.getNextBoolean();
this.min_smth= gd.getNextNumber();
this.sure_smth= gd.getNextNumber();
this.sure_smth= gd.getNextNumber();
this.bgnd_range= gd.getNextNumber();
this.other_range= gd.getNextNumber();
this.bgnd_sure= gd.getNextNumber();
this.bgnd_maybe= gd.getNextNumber();
this.min_clstr_seed= (int) gd.getNextNumber();
......
......@@ -2358,8 +2358,22 @@ public class EyesisCorrections {
String path=null;
if (save) path= correctionsParameters.selectResultsDirectory(
true, // smart,
true); //newAllowed, // save
true); //newAllowed, // save
saveAndShow(
imp,
path,
correctionsParameters.png,
show,
jpegQuality);
}
void saveAndShow(
ImagePlus imp,
String path,
boolean png,
boolean show,
int jpegQuality){// <0 - keep current, 0 - force Tiff, >0 use for JPEG
if (path!=null) {
path+=Prefs.getFileSeparator()+imp.getTitle();
boolean hasAlphaHighByte = false;
......@@ -2374,7 +2388,7 @@ public class EyesisCorrections {
}
if (hasAlphaHighByte){
if (correctionsParameters.png){
if (png){
if (this.debugLevel > 0) System.out.println("Saving RGBA result to "+path+".png");
(new EyesisTiff()).savePNG_ARGB32(
imp,
......@@ -2441,27 +2455,7 @@ public class EyesisCorrections {
imp.show();
}
}
/*
private void saveAndShow(
CompositeImage compositeImage,
EyesisCorrectionParameters.ProcessParameters processParameters,
EyesisCorrectionParameters.CorrectionParameters correctionsParameters){
saveAndShow(compositeImage, processParameters, correctionsParameters , true, true);
}
private void saveAndShow(
CompositeImage compositeImage,
EyesisCorrectionParameters.ProcessParameters processParameters,
EyesisCorrectionParameters.CorrectionParameters correctionsParameters,
boolean enableSave,
boolean enableShow){
saveAndShow(
compositeImage,
correctionsParameters,
processParameters.save && enableSave,
processParameters.show && enableShow);
}
*/
private void saveAndShow(
CompositeImage compositeImage,
EyesisCorrectionParameters.CorrectionParameters correctionsParameters,
......
......@@ -33,7 +33,6 @@ import ij.ImagePlus;
import ij.ImageStack;
import ij.Prefs;
import ij.io.FileSaver;
import ij.process.ByteProcessor;
import ij.process.ColorProcessor;
import ij.process.ImageProcessor;
......@@ -57,13 +56,6 @@ public class EyesisDCT {
public int tilesX;
public int tilesY;
static int DISPARITY_INDEX_CM = 2; // index of disparity value in disparity_map == 2 (0,2 or 4)
static int DISPARITY_INDEX_POLY = 4; // index of disparity value in disparity_map == 2 (0,2 or 4)
static int STRENGTH_INDEX = 6; // index of strength data in disparity map ==6
static int IMG_DIFF0_INDEX = 8; // index of noise- normalized image difference for port 0 in disparity map
public EyesisDCT(
Properties properties,
......@@ -4884,12 +4876,15 @@ public class EyesisDCT {
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){
clt_corr_combo = new double [2][tilesY][tilesX][];
// clt_corr_combo = new double [2][tilesY][tilesX][];
clt_corr_combo = new double [ImageDtt.TCORR_TITLES.length][tilesY][tilesX][];
texture_tiles = new double [tilesY][tilesX][][]; // ["RGBA".length()][];
for (int i = 0; i < tilesY; i++){
for (int j = 0; j < tilesX; j++){
clt_corr_combo[0][i][j] = null;
clt_corr_combo[1][i][j] = null;
for (int k = 0; k<clt_corr_combo.length; k++){
clt_corr_combo[k][i][j] = null;
}
// clt_corr_combo[1][i][j] = null;
texture_tiles[i][j] = null;
}
}
......@@ -4905,8 +4900,7 @@ public class EyesisDCT {
clt_mismatch = new double [12][];
}
}
// double [][] disparity_map = new double [8][]; //[0] -residual disparity, [1] - orthogonal (just for debugging)
double [][] disparity_map = new double [12][]; //[0] -residual disparity, [1] - orthogonal (just for debugging) last 4 - max pixel differences
double [][] disparity_map = new double [ImageDtt.DISPARITY_TITLES.length][]; //[0] -residual disparity, [1] - orthogonal (just for debugging) last 4 - max pixel differences
double min_corr_selected = clt_parameters.corr_normalize? clt_parameters.min_corr_normalized: clt_parameters.min_corr;
double [][] shiftXY = {
......@@ -4937,6 +4931,9 @@ public class EyesisDCT {
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.enhortho_width, // 2; // reduce weight of center correlation pixels from center (0 - none, 1 - center, 2 +/-1 from center)
clt_parameters.enhortho_scale, // 0.2; // multiply center correlation pixels (inside enhortho_width)
clt_parameters.max_corr_double, // Double pass when masking center of mass to reduce preference for integer values
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)
......@@ -5050,15 +5047,13 @@ public class EyesisDCT {
if (clt_corr_combo!=null){
if (disparity_map != null){
if (clt_parameters.show_map){
String [] disparity_titles = {"int_disparity", "int_disp_ortho","cm_disparity", "cm_disp_ortho","poly_disparity", "poly_disp_ortho",
"strength", "variety","maxdiff0","maxdiff1","maxdiff2","maxdiff3"};
sdfa_instance.showArrays(
disparity_map,
tilesX,
tilesY,
true,
name+"-DISP_MAP-D"+clt_parameters.disparity,
disparity_titles);
ImageDtt.DISPARITY_TITLES);
}
}
......@@ -5091,7 +5086,8 @@ public class EyesisDCT {
if (clt_parameters.corr_show){
double [][] corr_rslt = new double [clt_corr_combo.length][];
String [] titles = {"combo","sum"};
String [] titles = new String[clt_corr_combo.length]; // {"combo","sum"};
for (int i = 0; i< titles.length; i++) titles[i] = ImageDtt.TCORR_TITLES[i];
for (int i = 0; i<corr_rslt.length; i++) {
corr_rslt[i] = image_dtt.corr_dbg(
clt_corr_combo[i],
......@@ -5364,11 +5360,11 @@ public class EyesisDCT {
ImagePlus result= new ImagePlus(titleFull, stack);
if (!toRGB && !this.correctionsParameters.jpeg){ // toRGB set for equirectangular
if (debugLevel > -1) System.out.println("!toRGB && !this.correctionsParameters.jpeg");
if (debugLevel > 1) System.out.println("!toRGB && !this.correctionsParameters.jpeg");
if (saveShowIntermediate) eyesisCorrections.saveAndShow(result, this.correctionsParameters);
return result;
} else { // that's not the end result, save if required
if (debugLevel > -1) System.out.println("!toRGB && !this.correctionsParameters.jpeg - else");
if (debugLevel > 1) System.out.println("!toRGB && !this.correctionsParameters.jpeg - else");
if (saveShowIntermediate) eyesisCorrections.saveAndShow(result, // saves OK with alpha - 32-bit float
......@@ -5398,7 +5394,8 @@ public class EyesisDCT {
}
result = eyesisCorrections.convertRGB48toRGB24(
stack,
name+"-RGB24"+suffix,
// name+"-RGB24"+suffix,
name+suffix,
0, 65536, // r range 0->0, 65536->256
0, 65536, // g range
0, 65536,// b range
......@@ -5419,8 +5416,8 @@ public class EyesisDCT {
int debugLevel)
{
// TODO: update the following indices when format of the arrays will change (removed unneeded data)
final int index_disparity = 2; // "cm_disparity"
final int index_strength = 6; // "strength"
final int index_disparity = ImageDtt.DISPARITY_INDEX_CM; // 2; // "cm_disparity"
final int index_strength = ImageDtt.DISPARITY_STRENGTH_INDEX; //6; // "strength"
final int [] indices_mismatch = {1,4,6,9}; // "dy0", "dy1", "dx2", "dx3"
final int numTiles = disparity_map[0].length;
final int tilesY = numTiles/tilesX;
......@@ -5892,10 +5889,11 @@ 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
// 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 [][][][] clt_corr_combo = new double [2][tilesY][tilesX][]; // will only be used inside?
double [][][][] clt_corr_combo = new double [ImageDtt.TCORR_TITLES.length][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)
double [][][] disparity_maps = new double [clt_parameters.disp_scan_count][ImageDtt.DISPARITY_TITLES.length][]; //[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;
......@@ -5929,6 +5927,9 @@ public class EyesisDCT {
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.enhortho_width, // 2; // reduce weight of center correlation pixels from center (0 - none, 1 - center, 2 +/-1 from center)
clt_parameters.enhortho_scale, // 0.2; // multiply center correlation pixels (inside enhortho_width)
clt_parameters.max_corr_double, // Double pass when masking center of mass to reduce preference for integer values
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)
......@@ -5956,10 +5957,16 @@ public class EyesisDCT {
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};
int [] disp_indices = {
ImageDtt.DISPARITY_INDEX_INT,
ImageDtt.DISPARITY_INDEX_CM,
ImageDtt.DISPARITY_INDEX_POLY,
ImageDtt.DISPARITY_STRENGTH_INDEX,
ImageDtt.DISPARITY_VARIATIONS_INDEX};
String [] disparity_titles = new String [disp_indices.length];
for (int i = 0; i < disparity_titles.length; i++ ) disparity_titles[i] = ImageDtt.DISPARITY_TITLES[i];
// 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;
......@@ -6318,7 +6325,9 @@ public class EyesisDCT {
public double [][] disparity; // per-tile disparity set for the pass[tileY][tileX]
public int [][] tile_op; // what was done in the current pass
public double [][] disparity_map; // add 4 layers - worst difference for the port
public boolean [] selected; // which tiles are selected for this layer
public double [][][][] texture_tiles;
public String texture = null; // relative (to x3d) path
}
public void resetCLTPasses(){
......@@ -6336,7 +6345,7 @@ public class EyesisDCT {
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
final int debugLevel){
String name = (String) imp_quad[0].getProperty("name");
double [][][] image_data = new double [imp_quad.length][][];
for (int i = 0; i < image_data.length; i++){
image_data[i] = eyesisCorrections.bayerToDoubleStack(
......@@ -6365,14 +6374,29 @@ public class EyesisDCT {
clt_parameters,
colorProcParameters,
rgbParameters,
(String) imp_quad[0].getProperty("name"), // .getTitle(), //String name=(String) imp_src.getProperty("name");
DISPARITY_INDEX_CM, // index of disparity value in disparity_map == 2 (0,2 or 4)
name, // .getTitle(), //String name=(String) imp_src.getProperty("name");
ImageDtt.DISPARITY_INDEX_CM, // index of disparity value in disparity_map == 2 (0,2 or 4)
threadsMax, // maximal number of threads to launch
updateStatus,
debugLevel);
bgnd_data.texture = imp_bgnd.getTitle()+".png";
// create x3d file
X3dOutput x3dOutput = new X3dOutput(
clt_parameters,
correctionsParameters,
geometryCorrection,
clt_3d_passes);
return imp_bgnd;
x3dOutput.generateBackground();
String path= correctionsParameters.selectX3dDirectory(
true, // smart,
true); //newAllowed, // save
if (path != null){
path+=Prefs.getFileSeparator()+name+".x3d";
x3dOutput.generateX3D(path);
}
return imp_bgnd; // relative (to x3d directory) path - (String) imp_bgnd.getProperty("name");
}
public ImagePlus getBackgroundImage(
......@@ -6388,7 +6412,8 @@ public class EyesisDCT {
)
{
showDoubleFloatArrays sdfa_instance = null;
if (debugLevel > -1) sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
if (clt_parameters.debug_filters && (debugLevel > -1)) sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
CLTPass3d bgnd_data = clt_3d_passes.get(0);
double [][][][] texture_tiles = bgnd_data.texture_tiles;
......@@ -6401,7 +6426,7 @@ public class EyesisDCT {
clt_parameters.min_clstr_seed, // number of tiles in a cluster to seed (just background?)
clt_parameters.min_clstr_block,// number of tiles in a cluster to block (just non-background?)
disparity_index, // index of disparity value in disparity_map == 2 (0,2 or 4)
debugLevel);
(clt_parameters.debug_filters ? debugLevel : -1));
boolean [] bgnd_strict = bgnd_tiles.clone(); // only these have non 0 alpha
growTiles(
clt_parameters.bgnd_grow, // grow tile selection by 1 over non-background tiles 1: 4 directions, 2 - 8 directions, 3 - 8 by 1, 4 by 1 more
......@@ -6410,7 +6435,7 @@ public class EyesisDCT {
growTiles(
2, // grow tile selection by 1 over non-background tiles 1: 4 directions, 2 - 8 directions, 3 - 8 by 1, 4 by 1 more
bgnd_tiles);
bgnd_data.selected = bgnd_tiles_grown; // selected for background w/o extra transparent layer
if (sdfa_instance!=null){
double [][] dbg_img = new double[3][tilesY * tilesX];
......@@ -6467,23 +6492,98 @@ public class EyesisDCT {
// for now - use just RGB. Later add oprion for RGBA
double [][] texture_rgb = {texture_overlap[0],texture_overlap[1],texture_overlap[2]};
double [][] texture_rgba = {texture_overlap[0],texture_overlap[1],texture_overlap[2],texture_overlap[3]};
// ImagePlus img_texture =
ImagePlus result = linearStackToColor(
ImagePlus imp_texture_bgnd = linearStackToColor(
clt_parameters,
colorProcParameters,
rgbParameters,
name+"-bgnd-texture", // String name,
name+"-texture-bgnd", // String name,
"", //String suffix, // such as disparity=...
true, // toRGB,
!this.correctionsParameters.jpeg, // boolean bpp16, // 16-bit per channel color mode for result
true, // boolean saveShowIntermediate, // save/show if set globally
true, // boolean saveShowFinal, // save/show result (color image?)
false, //true, // boolean saveShowFinal, // save/show result (color image?)
((clt_parameters.alpha1 > 0)? texture_rgba: texture_rgb),
tilesX,
tilesY,
1.0, // double scaleExposure, // is it needed?
debugLevel );
return result;
debugLevel);
// resize for backdrop here!
// public double getFOVPix(){ // get ratio of 1 pixel X/Y to Z (distance to object)
ImagePlus imp_texture_bgnd_ext = resizeForBackdrop(
imp_texture_bgnd,
debugLevel);
String path= correctionsParameters.selectX3dDirectory(
true, // smart,
true); //newAllowed, // save
// only show/save original size if debug or debug_filters)
if (clt_parameters.debug_filters || (debugLevel > 0)) {
eyesisCorrections.saveAndShow(
imp_texture_bgnd,
path,
correctionsParameters.png,
clt_parameters.show_textures,
-1); // jpegQuality){// <0 - keep current, 0 - force Tiff, >0 use for JPEG
}
eyesisCorrections.saveAndShow(
imp_texture_bgnd_ext,
path,
correctionsParameters.png,
clt_parameters.show_textures,
-1); // jpegQuality){// <0 - keep current, 0 - force Tiff, >0 use for JPEG
// testing 2-nd pass
secondPassSetup( // prepare tile tasks for the second pass based on the previous one(s)
// final double [][][] image_data, // first index - number of image in a quad
clt_parameters,
// disparity range - differences from
clt_parameters.bgnd_range, // double disparity_far,
clt_parameters.other_range, //double disparity_near, //
clt_parameters.bgnd_sure, // double this_sure, // minimal strength to be considered definitely background
clt_parameters.bgnd_maybe, // double this_maybe, // maximal strength to ignore as non-background
clt_parameters.sure_smth, // sure_smth, // if 2-nd worst image difference (noise-normalized) exceeds this - do not propagate bgnd
disparity_index, // index of disparity value in disparity_map == 2 (0,2 or 4)
threadsMax, // maximal number of threads to launch
updateStatus,
debugLevel);
return imp_texture_bgnd_ext;
}
public ImagePlus resizeForBackdrop(ImagePlus imp, int debugLevel){
double backdropPixels = 2.0/geometryCorrection.getFOVPix();
if (debugLevel > -1) {
System.out.println("backdropPixels = "+backdropPixels);
}
// TODO: currently - just adding pixels, no rescaling (add later). Alternatively - just modify geometry earlier
int width = imp.getWidth();
int height = imp.getHeight();
int h_margin = (int) Math.round((backdropPixels - width)/2);
int v_margin = (int) Math.round((backdropPixels - height)/2);
int width2 = width + 2 * h_margin;
int height2 = height + 2 * v_margin;
if (debugLevel > -1) {
System.out.println("backdropPixels = "+backdropPixels+" h_margin = "+h_margin+" v_margin = "+v_margin);
}
int [] src_pixels = (int []) imp.getProcessor().getPixels();
int [] pixels = new int [width2* height2];
int indx = 0;
int offset = v_margin * width2 + h_margin;
for (int i = 0; i < height; i++){
for (int j = 0; j < width; j++){
pixels[offset+ i * width2 + j] = src_pixels[indx++];
}
}
ColorProcessor cp=new ColorProcessor(width2,height2);
cp.setPixels(pixels);
ImagePlus imp_ext=new ImagePlus(imp.getTitle()+"-ext",cp);
return imp_ext;
}
//[tilesY][tilesX]["RGBA".length()][]
......@@ -6515,11 +6615,11 @@ public class EyesisDCT {
int tindx = tileY * tilesX + tileX;
if (Math.abs(disparity_map[disparity_index][tindx]) < bgnd_range){
if (disparity_map[STRENGTH_INDEX][tindx] >= bgnd_sure){
if (disparity_map[ImageDtt.DISPARITY_STRENGTH_INDEX][tindx] >= bgnd_sure){
bgnd_tiles[tindx] = true;
}
} else {
if (disparity_map[STRENGTH_INDEX][tindx] > bgnd_maybe){ // maybe non-bkgnd
if (disparity_map[ImageDtt.DISPARITY_STRENGTH_INDEX][tindx] > bgnd_maybe){ // maybe non-bkgnd
if (disparity_map[disparity_index][tindx] > 0.0) { // disregard negative disparity points
nonbgnd_tiles[tindx] = true;
}
......@@ -6528,13 +6628,13 @@ public class EyesisDCT {
// see if the second worst variatoin exceeds sure_smth (like a window), really close object
int imax1 = 0;
for (int i = 1; i< quad; i++){
if (disparity_map[IMG_DIFF0_INDEX+i][tindx] > disparity_map[IMG_DIFF0_INDEX + imax1][tindx]) imax1 = i;
if (disparity_map[ImageDtt.IMG_DIFF0_INDEX+i][tindx] > disparity_map[ImageDtt.IMG_DIFF0_INDEX + imax1][tindx]) imax1 = i;
}
int imax2 = (imax1 == 0)? 1 : 0;
for (int i = 0; i< quad; i++) if (i != imax1) {
if (disparity_map[IMG_DIFF0_INDEX+i][tindx] > disparity_map[IMG_DIFF0_INDEX + imax2][tindx]) imax2 = i;
if (disparity_map[ImageDtt.IMG_DIFF0_INDEX+i][tindx] > disparity_map[ImageDtt.IMG_DIFF0_INDEX + imax2][tindx]) imax2 = i;
}
block_propagate[tindx] = (disparity_map[IMG_DIFF0_INDEX + imax2][tindx] > sure_smth);
block_propagate[tindx] = (disparity_map[ImageDtt.IMG_DIFF0_INDEX + imax2][tindx] > sure_smth);
}
}
if (min_clstr_seed > 1){
......@@ -6562,7 +6662,7 @@ public class EyesisDCT {
dbg_img[0][i] = bgnd_tiles [i] ? 1 : 0;
dbg_img[1][i] = nonbgnd_tiles [i] ? 1 : 0;
dbg_img[2][i] = block_propagate[i] ? 1 : 0;
dbg_img[3][i] = disparity_map[STRENGTH_INDEX][i];
dbg_img[3][i] = disparity_map[ImageDtt.DISPARITY_STRENGTH_INDEX][i];
dbg_img[4][i] = disparity_map[disparity_index][i];
}
sdfa_instance.showArrays(dbg_img, tilesX, tilesY, true, "bgnd_nonbgnd",titles);
......@@ -6673,7 +6773,7 @@ public class EyesisDCT {
int min_area, // minimal number of pixels
double min_weight // minimal total weight of the cluster
){
// adding 1-tile frame around to avoid checking fro the borders
// adding 1-tile frame around to avoid checking for the borders
int tilesX2 = tilesX+2;
int tilesY2 = tilesY+2;
boolean [] tiles = new boolean [tilesX2*tilesY2];
......@@ -6795,6 +6895,10 @@ public class EyesisDCT {
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("getImgMask("+op+")="+ImageDtt.getImgMask(op) );
System.out.println("getPairMask("+op+")="+ImageDtt.getPairMask(op) );
System.out.println("getForcedDisparity("+op+")="+ImageDtt.getForcedDisparity(op) );
System.out.println("getOrthoLines("+op+")="+ImageDtt.getOrthoLines(op) );
System.out.println("tyt="+tyt+" tyb="+tyb+" txl="+txl+" txr="+txr );
}
return tile_op;
......@@ -6812,9 +6916,104 @@ public class EyesisDCT {
return disp_array;
}
public CLTPass3d secondPassSetup( // prepare tile tasks for the second pass based on the previous one(s)
// final double [][][] image_data, // first index - number of image in a quad
EyesisCorrectionParameters.CLTParameters clt_parameters,
// disparity range - differences from
double disparity_far, //
double disparity_near, //
double this_sure, // minimal strength to be considered definitely background
double this_maybe, // maximal strength to ignore as non-background
double sure_smth, // if 2-nd worst image difference (noise-normalized) exceeds this - do not propagate bgnd
int disparity_index, // index of disparity value in disparity_map == 2 (0,2 or 4)
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
final int debugLevel)
{
CLTPass3d scan_prev = clt_3d_passes.get(clt_3d_passes.size() -1);
CLTPass3d scan_next = new CLTPass3d();
showDoubleFloatArrays sdfa_instance = null;
if (debugLevel > -1) sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
int quad = 4;
int tlen = tilesY * tilesX;
//TODO: for next passes - combine all selected for previous passes (all passes with smaller disparity)
boolean [] bg_tiles = clt_3d_passes.get(0).selected; // selected for background w/o extra transparent layer
double [] this_map = scan_prev.disparity_map[disparity_index].clone();
double [] this_strength = scan_prev.disparity_map[ImageDtt.DISPARITY_STRENGTH_INDEX];
double [][] these_diffs = new double[quad][];
for (int i = 0; i< quad; i++) these_diffs[i] = scan_prev.disparity_map[ImageDtt.IMG_DIFF0_INDEX + i];
boolean [] these_tiles = new boolean [tlen];
boolean [] near_tiles = new boolean [tlen];
boolean [] far_tiles = new boolean [tlen];
boolean [] block_propagate = new boolean [tlen];
for (int i = 0; i < tilesY; i++){
for (int j = 0; j < tilesX; j++){
int indx = i * tilesX + j;
if (!Double.isNaN(this_map[i])){
this_map[indx] /= clt_parameters.corr_magic_scale;
this_map[indx] += scan_prev.disparity[i][j];
}
}
}
for (int i = 0; i <tlen; i++) if (!Double.isNaN(this_map[i])){
if (this_map[i] < disparity_far) {
if (this_strength[i] > this_maybe){
far_tiles[i] = true;
}
} else if (this_map[i] > disparity_near){
if ((this_strength[i] > this_maybe) && ! bg_tiles[i]){ // can not be farther if selected for near?
near_tiles[i] = true;
}
} else { // in range
if (this_strength[i] > this_sure)
these_tiles[i] = true;
}
// see if the second worst variatoin exceeds sure_smth (like a window), really close object
int imax1 = 0;
for (int ip = 1; ip< quad; ip++){
if (these_diffs[ip][i] > these_diffs[imax1][i]) imax1 = ip;
}
int imax2 = (imax1 == 0)? 1 : 0;
for (int ip = 0; ip< quad; ip++) if (ip != imax1) {
if (these_diffs[ip][i] > these_diffs[imax2][i]) imax2 = ip;
}
block_propagate[i] = (these_diffs[imax2][i] > sure_smth);
}
if (sdfa_instance!=null){
String [] titles = {"map","bg_sel","far","these","near","block","strength","diff0","diff1","diff2","diff3"};
double [][] dbg_img = new double[titles.length][tilesY * tilesX];
for (int i = 0; i<dbg_img[0].length;i++){
dbg_img[ 0][i] = this_map[i];
dbg_img[ 1][i] = bg_tiles [i] ? 1 : 0;
dbg_img[ 2][i] = far_tiles [i] ? 1 : 0;
dbg_img[ 3][i] = these_tiles [i] ? 1 : 0;
dbg_img[ 4][i] = near_tiles [i] ? 1 : 0;
dbg_img[ 5][i] = block_propagate[i] ? 1 : 0;
dbg_img[ 6][i] = this_strength[i];
dbg_img[ 7][i] = these_diffs[0][i];
dbg_img[ 8][i] = these_diffs[1][i];
dbg_img[ 9][i] = these_diffs[2][i];
dbg_img[10][i] = these_diffs[3][i];
}
sdfa_instance.showArrays(dbg_img, tilesX, tilesY, true, "bgnd_nonbgnd",titles);
}
return scan_next;
}
/*
public class CLTPass3d{
public double [][] disparity; // per-tile disparity set for the pass[tileY][tileX]
public int [][] tile_op; // what was done in the current pass
public double [][] disparity_map; // add 4 layers - worst difference for the port
public double [][][][] texture_tiles;
public String texture = null; // relative (to x3d) path
}
static int STRENGTH_INDEX = 6; // index of strength data in disparity map ==6
static int IMG_DIFF0_INDEX = 8; // index of noise- normalized image difference for port 0 in disparity map
*/
public CLTPass3d CLTBackgroundMeas( // measure background
// ImagePlus [] imp_quad, // should have properties "name"(base for saving results), "channel","path"
final double [][][] image_data, // first index - number of image in a quad
EyesisCorrectionParameters.CLTParameters clt_parameters,
final int threadsMax, // maximal number of threads to launch
......@@ -6823,14 +7022,18 @@ public class EyesisDCT {
{
CLTPass3d scan_rslt = new CLTPass3d();
int [][] tile_op = setSameTileOp(clt_parameters, 0xff | (1 << ImageDtt.FORCE_DISPARITY_BIT), debugLevel);
int d = ImageDtt.setImgMask(0, 0xf);
d = ImageDtt.setPairMask(d,0xf);
d = ImageDtt.setForcedDisparity(d,true);
int [][] tile_op = setSameTileOp(clt_parameters, d, debugLevel);
double [][] disparity_array =setSameDisparity(0.0); // [tilesY][tilesX] - individual per-tile expected disparity
// 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 [][][][] clt_corr_combo = new double [2][tilesY][tilesX][]; // will only be used inside?
double [][][][] clt_corr_combo = new double [ImageDtt.TCORR_TITLES.length][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_map = new double [12][]; //[0] -residual disparity, [1] - orthogonal (just for debugging)
double [][] disparity_map = new double [ImageDtt.DISPARITY_TITLES.length][]; //[0] -residual disparity, [1] - orthogonal (just for debugging)
double [][] shiftXY = {
{clt_parameters.fine_corr_x_0,clt_parameters.fine_corr_y_0},
......@@ -6862,6 +7065,9 @@ public class EyesisDCT {
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.enhortho_width, // 2; // reduce weight of center correlation pixels from center (0 - none, 1 - center, 2 +/-1 from center)
clt_parameters.enhortho_scale, // 0.2; // multiply center correlation pixels (inside enhortho_width)
clt_parameters.max_corr_double, // Double pass when masking center of mass to reduce preference for integer values
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)
......
......@@ -27,6 +27,8 @@ import ij.IJ;
*/
public class GeometryCorrection {
static double SCENE_UNITS_SCALE = 0.001;
static String SCENE_UNITS_NAME = "m";
public int debugLevel = 0;
// public double azimuth; // azimuth of the lens entrance pupil center, degrees, clockwise looking from top
// public double radius; // mm, distance from the rotation axis
......@@ -70,8 +72,8 @@ public class GeometryCorrection {
public double [][] XYZ_he; // all cameras coordinates transformed to eliminate heading and elevation (rolls preserved)
public double [][] XYZ_her = null; // XYZ of the lenses in a corrected CCS (adjusted for to elevation, heading, common_roll)
public double [][] rXY = null; // XY pairs of the in a normal plane, relative to disparityRadius
public double cameraRadius=0; // average distance from the "mass center" of the sencors to the sensors
public double disparityRadius=0; // distance between cameras to normalize disparity units to. sqrt(2)*disparityRadius for quad camera
public double cameraRadius=0; // average distance from the "mass center" of the sensors to the sensors
public double disparityRadius=0; // distance between cameras to normalize disparity units to. sqrt(2)*disparityRadius for quad camera (~=150mm)?
private double [] rByRDist=null;
private double stepR=0.001;
......@@ -307,7 +309,18 @@ public class GeometryCorrection {
// return distance from disparity (in pixel units) for the current camera geometry
public double getZFromDisparity(double disparity){
return disparity * this.focalLength * 0.001*this.pixelSize / this.disparityRadius;
return SCENE_UNITS_SCALE * this.focalLength * this.disparityRadius / (disparity * 0.001*this.pixelSize);
}
public double getFOVPix(){ // get ratio of 1 pixel X/Y to Z (distance to object)
return 0.001 * this.pixelSize / this.focalLength;
}
public double getFOVWidth(){ // get FOV ratio: width to distance
return this.pixelCorrectionWidth * 0.001 * this.pixelSize / this.focalLength;
}
public double getFOVHeight(){ // get FOV ratio: width to distance
return this.pixelCorrectionHeight * 0.001 * this.pixelSize / this.focalLength;
}
/*
......
......@@ -47,8 +47,37 @@ public class ImageDtt {
{1,2,4,5}, // bottom left
{0,1,2,3,4,5}, // mottom middle
{0,1,3,4}}; // bottom right
public static int FORCE_DISPARITY_BIT = 8; // move to parameters?
// public static int FORCE_DISPARITY_BIT = 8; // move to parameters?
static int DISPARITY_INDEX_INT = 0; // 0 - disparity from correlation integer pixels, 1 - ortho
static int DISPARITY_INDEX_CM = 2; // 2 - disparity from correlation "center mass", 3 - ortho (only used for fine correction)
static int DISPARITY_INDEX_HOR = 4; // disparity from correlation of the horizontal pairs with center suppressed
static int DISPARITY_INDEX_HOR_STRENGTH = 5; // strength for hor mode (emphasis on vertical lines)
static int DISPARITY_INDEX_VERT = 6; // disparity from correlation of the vertical pairs with center suppressed
static int DISPARITY_INDEX_VERT_STRENGTH = 7; // strength in vert mode (horizontal lines detection)
static int DISPARITY_INDEX_POLY = 8; // index of disparity value in disparity_map == 2 (0,2 or 4)
static int DISPARITY_STRENGTH_INDEX = 10; // index of strength data in disparity map ==6
static int DISPARITY_VARIATIONS_INDEX = 11; // index of strength data in disparity map ==6
static int IMG_DIFF0_INDEX = 12; // index of noise- normalized image difference for port 0 in disparity map
static String [] DISPARITY_TITLES = {
"int_disp","int_y_disp","cm_disp","cm_y_disp","hor_disp","hor_strength","vert_disp","vert_strength",
"poly_disp", "poly_y_disp", "strength_disp", "vary_disp","diff0","diff1","diff2","diff3"};
static int TCORR_COMBO_RSLT = 0; // normal combined correlation from all selected pairs (mult/sum)
static int TCORR_COMBO_SUM = 1; // sum of channle correlations from all selected pairs
static int TCORR_COMBO_HOR = 2; // combined correlation from 2 horizontal pairs (0,1). Used to detect vertical features
static int TCORR_COMBO_VERT = 3; // combined correlation from 2 vertical pairs (0,1). Used to detect horizontal features
static String [] TCORR_TITLES = {"combo","sum","hor","vert"};
public static int getImgMask (int data){ return (data & 0xf);} // which images to use
public static int getPairMask (int data){ return ((data >> 4) & 0xf);} // which pairs to combine in the combo: 1 - top, 2 bottom, 4 - left, 8 - right
public static int setImgMask (int data, int mask) {return (data & ~0xf) | (mask & 0xf);}
public static int setPairMask (int data, int mask) {return (data & ~0xf0) | ((mask & 0xf) << 4);}
public static boolean getForcedDisparity (int data){return (data & 0x100) != 0;}
public static int setForcedDisparity (int data, boolean force) {return (data & ~0x100) | (force?0x100:0);}
public static boolean getOrthoLines (int data){return (data & 0x200) != 0;}
public static int setOrthoLines (int data, boolean force) {return (data & ~0x200) | (force?0x200:0);}
public ImageDtt(){
......@@ -947,18 +976,23 @@ public class ImageDtt {
final double corr_sigma,
// final int corr_mask, // which pairs to combine in the combo: 1 - top, 2 bottom, 4 - left, 8 - right
final boolean corr_normalize, // normalize correlation results by rms
final double min_corr, // 0.0001; // minimal correlation value to consider valid
final double max_corr_sigma, // = 1.5; // weights of points around global max to find fractional
final double max_corr_radius, // = 2.5;
final double min_corr, // 0.0001; // minimal correlation value to consider valid
final double max_corr_sigma, // 1.5; // weights of points around global max to find fractional
final double max_corr_radius, // 3.5;
final int enhortho_width, // 2; // reduce weight of center correlation pixels from center (0 - none, 1 - center, 2 +/-1 from center)
final double enhortho_scale, // 0.2; // multiply center correlation pixels (inside enhortho_width)
final boolean max_corr_double, //"Double pass when masking center of mass to reduce preference for integer values
final int corr_mode, // Correlation mode: 0 - integer max, 1 - center of mass, 2 - polynomial
final double min_shot, // 10.0; // Do not adjust for shot noise if lower than
final double scale_shot, // 3.0; // scale when dividing by sqrt ( <0 - disable correction)
final double diff_sigma, // 5.0;//RMS difference from average to reduce weights (~ 1.0 - 1/255 full scale image)
final double diff_threshold, // 5.0; // RMS difference from average to discard channel (~ 1.0 - 1/255 full scale image)
final boolean diff_gauss, // true; // when averaging images, use gaussian around average as weight (false - sharp all/nothing)
final double min_agree, // 3.0; // minimal number of channels to agree on a point (real number to work with fuzzy averages)
final boolean dust_remove, // Do not reduce average weight when only one image differes much from the average
final boolean keep_weights, // Add port weights to RGBA stack (debug feature)
final double min_shot, // 10.0; // Do not adjust for shot noise if lower than
final double scale_shot, // 3.0; // scale when dividing by sqrt ( <0 - disable correction)
final double diff_sigma, // 5.0;//RMS difference from average to reduce weights (~ 1.0 - 1/255 full scale image)
final double diff_threshold, // 5.0; // RMS difference from average to discard channel (~ 1.0 - 1/255 full scale image)
final boolean diff_gauss, // true; // when averaging images, use gaussian around average as weight (false - sharp all/nothing)
final double min_agree, // 3.0; // minimal number of channels to agree on a point (real number to work with fuzzy averages)
final boolean dust_remove, // Do not reduce average weight when only one image differes much from the average
final boolean keep_weights, // Add port weights to RGBA stack (debug feature)
final GeometryCorrection geometryCorrection,
final double [][][][][][] clt_kernels, // [channel_in_quad][color][tileY][tileX][band][pixel] , size should match image (have 1 tile around)
final int kernel_step,
......@@ -973,20 +1007,16 @@ public class ImageDtt {
final int debug_tileY,
final boolean no_fract_shift,
final boolean no_deconvolution,
// final boolean transpose,
final int threadsMax, // maximal number of threads to launch
final int globalDebugLevel)
{
final int quad = 4; // number of subcameras
final int numcol = 3; // number of colors
final int FORCE_DISPARITY_BIT = 8; // move to parameters?
final int disparity_maxdiff_index = 8;
final int nChn = image_data[0].length;
final int height=image_data[0][0].length/width;
final int tilesX=width/transform_size;
final int tilesY=height/transform_size;
final int nTilesInChn=tilesX*tilesY;
// final double [][][][][][] clt_data = new double[quad][nChn][tilesY][tilesX][4][];
final double [][][][][][] clt_data = new double[quad][nChn][tilesY][tilesX][][];
final Thread[] threads = newThreadArray(threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
......@@ -1004,6 +1034,21 @@ public class ImageDtt {
}
}
// reducing weight of on-axis correlation values to enhance detection of vertical/horizontal lines
// multiply correlation results inside the horizontal center strip 2*enhortho_width - 1 wide by enhortho_scale
final double [] enh_ortho_scale = new double [corr_size];
for (int i = 0; i < corr_size; i++){
if ((i < (transform_size - enhortho_width)) || (i > (transform_size - 2 + enhortho_width))) enh_ortho_scale[i] = 1.0;
else enh_ortho_scale[i] = enhortho_scale;
}
if (globalDebugLevel > 0){
System.out.println("enhortho_width="+ enhortho_width+" enhortho_scale="+ enhortho_scale);
for (int i = 0; i < corr_size; i++){
System.out.println(" enh_ortho_scale["+i+"]="+ enh_ortho_scale[i]);
}
}
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);
......@@ -1103,13 +1148,12 @@ public class ImageDtt {
public void run() {
DttRad2 dtt = new DttRad2(transform_size);
dtt.set_window(window_type);
int tileY,tileX; // , chn;
int tileY,tileX,tIndex; // , chn;
// showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
double centerX; // center of aberration-corrected (common model) tile, X
double centerY; //
double [][] fract_shiftsXY = new double[quad][];
double [][] tcorr_combo = null; // [15*15] pixel space
// double [][] tcorr_tcombo = null; // [4][8*8] - transform space not used
double [][][] tcorr_partial = null; // [quad][numcol+1][15*15]
double [][][][] tcorr_tpartial = null; // [quad][numcol+1][4][8*8]
PolynomialApproximation pa = null;
......@@ -1117,9 +1161,10 @@ public class ImageDtt {
for (int nTile = ai.getAndIncrement(); nTile < nTilesInChn; nTile = ai.getAndIncrement()) {
tileY = nTile /tilesX;
tileX = nTile % tilesX;
tIndex = tileY * tilesX + tileX;
if (tile_op[tileY][tileX] == 0) continue; // nothing to do for this tile
int img_mask = (tile_op[tileY][tileX] >> 0) & 0xf; // which images to use
int corr_mask = (tile_op[tileY][tileX] >> 4) & 0xf; // which pairs to combine in the combo: 1 - top, 2 bottom, 4 - left, 8 - right
int img_mask = getImgMask(tile_op[tileY][tileX]); // which images to use
int corr_mask = getPairMask(tile_op[tileY][tileX]); // which pairs to combine in the combo: 1 - top, 2 bottom, 4 - left, 8 - right
// mask out pairs that use missing channels
for (int i = 0; i< corr_pairs.length; i++){
if ((((1 << corr_pairs[i][0]) & img_mask) == 0) || (((1 << corr_pairs[i][1]) & img_mask) == 0)) {
......@@ -1134,8 +1179,6 @@ public class ImageDtt {
centerX,
centerY,
disparity_array[tileY][tileX]);
// 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_corr(): color="+chn+", tileX="+tileX+", tileY="+tileY+
......@@ -1335,7 +1378,7 @@ public class ImageDtt {
}
}
} // all pairs calculated
tcorr_combo = new double [2][corr_size * corr_size];
tcorr_combo = new double [TCORR_TITLES.length][corr_size * corr_size];
int numPairs = 0;
for (int pair = 0; pair < corr_pairs.length; pair++) if (((corr_mask >> pair) & 1) != 0){
......@@ -1349,46 +1392,58 @@ public class ImageDtt {
System.out.println("avScale="+avScale+", corr_offset="+corr_offset);
}
if (corr_offset < 0) { // just add all partial correlations for composite color
for (int i = 0; i < tcorr_combo[0].length; i++){
tcorr_combo[0][i] = 0.0;
for (int i = 0; i < tcorr_combo[TCORR_COMBO_RSLT].length; i++){
tcorr_combo[TCORR_COMBO_RSLT][i] = 0.0;
tcorr_combo[TCORR_COMBO_HOR][i] = 0.0;
tcorr_combo[TCORR_COMBO_VERT][i] = 0.0;
for (int pair = 0; pair < corr_pairs.length; pair++) if (((corr_mask >> pair) & 1) != 0){
tcorr_combo[0][i] += avScale*tcorr_partial[pair][numcol][i]; // only composite color channel
tcorr_combo[TCORR_COMBO_RSLT][i] += avScale*tcorr_partial[pair][numcol][i]; // only composite color channel
if (corr_pairs[pair][2] == 0) { // horizontal pair
tcorr_combo[TCORR_COMBO_HOR][i] += avScale*tcorr_partial[pair][numcol][i]; // only composite color channel
} else { //vertical pair
tcorr_combo[TCORR_COMBO_VERT][i] += avScale*tcorr_partial[pair][numcol][i]; // only composite color channel
}
if (debugMax) {
System.out.println("tcorr_combo[0]["+i+"]="+tcorr_combo[0][i]+" tcorr_partial["+pair+"]["+numcol+"]["+i+"]="+tcorr_partial[pair][numcol][i]);
System.out.println("tcorr_combo[TCORR_COMBO_RSLT]["+i+"]="+tcorr_combo[TCORR_COMBO_RSLT][i]+" tcorr_partial["+pair+"]["+numcol+"]["+i+"]="+tcorr_partial[pair][numcol][i]);
}
}
// tcorr_combo[TCORR_COMBO_HOR][i] *=2; // no have the same scale as tcorr_combo[TCORR_COMBO_RSLT]
// tcorr_combo[TCORR_COMBO_VERT][i] *=2;
}
} else {
for (int i = 0; i < tcorr_combo[0].length; i++){
tcorr_combo[0][i] = 1.0;
for (int i = 0; i < tcorr_combo[TCORR_COMBO_RSLT].length; i++){
tcorr_combo[TCORR_COMBO_RSLT][i] = 1.0;
tcorr_combo[TCORR_COMBO_HOR][i] = 1.0;
tcorr_combo[TCORR_COMBO_VERT][i] = 1.0;
for (int pair = 0; pair < corr_pairs.length; pair++) if (((corr_mask >> pair) & 1) != 0){
tcorr_combo[0][i] *= (tcorr_partial[pair][numcol][i] + corr_offset); // only composite color channel
if (debugMax) {
System.out.println("tcorr_combo[0]["+i+"]="+tcorr_combo[0][i]+" tcorr_partial["+pair+"]["+numcol+"]["+i+"]="+tcorr_partial[pair][numcol][i]);
tcorr_combo[TCORR_COMBO_RSLT][i] *= (tcorr_partial[pair][numcol][i] + corr_offset); // only composite color channel
if (corr_pairs[pair][2] == 0) { // horizontal pair
tcorr_combo[TCORR_COMBO_HOR][i] *= (tcorr_partial[pair][numcol][i] + corr_offset); // only composite color channel
} else { //vertical pair
tcorr_combo[TCORR_COMBO_VERT][i] *= (tcorr_partial[pair][numcol][i] + corr_offset); // only composite color channel
}
/*
if (tcorr_combo[0][i] > 0){
tcorr_combo[0][i] = Math.pow(tcorr_combo[0][i],avScale) - corr_offset;
} else {
tcorr_combo[0][i] = 0; // -Math.pow(-tcorr_combo[0][i],avScale) - corr_offset;
if (debugMax) {
System.out.println("tcorr_combo[TCORR_COMBO_RSLT]["+i+"]="+tcorr_combo[TCORR_COMBO_RSLT][i]+" tcorr_partial["+pair+"]["+numcol+"]["+i+"]="+tcorr_partial[pair][numcol][i]);
}
*/
}
// tcorr_combo[TCORR_COMBO_HOR][i] *= tcorr_combo[TCORR_COMBO_HOR][i]; // no have the same scale as tcorr_combo[TCORR_COMBO_RSLT]
// tcorr_combo[TCORR_COMBO_VERT][i] *= tcorr_combo[TCORR_COMBO_VERT][i];
}
}
// calculate sum also
for (int i = 0; i < tcorr_combo[1].length; i++){
tcorr_combo[1][i] = 0.0;
for (int i = 0; i < tcorr_combo[TCORR_COMBO_SUM].length; i++){
tcorr_combo[TCORR_COMBO_SUM][i] = 0.0;
for (int pair = 0; pair < corr_pairs.length; pair++) if (((corr_mask >> pair) & 1) != 0){
tcorr_combo[1][i] += avScale*tcorr_partial[pair][numcol][i]; // only composite color channel
tcorr_combo[TCORR_COMBO_SUM][i] += avScale*tcorr_partial[pair][numcol][i]; // only composite color channel
if (debugMax) {
System.out.println("tcorr_combo[1]["+i+"]="+tcorr_combo[1][i]+" tcorr_partial["+pair+"]["+numcol+"]["+i+"]="+tcorr_partial[pair][numcol][i]);
System.out.println("tcorr_combo[TCORR_COMBO_SUM]["+i+"]="+tcorr_combo[TCORR_COMBO_SUM][i]+" tcorr_partial["+pair+"]["+numcol+"]["+i+"]="+tcorr_partial[pair][numcol][i]);
}
}
}
/*
double [] rms = new double [tcorr_combo.length];
for (int n = 0; n < rms.length; n++) rms[n] = 1.0;
if (corr_normalize){ // normalize both composite and sum by their RMS
for (int n = 0; n<tcorr_combo.length; n++){
rms[n] = 0;
......@@ -1404,8 +1459,9 @@ public class ImageDtt {
}
}
}
*/
// return results
for (int n = 0; n <clt_corr_combo.length; n++){
for (int n = 0; n < clt_corr_combo.length; n++){ // tcorr_combo now may be longer than clt_corr_combo
clt_corr_combo[n][tileY][tileX] = tcorr_combo[n];
}
if (clt_corr_partial != null){
......@@ -1413,70 +1469,89 @@ public class ImageDtt {
}
if (disparity_map != null) {
int [] icorr_max =getMaxXYInt( // find integer pair or null if below threshold
tcorr_combo[0], // [data_size * data_size]
tcorr_combo[TCORR_COMBO_RSLT], // [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;
disparity_map[2][tileY*tilesX + tileX] = Double.NaN;
disparity_map[3][tileY*tilesX + tileX] = Double.NaN;
disparity_map[4][tileY*tilesX + tileX] = Double.NaN;
disparity_map[5][tileY*tilesX + tileX] = Double.NaN;
disparity_map[DISPARITY_INDEX_INT] [tIndex] = Double.NaN;
disparity_map[DISPARITY_INDEX_INT+1] [tIndex] = Double.NaN;
disparity_map[DISPARITY_INDEX_CM] [tIndex] = Double.NaN;
disparity_map[DISPARITY_INDEX_CM+1] [tIndex] = Double.NaN;
disparity_map[DISPARITY_INDEX_HOR] [tIndex] = Double.NaN;
disparity_map[DISPARITY_INDEX_HOR_STRENGTH][tIndex] = Double.NaN;
disparity_map[DISPARITY_INDEX_VERT] [tIndex] = Double.NaN;
disparity_map[DISPARITY_INDEX_VERT_STRENGTH][tIndex] = Double.NaN;
disparity_map[DISPARITY_INDEX_POLY] [tIndex] = Double.NaN;
disparity_map[DISPARITY_INDEX_POLY+1] [tIndex] = 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;
clt_mismatch[3*pair + 0 ][tIndex] = Double.NaN;
clt_mismatch[3*pair + 1 ][tIndex] = Double.NaN;
clt_mismatch[3*pair + 2 ][tIndex] = 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];
disparity_map[DISPARITY_INDEX_INT][tIndex] = transform_size - 1 -corr_max_XYi[0];
disparity_map[DISPARITY_INDEX_INT+1][tIndex] = transform_size - 1 -corr_max_XYi[1];
// for the integer maximum provide contrast and variety
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
disparity_map[DISPARITY_STRENGTH_INDEX][tIndex] = tcorr_combo[TCORR_COMBO_RSLT][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
// disparity_map[DISPARITY_VARIATIONS_INDEX][tIndex] = (rms[1]*tcorr_combo[1][max_index])/(rms[0]*tcorr_combo[0][max_index]); // correlation combo value at the integer maximum
disparity_map[DISPARITY_VARIATIONS_INDEX][tIndex] = (tcorr_combo[TCORR_COMBO_SUM][max_index])/(tcorr_combo[TCORR_COMBO_RSLT][max_index]); // correlation combo value at the integer maximum
// Calculate "center of mass" coordinates
double [] corr_max_XYm = getMaxXYCm( // get fractiona center as a "center of mass" inside circle/square from the integer max
tcorr_combo[0], // [data_size * data_size]
tcorr_combo[TCORR_COMBO_RSLT], // [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
max_corr_double, //"Double pass when masking center of mass to reduce preference for integer values
debugMax);
if (corr_max_XYm != null){
disparity_map[2][tileY*tilesX + tileX] = transform_size - 1 -corr_max_XYm[0];
disparity_map[3][tileY*tilesX + tileX] = transform_size - 1 -corr_max_XYm[1];
} else {
disparity_map[2][tileY*tilesX + tileX] = Double.NaN;
disparity_map[3][tileY*tilesX + tileX] = Double.NaN;
}
disparity_map[DISPARITY_INDEX_CM][tIndex] = transform_size - 1 -corr_max_XYm[0];
disparity_map[DISPARITY_INDEX_CM+1][tIndex] = transform_size - 1 -corr_max_XYm[1];
// returns x and strength, not x,y
double [] corr_max_XS_hor = getMaxXSOrtho( // get fractiona center as a "center of mass" inside circle/square from the integer max
tcorr_combo[TCORR_COMBO_HOR], // [data_size * data_size]
enh_ortho_scale, // [data_size]
corr_size,
max_corr_radius,
// max_corr_double, // reusing, true - just poly for maximum
(globalDebugLevel > 0) && (tileX == debug_tileX) && (tileY == debug_tileY)); // debugMax);
disparity_map[DISPARITY_INDEX_HOR][tIndex] = transform_size - 1 - corr_max_XS_hor[0];
disparity_map[DISPARITY_INDEX_HOR_STRENGTH][tIndex] = corr_max_XS_hor[1];
double [] corr_max_XS_vert = getMaxXSOrtho( // get fractiona center as a "center of mass" inside circle/square from the integer max
tcorr_combo[TCORR_COMBO_VERT], // [data_size * data_size]
enh_ortho_scale, // [data_size]
corr_size,
max_corr_radius,
// max_corr_double, // reusing, true - just poly for maximum (probably keep it that way)
(globalDebugLevel > 0) && (tileX == debug_tileX) && (tileY == debug_tileY)); // debugMax);
disparity_map[DISPARITY_INDEX_VERT][tIndex] = transform_size - 1 - corr_max_XS_vert[0];
disparity_map[DISPARITY_INDEX_VERT_STRENGTH][tIndex] = corr_max_XS_vert[1];
// Calculate polynomial interpolated maximum coordinates
double [] corr_max_XY = getMaxXYPoly( // get interpolated maximum coordinates using 2-nd degree polynomial
pa,
tcorr_combo[0], // [data_size * data_size]
tcorr_combo[TCORR_COMBO_RSLT], // [data_size * data_size]
corr_size,
icorr_max, // integer center coordinates (relative to top left)
corr_max_weights_poly, // [(radius+1) * (radius+1)]
max_search_radius_poly, // max_search_radius, for polynomial - always use 1
debugMax);
if (corr_max_XY != null){
disparity_map[4][tileY*tilesX + tileX] = transform_size - 1 -corr_max_XY[0];
disparity_map[5][tileY*tilesX + tileX] = transform_size - 1 -corr_max_XY[1];
disparity_map[DISPARITY_INDEX_POLY][tIndex] = transform_size - 1 -corr_max_XY[0];
disparity_map[DISPARITY_INDEX_POLY+1][tIndex] = transform_size - 1 -corr_max_XY[1];
} else {
disparity_map[4][tileY*tilesX + tileX] = Double.NaN;
disparity_map[5][tileY*tilesX + tileX] = Double.NaN;
disparity_map[DISPARITY_INDEX_POLY][tIndex] = Double.NaN;
disparity_map[DISPARITY_INDEX_POLY+1][tIndex] = Double.NaN;
}
if (corr_mode == 0) extra_disparity = disparity_map[0][tileY*tilesX + tileX];
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 (corr_mode == 0) extra_disparity = disparity_map[DISPARITY_INDEX_INT][tIndex];
else if (corr_mode == 1) extra_disparity = disparity_map[DISPARITY_INDEX_CM][tIndex];
else if (corr_mode == 2) extra_disparity = disparity_map[DISPARITY_INDEX_POLY][tIndex];
else if (corr_mode == 3) extra_disparity = disparity_map[DISPARITY_INDEX_HOR][tIndex];
else if (corr_mode == 4) extra_disparity = disparity_map[DISPARITY_INDEX_VERT][tIndex];
if (Double.isNaN(extra_disparity)) extra_disparity = 0;
if (clt_mismatch != null){
......@@ -1487,30 +1562,31 @@ public class ImageDtt {
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;
clt_mismatch[3*pair + 0 ][tIndex] = Double.NaN;
clt_mismatch[3*pair + 1 ][tIndex] = Double.NaN;
clt_mismatch[3*pair + 2 ][tIndex] = 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
max_corr_double, //"Double pass when masking center of mass to reduce preference for integer values
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];
yp = transform_size - 1 -corr_max_XYmp[0] - disparity_map[DISPARITY_INDEX_CM][tIndex];
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];
xp = transform_size - 1 -corr_max_XYmp[0] - disparity_map[DISPARITY_INDEX_CM][tIndex];
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;
clt_mismatch[3*pair + 0 ][tIndex] = xp;
clt_mismatch[3*pair + 1 ][tIndex] = yp;
clt_mismatch[3*pair + 2 ][tIndex] = strength;
}
}
}
......@@ -1522,7 +1598,8 @@ public class ImageDtt {
if (texture_tiles !=null) {
if ((extra_disparity != 0) && (((1 << FORCE_DISPARITY_BIT) & tile_op[tileY][tileX]) == 0)){ // 0 - adjust disparity, 1 - use provided
// if ((extra_disparity != 0) && (((1 << FORCE_DISPARITY_BIT) & tile_op[tileY][tileX]) == 0)){ // 0 - adjust disparity, 1 - use provided
if ((extra_disparity != 0) && !getForcedDisparity(tile_op[tileY][tileX])){ // 0 - adjust disparity, 1 - use 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++) {
......@@ -1612,7 +1689,7 @@ public class ImageDtt {
}
double [] max_diff = null;
if ((disparity_map != null) && (disparity_map.length >= (disparity_maxdiff_index + quad))){
if ((disparity_map != null) && (disparity_map.length >= (IMG_DIFF0_INDEX + quad))){
max_diff = new double[quad];
}
texture_tiles[tileY][tileX] = tile_combine_rgba(
......@@ -1644,9 +1721,9 @@ public class ImageDtt {
}
}
}
if ((disparity_map != null) && (disparity_map.length >= (disparity_maxdiff_index + quad))){
if ((disparity_map != null) && (disparity_map.length >= (IMG_DIFF0_INDEX + quad))){
for (int i = 0; i < max_diff.length; i++){
disparity_map[disparity_maxdiff_index + i][tileY*tilesX + tileX] = max_diff[i];
disparity_map[IMG_DIFF0_INDEX + i][tIndex] = max_diff[i];
}
}
}
......@@ -2058,9 +2135,13 @@ public class ImageDtt {
int data_size,
int [] icenter, // integer center coordinates (relative to top left)
double radius, // positive - within that distance, negative - within 2*(-radius)+1 square
boolean max_corr_double,
boolean debug)
{
if (icenter == null) return null; //gigo
if (icenter == null) {
double [] rslt = {Double.NaN,Double.NaN};
return rslt; //gigo
}
//calculate as "center of mass"
int iradius = (int) Math.abs(radius);
int ir2 = (int) (radius*radius);
......@@ -2072,7 +2153,11 @@ public class ImageDtt {
int y2 = y*y;
for (int x = - iradius ; x <= iradius; x++){
int dataX = icenter[0] +x;
if ((dataX >= 0) && (dataX < data_size) && (square || ((y2 + x * x) <= ir2))){
double r2 = y2 + x * x;
// if ((dataX >= 0) && (dataX < data_size) && (square || ((y2 + x * x) <= ir2))){
if ((dataX >= 0) && (dataX < data_size) && (square || (r2 <= ir2))){
// double w = max_corr_double? (1.0 - r2/ir2):1.0;
// double d = w* data[dataY * data_size + dataX];
double d = data[dataY * data_size + dataX];
s0 += d;
sx += d * dataX;
......@@ -2086,9 +2171,88 @@ public class ImageDtt {
System.out.println("getMaxXYInt() -> "+rslt[0]+"/"+rslt[1]);
}
return rslt;
}
public double [] getMaxXSOrtho( // get fractional center as a "center of mass" inside circle/square from the integer max
double [] data, // [data_size * data_size]
double [] enhortho_scales, // [data_size]
int data_size,
double radius, // positive - within that distance, negative - within 2*(-radius)+1 square
// boolean poly_mode,
boolean debug)
{
double [] corr_1d = new double [data_size];
for (int j = 0; j < data_size; j++){
corr_1d[j] = 0;
for (int i = 0; i < data_size; i++){
corr_1d[j] += data[i * data_size + j] * enhortho_scales[i];
}
}
int icenter = 0;
for (int i = 1; i < data_size; i++){
if (corr_1d[i] > corr_1d[icenter]) icenter = i;
}
//calculate as "center of mass"
// int iradius = (int) Math.abs(radius);
double [] coeff = null;
double xcenter = icenter;
double [][] pa_data=null;
// try 3-point parabola
if ((icenter >0) && (icenter < (data_size - 1))) {
PolynomialApproximation pa = new PolynomialApproximation(debug?5:0); // debugLevel
double [][] pa_data0 = {
{icenter - 1, corr_1d[icenter - 1]},
{icenter, corr_1d[icenter ]},
{icenter + 1, corr_1d[icenter + 1]}};
pa_data = pa_data0;
coeff = pa.polynomialApproximation1d(pa_data, 2);
if (coeff != null){
xcenter = - coeff[1]/(2* coeff[2]);
}
}
icenter = (int) Math.round(xcenter);
double strength = corr_1d[icenter] / ((data_size+1) / 2);// scale to ~match regular strength
double [] rslt1 = {xcenter, strength};
return rslt1;
/*
double s0 = 0, sx=00;
int x_min = (int) Math.ceil(xcenter - radius);
if (x_min < 0) x_min = 0;
int x_max = (int) Math.floor(xcenter + radius);
if (x_max >= data_size) x_max = data_size - 1;
for (int x = x_min ; x <= x_max; x++){
double d = corr_1d[x];
s0 += d;
sx += d * x;
}
double [] rslt = {sx / s0, strength}; // scale to ~match regular strength
if (debug){
System.out.println("getMaxXYCmEnhOrtho() -> "+rslt[0]+"/"+rslt[1]);
for (int i = 0; i < data_size; i++){
System.out.println("corr_1d["+i+"]="+corr_1d[i]);
}
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
double [] masked_data = new double [data_size*data_size];
for (int j = 0; j < data_size; j++){
for (int i = 0; i < data_size; i++){
masked_data[i * data_size + j] = data[i * data_size + j] * enhortho_scales[i];
}
}
double [][] dbg_data = {data,masked_data};
String [] titles = {"correlation", "enhortho_correlation"};
sdfa_instance.showArrays(dbg_data, data_size, data_size, true, "getMaxXYCmEnhOrtho", titles);
if (coeff != null) System.out.println("a = "+coeff[2]+", b = "+coeff[1]+", c = "+coeff[0]);
System.out.println("xcenter="+xcenter);
if (pa_data != null) {
for (int i = 0; i < pa_data.length; i++){
System.out.println("pa_data["+i+"]={"+pa_data[i][0]+", "+pa_data[i][1]+"}");
}
}
}
return rslt;
*/
}
public double [] getMaxXYPoly( // get interpolated maximum coordinates using 2-nd degree polynomial
PolynomialApproximation pa,
......
......@@ -29,7 +29,10 @@ public class PolynomialApproximation {
}
S[2*N]+=wxn;
if (this.debugLevel>1){
System.out.println("polynomialApproximation1d() |"+i+"|: x=|"+data[i][0]+"| f(x)=|"+data[i][1]+"| (w=\t|"+data[i][2]+"|\t)");
if (data[i].length > 2)
System.out.println("polynomialApproximation1d() |"+i+"|: x=|"+data[i][0]+"| f(x)=|"+data[i][1]+"| (w=\t|"+data[i][2]+"|\t)");
else
System.out.println("polynomialApproximation1d() |"+i+"|: x=|"+data[i][0]+"| f(x)=|"+data[i][1]+"|\t)");
}
}
}
......
import java.util.ArrayList;
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
/**
**
** X3dOutput - generate x3d representation of the model
**
** Copyright (C) 2017 Elphel, Inc.
**
** -----------------------------------------------------------------------------**
**
** X3dOutput.java is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
** -----------------------------------------------------------------------------**
**
*/
// Will use 1m units
public class X3dOutput {
GeometryCorrection geometry_correction;
public ArrayList <EyesisDCT.CLTPass3d> clt_3d_passes;
public EyesisCorrectionParameters.CLTParameters clt_parameters;
public EyesisCorrectionParameters.CorrectionParameters correctionsParameters;
public int debugLevel = 1;
Document x3dDoc;
Element el_X3d;
Element el_Scene;
Element el_TopGroup;
public X3dOutput(
EyesisCorrectionParameters.CLTParameters clt_parameters,
EyesisCorrectionParameters.CorrectionParameters correctionsParameters,
GeometryCorrection geometry_correction,
ArrayList <EyesisDCT.CLTPass3d> clt_3d_passes){
this.clt_parameters = clt_parameters;
this.correctionsParameters = correctionsParameters;
this.geometry_correction = geometry_correction;
this.clt_3d_passes = clt_3d_passes;
}
// init document, bounding box, backdrop
public void generateBackground()
{
try {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
x3dDoc = docBuilder.newDocument();
} catch (ParserConfigurationException pce) {
pce.printStackTrace();
}
// root elements
el_X3d = x3dDoc.createElement("x3d");
el_X3d.setAttribute("profile","Interchange");
el_X3d.setAttribute("version","3.3");
x3dDoc.appendChild(el_X3d);
el_Scene = x3dDoc.createElement("Scene");
el_X3d.appendChild(el_Scene);
el_TopGroup = x3dDoc.createElement("Group");
double [][] bbox = getBBox();
el_TopGroup.setAttribute("class","GroupTop");
el_TopGroup.setAttribute("id", "GroupTop");
el_TopGroup.setAttribute("bboxCenter", String.format("%.3f %.3f %.3f ",bbox[0][0],bbox[0][1],bbox[0][2]));
el_TopGroup.setAttribute("bboxSize", String.format("%.3f %.3f %.3f ",bbox[1][0],bbox[1][1],bbox[1][2]));
el_Scene.appendChild(el_TopGroup);
EyesisDCT.CLTPass3d bgnd_pass = clt_3d_passes.get(0);
Element el_Bgnd = x3dDoc.createElement("Background");
el_Bgnd.setAttribute("class","Background");
el_Bgnd.setAttribute("id", "Background");
el_Bgnd.setAttribute("frontUrl", bgnd_pass.texture);
// temporarily - add same picture to all other sides. Actually - any square will work, make some
// perspective grids/ colors to simplify orientation when looking wrong way
el_Bgnd.setAttribute("backUrl", bgnd_pass.texture);
el_Bgnd.setAttribute("leftUrl", bgnd_pass.texture);
el_Bgnd.setAttribute("rightUrl", bgnd_pass.texture);
el_Bgnd.setAttribute("topUrl", bgnd_pass.texture);
el_Bgnd.setAttribute("bottomUrl", bgnd_pass.texture);
el_Scene.appendChild(el_Bgnd);
}
// close document, generate x3d file
public void generateX3D(String path)
{
try {
// write the content into xml file
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(x3dDoc);
StreamResult result = new StreamResult(new File(path));
// Output to console for testing
// StreamResult result = new StreamResult(System.out);
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
transformer.transform(source, result);
System.out.println("x3d file saved to "+path);
} catch (TransformerException tfe) {
tfe.printStackTrace();
}
}
public double [][] getBBox() // center: x,y,z, size:x,y,z
{
double depth = geometry_correction.getZFromDisparity(clt_parameters.bgnd_range);
double width = depth * geometry_correction.getFOVWidth();
double height = depth * geometry_correction.getFOVHeight();
double [][] bbox = {{0, 0, depth/2},{width,height,depth}};
return bbox;
}
}
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