Commit 42bc2c68 authored by Andrey Filippov's avatar Andrey Filippov

adding tile assignment to surfaces costs

parent 076baece
...@@ -69,6 +69,67 @@ public class CLTPass3d{ ...@@ -69,6 +69,67 @@ public class CLTPass3d{
{ {
return this.tileProcessor; return this.tileProcessor;
} }
public double [][][][] getTextureTiles()
{
return texture_tiles;
}
public double [][] getTileRBGA(
int num_layers)
{
if (texture_tiles == null) return null;
int tilesY = texture_tiles.length;
int tilesX = 0;
int nl = 0;
for (int ty = 0; ty < tilesY; ty++){
if (texture_tiles[ty] != null){
tilesX = texture_tiles[ty].length;
for (int tx = 0; tx < tilesX; tx++){
if (texture_tiles[ty][tx] != null){
nl = texture_tiles[ty][tx].length;
break;
}
}
if (nl > 0) break;
}
if (nl > 0) break;
}
if (num_layers > nl) num_layers = nl;
int numTiles = tilesX * tilesY;
double [] scales = new double [num_layers];
for (int n = 0; n < num_layers; n++){
if (n < 3) scales[n] = 1.0/255.0; // R,B,G
else if (n == 3) scales[n] = 1.0; //alpha
else if (n < 8) scales[n] = 1.0; // ports 0..3
else scales[n] = 1.0/255.0; // RBG rms, in 1/255 units, but small
}
double [][] tileTones = new double [num_layers][numTiles];
for (int ty = 0; ty < tilesY; ty++ ) if (texture_tiles[ty] != null){
for (int tx = 0; tx < tilesX; tx++ ) if (texture_tiles[ty][tx] != null) {
int indx = ty * tilesX + tx;
for (int n = 0; n < num_layers; n++) if (texture_tiles[ty][tx][n] != null){
double s = 0.0;
for (int i = 0; i < texture_tiles[ty][tx][n].length; i++){
s += texture_tiles[ty][tx][n][i];
}
s /= (texture_tiles[ty][tx][n].length/4); // overlapping tiles
s *= scales[n];
tileTones[n][indx] = s;
}
}
}
return tileTones;
}
public String getTextureName()
{
if (texture != null) {
return texture;
} else {
return "null-texture-name";
}
}
public void updateSelection(){ // add updating border tiles? public void updateSelection(){ // add updating border tiles?
int tilesX = tileProcessor.getTilesX(); int tilesX = tileProcessor.getTilesX();
int tilesY = tileProcessor.getTilesY(); int tilesY = tileProcessor.getTilesY();
......
...@@ -2350,7 +2350,21 @@ public class EyesisCorrectionParameters { ...@@ -2350,7 +2350,21 @@ public class EyesisCorrectionParameters {
public int tsConsensMode = 7; // Which assignments to match +1 - combo, +2 grown single, +4 plane seeds public int tsConsensMode = 7; // Which assignments to match +1 - combo, +2 grown single, +4 plane seeds
public int tsConsensAgree = 1; // Minimal number of assignments to agree public int tsConsensAgree = 1; // Minimal number of assignments to agree
// Tile assignment parameters
public double taCostEmpty = 1.0; // Cost of a tile that is not assigned
public double taCostNoLink = 1.0; // Cost of a tile not having any neighbor in particular direction
public double taCostSwitch = 1.0; // Cost of a tile switching to a neighbor that does not have a link
public double taCostColor = 1.0; // Cost of a tile switching to a disconnected neighbor divided by a color mismatch
public double taCostDiff = 1.0; // Cost of a weighted normalized tile disparity error
public double taCostDiffBest = 1.0; // Cost of a weighted normalized tile disparity error above best surface
public double taCostDiff9 = 1.0; // Cost of a weighted normalized tile disparity error for tile and 8 neighbors (DC)
public double taCostWeakFgnd = 1.0; // Cost of a weak foreground edge
public double taCostFlaps = 1.0; // Cost of using supertile "flaps" (not in the center 8x8 tiles area)
public double taCostMismatch = 1.0; // Cost of a measurement layer not having same layer in the same location or near
public boolean replaceWeakOutlayers = true; // false; public boolean replaceWeakOutlayers = true; // false;
public boolean dbg_migrate = true; public boolean dbg_migrate = true;
...@@ -2777,6 +2791,17 @@ public class EyesisCorrectionParameters { ...@@ -2777,6 +2791,17 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"tsConsensMode", this.tsConsensMode +""); properties.setProperty(prefix+"tsConsensMode", this.tsConsensMode +"");
properties.setProperty(prefix+"tsConsensAgree", this.tsConsensAgree +""); properties.setProperty(prefix+"tsConsensAgree", this.tsConsensAgree +"");
properties.setProperty(prefix+"taCostEmpty", this.taCostEmpty +"");
properties.setProperty(prefix+"taCostNoLink", this.taCostNoLink +"");
properties.setProperty(prefix+"taCostSwitch", this.taCostSwitch +"");
properties.setProperty(prefix+"taCostColor", this.taCostColor +"");
properties.setProperty(prefix+"taCostDiff", this.taCostDiff +"");
properties.setProperty(prefix+"taCostDiffBest", this.taCostDiffBest +"");
properties.setProperty(prefix+"taCostDiff9", this.taCostDiff9 +"");
properties.setProperty(prefix+"taCostWeakFgnd", this.taCostWeakFgnd +"");
properties.setProperty(prefix+"taCostFlaps", this.taCostFlaps +"");
properties.setProperty(prefix+"taCostMismatch", this.taCostMismatch +"");
properties.setProperty(prefix+"dbg_migrate", this.dbg_migrate+""); properties.setProperty(prefix+"dbg_migrate", this.dbg_migrate+"");
properties.setProperty(prefix+"show_ortho_combine", this.show_ortho_combine+""); properties.setProperty(prefix+"show_ortho_combine", this.show_ortho_combine+"");
...@@ -3176,9 +3201,9 @@ public class EyesisCorrectionParameters { ...@@ -3176,9 +3201,9 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"tsMaxSurStrength")!=null) this.tsMaxSurStrength=Double.parseDouble(properties.getProperty(prefix+"tsMaxSurStrength")); if (properties.getProperty(prefix+"tsMaxSurStrength")!=null) this.tsMaxSurStrength=Double.parseDouble(properties.getProperty(prefix+"tsMaxSurStrength"));
if (properties.getProperty(prefix+"tsCountDis")!=null) this.tsCountDis=Boolean.parseBoolean(properties.getProperty(prefix+"tsCountDis")); if (properties.getProperty(prefix+"tsCountDis")!=null) this.tsCountDis=Boolean.parseBoolean(properties.getProperty(prefix+"tsCountDis"));
if (properties.getProperty(prefix+"tsEnPlaneSeed")!=null) this.tsEnOnly=Boolean.parseBoolean(properties.getProperty(prefix+"tsEnPlaneSeed")); if (properties.getProperty(prefix+"tsEnPlaneSeed")!=null) this.tsEnPlaneSeed=Boolean.parseBoolean(properties.getProperty(prefix+"tsEnPlaneSeed"));
if (properties.getProperty(prefix+"tsEnOnly")!=null) this.tsEnOnly=Boolean.parseBoolean(properties.getProperty(prefix+"tsEnOnly")); if (properties.getProperty(prefix+"tsEnOnly")!=null) this.tsEnOnly=Boolean.parseBoolean(properties.getProperty(prefix+"tsEnOnly"));
if (properties.getProperty(prefix+"tsEnGrow")!=null) this.tsEnOnly=Boolean.parseBoolean(properties.getProperty(prefix+"tsEnGrow")); if (properties.getProperty(prefix+"tsEnGrow")!=null) this.tsEnGrow=Boolean.parseBoolean(properties.getProperty(prefix+"tsEnGrow"));
if (properties.getProperty(prefix+"tsGrowStrength")!=null) this.tsGrowStrength=Double.parseDouble(properties.getProperty(prefix+"tsGrowStrength")); if (properties.getProperty(prefix+"tsGrowStrength")!=null) this.tsGrowStrength=Double.parseDouble(properties.getProperty(prefix+"tsGrowStrength"));
if (properties.getProperty(prefix+"tsGrowStrong")!=null) this.tsGrowStrong=Boolean.parseBoolean(properties.getProperty(prefix+"tsGrowStrong")); if (properties.getProperty(prefix+"tsGrowStrong")!=null) this.tsGrowStrong=Boolean.parseBoolean(properties.getProperty(prefix+"tsGrowStrong"));
if (properties.getProperty(prefix+"tsContStrength")!=null) this.tsGrowStrength=Double.parseDouble(properties.getProperty(prefix+"tsContStrength")); if (properties.getProperty(prefix+"tsContStrength")!=null) this.tsGrowStrength=Double.parseDouble(properties.getProperty(prefix+"tsContStrength"));
...@@ -3197,6 +3222,17 @@ public class EyesisCorrectionParameters { ...@@ -3197,6 +3222,17 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"tsConsensMode")!=null) this.tsConsensMode=Integer.parseInt(properties.getProperty(prefix+"tsConsensMode")); if (properties.getProperty(prefix+"tsConsensMode")!=null) this.tsConsensMode=Integer.parseInt(properties.getProperty(prefix+"tsConsensMode"));
if (properties.getProperty(prefix+"tsConsensAgree")!=null) this.tsConsensAgree=Integer.parseInt(properties.getProperty(prefix+"tsConsensAgree")); if (properties.getProperty(prefix+"tsConsensAgree")!=null) this.tsConsensAgree=Integer.parseInt(properties.getProperty(prefix+"tsConsensAgree"));
if (properties.getProperty(prefix+"taCostEmpty")!=null) this.taCostEmpty=Double.parseDouble(properties.getProperty(prefix+"taCostEmpty"));
if (properties.getProperty(prefix+"taCostNoLink")!=null) this.taCostNoLink=Double.parseDouble(properties.getProperty(prefix+"taCostNoLink"));
if (properties.getProperty(prefix+"taCostSwitch")!=null) this.taCostSwitch=Double.parseDouble(properties.getProperty(prefix+"taCostSwitch"));
if (properties.getProperty(prefix+"taCostColor")!=null) this.taCostColor=Double.parseDouble(properties.getProperty(prefix+"taCostColor"));
if (properties.getProperty(prefix+"taCostDiff")!=null) this.taCostDiff=Double.parseDouble(properties.getProperty(prefix+"taCostDiff"));
if (properties.getProperty(prefix+"taCostDiffBest")!=null) this.taCostDiffBest=Double.parseDouble(properties.getProperty(prefix+"taCostDiffBest"));
if (properties.getProperty(prefix+"taCostDiff9")!=null) this.taCostDiff9=Double.parseDouble(properties.getProperty(prefix+"taCostDiff9"));
if (properties.getProperty(prefix+"taCostWeakFgnd")!=null) this.taCostWeakFgnd=Double.parseDouble(properties.getProperty(prefix+"taCostWeakFgnd"));
if (properties.getProperty(prefix+"taCostFlaps")!=null) this.taCostFlaps=Double.parseDouble(properties.getProperty(prefix+"taCostFlaps"));
if (properties.getProperty(prefix+"taCostMismatch")!=null) this.taCostMismatch=Double.parseDouble(properties.getProperty(prefix+"taCostMismatch"));
if (properties.getProperty(prefix+"dbg_migrate")!=null) this.dbg_migrate=Boolean.parseBoolean(properties.getProperty(prefix+"dbg_migrate")); if (properties.getProperty(prefix+"dbg_migrate")!=null) this.dbg_migrate=Boolean.parseBoolean(properties.getProperty(prefix+"dbg_migrate"));
if (properties.getProperty(prefix+"show_ortho_combine")!=null) this.show_ortho_combine=Boolean.parseBoolean(properties.getProperty(prefix+"show_ortho_combine")); if (properties.getProperty(prefix+"show_ortho_combine")!=null) this.show_ortho_combine=Boolean.parseBoolean(properties.getProperty(prefix+"show_ortho_combine"));
...@@ -3648,6 +3684,18 @@ public class EyesisCorrectionParameters { ...@@ -3648,6 +3684,18 @@ public class EyesisCorrectionParameters {
gd.addNumericField("Which assignments to match +1 - combo, +2 grown single, +4 plane seeds", this.tsConsensMode, 0); gd.addNumericField("Which assignments to match +1 - combo, +2 grown single, +4 plane seeds", this.tsConsensMode, 0);
gd.addNumericField("Minimal number of assignments to agree", this.tsConsensAgree, 0); gd.addNumericField("Minimal number of assignments to agree", this.tsConsensAgree, 0);
gd.addMessage ("--- Tile assignment parameters ---");
gd.addNumericField("Cost of a tile that is not assigned", this.taCostEmpty, 6);
gd.addNumericField("Cost of a tile not having any neighbor in particular direction", this.taCostNoLink, 6);
gd.addNumericField("Cost of a tile switching to a neighbor that does not have a link", this.taCostSwitch, 6);
gd.addNumericField("Cost of a tile switching to a disconnected neighbor divided by a color", this.taCostColor, 6);
gd.addNumericField("Cost of a weighted normalized tile disparity error", this.taCostDiff, 6);
gd.addNumericField("Cost of a weighted normalized tile disparity error above best surface", this.taCostDiffBest, 6);
gd.addNumericField("Cost of a weighted normalized tile disparity error for tile and 8 neighbors (DC)",this.taCostDiff9, 6);
gd.addNumericField("Cost of a weak foreground edge", this.taCostWeakFgnd, 6);
gd.addNumericField("Cost of using supertile \"flaps\" (not in the center 8x8 tiles area)", this.taCostFlaps, 6);
gd.addNumericField("Cost of a measurement layer not having same layer in the same location or near", this.taCostMismatch, 6);
gd.addCheckbox ("Test new mode after migration", this.dbg_migrate); gd.addCheckbox ("Test new mode after migration", this.dbg_migrate);
gd.addMessage ("--- Other debug images ---"); gd.addMessage ("--- Other debug images ---");
...@@ -4076,6 +4124,17 @@ public class EyesisCorrectionParameters { ...@@ -4076,6 +4124,17 @@ public class EyesisCorrectionParameters {
this.tsConsensMode = (int) gd.getNextNumber(); this.tsConsensMode = (int) gd.getNextNumber();
this.tsConsensAgree = (int) gd.getNextNumber(); this.tsConsensAgree = (int) gd.getNextNumber();
this.taCostEmpty= gd.getNextNumber();
this.taCostNoLink= gd.getNextNumber();
this.taCostSwitch= gd.getNextNumber();
this.taCostColor= gd.getNextNumber();
this.taCostDiff= gd.getNextNumber();
this.taCostDiffBest= gd.getNextNumber();
this.taCostDiff9= gd.getNextNumber();
this.taCostWeakFgnd= gd.getNextNumber();
this.taCostFlaps= gd.getNextNumber();
this.taCostMismatch= gd.getNextNumber();
this.dbg_migrate= gd.getNextBoolean(); this.dbg_migrate= gd.getNextBoolean();
this.show_ortho_combine= gd.getNextBoolean(); this.show_ortho_combine= gd.getNextBoolean();
...@@ -4139,6 +4198,17 @@ public class EyesisCorrectionParameters { ...@@ -4139,6 +4198,17 @@ public class EyesisCorrectionParameters {
gd.addNumericField("Which assignments to match +1 - combo, +2 grown single, +4 plane seeds", this.tsConsensMode, 0); gd.addNumericField("Which assignments to match +1 - combo, +2 grown single, +4 plane seeds", this.tsConsensMode, 0);
gd.addNumericField("Minimal number of assignments to agree", this.tsConsensAgree, 0); gd.addNumericField("Minimal number of assignments to agree", this.tsConsensAgree, 0);
gd.addMessage ("--- Tile assignment parameters ---");
gd.addNumericField("Cost of a tile that is not assigned", this.taCostEmpty, 6);
gd.addNumericField("Cost of a tile not having any neighbor in particular direction", this.taCostNoLink, 6);
gd.addNumericField("Cost of a tile switching to a neighbor that does not have a link", this.taCostSwitch, 6);
gd.addNumericField("Cost of a tile switching to a disconnected neighbor divided by a color", this.taCostColor, 6);
gd.addNumericField("Cost of a weighted normalized tile disparity error", this.taCostDiff, 6);
gd.addNumericField("Cost of a weighted normalized tile disparity error above best surface", this.taCostDiffBest, 6);
gd.addNumericField("Cost of a weighted normalized tile disparity error for tile and 8 neighbors (DC)",this.taCostDiff9, 6);
gd.addNumericField("Cost of a weak foreground edge", this.taCostWeakFgnd, 6);
gd.addNumericField("Cost of using supertile \"flaps\" (not in the center 8x8 tiles area)", this.taCostFlaps, 6);
gd.addNumericField("Cost of a measurement layer not having same layer in the same location or near", this.taCostMismatch, 6);
WindowTools.addScrollBars(gd); WindowTools.addScrollBars(gd);
gd.showDialog(); gd.showDialog();
...@@ -4184,10 +4254,19 @@ public class EyesisCorrectionParameters { ...@@ -4184,10 +4254,19 @@ public class EyesisCorrectionParameters {
this.tsNumClust= (int) gd.getNextNumber(); this.tsNumClust= (int) gd.getNextNumber();
this.tsConsensMode = (int) gd.getNextNumber(); this.tsConsensMode = (int) gd.getNextNumber();
this.tsConsensAgree = (int) gd.getNextNumber(); this.tsConsensAgree = (int) gd.getNextNumber();
this.taCostEmpty= gd.getNextNumber();
this.taCostNoLink= gd.getNextNumber();
this.taCostSwitch= gd.getNextNumber();
this.taCostColor= gd.getNextNumber();
this.taCostDiff= gd.getNextNumber();
this.taCostDiffBest= gd.getNextNumber();
this.taCostDiff9= gd.getNextNumber();
this.taCostWeakFgnd= gd.getNextNumber();
this.taCostFlaps= gd.getNextNumber();
this.taCostMismatch= gd.getNextNumber();
return true; return true;
} }
} }
public static class DCTParameters { public static class DCTParameters {
......
...@@ -3196,7 +3196,7 @@ public class QuadCLT { ...@@ -3196,7 +3196,7 @@ public class QuadCLT {
double [][][][] clt_corr_combo = null; double [][][][] clt_corr_combo = null;
double [][][][][] clt_corr_partial = null; // [tp.tilesY][tp.tilesX][pair][color][(2*transform_size-1)*(2*transform_size-1)] double [][][][][] clt_corr_partial = null; // [tp.tilesY][tp.tilesX][pair][color][(2*transform_size-1)*(2*transform_size-1)]
double [][] clt_mismatch = null; // [3*4][tp.tilesY * tp.tilesX] // transpose unapplied double [][] clt_mismatch = null; // [3*4][tp.tilesY * tp.tilesX] // transpose unapplied
double [][][][] texture_tiles = null; // [tp.tilesY][tp.tilesX]["RGBA".length()][]; // tiles will be 16x16, 2 visualizaion mode full 16 or overlapped double [][][][] texture_tiles = null; // [tp.tilesY][tp.tilesX]["RGBA".length()][]; // tiles will be 16x16, 2 visualization mode full 16 or overlapped
// undecided, so 2 modes of combining alpha - same as rgb, or use center tile only // undecided, so 2 modes of combining alpha - same as rgb, or use center tile only
final int tilesX = tp.getTilesX(); final int tilesX = tp.getTilesX();
final int tilesY = tp.getTilesY(); final int tilesY = tp.getTilesY();
......
/**
**
** TileAssignment - handle tile surfaces
**
** Copyright (C) 2017 Elphel, Inc.
**
** -----------------------------------------------------------------------------**
**
** TileAssignment.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/>.
** -----------------------------------------------------------------------------**
**
*/
import java.awt.Point;
import java.util.HashMap;
import java.util.concurrent.atomic.AtomicInteger;
//import ij.IJ;
public class TileAssignment {
private TileSurface ts;
private CLTPass3d p3d; // last/ combined FPGA data
private EyesisCorrectionParameters.CLTParameters clt_parameters;
private double [][][] dispStrength; // indexed as a surface (full supertiles), not as image
private boolean [] valid_ml;
private double [][] tile_tones;
private double [][][] tone_diff_weight; // for each surface (not image) tile, for each of 8 directions,
//a pair of normalized tone difference and weight (both weight and diff == 0.0 for connections to/from undefined tiles
private double kR = 1.0; // relative weight of red to green ratio
private double kB = 1.0; // relative weight of blue to green ratio
private double fatZero = 0.01; // for colors, normalized to 0..1.0 range
private int surfTilesX;
private int surfTilesY;
private int imgTilesX;
private int imgTilesY;
private TileNeibs tnImage;
private TileNeibs tnSurface;
private boolean [][][] valid_surf; // per measured layer, per surface tile, per surface layer
// from clt_parameters
private double dispNorm;
private TACosts cost_coeff;
private double minFgBg = 0.1; // Minimal foreground/ background separation to look for weak FG edge
private double minFgEdge = 0.2; // Minimal foreground edge strength (stronger edges will have proportionally smaller costs)
private double minColSep = 0.05; // Minimal surface separation that requires color change
private double minColDiff = 0.01; // Minimal surface separation that requires color change
static double [] NEIB_WEIGHTS = {0.5,0.25, 0.5, 0.25, 0.5,0.25, 0.5, 0.25, 1.0};
static int INDEX_R = 0;
static int INDEX_B = 1;
static int INDEX_G = 2;
static int INDEX_A = 3;
public class TACosts{
public double empty; // Cost of a tile that is not assigned
public double nolink; // Cost of a tile not having any neighbor in particular direction
public double swtch; // Cost of a tile switching to a neighbor that does not have a link
public double color; // Cost of a tile switching to a disconnected neighbor divided by a color mismatch
public double diff; // Cost of a weighted normalized tile disparity error
public double diff_best; // Cost of a weighted normalized tile disparity error above best surface
public double diff9; // Cost of a weighted normalized tile disparity error for tile and 8 neighbors (DC)
public double weak_fgnd; // Cost of a weak foreground edge
public double flaps; // Cost of using supertile "flaps" (not in the center 8x8 tiles area)
public double ml_mismatch; // Cost of a measurement layer not having same layer in the same location or near
public TACosts (int mode)
{
this.empty = 1.0;
this.nolink = 1.0/1.50705;
this.swtch = 1.0/0.59474;
this.color = 1.0/2.25763;
this.diff = 1.0/1.94213;
this.diff_best = 1.0/0.06731;
this.diff9 = 1.0/1.09087;
this.weak_fgnd = 1.0/0.22250;
this.flaps = 1.0/0.07229;
this.ml_mismatch = 1.0;
// ml_mismatch not yet implemented - is it needed - maybe some see-through data appears on one layer only
}
/*
empty= 0.00000 nolink= 1.50705 swtch= 0.59474 color= 2.25763 diff= 1.94213
diff_best= 0.06731 diff9= 1.09087 weak_fgnd= 0.22250 flaps= 0.07229 ml_mismatch= 0.00000
*/
public TACosts (EyesisCorrectionParameters.CLTParameters clt_parameters)
{
this.empty = clt_parameters.taCostEmpty;
this.nolink = clt_parameters.taCostNoLink;
this.swtch = clt_parameters.taCostSwitch;
this.color = clt_parameters.taCostColor;
this.diff = clt_parameters.taCostDiff;
this.diff_best = clt_parameters.taCostDiffBest;
this.diff9 = clt_parameters.taCostDiff9;
this.weak_fgnd = clt_parameters.taCostWeakFgnd;
this.flaps = clt_parameters.taCostFlaps;
this.ml_mismatch = clt_parameters.taCostMismatch;
// ml_mismatch not yet implemented - is it needed - maybe some see-through data appears on one layer only
}
public TACosts(){}
public TACosts(double [] vals)
{
set(vals);
}
public void set(double [] vals)
{
this.empty = vals[0];
this.nolink = vals[1];
this.swtch = vals[2];
this.color = vals[3];
this.diff = vals[4];
this.diff_best = vals[5];
this.diff9 = vals[6];
this.weak_fgnd = vals[7];
this.flaps = vals[8];
this.ml_mismatch = vals[9];
}
public double [] toArray(){
double [] rslt = {
this.empty,
this.nolink,
this.swtch,
this.color,
this.diff,
this.diff_best,
this.diff9,
this.weak_fgnd,
this.flaps,
this.ml_mismatch
};
return rslt;
}
public String [] getTitles()
{
String [] titles = {
"empty",
"nolink",
"swtch",
"color",
"diff",
"diff_best",
"diff9",
"weak_fgnd",
"flaps",
"ml_mismatch"};
return titles;
}
public String toString()
{
String s = "";
s+= String.format("empty= %8.5f nolink=%8.5f swtch= %8.5f color=%8.5f diff= %8.5f\n",empty, nolink, swtch, color, diff);
s+= String.format("diff_best=%8.5f diff9= %8.5f weak_fgnd=%8.5f flaps=%8.5f ml_mismatch=%8.5f\n",diff_best, diff9, weak_fgnd, flaps, ml_mismatch);
return s;
}
public double dotProd (TACosts costs){
double [] these = toArray();
double [] other = costs.toArray();
double prod = 0.0;
for (int i = 0; i < these.length; i++){
prod += these[i]*other[i];
}
return prod;
}
public void add (TACosts costs){
double [] these = toArray();
double [] other = costs.toArray();
for (int i = 0; i < these.length; i++){
these[i] += other[i];
}
set (these);
}
public void mul (TACosts costs){
double [] these = toArray();
double [] other = costs.toArray();
for (int i = 0; i < these.length; i++){
these[i] *= other[i];
}
set (these);
}
public void max (TACosts costs){
double [] these = toArray();
double [] other = costs.toArray();
for (int i = 0; i < these.length; i++){
these[i] = Math.max(these[i],other[i]);
}
set (these);
}
public void scale (double a){
double [] these = toArray();
for (int i = 0; i < these.length; i++){
these[i] *= a;
}
set (these);
}
}
/**
*
* @param ts
* @param p3d
* @param tile_sel
* @param dispStrength per measurement layer, combined disparity and strength array ([num_ml [2][])
* @param kR
* @param kB
* @param fatZero
*/
public TileAssignment (
EyesisCorrectionParameters.CLTParameters clt_parameters,
TileSurface ts,
CLTPass3d p3d,
double [][][] dispStrength,
double kR,
double kB,
double fatZero)
{
this.ts = ts;
this.p3d = p3d;
copyParams(clt_parameters);
this.clt_parameters = clt_parameters; // replace with copying specific ones
valid_ml = new boolean [dispStrength.length];
for (int ml = 0; ml < dispStrength.length; ml++){
valid_ml[ml] = dispStrength[ml] != null;
}
if (!Double.isNaN(kR)) this.kR = kR;
if (!Double.isNaN(kB)) this.kB = kB;
if (!Double.isNaN(fatZero)) this.fatZero = fatZero;
this.surfTilesX = ts.getSTilesX() * ts.getSuperTileSize();
this.surfTilesY = ts.getSTilesY() * ts.getSuperTileSize();
this.imgTilesX = ts.getImageTilesX();
this.imgTilesY = ts.getImageTilesX();
this.tnImage = new TileNeibs(imgTilesX, imgTilesY);
this.tnSurface = new TileNeibs(surfTilesX, surfTilesY);
setDispStrength(dispStrength);
setTones(p3d);
}
public void copyParams(EyesisCorrectionParameters.CLTParameters clt_parameters)
{
this.dispNorm = clt_parameters.plDispNorm;
cost_coeff = new TACosts (clt_parameters);
cost_coeff.mul(new TACosts (0)); // make average ~=1.0 for each used component
}
public void setDispStrength(
double [][][] ds)
{
this.dispStrength = new double [ds.length][][];
for (int ml = 0; ml < ds.length; ml++) if (ds[ml] != null){
this.dispStrength[ml] = new double [ surfTilesX * surfTilesY][];
for (int nTile = 0; nTile < ds[ml][0].length; nTile++){
int nSurfTile = ts.getSurfaceTileIndex(nTile);
this.dispStrength[ml][nSurfTile] = new double[2]; // ds[ml][nTile];
this.dispStrength[ml][nSurfTile][0] = ds[ml][0][nTile];
this.dispStrength[ml][nSurfTile][1] = ds[ml][1][nTile];
}
}
}
public void setTones(CLTPass3d p3d)
{
double [][] tt = p3d.getTileRBGA(4);
this.tile_tones = new double [surfTilesX * surfTilesY][tt.length];
for (int nTile = 0; nTile < tt[0].length; nTile++){
int nSurfTile = ts.getSurfaceTileIndex(nTile);
for (int j = 0; j < tt.length; j++){
this.tile_tones[nSurfTile][j] = tt[j][nTile];
}
}
this.tone_diff_weight = new double [surfTilesX * surfTilesY][8][2];
// final int numTiles = imgTilesX * imgTilesY;
final Thread[] threads = ImageDtt.newThreadArray(ts.getThreadsMax());
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nSurfTile = ai.getAndIncrement(); nSurfTile < tone_diff_weight.length; nSurfTile = ai.getAndIncrement()) {
if (nSurfTile >= 0){
for (int dir = 0; dir < 4; dir++){
int nSurfTile1 = tnSurface.getNeibIndex(nSurfTile, dir);
if (nSurfTile1 >= 0){
tone_diff_weight[nSurfTile][dir] =
getDiffWeight (
tile_tones[nSurfTile],
tile_tones[nSurfTile1]);
tone_diff_weight[nSurfTile1][(dir + 4) % 8] = tone_diff_weight[nSurfTile][dir];
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
}
public void showToneDiffWeights3(){
String [] titles = {"diffs","sqrt","centers","weights"};
double [][] img_data = new double[titles.length][9 * surfTilesX * surfTilesY];
TileNeibs tnSurface3 = new TileNeibs( 3 * surfTilesX, 3 * surfTilesY);
for (int nSurfTile = 0; nSurfTile < tone_diff_weight.length; nSurfTile++){
int [] txy = tnSurface.getXY(nSurfTile);
int [] txy3 = {3 * txy[0] + 1, 3 * txy[1] + 1};
double sdw = 0.0, sw = 0.0;
int num_neibs = 0;
for (int dir = 0; dir < 8; dir++){
sw += tone_diff_weight[nSurfTile][dir][1];
sdw += tone_diff_weight[nSurfTile][dir][0] * tone_diff_weight[nSurfTile][dir][1];
int nSurfTile3 = tnSurface3.getNeibIndex(tnSurface3.getIndex(txy3[0],txy3[1]),dir);
img_data[0][nSurfTile3] = tone_diff_weight[nSurfTile][dir][0];
img_data[1][nSurfTile3] = Math.sqrt(tone_diff_weight[nSurfTile][dir][0]);
img_data[3][nSurfTile3] = tone_diff_weight[nSurfTile][dir][1];
if (tone_diff_weight[nSurfTile][dir][1] > 0.0) num_neibs ++;
}
if (sw > 0.0){
sdw /= sw;
}
if (num_neibs > 0){
sw /= num_neibs;
}
int nSurfTile3 = tnSurface3.getIndex(txy3[0],txy3[1]);
img_data[0][nSurfTile3] = sdw;
img_data[1][nSurfTile3] = Math.sqrt(sdw);
img_data[2][nSurfTile3] = sdw;
img_data[3][nSurfTile3] = sw;
}
(new showDoubleFloatArrays()).showArrays(img_data, 3 * surfTilesX, 3 * surfTilesY, true, "Tone_diffs3", titles);
}
public void showToneDiffWeights1(){
double [][] img_data = new double[2][surfTilesX * surfTilesY];
for (int nSurfTile = 0; nSurfTile < tone_diff_weight.length; nSurfTile++){
double sdw = 0.0, sw = 0.0;
int num_neibs = 0;
for (int dir = 0; dir < 8; dir++){
sw += tone_diff_weight[nSurfTile][dir][1];
sdw += tone_diff_weight[nSurfTile][dir][0] * tone_diff_weight[nSurfTile][dir][1];
if (tone_diff_weight[nSurfTile][dir][1] > 0.0) num_neibs ++;
}
if (sw > 0.0){
sdw /= sw;
}
if (num_neibs > 0){
sw /= num_neibs;
}
img_data[0][nSurfTile] = sdw;
img_data[1][nSurfTile] = sw;
}
String [] titles = {"diffs","weights"};
(new showDoubleFloatArrays()).showArrays(img_data, surfTilesX, surfTilesY, true, "Tone_diffs1", titles);
}
private double [] getDiffWeight(
double [] tone1,
double [] tone2)
{
double [] tone_weight = {0.0, Math.max(tone1[INDEX_A] * tone2[INDEX_A], 0.0)};
if (tone_weight[1] > 0.0){
double [][] scaled = {
{(Math.max(tone1[INDEX_R], 0.0) + fatZero) * kR, (Math.max(tone1[INDEX_B], 0.0) + fatZero) * kB, (Math.max(tone1[INDEX_G], 0.0) + fatZero) },
{(Math.max(tone2[INDEX_R], 0.0) + fatZero) * kR, (Math.max(tone2[INDEX_B], 0.0) + fatZero) * kB, (Math.max(tone2[INDEX_G], 0.0) + fatZero)}};
double rdiff2 = 0.0;
for (int i = 0; i < 3; i++){
double rd = (scaled[0][i] - scaled[1][i])/(scaled[0][i] + scaled[1][i]);
rdiff2 += rd*rd;
}
tone_weight[0] = rdiff2/3.0;
}
return tone_weight;
}
public void intValidSurf()
{
TileSurface.TileData [][] tileData = ts.getTileData();
int nSurfTiles = surfTilesX * surfTilesY;
valid_surf = new boolean [valid_ml.length][][]; // surfTilesX * surfTilesY][];
for (int ml = 0; ml < valid_ml.length; ml++) if (valid_ml[ml]) {
valid_surf[ml] = new boolean [nSurfTiles][];
}
for (int nSurfTile = 0; nSurfTile < nSurfTiles; nSurfTile++) if (tileData[nSurfTile] != null){
boolean [] surf_en = new boolean [tileData[nSurfTile].length];
for (int i = 0; i < surf_en.length; i++) {
surf_en[i] = true;
}
for (int ml = 0; ml < valid_ml.length; ml++) if (valid_surf[ml] != null){
valid_surf[ml][nSurfTile] = surf_en.clone();
}
}
}
/**
* limit layer options for assigned cells to a single (selected) option, disable all negative ones
* @param tileLayers
*/
public void restrictSingle (
final int [][] tileLayers)
{
for (int ml = 0; ml < valid_ml.length; ml++) if ((valid_surf[ml] != null) && (tileLayers[ml] != null)){
for (int nTile = 0; nTile < tileLayers[ml].length; nTile++) if (tileLayers[ml][nTile] != 0){
int nSurfTile = ts.getSurfaceTileIndex(nTile);
for (int ns = 0; ns < valid_surf[ml][nSurfTile].length; ns++){
valid_surf[ml][nSurfTile][ns] = false;
}
if (tileLayers[ml][nTile] > 0) valid_surf[ml][nSurfTile][tileLayers[ml][nTile] - 1] = true;
}
}
}
/**
* Limit layer options for assigned cells to a multiple options per tile cell
* @param options
*/
public void restrictMulti (
final int [][][] options)
{
for (int ml = 0; ml < valid_ml.length; ml++) if ((valid_surf[ml] != null) && (options[ml] != null)){
for (int nTile = 0; nTile < options[ml].length; nTile++) if ((options[ml][nTile] != null) && (options[ml][nTile].length > 0)){
int nSurfTile = ts.getSurfaceTileIndex(nTile);
for (int ns = 0; ns < valid_surf[ml][nSurfTile].length; ns++){
valid_surf[ml][nSurfTile][ns] = false;
}
for (int i = 0; i < options[ml][nTile].length; i++) {
valid_surf[ml][nSurfTile][options[ml][nTile][i] - 1] = true;
}
}
}
}
/**
* Get signed normalized difference from the measured disparity to the selected surface
* @param ml measured layer (combo, quad, hor, vert)
* @param nSurfTile tile index in surface array (includes full supertiles)
* @param ns number of the surface
* @return signed disparity error, scaled down for large disparities
*/
public double dispDiff(
int ml,
int nSurfTile,
int ns)
{
if ((dispStrength[ml] == null) || (dispStrength[ml][nSurfTile] == null)) {
String msg="dispDiff(): no data for ml="+ml+", nSurfTile="+nSurfTile+", ns="+ns;
// IJ.showMessage(msg);
throw new IllegalArgumentException (msg);
}
double dm = dispStrength[ml][nSurfTile][0];
double ds = ts.getTileData()[nSurfTile][ns].getDisparity();
double diff = dm - ds;
double d_av = 0.5 * (dm + ds);
if (d_av > dispNorm){
diff *= dispNorm/d_av;
}
return diff;
}
/**
* Get absolute value of the normalized disparity difference from the measured value to the nearest surface
* @param ml measured layer (combo, quad, hor, vert)
* @param nSurfTile tile index in surface array (includes full supertiles)
* @return absolute value of the disparity error (scaled down for large disparities) to the nearest surface
*/
public double dispDiffBest(
int ml,
int nSurfTile)
{
double best = Double.NaN;
for (int ns = 0; ns < ts.getTileData()[nSurfTile].length; ns++){
double diff = dispDiff(ml, nSurfTile, ns);
double adiff = Math.abs(diff);
if (Double.isNaN(best) || (adiff < best)) {
best = adiff;
}
}
return best;
}
/**
* Get absolute value of the normalized disparity difference from the measured value to the farthest surface
* Used to estimate cost of un-assigned tiles
* @param ml measured layer (combo, quad, hor, vert)
* @param nSurfTile tile index in surface array (includes full supertiles)
* @return absolute value of the disparity error (scaled down for large disparities) to the farthest surface
*/
public double dispDiffWorst(
int ml,
int nSurfTile)
{
double worst = Double.NaN;
if ((ts.getTileData() == null) || (ts.getTileData()[nSurfTile] == null)){
System.out.println("dispDiffWorst("+ml+","+nSurfTile+")");
return worst;
}
for (int ns = 0; ns < ts.getTileData()[nSurfTile].length; ns++){
double diff = dispDiff(ml, nSurfTile, ns);
double adiff = Math.abs(diff);
if (Double.isNaN(worst) || (adiff < worst)) {
worst = adiff;
}
}
return worst;
}
public TACosts [] getTileCosts(
boolean all_tiles,
int [][] tileLayers)
{
TACosts [] ta_costs = new TACosts [surfTilesX * surfTilesY];
for (int nSurfTile = 0; nSurfTile < ta_costs.length; nSurfTile++){
boolean has_tile = false;
boolean has_block = false;
for (int ml = 0; ml < tileLayers.length; ml++) if(tileLayers[ml] != null) {
if (tileLayers[ml][nSurfTile] < 0) {
has_block = true;
break;
}
if (tileLayers[ml][nSurfTile] > 0) {
has_tile = true;
}
}
if (!has_block && (all_tiles || has_tile)){
ta_costs[nSurfTile] = getTileCosts(
nSurfTile, // int nSurfTile,
tileLayers, // int [][] tileLayers,
null); // HashMap<Point,Integer> replacements)
}
} //for (int nSurfTile)
return ta_costs;
}
public double [] calcTileCosts(
int [][] tileLayers)
{
double [] costs = new double [surfTilesX * surfTilesY];
for (int nSurfTile = 0; nSurfTile < costs.length; nSurfTile++){
boolean has_tile = false;
boolean has_block = false;
for (int ml = 0; ml < tileLayers.length; ml++) if(tileLayers[ml] != null) {
if (tileLayers[ml][nSurfTile] < 0) {
has_block = true;
break;
}
if (tileLayers[ml][nSurfTile] > 0) {
has_tile = true;
}
}
if (!has_block && has_tile){
TACosts ta_cost = getTileCosts(
nSurfTile, // int nSurfTile,
tileLayers, // int [][] tileLayers,
null); // HashMap<Point,Integer> replacements)
costs[nSurfTile] = cost_coeff.dotProd(ta_cost);
}
}
return costs;
}
public void showTileCost(int [][] tileLayers)
{
double [] composite_costs = calcTileCosts(tileLayers);
(new showDoubleFloatArrays()).showArrays(composite_costs, surfTilesX, surfTilesY, "composite_costs");
}
public void showTileCosts(int [][] tileLayers)
{
String [] titles = (new TACosts()).getTitles();
int num_stiles = surfTilesX*surfTilesY;
double [][] cost_components = new double[titles.length][surfTilesX * surfTilesY];
double [] NaNs = new double[titles.length];
for (int i = 0; i < NaNs.length; i++) NaNs[i] = Double.NaN;
for (int nSurfTile = 0; nSurfTile < num_stiles; nSurfTile++){
boolean has_tile = false;
boolean has_block = false;
for (int ml = 0; ml < tileLayers.length; ml++) if(tileLayers[ml] != null) {
if (tileLayers[ml][nSurfTile] < 0) {
has_block = true;
break;
}
if (tileLayers[ml][nSurfTile] > 0) {
has_tile = true;
}
}
double [] costs = NaNs;
if (!has_block) { // && has_tile){
TACosts ta_cost = getTileCosts(
nSurfTile, // int nSurfTile,
tileLayers, // int [][] tileLayers,
null); // HashMap<Point,Integer> replacements)
ta_cost.mul(cost_coeff);
costs = ta_cost.toArray();
}
for (int i =0; i < cost_components.length; i++){
cost_components[i][nSurfTile] = costs[i];
}
}
(new showDoubleFloatArrays()).showArrays(cost_components, surfTilesX, surfTilesY, true, "cost_components", titles);
}
public TACosts [] statTileCosts(
int [][] tileLayers)
{
TACosts [] ta_stats = {new TACosts(), new TACosts()}; // average, max
int num_tiles = 0;
int numSurfTiles =surfTilesX * surfTilesY;
for (int nSurfTile = 0; nSurfTile < numSurfTiles; nSurfTile++){
if (nSurfTile == 47459){
System.out.println("statTileCosts() nSurfTile="+nSurfTile);
}
boolean has_tile = false;
boolean has_block = false;
for (int ml = 0; ml < tileLayers.length; ml++) if(tileLayers[ml] != null) {
if (tileLayers[ml][nSurfTile] < 0) {
has_block = true;
break;
}
if (tileLayers[ml][nSurfTile] > 0) {
has_tile = true;
}
}
if (!has_block) { // && has_tile){
TACosts ta_cost = getTileCosts(
nSurfTile, // int nSurfTile,
tileLayers, // int [][] tileLayers,
null); // HashMap<Point,Integer> replacements)
ta_stats[0].max(ta_cost);
ta_stats[1].add(ta_cost);
num_tiles++;
}
}
if (num_tiles > 0){
ta_stats[1].scale(1.0/num_tiles);
}
return ta_stats;
}
/**
* Get costs (not scaled) for the particular tile, add for all defined layers
* @param nSurfTile tile index in surface array (includes full supertiles)
* @param tileLayers current assignment
* @param replacements optional assignment modification (or null)
* @return TACosts instance with assigned values
*/
public TACosts getTileCosts(
int nSurfTile,
int [][] tileLayers,
HashMap<Point,Integer> replacements)
{
TACosts costs = new TACosts();
if (nSurfTile == 47459){
System.out.println("getTileCosts() nSurfTile="+nSurfTile);
}
int [][] around = new int [valid_ml.length][]; // contains layer + 1
for (int ml = 0; ml < valid_ml.length; ml++) if(valid_ml[ml]) {
around[ml] = new int [9];
}
int [] nSurfTiles = new int[9];
for (int dir = 0; dir < 9; dir++){
nSurfTiles[dir] = tnSurface.getNeibIndex(nSurfTile, dir);
if (nSurfTiles[dir] < 0) {
for (int ml = 0; ml < around.length; ml++) if (around[ml] != null){
around[ml][dir] = TileSurface.PROHOBITED;
}
} else {
for (int ml = 0; ml < around.length; ml++) if (around[ml] != null){
around[ml][dir] = tileLayers[ml][nSurfTiles[dir]];
if (replacements != null){
Integer isurf = replacements.get(new Point(ml, nSurfTiles[dir]));
if (isurf != null) {
around[ml][dir] = isurf; // substitute
}
}
}
}
}
//
// public double empty; // Cost of a tile that is not assigned
for (int ml = 0; ml < around.length; ml++) if (around[ml] != null){
if (around[ml][8] == 0) costs.empty +=1.0; // Cost of a tile that is not assigned
}
// public double nolink; // Cost of a tile not having any neighbor in particular direction
for (int ml = 0; ml < around.length; ml++) if ((around[ml] != null) && (around[ml][8] > 0)){
if ((around[ml][8] - 1) >= ts.getTileData()[nSurfTile].length){
System.out.println("getTileCosts() BUG: nSurfTile="+nSurfTile);
}
int [] neibs = ts.getTileData()[nSurfTile][around[ml][8] - 1].getNeighbors();
for (int dir = 0; dir < 8; dir++) if (neibs[dir] >= 0){ // do not count non-existing connections
boolean link_this = false;
boolean link_other = false;
int ml1 = ml;
int neibp1 = neibs[dir] + 1;
if (around[ml][dir] > 0) {
if (around[ml][dir] == neibp1) {
link_this = true;
} else {
link_other = true;
}
} else if (around[ml][dir] == 0){
// see if some other ml contains this surface (ignore other surfaces
for (ml1 = 0; ml1 < around.length; ml1++) if ((ml1 != ml) && (around[ml1] != null)) {
if (around[ml1][dir] == neibp1){
link_this = true;
break; // ml1 will keep other ml
}
}
} else { // negative/prohibited
continue;
}
if (!link_this && !link_other){
costs.nolink +=1.0;
} else if (link_other) {
costs.swtch += 1.0; // cost for any switch
// check if it is fb->bg transition and fg is weak
double d_this = ts.getTileData()[nSurfTiles[dir]][neibs[dir]].getDisparity();
double d_other = ts.getTileData()[nSurfTiles[dir]][around[ml][dir] -1].getDisparity();
double disp_diff = d_this - d_other;
double d_av = 0.5 * (d_this + d_other);
if (d_av > dispNorm){
disp_diff *= dispNorm/d_av;
}
// disp_diff here is signed, positive if center is FG, other is BG
if (disp_diff > minFgBg) {
double strength = dispStrength[ml][nSurfTile][1];
strength = Math.max(strength, minFgEdge);
costs.weak_fgnd += minFgEdge / strength;
}
if (Math.abs(disp_diff) > minColSep){
double col_diff = tone_diff_weight[nSurfTile][dir][0];
col_diff= Math.max(col_diff,minColDiff);
costs.color += tone_diff_weight[nSurfTile][dir][1] * minColSep/col_diff;
}
} else { // v, both can not coexist
// Anything to cost here?
}
}
// if (around[ml][8] == 0) costs.empty +=1.0; // each existing measurement layer that is not assigned
} //for (int ml = 0; ml < around.length; ml++) if ((around[ml] != null) && (around[ml][8] > 0))
double disp_diff_lpf = 0.0, disp_diff_weight = 0.0; // calculate LPF of the disparity signed error over all ML and 9 cells
double disp_diff2 = 0.0, disp_weight = 0.0; // calculate disparity error in the center, weighted
double disp_diff_over_best = 0.0; // calculate disparity error in the center, weighted
for (int ml = 0; ml < around.length; ml++) if (around[ml] != null){
double diff=0.0, weight=0.0;
for (int dir = 0; dir < 9; dir++){
if (around[ml][dir] > 0){ // assigned
diff = dispDiff(
ml, // int ml,
nSurfTiles[dir], // int nSurfTile,
around[ml][dir] - 1); // int ns)
} else if ((dir == 8) && (around[ml][dir] == 0) ) { //no assigned (not prohibited) - center only, because worst does not have sign
diff = dispDiffWorst( // worst for all surfaces
ml, // int ml,
nSurfTiles[dir]); // int nSurfTile,
}
if (dispStrength[ml][nSurfTile] != null) { // not a bug
weight = dispStrength[ml][nSurfTile][1] * NEIB_WEIGHTS[dir];
disp_diff_lpf += diff * weight;
disp_diff_weight += weight;
// } else {
// System.out.println("getTileCosts() BUG, nSurfTile="+nSurfTile);
}
}
// now diff, weight are for the center
disp_diff2 += diff * diff * weight;
disp_weight += weight;
disp_diff_over_best += (Math.abs(diff) - dispDiffBest( ml, nSurfTiles[8])) * weight; // this one - not squared
}
if (disp_diff_weight > 0.0) {
disp_diff_lpf /= disp_diff_weight;
costs.diff9 += disp_diff_lpf * disp_diff_lpf;
}
if (disp_weight > 0.0) {
costs.diff += disp_diff2 / disp_weight;
costs.diff_best += disp_diff_over_best / disp_weight;
}
int [] txy = tnSurface.getXY(nSurfTile);
int nSTile = (txy[0] / ts.getSuperTileSize()) + (txy[1] / ts.getSuperTileSize()) * ts.getSTilesX();
for (int ml = 0; ml < around.length; ml++) if ((around[ml] != null) && (around[ml][8] > 0)){
int parentSTile =ts.getTileData()[nSurfTile][around[ml][8] -1].getParentNsTile();
if (parentSTile != nSTile){
costs.flaps += 1.0;
}
}
return costs;
}
public int [][] imgToSurf (
int [][] tileLayersImg)
{
int [][] tileLayersSurf = new int[tileLayersImg.length][];
for (int ml = 0; ml < tileLayersImg.length; ml++) if (tileLayersImg[ml] != null){
tileLayersSurf[ml] = new int [tnSurface.getLength()];
for (int nTile = 0; nTile < tileLayersImg[ml].length; nTile++){
int nSurfTile = tnSurface.getIndex(tnImage.getXY(nTile));
if (nSurfTile >= 0) {
tileLayersSurf[ml][nSurfTile] = tileLayersImg[ml][nTile];
}
}
}
return tileLayersSurf;
}
public int [][] surfToImg (
int [][] tileLayersSurf)
{
int [][] tileLayersImg = new int[tileLayersSurf.length][];
for (int ml = 0; ml < tileLayersSurf.length; ml++) if (tileLayersSurf[ml] != null){
tileLayersImg[ml] = new int [tnImage.getLength()];
for (int nSurfTile = 0; nSurfTile < tileLayersSurf[ml].length; nSurfTile++){
int nImgTile = tnImage.getIndex(tnSurface.getXY(nSurfTile));
if (nImgTile >= 0) {
tileLayersSurf[ml][nImgTile] = tileLayersImg[ml][nSurfTile];
}
}
}
return tileLayersSurf;
}
}
...@@ -43,7 +43,11 @@ public class TileNeibs{ ...@@ -43,7 +43,11 @@ public class TileNeibs{
public int opposite(int dir){ public int opposite(int dir){
return (dir + dirs / 2) % dirs; return (dir + dirs / 2) % dirs;
} }
int getLength(){
return sizeX * sizeY;
}
/** /**
* Get x,y pair from index * Get x,y pair from index
* @param indx element index * @param indx element index
...@@ -64,9 +68,15 @@ public class TileNeibs{ ...@@ -64,9 +68,15 @@ public class TileNeibs{
*/ */
int getIndex(int x, int y){ int getIndex(int x, int y){
if ((x < 0) || (y < 0) || (x >= sizeX) || (y >= sizeY)) return -1;
return y * sizeX + x; return y * sizeX + x;
} }
int getIndex(int [] xy){
if ((xy[0] < 0) || (xy[1] < 0) || (xy[0] >= sizeX) || (xy[1] >= sizeY)) return -1;
return xy[1] * sizeX + xy[0];
}
/** /**
* Get 2d element index after step N, NE, ... NW. Returns -1 if leaving array * Get 2d element index after step N, NE, ... NW. Returns -1 if leaving array
* @param indx start index * @param indx start index
...@@ -78,7 +88,11 @@ public class TileNeibs{ ...@@ -78,7 +88,11 @@ public class TileNeibs{
int y = indx / sizeX; int y = indx / sizeX;
int x = indx % sizeX; int x = indx % sizeX;
if (dir < 0) return indx; if (dir < 0) return indx;
switch (dir % dirs){ if (dir > 8) {
System.out.println("getNeibIndex(): indx="+indx+", dir="+dir);
}
// switch (dir % dirs){
switch (dir){
case 0: return (y == 0) ? -1 : (indx - sizeX); case 0: return (y == 0) ? -1 : (indx - sizeX);
case 1: return ((y == 0) || ( x == (sizeX - 1))) ? -1 : (indx - sizeX + 1); case 1: return ((y == 0) || ( x == (sizeX - 1))) ? -1 : (indx - sizeX + 1);
case 2: return ( ( x == (sizeX - 1))) ? -1 : (indx + 1); case 2: return ( ( x == (sizeX - 1))) ? -1 : (indx + 1);
......
...@@ -27,6 +27,7 @@ import java.util.ArrayList; ...@@ -27,6 +27,7 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
//import java.util.concurrent.atomic.AtomicInteger; //import java.util.concurrent.atomic.AtomicInteger;
public class TileProcessor { public class TileProcessor {
public ArrayList <CLTPass3d> clt_3d_passes = null; public ArrayList <CLTPass3d> clt_3d_passes = null;
public int clt_3d_passes_size = 0; //clt_3d_passes size after initial processing public int clt_3d_passes_size = 0; //clt_3d_passes size after initial processing
...@@ -3136,17 +3137,139 @@ public class TileProcessor { ...@@ -3136,17 +3137,139 @@ public class TileProcessor {
if (tileSurface == null){ if (tileSurface == null){
return false; return false;
} }
/* // show testure_tiles
tileSurface.testSimpleConnected(
230, // clt_parameters.tileX, double [][][][] texture_tiles = scan_prev.getTextureTiles();
131);//clt_parameters.tileY); ImageDtt image_dtt = new ImageDtt();
*/
double [][][] dispStrength = st.getDisparityStrengths( double [][][] dispStrength = st.getDisparityStrengths(
clt_parameters.stMeasSel); // int stMeasSel) // = 1; // Select measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert) clt_parameters.stMeasSel); // int stMeasSel) // = 1; // Select measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert)
boolean [][] tileSel = st.getMeasurementSelections( boolean [][] tileSel = st.getMeasurementSelections(
clt_parameters.stMeasSel); // int stMeasSel) // = 1; // Select measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert) clt_parameters.stMeasSel); // int stMeasSel) // = 1; // Select measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert)
if (texture_tiles != null){
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
double [][] texture_nonoverlap = null;
double [][] texture_overlap = null;
String [] rgba_titles = {"red","blue","green","alpha"};
String [] rgba_weights_titles = {"red","blue","green","alpha","port0","port1","port2","port3","r-rms","b-rms","g-rms","w-rms"};
String name = scan_prev.getTextureName();
boolean show_nonoverlap = false; // true; // clt_parameters.show_nonoverlap
boolean show_overlap = false; //true; // clt_parameters.show_overlap
boolean show_rgba_color = false; //true; // clt_parameters.show_rgba_color
if (show_nonoverlap){
texture_nonoverlap = image_dtt.combineRGBATiles(
texture_tiles, // array [tp.tilesY][tp.tilesX][4][4*transform_size] or [tp.tilesY][tp.tilesX]{null}
clt_parameters.transform_size,
false, // when false - output each tile as 16x16, true - overlap to make 8x8
clt_parameters.sharp_alpha, // combining mode for alpha channel: false - treat as RGB, true - apply center 8x8 only
threadsMax, // maximal number of threads to launch
debugLevel);
sdfa_instance.showArrays(
texture_nonoverlap,
tilesX * (2 * clt_parameters.transform_size),
tilesY * (2 * clt_parameters.transform_size),
true,
name + "-TXTNOL-D",
(clt_parameters.keep_weights?rgba_weights_titles:rgba_titles));
}
if (show_overlap || show_rgba_color){
int alpha_index = 3;
texture_overlap = image_dtt.combineRGBATiles(
texture_tiles, // array [tp.tilesY][tp.tilesX][4][4*transform_size] or [tp.tilesY][tp.tilesX]{null}
clt_parameters.transform_size,
true, // when false - output each tile as 16x16, true - overlap to make 8x8
clt_parameters.sharp_alpha, // combining mode for alpha channel: false - treat as RGB, true - apply center 8x8 only
threadsMax, // maximal number of threads to launch
debugLevel);
if (clt_parameters.alpha1 > 0){ // negative or 0 - keep alpha as it was
double scale = (clt_parameters.alpha1 > clt_parameters.alpha0) ? (1.0/(clt_parameters.alpha1 - clt_parameters.alpha0)) : 0.0;
for (int i = 0; i < texture_overlap[alpha_index].length; i++){
double d = texture_overlap[alpha_index][i];
if (d >=clt_parameters.alpha1) d = 1.0;
else if (d <=clt_parameters.alpha0) d = 0.0;
else d = scale * (d- clt_parameters.alpha0);
texture_overlap[alpha_index][i] = d;
}
}
if (show_overlap) {
sdfa_instance.showArrays(
texture_overlap,
tilesX * clt_parameters.transform_size,
tilesY * clt_parameters.transform_size,
true,
name + "-TXTOL-D",
(clt_parameters.keep_weights?rgba_weights_titles:rgba_titles));
}
/*
if (clt_parameters.show_rgba_color) {
// 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 =
linearStackToColor(
clt_parameters,
colorProcParameters,
rgbParameters,
name+"-texture", // String name,
"-D"+clt_parameters.disparity, //String suffix, // such as disparity=...
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?)
((clt_parameters.alpha1 > 0)? texture_rgba: texture_rgb),
tilesX * clt_parameters.transform_size,
tilesY * clt_parameters.transform_size,
1.0, // double scaleExposure, // is it needed?
debugLevel );
}
*/
}
double [][] tiles_tone = scan_prev.getTileRBGA(
12); // int num_layers);
sdfa_instance.showArrays(
tiles_tone,
tilesX,
tilesY,
true,
name + "tiles_tone",
(clt_parameters.keep_weights?rgba_weights_titles:rgba_titles));
}
TileAssignment ta = new TileAssignment(
clt_parameters, // EyesisCorrectionParameters.CLTParameters clt_parameters,
tileSurface, // TileSurface ts,
scan_prev, // CLTPass3d p3d,
// tileSel, // boolean[][] tile_sel,
dispStrength, // double [][][] dispStrength,
Double.NaN, // double kR,
Double.NaN, // double kB,
Double.NaN); // double fatZero)
ta.showToneDiffWeights3();
ta.showToneDiffWeights1();
// }
// end of show testure_tiles
/*
tileSurface.testSimpleConnected(
230, // clt_parameters.tileX,
131);//clt_parameters.tileY);
*/
// Reset/initialize assignments - if not done so yet or specifically requested // Reset/initialize assignments - if not done so yet or specifically requested
boolean first_run = !tileSurface.isInit() || clt_parameters.tsReset; boolean first_run = !tileSurface.isInit() || clt_parameters.tsReset;
...@@ -3195,7 +3318,7 @@ public class TileProcessor { ...@@ -3195,7 +3318,7 @@ public class TileProcessor {
(clt_parameters.tsEnGrow? growMaxDiffNear: null), // final double [] maxDiffNear, // null (clt_parameters.tsEnGrow? growMaxDiffNear: null), // final double [] maxDiffNear, // null
clt_parameters.plDispNorm, // final double dispNorm, // disparity normalize (proportionally scale down disparity difference if above clt_parameters.plDispNorm, // final double dispNorm, // disparity normalize (proportionally scale down disparity difference if above
dispStrength, // final double [][][] dispStrength, dispStrength, // final double [][][] dispStrength,
2, // -1, // debugLevel, // final int debugLevel) debugLevel, // 2, // -1, // debugLevel, // final int debugLevel)
clt_parameters.tileX, clt_parameters.tileX,
clt_parameters.tileY); clt_parameters.tileY);
System.out.print("growWeakAssigned():"); System.out.print("growWeakAssigned():");
...@@ -3205,7 +3328,8 @@ public class TileProcessor { ...@@ -3205,7 +3328,8 @@ public class TileProcessor {
int [] stats_planes = tileSurface.assignPlanesTiles( int [] stats_planes = tileSurface.assignPlanesTiles(
true, // final boolean force, true, // final boolean force,
tile_layers_planes, //final int [][] tileLayers, tile_layers_planes, //final int [][] tileLayers,
st.planes_mod, // final TilePlanes.PlaneData[][] planes, st.planes_mod, // final TilePlanes.PlaneData[][] planes
clt_parameters.tsNoEdge , // final boolean noEdge,
2, // -1, // debugLevel, // final int debugLevel) 2, // -1, // debugLevel, // final int debugLevel)
clt_parameters.tileX, clt_parameters.tileX,
clt_parameters.tileY); clt_parameters.tileY);
...@@ -3369,7 +3493,14 @@ public class TileProcessor { ...@@ -3369,7 +3493,14 @@ public class TileProcessor {
opinions, // int [][][] opinions_in, opinions, // int [][][] opinions_in,
tile_assignments); // final int [][][] tileAssignments) tile_assignments); // final int [][][] tileAssignments)
int [][] tile_layers_surf = ta.imgToSurf(tile_layers);
ta.showTileCost(tile_layers_surf);
ta.showTileCosts(tile_layers_surf);
TileAssignment.TACosts [] ta_stats = ta.statTileCosts(tile_layers_surf);
for (int i = 0; i < ta_stats.length; i++){
System.out.println(ta_stats[i].toString());
}
tileSurface.setTileLayers(tile_layers); tileSurface.setTileLayers(tile_layers);
......
...@@ -105,11 +105,36 @@ public class TileSurface { ...@@ -105,11 +105,36 @@ public class TileSurface {
this.t_dirs8 = tdirs; this.t_dirs8 = tdirs;
} }
public int getThreadsMax(){
return this.threadsMax;
}
public int getSTilesX(){
return stilesX;
}
public int getSTilesY(){
return stilesY;
}
public int getSuperTileSize(){
return superTileSize;
}
public int [][] getTileLayers() public int [][] getTileLayers()
{ {
return this.tileLayers; return this.tileLayers;
} }
public int getImageTilesX(){
return imageTilesX;
}
public int getImageTilesY(){
return imageTilesY;
}
public TileData [][] getTileData(){
return this.tileData;
}
public int [][] getTileLayersCopy() public int [][] getTileLayersCopy()
{ {
...@@ -155,6 +180,31 @@ public class TileSurface { ...@@ -155,6 +180,31 @@ public class TileSurface {
return this.parent_plane; return this.parent_plane;
} }
*/ */
public String getNeibString()
{
String s = "[";
for (int dir = 0; dir < 8; dir++){
s += (neighbors[dir]>=0) ? neighbors[dir]:"x";
if (dir < 7) s += ", ";
}
s+= "] ";
return s;
}
public String toString()
{
String s = " ";
s += getNeibString();
s += String.format( "index=%2d(%2d) parent = %3d:%1d disp=%8.5f weight=%8.5f",
new_index, indx,
parent_nsTile, parent_layer, disp_strength[0], disp_strength[1]);
return s;
}
public void setParentTileLayer (int parent_nsTile, int parent_layer) public void setParentTileLayer (int parent_nsTile, int parent_layer)
{ {
this.parent_nsTile = parent_nsTile; this.parent_nsTile = parent_nsTile;
...@@ -2069,7 +2119,7 @@ public class TileSurface { ...@@ -2069,7 +2119,7 @@ public class TileSurface {
* @param dbg_Y debug tile Y coordinate * @param dbg_Y debug tile Y coordinate
* @return * @return
*/ */
public int [] assignTilesToSingleCandidate( // not used public int [] assignTilesToSingleCandidate_old( // not used
final boolean noEdge, final boolean noEdge,
final double maxDiff, final double maxDiff,
final double minDiffOther, final double minDiffOther,
...@@ -2077,8 +2127,6 @@ public class TileSurface { ...@@ -2077,8 +2127,6 @@ public class TileSurface {
final double maxStrength, final double maxStrength,
final int moveDirs, // 1 increase disparity, 2 - decrease disparity, 3 - both directions final int moveDirs, // 1 increase disparity, 2 - decrease disparity, 3 - both directions
final double dispNorm, // disparity normalize (proportionally scale down disparity difference if above final double dispNorm, // disparity normalize (proportionally scale down disparity difference if above
// final int [][] tileLayers,
// final TileData [][] tileData,
final double [][][] dispStrength, final double [][][] dispStrength,
final int debugLevel, final int debugLevel,
final int dbg_X, final int dbg_X,
...@@ -2217,7 +2265,7 @@ public class TileSurface { ...@@ -2217,7 +2265,7 @@ public class TileSurface {
public int [][] getConsensusAssignment( public int [][] getConsensusAssignment(
final int min_agree, final int min_agree,
int [][][] opinions_in, int [][][] opinions_in, // options contain 1-based surface indices
final int [][][] tileAssignments) final int [][][] tileAssignments)
{ {
final int imgTiles = imageTilesX * imageTilesY; final int imgTiles = imageTilesX * imageTilesY;
...@@ -2241,7 +2289,7 @@ public class TileSurface { ...@@ -2241,7 +2289,7 @@ public class TileSurface {
System.out.println("getConsensusAssignment(): nTile="+nTile); System.out.println("getConsensusAssignment(): nTile="+nTile);
} }
int num_agree = 0; int num_agree = 0;
ArrayList <Integer> alts = new ArrayList <Integer>(); ArrayList <Integer> alts = new ArrayList <Integer>(); // elements are 1-based surfaces
for (int n = 0; n < num_in; n++)if (tileAssignments[n] != null){ for (int n = 0; n < num_in; n++)if (tileAssignments[n] != null){
int surf1 = tileAssignments[n][ml][nTile]; int surf1 = tileAssignments[n][ml][nTile];
if (surf1 != 0){ if (surf1 != 0){
...@@ -2279,6 +2327,7 @@ public class TileSurface { ...@@ -2279,6 +2327,7 @@ public class TileSurface {
* Assign tiles that were used to generate planes. Only tiles in the center (non-overlapping) part of the supertile * Assign tiles that were used to generate planes. Only tiles in the center (non-overlapping) part of the supertile
* @param force re-assign tile if it was already assigned * @param force re-assign tile if it was already assigned
* @param tileLayers * @param tileLayers
* @param noEdge do not assign tiles to the surface edges (can not add border later)
* @param debugLevel * @param debugLevel
* @param dbg_X * @param dbg_X
* @param dbg_Y * @param dbg_Y
...@@ -2289,6 +2338,7 @@ public class TileSurface { ...@@ -2289,6 +2338,7 @@ public class TileSurface {
final boolean force, final boolean force,
final int [][] tileLayers, final int [][] tileLayers,
final TilePlanes.PlaneData[][] planes, final TilePlanes.PlaneData[][] planes,
final boolean noEdge,
final int debugLevel, final int debugLevel,
final int dbg_X, final int dbg_X,
final int dbg_Y) final int dbg_Y)
...@@ -2335,9 +2385,10 @@ public class TileSurface { ...@@ -2335,9 +2385,10 @@ public class TileSurface {
int ns = -1; int ns = -1;
for (int ml = 0; ml < meas_sel.length; ml++) if (meas_sel[ml] != null){ for (int ml = 0; ml < meas_sel.length; ml++) if (meas_sel[ml] != null){
if (meas_sel[ml][st_index]){ if (meas_sel[ml][st_index]){
int nSurfTile = -1;
if (ns < 0){ // find for the first used ml, if there are more - they will reuse if (ns < 0){ // find for the first used ml, if there are more - they will reuse
nTile = (superTileSize * sty + dy) * imageTilesX + (superTileSize * stx + dx); nTile = (superTileSize * sty + dy) * imageTilesX + (superTileSize * stx + dx);
int nSurfTile = getSurfaceTileIndex(nTile); nSurfTile = getSurfaceTileIndex(nTile);
for (int i = 0; i < tileData[nSurfTile].length; i ++){ for (int i = 0; i < tileData[nSurfTile].length; i ++){
if ( (tileData[nSurfTile][i].getParentNsTile() == nsTile) && if ( (tileData[nSurfTile][i].getParentNsTile() == nsTile) &&
(tileData[nSurfTile][i].getParentLayer() == np)) { (tileData[nSurfTile][i].getParentLayer() == np)) {
...@@ -2359,9 +2410,24 @@ public class TileSurface { ...@@ -2359,9 +2410,24 @@ public class TileSurface {
(superTileSize * sty + dy)+")"); (superTileSize * sty + dy)+")");
} }
} }
if ((ns >= 0) && (force || (tileLayers[ml][nTile] == 0))) { if ((ns >= 0) && (force || (tileLayers[ml][nTile] == 0))) {
tileLayers[ml][nTile] = ns + 1; boolean bad_edge = noEdge;
stats_all[numThread][NEW_ASSIGNED] ++; if (bad_edge) {
bad_edge = false;
int []neibs = tileData[nSurfTile][ns].getNeighbors();
for (int i = 0; i < neibs.length; i++) if (neibs[i] < 0) {
bad_edge = true;
break;
}
}
if (bad_edge) {
stats_all[numThread][NO_SURF] ++;
tileLayers[ml][nTile] = IMPOSSIBLE;
} else {
tileLayers[ml][nTile] = ns + 1;
stats_all[numThread][NEW_ASSIGNED] ++;
}
} }
} }
} }
...@@ -2560,8 +2626,10 @@ public class TileSurface { ...@@ -2560,8 +2626,10 @@ public class TileSurface {
// calculate index in tileData (has different dimensions - TODO: trim? // calculate index in tileData (has different dimensions - TODO: trim?
int nSurfTile1 = getSurfaceTileIndex(nTile1); int nSurfTile1 = getSurfaceTileIndex(nTile1);
int ns1 = neibs[dir]; int ns1 = neibs[dir];
System.out.println("growWeakAssigned(): nTile="+pTile.x+" ns="+pTile.y+" dir = "+dir+ if (debugLevel > 0) {
" nSurfTile="+nSurfTile+" nSurfTile1="+nSurfTile1+" ns1="+ns1); System.out.println("growWeakAssigned(): nTile="+pTile.x+" ns="+pTile.y+" dir = "+dir+
" nSurfTile="+nSurfTile+" nSurfTile1="+nSurfTile1+" ns1="+ns1);
}
boolean bad_edge = noEdge; boolean bad_edge = noEdge;
if (bad_edge) { if (bad_edge) {
bad_edge = false; bad_edge = false;
...@@ -3750,7 +3818,7 @@ public class TileSurface { ...@@ -3750,7 +3818,7 @@ public class TileSurface {
if (nl1 < 0){ if (nl1 < 0){
if (debugLevel >-1) { if (debugLevel >-1) {
System.out.println("growClusterOnce(): Expected 8 neighbors for tile nSurfTile0="+ System.out.println("growClusterOnce(): Expected 8 neighbors for tile nSurfTile0="+
nSurfTile0+" neibs["+dir+"] = "+nl1); nSurfTile0+":"+nl0+" neibs["+dir+"] = "+nl1);
} }
} else { } else {
int neTile1 = tnWindow.getNeibIndex(neTile0, dir); int neTile1 = tnWindow.getNeibIndex(neTile0, dir);
...@@ -4176,7 +4244,7 @@ public class TileSurface { ...@@ -4176,7 +4244,7 @@ public class TileSurface {
if (nl1 < 0){ if (nl1 < 0){
if (debugLevel >-1) { if (debugLevel >-1) {
System.out.println("growEachCluster(): Expected 8 neighbors for tile nSurfTile0="+ System.out.println("growEachCluster(): Expected 8 neighbors for tile nSurfTile0="+
nSurfTile0+" neibs["+dir+"] = "+nl1); nSurfTile0+":"+nl0+" neibs["+dir+"] = "+nl1);
} }
int nTile1 = tnImage.getNeibIndex(nTile0, dir); int nTile1 = tnImage.getNeibIndex(nTile0, dir);
if (nTile1 >= 0) { if (nTile1 >= 0) {
......
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