Blog · PDF tips

Using AI OCR to extract text from scanned documents

Page 19 of a carbon-copy letter came back from AI OCR with the amount as 1860. The page said 1050. The 0 was faint and the 5 had a broken stroke. The model picked a plausible neighbor and kept writing. I only noticed because the amount was the point of the page. If it had been a middle initial I might have shipped it.

What is actually sent

OCR on this site is a vision request. The page image goes to the Worker, which tries a vision model and asks for the visible text in reading order, without inventing missing text. “Without inventing” is the instruction. It is not a physical law. You still proof numbers, negatives, and names. The image leaves the browser. Do not OCR a document you are not willing to transmit.

Printed text, upright, filling the frame, no thumb, no coffee stain across the line: I often get a draft I can fix in a few minutes per page. Handwriting: I expect to retype. A stamp over a word: I expect the word under the stamp to be wrong or gone. A page photographed at an angle: I reshoot or I accept errors in the corner that was farthest from the lens. The model does not unwarp the page as a geometry problem you can configure. There is no DPI setting in the button.

PageResultWhat I did
Typed letter, upright, good lightA few line-break hyphens, one missed commaFind-replace, then a read-aloud of the operative paragraph
Two-column journal pageColumns interleaved onceSplit the text by hand into two blocks
Carbon copy with a faint digitWrong amount, fluent sentence around itRetyped the line from the image. Marked the page “human figures only”
Rotated 90°Garbage and a description of the marginRotated, ran OCR again
Handwritten annotations in the marginHalf the notes, one inverted “not”Did not use the OCR for the notes at all

Order of work, because the reverse wastes the call

Rotate first. Crop out the table and the thumb if they are in the frame and you can do that without cutting text. Then OCR a few pages, not a 200-page book, unless you enjoy proofing a 200-page book in one sitting. I do chapters. I copy the text out. I correct. Then I might summarize or translate. Those tools read text. If I summarize before I correct, I am summarizing the 1860.

Reading order is “what the model thought was reading order.” Multi-column pages and captions beside figures come back in an order a human would not choose. I do not trust the sequence of two adjacent numbers until I see which column they came from. A caption glued to the previous paragraph is the classic. I insert a blank line when I see the figure number and I move the caption.

Hyphenation, same nuisance as text extraction: line-end hyphens become real hyphens. I search for them. I do not globally delete hyphens in a chemistry name or a double-barreled surname. The search is a list of suspects, not a macro I run blind.

A proofing pass that is shorter than re-reading the world

I do not re-read every function word on a clean typed page. I do re-read every number, every name, every “not” and “or,” and the first and last line of each page, which is where clipping happens. On a dirty page I re-read everything or I refuse to use the OCR. There is no credit for having run the tool.

I keep the image and the text together in the folder. If someone challenges a digit, the image is the exhibit and the text is my transcript. Sending only the transcript is how the 1860 becomes the record. I name them p19.jpg and p19-ocr.txt so the pair is obvious.

Batch size and failures: a huge image can fail or time out. Split the PDF and OCR the piece. If the status returns an error from the model, retry once. If it fails again, the page may be too large or the service is unhappy. Shrinking the image’s pixel dimensions in an editor, without cropping off text, has unstuck a scan that was a photograph of an entire broadsheet. Readability for the model is about the text size in the bitmap, not about your feelings toward resolution. A 4000-pixel-wide photo of a tiny receipt is a large file and a small string of text. Crop to the receipt.

I do not OCR to “make a searchable PDF” inside this button. The button returns text. Putting that text back into a PDF as an invisible layer is a different product. If all you needed was to copy one paragraph, you are done when the paragraph is correct in the text box. If you needed an archival searchable PDF, say so in the project and use a pipeline that writes text back onto the page. Do not tell a records manager that a .txt beside a scan is a searchable PDF. They will believe you, and the next system will not.

A page I split into two OCR jobs

The top half was a typed table. The bottom half was a handwritten log. One image, one request, and the log’s scrawl contaminated the table’s last row: a 4 became a symbol and the row shifted. I cropped the table, OCR’d that crop, and typed the log myself from the photo. Two artifacts, p7-table.txt and p7-log-manual.txt. The combined transcript I almost made would have looked efficient and been wrong at the seam. Seams are where reading order invents a relationship between a printed total and a handwritten note that was never a total.

Stamps in red across a signature line: I cover the stamp with a white rectangle in an editor only when I need the words under a light stamp and I keep the unedited image as the record. If the stamp is the legally interesting part, I do not cover it, and I do not trust the letters inside it. I describe the stamp in my own words — “round stamp, partly legible, date looks like March” — which is weaker and accurate. The OCR of that region had produced a full date with a day I could not see. I deleted the day.

Language mixes on one page need a slower read. The model may transliterate a name one way on line 2 and another way on line 40. I pick the spelling from the clearest instance and I replace the variants. I do not let both survive in a summary downstream. Two spellings become two people. I have introduced a ghost colleague that way, and the summary promoted them to “the site lead.” The site lead was a smudge.

Cost of a retry: if the first pass is badly ordered, a second pass on the same image often repeats the order. I change the image — crop, rotate, or raise contrast slightly — before I spend another call hoping for a different reading of the same pixels. Contrast that crushes a faint digit is the 1860 problem again. I duplicate the file, experiment on the duplicate, and I compare the digit to the untreated photo before I accept the cleaner-looking text.