Commit b7a494a1 authored by Andrey Filippov's avatar Andrey Filippov

improving pairwise matching

parent 2f51f8e6
...@@ -1597,7 +1597,19 @@ adjusted affines[1] for a pair: 1694564291_293695/1694564778_589341 ...@@ -1597,7 +1597,19 @@ adjusted affines[1] for a pair: 1694564291_293695/1694564778_589341
} }
/**
*
* @param clt_parameters
* @param fpixels
* @param img_width
* @param woi
* @param affine
* @param tp_tasks_o
* @param batch_mode
* @param dbg_suffix
* @param debugLevel
* @return [2][tilesX*tilesY][3]
*/
public static double [][][] rectilinearVectorField( // scene0/scene1 public static double [][][] rectilinearVectorField( // scene0/scene1
final CLTParameters clt_parameters, final CLTParameters clt_parameters,
final float [][] fpixels, // to check for empty final float [][] fpixels, // to check for empty
......
...@@ -3461,7 +3461,7 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{ ...@@ -3461,7 +3461,7 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
} }
/** /**
* Remove (mask out) tiles that have high product of distance (in pixels) from the vertiacal point * Remove (mask out) tiles that have high product of distance (in pixels) from the vertical point
* by the metric difference between the elevation and an approximation plane * by the metric difference between the elevation and an approximation plane
* @param data elevation data, decimated to match GPU tile grid. May have NaNs. * @param data elevation data, decimated to match GPU tile grid. May have NaNs.
* @param mask_in null or boolean[] mask same dimension as the data[]/ False disables processing, * @param mask_in null or boolean[] mask same dimension as the data[]/ False disables processing,
......
...@@ -1449,10 +1449,10 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -1449,10 +1449,10 @@ public class OrthoMapsCollection implements Serializable{
double [][] ground_planes_metric = new double [tp_tasks.length][]; double [][] ground_planes_metric = new double [tp_tasks.length][];
boolean [][] ground_planes_masks = new boolean[2][]; boolean [][] ground_planes_masks = new boolean[2][];
double initial_above = 3; // m double initial_above = 3; // m
double initial_below = 3; // m double initial_below = 5; //3; // m
int num_refine = 3; int num_refine = 3;
double frac_above = 0.3; double frac_above = 0.5; // 0.3;
double frac_below = 0.1; double frac_below = 0.01; // 0.1;
double [][] jtj = null; double [][] jtj = null;
double rms = Double.NaN; double rms = Double.NaN;
double last_center_radius = 0; double last_center_radius = 0;
...@@ -5067,7 +5067,8 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -5067,7 +5067,8 @@ public class OrthoMapsCollection implements Serializable{
int [] indices = getScenesSelection( int [] indices = getScenesSelection(
null, // boolean select_all, null, // boolean select_all,
" to find intersects"); // String purpose) " to find intersects"); // String purpose)
if (indices == null) { if ((indices == null) || (indices.length < 2)) {
System.out.println ("generatePairwiseAffines(): indices[] is null or too short, exiting");
return false; return false;
} }
...@@ -5077,13 +5078,13 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -5077,13 +5078,13 @@ public class OrthoMapsCollection implements Serializable{
} }
int num_defined = 0; int num_defined = 0;
int num_undefined = 0; int num_undefined = 0;
boolean single_pair = indices.length==2;
for (int i = 0; i < indices.length-1; i++) { for (int i = 0; i < indices.length-1; i++) {
for (int j = i+1; j < indices.length; j++){ for (int j = i+1; j < indices.length; j++){
String name2 = ortho_maps[indices[j]].getName(); String name2 = ortho_maps[indices[j]].getName();
PairwiseOrthoMatch match = ortho_maps[indices[i]].getMatch(name2,true); PairwiseOrthoMatch match = ortho_maps[indices[i]].getMatch(name2,true);
if (match != null) { if (match != null) {
if (match.isDefined()) { if (match.isDefined() && !single_pair) {
num_defined++; num_defined++;
} else { } else {
num_undefined++; num_undefined++;
...@@ -5139,7 +5140,7 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -5139,7 +5140,7 @@ public class OrthoMapsCollection implements Serializable{
boolean use_multi = true; boolean use_multi = true;
int heur = 15; int heur = 15;
int min_scene = 0; int min_scene = 0;
GenericJTabbedDialog gd = new GenericJTabbedDialog("Pairwise Match Parameters",1200,1000); GenericJTabbedDialog gd = new GenericJTabbedDialog("Pairwise Match Parameters",1200,1100);
gd.addMessage("Number of scenes - "+indices.length+ gd.addMessage("Number of scenes - "+indices.length+
", number of defined pairs - "+num_defined+ ", number of defined pairs - "+num_defined+
", number of undefined pairs - "+num_undefined); ", number of undefined pairs - "+num_undefined);
...@@ -5232,7 +5233,7 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -5232,7 +5233,7 @@ public class OrthoMapsCollection implements Serializable{
heur = (int) gd.getNextNumber(); heur = (int) gd.getNextNumber();
use_multi = gd.getNextBoolean(); use_multi = gd.getNextBoolean();
double max_rmse_reuse= max_rms_refine; double max_rmse_reuse= max_rms_refine;
int [][] pairs_defined = filterPairs( int [][] pairs_defined = single_pair?(new int[0][]):filterPairs(
indices, // int [] indices_in, indices, // int [] indices_in,
min_overlap_frac, // double min_overlap_frac, min_overlap_frac, // double min_overlap_frac,
max_rmse_reuse, // double max_rmse, max_rmse_reuse, // double max_rmse,
...@@ -5415,7 +5416,7 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -5415,7 +5416,7 @@ public class OrthoMapsCollection implements Serializable{
System.out.println ("Skipping "+ipair[0]+":"+ipair[1]+" until "+min_scene); System.out.println ("Skipping "+ipair[0]+":"+ipair[1]+" until "+min_scene);
continue; continue;
} }
boolean direct = ipair[0] < ipair[0]; // always? boolean direct = ipair[0] < ipair[1]; // always?
int min_zoom_lev = ortho_maps[ipair[0]].getOriginalZoomLevel(); int min_zoom_lev = ortho_maps[ipair[0]].getOriginalZoomLevel();
int max_zoom_lev = ortho_maps[ipair[0]].getOriginalZoomLevel(); int max_zoom_lev = ortho_maps[ipair[0]].getOriginalZoomLevel();
double max_agl = ortho_maps[ipair[0]].getAGL(); double max_agl = ortho_maps[ipair[0]].getAGL();
...@@ -5439,7 +5440,7 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -5439,7 +5440,7 @@ public class OrthoMapsCollection implements Serializable{
// unityAffine() // unityAffine()
double [][] affine0 = pmtch_use_affine?ortho_maps[ipair[0]].getAffine():unityAffine(); // {{1,0,0},{0,1,0}}; // will always stay the same double [][] affine0 = pmtch_use_affine?ortho_maps[ipair[0]].getAffine():unityAffine(); // {{1,0,0},{0,1,0}}; // will always stay the same
double [][] affine1 = pmtch_use_affine?ortho_maps[ipair[0]].getAffine():unityAffine(); // {{1,0,0},{0,1,0}}; // here (manual mode) start from the center, may use prediction in auto double [][] affine1 = pmtch_use_affine?ortho_maps[ipair[1]].getAffine():unityAffine(); // {{1,0,0},{0,1,0}}; // here (manual mode) start from the center, may use prediction in auto
double [][][] affines = new double[][][] {affine0,affine1}; double [][][] affines = new double[][][] {affine0,affine1};
double spiral_rms = Double.NaN; double spiral_rms = Double.NaN;
// now always unity, but after partial adjustment may be non-unity // now always unity, but after partial adjustment may be non-unity
......
...@@ -237,6 +237,8 @@ public class OrthoPairLMA { ...@@ -237,6 +237,8 @@ public class OrthoPairLMA {
double r_pix = Math.sqrt(r_pix2); // radius in pixels double r_pix = Math.sqrt(r_pix2); // radius in pixels
double wr = 0.5*(1.0 + Math.cos(0.5*Math.PI*r_pix/radius_pix)); double wr = 0.5*(1.0 + Math.cos(0.5*Math.PI*r_pix/radius_pix));
weights[aTile] = w*wr; weights[aTile] = w*wr;
} else {
weights[aTile] = 0;
} }
} }
} }
...@@ -275,6 +277,7 @@ public class OrthoPairLMA { ...@@ -275,6 +277,7 @@ public class OrthoPairLMA {
final double [][] vector_XYS, final double [][] vector_XYS,
final double [] weights_extra, // null or additional weights (such as elevation-based) final double [] weights_extra, // null or additional weights (such as elevation-based)
final double [][] centers) { final double [][] centers) {
boolean dbg = false;
final int rad_max = Math.max(woi.width,woi.height)/2 +1; final int rad_max = Math.max(woi.width,woi.height)/2 +1;
final int rad_length = rad_max +1; final int rad_length = rad_max +1;
final Thread[] threads = ImageDtt.newThreadArray(); final Thread[] threads = ImageDtt.newThreadArray();
...@@ -286,53 +289,6 @@ public class OrthoPairLMA { ...@@ -286,53 +289,6 @@ public class OrthoPairLMA {
final double [][] sy_arr = new double [threads.length][rad_length]; final double [][] sy_arr = new double [threads.length][rad_length];
final double [][] sy2_arr = new double [threads.length][rad_length]; final double [][] sy2_arr = new double [threads.length][rad_length];
final int [][] sn_arr = new int [threads.length][rad_length]; final int [][] sn_arr = new int [threads.length][rad_length];
boolean dbg = false;
if (dbg) {
String [] titles = {"fx","fy","vw","w","cent-x","cent-y","dx","dy","r_t","irt"};
final double [][] dbg_img = new double [titles.length][woi.width*woi.height];
for (int i = 0; i < dbg_img.length; i++) {
Arrays.fill(dbg_img[i], Double.NaN);
}
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int iTile = ai.getAndIncrement(); iTile < N; iTile = ai.getAndIncrement()) {
int tileX = iTile % woi.width + woi.x;
int tileY = iTile / woi.width + woi.y;
int aTile = tileY * width + tileX;
if ((vector_XYS[aTile] != null) && (centers[aTile] != null)) {
double w = vector_XYS[aTile][2];
if (weights_extra != null) w *= weights_extra[aTile];
if (Double.isNaN(w)) w = 0;
double dx = centers[aTile][0] - origin[0];
double dy = centers[aTile][1] - origin[1];
double r_t = Math.sqrt(dx*dx+dy*dy)/GPUTileProcessor.DTT_SIZE; // radius in tiles
int irt = (int) Math.round(r_t);
dbg_img[0][iTile] = vector_XYS[aTile][0];
dbg_img[1][iTile] = vector_XYS[aTile][1];
dbg_img[2][iTile] = vector_XYS[aTile][2];
dbg_img[3][iTile] = w;
dbg_img[4][iTile] = centers[aTile][0];
dbg_img[5][iTile] = centers[aTile][1];
dbg_img[6][iTile] = dx;
dbg_img[7][iTile] = dy;
dbg_img[8][iTile] = r_t;
dbg_img[9][iTile] = irt;
}
}
}
};
}
ImageDtt.startAndJoin(threads);
ai.set(0);
ShowDoubleFloatArrays.showArrays(
dbg_img,
woi.width,
woi.height,
true,
"getCenterRadius",
titles);
}
for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() { threads[ithread] = new Thread() {
public void run() { public void run() {
...@@ -416,6 +372,60 @@ public class OrthoPairLMA { ...@@ -416,6 +372,60 @@ public class OrthoPairLMA {
} }
std_prev = std; std_prev = std;
} }
if (dbg) {
final double [] weights_center = applyRadialWeights( // uses this.center_radius;
vector_XYS, // final double [][] vector_XYS,
weights_extra, // final double [] weights_extra,
centers); // final double [][] centers);
String [] titles = {"fx","fy","wc","vw","w","cent-x","cent-y","dx","dy","r_t","irt"};
final double [][] dbg_img = new double [titles.length][woi.width*woi.height];
for (int i = 0; i < dbg_img.length; i++) {
Arrays.fill(dbg_img[i], Double.NaN);
}
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int iTile = ai.getAndIncrement(); iTile < N; iTile = ai.getAndIncrement()) {
int tileX = iTile % woi.width + woi.x;
int tileY = iTile / woi.width + woi.y;
int aTile = tileY * width + tileX;
dbg_img[ 2][iTile] = weights_center[aTile];
if ((vector_XYS[aTile] != null) && (centers[aTile] != null)) {
double w = vector_XYS[aTile][2];
if (weights_extra != null) w *= weights_extra[aTile];
if (Double.isNaN(w)) w = 0;
double dx = centers[aTile][0] - origin[0];
double dy = centers[aTile][1] - origin[1];
double r_t = Math.sqrt(dx*dx+dy*dy)/GPUTileProcessor.DTT_SIZE; // radius in tiles
int irt = (int) Math.round(r_t);
dbg_img[ 0][iTile] = vector_XYS[aTile][0];
dbg_img[ 1][iTile] = vector_XYS[aTile][1];
dbg_img[ 3][iTile] = vector_XYS[aTile][2];
dbg_img[ 4][iTile] = w;
dbg_img[ 5][iTile] = centers[aTile][0];
dbg_img[ 6][iTile] = centers[aTile][1];
dbg_img[ 7][iTile] = dx;
dbg_img[ 8][iTile] = dy;
dbg_img[ 9][iTile] = r_t;
dbg_img[10][iTile] = irt;
}
}
}
};
}
ImageDtt.startAndJoin(threads);
ai.set(0);
ShowDoubleFloatArrays.showArrays(
dbg_img,
woi.width,
woi.height,
true,
"getCenterRadius",
titles);
}
if ((min_tiles > 0) && (min_radius > 0) && (scnc < min_tiles)) { if ((min_tiles > 0) && (min_radius > 0) && (scnc < min_tiles)) {
center_radius = 0; center_radius = 0;
} }
......
...@@ -147,13 +147,18 @@ public class PairsGraph { ...@@ -147,13 +147,18 @@ public class PairsGraph {
timestamps[i] = ortho_maps[indices[i]].getTimeStamp(); timestamps[i] = ortho_maps[indices[i]].getTimeStamp();
} }
for (int [] u_pair: undefined_pairs) { for (int [] pair: undefined_pairs) {
pair_state[u_pair[0]][u_pair[0]] = PAIR_UNDEFINED; pair_state[pair[0]][pair[1]] = PAIR_UNDEFINED;
PairwiseOrthoMatch match = ortho_maps[indices[pair[0]]].getMatch(ortho_maps[indices[pair[1]]].getName(),true);
overlaps[pair[0]][pair[1]] = match.getOverlap();
} }
for (int [] d_pair: defined_pairs) { for (int [] pair: defined_pairs) {
pair_state[d_pair[0]][d_pair[0]] = PAIR_DEFINED; pair_state[pair[0]][pair[1]] = PAIR_DEFINED;
PairwiseOrthoMatch match = ortho_maps[indices[pair[0]]].getMatch(ortho_maps[indices[pair[1]]].getName(),true);
overlaps[pair[0]][pair[1]] = match.getOverlap();
recordPair( recordPair(
d_pair, // int [] pair, pair, // int [] pair,
true, // boolean success, true, // boolean success,
multi); multi);
} }
......
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