Leave a panorama frame out without leaving the page
A frame that did not fit ended the job with its name, and the only way on was Back, a smaller selection and every frame read, demosaiced and searched for keypoints again. Each row on the page now has a box. An unticked frame is left out and the rest are solved again from what the first pass measured. dr_pano::align is split for it: match_pairs does the matching and the pairwise RANSAC once over every frame (about 5 s for twelve), and solve takes a subset of the frames and uses only the links among them (about 0.1 s). Solving a subset by re-aligning it also moved every RANSAC seed, which are keyed on frame position, and on the fixture set that was enough to lose a marginal link and strand a neighbour of the frame left out. A frame that cannot be placed no longer stops the job either. Its row names it and Merge stays off until it is unticked; the headless example leaves such frames out the same way, and takes --leave-out N to try it.
This commit is contained in:
@@ -616,6 +616,7 @@ export component AppWindow inherits Window {
|
||||
callback merge-confirm();
|
||||
callback merge-abandon();
|
||||
callback merge-projection-picked(int);
|
||||
callback merge-frame-toggled(int, bool);
|
||||
callback merge-border-picked(int);
|
||||
/// A fill knob turned: its name and the new value.
|
||||
callback merge-fill-knob(string, float);
|
||||
@@ -1182,6 +1183,7 @@ in property <bool> panel-visible: true;
|
||||
merge() => { root.merge-confirm(); }
|
||||
abandon() => { root.merge-abandon(); }
|
||||
projection-picked(i) => { root.merge-projection-picked(i); }
|
||||
frame-toggled(i, on) => { root.merge-frame-toggled(i, on); }
|
||||
border-picked(i) => { root.merge-border-picked(i); }
|
||||
fill-knob(name, value) => { root.merge-fill-knob(name, value); }
|
||||
close() => { root.merge-close(); }
|
||||
|
||||
+24
-8
@@ -7,11 +7,13 @@
|
||||
// one. The difference is the pause in the middle: the job aligns, this
|
||||
// page shows what it found, and nothing is written until the photographer
|
||||
// presses Merge (FR-MRG-1). A frame that could not be placed is named on
|
||||
// its row and the button stays off (FR-MRG-5).
|
||||
// its row and the button stays off (FR-MRG-5) until it is unticked: each
|
||||
// row's box keeps or leaves out its frame, and the job aligns again over
|
||||
// the ones kept without reading any of them again.
|
||||
|
||||
import { Theme } from "theme.slint";
|
||||
import { Button, PanelHeading, Label, Value, Caption, Panel, ProgressBar } from "widgets.slint";
|
||||
import { Segmented, SliderRow } from "controls.slint";
|
||||
import { Segmented, SliderRow, Check } from "controls.slint";
|
||||
|
||||
/// One source frame's line in the alignment table.
|
||||
export struct MergeFrameRow {
|
||||
@@ -19,6 +21,8 @@ export struct MergeFrameRow {
|
||||
/// "yaw −55.9° · pitch −1.6°", or why it is not aligned.
|
||||
detail: string,
|
||||
aligned: bool,
|
||||
/// Whether the frame is in the alignment; unticked, it is left out.
|
||||
included: bool,
|
||||
}
|
||||
|
||||
export component MergePage inherits Rectangle {
|
||||
@@ -75,6 +79,8 @@ export component MergePage inherits Rectangle {
|
||||
callback merge();
|
||||
callback abandon();
|
||||
callback projection-picked(int);
|
||||
/// A frame's box: its index in `frames`, and whether to keep it.
|
||||
callback frame-toggled(int, bool);
|
||||
callback border-picked(int);
|
||||
/// A knob turned: its name ("scale", "erosion", "coarse", "band",
|
||||
/// "mirror", "feather") and the new value.
|
||||
@@ -276,18 +282,28 @@ export component MergePage inherits Rectangle {
|
||||
Panel {
|
||||
PanelHeading { text: "Frames"; }
|
||||
|
||||
for row in root.frames: HorizontalLayout {
|
||||
// Controlled: the tick follows the report the job sends
|
||||
// back, so a box never claims a frame the alignment on
|
||||
// screen does not have.
|
||||
for row[i] in root.frames: HorizontalLayout {
|
||||
spacing: Theme.gap;
|
||||
Label {
|
||||
text: row.name;
|
||||
width: 160px;
|
||||
overflow: elide;
|
||||
Check {
|
||||
label: row.name;
|
||||
width: 200px;
|
||||
checked: row.included;
|
||||
controlled: true;
|
||||
toggled(on) => {
|
||||
if (!root.running && !root.done) {
|
||||
root.frame-toggled(i, on);
|
||||
}
|
||||
}
|
||||
}
|
||||
Caption {
|
||||
text: row.detail;
|
||||
warn: !row.aligned;
|
||||
warn: row.included && !row.aligned;
|
||||
overflow: elide;
|
||||
horizontal-stretch: 1;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user