Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
I
imagej-elphel
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
3
Issues
3
List
Board
Labels
Milestones
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Elphel
imagej-elphel
Commits
f84524bd
Commit
f84524bd
authored
Mar 05, 2026
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Commits related to global LMA using center, 1/4 and 3/4 references.
parent
11801a89
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
208 additions
and
46 deletions
+208
-46
Interscene.java
...main/java/com/elphel/imagej/tileprocessor/Interscene.java
+1
-0
IntersceneGlobalLmaParameters.java
...l/imagej/tileprocessor/IntersceneGlobalLmaParameters.java
+8
-0
IntersceneGlobalRefine.java
...m/elphel/imagej/tileprocessor/IntersceneGlobalRefine.java
+199
-46
No files found.
src/main/java/com/elphel/imagej/tileprocessor/Interscene.java
View file @
f84524bd
...
...
@@ -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
]
+
","
+
...
...
src/main/java/com/elphel/imagej/tileprocessor/IntersceneGlobalLmaParameters.java
View file @
f84524bd
...
...
@@ -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
;
...
...
src/main/java/com/elphel/imagej/tileprocessor/IntersceneGlobalRefine.java
View file @
f84524bd
...
...
@@ -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
>();
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
&
0xffffffff
L
);
if
(
used
.
add
(
key
))
{
factors
.
add
(
new
PairFactor
(
nscene
,
centerIndex
,
false
,
1.0
));
}
}
}
if
(!
clt_parameters
.
imp
.
fmg_initial_en
)
{
return
factors
;
}
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
])
{
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
((
ivar
>=
0
)
&&
(
ivar
<
activePoseScene
.
length
)
&&
activePoseScene
[
ivar
])
{
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
&
0xffffffff
L
);
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
;
}
double
fmgDistance
=
clt_parameters
.
imp
.
fmg_distance
;
if
(
fmgDistance
<
(
m
inOffset
+
2.0
))
{
fmgDistance
=
m
inOffset
+
2.0
;
if
(
fmgDistance
<
(
pairM
inOffset
+
2.0
))
{
fmgDistance
=
pairM
inOffset
+
2.0
;
}
final
int
[][]
fpnPairs
=
Interscene
.
getFPNPairs
(
fpnList
,
fmgDistance
,
clt_parameters
.
imp
.
fmg_r
ectilinear
,
fmgR
ectilinear
,
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
&
0xffffffff
L
);
if
(
used
.
add
(
key
))
{
factors
.
add
(
new
PairFactor
(
...
...
@@ -1409,7 +1552,7 @@ public class IntersceneGlobalRefine {
ref
,
true
,
1.0
));
added
NonCenter
++;
added
Fpn
++;
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
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment