Skip to content

Conversation

@schipp0
Copy link
Owner

@schipp0 schipp0 commented Jul 30, 2026

… collections (v0.8.8)

Tesseract 5's LSTM engine thresholds internally and reads grayscale better than anything we hand it pre-binarized. Our adaptive window was flipping background paper grain to ink, which Tesseract emitted as stray punctuation ('.', '|', ':') and glued onto real words ('the.', 'of.').

Measured mean WC, adaptive threshold ON -> OFF:

ZeffPapers/MSP00074 (106 pg)  0.828 -> 0.909   review pages 28 -> 6
MSA00005 (11 pg)              0.583 -> 0.781                 7 -> 3
MSA00005 (2 pg)               0.453 -> 0.945                 2 -> 0
MSA00018 (82 pg)              0.803 -> 0.919                25 -> 6

Token-level diffing confirms the words that disappear are exactly those artifacts while real words are gained, so the lower total word count after the change is noise leaving, not text lost.

  • PreprocessConfig.do_binarize now False, with the evidence recorded inline.
  • CLI takes --binarize/--no-binarize; the old --no-binarize spelling still parses so existing scripts keep running.
  • gui._migrate_settings retires a persisted do_binarize=True once. Saved GUI settings outrank dataclass defaults, so a default flip alone would never have reached anyone who had already run the app.
  • CLAUDE.md documents the default and, separately, --psm 1 as the fix for collections with rotated scans: it recovers sideways pages and still emits ALTO coordinates in the input frame (verified by overlaying boxes on the untouched scan), but is deliberately NOT the default — it is a wash on unrotated material, costs ~13% wall time, and its OSD manufactures noise on blank pages (a clean empty page became 9 junk words at PC 0.39).

Found by the first production pilot, MSA00018 Cornell Bell papers. Outputs produced before this commit were binarized and score lower than a re-run would; re-OCR before upload, same caveat as the pre-v0.8.3 frame fix.

… collections (v0.8.8)

Tesseract 5's LSTM engine thresholds internally and reads grayscale better
than anything we hand it pre-binarized. Our adaptive window was flipping
background paper grain to ink, which Tesseract emitted as stray punctuation
('.', '|', ':') and glued onto real words ('the.', 'of.').

Measured mean WC, adaptive threshold ON -> OFF:

    ZeffPapers/MSP00074 (106 pg)  0.828 -> 0.909   review pages 28 -> 6
    MSA00005 (11 pg)              0.583 -> 0.781                 7 -> 3
    MSA00005 (2 pg)               0.453 -> 0.945                 2 -> 0
    MSA00018 (82 pg)              0.803 -> 0.919                25 -> 6

Token-level diffing confirms the words that disappear are exactly those
artifacts while real words are gained, so the lower total word count after
the change is noise leaving, not text lost.

- PreprocessConfig.do_binarize now False, with the evidence recorded inline.
- CLI takes --binarize/--no-binarize; the old --no-binarize spelling still
  parses so existing scripts keep running.
- gui._migrate_settings retires a persisted do_binarize=True once. Saved GUI
  settings outrank dataclass defaults, so a default flip alone would never
  have reached anyone who had already run the app.
- CLAUDE.md documents the default and, separately, --psm 1 as the fix for
  collections with rotated scans: it recovers sideways pages and still emits
  ALTO coordinates in the input frame (verified by overlaying boxes on the
  untouched scan), but is deliberately NOT the default — it is a wash on
  unrotated material, costs ~13% wall time, and its OSD manufactures noise
  on blank pages (a clean empty page became 9 junk words at PC 0.39).

Found by the first production pilot, MSA00018 Cornell Bell papers.
Outputs produced before this commit were binarized and score lower than a
re-run would; re-OCR before upload, same caveat as the pre-v0.8.3 frame fix.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@schipp0 schipp0 merged commit fd01689 into main Jul 30, 2026
1 check failed
@schipp0 schipp0 deleted the preprocessing-binarize-default branch July 30, 2026 17:29
schipp0 added a commit that referenced this pull request Aug 6, 2026
…vation land (v0.8.13)

The remote main gained PRs #1#2 (branch preprocessing-binarize-default)
while local main re-landed the binarize-off default independently and
advanced through v0.8.12 — the histories diverged. Resolutions:

- KEPT from the remote line (was missing locally): atomic_write_bytes'
  _replace_with_retry (6 attempts/backoff on WinError 5/32 — transient
  SMB handle failures during replace-existing), triage deriving Page PC
  from word WCs when the merge's write was lost, both test files, and
  CLAUDE.md's --psm 1 rotated-scans section.
- KEPT from local: everything v0.8.8–v0.8.12 (add-word, clear-page,
  Repackage button, reading-order mode, audit refactors); version
  resolved to 0.8.13 since the merged tree adds behavior over 0.8.12.
- RECONCILED by hand: git auto-merge had silently kept BOTH
  _migrate_settings definitions in gui.py (the second shadowed the
  first). Now one function honoring BOTH marker names — the remote
  build's "binarize_default_2026_07_30" and the local
  "_migrated_binarize_default_off" — so a settings file migrated by
  either build is never re-migrated (which would clear a deliberate
  binarize re-opt-in). Remote's gentler semantics kept: an explicit
  pre-migration do_binarize:false survives; clearing a stale true logs
  a user-facing note. test_preprocess_defaults.py is the union of both
  versions plus a new legacy-marker regression test.

Suite: 184 tests green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign in to join this conversation on GitHub.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant