You Really Can Scan a Book Quickly With High-Res Video and No Special Hardware

Yes, you can scan an old, bound book by simply shooting a high-resolution video of yourself turning its pages, then doing some post-processing with OCR and AI to digitize it: one Markdown text file of all the content, with the photographs captured, deskewed and linked. It doesn’t require any special hardware.

I do have the source code, written with Claude Code, that does all of this. You could probably make the same project by giving this article as a prompt. I’m not trying to add to the half-baked code repos we’re all seeing on Hacker News and other sites.

I didn’t expect this to actually work. It doesn’t need a big specialized book scanner; it uses the iPhone in my pocket. It seems like the minimum time I need to spend with an old book in my possession to digitize it, without making it a 40-hour project or cutting the binding.

Using video to scan and OCR a book does have issues:

  • Set the resolution to 4K and make sure you have good lighting.
  • You don’t get immediate feedback if you blocked a page with your hand or had some other problem.
  • You are not guaranteed a flat scanning surface, so page skew and page curl must be dealt with.
  • Several stills can be taken of each page, then compared and processed when problems are found.
  • An AI model can combine the stills of the same page and find a consensus.

It took about 30 minutes to scan a 400-page book, pausing for a second or so between pages. The pause is also the trigger for the processing to take a still of the page for OCR. Processing took a couple of hours on a desktop: local OCR first, then Claude merging the reads of each page.

For the rest of this, I’ll have Claude add the technical details.


The process, in four stages

It is a small Python command-line tool. Give it one or more video clips and it writes a folder for the run: the stills it pulled, the OCR of each, the cut-out figures, and book.md at the end. Each stage caches its work, so a crash or a change to one stage only reruns that stage.

A 4K video frame looking down at a bound typescript on a desk, one hand turning a page
One still from the video. The phone is on a stand pointing down at the book. A page gets turned about every second and a half.

1. Finding the held moments

The video is read once. Each frame is shrunk to 480 pixels wide and converted to grey before Python sees it, because decoding 4K in OpenCV is slow. Two numbers are kept per frame: motion (mean difference from the previous frame) and sharpness (variance of the Laplacian). A run of low-motion frames means a page is being held still. The three sharpest frames of each run are saved as full-resolution stills.

Line chart of per-frame motion over one minute of video, with low-motion runs shaded
One minute of a clip. Each spike is a page turn. Each shaded band is a page held still, and becomes a few stills.

So the pause between pages is the trigger. There is no button. Hold the page for a second and it gets captured. Flick past it and it doesn’t.

Each clip can be rotated differently, depending on how the phone was held for that take. The tool OCRs a sharp frame all four ways round and keeps whichever reads best.

2. Local OCR

Each still goes through RapidOCR (the PP-OCR models on onnxruntime, CPU only). The lines come back with boxes and a confidence score. Then they have to be put in reading order. The gutter is found as the dark shadow between the pages, the lines on each page are clustered into columns by their left edge, and paragraph breaks come from vertical gaps.

Resolution matters more than anything else here. At 1080p the body type is about 8 pixels high and the OCR misreads a lot of it. At 4K it is about 16 pixels and mean line confidence went from 0.94 to 0.98. On the first test book that was the difference between 17 illegible words per thousand and about one. iPhones record 1080p unless you change it under Settings > Camera > Record Video.

3. Cutting out the figures

A photograph on a page is a large block that is dark or halftone-textured where paper would be blank. The OCR line boxes are blanked out first so a column of text can’t be mistaken for one. The four corners come from the convex hull, the figure is deskewed with a perspective warp, saved as its own JPEG and linked from the transcript ahead of its caption. A second pass looks for line drawings and maps, which are mostly white, by keeping long straight dark strokes and the closed rectangles they form.

An old black and white photograph of a steam locomotive in front of a small station building, cut from a page and squared up
A photograph cut from a page of a different test book and deskewed. Some cuts are a lot worse than this: glare and page curl produce rotated, washed-out blobs.

This is the most fragile stage. On a typescript with no pictures at all it found 31 “figures”, all wrong: typed text blocks, bleed-through from a thin sheet, and in one case a shoe. There is a flag to skip it.

4. Merging the reads with Claude

The same page is usually held still more than once, and each still has its own problems: blur, a hand, curl near the binding, a reflection. Consecutive stills are grouped into one page when their OCR text matches. A looser check, based on shared three-word runs, lets a hand-covered read of a page join the clean read of that page.

Three photographs of the same typed page from three held moments, a hand intruding at the bottom of two of them
What the model sees for one page: the best still from each held moment. The hand at the bottom of two of them is clear in the third.

For each page, Claude gets the best still from each held moment (left and right page crops), the raw OCR text of each, and a system prompt: transcribe every word, use the other photos where one is unclear, join hyphenated line breaks, write [illegible] for a word unreadable in every photo, and never invent text. The output is the page as Markdown.

The call goes through the claude command-line tool in headless mode, with only the Read tool allowed so the model can open the image files. That means it runs on the Claude subscription rather than a metered API key. Two models split the work. Sonnet handles a page whose OCR reads agree with each other. Opus gets a page whose reads disagree, which is where the photos are poor and there is actual work to do. About a third of the pages of the test book went to Opus. A page takes around 30 seconds either way.

Knowing what you missed

What you give up with video is feedback. With a flatbed you see each page as it comes. Here you find out two hours later. So the tool reads the printed page numbers back out of the transcription and prints a report: pages with illegible words, numbers that never turned up, numbers that turned up twice. A missing page gets a *[page 357 not captured]* marker in the body text where it belongs.

A missing page was usually held, just not quite still enough. So a rescue pass goes back to the video for whatever the first pass got wrong. For a missing page it searches the frames between the pages on either side with the motion limit loosened. For a page with illegible words it pulls up to six more frames from the time that page was on screen and merges the page again with more photos. Each round only costs the problem pages.

Whatever is still wrong after that was not in the footage. For those, a short second video of just the problem pages, or a handful of photos, goes through the same pipeline and the pages are merged into place by number. For the last few dozen illegible words the tool listed each one with the sentence around it, to be filled in by hand against the book.

How the 400-page book went

Videofour clips, 34 minutes in total, mostly 4K at 24 fps
Stills pulledabout 3,200
Pages in the transcript414
Wordsabout 139,000
Illegible words after the first pass232, about 1.7 per thousand
After the rescue pass, a short re-shoot and eight photosa few dozen, answered by hand
Figuresnone; it was a typescript, so the figures stage was skipped

Frame analysis and OCR took under an hour for all four clips on a 16-core desktop. The Claude merge is the slow part, at half a minute a page.

Advice for trying it

  • Shoot 4K. It is the biggest improvement available and it costs nothing.
  • Light from beside or behind the camera. The illegible words on the first test book were almost all on a page that curled toward a window and reflected it. Nothing downstream can recover a reflection.
  • Hold each page a full second, or rest the phone on something. The held moments are what the tool keys on.
  • Hold the page by its margin. A hand over the text in every still of a page is gone for good. A hand in one of three is fine.
  • Film in clips of fifty pages or so. A mistake then costs one clip. The clips are given to the tool in order as one book.
  • Keep the video. It is the source. The processing can be redone anywhere, with a better OCR model or a better prompt, long after the book has gone back on the shelf.