Ultimate guide to Python Tesseract
Table of contents
Tesseract with the pytesseract Python wrapper extracts text from images and scanned documents. This guide covers installation, image preprocessing (grayscale, thresholding, deskewing), multilingual OCR, advanced configuration, and performance tips. For searchable PDFs without manual preprocessing, see the Nutrient OCR API.
Nutrient OCR API creates searchable PDFs from scanned images — no preprocessing required. 50 free credits/month.
Tesseract OCR(opens in a new tab) is the most widely used open source optical character recognition (OCR) engine. Its Python wrapper, pytesseract, lets developers extract text from images with a few lines of code.
What is Tesseract?
Tesseract is an open source OCR engine that extracts text from images, scanned documents, and PDFs. It’s originally developed by Hewlett-Packard (HP) and maintained by Google since 2006, and it recognizes more than 100 languages. It extracts text from scanned documents, images, and PDFs. With pytesseract, you can integrate Tesseract into Python projects to automate data extraction.
What is pytesseract?
pytesseract is a Python wrapper for the Tesseract OCR engine. It provides a Pythonic interface to Tesseract without requiring direct interaction with the C++ engine. For a hands-on tutorial with code examples, see our pytesseract tutorial.
| Feature | Tesseract | pytesseract |
|---|---|---|
| Language | C++ | Python wrapper |
| Usage | Command-line tool or C++ API | Python import pytesseract |
| Installation | System package (brew, apt, installer) | pip install pytesseract |
| Requires | Standalone installation | Tesseract must be installed separately |
| Output formats | Text, hOCR, TSV, PDF | String, dict, DataFrame, bytes |
| Best for | Direct CLI usage, C++ integration | Python scripts, automation, data pipelines |
Prerequisites
Make sure you have the following installed:
- Installation of Python environment — Install Python on your system. You can download it from the official Python website(opens in a new tab).
- Pip package manager — If you don’t have pip installed, follow these steps:
- Windows — Pip comes bundled with Python. If it’s missing, download
get-pip.py(opens in a new tab) and run:
- Windows — Pip comes bundled with Python. If it’s missing, download
python get-pip.py- macOS/Linux — Open a terminal and run:
sudo apt install python3-pip # For Debian-based Linuxsudo dnf install python3-pip # For Fedora-based Linuxbrew install python # For macOS (via Homebrew)- OpenCV library — This is required for image preprocessing tasks such as grayscale conversion, thresholding, and noise removal. Install it using:
pip install opencv-python- NumPy library — Used for handling numerical operations on image data. Install it using:
pip install numpy- Pillow — This is a fork of the Python Imaging Library (PIL), which you’ll need to open image files:
pip install PillowSetting up Tesseract with Python
The setup process covers installing the Tesseract engine and the pytesseract Python wrapper.
Installation
Install both the Tesseract OCR engine and the pytesseract(opens in a new tab) library.
Installing Tesseract
- Windows — Download the Windows installer from Tesseract’s official repository(opens in a new tab) and follow the installation instructions provided.
- macOS — Install Tesseract using Homebrew, a package manager for macOS, by executing the following command:
brew install tesseract- Linux — Most Linux distributions include Tesseract in their package repositories, so you can install it using APT with the following command:
sudo apt install tesseract-ocr- For Fedora-based distributions, use:
sudo dnf install tesseractAfter installation, make sure Tesseract is available in your system’s PATH, or provide the direct path in your code.
Installing pytesseract
Once Tesseract is installed on your system, install the pytesseract(opens in a new tab) library using Python’s package manager, pip:
pip install pytesseractVerifying installation
To ensure Tesseract has been installed correctly, open a terminal or command prompt and run the following command:
tesseract --versionIf the installation was successful, the terminal will display the version number of Tesseract, along with other relevant details.
How to use Tesseract with Python
To use Tesseract with Python, install pytesseract, open an image with Pillow, and call pytesseract.image_to_string() to return the recognized text as a string. The example below demonstrates this with a sample image containing printed text.

Use this code to get started with OCR using Tesseract and Python:
from PIL import Imageimport pytesseract
# Open an image file.image = Image.open('example.png')
# Use pytesseract to do OCR on the image.text = pytesseract.image_to_string(image)
# Print the extracted text.print(text)In this example:
- Open an image file using Pillow.
- Pass the image to
pytesseract.image_to_string()to extract the text.

Understanding OpenCV (cv2)
Image preprocessing in this guide uses OpenCV(opens in a new tab), an open source computer vision library for Python. The cv2 module provides functions to manipulate and enhance images before passing them to Tesseract.
Key features of OpenCV (cv2)
- Reading and writing images — OpenCV enables loading, displaying, and saving images using functions like
cv2.imread()andcv2.imwrite(). - Image preprocessing — It provides various image enhancement techniques, such as grayscale conversion, thresholding, noise removal, and edge detection.
- Geometric transformations — Functions like rotation, resizing, and deskewing help in improving OCR accuracy.
- Object and text detection — OpenCV supports contour detection, which is useful for extracting regions of interest in images containing text.
Image preprocessing for better OCR accuracy
Tesseract accuracy depends on input image quality. Preprocessing the image before OCR reduces character misreads. For a complete walkthrough of preprocessing pipelines, see our guide on building a document scanner with OCR in Python.
Grayscale conversion
Converting an image to grayscale reduces the complexity of the image by eliminating unnecessary color information, making it easier for Tesseract to focus on text detection:
import cv2image = cv2.imread('image.png')gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)cv2.imwrite('gray_image.png', gray)| Original image | Grayscale image |
|---|---|
![]() | ![]() |
Thresholding
Thresholding(opens in a new tab) is a technique that helps separate text from a background by converting an image into a binary format where pixels are either black or white:
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]cv2.imwrite('thresholded_image.png', thresh)The code above applies Otsu’s thresholding(opens in a new tab) to a grayscale image, converting it into a binary image where pixels are either black or white. The thresholded result is then saved as thresholded_image.png.
| Original image | Thresholded image |
|---|---|
![]() | ![]() |
Noise removal
Noise, such as small speckles or distortions, can interfere with OCR. The following code, broken down into steps, applies image processing techniques to remove noise and improve text clarity.
Step 1
Load and convert to grayscale:
import cv2import numpy as np
image = cv2.imread('fax.jpg')gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)cv2.imwrite('gray_image.png', gray)- Loads the image and converts it to grayscale for simpler processing.
Step 2
Apply a bilateral filter:
denoised = cv2.bilateralFilter(gray, 9, 75, 75)- Reduces noise while preserving edges using a bilateral filter.
Step 3
Sharpen the image:
kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]])sharpened = cv2.filter2D(denoised, -1, kernel)- Sharpens the image by enhancing edges with a kernel filter.
Step 4
Save the processed image:
cv2.imwrite('denoised_image.png', sharpened)- Saves the final sharpened and denoised image.
Why does this matter for OCR?
- Reduces noise, making text more readable.
- Preserves important details while removing unwanted distortions.
- Improves OCR accuracy, as clearer text leads to better recognition.
| Original image | Denoised image |
|---|---|
![]() | ![]() |
Deskewing for better OCR accuracy
After applying thresholding, some scanned documents may have tilted text, affecting OCR accuracy. Deskewing corrects this misalignment, ensuring Tesseract processes the text properly:
coords = np.column_stack(np.where(thresh > 0)) # Find non-zero pixel coordinates.angle = cv2.minAreaRect(coords)[-1] # Calculate the skew angle
# Adjust the angle for the correct rotation.if angle < -45: angle = -(90 + angle)else: angle = -angle
# Rotate the image to correct the skew.(h, w) = thresh.shape[:2]center = (w // 2, h // 2)M = cv2.getRotationMatrix2D(center, angle, 1.0)deskewed = cv2.warpAffine(thresh, M, (w, h), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_REPLICATE)
cv2.imwrite('deskewed_image.png', deskewed)By detecting the text angle and rotating the image, this method straightens skewed text, improving OCR results.
| Original image | Deskewed image |
|---|---|
![]() | ![]() |
Multilingual text recognition
Tesseract supports more than 100 languages, which lets you extract text in different scripts and dialects. To enable multilingual OCR, the required language data files must be correctly installed and configured.
Language data files
Tesseract provides language data files that can be downloaded from Tesseract’s language repository(opens in a new tab) and placed in the tessdata directory of the Tesseract installation.
Configuring language in pytesseract
To instruct Tesseract to recognize multiple languages in an image, specify the desired languages in the lang parameter of pytesseract.image_to_string():
import pytesseracttext = pytesseract.image_to_string(image, lang='eng+fra')print(text)Advanced configuration options
These options let you control how Tesseract analyzes page layout, which recognition engine it uses, and which characters it considers during extraction.
PSM
Tesseract offers various page segmentation modes (PSM)(opens in a new tab) that determine how text is segmented within an image. For example:
text = pytesseract.image_to_string(image, config='--psm 6')Common PSM modes include:
- 3 — Fully automatic page segmentation.
- 6 — Assumes a single uniform block of text.
- 11 — Sparse text with no predefined order.
OEM
Tesseract supports multiple OCR engine modes (OEM), which define the underlying text recognition approach:
text = pytesseract.image_to_string(image, config='--oem 1')Common OEM modes include:
- 0 — Uses the legacy OCR engine only.
- 1 — Uses the long short-term memory (LSTM)-based OCR engine.
- 3 — Uses a combination of the legacy and LSTM engines.
Allowed and disallowed characters
To improve accuracy, Tesseract allows restricting recognition to specific characters:
custom_config = r'--psm 6 -c tessedit_char_whitelist=ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'text = pytesseract.image_to_string(image, config=custom_config)Extracting text from PDF
Tesseract can extract text from PDFs by converting them to images. Ensure you have Poppler(opens in a new tab) installed first. For alternative Python approaches to PDF text extraction, see our dedicated guides.
Installing Poppler
First, install Poppler:
- macOS —
brew install poppler - Ubuntu —
sudo apt-get install poppler-utils - Windows — Download Poppler(opens in a new tab) and add it to your
PATH.
Then, use this code:
import pytesseractfrom pdf2image import convert_from_path
# Convert PDF to images.images = convert_from_path('example.pdf')
# Extract text from the first page.text = pytesseract.image_to_string(images[0])
print(text)You’ll need to install pdf2image using:
pip install pdf2imageFor extracting text from PDFs without OCR (when text is already selectable), see how to extract text from a PDF using PyMuPDF.
Tesseract vs. commercial OCR solutions
Choosing between Tesseract and a commercial OCR solution depends on your use case, volume, and accuracy requirements.
| Feature | Tesseract (open source) | Nutrient OCR API (commercial) |
|---|---|---|
| Cost | Free (Apache 2.0) | 50 free credits/month, then paid |
| Installation | Local engine required | Cloud API — no installation |
| Preprocessing | Manual (grayscale, threshold, deskew) | Automatic — built-in preprocessing |
| Output format | Plain text, hOCR, TSV | Searchable PDF with embedded text layer |
| Languages | 100+ (install language packs) | 80+ languages built in |
| Batch processing | Build your own pipeline | Single API call for multiple pages |
| PDF support | Requires pdf2image conversion | Native PDF input and output |
| Layout preservation | Limited | Retains tables, columns, and formatting |
| Accuracy | Good with proper preprocessing | Consistent without manual tuning |
| Best for | Prototyping, local processing, customization | Production workflows, searchable PDFs |
For production OCR that outputs searchable PDFs, see the Nutrient OCR API. You can also OCR PDFs directly using the API in JavaScript, Python, PHP, or Java.
Performance optimization tips
When processing large batches of images or working with high-resolution scans, performance becomes critical. These tips help you get the most out of Tesseract.
- Use
tessdata_fastmodels — The tessdata_fast(opens in a new tab) models are smaller and faster than default models with minimal accuracy loss. Swap yourtessdatadirectory to use the fast variants for production workloads. - Resize images appropriately — Tesseract works best with text at 300 dots per inch (DPI). Images that are too large waste processing time; images that are too small reduce accuracy. Resize to an optimal range before OCR.
- Limit the recognition region — If you only need text from a specific area, crop the image before passing it to Tesseract. This reduces processing time significantly.
- Use the right PSM mode — Choosing the correct page segmentation mode avoids unnecessary layout analysis. For single text blocks,
--psm 6is faster than the default--psm 3. - Process pages in parallel — For multipage documents, use Python’s
concurrent.futuresto OCR pages in parallel:
from concurrent.futures import ThreadPoolExecutorimport pytesseractfrom pdf2image import convert_from_path
images = convert_from_path('document.pdf')
def ocr_page(image): return pytesseract.image_to_string(image)
with ThreadPoolExecutor(max_workers=4) as executor: results = list(executor.map(ocr_page, images))
full_text = '\n'.join(results)- Cache preprocessed images — If you’re iterating on OCR settings, save preprocessed images to disk so you don’t repeat expensive preprocessing steps.
For high-volume document processing, consider automated OCR workflows or the Nutrient OCR API, which handles preprocessing and optimization automatically.
Common errors and troubleshooting
Most issues fall into four categories: the Tesseract engine can’t be found, output is empty or incorrect, the Python library won’t import, or processing is too slow.
TesseractNotFoundError
This means Python cannot locate the Tesseract executable. Fix it by setting the path explicitly:
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe' # Windows# pytesseract.pytesseract.tesseract_cmd = '/usr/local/bin/tesseract' # macOS/LinuxEmpty or garbled output
If Tesseract returns empty strings or incorrect characters, check these common causes:
- Image quality — Apply grayscale conversion, thresholding, and noise removal before OCR.
- Wrong PSM mode — Try
--psm 6for blocks of text,--psm 7for single lines. - Wrong language — Specify the correct language with
lang='eng'or install additional language packs. - Low resolution — Upscale images to at least 300 DPI for reliable recognition.
Import errors
If import pytesseract fails, ensure the library is installed in the correct Python environment. See the troubleshooting guide in our pytesseract tutorial for detailed solutions.
Slow processing
If OCR is taking too long, reduce image resolution, use tessdata_fast models, limit the recognition region, or switch to parallel processing as described in the performance optimization section above.
Common OCR challenges
The most frequent sources of reduced accuracy are poor image quality, unusual fonts, and non-standard characters.
Low-quality images
For blurry or noisy images, apply preprocessing before OCR:
- Denoising —
cv2.fastNlMeansDenoising() - Binarization —
cv2.threshold()
Text in uncommon fonts
Tesseract may struggle with decorative or distorted fonts. Try training Tesseract on custom font data, or apply additional image processing to increase contrast and clarity.
Non-standard characters
If Tesseract misrecognizes special characters or symbols, verify that you have the correct language data installed and try adjusting the OEM or PSM settings.
Nutrient OCR solutions and features
Nutrient offers OCR across multiple platforms, extracting text from scanned PDFs and images to make documents searchable and editable.
Nutrient products supporting OCR
- Nutrient OCR API — Cloud-based OCR with searchable PDF output. No local engine required.
- Web SDK — OCR via Document Engine in server-backed mode.
- iOS SDK and Android SDK — On-device text recognition for mobile apps.
- .NET SDK — OCR for Windows applications.
- Java SDK — OCR for Java applications. See how to OCR images and PDFs using Java.
- Document Converter — OCR for SharePoint and server-based conversions (from version 7.1).
Nutrient also supports OCR on Mac Catalyst, React Native, and Flutter.
Key differentiators
- Searchable PDFs — Converts scanned documents into searchable, selectable text with the original layout preserved.
- Built-in preprocessing — No manual grayscale/threshold/deskew steps required.
- Batch processing — Single API call for multipage documents. See our guide on automated PDF OCR workflows.
OCR may require an additional license component. For more details, visit Nutrient OCR solutions or contact Sales.
Conclusion
Tesseract with Python is a free, customizable option for text recognition — from digitizing medical records to automating data entry. Image preprocessing and the right PSM/OEM settings make the biggest difference in accuracy. For production OCR that outputs searchable PDFs without manual preprocessing, see the Nutrient OCR API or contact Sales.
Related Python guides
- pytesseract tutorial: Extract text from images
- Watermark PDFs with Python
- Generate PDF invoices with Python
- Convert HTML to PDF with Python
- Extract text from PDF with Python
- Extract text from PDF using PyMuPDF
- Top 10 Python PDF generator libraries
OCR and document processing
- Build a document scanner with OCR in Python
- OCR images and PDFs in Java
- OCR images and PDFs in C#
- Automated OCR workflows from images
- Automated PDF OCR workflows
- Barcode OCR
- Document searchability best practices
- AI-powered redaction
- Medical records digitization with OCR
FAQ
Tesseract OCR reads image pixels and applies recognition algorithms to identify characters. The pytesseract Python wrapper calls the Tesseract engine and returns the extracted text as a string, making it easy to integrate OCR into Python scripts.
pytesseract is a Python wrapper library for the Tesseract OCR engine. It provides a simple interface — pytesseract.image_to_string(image) — that lets you extract text from images directly in Python without interacting with the C++ engine. You need both Tesseract (the engine) and pytesseract (the Python wrapper) installed.
Start with high-quality images and apply preprocessing: grayscale conversion, thresholding, and noise removal. Then tune the page segmentation mode (PSM) and OCR engine mode (OEM) to match your document layout. These two steps account for most accuracy gains.
pytesseract doesn’t support PDFs directly. Convert PDF pages to images first using the pdf2image library: images = convert_from_path('file.pdf'). Then run pytesseract.image_to_string() on each image. You also need Poppler installed on your system. For native PDF OCR without this extra step, use the Nutrient OCR API.
TesseractNotFoundError?This error means Python cannot find the Tesseract executable. Either add Tesseract to your system PATH, or set the path explicitly: pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe' on Windows, or pytesseract.pytesseract.tesseract_cmd = '/usr/local/bin/tesseract' on macOS/Linux.
Nutrient adds batch processing, built-in preprocessing, and multiplatform support on top of what Tesseract offers. The API produces searchable PDFs directly, which removes the need to build your own post-processing pipeline.
Nutrient Web SDK handles OCR through Document Engine in server-backed mode. It extracts text from documents and images delivered via the browser and returns searchable PDF output.
The Nutrient OCR API accepts PDF or image input via a REST call and returns a searchable PDF with an embedded text layer. It handles preprocessing automatically, so you don’t need to manage grayscale conversion, thresholding, or deskewing yourself.
Tesseract has limited support for handwriting recognition out of the box. While it can recognize clearly printed handwriting, it struggles with cursive or informal handwriting. For better results with handwritten text, consider training Tesseract on a custom dataset of handwriting samples, or use a commercial OCR solution with built-in handwriting support.
pytesseract supports all image formats that Pillow (PIL) can open, including PNG, JPEG, TIFF, BMP, GIF, and WebP. For best OCR results, use lossless formats like PNG or TIFF. JPEG compression artifacts can reduce accuracy, especially with small or low-contrast text.






