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 {
", showObsHs=" + opts.debugShowObservationHyperstack +
", saveInitialFinalOnly=" + opts.saveInitialFinalOnly +
", centerPairWeightMode=" + opts.centerPairWeightMode +
", useNonCenterPairs=" + clt_parameters.iglp.glob_use_non_center_pairs +
", solverMode=" + solverMode + " (" + solverName + ")");
System.out.println(" param_select(X,Y,Z,A,T,R)=[" +
param_select[ErsCorrection.DP_DSX] + "," +
......
......@@ -26,6 +26,7 @@ public class IntersceneGlobalLmaParameters {
public boolean glob_en;
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_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
......@@ -57,6 +58,7 @@ public class IntersceneGlobalLmaParameters {
public IntersceneGlobalLmaParameters() {
glob_en = true;
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_quarter_refs_sfm_only = true;
glob_solver_mode = GLOB_SOLVER_SPARSE_BANDED;
......@@ -97,6 +99,8 @@ public class IntersceneGlobalLmaParameters {
"Use global LMA for adjusting scenes poses." );
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");
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,
"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,
......@@ -156,6 +160,7 @@ public class IntersceneGlobalLmaParameters {
public void dialogAnswers(GenericJTabbedDialog gd) {
this.glob_en = 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_quarter_refs_sfm_only = gd.getNextBoolean();
this.glob_solver_mode = clampSolverMode((int) gd.getNextNumber());
......@@ -194,6 +199,7 @@ public class IntersceneGlobalLmaParameters {
public void setProperties(String prefix,Properties properties){
properties.setProperty(prefix+"glob_en", this.glob_en+"");
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_quarter_refs_sfm_only", this.glob_quarter_refs_sfm_only+"");
properties.setProperty(prefix+"glob_solver_mode", this.glob_solver_mode+"");
......@@ -227,6 +233,7 @@ public class IntersceneGlobalLmaParameters {
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_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_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"));
......@@ -264,6 +271,7 @@ public class IntersceneGlobalLmaParameters {
IntersceneGlobalLmaParameters iglp = new IntersceneGlobalLmaParameters();
iglp.glob_en = this.glob_en;
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_quarter_refs_sfm_only = this.glob_quarter_refs_sfm_only;
iglp.glob_solver_mode = this.glob_solver_mode;
......
......@@ -1302,11 +1302,69 @@ public class IntersceneGlobalRefine {
// 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.
* Base set is scene-to-center for all active scenes.
* Optional add-on uses legacy {@link Interscene#getFPNPairs(...)} to add
* non-center parent references for FPN-prone scenes.
*
* <p>Base set is scene-to-center for all active scenes. When enabled, non-center references
* 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(
final CLTParameters clt_parameters,
......@@ -1320,68 +1378,140 @@ public class IntersceneGlobalRefine {
final int debugLevel) {
final ArrayList<PairFactor> factors = new ArrayList<PairFactor>();
final HashSet<Long> used = new HashSet<Long>();
final boolean useNonCenterPairs = (clt_parameters != null) &&
(clt_parameters.iglp != null) &&
clt_parameters.iglp.glob_use_non_center_pairs;
final boolean fmgRectilinear = clt_parameters.imp.fmg_rectilinear;
final double avgZ = getAverageAbsZ(
scenes_xyzatr,
activePoseScene,
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>();
for (int nscene = firstScene; nscene <= lastScene; nscene++) {
final int ivar = nscene - firstScene;
if ((ivar >= 0) && (ivar < activePoseScene.length) && activePoseScene[ivar]) {
final long key = (((long) nscene) << 32) | (centerIndex & 0xffffffffL);
boolean addedAny = false;
final ArrayList<Integer> refs = new ArrayList<Integer>();
refs.add(centerIndex);
if (useNonCenterPairs && (q1Index >= 0) && (nscene <= q1RangeEnd)) {
refs.add(q1Index);
}
if (useNonCenterPairs && (q3Index >= 0) && (nscene >= q3RangeStart) && (q3Index != q1Index)) {
refs.add(q3Index);
}
for (int iref = 0; iref < refs.size(); iref++) {
final int ref = refs.get(iref).intValue();
if ((ref < firstScene) || (ref > lastScene) || (ref == nscene)) {
continue;
}
final double estShift = estimatePairShift(
quadCLTs,
scenes_xyzatr,
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,
centerIndex,
false,
ref,
ref != centerIndex,
1.0));
addedAny = true;
if (ref == centerIndex) {
addedCenter++;
} else if (ref == q1Index) {
addedQ1++;
} else if (ref == q3Index) {
addedQ3++;
}
}
}
if (!clt_parameters.imp.fmg_initial_en) {
return factors;
if (!addedAny) {
scenesWithoutPairs++;
}
final double avgZ = getAverageAbsZ(
scenes_xyzatr,
activePoseScene,
firstScene);
final ArrayList<Integer> fpnList = new ArrayList<Integer>();
for (int nscene = firstScene; nscene <= lastScene; nscene++) {
final int ivar = nscene - firstScene;
if ((ivar < 0) || (ivar >= activePoseScene.length) || !activePoseScene[ivar]) {
continue;
}
double estShift = quadCLTs[centerIndex].estimateAverageShift(
getScenePose(scenes_xyzatr, centerIndex, centerIndex),
getScenePose(scenes_xyzatr, nscene, centerIndex),
avgZ,
false,
clt_parameters.imp.fmg_rectilinear);
if (estShift < minOffset) {
estShift = quadCLTs[centerIndex].estimateAverageShift(
getScenePose(scenes_xyzatr, centerIndex, centerIndex),
getScenePose(scenes_xyzatr, nscene, centerIndex),
avgZ,
true,
clt_parameters.imp.fmg_rectilinear);
}
if (estShift < minOffset) {
fpnList.add(nscene);
}
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);
}
if (fpnList.isEmpty()) {
return factors;
}
double fmgDistance = clt_parameters.imp.fmg_distance;
if (fmgDistance < (minOffset + 2.0)) {
fmgDistance = minOffset + 2.0;
if (fmgDistance < (pairMinOffset + 2.0)) {
fmgDistance = pairMinOffset + 2.0;
}
final int[][] fpnPairs = Interscene.getFPNPairs(
fpnList,
fmgDistance,
clt_parameters.imp.fmg_rectilinear,
fmgRectilinear,
quadCLTs,
scenes_xyzatr,
avgZ,
centerIndex,
firstScene);
int addedNonCenter = 0;
for (int i = 0; i < fpnPairs.length; i++) {
final int scene = fpnPairs[i][0];
final int ref = fpnPairs[i][1];
......@@ -1402,6 +1532,19 @@ public class IntersceneGlobalRefine {
if ((quadCLTs[ref] == null) || (scenes_xyzatr[ref] == null)) {
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);
if (used.add(key)) {
factors.add(new PairFactor(
......@@ -1409,7 +1552,7 @@ public class IntersceneGlobalRefine {
ref,
true,
1.0));
addedNonCenter++;
addedFpn++;
if (debugLevel > 1) {
System.out.println("IntersceneGlobalRefine: added non-center pair scene=" + scene + " ref=" + ref);
}
......@@ -1417,7 +1560,17 @@ public class IntersceneGlobalRefine {
}
if (debugLevel > -3) {
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;
}
......
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