Commit 960d054f authored by Andrey Filippov's avatar Andrey Filippov

tested conflicts with variable costs

parent 364204c4
......@@ -248,5 +248,42 @@ public class Conflict{
return num_dual;
}
/**
* Get directions from center and layers of the 2 non-center tiles involved in each triangular conflict
* Full triangle is center:nl1 -> dir1 -> dir2 -> center:nl2
* @return array of 2-tuples:{dir1, dir2}
*/
public int [][] getInvolvedTiles(){
int [][] involved = new int [getNumConflicts()][2];
int nt = 0;
for (int i = 0; i < 4; i++){
if (start_dirs[i + 0]) {
involved[nt][0] = i * 2;
involved[nt++][1] = ((i * 2) + 2) % 8;
}
if (start_dirs[i + 4]) {
involved[nt][0] = ((i * 2) + 2) % 8;
involved[nt++][1] = i * 2;
}
if (start_dirs[i + 8]) {
involved[nt][0] = i * 2;
involved[nt++][1] = ((i * 2) + 1) % 8;
}
if (start_dirs[i + 12]) {
involved[nt][0] = ((i * 2) + 1) % 8;
involved[nt++][1] = i * 2;
}
if (start_dirs[i + 16]) {
involved[nt][0] = i * 2;
involved[nt++][1] = ((i * 2) + 7) % 8;
}
if (start_dirs[i + 20]) {
involved[nt][0] = ((i * 2) + 7) % 8;
involved[nt++][1] = i * 2;
}
}
return involved;
}
}
......@@ -198,6 +198,34 @@ public class Conflicts {
if (better? (num_ortho_dual < 0) : (num_ortho_dual > 0)) num++;
}
if (use_ood) {
for (int i = 0; i < num_ortho_ortho_diag.length; i++){
if (better?(num_ortho_ortho_diag[i] < 0):(num_ortho_ortho_diag[i] > 0)) num++;
}
}
return num;
}
public int sumConflicts(
boolean use_all,
boolean use_odo,
boolean use_ood)
{
int num = 0;
if (use_all) {
for (int i = 0; i < num_all_conflicts.length; i++){
num += num_all_conflicts[i];
}
}
if (use_odo) {
for (int i = 0; i < num_ortho_diag_ortho.length; i++){
num +=num_ortho_diag_ortho[i];
}
}
if (use_ood) {
for (int i = 0; i < num_ortho_ortho_diag.length; i++){
num +=num_ortho_ortho_diag[i];
}
}
return num;
}
......@@ -286,11 +314,157 @@ public class Conflicts {
return conflicts;
}
/**
* Calculate cost of all conflicts around supertile nsTile0 by adding "star" weight of each tile involved.
* Tile weight can be either from the planes[][] array or from the replacement values in replacement_val_weights
* (when the tiles configuration is not yet committed)
* @param nsTile0 supertile index to process
* @param scaleStartEnd for each conflict triangle add start and end tiles (at the center nsTile0) scaled by this value
* @param conflicts array of calculated conflicts (each is {start_layer, end_layer, direction/type bitmask} or null,
* in that case it will be calculated
* @param replacement_tiles a map of supertile indices to replacement indices (for replacement_neibs and
* replacement_val_weights) or null. If not null, and entry for the supertile full index exists,
* replacement_neibs and replacement_val_weights will be used, otherwise planes[][] data.
* replacement_tiles may be null, in that case planes[][] data will be used unconditionally.
* @param replacement_neibs array of neighbors to use instead of the planes data. First index is an index
* of the replacement supertile (values in the replacement_tiles map), second - layer number and
* the 3-rd one - direction index for 8 connections: N, NE, E...NW. Value is the destination layer
* number. Can be null if not used (when replacement_tiles is null)
* @param replacement_val_weights similar array for tile value/weight data (per-tile index, per layer).
* The innermost data is a tuple {value, weight}
* @param tnSurface TileNeibs instance to navigate through the 2-d array encoded in linescan order
* @return sum ao the weights of all conflicts fro this tile
*/
public double getConflictsCost(
int nsTile0,
double scaleStartEnd, // include start and and layer tiles in the center in overall cost for each triangle (1.0)
int [][] conflicts, //
HashMap<Integer,Integer> replacement_tiles, // null is OK
int [][][] replacement_neibs, // null OK if replacement_tiles == null
double [][][] replacement_val_weights,
TileSurface.TileNeibs tnSurface)
{
TilePlanes.PlaneData [][] planes = st.getPlanes();
// generate conflicts if not provided
if (conflicts == null) {
conflicts = detectTriangularTileConflicts(
nsTile0,
replacement_tiles, //
replacement_neibs,
tnSurface);
}
double cost = 0.0;
if (conflicts != null){
Integer isTile = (replacement_tiles != null) ? replacement_tiles.get(nsTile0) : null;
for (int nConfl = 0; nConfl < conflicts.length; nConfl++){
Conflict conflict = new Conflict(nsTile0, conflicts[nConfl]);
int start_layer = conflict.getStartLayer();
int end_layer = conflict.getEndLayer();
int [] neibs1 = ((isTile == null) ?
planes[nsTile0][start_layer].getNeibBest() :
replacement_neibs[isTile][start_layer]);
int [] neibs2 = ((isTile == null) ?
planes[nsTile0][end_layer].getNeibBest() :
replacement_neibs[isTile][end_layer]);
int [][] involved = conflict.getInvolvedTiles();
for (int nTri = 0; nTri < involved.length; nTri++){
int [] nsTiles = {
tnSurface.getNeibIndex(nsTile0, involved[nTri][0]),
tnSurface.getNeibIndex(nsTile0, involved[nTri][1])};
int [] layers = {neibs1[involved[nTri][0]], neibs2[involved[nTri][1]]};
for (int it = 0; it < nsTiles.length; it++){
Integer isTile1 = (replacement_tiles != null) ? replacement_tiles.get(nsTiles[it]) : null;
if (isTile1 != null){
cost += replacement_val_weights[isTile1][layers[it]][1];
} else {
cost += planes[nsTiles[it]][layers[it]].getStarValueWeight()[1];
}
}
}
if (scaleStartEnd != 0.0) {
if (isTile != null){
cost += scaleStartEnd * (replacement_val_weights[isTile][start_layer][1]+
replacement_val_weights[isTile][end_layer][1]);
} else {
cost += scaleStartEnd * (planes[nsTile0][start_layer].getStarValueWeight()[1]+
planes[nsTile0][end_layer].getStarValueWeight()[1]);
}
}
}
}
return cost;
}
public double getConflictsCost(
int nsTile0,
double scaleStartEnd, // include start and and layer tiles in the center in overall cost for each triangle (1.0)
int [][] conflicts, //
HashMap<Integer,Integer> replacement_tiles, // null is OK
int [][][] replacement_neibs, // null OK if replacement_tiles == null
ConnectionCosts connectionCosts,
TileSurface.TileNeibs tnSurface)
{
TilePlanes.PlaneData [][] planes = st.getPlanes();
// generate conflicts if not provided
if (conflicts == null) {
conflicts = detectTriangularTileConflicts(
nsTile0,
replacement_tiles, //
replacement_neibs,
tnSurface);
}
double cost = 0.0;
if (conflicts != null){
Integer isTile = (replacement_tiles != null) ? replacement_tiles.get(nsTile0) : null;
for (int nConfl = 0; nConfl < conflicts.length; nConfl++){
Conflict conflict = new Conflict(nsTile0, conflicts[nConfl]);
int start_layer = conflict.getStartLayer();
int end_layer = conflict.getEndLayer();
int [] neibs1 = ((isTile == null) ?
planes[nsTile0][start_layer].getNeibBest() :
replacement_neibs[isTile][start_layer]);
int [] neibs2 = ((isTile == null) ?
planes[nsTile0][end_layer].getNeibBest() :
replacement_neibs[isTile][end_layer]);
int [][] involved = conflict.getInvolvedTiles();
for (int nTri = 0; nTri < involved.length; nTri++){
int [] nsTiles = {
tnSurface.getNeibIndex(nsTile0, involved[nTri][0]),
tnSurface.getNeibIndex(nsTile0, involved[nTri][1])};
int [] layers = {neibs1[involved[nTri][0]], neibs2[involved[nTri][1]]};
for (int it = 0; it < nsTiles.length; it++){
cost += connectionCosts. getValWeightLast(
nsTiles[it], // int nsTile,
layers[it], // int nl,
false)[1]; // boolean initialValue)
}
}
if (scaleStartEnd != 0.0) {
cost += scaleStartEnd * connectionCosts. getValWeightLast(
nsTile0, // int nsTile,
start_layer, // int nl,
false)[1]; // boolean initialValue)
cost += scaleStartEnd * connectionCosts. getValWeightLast(
nsTile0, // int nsTile,
end_layer, // int nl,
false)[1]; // boolean initialValue)
}
}
}
return cost;
}
public int [][] detectTriangularTileConflicts(
int nsTile0,
HashMap<Integer,Integer> replacement_tiles, //
int [][][] replacement_neibs,
HashMap<Integer,Integer> replacement_tiles, // null is OK - will use only planes data
int [][][] replacement_neibs, // null OK if replacement_tiles == null
TileSurface.TileNeibs tnSurface)
{
TilePlanes.PlaneData [][] planes = st.getPlanes();
......
......@@ -36,10 +36,12 @@ public class ConnectionCosts {
int [][][] neibs_init;
int [] mod_tiles;
int [] all_tiles;
double [][][] val_weights;
double [][][] val_weights; // initial values/weights
double init_val;
double init_weight;
double [][][] last_val_weights; // last calculated
HashMap<Integer,Integer> tile_map; // map from tile full index to index in neibs[] and
HashMap<Integer,Integer> all_tile_map; // map from tile full index to index in val_weights[] and
public ConnectionCosts(
double orthoWeight,
......@@ -93,6 +95,11 @@ public class ConnectionCosts {
tile_map.put(mod_tiles[i], i);
}
all_tile_map = new HashMap<Integer,Integer>();
for (int i = 0; i < all_tiles.length; i++){
all_tile_map.put(all_tiles[i], i);
}
switch (steps){
case 1:
val_weights = getConnectionsCostSingleStep (
......@@ -110,6 +117,8 @@ public class ConnectionCosts {
-1); // int debugLevel)
}
last_val_weights = val_weights;
init_val = 0.0;
init_weight = 0.0; // should not change during update
for (int isTile = 0; isTile < all_tiles.length; isTile++){
......@@ -125,6 +134,35 @@ public class ConnectionCosts {
return neibs_init; // neighbors to clone
}
public double [] getValWeightLast(
int nsTile,
int nl,
boolean initialValue)
{
Integer isTile = all_tile_map.get(nsTile);
if ((isTile != null) && (isTile < 0)){
System.out.println("isTile < 0");
}
if (nl < 0){
System.out.println(" nl < 0");
}
if ((isTile != null) && (isTile >= 0)){
return initialValue? val_weights[isTile][nl] : last_val_weights[isTile][nl];
} else {
return planes[nsTile][nl].getStarValueWeight();
}
}
public double [] getValWeight()
{
double [] val_weight = {init_val,init_weight};
return val_weight;
}
public double [][][] getValWeights()
{
return val_weights;
}
public double [][][] getConnectionsCostSingleStep (
int [][][] neibs,
......@@ -272,7 +310,7 @@ public class ConnectionCosts {
neibs,
-1); // int debugLevel)
}
last_val_weights = vw;
// calculate new cost
double new_value = 0.0;
double new_weight = 0.0; // should not change during update
......@@ -288,6 +326,9 @@ public class ConnectionCosts {
return new_value - init_val; // negative - improvement
}
double [][][] getLastValueWeight(){
return last_val_weights;
}
/**
* Calculate main eigenvalue of the current plane and all connected ones - used to estimate advantage of connection swap
* @param nsTile supertile index
......
This diff is collapsed.
......@@ -82,6 +82,7 @@ public class TilePlanes {
int smplNum = 3; // Number after removing worst
double smplRms = 0.1; // Maximal RMS of the remaining tiles in a sample
double [] starValueWeight = null;
boolean preferDisparity = false;
......@@ -133,9 +134,29 @@ public class TilePlanes {
pd.preferDisparity = this.preferDisparity;
copyNeib(this,pd);
if (starValueWeight != null){
pd.starValueWeight = starValueWeight.clone();
}
return pd;
}
public void setStarValueWeight(double value, double weight){
this.starValueWeight = new double[2];
this.starValueWeight[0] = value;
this.starValueWeight[1] = weight;
}
public void setStarValueWeight(double[] val_weight){
this.starValueWeight = val_weight;
}
public double [] getStarValueWeight()
{
return starValueWeight;
}
public void setSelMask (boolean []sel_mask)
{
this.sel_mask = sel_mask;
......
......@@ -3445,6 +3445,25 @@ public class TileProcessor {
1, // final int debugLevel)
clt_parameters.tileX,
clt_parameters.tileY);
/*
st.resolveConflicts(
clt_parameters.plMaxEigen,
clt_parameters.plConflDualTri, // boolean conflDualTri, // Resolve dual triangles conflict (odoodo)
clt_parameters.plConflMulti, // boolean conflMulti, // Resolve multiple odo triangles conflicts
clt_parameters.plConflDiag, // boolean conflDiag, // Resolve diagonal (ood) conflicts
clt_parameters.plConflStar, // boolean conflStar, // Resolve all conflicts around a supertile
clt_parameters.plStarSteps, // int starSteps, // How far to look around when calculationg connection cost
clt_parameters.plStarOrtho, // double orthoWeight,
clt_parameters.plStarDiag, // double diagonalWeight,
clt_parameters.plStarPwr, // double starPwr, // Divide cost by number of connections to this power
clt_parameters.plDblTriLoss, // double diagonalWeight,
true, // clt_parameters.plNewConfl, // Allow more conflicts if overall cost is reduced
clt_parameters.plPreferDisparity,
1, // final int debugLevel)
clt_parameters.tileX,
clt_parameters.tileY);
*/
if (clt_parameters.plSplitApply) {
while (true) {
......
......@@ -154,9 +154,29 @@ public class TwoLayerNeighbors {
if (old_nl1 >= 0){
neibs_start[old_nl1][dir12] = old_nl2; // (old_nl2 may be -1 here)
}
}
public int getConnection(
int dir,
int nl,
int dir2)
{
int [][] neibs_start = getNeighbors(dir);
int dir12 = getDir2From1(dir, dir2);
if (dir12 <0){
throw new IllegalArgumentException ("Invalid connection from "+dir+" to "+dir2+": resulted in direction 1->2 = "+dir12);
}
if (neibs_start.length <= nl){
System.out.println("BUG");
return -1;
}
return neibs_start[nl][dir12];
}
public void diffToOther(NeibVariant other_variant)
{
for (int dir0 = 0; dir0 < neighbors.length; dir0++){
......@@ -200,8 +220,8 @@ public class TwoLayerNeighbors {
// increment connection variant if possible
for (int np = 0; np < PAIRS.length; np++){
if ((num_se[np] != null) && (num_se[np][0] == 2) && (num_se[np][1] == 2) && (conns[np] != null) && (conns[np].length == 1)){
if (selection_conns[np] == 0){
selection_conns[np] = 1;
if (selection_conns[np] < 2){
selection_conns[np]++; // = 1;
for (int i = 0; i < np; i ++){
selection_conns[i] = 0;
}
......@@ -275,7 +295,9 @@ public class TwoLayerNeighbors {
int start_dir = PAIRS[np][0];
int end_dir = PAIRS[np][1];
boolean swap = (selection_star[start_dir] != selection_star[end_dir]) ^ (selection_conns[np] > 0);
boolean swap = (selection_star[start_dir] != selection_star[end_dir]) ^ (selection_conns[np] == 1);
int [] opts = {0,0};
if (swap){
if (num_se[np][0] > 1){
......@@ -290,6 +312,23 @@ public class TwoLayerNeighbors {
end_dir, // int dir2,
layers_around[end_dir][opts[1]], // int nl2);
debugLevel);
if (selection_conns[np] > 1){
// add 3-rd variant if possible, if not - return null
// if at least one of the unused ends has a pair - connect other ends
int nl_start_other = layers_around[start_dir][1-opts[0]];
int nl_end_other = layers_around[end_dir][1-opts[1]];
if ( (variant.getConnection(start_dir,nl_start_other,end_dir) >= 0) ||
(variant.getConnection(end_dir,nl_end_other,start_dir) >= 0)) {
variant.connect(
start_dir, // int dir1,
nl_start_other, // int nl1,
end_dir, // int dir2,
nl_end_other, // int nl2);
debugLevel);
} else {
return null; // failed to swap connection - other ends are both not connected
}
}
}
if (debugLevel > 1){
System.out.println();
......
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