How to extract text from scanned PDF with OCR in Python
Learn how to automate text extraction from scanned PDF documents using open-source OCR libraries and Python locally on your computer.
Summary
- Local OCR pipelines ensure complete data privacy by keeping sensitive documents off third-party cloud servers.
- Combining PyMuPDF with Tesseract OCR accurately converts image-based PDF documents into machine-readable text.
- Image preprocessing techniques like thresholding and deskewing drastically improve character recognition accuracy.
- Batch automation allows processing entire folders of scanned contracts and invoices in just a few seconds.
- Proper exception handling and text noise cleanup prevent common errors when structuring extracted data.
The challenge of extracting data from scanned files
When we receive a document that has been digitized by a scanner or photographed with a smartphone, the resulting PDF file is usually just a large image wrapped in a digital format. To the computer, those visible words on the screen are nothing more than colored pixels, making it impossible to select, copy, or search for specific terms without specialized help. This is precisely where OCR (Optical Character Recognition) comes in, a technology capable of analyzing visual shapes in images and converting them into machine-readable text.
In many corporate or academic scenarios, we need to process piles of these digital documents without relying on paid cloud services that charge per page or expose confidential client data. The Python language offers a robust and free ecosystem to solve this demand end-to-end on your own machine. If you have ever needed to extract old reports or looked into file conversion, you might be familiar with terminal tools such as those we detail in our guide on how to convert scanned PDF to text with OCR on Linux, but doing it via Python code opens up a massive array of customized automations.
Setting up the environment and installing required dependencies
Before writing any Python code, we need to prepare the ground by installing the system's core OCR engine and the libraries that will bridge the gap between the PDF and the recognition engine. The most famous and reliable engine in the open-source world is Tesseract, maintained by Google. Alongside it, we will use the PyMuPDF library (known as the fitz package) to convert PDF pages into high-resolution images and the pytesseract library to invoke the OCR engine directly from our script.
To get your hands dirty locally in a practical way, follow the sequence below:
- Install the Tesseract engine on your operating system (on Ubuntu or Debian, run
sudo apt install tesseract-ocr tesseract-ocr-engto ensure English support). - Create an isolated Python virtual environment for your project using
python3 -m venv venvand activate it. - Install the required Python libraries by running
pip install pymupdf pytesseract pillowin your terminal.
Converting PDF pages into high-resolution images
The first practical step in Python code consists of opening the PDF file and turning each of its pages into a digital image that the OCR engine can read clearly. Doing this requires special attention to resolution, because images that are too small or blurry cause Tesseract to confuse similar letters, such as an uppercase 'l' with the number '1' or the letter 'O' with zero.
In the code snippet below, we open the PDF, loop through each page automatically, and generate a visual representation that will be sent for character recognition right after. Here is how to implement this routine cleanly:
import fitz # PyMuPDF import pytesseract from PIL import Image import io def pdf_to_images(pdf_path): document = fitz.open(pdf_path) images = [] for page_num in range(len(document)): page = document.load_page(page_num) # Render page with 2x zoom to improve OCR clarity zoom = 2.0 mat = fitz.Matrix(zoom, zoom) pix = page.get_pixmap(matrix=mat) img_bytes = pix.tobytes("png") image = Image.open(io.BytesIO(img_bytes)) images.append(image) return imagesApplying OCR and extracting text with Python
With the page images properly generated in the program's memory, we can invoke Tesseract to scan each of them and return the recognized text as a string. To ensure the engine knows exactly which language to look for, we specify the language parameter, which drastically reduces interpretation errors in common words.
If you want to dive deeper into recognizing isolated snippets or smaller screens, it is worth checking out the practical guide on how to extract text from images in the terminal with Tesseract OCR to understand advanced engine configuration options.
def extract_text_from_images(images): full_text = "" for index, image in enumerate(images): print(f"Processing page {index + 1}...") # Calls Tesseract passing the image and language ('eng') page_text = pytesseract.image_to_string(image, lang='eng') full_text += f"--- Page {index + 1} ---
" + page_text + "
" return full_text # Example usage of the complete function path = "scanned_document.pdf" my_images = pdf_to_images(path) ocr_result = extract_text_from_images(my_images) print(ocr_result[:500])Handling noise and improving reading accuracy
Scanned documents do not always reach us with perfect lighting or without smudges. Old documents, crumpled invoices, or poor photocopies contain visual noise that confuses the OCR algorithm, resulting in truncated terms or corrupted characters. To work around this problem in practice, we can apply basic image processing techniques before sending the page to Tesseract.
Converting the image to grayscale and applying a threshold (binarization) eliminates background shadows and highlights black text against white paper. Libraries like Pillow or OpenCV help clean up imperfections quickly, ensuring your automation pipeline does not break when receiving lower-quality files sent by business partners. To explore these architectural concepts further in production, see our related technical analysis on How to test optocouplers on board with a multimeter.
Final considerations on document automation at scale
Automating text extraction from scanned PDFs using Python and open-source tools puts full control of your data in your hands, with no recurring costs for cloud APIs. Although it requires minor adjustments in lighting and resolution depending on the original document's quality, combining PyMuPDF with Tesseract delivers a robust, fast, and highly customizable solution for any office routine or data engineering task.
Adopting this type of routine locally saves hours of manual typing and enables the creation of internal search engines across your company's historical document bases. With a well-structured script, you transform piles of dead paper into structured data ready for analysis.