dr-pano: a second XFeat shape for portrait frames, and a matcher that takes seconds
Twelve real frames from the fixture set now align in 4.5 s — 4.4 s of matching, 118 ms of bundle adjustment — where the first run took 51 s and left the first two frames out. The matcher computes each pair's similarity matrix once, across the cores, with a dot product written to vectorise; both nearest-neighbour directions read it. The frames that failed were portrait: fitted into the landscape input they used 512 of 1024 px, and their thin overlap did not survive at half resolution. The same weights are now exported at 768×1024 as well and the detector picks the shape by aspect. The example aligns from embedded previews and draws the set on a cylinder; on the fixture the sweep is 152° at a fitted 47.9 mm against the EXIF's 50, RMS 1.5 px, and the overlaps show no ghosting.
This commit is contained in:
@@ -151,9 +151,11 @@ pub fn align(frames: &[Features], opts: &AlignOptions) -> Result<Alignment, Pano
|
||||
let mut links = Vec::new();
|
||||
let mut observations: Vec<Observation> = Vec::new();
|
||||
let mut matched_any = vec![false; n];
|
||||
let t_match = std::time::Instant::now();
|
||||
for i in 0..n {
|
||||
for j in i + 1..n {
|
||||
let matches: Vec<Match> = match_features(&frames[i], &frames[j], opts.min_similarity);
|
||||
log::debug!("pair {i}-{j}: {} matches", matches.len());
|
||||
if matches.len() < 4 {
|
||||
continue;
|
||||
}
|
||||
@@ -175,6 +177,10 @@ pub fn align(frames: &[Features], opts: &AlignOptions) -> Result<Alignment, Pano
|
||||
continue;
|
||||
};
|
||||
let needed = (8.0 + 0.3 * matches.len() as f64).ceil() as usize;
|
||||
log::debug!(
|
||||
"pair {i}-{j}: {} inliers, {needed} needed",
|
||||
inliers.len()
|
||||
);
|
||||
if inliers.len() <= needed || inliers.len() < opts.min_inliers {
|
||||
continue;
|
||||
}
|
||||
@@ -204,6 +210,8 @@ pub fn align(frames: &[Features], opts: &AlignOptions) -> Result<Alignment, Pano
|
||||
}
|
||||
}
|
||||
|
||||
log::debug!("matching and pairwise geometry in {:?}", t_match.elapsed());
|
||||
|
||||
// 3: the focal length.
|
||||
let mut estimates: Vec<f64> = links
|
||||
.iter()
|
||||
@@ -304,7 +312,14 @@ pub fn align(frames: &[Features], opts: &AlignOptions) -> Result<Alignment, Pano
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
let t_adjust = std::time::Instant::now();
|
||||
let adjusted = bundle::adjust(start, &obs, &opts.adjust)?;
|
||||
log::debug!(
|
||||
"bundle adjustment: {} observations, {} iterations in {:?}",
|
||||
obs.len(),
|
||||
adjusted.iterations,
|
||||
t_adjust.elapsed()
|
||||
);
|
||||
for (slot, &k) in aligned.iter().enumerate() {
|
||||
rotations[k] = Some(adjusted.cameras.rotations[slot]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user