erikandClaude Opus 5.5 c8b9f610bf Split stitching into a hardware-independent myscan.stitching package
stitch.py and pagegraph.py mixed laser odometry, image registration,
frame correction, canvas handling, pose-graph maths and the two stitchers.
They are now modules of myscan/stitching, which imports nothing from the
device code:

  geometry    rigid transforms, pose vectors, warp_add
  filters     grayscale, high-pass, feather weights
  correct     Corrector: undistortion + flat field (and weighted variant)
  odometry    LaserOdometry: the laser model and the phase-correlation
              override, shared by both stitchers
  register    ECC, phase correlation, SIFT matching, overlap agreement
  canvas      growable Canvas, layout, parallel render, normalize/compose
  posegraph   robust Gauss-Newton, largest connected component
  loops       keyframes and loop-closure candidates
  pagegraph   PageGraph, now orchestration only
  incremental Stitcher, on the shared Canvas

The stitchers take a Corrector and an odometry object (anything with
predict()) instead of building them, so another device can supply its
own motion prior. live.py drops its own canvas and normalisation for the
shared ones; PageGraph's mosaic check uses the parallel renderer.

Output on scan_text is unchanged (global stitcher identical, incremental
within 1 grey level). stitch.py --live now applies lens correction too
(--no-undistort restores the old output).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 07:55:22 +00:00

myscan

Linux driver tools for the Hama myScan (00052343) scanner mouse, a Dacuda design (USB 274f:c001: UVC MJPEG camera + HID mouse).

  • myscan/xu.py — UVC extension-unit access: switch between mouse and scan mode, LEDs, exposure
  • myscan/frame.py — fix the lying JPEG header and decode the per-frame sensor record (laser dx/dy)
  • myscan/calib.py — per-device calibration from the mouse's EEPROM: colour gains, flat field, lens undistortion
  • myscan/stitching/ — page stitching, independent of the scanner hardware (no device imports), so it can be used elsewhere: from myscan.stitching import Corrector, PageGraph. Its modules, lowest level first: geometry (rigid transforms, poses), filters (grayscale, high-pass, feather weights), correct (Corrector: lens undistortion + flat field), odometry (LaserOdometry, the myScan's laser motion prior; another device can pass its own object with predict()), register (ECC, phase correlation, SIFT matching, overlap check), canvas (weighted canvases, page composition, parallel rendering), posegraph (robust pose-graph optimisation), loops (loop-closure candidates), and the two stitchers built from them: pagegraph (PageGraph: assembles the page from all frames at once with loop closures between passes; used by scan.py and stitch.py) and incremental (Stitcher: frame by frame, stitch.py --live)
  • tools/scan.py — scan with the button: python tools/scan.py (press to start, press again to stop). --view [PORT] serves a live view at http://<host>:8000/: the camera, the page as it is stitched (re-solved every 1.5 s, current position outlined), Start/Stop buttons, PNG/JPEG download of the finished page and a Screenshot button (camera + page + status as one PNG)
  • myscan/live.py, myscan/webview.py — the live preview and its browser viewer (standard library only)
  • tools/record.py — record a scan session: python tools/record.py -d 25 -o scan_text
  • tools/stitch.py — stitch a recording: python tools/stitch.py scan_text -> scan_text/page.png
  • tools/probe.py — log raw frames and HID reports side by side
  • tools/scantest.py — minimal scan-mode test: grab frames, decode records, restore mouse mode

See FINDINGS.md for the protocol and calibration notes, and EEPROM.md for the calibration blob.

Setup: python -m venv .venv && .venv/bin/pip install -r requirements.txt

Calibration cache: calib/eeprom_3000.bin in this repo is the EEPROM dump of one specific mouse. myscan/calib.py uses that file whenever it exists and only reads the mouse when it is missing. With a different mouse, delete it first (rm calib/eeprom_3000.bin), so the next scan reads and caches your own unit's calibration (about 15 s).

S
Description
Vibecoded driver and picture stitched for the Dacuda Scanner Mose (HAMA myScan)
Readme
1 MiB
Languages
Python 100%