Commit e2689c1b authored by Andrey Filippov's avatar Andrey Filippov

working on tile processing

parent 21c8e480
......@@ -2039,8 +2039,31 @@ public class EyesisCorrectionParameters {
public int ortho_half_length = 4; // convolve hor/vert strength by 3*(2*l+1) kernels to detect multi-tile features
public double ortho_mix = 0.5; // Fraction ovf convolved ortho in a mix with raw
public int max_clusters = 10; // Maximal number of clusters to generate for one run
public boolean correct_distortions = false; // Correct lens geometric distortions in a model (will need backdrop to be corrected too)
public boolean show_triangles = true; // Show generated triangles
public boolean avg_cluster_disp = false; // Weight-average disparity for the whole cluster
public double maxDispTriangle = 0.2; // Maximal disparity difference in a triangle face to show
// Thin ice parameters
public double tiRigidVertical = 3.0; // relative disparity rigidity in vertical direction
public double tiRigidHorizontal = 1.0; // relative disparity rigidity in horizontal direction
public double tiRigidDiagonal = 0.5; // relative disparity rigidity in diagonal direction
public double tiStrengthOffset = 0.1; // strength "floor" - subtract (limit 0) before applying
public double tiDispScale = 0.5; // divide actual (disparity*eff_Strength) by this before Math.pow and applying to T.I.
public double tiDispPow = 0.0; // apply pow to disparity (restore sign) for disparity difference pressure on ice
public double tiDispPull = .1; // tiDispPull: multiply strength*disparity difference to pull force
public double tiDispPullPreFinal= .1; // Scale tiDispPull for pre-final pass
public double tiDispPullFinal = .01; // Scale tiDispPull for final pass
public double tiBreak3 = 0.6; // TI break value of abs(d0-3d1+3d2-d3)
public double tiBreak31 = 0.1; // TI break value of (d0-3d1+3d2-d3) * (d1 - d2)
public double tiBreak21 = 0.1; // TI break value of (-d0+d1+d2-d3) * abs(d1 - d2)
public int tiBreakMode = 0; // TI break mode: 0: abs(3-rd derivative), 1: -(3-rd * 1-st), 2: -(2-nd * abs(1-st))
public double tiBreakSame = 0.5; // Amplify colinear breaks in neighbor tiles
public double tiBreakTurn = 0.125; // Amplify 90-degree turnintg breaks in neighbor tiles
public int tiIterations = 1000; // maximal number of TI iterations for each step
public int tiPrecision = 6; // iteration maximal error (1/power of 10)
public int tiNumCycles = 5; // Number of cycles break-smooth (after the first smooth)
public CLTParameters(){}
public void setProperties(String prefix,Properties properties){
......@@ -2152,7 +2175,6 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"ortho_min_hor", this.ortho_min_hor +"");
properties.setProperty(prefix+"ortho_min_vert", this.ortho_min_vert +"");
properties.setProperty(prefix+"ortho_asym", this.ortho_asym +"");
properties.setProperty(prefix+"ortho_sustain", this.ortho_sustain +"");
properties.setProperty(prefix+"ortho_run", this.ortho_run+"");
properties.setProperty(prefix+"ortho_minmax", this.ortho_minmax +"");
......@@ -2160,6 +2182,32 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"ortho_rms", this.ortho_rms +"");
properties.setProperty(prefix+"ortho_half_length",this.ortho_half_length+"");
properties.setProperty(prefix+"ortho_mix", this.ortho_mix +"");
properties.setProperty(prefix+"max_clusters", this.max_clusters+"");
properties.setProperty(prefix+"correct_distortions",this.correct_distortions+"");
properties.setProperty(prefix+"show_triangles", this.show_triangles+"");
properties.setProperty(prefix+"avg_cluster_disp", this.avg_cluster_disp+"");
properties.setProperty(prefix+"maxDispTriangle", this.maxDispTriangle +"");
properties.setProperty(prefix+"tiRigidVertical", this.tiRigidVertical +"");
properties.setProperty(prefix+"tiRigidHorizontal",this.tiRigidHorizontal +"");
properties.setProperty(prefix+"tiRigidDiagonal", this.tiRigidDiagonal +"");
properties.setProperty(prefix+"tiStrengthOffset", this.tiStrengthOffset +"");
properties.setProperty(prefix+"tiDispScale", this.tiDispScale +"");
properties.setProperty(prefix+"tiDispPow", this.tiDispPow +"");
properties.setProperty(prefix+"tiDispPull", this.tiDispPull +"");
properties.setProperty(prefix+"tiDispPullPreFinal",this.tiDispPullPreFinal +"");
properties.setProperty(prefix+"tiDispPullFinal", this.tiDispPullFinal +"");
properties.setProperty(prefix+"tiBreak3", this.tiBreak3 +"");
properties.setProperty(prefix+"tiBreak31", this.tiBreak31 +"");
properties.setProperty(prefix+"tiBreak21", this.tiBreak21 +"");
properties.setProperty(prefix+"tiBreakMode", this.tiBreakMode +"");
properties.setProperty(prefix+"tiBreakSame", this.tiBreakSame +"");
properties.setProperty(prefix+"tiBreakTurn", this.tiBreakTurn +"");
properties.setProperty(prefix+"tiIterations", this.tiIterations+"");
properties.setProperty(prefix+"tiPrecision", this.tiPrecision+"");
properties.setProperty(prefix+"tiNumCycles", this.tiNumCycles+"");
}
public void getProperties(String prefix,Properties properties){
if (properties.getProperty(prefix+"transform_size")!=null) this.transform_size=Integer.parseInt(properties.getProperty(prefix+"transform_size"));
......@@ -2266,7 +2314,6 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"ortho_min_hor")!=null) this.ortho_min_hor=Double.parseDouble(properties.getProperty(prefix+"ortho_min_hor"));
if (properties.getProperty(prefix+"ortho_min_vert")!=null) this.ortho_min_vert=Double.parseDouble(properties.getProperty(prefix+"ortho_min_vert"));
if (properties.getProperty(prefix+"ortho_asym")!=null) this.ortho_asym=Double.parseDouble(properties.getProperty(prefix+"ortho_asym"));
if (properties.getProperty(prefix+"ortho_sustain")!=null) this.ortho_sustain=Double.parseDouble(properties.getProperty(prefix+"ortho_sustain"));
if (properties.getProperty(prefix+"ortho_run")!=null) this.ortho_run=Integer.parseInt(properties.getProperty(prefix+"ortho_run"));
if (properties.getProperty(prefix+"ortho_minmax")!=null) this.ortho_minmax=Double.parseDouble(properties.getProperty(prefix+"ortho_minmax"));
......@@ -2274,6 +2321,32 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"ortho_rms")!=null) this.ortho_rms=Double.parseDouble(properties.getProperty(prefix+"ortho_rms"));
if (properties.getProperty(prefix+"ortho_half_length")!=null) this.ortho_half_length=Integer.parseInt(properties.getProperty(prefix+"ortho_half_length"));
if (properties.getProperty(prefix+"ortho_mix")!=null) this.ortho_mix=Double.parseDouble(properties.getProperty(prefix+"ortho_mix"));
if (properties.getProperty(prefix+"max_clusters")!=null) this.max_clusters=Integer.parseInt(properties.getProperty(prefix+"max_clusters"));
if (properties.getProperty(prefix+"correct_distortions")!=null) this.correct_distortions=Boolean.parseBoolean(properties.getProperty(prefix+"correct_distortions"));
if (properties.getProperty(prefix+"show_triangles")!=null) this.show_triangles=Boolean.parseBoolean(properties.getProperty(prefix+"show_triangles"));
if (properties.getProperty(prefix+"avg_cluster_disp")!=null) this.avg_cluster_disp=Boolean.parseBoolean(properties.getProperty(prefix+"avg_cluster_disp"));
if (properties.getProperty(prefix+"maxDispTriangle")!=null) this.maxDispTriangle=Double.parseDouble(properties.getProperty(prefix+"maxDispTriangle"));
if (properties.getProperty(prefix+"tiRigidVertical")!=null) this.tiRigidVertical=Double.parseDouble(properties.getProperty(prefix+"tiRigidVertical"));
if (properties.getProperty(prefix+"tiRigidHorizontal")!=null) this.tiRigidHorizontal=Double.parseDouble(properties.getProperty(prefix+"tiRigidHorizontal"));
if (properties.getProperty(prefix+"tiRigidDiagonal")!=null) this.tiRigidDiagonal=Double.parseDouble(properties.getProperty(prefix+"tiRigidDiagonal"));
if (properties.getProperty(prefix+"tiStrengthOffset")!=null) this.tiStrengthOffset=Double.parseDouble(properties.getProperty(prefix+"tiStrengthOffset"));
if (properties.getProperty(prefix+"tiDispScale")!=null) this.tiDispScale=Double.parseDouble(properties.getProperty(prefix+"tiDispScale"));
if (properties.getProperty(prefix+"tiDispPow")!=null) this.tiDispPow=Double.parseDouble(properties.getProperty(prefix+"tiDispPow"));
if (properties.getProperty(prefix+"tiDispPull")!=null) this.tiDispPull=Double.parseDouble(properties.getProperty(prefix+"tiDispPull"));
if (properties.getProperty(prefix+"tiDispPullPreFinal")!=null)this.tiDispPullPreFinal=Double.parseDouble(properties.getProperty(prefix+"tiDispPullPreFinal"));
if (properties.getProperty(prefix+"tiDispPullFinal")!=null) this.tiDispPullFinal=Double.parseDouble(properties.getProperty(prefix+"tiDispPullFinal"));
if (properties.getProperty(prefix+"tiBreak3")!=null) this.tiBreak3=Double.parseDouble(properties.getProperty(prefix+"tiBreak3"));
if (properties.getProperty(prefix+"tiBreak31")!=null) this.tiBreak31=Double.parseDouble(properties.getProperty(prefix+"tiBreak31"));
if (properties.getProperty(prefix+"tiBreak21")!=null) this.tiBreak21=Double.parseDouble(properties.getProperty(prefix+"tiBreak21"));
if (properties.getProperty(prefix+"tiBreakMode")!=null) this.tiBreakMode=Integer.parseInt(properties.getProperty(prefix+"tiBreakMode"));
if (properties.getProperty(prefix+"tiBreakSame")!=null) this.tiBreakSame=Double.parseDouble(properties.getProperty(prefix+"tiBreakSame"));
if (properties.getProperty(prefix+"tiBreakTurn")!=null) this.tiBreakTurn=Double.parseDouble(properties.getProperty(prefix+"tiBreakTurn"));
if (properties.getProperty(prefix+"tiIterations")!=null) this.tiIterations=Integer.parseInt(properties.getProperty(prefix+"tiIterations"));
if (properties.getProperty(prefix+"tiPrecision")!=null) this.tiPrecision=Integer.parseInt(properties.getProperty(prefix+"tiPrecision"));
if (properties.getProperty(prefix+"tiNumCycles")!=null) this.tiNumCycles=Integer.parseInt(properties.getProperty(prefix+"tiNumCycles"));
}
public boolean showDialog() {
......@@ -2402,9 +2475,33 @@ public class EyesisCorrectionParameters {
gd.addNumericField("Minimal maximal strength in an ortho run (max. in run >=...)", this.ortho_minmax, 3);
gd.addNumericField("Number of tiles to bridge over hor/vert gaps", this.ortho_bridge, 0);
gd.addNumericField("Maximal disparity RMS in a run to replace by average)", this.ortho_rms, 3);
gd.addNumericField("convolve hor/vert strength by 3*(2*l+1) kernels to detect multi-tile features",this.ortho_half_length, 0);
gd.addNumericField("Fraction ovf convolved ortho in a mix with raw", this.ortho_mix, 3);
gd.addNumericField("Convolve hor/vert strength by 3*(2*l+1) kernels to detect multi-tile features",this.ortho_half_length, 0);
gd.addNumericField("Fraction of convolved ortho in a mix with raw", this.ortho_mix, 3);
gd.addNumericField("Maximal number of clusters to generate for one run", this.max_clusters, 0);
gd.addCheckbox ("Correct lens geometric distortions in a model (will need backdrop to be corrected too)", this.correct_distortions);
gd.addCheckbox ("Show generated triangles", this.show_triangles);
gd.addCheckbox ("Weight-average disparity for the whole cluster ", this.avg_cluster_disp);
gd.addNumericField("Maximal disparity difference in a triangle face to show", this.maxDispTriangle, 6);
gd.addMessage ("--- Thin ice parameters ---");
gd.addNumericField("Relative disparity rigidity in vertical direction", this.tiRigidVertical, 6);
gd.addNumericField("Relative disparity rigidity in horizontal direction", this.tiRigidHorizontal, 6);
gd.addNumericField("Relative disparity rigidity in diagonal direction", this.tiRigidDiagonal, 6);
gd.addNumericField("Strength floor - subtract (limit with 0) before applying", this.tiStrengthOffset, 6);
gd.addNumericField("Divide actual disparity by this before Math.pow and applying to TI", this.tiDispScale, 6);
gd.addNumericField("Apply pow to disparity (restore sign) for disparity difference pressure on TI",this.tiDispPow, 6);
gd.addNumericField("tiDispPull: multiply strength*disparity difference to pull force", this.tiDispPull, 6);
gd.addNumericField("Scale tiDispPull for pre-final pass", this.tiDispPullPreFinal, 6);
gd.addNumericField("Scale tiDispPull for final pass", this.tiDispPullFinal, 6);
gd.addNumericField("TI break value of abs(d0-3d1+3d2-d3)", this.tiBreak3, 6);
gd.addNumericField("TI break value of (d0-3d1+3d2-d3) * (d1 - d2)", this.tiBreak31, 6);
gd.addNumericField("TI break value of (-d0+d1+d2-d3) * abs(d1 - d2)", this.tiBreak21, 6);
gd.addNumericField("TI break mode: +1: abs(3-rd derivative), +2: -(3-rd * 1-st), +4: -(2-nd * abs(1-st))", this.tiBreakMode, 0);
gd.addNumericField("Amplify colinear breaks in neighbor tiles", this.tiBreakSame, 6);
gd.addNumericField("Amplify 90-degree turnintg breaks in neighbor tiles", this.tiBreakTurn, 6);
gd.addNumericField("Maximal number of TI iterations for each step", this.tiIterations, 0);
gd.addNumericField("Iteration maximal error (1/power of 10)", this.tiPrecision, 0);
gd.addNumericField("Number of cycles break-smooth (after the first smooth)", this.tiNumCycles, 0);
WindowTools.addScrollBars(gd);
gd.showDialog();
......@@ -2526,6 +2623,33 @@ public class EyesisCorrectionParameters {
this.ortho_rms= gd.getNextNumber();
this.ortho_half_length=(int)gd.getNextNumber();
this.ortho_mix= gd.getNextNumber();
this.max_clusters= (int) gd.getNextNumber();
this.correct_distortions= gd.getNextBoolean();
this.show_triangles= gd.getNextBoolean();
this.avg_cluster_disp= gd.getNextBoolean();
this.maxDispTriangle= gd.getNextNumber();
this.tiRigidVertical= gd.getNextNumber();
this.tiRigidHorizontal= gd.getNextNumber();
this.tiRigidDiagonal= gd.getNextNumber();
this.tiStrengthOffset= gd.getNextNumber();
this.tiDispScale= gd.getNextNumber();
this.tiDispPow= gd.getNextNumber();
this.tiDispPull= gd.getNextNumber();
this.tiDispPullPreFinal= gd.getNextNumber();
this.tiDispPullFinal= gd.getNextNumber();
this.tiBreak3= gd.getNextNumber();
this.tiBreak31= gd.getNextNumber();
this.tiBreak21= gd.getNextNumber();
this.tiBreakMode= (int) gd.getNextNumber();
this.tiBreakSame= gd.getNextNumber();
this.tiBreakTurn= gd.getNextNumber();
this.tiIterations= (int) gd.getNextNumber();
this.tiPrecision= (int) gd.getNextNumber();
this.tiNumCycles= (int) gd.getNextNumber();
return true;
}
}
......
......@@ -6,7 +6,7 @@ import ij.IJ;
** GeometryCorrection - geometry correction for multiple sensors sharing the same
** lens radial distortion model
**
** Copyright (C) 2016 Elphel, Inc.
** Copyright (C) 2017 Elphel, Inc.
**
** -----------------------------------------------------------------------------**
**
......@@ -323,6 +323,33 @@ public class GeometryCorrection {
return this.pixelCorrectionHeight * 0.001 * this.pixelSize / this.focalLength;
}
public double getScaleDzDx()
{
return ( 0.001 * this.pixelSize) / this.focalLength;
}
/*
* Get real world coordinates from pixel coordinates and nominal disparity
*/
public double [] getWorldCoordinates(
double px,
double py,
double disparity,
boolean correctDistortions) // correct distortion (will need corrected background too !)
{
double pXcd = px - 0.5 * this.pixelCorrectionWidth;
double pYcd = py - 0.5 * this.pixelCorrectionHeight;
double rD = Math.sqrt(pXcd*pXcd + pYcd*pYcd)*0.001*this.pixelSize; // distorted radius in a virtual center camera
double rND2R = correctDistortions?(getRByRDist(rD/this.distortionRadius, false)): 1.0;
double pXc = pXcd * rND2R; // non-distorted coordinates relative to the (0.5 * this.pixelCorrectionWidth, 0.5 * this.pixelCorrectionHeight)
double pYc = pYcd * rND2R; // in pixels
double z = -SCENE_UNITS_SCALE * this.focalLength * this.disparityRadius / (disparity * 0.001*this.pixelSize); // "+" - near, "-" far
double x = SCENE_UNITS_SCALE * pXc * this.disparityRadius / disparity;
double y = -SCENE_UNITS_SCALE * pYc * this.disparityRadius / disparity;
double [] xyz = {x,y,z};
return xyz;
}
/*
* 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
......@@ -343,8 +370,6 @@ public class GeometryCorrection {
double [] a={this.distortionC,this.distortionB,this.distortionA,this.distortionA5,this.distortionA6,this.distortionA7,this.distortionA8};
for (int i = 0; i < numSensors; i++){
// non-distorted XY of the shifted location of the individual sensor
// double pXci = pXc + disparity * this.rXY[i][0]; // in pixels
// double pYci = pYc + disparity * this.rXY[i][1];
double pXci = pXc - disparity * this.rXY[i][0]; // in pixels
double pYci = pYc - disparity * this.rXY[i][1];
// calculate back to distorted
......
......@@ -3558,16 +3558,20 @@ public class QuadCLT {
int tilesX,
int tilesY,
Rectangle bounds){
int width = tileSize*bounds.width + 1;
int height = tileSize*bounds.height + 1;
// int width = tileSize*bounds.width + 1;
// int height = tileSize*bounds.height + 1;
int width = tileSize*bounds.width;
int height = tileSize*bounds.height;
// Adding row/column of all 0, assuming java zeroes arrays
int numSlices = imgData.length;
double [][] rslt = new double [numSlices][width*height];
int offset = (tileSize*bounds.y)*tileSize*tilesX + (tileSize*bounds.x);
// System.out.println("bounds = {.x:"+bounds.x + ", .y=" + bounds.y + ", .width=" + bounds.width + ", .height=" + bounds.height+ ", numSlices="+numSlices);
// System.out.println("offset = " + offset+ " tileSize = "+tileSize);
for (int y = 0; y < (height - 1); y ++){
for (int x = 0; x < width-1; x ++){
// for (int y = 0; y < (height - 1); y ++){
// for (int x = 0; x < width-1; x ++){
for (int y = 0; y < height; y ++){
for (int x = 0; x < width; x ++){
int indx = width * y + x;
int indx_in = indx + offset;
for (int i = 0; i < numSlices; i++) {
......@@ -4732,13 +4736,9 @@ public class QuadCLT {
tp.clt_3d_passes);
x3dOutput.generateBackground();
String path= correctionsParameters.selectX3dDirectory(
String x3d_path= correctionsParameters.selectX3dDirectory(
true, // smart,
true); //newAllowed, // save
if (path != null){
path+=Prefs.getFileSeparator()+name+".x3d";
x3dOutput.generateX3D(path);
}
// testing 2-nd pass
tp.secondPassSetup( // prepare tile tasks for the second pass based on the previous one(s)
......@@ -4751,6 +4751,7 @@ public class QuadCLT {
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
ImageDtt.DISPARITY_INDEX_CM, // index of disparity value in disparity_map == 2 (0,2 or 4)
geometryCorrection,
threadsMax, // maximal number of threads to launch
updateStatus,
debugLevel);
......@@ -4770,12 +4771,13 @@ public class QuadCLT {
}
int scan_limit = 10;
for (int scanIndex = 1; (scanIndex < tp.clt_3d_passes.size()) && (scanIndex < scan_limit); scanIndex++){ // just temporary limiting
// int scan_limit = 10;
for (int scanIndex = 1; (scanIndex < tp.clt_3d_passes.size()) && (scanIndex < clt_parameters.max_clusters); scanIndex++){ // just temporary limiting
if (debugLevel > -1){
System.out.println("Generating cluster images, hardwired limit of "+scan_limit+" largest, scan #"+scanIndex);
System.out.println("Generating cluster images (limit is set to "+clt_parameters.max_clusters+") largest, scan #"+scanIndex);
}
ImagePlus cluster_image = getPassImage( // get image form a single pass
// ImagePlus cluster_image = getPassImage( // get image form a single pass
String texturePath = getPassImage( // get image form a single pass
clt_parameters,
colorProcParameters,
rgbParameters,
......@@ -4784,15 +4786,126 @@ public class QuadCLT {
threadsMax, // maximal number of threads to launch
updateStatus,
debugLevel);
TileProcessor.CLTPass3d scan = tp.clt_3d_passes.get(scanIndex);
// TODO: use new updated disparity, for now just what was forced for the picture
double [] scan_disparity = new double [tp.tilesX * tp.tilesY];
int indx = 0;
for (int ty = 0; ty < tp.tilesY; ty ++) for (int tx = 0; tx < tp.tilesX; tx ++){
scan_disparity[indx++] = scan.disparity[ty][tx];
}
if (clt_parameters.avg_cluster_disp){
double sw = 0.0, sdw = 0.0;
for (int i = 0; i< scan_disparity.length; i++){
if (scan.selected[i] && !scan.border_tiles[i]){
double w = scan.disparity_map[ImageDtt.DISPARITY_STRENGTH_INDEX][i];
sw +=w;
sdw += scan_disparity[i]*w;
}
}
sdw/=sw;
for (int i = 0; i< scan_disparity.length; i++){
scan_disparity[i] = sdw;
}
}
generateClusterX3d(
x3dOutput,
texturePath,
scan.bounds,
scan.selected,
scan_disparity, // scan.disparity_map[ImageDtt.DISPARITY_INDEX_CM],
clt_parameters.transform_size,
clt_parameters.correct_distortions, // requires backdrop image to be corrected also
(scanIndex <2) && clt_parameters.show_triangles,
clt_parameters.bgnd_range,
clt_parameters.other_range,
clt_parameters.maxDispTriangle);
}
// now generate and save texture files (start with full, later use bounding rectangle?)
if (x3d_path != null){
x3d_path+=Prefs.getFileSeparator()+name+".x3d";
x3dOutput.generateX3D(x3d_path);
}
return imp_bgnd; // relative (to x3d directory) path - (String) imp_bgnd.getProperty("name");
}
public void generateClusterX3d(
X3dOutput x3dOutput,
String texturePath,
Rectangle bounds,
boolean [] selected,
double [] disparity,
int tile_size,
boolean correctDistortions, // requires backdrop image to be corrected also
boolean show_triangles,
double min_disparity,
double max_disparity,
double maxDispTriangle
)
{
int [][] indices = tp.getCoordIndices( // starting with 0, -1 - not selected
bounds,
selected);
double [][] texCoord = tp.getTexCoords( // get texture coordinates for indices
indices);
double [][] worldXYZ = tp.getCoords( // get world XYZ in meters for indices
disparity,
min_disparity,
max_disparity,
bounds,
indices,
tile_size,
correctDistortions, // requires backdrop image to be corrected also
this.geometryCorrection);
double [] indexedDisparity = tp.getIndexedDisparities( // get disparity for each index
disparity,
min_disparity,
max_disparity,
bounds,
indices,
tile_size);
int [][] triangles = tp.triangulateCluster(
indices);
triangles = tp.filterTriangles(
triangles,
indexedDisparity, // disparities per vertex index
maxDispTriangle); // maximal disparity difference in a triangle
if (show_triangles) {
tp.testTriangles(
texturePath,
bounds,
selected,
disparity,
tile_size,
indices,
triangles);
}
x3dOutput.addCluster(
texturePath,
texCoord,
worldXYZ,
triangles);
}
public ImagePlus getBackgroundImage(
EyesisCorrectionParameters.CLTParameters clt_parameters,
EyesisCorrectionParameters.ColorProcParameters colorProcParameters,
......@@ -4936,7 +5049,8 @@ public class QuadCLT {
public ImagePlus getPassImage( // get image form a single pass
// public ImagePlus getPassImage( // get image form a single pass
public String getPassImage( // get image form a single pass, return relative path for x3d
EyesisCorrectionParameters.CLTParameters clt_parameters,
EyesisCorrectionParameters.ColorProcParameters colorProcParameters,
EyesisCorrectionParameters.RGBParameters rgbParameters,
......@@ -5011,8 +5125,10 @@ public class QuadCLT {
int width = resize ? (clt_parameters.transform_size * scan.bounds.width + 1): (clt_parameters.transform_size * tp.tilesX);
int height = resize ? (clt_parameters.transform_size * scan.bounds.height + 1): (clt_parameters.transform_size * tp.tilesY);
// int width = resize ? (clt_parameters.transform_size * scan.bounds.width + 1): (clt_parameters.transform_size * tp.tilesX);
// int height = resize ? (clt_parameters.transform_size * scan.bounds.height + 1): (clt_parameters.transform_size * tp.tilesY);
int width = resize ? (clt_parameters.transform_size * scan.bounds.width): (clt_parameters.transform_size * tp.tilesX);
int height = resize ? (clt_parameters.transform_size * scan.bounds.height): (clt_parameters.transform_size * tp.tilesY);
// sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
// sdfa_instance.showArrays(texture_rgbx, width, height, true, "texture_rgbx");
......@@ -5044,7 +5160,7 @@ public class QuadCLT {
correctionsParameters.png,
clt_parameters.show_textures,
-1); // jpegQuality){// <0 - keep current, 0 - force Tiff, >0 use for JPEG
return imp_texture_cluster;
return imp_texture_cluster.getTitle()+".png"; // imp_texture_cluster;
}
......
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Arrays;
/**
**
** TileProcessor - Process tiles resulted from quad image sets
**
** Copyright (C) 2016 Elphel, Inc.
** Copyright (C) 2017 Elphel, Inc.
**
** -----------------------------------------------------------------------------**
**
** EyesisDCT.java is free software: you can redistribute it and/or modify
** TileProcessor.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.
......@@ -26,6 +22,10 @@ import java.util.Arrays;
**
*/
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Arrays;
public class TileProcessor {
public ArrayList <CLTPass3d> clt_3d_passes = null;
public int tilesX;
......@@ -492,7 +492,7 @@ public class TileProcessor {
prohibit);
// invert selection again (restore)
for (int i =0; i< tiles.length; i++) tiles[i] = !tiles[i];
// for (int i =0; i< tiles.length; i++) tiles[i] = !tiles[i] || orig_tiles[i]; // and or with original (why result does not have some of original - only with prohibit?
// for (int i =0; i< tiles.length; i++) tiles[i] = !tiles[i] || orig_tiles[i]; // and or with original (why result does not have some of original - only with prohibit?
if (prohibit != null) { // second pass w/o prohoibit, then end results
growTiles(
depth, // grow tile selection by 1 over non-background tiles 1: 4 directions, 2 - 8 directions, 3 - 8 by 1, 4 by 1 more
......@@ -591,7 +591,7 @@ public class TileProcessor {
weights_src, // or null
grown_min, // minimal number of pixels
min_weight); // minimal total weight of the cluster
/*** showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
/*** showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
String [] titles = {"orig","grown","combined"};
double [][] dbg_img = new double [titles.length][tiles.length];
for (int i = 0; i<tiles.length; i++){
......@@ -603,7 +603,7 @@ public class TileProcessor {
dbg_img[2][i] = tiles[i]? 1:-1;
}
sdfa_instance.showArrays(dbg_img, tilesX, tilesY, true, "bgnd_nonbgnd",titles);
***/
***/
for (int i = 0; i< tiles.length; i++) tiles[i] &= grown_by_1[i];
}
......@@ -750,7 +750,7 @@ public class TileProcessor {
}
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
// final double [][][] image_data, // first index - number of image in a quad
EyesisCorrectionParameters.CLTParameters clt_parameters,
// disparity range - differences from
double disparity_far, //
......@@ -759,6 +759,7 @@ public class TileProcessor {
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)
GeometryCorrection geometryCorrection,
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
final int debugLevel)
......@@ -862,7 +863,7 @@ public class TileProcessor {
disp = this_vert_disparity[indx];
used_vert[indx] = true;
}
// this_disparity[indx] = disp; // /clt_parameters.corr_magic_scale + scan_prev.disparity[i][j];
// this_disparity[indx] = disp; // /clt_parameters.corr_magic_scale + scan_prev.disparity[i][j];
}
}
}
......@@ -885,7 +886,7 @@ public class TileProcessor {
// if (clt_parameters.ortho_bridge > 0) {
// if (clt_parameters.ortho_bridge > 0) {
// bridge over small gaps in horizontal/vertical features
int numHorBridged = bridgeFgndOrthoGap(
clt_parameters,
......@@ -925,8 +926,8 @@ public class TileProcessor {
}
}
} else if (this_disparity[i] > disparity_near){
// if ((this_strength[i] > this_maybe) && ! bg_tiles[i]){ // can not be farther if selected for near?
// if ((this_strength[i] > this_maybe) || used_hor[i] || used_vert[i] ){ // can not be farther if selected for near?
// if ((this_strength[i] > this_maybe) && ! bg_tiles[i]){ // can not be farther if selected for near?
// if ((this_strength[i] > this_maybe) || used_hor[i] || used_vert[i] ){ // can not be farther if selected for near?
if ((this_strength[i] > this_maybe)){ // can not be farther if selected for near?
near_tiles[i] = true;
}
......@@ -1029,10 +1030,221 @@ public class TileProcessor {
}
sdfa_instance.showArrays(dbg_img, tilesX, tilesY, true, "bgnd_nonbgnd",titles);
}
//clt_parameters.transform_size;
DisparityProcessor dp = new DisparityProcessor(this, clt_parameters.transform_size * geometryCorrection.getScaleDzDx());
boolean [] grown = these_tiles.clone();
growTiles(
1, // grow tile selection by 1 over non-background tiles 1: 4 directions, 2 - 8 directions, 3 - 8 by 1, 4 by 1 more
grown, // boolean [] tiles,
null); // boolean [] prohibit)
boolean [] border = grown.clone();
for (int i = 0; i < border.length; i++) border[i] &= !these_tiles[i];
int [] neighbors = dp.getNeighbors( // creates neighbors mask from bitmask
these_tiles, // grown, // these_tiles, // boolean [] selected,
tilesX);
// int [] neighbors_orig = neighbors.clone();
double [] dbg_neib = dp.dbgShowNeighbors(
these_tiles, // grown, // these_tiles,
neighbors, // _orig, // int [] neighbors,
clt_parameters.transform_size, // int tile_size,
-1.0, // double bgnd,
1.0); // double fgnd)
double [] new_disparity = this_disparity.clone();
double [][]dbgDeriv = new double [2][]; // [these_tiles.length];
// sdfa_instance.showArrays(dbg_neib,tilesX*clt_parameters.transform_size, tilesY*clt_parameters.transform_size,"neighbors");
dp.smoothDisparity(
clt_parameters.tiDispPull, // final double dispPull, // clt_parameters.tiDispPull or 0.0
3, // final int mask, // 1 - work on internal elements, 2 - on border elements, 3 - both (internal first);
clt_parameters.tiIterations, // final int num_passes,
Math.pow(10.0, -clt_parameters.tiPrecision), // final double maxDiff, // maximal change in any of the disparity values
neighbors, // final int [] neighbors, // +1 - up (N), +2 - up-right - NE, ... +0x80 - NW
new_disparity, // final double [] disparity, // current disparity value
this_disparity, // final double [] measured_disparity, // measured disparity
this_strength, // final double [] strength,
this_hor_disparity, // final double hor_disparity, // not yet used
hor_strength_conv, // final double hor_strength, // not yet used
these_tiles, // grown, // these_tiles, // final boolean [] selected,
border, // final boolean [] border,
clt_parameters,
// dbgDeriv, // final double [][] dbgDeriv, //double [2][len] or null;
threadsMax, // maximal number of threads to launch
debugLevel);
double [] measured_disparity = dp.dbgRescaleToPixels(
this_disparity,
clt_parameters.transform_size); // int tile_size)
// break once
double [][] stresses = new double [clt_parameters.tiNumCycles + 1][];
double [][] neibs_broken = new double [clt_parameters.tiNumCycles][];
double [][] smooth_disparities = new double [clt_parameters.tiNumCycles + 1][];
smooth_disparities[0] = dp.dbgRescaleToPixels(
new_disparity,
clt_parameters.transform_size);
double break012 = (clt_parameters.tiBreakMode ==0)? clt_parameters.tiBreak3 : ((clt_parameters.tiBreakMode == 1)? clt_parameters.tiBreak31 : clt_parameters.tiBreak21);
for (int numCycle = 0; numCycle < clt_parameters.tiNumCycles; numCycle++) { // = 5; // Number of cycles break-smooth (after the first smooth)
double breakScale = 1.0;
/*
if (numCycle >= (clt_parameters.tiNumCycles -3)) {
breakScale = 0.7;
if (numCycle >= (clt_parameters.tiNumCycles -2)) {
breakScale = 0.5;
}
}
*/
if ((clt_parameters.tiBreakMode & 1) != 0) {
dp.breakDisparity( // break using derivatives
clt_parameters.tiBreak3 * breakScale, // clt_parameters.tiBreak, // final double break4, // clt_parameters.tiBreak/0 allow disconnecting from neighbors (fg/bg)
0, // mode, // 0: 3-rd derivative, 1: - third * first (compare positive threshold only), 2: second by abs(first) (compare positive threshold only)
neighbors, // final int [] neighbors, // UPDATED +1 - up (N), +2 - up-right - NE, ... +0x80 - NW
new_disparity, // final double [] disparity, // current disparity value
these_tiles, // final boolean [] selected,
true, // final boolean extend_flat, // if the tile is on the hor/vert edge, assume same disparity on the other side
clt_parameters.tiBreakSame, // final double k_same,
clt_parameters.tiBreakTurn, // final double k_turn,
clt_parameters,
dbgDeriv, // final double [][] dbgDeriv, //double [2][len] or null;
threadsMax, // maximal number of threads to launch
debugLevel);
}
if ((clt_parameters.tiBreakMode & 2) != 0) {
dp.breakDisparity( // break using derivatives
clt_parameters.tiBreak31 * breakScale, // clt_parameters.tiBreak, // final double break4, // clt_parameters.tiBreak/0 allow disconnecting from neighbors (fg/bg)
1, // mode, // 0: 3-rd derivative, 1: - third * first (compare positive threshold only), 2: second by abs(first) (compare positive threshold only)
neighbors, // final int [] neighbors, // UPDATED +1 - up (N), +2 - up-right - NE, ... +0x80 - NW
new_disparity, // final double [] disparity, // current disparity value
these_tiles, // final boolean [] selected,
true, // final boolean extend_flat, // if the tile is on the hor/vert edge, assume same disparity on the other side
clt_parameters.tiBreakSame, // final double k_same,
clt_parameters.tiBreakTurn, // final double k_turn,
clt_parameters,
dbgDeriv, // final double [][] dbgDeriv, //double [2][len] or null;
threadsMax, // maximal number of threads to launch
debugLevel);
}
if ((clt_parameters.tiBreakMode & 4) != 0) {
dp.breakDisparity( // break using derivatives
clt_parameters.tiBreak21 * breakScale, // clt_parameters.tiBreak, // final double break4, // clt_parameters.tiBreak/0 allow disconnecting from neighbors (fg/bg)
2, // mode, // 0: 3-rd derivative, 1: - third * first (compare positive threshold only), 2: second by abs(first) (compare positive threshold only)
neighbors, // final int [] neighbors, // UPDATED +1 - up (N), +2 - up-right - NE, ... +0x80 - NW
new_disparity, // final double [] disparity, // current disparity value
these_tiles, // final boolean [] selected,
true, // final boolean extend_flat, // if the tile is on the hor/vert edge, assume same disparity on the other side
clt_parameters.tiBreakSame, // final double k_same,
clt_parameters.tiBreakTurn, // final double k_turn,
clt_parameters,
dbgDeriv, // final double [][] dbgDeriv, //double [2][len] or null;
threadsMax, // maximal number of threads to launch
debugLevel);
}
stresses[numCycle] = dp.dbgShowStress(
dbgDeriv, // double [][] stress,
clt_parameters.transform_size); // int tile_size)
neibs_broken[numCycle] = dp.dbgShowNeighbors(
these_tiles, // grown, // these_tiles,
neighbors, // _orig, // int [] neighbors,
clt_parameters.transform_size, // int tile_size,
-1.0, // double bgnd,
1.0); // double fgnd)
// more smoothing
double disp_pull = clt_parameters.tiDispPull;
if (numCycle >= (clt_parameters.tiNumCycles -2)) {
disp_pull = 0.1 * clt_parameters.tiDispPull;
if (numCycle >= (clt_parameters.tiNumCycles -1)) {
disp_pull = 0.01 * clt_parameters.tiDispPull;
}
}
dp.smoothDisparity(
disp_pull, // clt_parameters.tiDispPull, // final double dispPull, // clt_parameters.tiDispPull or 0.0
3, // final int mask, // 1 - work on internal elements, 2 - on border elements, 3 - both (internal first);
clt_parameters.tiIterations, // final int num_passes,
Math.pow(10.0, -clt_parameters.tiPrecision), // final double maxDiff, // maximal change in any of the disparity values
neighbors, // final int [] neighbors, // +1 - up (N), +2 - up-right - NE, ... +0x80 - NW
new_disparity, // final double [] disparity, // current disparity value
this_disparity, // final double [] measured_disparity, // measured disparity
this_strength, // final double [] strength,
this_hor_disparity, // final double hor_disparity, // not yet used
hor_strength_conv, // final double hor_strength, // not yet used
these_tiles, // grown, // these_tiles, // final boolean [] selected,
border, // final boolean [] border,
clt_parameters,
threadsMax, // maximal number of threads to launch
debugLevel);
smooth_disparities[numCycle+1] = dp.dbgRescaleToPixels(
new_disparity,
clt_parameters.transform_size);
}
// Just calculate stress, do not actually break (after last smoothing)
dp.breakDisparity(
0.0, // final double break4, // clt_parameters.tiBreak/0 allow disconnecting from neighbors (fg/bg)
0, // clt_parameters.tiBreakMode, // mode, // 0: 3-rd derivative, 1: - third * first (compare positive threshold only), 2: second by abs(first) (compare positive threshold only)
neighbors, // final int [] neighbors, // UPDATED +1 - up (N), +2 - up-right - NE, ... +0x80 - NW
new_disparity, // final double [] disparity, // current disparity value
these_tiles, // final boolean [] selected,
true, // final boolean extend_flat, // if the tile is on the hor/vert edge, assume same disparity on the other side
clt_parameters.tiBreakSame, // final double k_same,
clt_parameters.tiBreakTurn, // final double k_turn,
clt_parameters,
dbgDeriv, // final double [][] dbgDeriv, //double [2][len] or null;
threadsMax, // maximal number of threads to launch
debugLevel);
stresses[clt_parameters.tiNumCycles] = dp.dbgShowStress(
dbgDeriv, // double [][] stress,
clt_parameters.transform_size); // int tile_size)
// String [] titles0 = {"neib", "neib_broken", "stress", "stress1", "disp-measured", "disp-result","disp-result1"};
int numImages = 2 + 3*clt_parameters.tiNumCycles+2;
String [] titles_all = new String[numImages];
double [][] dbg_img = new double[numImages][];
int indx = 0;
titles_all[indx] = "neib";
dbg_img[indx++]= dbg_neib;
for (int i = 0; i < neibs_broken.length; i++){
titles_all[indx] = "neib_"+i;
dbg_img[indx++]= neibs_broken[i];
}
for (int i = 0; i < stresses.length; i++){
titles_all[indx] = "stress_"+i;
dbg_img[indx++]= stresses[i];
}
titles_all[indx] = "disp_meas";
dbg_img[indx++]= measured_disparity;
for (int i = 0; i < smooth_disparities.length; i++){
titles_all[indx] = "disp_"+i;
dbg_img[indx++]= smooth_disparities[i];
}
// double [][] dbg_img = {dbg_neib, dbg_neib_broken, stress, stress1, measured_disparity, smooth_disparity,smooth_disparity1};
// sdfa_instance.showArrays(dbg_neib,tilesX*clt_parameters.transform_size, tilesY*clt_parameters.transform_size,"neighbors");
sdfa_instance.showArrays(dbg_img, tilesX*clt_parameters.transform_size, tilesY*clt_parameters.transform_size,
true, "neighbors", titles_all);
//************************************************
int numScans = createTileTasks(
50, // int maxClusters,
0, // int minClusterArea,
this_disparity, // [] disparity_in, masked ok too
new_disparity, // this_disparity, // [] disparity_in, masked ok too
this_strength, // double [] strength_in,
0.0, // double minStrength,
enum_clusters, // int [] clusters_in,
......@@ -1075,7 +1287,7 @@ public class TileProcessor {
int rm = tilesX - (vert? 1:0);
int bm = tilesY - (vert? 0:1);
int gap_2 = clt_parameters.ortho_bridge + 2;
// boolean [] used_ortho_original = used_ortho.clone();
// boolean [] used_ortho_original = used_ortho.clone();
if (clt_parameters.ortho_bridge > 0) {
for (int ty = 0; ty < bm; ty++){
for (int tx = 0; tx < rm; tx++){
......@@ -1306,4 +1518,287 @@ public class TileProcessor {
return rslt;
}
public int [][] getCoordIndices( // starting with 0, -1 - not selected
Rectangle bounds,
boolean [] selected
)
{
int [][] indices = new int [bounds.height][bounds.width];
int indx = 0;
for (int y = 0; y < bounds.height; y++) {
for (int x = 0; x < bounds.width; x++){
if (selected[this.tilesX * (bounds.y + y) + (bounds.x + x)]){
indices[y][x] = indx++;
} else {
indices[y][x] = -1;
}
}
}
return indices;
}
public double [][] getTexCoords( // get texture coordinates for indices
int [][] indices)
{
int maxIndex = -1;
int height = indices.length;
int width = indices[0].length;
outer_label:{
for (int y = height - 1 ; y >= 0; y--) {
for (int x = width - 1; x >= 0; x--){
if (indices[y][x] >=0){
maxIndex = indices[y][x];
break outer_label;
}
}
}
}
double [][] textureCoordinate = new double [maxIndex+1][2];
int indx = 0;
for (int y = 0; indx <= maxIndex; y++) {
for (int x = 0; (x < width) && (indx <= maxIndex); x++){
if (indices[y][x] >=0){
textureCoordinate[indx][0] = (x + 0.5)/width;
textureCoordinate[indx][1] = (height - y - 0.5) / height; // y is up
indx ++;
}
}
}
return textureCoordinate;
}
public double [] getIndexedDisparities( // get disparity for each index
double [] disparity,
double min_disparity,
double max_disparity,
Rectangle bounds,
int [][] indices,
int tile_size)
{
// int height = indices.length;
int width = indices[0].length;
int maxIndex = getMaxIndex(indices);
double [] indexedDisparity = new double [maxIndex+1];
int indx = 0;
for (int y = 0; indx <= maxIndex; y++) {
for (int x = 0; (x < width) && (indx <= maxIndex); x++){
if (indices[y][x] >=0){
// center coordinates for 8*8 tile is [3.5,3.5]
double disp = disparity[(bounds.y + y) * tilesX + (bounds.x + x)];
if (disp < min_disparity) disp = min_disparity;
else if (disp > max_disparity) disp = max_disparity;
indexedDisparity[indx] =disp;
indx ++;
}
}
}
return indexedDisparity;
}
public double [][] getCoords( // get world XYZ in meters for indices
double [] disparity,
double min_disparity,
double max_disparity,
Rectangle bounds,
int [][] indices,
int tile_size,
boolean correctDistortions, // requires backdrop image to be corrected also
GeometryCorrection geometryCorrection)
{
// int height = indices.length;
int width = indices[0].length;
int maxIndex = getMaxIndex(indices);
double [][] coordinate = new double [maxIndex+1][];
int indx = 0;
for (int y = 0; indx <= maxIndex; y++) {
for (int x = 0; (x < width) && (indx <= maxIndex); x++){
if (indices[y][x] >=0){
// center coordinates for 8*8 tile is [3.5,3.5]
double px = (bounds.x + x + 0.5) * tile_size - 0.5;
double py = (bounds.y + y + 0.5) * tile_size - 0.5;
double disp = disparity[(bounds.y + y) * tilesX + (bounds.x + x)];
if (disp < min_disparity) disp = min_disparity;
else if (disp > max_disparity) disp = max_disparity;
coordinate[indx] = geometryCorrection.getWorldCoordinates(
px,
py,
disp,
correctDistortions);
indx ++;
}
}
}
return coordinate;
}
int getMaxIndex(int [][] indices)
{
int height = indices.length;
int width = indices[0].length;
for (int y = height - 1 ; y >= 0; y--) {
for (int x = width - 1; x >= 0; x--){
if (indices[y][x] >= 0){
return indices[y][x];
}
}
}
return -1;
}
public int [][] filterTriangles(
int [][] triangles,
double [] disparity, // disparities per vertex index
double maxDispDiff) // maximal disparity difference in a triangle
{
class Triangle {
int [] points = new int [3];
Triangle (int i1, int i2, int i3){
points[0] = i1;
points[1] = i2;
points[2] = i3;
}
}
ArrayList<Triangle> triList = new ArrayList<Triangle>();
for (int i = 0; i < triangles.length; i++){
loop:{
for (int j = 0; j < 3; j++){
int j1 = (j + 1) % 3;
if (Math.abs(disparity[triangles[i][j]] - disparity[triangles[i][j1]]) > maxDispDiff) break loop;
}
triList.add(new Triangle(
triangles[i][0],
triangles[i][1],
triangles[i][2]));
}
}
int [][] filteredTriangles = new int [triList.size()][3];
for (int i = 0; i < filteredTriangles.length; i++){
filteredTriangles[i] = triList.get(i).points;
}
return filteredTriangles;
}
public int [][] triangulateCluster(
int [][] indices)
{
int height = indices.length;
int width = indices[0].length;
// int [][] ind = new int [height][];
// for (int i = 0; i < width; i++) ind[i] = indices[i].clone();
class Triangle {
int [] points = new int [3];
Triangle (int i1, int i2, int i3){
points[0] = i1;
points[1] = i2;
points[2] = i3;
}
}
ArrayList<Triangle> triList = new ArrayList<Triangle>();
for (int y = 0; y < (height - 1); y++){
for (int x = 0; x < width; x++){
if (indices[y][x] >= 0){
if ((x > 0) && (indices[y + 1][x - 1] >= 0) && (indices[y + 1][x] >= 0)){
triList.add(new Triangle(
indices[y][x],
indices[y + 1][x],
indices[y + 1][x - 1]));
}
if (x < (width - 1)) {
if (indices[y + 1][x] >= 0){
if (indices[y][x + 1] >= 0){
triList.add(new Triangle(
indices[y][x],
indices[y][x + 1],
indices[y + 1][x]));
} else if (indices[y + 1][x + 1] >= 0){
triList.add(new Triangle(
indices[y][x],
indices[y + 1][x + 1],
indices[y + 1][x]));
}
} else if ((indices[y][x + 1] >= 0) && (indices[y + 1][x + 1] >= 0)) {
triList.add(new Triangle(
indices[y][x],
indices[y][x + 1],
indices[y + 1][x + 1]));
}
}
}
}
}
int [][] triangles = new int [triList.size()][3];
for (int i = 0; i < triangles.length; i++){
triangles[i] = triList.get(i).points;
}
return triangles;
}
int iSign (int a) {return (a > 0) ? 1 : ((a < 0)? -1 : 0);}
public void testTriangles(
String texturePath,
Rectangle bounds,
boolean [] selected,
double [] disparity,
int tile_size,
int [][] indices,
int [][] triangles)
{
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays();
String [] titles = {"disparity","triangles"};
double [][] dbg_img = new double [titles.length][tilesX*tilesY*tile_size*tile_size];
for (int i = 0; i < selected.length; i++ ){
double d = selected[i]?disparity[i]:Double.NaN;
int y = i / tilesX;
int x = i % tilesX;
for (int dy = 0; dy <tile_size; dy ++){
for (int dx = 0; dx <tile_size; dx ++){
dbg_img[0][(y * tile_size + dy)*(tile_size*tilesX) + (x * tile_size + dx)] = d;
}
}
if (selected[i]) dbg_img[0][i] = disparity[i];
else dbg_img[0][i] = Double.NaN;
}
int maxIndex = getMaxIndex(indices);
int [][] pxy = new int [maxIndex+1][2];
int height = indices.length;
int width = indices[0].length;
for (int y = 0; y < height; y++){
for (int x = 0; x < width; x++){
if (indices[y][x] >= 0){
pxy[indices[y][x]][0] = (bounds.x + x)*tile_size + (tile_size/2);
pxy[indices[y][x]][1] = (bounds.y + y)*tile_size + (tile_size/2);
}
}
}
for (int i = 0; i < triangles.length; i++ ){
for (int side = 0; side < triangles[i].length; side++){
int [] pntIndx = {
triangles[i][side],
(side == (triangles[i].length -1)? triangles[i][0]:triangles[i][side+1])};
int dx = iSign(pxy[pntIndx[1]][0] - pxy[pntIndx[0]][0]);
int dy = iSign(pxy[pntIndx[1]][1] - pxy[pntIndx[0]][1]);
for (int j = 0; j < tile_size; j++){
int x = pxy[pntIndx[0]][0] + dx*j;
int y = pxy[pntIndx[0]][1] + dy*j;
// int indx = y * tile_size * tilesX + x;
// if (indx < dbg_img[1].length) {
dbg_img[1][y * tile_size * tilesX + x] = 10.0; //1711748
// } else {
// indx += 0;
// }
}
}
}
sdfa_instance.showArrays(dbg_img,
tilesX * tile_size,
tilesY * tile_size,
true,
"triangles-"+texturePath,
titles);
}
}
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;
/**
**
......@@ -38,6 +22,23 @@ import org.w3c.dom.Element;
** -----------------------------------------------------------------------------**
**
*/
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;
// Will use 1m units
public class X3dOutput {
......@@ -50,6 +51,7 @@ public class X3dOutput {
Element el_X3d;
Element el_Scene;
Element el_TopGroup;
public int max_line_length = 0; // 100; // 0 - no limit
public X3dOutput(
EyesisCorrectionParameters.CLTParameters clt_parameters,
......@@ -106,6 +108,87 @@ public class X3dOutput {
el_Bgnd.setAttribute("bottomUrl", bgnd_pass.texture);
el_Scene.appendChild(el_Bgnd);
}
public void addCluster(
String url,
double [][] texCoord,
double [][] coordinate,
int [][] triangles)
{
// public int max_line_length = 100; // 0 - no limit
int linepos = 0;
StringBuffer sb_coord_index = new StringBuffer();
for (int i = 0; i < triangles.length; i++){
if ((max_line_length > 0) && ((sb_coord_index.length()-linepos) >= max_line_length)){
sb_coord_index.append("\n");
linepos = 0;
} else if ((linepos > 0) || ((max_line_length == 0) && (sb_coord_index.length() > 0))){
sb_coord_index.append(" ");
}
// sb_coord_index.append(triangles[i][0]+" "+triangles[i][1]+" "+triangles[i][2]+" -1");
sb_coord_index.append(triangles[i][2]+" "+triangles[i][1]+" "+triangles[i][0]+" -1");
}
StringBuffer sb_coords = new StringBuffer();
linepos = 0;
for (int i = 0; i < coordinate.length; i++){
if ((max_line_length >0) && ((sb_coords.length()-linepos) >= max_line_length)){
sb_coords.append("\n");
linepos = 0;
} else if ((linepos > 0) || ((max_line_length == 0) && (sb_coords.length() > 0))){
sb_coords.append(" ");
}
sb_coords.append(String.format("%.3f %.3f %.3f", coordinate[i][0], coordinate[i][1], coordinate[i][2]));
}
StringBuffer sb_tex_coords = new StringBuffer();
linepos = 0;
for (int i = 0; i < texCoord.length; i++){
if ((max_line_length >0) && ((sb_tex_coords.length()-linepos) >= max_line_length)){
sb_tex_coords.append("\n");
linepos = 0;
} else if ((linepos > 0) || ((max_line_length == 0) && (sb_tex_coords.length() > 0))){
sb_tex_coords.append(" ");
}
sb_tex_coords.append(String.format("%.4f %.4f", texCoord[i][0], texCoord[i][1]));
}
String sindex = sb_coord_index.toString(); // for both coordIndex and texCoordIndex
String scoord = sb_coords.toString();
String stcoord = sb_tex_coords.toString();
Element el_shape = x3dDoc.createElement("Shape");
el_Scene.appendChild(el_shape);
Element el_appearance = x3dDoc.createElement("Appearance");
el_shape.appendChild(el_appearance);
Element el_material = x3dDoc.createElement("Material");
el_appearance.appendChild(el_material);
el_material.setAttribute("diffuseColor", "0.376471 0.5 0.376471");
Element el_imageTexture = x3dDoc.createElement("ImageTexture");
el_imageTexture.setAttribute("url",url);
el_appearance.appendChild(el_imageTexture);
Element el_IFC = x3dDoc.createElement("IndexedFaceSet");
el_IFC.setAttribute("coordIndex", sindex); // can it be reused?
el_IFC.setAttribute("texCoordIndex", sindex);
el_shape.appendChild(el_IFC);
Element el_coordinate = x3dDoc.createElement("Coordinate");
el_coordinate.setAttribute("point", scoord);
el_IFC.appendChild(el_coordinate);
Element el_texCoordinate = x3dDoc.createElement("TextureCoordinate");
el_texCoordinate.setAttribute("point", stcoord);
el_IFC.appendChild(el_texCoordinate);
}
// close document, generate x3d file
public void generateX3D(String path)
{
......@@ -133,43 +216,7 @@ public class X3dOutput {
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}};
double [][] bbox = {{0, 0, -depth/2},{width,height,depth}};
return bbox;
}
}
/*
An IndexedFaceSet geometry node creates geometry out of faces
texCoord and texCoordIndex - specify texture pieces
Shape {
appearance Appearance { . . . }
geometry IndexedFaceSet {
coord Coordinate { . . . }
coordIndex [ . . . ]
texCoord TextureCoordinate { . . . }
texCoordIndex [ . . . ]
}
}
<IndexedFaceSet coordIndex="0 1 2 -1 0 2 3 -1 ..." texCoordIndex="0 1 2 -1 0 2 3 -1 ...">
<Coordinate point="-37.500000 4.000000 -46.450000 .../>
<TextureCoordinate point="-37.500000 4.000000 -46.450000 .../>
</IndexedFaceSet>
<Shape DEF='Back'>
<IndexedFaceSet coordIndex='7 6 5 4' texCoordIndex='0 1 2 3'>
<Coordinate USE='Points'/>
<TextureCoordinate USE='DefaultTextureCoordinate'/>
</IndexedFaceSet>
<Appearance>
<ImageTexture
url=' "images/back.png" "http://x3dGraphics.com/examples/X3dForAdvancedModeling/GeometricShapes/images/back.png" "http://www.web3d.org/x3d/content/examples/Basic/DistributedInteractiveSimulation/images/back.png" '/>
<TextureTransform USE='RotateRight'/>
</Appearance>
</Shape>
*/
\ No newline at end of file
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