Commit cee97f1b authored by Andrey Filippov's avatar Andrey Filippov

more debugging planes merging

parent 86cdc8a0
......@@ -515,6 +515,10 @@ public class CLTPass3d{
return weakOutlayers;
}
public SuperTiles getSuperTiles()
{
return this.superTiles;
}
public SuperTiles setSuperTiles(
double step_near,
......
......@@ -1921,7 +1921,7 @@ public class EyesisCorrectionParameters {
public int ishift_x = 0; // debug feature - shift source image by this pixels left
public int ishift_y = 0; // debug feature - shift source image by this pixels down
public double fat_zero = 0.0; // modify phase correlation to prevent division by very small numbers
public double corr_sigma = 0.8; // LPF correlarion sigma
public double corr_sigma = 0.8; // LPF correlation sigma
public boolean norm_kern = true; // normalize kernels
public boolean gain_equalize = false;// equalize green channel gain
public boolean colors_equalize = true; // equalize R/G, B/G of the individual channels
......@@ -2149,7 +2149,10 @@ public class EyesisCorrectionParameters {
public int plMaxOutliers = 20; // Maximal number of outliers to remove
public double plMinStrength = 0.1; // Minimal total strength of a plane
public double plMaxEigen = 0.3; // Maximal eigenvalue of a plane
public boolean plDbgMerge = true; // Combine 'other' plane with current
public boolean plDbgMerge = true; // Combine 'other' plane with current
public double plWorstWorsening = 2.0; // Worst case worsening after merge
public boolean plMutualOnly = true; // keep only mutual links, remove weakest if conflict
// other debug images
public boolean show_ortho_combine = false; // Show 'ortho_combine'
......@@ -2391,6 +2394,8 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"plMinStrength", this.plMinStrength +"");
properties.setProperty(prefix+"plMaxEigen", this.plMaxEigen +"");
properties.setProperty(prefix+"plDbgMerge", this.plDbgMerge+"");
properties.setProperty(prefix+"plWorstWorsening", this.plWorstWorsening +"");
properties.setProperty(prefix+"plMutualOnly", this.plMutualOnly+"");
properties.setProperty(prefix+"show_ortho_combine", this.show_ortho_combine+"");
properties.setProperty(prefix+"show_refine_supertiles", this.show_refine_supertiles+"");
......@@ -2623,6 +2628,8 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"plMinStrength")!=null) this.plMinStrength=Double.parseDouble(properties.getProperty(prefix+"plMinStrength"));
if (properties.getProperty(prefix+"plMaxEigen")!=null) this.plMaxEigen=Double.parseDouble(properties.getProperty(prefix+"plMaxEigen"));
if (properties.getProperty(prefix+"plDbgMerge")!=null) this.plDbgMerge=Boolean.parseBoolean(properties.getProperty(prefix+"plDbgMerge"));
if (properties.getProperty(prefix+"plWorstWorsening")!=null) this.plWorstWorsening=Double.parseDouble(properties.getProperty(prefix+"plWorstWorsening"));
if (properties.getProperty(prefix+"plMutualOnly")!=null) this.plMutualOnly=Boolean.parseBoolean(properties.getProperty(prefix+"plMutualOnly"));
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_refine_supertiles")!=null) this.show_refine_supertiles=Boolean.parseBoolean(properties.getProperty(prefix+"show_refine_supertiles"));
......@@ -2877,6 +2884,8 @@ public class EyesisCorrectionParameters {
gd.addNumericField("Minimal total strength of a plane", this.plMinStrength, 6);
gd.addNumericField("Maximal eigenvalue of a plane", this.plMaxEigen, 6);
gd.addCheckbox ("Combine 'other' plane with the current", this.plDbgMerge);
gd.addNumericField("Worst case worsening after merge", this.plWorstWorsening, 6);
gd.addCheckbox ("Keep only mutual links, remove weakest if conflict", this.plMutualOnly);
gd.addMessage ("--- Other debug images ---");
gd.addCheckbox ("Show 'ortho_combine'", this.show_ortho_combine);
......@@ -3118,6 +3127,8 @@ public class EyesisCorrectionParameters {
this.plMinStrength= gd.getNextNumber();
this.plMaxEigen= gd.getNextNumber();
this.plDbgMerge= gd.getNextBoolean();
this.plWorstWorsening= gd.getNextNumber();
this.plMutualOnly= gd.getNextBoolean();
this.show_ortho_combine= gd.getNextBoolean();
this.show_refine_supertiles= gd.getNextBoolean();
......
......@@ -506,6 +506,7 @@ private Panel panel1,
addButton("CLT apply fine corr", panelClt1, color_process);
addButton("CLT reset 3D", panelClt1, color_stop);
addButton("CLT 3D", panelClt1, color_conf_process);
addButton("CLT planes", panelClt1, color_conf_process);
add(panelClt1);
}
......@@ -4764,13 +4765,22 @@ private Panel panel1,
}
return;
} else if (label.equals("CLT planes")) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
EYESIS_CORRECTIONS.setDebug(DEBUG_LEVEL);
if (QUAD_CLT == null){
System.out.println("QUAD_CLT is null, nothing to show");
return;
}
//"CLT planes"
QUAD_CLT.showCLTPlanes(
CLT_PARAMETERS, // EyesisCorrectionParameters.DCTParameters dct_parameters,
THREADS_MAX, //final int threadsMax, // maximal number of threads to launch
UPDATE_STATUS, //final boolean updateStatus,
DEBUG_LEVEL); //final int debugLevel);
return;
//
// End of buttons code
}
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
......
......@@ -4458,6 +4458,30 @@ public class QuadCLT {
return rslt;
}
// public ImagePlus [] cltDisparityScan(
public void showCLTPlanes(
EyesisCorrectionParameters.CLTParameters clt_parameters,
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
final int debugLevel)
{
if (tp == null){
System.out.println("showCLTPlanes(): tp is null");
return;
}
if (tp.clt_3d_passes == null){
System.out.println("showCLTPlanes(): tp.clt_3d_passes is null");
return;
}
tp.showPlanes(
clt_parameters,
threadsMax,
updateStatus,
debugLevel);
// CLTPass3d last_scan = tp.clt_3d_passes.get(tp.clt_3d_passes.size() -1); // get last one
}
public void processCLTQuads3d(
EyesisCorrectionParameters.CLTParameters clt_parameters,
......@@ -5062,6 +5086,14 @@ public class QuadCLT {
2); // debugLevel);
// get images for predefined regions and disparities. First - with just fixed scans 1 .. list.size()
// TEMPORARY EXIT
if (tp.clt_3d_passes.size() > 0) {
System.out.println("-------- temporary exit after secondPassSetup() ------- ");
return null; // just to fool compiler
}
tp.showScan(
tp.clt_3d_passes.get(next_pass-1), // CLTPass3d scan,
"after_pass2-"+(next_pass-1)); //String title)
......
......@@ -166,15 +166,11 @@ public class SuperTiles{
}
public double [][] getDisparityHistograms(
final boolean [] selected, // or null
final int debugLevel)
{
if (this.disparityHistograms != null) return this.disparityHistograms;
final double step_disparity = step_near; // TODO: implement
final int tilesX = tileProcessor.getTilesX();
final int tilesY = tileProcessor.getTilesY();
final int superTileSize = tileProcessor.superTileSize;
......@@ -183,14 +179,11 @@ public class SuperTiles{
final int stilesX = (tilesX + superTileSize -1)/superTileSize;
final int stilesY = (tilesY + superTileSize -1)/superTileSize;
final int nStiles = stilesX * stilesY;
/// final double dMin = min_disparity - step_disparity/2;
/// final double dMax = dMin + numBins * step_disparity;
final double [][] dispHist = new double [nStiles][]; // now it will be sparse
final double [] strengthHist = new double [nStiles];
final Thread[] threads = ImageDtt.newThreadArray(tileProcessor.threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
final int st_start = - superTileSize/2;
// final int st_end = st_start + superTileSize;
final int superTileSize2 = 2 * superTileSize;
final double [][] lapWeight = getLapWeights();
for (int ithread = 0; ithread < threads.length; ithread++) {
......@@ -201,13 +194,11 @@ public class SuperTiles{
int stileX = nsTile % stilesX;
double sw = 0.0; // sum weights
double [] hist = new double [numBins];
// for (int tileY = stileY * superTileSize + st_start; tileY < stileY * superTileSize + st_end; tileY++){
int tY0 = stileY * superTileSize + st_start;
int tX0 = stileX * superTileSize + st_start;
for (int tY = 0; tY < superTileSize2; tY++){
int tileY = tY0 +tY;
if ((tileY >= 0) && (tileY < tilesY)) {
// for (int tileX = stileX * superTileSize + st_start; tileX < stileX * superTileSize + st_end; tileX++){
for (int tX = 0; tX < superTileSize2; tX++){
int tileX = tX0 +tX;
if ((tileX >= 0) && (tileX < tilesX)) {
......@@ -218,7 +209,6 @@ public class SuperTiles{
if (w > 0.0){
if (strength_pow != 1.0) w = Math.pow(w, strength_pow);
w *= lapWeight[tY][tX];
// int bin = (int) ((d-dMin)/step_disparity);
// ignore too near/ too far
int bin = disparityToBin(d);
if ((bin >= 0) && (bin < numBins)){ // maybe collect below min and above max somewhere?
......@@ -253,6 +243,8 @@ public class SuperTiles{
return this.disparityHistograms; // dispHist;
}
public void blurDisparityHistogram( // in-place
final int debugLevel)
{
......@@ -1039,7 +1031,9 @@ public class SuperTiles{
final int plMaxOutliers, // = 20; // Maximal number of outliers to remove
final GeometryCorrection geometryCorrection,
final boolean correct_distortions,
final int debugLevel)
final int debugLevel,
final int dbg_X,
final int dbg_Y)
{
if (maxMinMax == null) getMaxMinMax();
// final int np_min = 5; // minimal number of points to consider
......@@ -1067,7 +1061,8 @@ public class SuperTiles{
// final int debug_stile = 18 * stilesX + 25;
// final int debug_stile = 20 * stilesX + 24;
final int debug_stile = 16 * stilesX + 27; // 10;
// final int debug_stile = 16 * stilesX + 27; // 10;
final int debug_stile = (debugLevel > -1)? (dbg_Y * stilesX + dbg_X):-1;
for (int ithread = 0; ithread < threads.length; ithread++) {
......@@ -1124,7 +1119,8 @@ public class SuperTiles{
int dl1 = (nsTile == debug_stile) ? 3 : 0;
// int dl = (nsTile == debug_stile) ? 3 : 0;
// int dl = ((stileY >= 15) && (stileY <= 18) && (stileX >= 5) && (stileX <= 31)) ? 1 : 0;
int dl = ((stileY == 16) && (stileX == 27) ) ? 3 : 0;
// int dl = ((stileY == 16) && (stileX == 27) ) ? 3 : 0;
int dl = (nsTile == debug_stile) ? 3 : 0;
// int debugLevel1 = ((sTileXY[0] == 27) && (sTileXY[1] == 16))? 1: 0; // check why v[0][0] <0
......@@ -1329,9 +1325,12 @@ public class SuperTiles{
return wh;
}
TilePlanes.PlaneData [][] getNeibPlanes(
final int dir, // 0: get from up (N), 1:from NE, ... 7 - from NW
final boolean dbgMerge // Combine 'other' plane with current
final boolean dbgMerge, // Combine 'other' plane with current
final int dbg_X,
final int dbg_Y
)
{
final int tilesX = tileProcessor.getTilesX();
......@@ -1346,7 +1345,9 @@ public class SuperTiles{
TilePlanes.PlaneData [][] neib_planes = new TilePlanes.PlaneData[stilesY * stilesX][];
TilePlanes tpl = null; // new TilePlanes(tileSize,superTileSize, geometryCorrection);
// final int debug_stile = 20 * stilesX + 27;
final int debug_stile = 17 * stilesX + 27;
// final int debug_stile = 17 * stilesX + 27;
final int debug_stile = dbg_Y * stilesX + dbg_X;
// final int debug_stile = -1;
for (int sty0 = 0; sty0 < stilesY; sty0++){
int sty = sty0 + dirsYX[dir][0];
......@@ -1432,12 +1433,405 @@ public class SuperTiles{
return neib_planes;
}
public double mergeRQuality(
double L1,
double L2,
double L,
double w1,
double w2)
{
// double Lav = Math.sqrt((L1*L1*w1 + L2*L2*w2)/(w1+w2));
double Lav = (L1*w1 + L2*w2)/(w1+w2);
/// double wors = (L - Lav)*(w1+w2)*(w1+w2) /(Lav*w1*w2);
double rquality = (L - Lav)*(w1+w2) /(Lav*w1*w2); // ==wors/(w1+w2) to amplify stronger planes
return rquality;
}
public void matchPlanes(
final int dbg_X,
final int dbg_Y)
{
final int tilesX = tileProcessor.getTilesX();
final int tilesY = tileProcessor.getTilesY();
final int superTileSize = 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(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()) {
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("matchPlanes(): nsTile0 ="+nsTile0);
}
for (int np0 = 0; np0 < planes[nsTile0].length; np0++){ // nu
// planes[nsTile0][np0].initNeibBest(); //
TilePlanes.PlaneData this_plane = planes[nsTile0][np0];
this_plane.initNeibMatch();
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.initNeibMatch(dir,other_planes.length); // filled with NaN
for (int np = 0; np < other_planes.length; np ++){
TilePlanes.PlaneData other_plane = this_plane.getPlaneToThis(
other_planes[np],
dl); // 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,
false, // boolean ignore_weights,
dl); // int debugLevel)
if (merged_pd !=null) { // now always, but may add later
// calculate worsening of the merge (the lower - the better)
double rquality = mergeRQuality(
this_plane.getValue(), // double L1,
other_plane.getValue(), // double L2,
merged_pd.getValue(), // double L,
this_plane.getWeight(), // double w1,
other_plane.getWeight()); // double w2)
this_plane.setNeibMatch(dir, np, rquality);
// still happens negative but only for very bad planes - investigate?
if ((rquality < 0) && (this_plane.getWeight() > 0.0) && (other_plane.getWeight() > 0.0) && (merged_pd.getValue() < 1.0) ){ //
System.out.println("nsTile0="+nsTile0+":"+np0+", nsTile="+nsTile+":"+np+", rquality="+rquality+
" w1="+this_plane.getWeight()+" w2="+other_plane.getWeight()+
" L1="+this_plane.getValue()+" L2="+other_plane.getValue()+" L="+merged_pd.getValue());
}
if ((merged_pd.getValue() < 0.1) && (this_plane.getWeight() > 1.0) && (other_plane.getWeight() > 1.0) ){ // fixed
System.out.println("nsTile0="+nsTile0+":"+np0+", nsTile="+nsTile+":"+np+", rquality="+rquality+
" w1="+this_plane.getWeight()+" w2="+other_plane.getWeight()+
" L1="+this_plane.getValue()+" L2="+other_plane.getValue()+" L="+merged_pd.getValue());
}
}
}
}
}
}
}
}
}
}
}
}
};
}
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 = (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];
// this_plane.initNeibMatch();
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 ((stx < stilesX) && (sty < stilesY) && (sty > 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.initNeibMatch(dir,other_planes.length); // filled with NaN
for (int np = 0; np < other_planes.length; np ++){
/*
if ((other_planes[np] != null) && (other_planes[np].getNeibMatch(dir-4) != null)) {
double [] dbg_nm = other_planes[np].getNeibMatch(dir-4);
this_plane.setNeibMatch(dir,np, other_planes[np].getNeibMatch(dir-4, np0)); //
}
*/
if (other_planes[np] != null) { // && (other_planes[np].getNeibMatch(dir-4) != null)) {
double [] nm = other_planes[np].getNeibMatch(dir-4);
if (nm != null) {
// this_plane.setNeibMatch(dir,np, other_planes[np].getNeibMatch(dir-4, np0)); //
this_plane.setNeibMatch(dir,np, nm[np0]); //
}
}
}
}
}
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
}
public void selectNeighborPlanes(
final double worst_worsening,
final boolean mutual_only,
final int debugLevel)
{
final int tilesX = tileProcessor.getTilesX();
final int tilesY = tileProcessor.getTilesY();
final int superTileSize = 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 Thread[] threads = ImageDtt.newThreadArray(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()) {
// int sty0 = nsTile0 / stilesX;
// int stx0 = nsTile0 % stilesX;
// int dl = (nsTile0 == debug_stile) ? 1:0;
if ( planes[nsTile0] != null) {
int np0_min = (planes[nsTile0].length > 1) ? 1:0; // Modify if overall plane will be removed
for (int np0 = np0_min; np0 < planes[nsTile0].length; np0++){ // nu
TilePlanes.PlaneData this_plane = planes[nsTile0][np0];
this_plane.initNeibBest();
if (this_plane.getNeibMatch() != null) {
for (int dir = 0; dir < 8; dir++){ //
double [] neib_worse = this_plane.getNeibMatch(dir);
if (neib_worse != null) {
int best_index = -1;
int np_min = (neib_worse.length > 1) ? 1:0; // Modify if overall plane will be removed
for (int np = np_min; np < neib_worse.length; np++){
if ( ((worst_worsening == 0.0) || (neib_worse[np] < worst_worsening)) &&
!Double.isNaN(neib_worse[np]) &&
((best_index < 0) || (neib_worse[np] < neib_worse[best_index]))){
best_index = np;
}
}
if (best_index >= 0){
this_plane.setNeibBest(dir, best_index);
}
}
}
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
if (mutual_only) { // resolve love triangles (by combined strength)
ai.set(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()) {
int sty0 = nsTile0 / stilesX;
int stx0 = nsTile0 % stilesX;
// int dl = (nsTile0 == debug_stile) ? 1:0;
if ( planes[nsTile0] != null) {
for (int np0 = 0; np0 < planes[nsTile0].length; np0++){ // nu
TilePlanes.PlaneData this_plane = planes[nsTile0][np0];
if (this_plane.getNeibBest() != null) {
for (int dir = 0; dir < 4; dir++){ // just half directions - relations are symmetrical
int other_np = this_plane.getNeibBest(dir);
if (other_np >= 0){ // may be -1, but the opposite is pointing to this
int stx = stx0 + dirsYX[dir][1];
int sty = sty0 + dirsYX[dir][0]; // no need to check limits as other_np >= 0
int nsTile = sty * stilesX + stx; // from where to get
TilePlanes.PlaneData [] other_planes = planes[nsTile]; // known != null
int other_other_np = other_planes[other_np].getNeibBest(dir + 4);
// see if there is not a mutual love
if (other_other_np != np0){
if (debugLevel > -1){
System.out.println("Planes not mutual: "+nsTile0+":"+np0+":"+dir+" -> "+
nsTile+":"+other_np+" -> "+other_other_np);
}
if (other_other_np >= 0){
// Which pair is stronger (not comparing worsening)
double w_this = this_plane.getWeight()+other_planes[other_np].getWeight();
double w_other = other_planes[other_np].getWeight() + planes[nsTile0][other_other_np].getWeight();
if (w_this > w_other){ // kill other's love
// other_planes[other_np].setNeibBest(dir + 4, -1);
other_planes[other_np].setNeibBest(dir + 4, np0);
} else { // kill my love
// this_plane.setNeibBest(dir, -1);
this_plane.setNeibBest(dir, -1);
}
} else { // other points nowhere, point it to this
other_planes[other_np].setNeibBest(dir + 4, np0);
}
}
}
}
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
}
}
public void selectNeighborPlanesMutual(
final double rquality,
// final boolean mutual_only,
final double maxEigen, // maximal eigenvalue of planes to consider
final double minWeight, // minimal pain weight to consider
final int debugLevel,
final int dbg_X,
final int dbg_Y)
{
final int tilesX = tileProcessor.getTilesX();
final int tilesY = tileProcessor.getTilesY();
final int superTileSize = 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(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("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].getNeibMatch(dir) != null){
int l = planes[nsTile0][np0].getNeibMatch(dir).length;
if (l > num_other_planes)num_other_planes = l;
}
}
if (num_other_planes > 0){ // will eliminate bad margins
int np_min = (num_other_planes > 1) ? 1:0; // Modify if overall plane will be removed
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 ++){
int [] best_pair = {-1,-1};
double best_rqual = Double.NaN;
for (int np0 = np0_min; np0 < this_matched.length; np0++){
double [] this_rq = planes[nsTile0][np0].getNeibMatch(dir);
if (!this_matched[np0] &&
(this_rq != null) &&
((maxEigen == 0.0) || (planes[nsTile0][np0].getValue() < maxEigen)) &&
(planes[nsTile0][np0].getWeight() > minWeight)) {
for (int np = np_min; np < this_rq.length; np++){
if (!other_matched[np] &&
!Double.isNaN(this_rq[np]) &&
((maxEigen == 0.0) || (planes[nsTile][np].getValue() < maxEigen)) &&
(planes[nsTile][np].getWeight() > minWeight)) {
if (Double.isNaN(best_rqual) || (this_rq[np] < best_rqual)){ // OK if Double.isNaN(this_rq[np])
best_rqual = this_rq[np];
best_pair[0]= np0;
best_pair[1]= np;
}
}
}
}
}
if (Double.isNaN(best_rqual)){
break; // nothing 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();
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 (!this_matched[np]){
planes[nsTile0][np].setNeibBest(dir,-1);
}
}
for (int np = 0; np < other_matched.length; np++){
if (!other_matched[np]){
planes[nsTile][np].setNeibBest(dir + 4,-1);
}
}
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
}
public double [][] getShowPlanes(
TilePlanes.PlaneData [][] planes,
double minWeight,
double maxEigen,
double dispNorm,
boolean use_NaN)
boolean use_NaN,
double arrow_dark,
double arrow_white)
{
final int tilesX = tileProcessor.getTilesX();
final int tilesY = tileProcessor.getTilesY();
......@@ -1450,7 +1844,14 @@ public class SuperTiles{
final double [] nan_plane = new double [superTileSize*superTileSize];
for (int i = 0; i < nan_plane.length; i++) nan_plane[i] = Double.NaN;
final int centerIndex = (superTileSize+1) * superTileSize / 2;
final int [] dirs = {-superTileSize,
-superTileSize + 1,
1,
superTileSize + 1,
superTileSize,
superTileSize - 1,
-1,
-superTileSize - 1};
// final int debug_stile = 17 * stilesX + 27;
final int debug_stile = 20 * stilesX + 27;
// final int debug_stile = 19 * stilesX + 27;
......@@ -1501,6 +1902,17 @@ public class SuperTiles{
}
if (eigVal < maxEigen) {
plane = planes[nsTile][np].getPlaneDisparity(use_NaN);
// add connections to neighbors if available
int [] neib_best = planes[nsTile][np].getNeibBest();
if (neib_best != null){
for (int dir = 0; dir < neib_best.length; dir ++) if (neib_best[dir] >= 0){
// draw a line
//int center_index = indx + centerIndex;
for (int i = 0; i < (superTileSize / 2); i++){
plane[centerIndex + i * dirs[dir]] = ((i & 1) == 0) ? arrow_white:arrow_white; // arrow_dark : arrow_white;
}
}
}
for (int y = 0; y < superTileSize; y++) {
System.arraycopy(plane, superTileSize * y, data[ns], indx + width * y, superTileSize);
}
......@@ -1515,6 +1927,7 @@ public class SuperTiles{
System.arraycopy(plane, superTileSize * y, data[ns], indx + width * y, superTileSize);
}
}
}
}
return data;
......
......@@ -58,6 +58,14 @@ public class TilePlanes {
double [] world_v2 = null; // world in-plane vector, corresponding to vectors[1]
// double [] daxy = null; // disparity and 2 relative angles (ax and ay) corresponding to fisheye view, near (0,0) scale is pixel size
double [][] neib_match = null; // for each of the directions (N, NE, .. NW) quality match for each layer
int [] neib_best = new int [8]; // for each of the directions (N, NE, .. NW) index of best match, -1 if none
// stores "worsening" of merging 2 planes. if L1,L2,L = values[0] of plane1, plane2 plane composite: w1, w2 - weights for plane1, plane2
// Lav = Math.sqrt((L1 * L1 * w1 + L2 * L2 * w2)/(w1 + w2))
// worsening_12 = (L - Lav) * (w1 + w2) * (w1 + w2) / (Lav * x1 * w2)
int tileSize;
int superTileSize;
int [] sTileXY = null; // X and Y indices of this superTile in the image
......@@ -84,6 +92,15 @@ public class TilePlanes {
pd.vectors[1] = this.vectors[1].clone();
pd.vectors[2] = this.vectors[2].clone();
}
if (this.neib_match != null){
pd.neib_match = this.neib_match.clone();
for (int i = 0; i<this.neib_match.length; i++){
if (this.neib_match[i] != null){
pd.neib_match[i] = this.neib_match[i].clone();
}
}
}
if (this.neib_best != null) pd.neib_best = this.neib_best.clone();
return pd;
}
......@@ -99,6 +116,71 @@ public class TilePlanes {
this.superTileSize = superTileSize;
this.sTileXY = sTileXY.clone();
}
public double [][] initNeibMatch()
{
this.neib_match = new double[8][];
return this.neib_match;
}
public double [][] getNeibMatch()
{
return this.neib_match;
}
public double [] initNeibMatch(int dir, int leng)
{
this.neib_match[dir] = new double[leng];
for (int i = 0; i < leng; i++) this.neib_match[dir][i] = Double.NaN;
return getNeibMatch(dir);
}
public double [] getNeibMatch(int dir)
{
if (this.neib_match == null) {
return null;
}
return this.neib_match[dir];
}
public double getNeibMatch(int dir, int plane)
{
if ((this.neib_match == null) ||(this.neib_match[dir] == null)){
return Double.NaN;
}
return this.neib_match[dir][plane];
}
public void setNeibMatch(int dir, int plane, double value)
{
this.neib_match[dir][plane] = value;
}
public int [] initNeibBest()
{
this.neib_best = new int[8];
for (int i = 0; i < 8; i++) this.neib_best[i] = -1;
return this.neib_best;
}
public int [] getNeibBest()
{
return this.neib_best;
}
public int getNeibBest(int dir)
{
if (this.neib_best == null) {
return -1;
}
return this.neib_best[dir];
}
public void setNeibBest(int dir, int val)
{
this.neib_best[dir] = val;
}
public void setCorrectDistortions(
boolean correctDistortions)
{
......
......@@ -2808,6 +2808,107 @@ public class TileProcessor {
//======================
public void showPlanes(
EyesisCorrectionParameters.CLTParameters clt_parameters,
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
final int debugLevel)
{
CLTPass3d scan_prev = clt_3d_passes.get(clt_3d_passes.size() -1); // get last one
SuperTiles st = scan_prev.getSuperTiles();
showDoubleFloatArrays sdfa_instance = null;
if (debugLevel > -1) sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
st.matchPlanes(
clt_parameters.tileX,
clt_parameters.tileY);
if (clt_parameters.plMutualOnly) {
st.selectNeighborPlanesMutual(
clt_parameters.plWorstWorsening, // final double worst_worsening,
clt_parameters.plMaxEigen,
clt_parameters.plMinStrength,
0, // final int debugLevel)
clt_parameters.tileX,
clt_parameters.tileY);
} else {
st.selectNeighborPlanes(
clt_parameters.plWorstWorsening, // final double worst_worsening,
clt_parameters.plMutualOnly, // final boolean mutual_only,
0); // final int debugLevel)
}
if (clt_parameters.show_planes){
int [] wh = st.getShowPlanesWidthHeight();
double [][] plane_data_nonan = st.getShowPlanes(
st.getPlanes(),
clt_parameters.plMinStrength, // minWeight,
clt_parameters.plMaxEigen, // maxEigen,
clt_parameters.plDispNorm,
false, //boolean use_NaN)
0.0,
10.0);
double [][] plane_data_nan = st.getShowPlanes(
st.getPlanes(),
clt_parameters.plMinStrength, // minWeight,
clt_parameters.plMaxEigen, // maxEigen,
clt_parameters.plDispNorm,
true, //boolean use_NaN)
0.0,
10.0);
double [][] plane_data = new double [plane_data_nonan.length + plane_data_nan.length][];
int indx = 0;
for (int i = 0; i < plane_data_nonan.length; i++){
plane_data[indx++] = plane_data_nonan[i];
}
for (int i = 0; i < plane_data_nan.length; i++){
plane_data[indx++] = plane_data_nan[i];
}
// sdfa_instance.showArrays(plane_data_nonan, wh[0], wh[1], true, "plane_data_noNaN");
// sdfa_instance.showArrays(plane_data_nan, wh[0], wh[1], true, "plane_data_NaN");
sdfa_instance.showArrays(plane_data, wh[0], wh[1], true, "plane_data");
// show plane data
/*
for (int dr = 0; dr < 8; dr++){
TilePlanes.PlaneData [][] planes = st.getNeibPlanes(
dr,
clt_parameters.plDbgMerge);
plane_data_nonan = st.getShowPlanes(
planes,
clt_parameters.plMinStrength, // minWeight,
clt_parameters.plMaxEigen, // maxEigen,
clt_parameters.plDispNorm,
false, //boolean use_NaN)
0.0,
10.0);
plane_data_nan = st.getShowPlanes(
planes,
clt_parameters.plMinStrength, // minWeight,
clt_parameters.plMaxEigen, // maxEigen,
clt_parameters.plDispNorm,
true, //boolean use_NaN)
0.0,
10.0);
plane_data = new double [plane_data_nonan.length + plane_data_nan.length][];
indx = 0;
for (int i = 0; i < plane_data_nonan.length; i++){
plane_data[indx++] = plane_data_nonan[i];
}
for (int i = 0; i < plane_data_nan.length; i++){
plane_data[indx++] = plane_data_nan[i];
}
sdfa_instance.showArrays(plane_data, wh[0], wh[1], true, "plane_data_"+dr);
}
*/
}
}
//
public void secondPassSetup( // prepare tile tasks for the second pass based on the previous one(s)
// final double [][][] image_data, // first index - number of image in a quad
......@@ -2972,7 +3073,13 @@ public class TileProcessor {
clt_parameters.plMaxOutliers, // = 20; // Maximal number of outliers to remove
geometryCorrection,
clt_parameters.correct_distortions,
debugLevel); // final int debugLevel)
-1, // debugLevel, // final int debugLevel)
clt_parameters.tileX,
clt_parameters.tileY);
/*
if (clt_parameters.show_planes){
int [] wh = st.getShowPlanesWidthHeight();
double [][] plane_data_nonan = st.getShowPlanes(
......@@ -3026,6 +3133,10 @@ public class TileProcessor {
sdfa_instance.showArrays(plane_data, wh[0], wh[1], true, "plane_data_"+dr);
}
}
*/
/*
st.processPlanes1(
......@@ -3043,6 +3154,13 @@ public class TileProcessor {
*/
if (debugLevel < 100) {
return; // just temporarily
}
if (use_supertiles) {
scan_prev.getBgDispStrength( // calculate (check non-null)?
clt_parameters.stMinBgDisparity, // final double minBgDisparity,
......
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