Commit f84524bd authored by Andrey Filippov's avatar Andrey Filippov

Commits related to global LMA using center, 1/4 and 3/4 references.

parent 11801a89
...@@ -4860,6 +4860,7 @@ public class Interscene { ...@@ -4860,6 +4860,7 @@ public class Interscene {
", showObsHs=" + opts.debugShowObservationHyperstack + ", showObsHs=" + opts.debugShowObservationHyperstack +
", saveInitialFinalOnly=" + opts.saveInitialFinalOnly + ", saveInitialFinalOnly=" + opts.saveInitialFinalOnly +
", centerPairWeightMode=" + opts.centerPairWeightMode + ", centerPairWeightMode=" + opts.centerPairWeightMode +
", useNonCenterPairs=" + clt_parameters.iglp.glob_use_non_center_pairs +
", solverMode=" + solverMode + " (" + solverName + ")"); ", solverMode=" + solverMode + " (" + solverName + ")");
System.out.println(" param_select(X,Y,Z,A,T,R)=[" + System.out.println(" param_select(X,Y,Z,A,T,R)=[" +
param_select[ErsCorrection.DP_DSX] + "," + param_select[ErsCorrection.DP_DSX] + "," +
......
...@@ -26,6 +26,7 @@ public class IntersceneGlobalLmaParameters { ...@@ -26,6 +26,7 @@ public class IntersceneGlobalLmaParameters {
public boolean glob_en; public boolean glob_en;
public boolean glob_exit_after_test; // exit OpticalFlow.buildSeries() immediately after running, do not increment num_orient public boolean glob_exit_after_test; // exit OpticalFlow.buildSeries() immediately after running, do not increment num_orient
public boolean glob_use_non_center_pairs; // off: center-only pairs, on: include quarter/FPN non-center references
public boolean glob_recalculate_quarter_refs; // force regeneration of quarter-reference DSI/INTER-INTRA-LMA files public boolean glob_recalculate_quarter_refs; // force regeneration of quarter-reference DSI/INTER-INTRA-LMA files
public boolean glob_quarter_refs_sfm_only; // generate quarter-reference INTER-INTRA-LMA using SfM-only (no pose LMA updates) public boolean glob_quarter_refs_sfm_only; // generate quarter-reference INTER-INTRA-LMA using SfM-only (no pose LMA updates)
public int glob_solver_mode; // 0 - current sparse global refine, 1 - classic LMA-structure implementation public int glob_solver_mode; // 0 - current sparse global refine, 1 - classic LMA-structure implementation
...@@ -57,6 +58,7 @@ public class IntersceneGlobalLmaParameters { ...@@ -57,6 +58,7 @@ public class IntersceneGlobalLmaParameters {
public IntersceneGlobalLmaParameters() { public IntersceneGlobalLmaParameters() {
glob_en = true; glob_en = true;
glob_exit_after_test = true; // TODO: change default to false when debugging is over glob_exit_after_test = true; // TODO: change default to false when debugging is over
glob_use_non_center_pairs = true;
glob_recalculate_quarter_refs = false; glob_recalculate_quarter_refs = false;
glob_quarter_refs_sfm_only = true; glob_quarter_refs_sfm_only = true;
glob_solver_mode = GLOB_SOLVER_SPARSE_BANDED; glob_solver_mode = GLOB_SOLVER_SPARSE_BANDED;
...@@ -97,6 +99,8 @@ public class IntersceneGlobalLmaParameters { ...@@ -97,6 +99,8 @@ public class IntersceneGlobalLmaParameters {
"Use global LMA for adjusting scenes poses." ); "Use global LMA for adjusting scenes poses." );
gd.addCheckbox("Exit after Global LMA (debug mode)", this.glob_exit_after_test, gd.addCheckbox("Exit after Global LMA (debug mode)", this.glob_exit_after_test,
"exit OpticalFlow.buildSeries() immediately after running, do not increment num_orient enabling re-running next time"); "exit OpticalFlow.buildSeries() immediately after running, do not increment num_orient enabling re-running next time");
gd.addCheckbox("Use non-center references (quarter/FPN)", this.glob_use_non_center_pairs,
"ON: include non-center pair references (quarter/FPN parents). OFF: center-only pairs.");
gd.addCheckbox("Recalculate quarter refs each run (debug)", this.glob_recalculate_quarter_refs, gd.addCheckbox("Recalculate quarter refs each run (debug)", this.glob_recalculate_quarter_refs,
"Force regeneration of quarter-reference -DSI_MAIN and -INTER-INTRA-LMA before Global LMA."); "Force regeneration of quarter-reference -DSI_MAIN and -INTER-INTRA-LMA before Global LMA.");
gd.addCheckbox("Quarter refs use SfM-only generation", this.glob_quarter_refs_sfm_only, gd.addCheckbox("Quarter refs use SfM-only generation", this.glob_quarter_refs_sfm_only,
...@@ -156,6 +160,7 @@ public class IntersceneGlobalLmaParameters { ...@@ -156,6 +160,7 @@ public class IntersceneGlobalLmaParameters {
public void dialogAnswers(GenericJTabbedDialog gd) { public void dialogAnswers(GenericJTabbedDialog gd) {
this.glob_en = gd.getNextBoolean(); this.glob_en = gd.getNextBoolean();
this.glob_exit_after_test = gd.getNextBoolean(); this.glob_exit_after_test = gd.getNextBoolean();
this.glob_use_non_center_pairs = gd.getNextBoolean();
this.glob_recalculate_quarter_refs = gd.getNextBoolean(); this.glob_recalculate_quarter_refs = gd.getNextBoolean();
this.glob_quarter_refs_sfm_only = gd.getNextBoolean(); this.glob_quarter_refs_sfm_only = gd.getNextBoolean();
this.glob_solver_mode = clampSolverMode((int) gd.getNextNumber()); this.glob_solver_mode = clampSolverMode((int) gd.getNextNumber());
...@@ -194,6 +199,7 @@ public class IntersceneGlobalLmaParameters { ...@@ -194,6 +199,7 @@ public class IntersceneGlobalLmaParameters {
public void setProperties(String prefix,Properties properties){ public void setProperties(String prefix,Properties properties){
properties.setProperty(prefix+"glob_en", this.glob_en+""); properties.setProperty(prefix+"glob_en", this.glob_en+"");
properties.setProperty(prefix+"glob_exit_after_test", this.glob_exit_after_test+""); properties.setProperty(prefix+"glob_exit_after_test", this.glob_exit_after_test+"");
properties.setProperty(prefix+"glob_use_non_center_pairs", this.glob_use_non_center_pairs+"");
properties.setProperty(prefix+"glob_recalculate_quarter_refs", this.glob_recalculate_quarter_refs+""); properties.setProperty(prefix+"glob_recalculate_quarter_refs", this.glob_recalculate_quarter_refs+"");
properties.setProperty(prefix+"glob_quarter_refs_sfm_only", this.glob_quarter_refs_sfm_only+""); properties.setProperty(prefix+"glob_quarter_refs_sfm_only", this.glob_quarter_refs_sfm_only+"");
properties.setProperty(prefix+"glob_solver_mode", this.glob_solver_mode+""); properties.setProperty(prefix+"glob_solver_mode", this.glob_solver_mode+"");
...@@ -227,6 +233,7 @@ public class IntersceneGlobalLmaParameters { ...@@ -227,6 +233,7 @@ public class IntersceneGlobalLmaParameters {
public void getProperties(String prefix,Properties properties){ public void getProperties(String prefix,Properties properties){
if (properties.getProperty(prefix+"glob_en")!=null) this.glob_en=Boolean.parseBoolean(properties.getProperty(prefix+"glob_en")); if (properties.getProperty(prefix+"glob_en")!=null) this.glob_en=Boolean.parseBoolean(properties.getProperty(prefix+"glob_en"));
if (properties.getProperty(prefix+"glob_exit_after_test")!=null) this.glob_exit_after_test=Boolean.parseBoolean(properties.getProperty(prefix+"glob_exit_after_test")); if (properties.getProperty(prefix+"glob_exit_after_test")!=null) this.glob_exit_after_test=Boolean.parseBoolean(properties.getProperty(prefix+"glob_exit_after_test"));
if (properties.getProperty(prefix+"glob_use_non_center_pairs")!=null) this.glob_use_non_center_pairs=Boolean.parseBoolean(properties.getProperty(prefix+"glob_use_non_center_pairs"));
if (properties.getProperty(prefix+"glob_recalculate_quarter_refs")!=null) this.glob_recalculate_quarter_refs=Boolean.parseBoolean(properties.getProperty(prefix+"glob_recalculate_quarter_refs")); if (properties.getProperty(prefix+"glob_recalculate_quarter_refs")!=null) this.glob_recalculate_quarter_refs=Boolean.parseBoolean(properties.getProperty(prefix+"glob_recalculate_quarter_refs"));
if (properties.getProperty(prefix+"glob_quarter_refs_sfm_only")!=null) this.glob_quarter_refs_sfm_only=Boolean.parseBoolean(properties.getProperty(prefix+"glob_quarter_refs_sfm_only")); if (properties.getProperty(prefix+"glob_quarter_refs_sfm_only")!=null) this.glob_quarter_refs_sfm_only=Boolean.parseBoolean(properties.getProperty(prefix+"glob_quarter_refs_sfm_only"));
if (properties.getProperty(prefix+"glob_solver_mode")!=null) this.glob_solver_mode=Integer.parseInt(properties.getProperty(prefix+"glob_solver_mode")); if (properties.getProperty(prefix+"glob_solver_mode")!=null) this.glob_solver_mode=Integer.parseInt(properties.getProperty(prefix+"glob_solver_mode"));
...@@ -264,6 +271,7 @@ public class IntersceneGlobalLmaParameters { ...@@ -264,6 +271,7 @@ public class IntersceneGlobalLmaParameters {
IntersceneGlobalLmaParameters iglp = new IntersceneGlobalLmaParameters(); IntersceneGlobalLmaParameters iglp = new IntersceneGlobalLmaParameters();
iglp.glob_en = this.glob_en; iglp.glob_en = this.glob_en;
iglp.glob_exit_after_test = this.glob_exit_after_test; iglp.glob_exit_after_test = this.glob_exit_after_test;
iglp.glob_use_non_center_pairs = this.glob_use_non_center_pairs;
iglp.glob_recalculate_quarter_refs = this.glob_recalculate_quarter_refs; iglp.glob_recalculate_quarter_refs = this.glob_recalculate_quarter_refs;
iglp.glob_quarter_refs_sfm_only = this.glob_quarter_refs_sfm_only; iglp.glob_quarter_refs_sfm_only = this.glob_quarter_refs_sfm_only;
iglp.glob_solver_mode = this.glob_solver_mode; iglp.glob_solver_mode = this.glob_solver_mode;
......
...@@ -1302,11 +1302,69 @@ public class IntersceneGlobalRefine { ...@@ -1302,11 +1302,69 @@ public class IntersceneGlobalRefine {
// Pair/reference orchestration // Pair/reference orchestration
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
private static int findSceneIndexByTimestamp(
final QuadCLT[] quadCLTs,
final int firstScene,
final int lastScene,
final String timestamp) {
if ((timestamp == null) || timestamp.isEmpty()) {
return -1;
}
for (int nscene = firstScene; nscene <= lastScene; nscene++) {
if ((nscene >= 0) && (nscene < quadCLTs.length) && (quadCLTs[nscene] != null)) {
final String ts = quadCLTs[nscene].getImageName();
if (timestamp.equals(ts)) {
return nscene;
}
}
}
return -1;
}
private static double estimatePairShift(
final QuadCLT[] quadCLTs,
final double[][][] scenes_xyzatr,
final int centerIndex,
final int refSceneIndex,
final int sceneIndex,
final double avgZ,
final boolean fmgRectilinear,
final double threshold) {
if ((refSceneIndex < 0) || (refSceneIndex >= quadCLTs.length) || (quadCLTs[refSceneIndex] == null)) {
return Double.NaN;
}
final double[][] refPose = getScenePose(
scenes_xyzatr,
refSceneIndex,
centerIndex);
final double[][] scenePose = getScenePose(
scenes_xyzatr,
sceneIndex,
centerIndex);
double estShift = quadCLTs[refSceneIndex].estimateAverageShift(
refPose,
scenePose,
avgZ,
false,
fmgRectilinear);
if (!Double.isNaN(threshold) && (threshold > 0.0) && (estShift < threshold)) {
estShift = quadCLTs[refSceneIndex].estimateAverageShift(
refPose,
scenePose,
avgZ,
true,
fmgRectilinear);
}
return estShift;
}
/** /**
* Build pair factors for one outer iteration. * Build pair factors for one outer iteration.
* Base set is scene-to-center for all active scenes. *
* Optional add-on uses legacy {@link Interscene#getFPNPairs(...)} to add * <p>Base set is scene-to-center for all active scenes. When enabled, non-center references
* non-center parent references for FPN-prone scenes. * are added from quarter timestamps and legacy {@link Interscene#getFPNPairs(...)} fallback.
* Pairs with predicted sub-threshold offset are skipped before correlation to avoid known
* FPN-prone combinations.
*/ */
private static ArrayList<PairFactor> buildPairFactors( private static ArrayList<PairFactor> buildPairFactors(
final CLTParameters clt_parameters, final CLTParameters clt_parameters,
...@@ -1320,68 +1378,140 @@ public class IntersceneGlobalRefine { ...@@ -1320,68 +1378,140 @@ public class IntersceneGlobalRefine {
final int debugLevel) { final int debugLevel) {
final ArrayList<PairFactor> factors = new ArrayList<PairFactor>(); final ArrayList<PairFactor> factors = new ArrayList<PairFactor>();
final HashSet<Long> used = new HashSet<Long>(); final HashSet<Long> used = new HashSet<Long>();
final boolean useNonCenterPairs = (clt_parameters != null) &&
for (int nscene = firstScene; nscene <= lastScene; nscene++) { (clt_parameters.iglp != null) &&
final int ivar = nscene - firstScene; clt_parameters.iglp.glob_use_non_center_pairs;
if ((ivar >= 0) && (ivar < activePoseScene.length) && activePoseScene[ivar]) { final boolean fmgRectilinear = clt_parameters.imp.fmg_rectilinear;
final long key = (((long) nscene) << 32) | (centerIndex & 0xffffffffL);
if (used.add(key)) {
factors.add(new PairFactor(
nscene,
centerIndex,
false,
1.0));
}
}
}
if (!clt_parameters.imp.fmg_initial_en) {
return factors;
}
final double avgZ = getAverageAbsZ( final double avgZ = getAverageAbsZ(
scenes_xyzatr, scenes_xyzatr,
activePoseScene, activePoseScene,
firstScene); firstScene);
final double fpnMinOffset = clt_parameters.imp.fpn_min_offset;
final double pairMinOffset = Math.max(
Math.max(0.0, minOffset),
(fpnMinOffset > 0.0) ? fpnMinOffset : 0.0);
int q1Index = -1;
int q3Index = -1;
int q1RangeEnd = -1;
int q3RangeStart = -1;
if (useNonCenterPairs &&
(centerIndex >= 0) && (centerIndex < quadCLTs.length) &&
(quadCLTs[centerIndex] != null)) {
final int overlapScenes = Math.max(
1,
Math.min(4, (lastScene - firstScene + 1) / 20 + 1));
q1RangeEnd = Math.min(
lastScene,
centerIndex + overlapScenes);
q3RangeStart = Math.max(
firstScene,
centerIndex - overlapScenes);
q1Index = findSceneIndexByTimestamp(
quadCLTs,
firstScene,
lastScene,
quadCLTs[centerIndex].timestamp_quarter1);
q3Index = findSceneIndexByTimestamp(
quadCLTs,
firstScene,
lastScene,
quadCLTs[centerIndex].timestamp_quarter3);
}
int addedCenter = 0;
int addedQ1 = 0;
int addedQ3 = 0;
int addedFpn = 0;
int skippedFpn = 0;
int scenesWithoutPairs = 0;
final ArrayList<Integer> fpnList = new ArrayList<Integer>(); final ArrayList<Integer> fpnList = new ArrayList<Integer>();
for (int nscene = firstScene; nscene <= lastScene; nscene++) { for (int nscene = firstScene; nscene <= lastScene; nscene++) {
final int ivar = nscene - firstScene; final int ivar = nscene - firstScene;
if ((ivar < 0) || (ivar >= activePoseScene.length) || !activePoseScene[ivar]) { if ((ivar >= 0) && (ivar < activePoseScene.length) && activePoseScene[ivar]) {
continue; boolean addedAny = false;
} final ArrayList<Integer> refs = new ArrayList<Integer>();
double estShift = quadCLTs[centerIndex].estimateAverageShift( refs.add(centerIndex);
getScenePose(scenes_xyzatr, centerIndex, centerIndex), if (useNonCenterPairs && (q1Index >= 0) && (nscene <= q1RangeEnd)) {
getScenePose(scenes_xyzatr, nscene, centerIndex), refs.add(q1Index);
avgZ, }
false, if (useNonCenterPairs && (q3Index >= 0) && (nscene >= q3RangeStart) && (q3Index != q1Index)) {
clt_parameters.imp.fmg_rectilinear); refs.add(q3Index);
if (estShift < minOffset) { }
estShift = quadCLTs[centerIndex].estimateAverageShift( for (int iref = 0; iref < refs.size(); iref++) {
getScenePose(scenes_xyzatr, centerIndex, centerIndex), final int ref = refs.get(iref).intValue();
getScenePose(scenes_xyzatr, nscene, centerIndex), if ((ref < firstScene) || (ref > lastScene) || (ref == nscene)) {
avgZ, continue;
true, }
clt_parameters.imp.fmg_rectilinear); final double estShift = estimatePairShift(
} quadCLTs,
if (estShift < minOffset) { scenes_xyzatr,
fpnList.add(nscene); centerIndex,
ref,
nscene,
avgZ,
fmgRectilinear,
pairMinOffset);
if ((pairMinOffset > 0.0) && (estShift < pairMinOffset)) {
skippedFpn++;
if (ref == centerIndex) {
fpnList.add(Integer.valueOf(nscene));
}
continue;
}
final long key = (((long) nscene) << 32) | (ref & 0xffffffffL);
if (used.add(key)) {
factors.add(new PairFactor(
nscene,
ref,
ref != centerIndex,
1.0));
addedAny = true;
if (ref == centerIndex) {
addedCenter++;
} else if (ref == q1Index) {
addedQ1++;
} else if (ref == q3Index) {
addedQ3++;
}
}
}
if (!addedAny) {
scenesWithoutPairs++;
}
} }
} }
if (fpnList.isEmpty()) {
if (!useNonCenterPairs || !clt_parameters.imp.fmg_initial_en || fpnList.isEmpty()) {
if (debugLevel > -3) {
System.out.println("IntersceneGlobalRefine: pair factors total=" + factors.size() +
", center=" + addedCenter +
", q1=" + addedQ1 +
", q3=" + addedQ3 +
", fpnAdded=" + addedFpn +
", skippedFpnLike=" + skippedFpn +
", scenesWithoutPairs=" + scenesWithoutPairs +
", useNonCenterPairs=" + useNonCenterPairs +
", q1Index=" + q1Index +
", q3Index=" + q3Index +
", pairMinOffset=" + pairMinOffset);
}
return factors; return factors;
} }
double fmgDistance = clt_parameters.imp.fmg_distance; double fmgDistance = clt_parameters.imp.fmg_distance;
if (fmgDistance < (minOffset + 2.0)) { if (fmgDistance < (pairMinOffset + 2.0)) {
fmgDistance = minOffset + 2.0; fmgDistance = pairMinOffset + 2.0;
} }
final int[][] fpnPairs = Interscene.getFPNPairs( final int[][] fpnPairs = Interscene.getFPNPairs(
fpnList, fpnList,
fmgDistance, fmgDistance,
clt_parameters.imp.fmg_rectilinear, fmgRectilinear,
quadCLTs, quadCLTs,
scenes_xyzatr, scenes_xyzatr,
avgZ, avgZ,
centerIndex, centerIndex,
firstScene); firstScene);
int addedNonCenter = 0;
for (int i = 0; i < fpnPairs.length; i++) { for (int i = 0; i < fpnPairs.length; i++) {
final int scene = fpnPairs[i][0]; final int scene = fpnPairs[i][0];
final int ref = fpnPairs[i][1]; final int ref = fpnPairs[i][1];
...@@ -1402,6 +1532,19 @@ public class IntersceneGlobalRefine { ...@@ -1402,6 +1532,19 @@ public class IntersceneGlobalRefine {
if ((quadCLTs[ref] == null) || (scenes_xyzatr[ref] == null)) { if ((quadCLTs[ref] == null) || (scenes_xyzatr[ref] == null)) {
continue; continue;
} }
final double estShift = estimatePairShift(
quadCLTs,
scenes_xyzatr,
centerIndex,
ref,
scene,
avgZ,
fmgRectilinear,
pairMinOffset);
if ((pairMinOffset > 0.0) && (estShift < pairMinOffset)) {
skippedFpn++;
continue;
}
final long key = (((long) scene) << 32) | (ref & 0xffffffffL); final long key = (((long) scene) << 32) | (ref & 0xffffffffL);
if (used.add(key)) { if (used.add(key)) {
factors.add(new PairFactor( factors.add(new PairFactor(
...@@ -1409,7 +1552,7 @@ public class IntersceneGlobalRefine { ...@@ -1409,7 +1552,7 @@ public class IntersceneGlobalRefine {
ref, ref,
true, true,
1.0)); 1.0));
addedNonCenter++; addedFpn++;
if (debugLevel > 1) { if (debugLevel > 1) {
System.out.println("IntersceneGlobalRefine: added non-center pair scene=" + scene + " ref=" + ref); System.out.println("IntersceneGlobalRefine: added non-center pair scene=" + scene + " ref=" + ref);
} }
...@@ -1417,7 +1560,17 @@ public class IntersceneGlobalRefine { ...@@ -1417,7 +1560,17 @@ public class IntersceneGlobalRefine {
} }
if (debugLevel > -3) { if (debugLevel > -3) {
System.out.println("IntersceneGlobalRefine: pair factors total=" + factors.size() + System.out.println("IntersceneGlobalRefine: pair factors total=" + factors.size() +
", nonCenterAdded=" + addedNonCenter + ", fpnCandidates=" + fpnList.size()); ", center=" + addedCenter +
", q1=" + addedQ1 +
", q3=" + addedQ3 +
", fpnAdded=" + addedFpn +
", fpnCandidates=" + fpnList.size() +
", skippedFpnLike=" + skippedFpn +
", scenesWithoutPairs=" + scenesWithoutPairs +
", useNonCenterPairs=" + useNonCenterPairs +
", q1Index=" + q1Index +
", q3Index=" + q3Index +
", pairMinOffset=" + pairMinOffset);
} }
return factors; return factors;
} }
......
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