36e714cd6269b93277c974beec48cbbfb884de28
PageGraph.add registers consecutive frames on half-resolution high-pass images (ECC without pre-blur, phase correlation on a half-size window) and builds the high-pass with the illumination blur done on a 4x smaller copy; full-resolution high-pass images are made on demand for keyframes only. The flat field is pre-warped into undistorted coordinates, so a frame is remapped as uint8 and corrected with one multiply. add() goes from ~13-20 to ~3-7 ms per frame with the same registration. image() draws the page on one thread per row strip of the canvas, with the flat-field gain and feather weight folded into one multiply. compose crops before normalising and takes the white point from a 1/16 subsample. _agree computes its moments with OpenCV, which releases the GIL; its decisions are unchanged on all 1425 checks of a 2525-frame scan. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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, exposuremyscan/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 undistortionmyscan/pagegraph.py— assemble a page from all frames at once: frame-to-frame registration, loop closures between passes, pose-graph optimisation (used byscan.pyandstitch.py)myscan/stitch.py— the older live, frame-by-frame stitcher (stitch.py --live) and shared helperstools/scan.py— scan with the button:python tools/scan.py(press to start, press again to stop).--view [PORT]serves a live view athttp://<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_texttools/stitch.py— stitch a recording:python tools/stitch.py scan_text->scan_text/page.pngtools/probe.py— log raw frames and HID reports side by sidetools/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).
Description
Vibecoded driver and picture stitched for the Dacuda Scanner Mose (HAMA myScan)
1 MiB
Languages
Python
100%