Commit 3a9193c3 authored by Andrey Filippov's avatar Andrey Filippov

tested refactoring

parent 3ead1b3d
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicInteger;
/** /**
** **
** LinkPlanes - manage links between supertile planes ** LinkPlanes - manage links between supertile planes
...@@ -79,6 +82,7 @@ public class LinkPlanes { ...@@ -79,6 +82,7 @@ public class LinkPlanes {
plMinStrength = clt_parameters.plMinStrength; plMinStrength = clt_parameters.plMinStrength;
dbg_tileX = clt_parameters.tileX; dbg_tileX = clt_parameters.tileX;
dbg_tileY = clt_parameters.tileY; dbg_tileY = clt_parameters.tileY;
this.st = st;
} }
public boolean planesFit( public boolean planesFit(
TilePlanes.PlaneData plane1, // should belong to the same supertile (or be converted for one) TilePlanes.PlaneData plane1, // should belong to the same supertile (or be converted for one)
...@@ -179,15 +183,15 @@ public class LinkPlanes { ...@@ -179,15 +183,15 @@ public class LinkPlanes {
this_rq_eq_norm+" <= plWorstEq2="+plWorstEq2+")"); this_rq_eq_norm+" <= plWorstEq2="+plWorstEq2+")");
System.out.println(); System.out.println();
if (debugLevel > 1){ if (debugLevel > 1){
System.out.println(prefix+" this_rq="+this_rq+ System.out.println(prefix+" (fit) this_rq="+this_rq+
", this_rq_eq="+this_rq_eq+ ", this_rq_eq="+this_rq_eq+
" w1="+w1+" w2="+w2+ " w1="+w1+" w2="+w2+
" L1="+plane1.getValue()+" L2="+plane2.getValue()+ " L1="+plane1.getValue()+" L2="+plane2.getValue()+
" L="+merged_ev+" L_eq="+merged_ev_eq); " L="+merged_ev+" L_eq="+merged_ev_eq);
System.out.println(prefix+", world sin2 ="+ System.out.println(prefix+" (fit) world sin2 ="+
plane1.getWorldSin2(plane2)); plane1.getWorldSin2(plane2));
System.out.println(prefix+ System.out.println(prefix+ " (fit)" +
", world dist this="+ Math.sqrt(plane1.getWorldPlaneDist2(plane2))+ " world dist this="+ Math.sqrt(plane1.getWorldPlaneDist2(plane2))+
", world dist other="+Math.sqrt(plane2.getWorldPlaneDist2(plane1))+ ", world dist other="+Math.sqrt(plane2.getWorldPlaneDist2(plane1))+
", world dist sum="+Math.sqrt(plane1.getWorldPlaneDist2(plane2)+ ", world dist sum="+Math.sqrt(plane1.getWorldPlaneDist2(plane2)+
plane2.getWorldPlaneDist2(plane1))); plane2.getWorldPlaneDist2(plane1)));
...@@ -197,16 +201,16 @@ public class LinkPlanes { ...@@ -197,16 +201,16 @@ public class LinkPlanes {
} }
} }
if (debugLevel > 0) { if (debugLevel > 0) {
System.out.print(prefix+": planes DO NOT FIT"); System.out.println(prefix+": planes DO NOT FIT");
if (debugLevel > 1){ if (debugLevel > 1){
System.out.println(prefix+" this_rq="+this_rq+ System.out.println(prefix+" (do not fit) this_rq="+this_rq+
", this_rq_eq="+this_rq_eq+ ", this_rq_eq="+this_rq_eq+
" w1="+w1+" w2="+w2+ " w1="+w1+" w2="+w2+
" L1="+plane1.getValue()+" L2="+plane2.getValue()+ " L1="+plane1.getValue()+" L2="+plane2.getValue()+
" L="+merged_ev+" L_eq="+merged_ev_eq); " L="+merged_ev+" L_eq="+merged_ev_eq);
System.out.println(prefix+", world sin2 ="+ System.out.println(prefix+" (do not fit) world sin2 ="+
plane1.getWorldSin2(plane2)); plane1.getWorldSin2(plane2));
System.out.println(prefix+ System.out.println(prefix+" (do not fit)"+
", world dist this="+ Math.sqrt(plane1.getWorldPlaneDist2(plane2))+ ", world dist this="+ Math.sqrt(plane1.getWorldPlaneDist2(plane2))+
", world dist other="+Math.sqrt(plane2.getWorldPlaneDist2(plane1))+ ", world dist other="+Math.sqrt(plane2.getWorldPlaneDist2(plane1))+
", world dist sum="+Math.sqrt(plane1.getWorldPlaneDist2(plane2)+ ", world dist sum="+Math.sqrt(plane1.getWorldPlaneDist2(plane2)+
...@@ -216,7 +220,7 @@ public class LinkPlanes { ...@@ -216,7 +220,7 @@ public class LinkPlanes {
return false; return false;
} }
public double getFitQuality( public double [] getFitQualities(
TilePlanes.PlaneData plane1, // should belong to the same supertile (or be converted for one) TilePlanes.PlaneData plane1, // should belong to the same supertile (or be converted for one)
TilePlanes.PlaneData plane2, TilePlanes.PlaneData plane2,
double merged_ev, // if NaN will calculate assuming the same supertile double merged_ev, // if NaN will calculate assuming the same supertile
...@@ -224,7 +228,7 @@ public class LinkPlanes { ...@@ -224,7 +228,7 @@ public class LinkPlanes {
String prefix, String prefix,
int debugLevel) int debugLevel)
{ {
if ((plane1 == null) || (plane2 == null)) return 0.0; if ((plane1 == null) || (plane2 == null)) return null;
TilePlanes.PlaneData merged_pd = null; TilePlanes.PlaneData merged_pd = null;
TilePlanes.PlaneData merged_pd_eq = null; TilePlanes.PlaneData merged_pd_eq = null;
if (Double.isNaN(merged_ev)) { if (Double.isNaN(merged_ev)) {
...@@ -292,9 +296,593 @@ public class LinkPlanes { ...@@ -292,9 +296,593 @@ public class LinkPlanes {
plane2.getWorldPlaneDist2(plane1))); plane2.getWorldPlaneDist2(plane1)));
} }
} }
return this_rq; // TODO: add modes to select what is output double [] qualities = {this_rq,this_rq_eq};
return qualities; // TODO: add modes to select what is output
}
public void matchPlanes(
final TilePlanes.PlaneData [][] planes,
final int debugLevel,
final int dbg_X,
final int dbg_Y)
{
final int tilesX = st.tileProcessor.getTilesX();
final int tilesY = st.tileProcessor.getTilesY();
final int superTileSize = st.tileProcessor.getSuperTileSize();
// final int tileSize = tileProcessor.getTileSize();
final int stilesX = (tilesX + superTileSize -1)/superTileSize;
final int stilesY = (tilesY + superTileSize -1)/superTileSize;
final int nStiles = stilesX * stilesY;
final double [] nan_plane = new double [superTileSize*superTileSize];
for (int i = 0; i < nan_plane.length; i++) nan_plane[i] = Double.NaN;
final int [][] dirsYX = {{-1, 0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};
// final int debug_stile = 20 * stilesX + 27;
final int debug_stile = dbg_Y * stilesX + dbg_X;
final Thread[] threads = ImageDtt.newThreadArray(st.tileProcessor.threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
// Select best symmetrical match, consider only N, NE, E, SE - later opposite ones will be copied
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
// TilePlanes.PlaneData [] dbg_planes = null;
for (int nsTile0 = ai.getAndIncrement(); nsTile0 < nStiles; nsTile0 = ai.getAndIncrement()) {
int sty0 = nsTile0 / stilesX;
int stx0 = nsTile0 % stilesX;
int dl = ((debugLevel > -1) && (nsTile0 == debug_stile)) ? 1:0;
if ( planes[nsTile0] != null) {
if (dl > 0){
System.out.println("matchPlanes(): nsTile0 ="+nsTile0);
// dbg_planes = planes[nsTile0];
}
for (int np0 = 0; np0 < planes[nsTile0].length; np0++){ // nu
// planes[nsTile0][np0].initNeibBest(); //
TilePlanes.PlaneData this_plane = planes[nsTile0][np0];
if (this_plane != null) {
this_plane.initMergedValue();
for (int dir = 0; dir < 4; dir++){ // just half directions - relations are symmetrical
int stx = stx0 + dirsYX[dir][1];
int sty = sty0 + dirsYX[dir][0];
// if ((sty < stilesY) && (sty > 0) && (stx < 0)) {
if ((stx < stilesX) && (sty < stilesY) && (sty > 0)) {
int nsTile = sty * stilesX + stx; // from where to get
if (nsTile >= planes.length){
System.out.println("BUG!!!!");
} else {
TilePlanes.PlaneData [] other_planes = planes[nsTile];
if (other_planes != null) {
this_plane.initMergedValue(dir,other_planes.length); // filled with NaN
for (int np = 0; np < other_planes.length; np ++){
if (other_planes[np] != null) {
TilePlanes.PlaneData other_plane = this_plane.getPlaneToThis(
other_planes[np],
dl-1); // debugLevel);
if (other_plane !=null) { // now always, but may add later
TilePlanes.PlaneData merged_pd = this_plane.mergePlaneToThis(
other_plane, // PlaneData otherPd,
1.0, // double scale_other,
1.0, // double starWeightPwr, // Use this power of tile weight when calculating connection cost
false, // boolean ignore_weights,
true, // boolean sum_weights,
plPreferDisparity,
dl-1); // int debugLevel)
if (merged_pd !=null) { // now always, but may add later
/// merged_pd.scaleWeight(0.5);
this_plane.setNeibMatch(dir, np, merged_pd.getValue()); // smallest eigenValue
}
merged_pd = this_plane.mergePlaneToThis(
other_plane, // PlaneData otherPd,
1.0, // double scale_other,
1.0, // double starWeightPwr, // Use this power of tile weight when calculating connection cost
true, // false, // boolean ignore_weights,
true, // boolean sum_weights,
plPreferDisparity,
dl-1); // int debugLevel)
if (merged_pd !=null) { // now always, but may add later
/// merged_pd.scaleWeight(0.5);
this_plane.setNeibMatchEq(dir, np, merged_pd.getValue()); // smallest eigenValue
}
}
}
}
}
}
}
}
}
}
if (dl > 0){
System.out.println("matchPlanes(): nsTile0 ="+nsTile0+ " Done.");
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
// copy symmetrical relations
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
// TilePlanes.PlaneData [][] dbg_planes = planes;
for (int nsTile0 = ai.getAndIncrement(); nsTile0 < nStiles; nsTile0 = ai.getAndIncrement()) {
int sty0 = nsTile0 / stilesX;
int stx0 = nsTile0 % stilesX;
int dl = ((debugLevel > -1) && (nsTile0 == debug_stile)) ? 1:0;
if (dl>0) {
System.out.println("matchPlanes() nsTile0="+nsTile0);
}
if ( planes[nsTile0] != null) {
for (int np0 = 0; np0 < planes[nsTile0].length; np0++){ // nu
TilePlanes.PlaneData this_plane = planes[nsTile0][np0];
if (this_plane != null) {
for (int dir = 4; dir < 8; dir++){ // other half - copy from opposite
int stx = stx0 + dirsYX[dir][1];
int sty = sty0 + dirsYX[dir][0];
if ((sty < stilesY) && (sty > 0) && (stx > 0)) {
int nsTile = sty * stilesX + stx; // from where to get
TilePlanes.PlaneData [] other_planes = planes[nsTile];
if (other_planes !=null) {
this_plane.initMergedValue(dir,other_planes.length); // filled with NaN
for (int np = 0; np < other_planes.length; np ++){
if (other_planes[np] != null) { // && (other_planes[np].getMergedValue(dir-4) != null)) {
double [] nm = other_planes[np].getMergedValue(dir-4);
if (nm != null) {
this_plane.setNeibMatch(dir,np, nm[np0]); //
}
nm = other_planes[np].getMergedValueEq(dir-4);
if (nm != null) {
this_plane.setNeibMatchEq(dir,np, nm[np0]); //
}
}
}
}
}
}
}
}
}
if (dl>0) {
System.out.println("matchPlanes() nsTile0="+nsTile0);
}
}
}
};
}
ImageDtt.startAndJoin(threads);
}
/**
* Mark which links between neighbor planes are valid
* @param debugLevel debug level
* @param dbg_X debug supertile X coordinate
* @param dbg_Y debug supertile Y coordinate
*/
public void filterNeighborPlanes(
final TilePlanes.PlaneData [][] planes,
final int debugLevel,
final int dbg_X,
final int dbg_Y)
{
final int tilesX = st.tileProcessor.getTilesX();
final int tilesY = st.tileProcessor.getTilesY();
final int superTileSize = st.tileProcessor.getSuperTileSize();
// final int tileSize = tileProcessor.getTileSize();
final int stilesX = (tilesX + superTileSize -1)/superTileSize;
final int stilesY = (tilesY + superTileSize -1)/superTileSize;
final int nStiles = stilesX * stilesY;
final double [] nan_plane = new double [superTileSize*superTileSize];
for (int i = 0; i < nan_plane.length; i++) nan_plane[i] = Double.NaN;
final int [][] dirsYX = {{-1, 0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};
// final int debug_stile = 20 * stilesX + 27;
// final int debug_stile = 17 * stilesX + 27;
// final int debug_stile = 9 * stilesX + 26;
final int debug_stile = dbg_Y * stilesX + dbg_X;
final Thread[] threads = ImageDtt.newThreadArray(st.tileProcessor.threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
// TilePlanes.PlaneData [][] dbg_planes = planes;
for (int nsTile0 = ai.getAndIncrement(); nsTile0 < nStiles; nsTile0 = ai.getAndIncrement()) {
int sty0 = nsTile0 / stilesX;
int stx0 = nsTile0 % stilesX;
int dl = (nsTile0 == debug_stile) ? 1:0;
if ( planes[nsTile0] != null) {
if (dl > 0){
System.out.println("filterNeighborPlanes() nsTile0="+nsTile0);
}
int np0_min = (planes[nsTile0].length > 1) ? 1:0; // Modify if overall plane will be removed
for (int dir = 0; dir < 4; dir++){ //
int stx = stx0 + dirsYX[dir][1];
int sty = sty0 + dirsYX[dir][0];
int nsTile = sty * stilesX + stx; // from where to get
for (int np0 = np0_min; np0 < planes[nsTile0].length; np0++){
if ((planes[nsTile0][np0] != null) && (planes[nsTile0][np0].getMergedValue(dir) != null)){
double [] merge_ev = planes[nsTile0][np0].getMergedValue(dir);
double [] merge_ev_eq = planes[nsTile0][np0].getMergedValueEq(dir);
if ( (merge_ev != null) &&
(merge_ev_eq != null)) {
int np_min = SuperTiles.LOWEST_PLANE(merge_ev.length);
for (int np = np_min; np < merge_ev.length; np++){
if ( (planes[nsTile][np] != null) &&
!Double.isNaN(merge_ev[np])) {
String prefix = "filterNeighborPlanes() nsTile0="+nsTile0+" np0="+np0+" dir="+dir+" nsTile="+nsTile+" np="+np;
if (planesFit(
planes[nsTile0][np0], // TilePlanes.PlaneData plane1, // should belong to the same supertile (or be converted for one)
planes[nsTile][np], // TilePlanes.PlaneData plane2,
merge_ev[np], // double merged_ev, // if NaN will calculate assuming the same supertile
merge_ev_eq[np], //double merged_ev_eq, // if NaN will calculate assuming the same supertile
prefix, // String prefix,
dl) // int debugLevel)
){
planes[nsTile0][np0].setMergedValid(dir, np, true, planes[nsTile].length);
planes[nsTile][np].setMergedValid((dir + 4) %8, np0, true, planes[nsTile0].length);
}
}
}
}
}
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
}
/**
* Find mutual links between multi-layer planes for supertiles. requires that for each plane there are calculated smalles eigenvalues
* for merging with each plane for each of 8 neighbors
* @param debugLevel debug level
* @param dbg_X debug supertile X coordinate
* @param dbg_Y debug supertile Y coordinate
*/
public void selectNeighborPlanesMutual(
final TilePlanes.PlaneData [][] planes,
final int debugLevel,
final int dbg_X,
final int dbg_Y)
{
final int tilesX = st.tileProcessor.getTilesX();
final int tilesY = st.tileProcessor.getTilesY();
final int superTileSize = st.tileProcessor.getSuperTileSize();
// final int tileSize = tileProcessor.getTileSize();
final int stilesX = (tilesX + superTileSize -1)/superTileSize;
final int stilesY = (tilesY + superTileSize -1)/superTileSize;
final int nStiles = stilesX * stilesY;
final double [] nan_plane = new double [superTileSize*superTileSize];
for (int i = 0; i < nan_plane.length; i++) nan_plane[i] = Double.NaN;
final int [][] dirsYX = {{-1, 0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};
final int debug_stile = dbg_Y * stilesX + dbg_X;
final Thread[] threads = ImageDtt.newThreadArray(st.tileProcessor.threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nsTile0 = ai.getAndIncrement(); nsTile0 < nStiles; nsTile0 = ai.getAndIncrement()) {
if ( planes[nsTile0] != null) {
for (int np0 = 0; np0 < planes[nsTile0].length; np0++){ // nu
TilePlanes.PlaneData this_plane = planes[nsTile0][np0];
if (this_plane != null) {
this_plane.initNeibBest();
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
// TilePlanes.PlaneData [][] dbg_planes = planes;
for (int nsTile0 = ai.getAndIncrement(); nsTile0 < nStiles; nsTile0 = ai.getAndIncrement()) {
int sty0 = nsTile0 / stilesX;
int stx0 = nsTile0 % stilesX;
int dl = (nsTile0 == debug_stile) ? 1:0;
if ( planes[nsTile0] != null) {
if (dl > 0){
System.out.println(" ===== selectNeighborPlanesMutual() nsTile0="+nsTile0+" =====");
}
int np0_min = (planes[nsTile0].length > 1) ? 1:0; // Modify if overall plane will be removed
for (int dir = 0; dir < 4; dir++){ //
int stx = stx0 + dirsYX[dir][1];
int sty = sty0 + dirsYX[dir][0];
int nsTile = sty * stilesX + stx; // from where to get
int num_other_planes = 0;
for (int np0 = np0_min; np0 < planes[nsTile0].length; np0++){
if ((planes[nsTile0][np0] != null) && (planes[nsTile0][np0].getMergedValue(dir) != null)){
int l = planes[nsTile0][np0].getMergedValue(dir).length;
if (l > num_other_planes)num_other_planes = l;
}
}
if (num_other_planes > 0){ // will eliminate bad margins
int np_min = SuperTiles.LOWEST_PLANE(num_other_planes);
boolean [] this_matched = new boolean [planes[nsTile0].length];
boolean [] other_matched = new boolean [num_other_planes];
int num_pairs = this_matched.length - np0_min;
if ((other_matched.length - np_min) < num_pairs) num_pairs = other_matched.length - np_min;
for (int pair = 0; pair < num_pairs; pair ++){
// if (dl > 0){
// System.out.println(" pair = "+pair+" (of "+num_pairs+")");
// }
int [] best_pair = {-1,-1};
double best_rqual = Double.NaN;
for (int np0 = np0_min; np0 < this_matched.length; np0++) if (planes[nsTile0][np0] != null){
double [] merge_ev = planes[nsTile0][np0].getMergedValue(dir);
double [] merge_ev_eq = planes[nsTile0][np0].getMergedValueEq(dir);
// if (dl > 0){
// System.out.println(" np0 = "+np0+" (of ("+np0_min+"..."+this_matched.length+"), ");
// }
boolean [] merge_valid = planes[nsTile0][np0].getMergedValid(dir);
if (!this_matched[np0] &&(merge_valid != null)) {
for (int np = np_min; np < merge_ev.length; np++){
// if (dl > 0){
// System.out.println(" np = "+np+" (of ("+np_min+"..."+merge_ev.length+"), ");
// }
if (!other_matched[np] && merge_valid[np]) {
String prefix = "selectNeighborPlanesMutual(): nsTile0="+nsTile0+":"+np0+", nsTile="+nsTile+":"+np;
double [] qualities = getFitQualities( // {this_rq, this_rq_eq};
planes[nsTile0][np0], //TilePlanes.PlaneData plane1, // should belong to the same supertile (or be converted for one)
planes[nsTile][np], //TilePlanes.PlaneData plane2,
merge_ev[np], // double merged_ev, // if NaN will calculate assuming the same supertile
merge_ev_eq[np], // double merged_ev_eq, // if NaN will calculate assuming the same supertile
prefix, // String prefix,
dl); // int debugLevel)
if (qualities != null) {
double this_rq = qualities[0];
if (Double.isNaN(best_rqual) || (this_rq < best_rqual)){ // OK if Double.isNaN(this_rq[np])
if (dl > 0){
System.out.println(" ===== selectNeighborPlanesMutual) : nsTile0="+nsTile0+":"+np0+", nsTile="+nsTile+":"+np+", this_rq="+this_rq);
}
best_rqual = this_rq;
best_pair[0]= np0;
best_pair[1]= np;
}
}
}
}
}
}
if (Double.isNaN(best_rqual)){
if (dl >0) {
System.out.println("selectNeighborPlanesMutual - nothing more found for "+nsTile0+" dir = " + dir);
}
break; // nothing (more) found
}
this_matched[best_pair[0]] = true;
other_matched[best_pair[1]] = true;
// neib_best should be initialized as int [8];
// planes[nsTile0][0].initNeibBest();
if (dl >0) {
System.out.println("1. planes["+nsTile0+"]["+best_pair[0]+"].setNeibBest("+dir+","+best_pair[1]+")");
}
if (dl >0) {
System.out.println("2. planes["+nsTile+"]["+best_pair[1]+"].setNeibBest("+(dir+4)+","+best_pair[0]+")");
}
planes[nsTile0][best_pair[0]].setNeibBest(dir,best_pair[1]);
planes[nsTile][best_pair[1]].setNeibBest(dir + 4,best_pair[0]);
}
// disable remaining neighbors
for (int np = 0; np < this_matched.length; np++) if (planes[nsTile0][np] != null){
if (dl >0) {
System.out.println("this_matched["+np+"]="+this_matched[np]);
}
if (!this_matched[np]){
planes[nsTile0][np].setNeibBest(dir,-1);
}
}
// for (int np = 0; np < other_matched.length; np++) if (planes[nsTile][np] != null){
for (int np = 0; np < other_matched.length; np++) if ((planes[nsTile][np] != null) && (planes[nsTile][np].getWeight() > 0.0)){ // disregard 0-weight planes
if (!other_matched[np]){
if (dl >0) {
System.out.println("other_matched["+np+"]="+other_matched[np]);
}
planes[nsTile][np].setNeibBest(dir + 4,-1);
}
}
if (dl >0) {
for (int np = 0; np < this_matched.length; np++) if (planes[nsTile0][np] != null){
int [] bn = planes[nsTile0][np].getNeibBest();
System.out.println("nsTile0="+nsTile0+":"+np+" : ["+
bn[0]+","+bn[1]+","+bn[2]+","+bn[3]+","+bn[4]+","+bn[5]+","+bn[6]+","+bn[7]+"]");
}
// for (int np = 0; np < other_matched.length; np++) if (planes[nsTile][np] != null){
for (int np = 0; np < other_matched.length; np++) if ((planes[nsTile][np] != null) && (planes[nsTile][np].getWeight() > 0.0)){ // disregard 0-weight planes
int [] bn = planes[nsTile][np].getNeibBest();
System.out.println("nsTile="+nsTile+":"+np+" best neighbors : ["+
bn[0]+","+bn[1]+","+bn[2]+","+bn[3]+","+bn[4]+","+bn[5]+","+bn[6]+","+bn[7]+"]");
}
}
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
}
public int [][][] getMergeSameTileCandidates(
final TilePlanes.PlaneData [][] planes,
final int debugLevel,
final int dbg_X,
final int dbg_Y)
{
final int tilesX = st.tileProcessor.getTilesX();
final int tilesY = st.tileProcessor.getTilesY();
final int superTileSize = st.tileProcessor.getSuperTileSize();
// final int tileSize = tileProcessor.getTileSize();
final int stilesX = (tilesX + superTileSize -1)/superTileSize;
final int stilesY = (tilesY + superTileSize -1)/superTileSize;
final int nStiles = stilesX * stilesY;
final int [][][] merge_candidates = new int [nStiles][][];
final int debug_stile = dbg_Y * stilesX + dbg_X;
class LayersLinks{
int nl1, nl2, links1, links2, shared;
LayersLinks (int nl1, int nl2, int links1, int links2, int shared){
this.nl1 = nl1;
this.nl2 = nl2;
this.links1 = links1;
this.links2 = links2;
this.shared = shared;
}
int [] toArray()
{
int [] data = {nl1, nl2, links1, links2, shared};
return data;
}
}
final Thread[] threads = ImageDtt.newThreadArray(st.tileProcessor.threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nsTile = ai.getAndIncrement(); nsTile < nStiles; nsTile = ai.getAndIncrement()) if ( planes[nsTile] != null) {
ArrayList<LayersLinks> links_list = new ArrayList<LayersLinks>();
int dl = ((debugLevel > 0) && (nsTile == debug_stile)) ? 1:0;
if (dl > 0){
System.out.println("getMergeCandidates(): nsTile="+nsTile);
}
for (int np1 = 0; np1 < planes[nsTile].length; np1++) if (planes[nsTile][np1] != null){ // nu
boolean [][] merged_valid1 = planes[nsTile][np1].getMergedValid();
if (merged_valid1 != null){
for (int np2 = np1 + 1; np2 < planes[nsTile].length; np2++) if (planes[nsTile][np2] != null){ // nu
boolean [][] merged_valid2 = planes[nsTile][np2].getMergedValid();
if (merged_valid2 != null){
int num_links1 = 0;
int num_links2 = 0;
int num_shared = 0;
for (int dir = 0; dir < 8; dir++){
if (merged_valid1[dir] != null){
for (int nl = 0; nl < merged_valid1[dir].length; nl++){
if (merged_valid1[dir][nl]) num_links1++;
}
}
if (merged_valid2[dir] != null){
for (int nl = 0; nl < merged_valid2[dir].length; nl++){
if (merged_valid2[dir][nl]) num_links2++;
}
}
if ((merged_valid1[dir] != null) && (merged_valid2[dir] != null)) { // should be the same length
for (int nl = 0; nl < merged_valid2[dir].length; nl++){
if (merged_valid1[dir][nl] && merged_valid2[dir][nl]) num_shared++;
}
}
}
if (num_shared > 0) links_list.add(new LayersLinks(np1, np2, num_links1, num_links2, num_shared));
}
}
}
}
if (!links_list.isEmpty()){
merge_candidates[nsTile] = new int [links_list.size()][];
int indx = 0;
for (LayersLinks ll : links_list){
merge_candidates[nsTile][indx++] = ll.toArray();
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
if (debugLevel > 1){
System.out.println("Supertile planes that are candidates for merging:");
for (int nsTile = 0; nsTile < nStiles; nsTile++){
int stx = nsTile % stilesX;
int sty = nsTile / stilesX;
if (merge_candidates[nsTile] != null){
for (int i = 0 ; i < merge_candidates[nsTile].length; i++){
double sharedRatio = 2.0 * merge_candidates[nsTile][i][4] / (merge_candidates[nsTile][i][2] + merge_candidates[nsTile][i][3]);
System.out.println(nsTile+" ["+stx+":"+sty+"] ("+merge_candidates[nsTile][i][0]+", "+merge_candidates[nsTile][i][1]+")"+
" shared "+(((int) (sharedRatio * 1000)) / 10) + "%" +
" links1 = "+merge_candidates[nsTile][i][2]+
" links2 = "+merge_candidates[nsTile][i][3]+
" shared links = "+merge_candidates[nsTile][i][4]);
}
}
}
}
return merge_candidates;
}
public boolean [][] mergeSameTileEvaluate(
final TilePlanes.PlaneData [][] planes,
final int [][][] merge_candidates,
final int debugLevel,
final int dbg_X,
final int dbg_Y)
{
final int tilesX = st.tileProcessor.getTilesX();
final int tilesY = st.tileProcessor.getTilesY();
final int superTileSize = st.tileProcessor.getSuperTileSize();
// final int tileSize = tileProcessor.getTileSize();
final int stilesX = (tilesX + superTileSize -1)/superTileSize;
final int stilesY = (tilesY + superTileSize -1)/superTileSize;
final int nStiles = stilesX * stilesY;
final boolean [][] merge_pairs = new boolean [nStiles][];
final int debug_stile = dbg_Y * stilesX + dbg_X;
final Thread[] threads = ImageDtt.newThreadArray((debugLevel > 1)? 1 : st.tileProcessor.threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nsTile = ai.getAndIncrement(); nsTile < nStiles; nsTile = ai.getAndIncrement()) if ( merge_candidates[nsTile] != null) {
merge_pairs[nsTile] = new boolean [merge_candidates[nsTile].length];
int dl = ((debugLevel > 0) && (nsTile == debug_stile)) ? 1: ((debugLevel > 1) ? 1:0);
if (dl > 0){
System.out.println("mergeSameTileEvaluate(): nsTile="+nsTile);
}
for (int pair = 0; pair < merge_candidates[nsTile].length; pair ++){
int np1 = merge_candidates[nsTile][pair][0];
int np2 = merge_candidates[nsTile][pair][1];
String prefix = "mergeSameTileEvaluate() pair="+pair+" nsTile="+nsTile+" np1="+np1+" np2="+np2;
if (planesFit(
planes[nsTile][np1], // TilePlanes.PlaneData plane1, // should belong to the same supertile (or be converted for one)
planes[nsTile][np2], // TilePlanes.PlaneData plane2,
Double.NaN, // calculate double merged_ev, // if NaN will calculate assuming the same supertile
Double.NaN, // calculate double merged_ev_eq, // if NaN will calculate assuming the same supertile
prefix, // String prefix,
dl) // int debugLevel)
){
merge_pairs[nsTile][pair] = true;
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
return merge_pairs;
} }
public double corrMaxEigen( public double corrMaxEigen(
double maxEigen, double maxEigen,
double dispNorm, double dispNorm,
...@@ -320,6 +908,20 @@ public class LinkPlanes { ...@@ -320,6 +908,20 @@ public class LinkPlanes {
return corrV; return corrV;
} }
/**
* Measure how merging of two plains degrades individual flatness (smaller - better). For comparing divide by (w1+w2) to make strong
* planes score better
* @param L1 smallest eigenvalue of the first plane
* @param L2 smallest eigenvalue of the second plane
* @param L smallest eigenvalue of the merged plane
* @param w1 weight of the first plane
* @param w2 weight of the second plane
* @param eigen_floor add to each L
* @return degrading by merging measure. 0 if both are co-planar, is supposed to be positive. very "bad" planes do produce negative results -
* not yet clear why (related to non-linear coordinate transformation?)
*/
public double mergeRQuality( public double mergeRQuality(
double L1_in, double L1_in,
double L2_in, double L2_in,
......
...@@ -6835,23 +6835,11 @@ public class SuperTiles{ ...@@ -6835,23 +6835,11 @@ public class SuperTiles{
/** /**
* Find mutual links between multi-layer planes for supertiles. requires that for each plane there are calculated smalles eigenvalues * Find mutual links between multi-layer planes for supertiles. requires that for each plane there are calculated smalles eigenvalues
* for merging with each plane for each of 8 neighbors * for merging with each plane for each of 8 neighbors
* @param rquality maximal degradation by merging (does not depend on the total weight)
* @param okMergeEigen if result eigenvalue of the merged planes is below, OK to bypass worst worsening
* @param maxWorldSin2 maximal square of the sine of the angle between the planes to allow merge (>= 1.0 - disable)
* @param maxEigen maximal eigenvalue of each of the merged planes
* @param minWeight minimal weight of each of the planes
* @param debugLevel debug level * @param debugLevel debug level
* @param dbg_X debug supertile X coordinate * @param dbg_X debug supertile X coordinate
* @param dbg_Y debug supertile Y coordinate * @param dbg_Y debug supertile Y coordinate
*/ */
public void selectNeighborPlanesMutual( public void selectNeighborPlanesMutual(
// final double rquality,
// final double weakWorsening,
// final double okMergeEigen,
// final double maxWorldSin2,
// final double dispNorm,
// final double maxEigen, // maximal eigenvalue of planes to consider
// final double minWeight, // minimal pain weight to consider
final double eigenFloor, // Add to eigenvalues of each participating plane and result to validate connections final double eigenFloor, // Add to eigenvalues of each participating plane and result to validate connections
final int debugLevel, final int debugLevel,
final int dbg_X, final int dbg_X,
......
...@@ -3343,7 +3343,7 @@ public class TileProcessor { ...@@ -3343,7 +3343,7 @@ public class TileProcessor {
// moved here // moved here
if (clt_parameters.dbg_migrate) { // if (clt_parameters.dbg_migrate) {
// separate each supertile data into clusters, trying both horizontal and perpendicular to view planes // separate each supertile data into clusters, trying both horizontal and perpendicular to view planes
double [] world_hor = {0.0, 1.0, 0.0}; double [] world_hor = {0.0, 1.0, 0.0};
st.processPlanes5( st.processPlanes5(
...@@ -3380,7 +3380,7 @@ public class TileProcessor { ...@@ -3380,7 +3380,7 @@ public class TileProcessor {
0, // -1, // debugLevel, // final int debugLevel) 0, // -1, // debugLevel, // final int debugLevel)
clt_parameters.tileX, clt_parameters.tileX,
clt_parameters.tileY); clt_parameters.tileY);
} else { /* } else {
st.processPlanes4( st.processPlanes4(
clt_parameters.stMeasSel, // = 1 //Select measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert clt_parameters.stMeasSel, // = 1 //Select measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert
clt_parameters.plDispNorm, // = 2.0; // Normalize disparities to the average if above clt_parameters.plDispNorm, // = 2.0; // Normalize disparities to the average if above
...@@ -3406,78 +3406,95 @@ public class TileProcessor { ...@@ -3406,78 +3406,95 @@ public class TileProcessor {
clt_parameters.tileX, clt_parameters.tileX,
clt_parameters.tileY); clt_parameters.tileY);
} }
*/
showDoubleFloatArrays sdfa_instance = null; showDoubleFloatArrays sdfa_instance = null;
if (debugLevel > -1) sdfa_instance = new showDoubleFloatArrays(); // just for debugging? if (debugLevel > -1) sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
if (clt_parameters.dbg_migrate) {
// Trying new class
LinkPlanes lp = new LinkPlanes (clt_parameters, st);
lp.matchPlanes(
st.planes, // final TilePlanes.PlaneData [][] planes,
2, // -1, // debugLevel, // final int debugLevel)
clt_parameters.tileX,
clt_parameters.tileY);
st.matchPlanes( lp.filterNeighborPlanes(
clt_parameters.plPreferDisparity, st.planes, // final TilePlanes.PlaneData [][] planes,
0, // debugLevel 2, // -1, // debugLevel, // final int debugLevel)
clt_parameters.tileX, clt_parameters.tileX,
clt_parameters.tileY); clt_parameters.tileY);
st.filterNeighborPlanes(
clt_parameters.plWorstWorsening, // final double worst_worsening,
clt_parameters.plWorstWorsening2,// final double worst_worsening2 Worst case worsening for thin planes,
clt_parameters.plWorstEq, // final double worstEq, // Worst case worsening after merge with equal weights
clt_parameters.plWorstEq2, // final double worstEq2, // Worst case worsening for thin planes with equal weights
clt_parameters.plWeakWorsening, // final double worst_worsening,
clt_parameters.plOKMergeEigen, // final double okMergeEigen, f result of the merged planes is below, OK to use thin planes (higher) threshold
clt_parameters.plMaxWorldSin2, // final double maxWorldSin2,
clt_parameters.plDispNorm,
clt_parameters.plMaxEigen,
clt_parameters.plEigenFloor, // final double eigenFloor, // Add to eigenvalues of each participating plane and result to validate connections
clt_parameters.plMinStrength,
0, // final int debugLevel)
clt_parameters.tileX,
clt_parameters.tileY);
/* */
int [][][] merge_candidates = st.getMergeSameTileCandidates(
2, // final int debugLevel,
clt_parameters.tileX,
clt_parameters.tileY);
boolean [][] pairs_to_merge = st.mergeSameTileEvaluate(
merge_candidates, // final int [][][] merge_candidates,
clt_parameters.plWorstWorsening, // final double worst_worsening,
clt_parameters.plWorstWorsening2,// final double worst_worsening2 Worst case worsening for thin planes,
clt_parameters.plWorstEq, // final double worstEq, // Worst case worsening after merge with equal weights
clt_parameters.plWorstEq2, // final double worstEq2, // Worst case worsening for thin planes with equal weights
clt_parameters.plWeakWorsening, // final double worst_worsening,
clt_parameters.plOKMergeEigen, // final double okMergeEigen, f result of the merged planes is below, OK to use thin planes (higher) threshold
clt_parameters.plMaxWorldSin2, // final double maxWorldSin2,
clt_parameters.plDispNorm,
clt_parameters.plMaxEigen,
clt_parameters.plEigenFloor, // final double eigenFloor, // Add to eigenvalues of each participating plane and result to validate connections
0.0, // clt_parameters.plMinStrength,
clt_parameters.plPreferDisparity,
2, // final int debugLevel)
clt_parameters.tileX,
clt_parameters.tileY);
st.selectNeighborPlanesMutual(
clt_parameters.plEigenFloor, // final double eigenFloor, // Add to eigenvalues of each participating plane and result to validate connections
0, // final int debugLevel)
clt_parameters.tileX,
clt_parameters.tileY);
/*
st.selectNeighborPlanesMutual_old(
clt_parameters.plWorstWorsening, // final double worst_worsening,
clt_parameters.plWeakWorsening, // final double worst_worsening,
clt_parameters.plOKMergeEigen, // final double okMergeEigen,
clt_parameters.plMaxWorldSin2, // final double maxWorldSin2,
clt_parameters.plDispNorm, int [][][] merge_candidates = lp.getMergeSameTileCandidates(
clt_parameters.plMaxEigen, st.planes, // final TilePlanes.PlaneData [][] planes,
clt_parameters.plEigenFloor, // final double eigenFloor, // Add to eigenvalues of each participating plane and result to validate connections 2, // -1, // debugLevel, // final int debugLevel)
clt_parameters.plMinStrength, clt_parameters.tileX,
0, // final int debugLevel) clt_parameters.tileY);
clt_parameters.tileX,
clt_parameters.tileY); boolean [][] pairs_to_merge = lp.mergeSameTileEvaluate(
*/ st.planes, // final TilePlanes.PlaneData [][] planes,
merge_candidates, // final int [][][] merge_candidates,
2, // -1, // debugLevel, // final int debugLevel)
clt_parameters.tileX,
clt_parameters.tileY);
System.out.println(pairs_to_merge.length);
lp.selectNeighborPlanesMutual(
st.planes, // final TilePlanes.PlaneData [][] planes,
0, // final int debugLevel)
clt_parameters.tileX,
clt_parameters.tileY);
} else {
st.matchPlanes(
clt_parameters.plPreferDisparity,
0, // debugLevel
clt_parameters.tileX,
clt_parameters.tileY);
st.filterNeighborPlanes(
clt_parameters.plWorstWorsening, // final double worst_worsening,
clt_parameters.plWorstWorsening2,// final double worst_worsening2 Worst case worsening for thin planes,
clt_parameters.plWorstEq, // final double worstEq, // Worst case worsening after merge with equal weights
clt_parameters.plWorstEq2, // final double worstEq2, // Worst case worsening for thin planes with equal weights
clt_parameters.plWeakWorsening, // final double worst_worsening,
clt_parameters.plOKMergeEigen, // final double okMergeEigen, f result of the merged planes is below, OK to use thin planes (higher) threshold
clt_parameters.plMaxWorldSin2, // final double maxWorldSin2,
clt_parameters.plDispNorm,
clt_parameters.plMaxEigen,
clt_parameters.plEigenFloor, // final double eigenFloor, // Add to eigenvalues of each participating plane and result to validate connections
clt_parameters.plMinStrength,
0, // final int debugLevel)
clt_parameters.tileX,
clt_parameters.tileY);
int [][][] merge_candidates = st.getMergeSameTileCandidates(
2, // final int debugLevel,
clt_parameters.tileX,
clt_parameters.tileY);
boolean [][] pairs_to_merge = st.mergeSameTileEvaluate(
merge_candidates, // final int [][][] merge_candidates,
clt_parameters.plWorstWorsening, // final double worst_worsening,
clt_parameters.plWorstWorsening2,// final double worst_worsening2 Worst case worsening for thin planes,
clt_parameters.plWorstEq, // final double worstEq, // Worst case worsening after merge with equal weights
clt_parameters.plWorstEq2, // final double worstEq2, // Worst case worsening for thin planes with equal weights
clt_parameters.plWeakWorsening, // final double worst_worsening,
clt_parameters.plOKMergeEigen, // final double okMergeEigen, f result of the merged planes is below, OK to use thin planes (higher) threshold
clt_parameters.plMaxWorldSin2, // final double maxWorldSin2,
clt_parameters.plDispNorm,
clt_parameters.plMaxEigen,
clt_parameters.plEigenFloor, // final double eigenFloor, // Add to eigenvalues of each participating plane and result to validate connections
0.0, // clt_parameters.plMinStrength,
clt_parameters.plPreferDisparity,
2, // final int debugLevel)
clt_parameters.tileX,
clt_parameters.tileY);
st.selectNeighborPlanesMutual(
clt_parameters.plEigenFloor, // final double eigenFloor, // Add to eigenvalues of each participating plane and result to validate connections
0, // final int debugLevel)
clt_parameters.tileX,
clt_parameters.tileY);
}
st.resolveConflicts( st.resolveConflicts(
clt_parameters.plMaxEigen, clt_parameters.plMaxEigen,
clt_parameters.plConflDualTri, // boolean conflDualTri, // Resolve dual triangles conflict (odoodo) clt_parameters.plConflDualTri, // boolean conflDualTri, // Resolve dual triangles conflict (odoodo)
...@@ -3580,7 +3597,8 @@ public class TileProcessor { ...@@ -3580,7 +3597,8 @@ public class TileProcessor {
clt_parameters.plMaxOutliers, // final int maxOutliers, // = 20; // Maximal number of outliers to remove clt_parameters.plMaxOutliers, // final int maxOutliers, // = 20; // Maximal number of outliers to remove
clt_parameters.stFloor, // final double strength_floor, clt_parameters.stFloor, // final double strength_floor,
clt_parameters.stPow, // final double strength_pow, clt_parameters.stPow, // final double strength_pow,
clt_parameters.dbg_migrate && clt_parameters.stSmplMode , // final boolean smplMode, // = true; // Use sample mode (false - regular tile mode) // clt_parameters.dbg_migrate && clt_parameters.stSmplMode , // final boolean smplMode, // = true; // Use sample mode (false - regular tile mode)
clt_parameters.stSmplMode , // final boolean smplMode, // = true; // Use sample mode (false - regular tile mode)
clt_parameters.stSmplSide , // final int smplSide, // = 2; // Sample size (side of a square) clt_parameters.stSmplSide , // final int smplSide, // = 2; // Sample size (side of a square)
clt_parameters.stSmplNum , // final int smplNum, // = 3; // Number after removing worst clt_parameters.stSmplNum , // final int smplNum, // = 3; // Number after removing worst
clt_parameters.stSmplRms , // final double smplRms, // = 0.1; // Maximal RMS of the remaining tiles in a sample clt_parameters.stSmplRms , // final double smplRms, // = 0.1; // Maximal RMS of the remaining tiles in a sample
......
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