Propose the content rectangle from the staff lines

Both scan problems reported from testing came from the same place: the
content rectangle defaulted to the whole page, so the mechanism meant
to handle margin junk never engaged. Ketun joululaulu has a vertical
scan streak down the right margin and Engel a shadow, and because trim
is tight and per slice, either one sets that slice's width, which sets
the song's widest slice, which scales the whole song down.

Detection can propose it. Staff lines are long horizontal runs; scan
shadows, spine darkening and glass streaks are vertical, so a wide flat
opening keeps one and erases the other. Three corrections were needed
against the corpus:

- Search only rows inside detected systems. A horizontal artefact above
  or below the music is itself a long horizontal run reaching the paper
  edge, which put Engel's left bound at 0.
- Take a percentile of the staff-line extents, not the maximum. Where
  an artefact touches a staff line the two merge into one component: on
  Ketun p2 the merged line ends at 1575px against 1544px on the clean
  page.
- Take the left bound from the brackets too. A bracket sits left of
  every staff line, so a staff-line bound crops it off — visible
  immediately when comparing exported slices.

Anchors are now a dataclass carrying their left edge rather than a
(top, bottom) tuple.

Engel now drops 12-14% of page width and its music fills 1920px instead
of leaving the shadow's dead space; Ketun drops 12%.

Existing projects keep their saved rectangle; the editor's new Auto-fit
and Auto-fit all buttons re-propose it without disturbing cuts.
This commit is contained in:
Esa Kataja
2026-07-28 23:28:45 +03:00
parent bc19eae111
commit c00a00bb2a
4 changed files with 152 additions and 21 deletions
+21
View File
@@ -194,6 +194,27 @@ fall back to row-profile runs, which is correct there.
**Staff height** — peak-to-peak spacing in the row profile.
**Content rectangle** — proposed per page from the staff lines. Staff lines are
long *horizontal* runs, while a scan-edge shadow, a spine darkening and the
streak a dirty scanner glass leaves are all *vertical*, so opening with a wide
flat kernel keeps the music and erases the artefacts. Three details make it
work:
- Only rows inside detected systems are searched. Otherwise a horizontal scan
artefact above or below the music is itself a long horizontal run, and it
reaches the paper edge.
- The horizontal bounds come from a *percentile* of the staff-line extents, not
their maximum. Where an artefact touches the end of a staff line the two merge
into one component; a page has dozens of staff lines and only a few are
contaminated.
- The left bound also considers the **brackets**, which sit left of every staff
line. A bound taken from staff lines alone crops the bracket off, and a
bracket is notation.
Only the horizontal bounds are proposed. Vertically the cuts and discard flags
already isolate the header and footer, and cropping the top would risk clipping
a tempo mark or a section label above the first staff.
**Source type**`get_images(full=True)` / `get_drawings()` proposes bitmap or
vector per PDF; the tool asks the user to confirm before routing. (`full=True` is
required, or `get_image_bbox` rejects the item.)