---
title: "Python OCR with pytesseract: Extract text from images using Tesseract (2026)"
canonical_url: "https://www.nutrient.io/blog/how-to-use-tesseract-ocr-in-python/"
md_url: "https://www.nutrient.io/blog/how-to-use-tesseract-ocr-in-python.md"
last_updated: "2026-07-14T11:39:19.086Z"
description: "Use pytesseract and Tesseract OCR to extract text from images in Python — full setup, image_to_string() examples, PSM modes, preprocessing, and accuracy fixes."
---

**TL;DR**

Install `pytesseract` and the Tesseract engine. Then call `pytesseract.image_to_string(image)` to extract text from an image. Preprocessing (grayscale, resizing, adaptive thresholding) and the right `--psm` mode are what take accuracy from mediocre to production grade. For scanned PDFs or batch processing, Nutrient OCR API skips most of that.

To use Tesseract OCR in Python, install the `pytesseract` wrapper library and Tesseract engine. Then call `pytesseract.image_to_string(image)` to extract text from any image. The function returns recognized text as a string — no cloud services or API keys are required for basic usage.

**Key capabilities of pytesseract**

- **Text extraction** — Extract text from JPG, PNG, TIFF, and other image formats

- **100+ languages** — Support for English, French, German, Chinese, Arabic, and more

- **Configurable** — Control page segmentation, language, and character allowlists

- **Free and open source** — Apache 2.0 license with active community support

- **Cross-platform** — Works on Windows, macOS, and Linux

Python developers use Tesseract OCR with the [pytesseract](https://pypi.org/project/pytesseract/) wrapper to extract text from images and scanned documents.

## What OCR does

OCR extracts text from images and scanned documents. Common uses include:

- Digitizing paper documents for search and archival

- [Automating data entry](https://www.nutrient.io/blog/how-to-create-automated-ocr-workflows-from-images/) from forms and invoices

- Making scanned PDFs searchable and copyable

- Indexing document content for retrieval

For a quick-start version of this guide with copy-paste code snippets, see our [pytesseract installation and usage guide](https://www.nutrient.io/blog/tesseract-python-guide.md).

## Tesseract OCR

[Tesseract OCR](https://github.com/tesseract-ocr/tesseract) is an open source OCR engine originally developed by Hewlett-Packard (1985–2006) and now maintained by Google. It uses neural networks and traditional image processing to recognize text. Tesseract ships trained models for [100+ languages](https://github.com/tesseract-ocr/tessdata) (101 at the 4.0 release, and more since), and it works with Python, Java, and C++ (Apache 2.0 license).

**Use Tesseract 5.x for best results.** Tesseract [4.0 introduced a long short-term memory (LSTM) neural network engine](https://tesseract-ocr.github.io/tessdoc/tess4/NeuralNetsInTesseract4.00.html) that significantly improved accuracy over the legacy character-pattern engine, and version 5.x builds on it. Check your version with `tesseract --version`.

### Pros and cons

**Pros**

- Free and open source

- 100+ languages supported

- Handles various fonts and text styles

- Active community, regular updates

**Cons**

- Setup can be tricky on some systems

- Accuracy drops with poor image quality or complex layouts

- No built-in preprocessing — you handle that separately

- Training required for non-standard fonts

## Prerequisites

You need:

1. Python 3.x

2. Tesseract OCR

3. [pytesseract](https://pypi.org/project/pytesseract/)

4. [Pillow (Python Imaging Library)](https://pillow.readthedocs.io/en/stable/)

pytesseract wraps the Tesseract OCR engine and provides a Python interface for text recognition. It also works as a standalone script for direct Tesseract interaction.

## Installing Tesseract OCR

Install Tesseract for your operating system:

- Windows — Download the installer from [the official GitHub repository](https://github.com/UB-Mannheim/tesseract/wiki) and run it.

- macOS — Use Homebrew by running `brew install tesseract`.

- Linux (Debian/Ubuntu) — Run `sudo apt install tesseract-ocr`.

For other operating systems, see the [installation guide](https://tesseract-ocr.github.io/tessdoc/Installation.html).

## Setting up your Python OCR environment

1. Create a file called `ocr.py`.

2. Download the [sample image](https://www.nutrient.io/images/blog/2023/how-to-use-tesseract-ocr-in-python/image.png) used in this tutorial and save it in the same directory as the Python file.

3. Install the required Python libraries using `pip`:

```bash

pip install pytesseract pillow

```

Verify the installation:

```bash

tesseract --version

```

If you encounter import issues, see [troubleshooting pytesseract imports](#why-pytesseract-fails-to-recognize-or-import-text).

## How to extract text from an image in Python with pytesseract

To extract text from an image, open it with Pillow and pass it to `pytesseract.image_to_string()`, which returns the recognized text as a string. The full process is three steps: Import the libraries, load the image, and call `image_to_string()`.

Import the libraries and load your image:

```python

import pytesseract
from PIL import Image

image_path = "path/to/your/image.jpg"
image = Image.open(image_path)

```

### Extracting text from the image

To extract text from the image, use the `image_to_string()` function from the pytesseract library:

```python

extracted_text = pytesseract.image_to_string(image)
print(extracted_text)

```

The `image_to_string()` function takes an image as an input and returns the recognized text as a string.

Run the Python script to see the extracted text from the sample image:

```bash

python3 ocr.py

```

The image below shows the output.![Terminal output showing the text pytesseract extracted from the sample image](@/assets/images/blog/2023/how-to-use-tesseract-ocr-in-python/terminal.png)

### Saving extracted text to a file

If you want to save the extracted text to a file, use Python’s built-in file I/O functions:

```python

with open("output.txt", "w") as output_file:
    output_file.write(extracted_text)

```

## Advanced Python OCR techniques

pytesseract supports several configuration options for the OCR engine.

### Configuring the OCR engine

Pass a configuration string to `image_to_string()` with space-separated key-value pairs. This example sets English as the language and treats the image as a single text block:

```python

config = '--psm 6 -l eng'
text = pytesseract.image_to_string(image, config=config)

```

### PSM reference

The `--psm` (page segmentation mode) option controls how Tesseract analyzes page layout. Choose the mode that matches your document structure:

| PSM | Mode                                  | Best for                               |
| --- | ------------------------------------- | -------------------------------------- |
| 0   | Orientation and script detection only | Detecting page rotation                |
| 1   | Automatic with OSD                    | General documents with mixed content   |
| 3   | Fully automatic (default)             | Standard documents                     |
| 4   | Single column of variable sizes       | Articles, single-column pages          |
| 6   | Single uniform block of text          | Paragraphs, text blocks                |
| 7   | Single text line                      | One-line captions, headers             |
| 8   | Single word                           | Individual words, labels               |
| 9   | Single word in a circle               | Circular text like stamps              |
| 10  | Single character                      | Individual digits or letters           |
| 11  | Sparse text                           | Text scattered across image            |
| 12  | Sparse text with OSD                  | Scattered text with rotation           |
| 13  | Raw line                              | Treat as single line, no preprocessing |

For non-standard installation paths, set the Tesseract executable location:

```python

pytesseract.pytesseract.tesseract_cmd = '/path/to/tesseract'

```

### Handling multiple languages

Tesseract supports 100+ languages. Use a plus sign to combine languages:

```python

config = '-l eng+fra'
text = pytesseract.image_to_string(image, config=config)

```

## How to improve Tesseract OCR accuracy

Improve Tesseract OCR accuracy by preprocessing the image before recognition — convert it to grayscale, upscale it, and apply thresholding — and by setting the `--psm` mode that matches the document layout. Clean, high-contrast input is the single biggest factor in recognition quality.

### Converting images to grayscale

Converting to grayscale improves contrast between text and the background:

```python

from PIL import Image, ImageOps

# Open an image.

image = Image.open("path_to_your_image.jpg")

# Convert image to grayscale.

gray_image = ImageOps.grayscale(image)

# Save or display the grayscale image.

gray_image.show()
gray_image.save("path_to_save_grayscale_image.jpg")

```

| Original image                                                                                                                          | Grayscale image                                                                                                                                                         |
| --------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|![Original image of a blue lizard with vibrant colors](@/assets/images/blog/2023/how-to-use-tesseract-ocr-in-python/original-image.png) |![Grayscale version of the original image, showing the blue lizard in shades of gray](@/assets/images/blog/2023/how-to-use-tesseract-ocr-in-python/grayscale-image.png) |

### Resizing the image for better accuracy

Resizing to a larger size makes text easier to recognize:

```python

# Resize the image.

scale_factor = 2
resized_image = gray_image.resize(
    (gray_image.width * scale_factor, gray_image.height * scale_factor),
    resample=Image.LANCZOS
)

```

This doubles the image dimensions using Lanczos resampling, which preserves sharpness during upscaling.

### Applying adaptive thresholding

Adaptive thresholding creates a binary image with clear separation between text and the background:

```python

from PIL import Image, ImageOps, ImageFilter

# Load the image.

image = Image.open('image.png')

# Convert the image to grayscale.

gray_image = ImageOps.grayscale(image)

# Resize the image to enhance details.

scale_factor = 2
resized_image = gray_image.resize(
    (gray_image.width * scale_factor, gray_image.height * scale_factor),
    resample=Image.LANCZOS
)

# Apply edge detection filter (find edges).

thresholded_image = resized_image.filter(ImageFilter.FIND_EDGES)

# Save or display the processed image.

thresholded_image.show()  # This will display the image.

# thresholded_image.save('path_to_save_image')  # This will save the image.

```

| Original image                                                                                                                       | Thresholded image                                                                                                                                                       |
| ------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|![Image of black-and-white text with standard contrast](@/assets/images/blog/2023/how-to-use-tesseract-ocr-in-python/text-image.png) |![Image of black-and-white text with enhanced contrast after applying thresholding](@/assets/images/blog/2023/how-to-use-tesseract-ocr-in-python/thresholded-image.png) |

Pass the preprocessed image to the OCR engine:

```python

# Extract text from the preprocessed image.

improved_text = pytesseract.image_to_string(thresholded_image)
print(improved_text)

```

### Complete OCR script

Here’s the complete preprocessing and OCR example:

```python

from PIL import Image, ImageOps, ImageFilter
import pytesseract

# Define the path to your image.

image_path = 'image.png'

# Open the image.

image = Image.open(image_path)

# Convert image to grayscale.

gray_image = ImageOps.grayscale(image)

# Resize the image to enhance details.

scale_factor = 2
resized_image = gray_image.resize(
    (gray_image.width * scale_factor, gray_image.height * scale_factor),
    resample=Image.LANCZOS
)

# Apply adaptive thresholding using the `FIND_EDGES` filter.

thresholded_image = resized_image.filter(ImageFilter.FIND_EDGES)

# Extract text from the preprocessed image.

improved_text = pytesseract.image_to_string(thresholded_image)

# Print the extracted text.

print(improved_text)

# Optional: Save the preprocessed image for review.

thresholded_image.save('preprocessed_image.jpg')

```

### Recognizing digits only

To extract only digits, use `--psm 6` and filter with regular expressions:

```python

import pytesseract
from PIL import Image, ImageOps
import re

image_path = "image.png"
image = Image.open(image_path)

config = '--psm 6'
text = pytesseract.image_to_string(image, config=config)
digits = re.findall(r'\d+', text)
print(digits)

```

The `re.findall()` method extracts all digit sequences from the OCR output.

### Character restrictions

Restrict OCR to specific characters using `tessedit_char_whitelist`:

```python

# Only recognize uppercase letters and numbers.

config = '--psm 6 -c tessedit_char_whitelist=ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
text = pytesseract.image_to_string(image, config=config)

```

To preserve spaces between words when using an allowlist, add `preserve_interword_spaces=1`:

```python

config = '--psm 6 -c preserve_interword_spaces=1 -c tessedit_char_whitelist=ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'

```

Use `tessedit_char_blacklist` to exclude specific characters instead.

### Getting bounding boxes

Extract character positions with `image_to_boxes`:

```python

import pytesseract
from PIL import Image

image = Image.open('image.png')
boxes = pytesseract.image_to_boxes(image)
h = image.height

for box in boxes.splitlines():
    b = box.split()
    char, x1, y1, x2, y2 = b[0], int(b[1]), int(b[2]), int(b[3]), int(b[4])
    # Note: y-coordinates are from image bottom, convert to top-origin

    print(f"Character '{char}' at ({x1}, {h - y2}) to ({x2}, {h - y1})")

```

For word-level bounding boxes with confidence scores, use `image_to_data` (requires `pip install pandas`):

```python

import pytesseract
from PIL import Image

image = Image.open('image.png')
data = pytesseract.image_to_data(image, output_type=pytesseract.Output.DATAFRAME)

# Filter: conf > 0 removes non-text rows, conf > 60 keeps high-confidence words

words = data[(data['conf'] > 60) & (data['text'].str.strip()!= '')]
for _, row in words.iterrows():
    print(f"'{row['text']}' (conf: {row['conf']}) at ({row['left']}, {row['top']})")

```

### Orientation and script detection

Detect the page rotation and script type with `image_to_osd`:

```python

import pytesseract
from PIL import Image

image = Image.open('rotated_image.png')
osd = pytesseract.image_to_osd(image)
print(osd)

# Output includes:

# - Page orientation (0, 90, 180, 270 degrees)

# - Script type (Latin, Cyrillic, Arabic, etc.)

# - Confidence scores

```

This helps preprocess images that need rotation correction before OCR.

## Training Tesseract with custom data

Training Tesseract improves accuracy for specific fonts, languages, or layouts not well-represented in the default model. The neural network engine learns from structured training data.

You need a dataset of images with corresponding text files containing the expected output. Tesseract provides `tesstrain` and `text2image` tools for generating and labeling training data.

Training takes hours to days depending on dataset size, but it produces measurably better accuracy for specialized fonts, symbols, or languages.

## Best practices

1. **Preprocess images** — Grayscale, resize, threshold. Clean images produce better results.

2. **Set the right PSM** — Page segmentation mode (`--psm`) affects how Tesseract interprets layout. Try different values for your document type.

3. **Specify the language** — Use the `-l` flag to set the recognition language (e.g. `-l eng` for English). Combine multiple languages with `+` (e.g. `-l eng+fra` for English and French).

4. **Use `tessdata_fast` for production** — The `tessdata_fast` models are smaller and faster than default models, with minimal accuracy loss. Download from the [`tessdata_fast` repository](https://github.com/tesseract-ocr/tessdata_fast).

5. **Filter by confidence** — Use `image_to_data` and filter results by confidence score (greater than 60 percent) to reduce errors.

6. **Train for custom fonts** — Non-standard fonts need custom training data.

7. **Test on representative samples** — Accuracy varies by document type. Test before deploying.

For more tips, including parallel processing and batch optimization, see the [complete pytesseract guide](https://www.nutrient.io/blog/tesseract-python-guide.md).

## Why pytesseract fails to recognize or import text

When pytesseract fails to import, the cause is usually installation, environment configuration, or system paths. When it imports correctly but returns poor or empty text, the cause is image quality or the wrong `--psm` mode — see [how to improve OCR accuracy](#how-to-improve-tesseract-ocr-accuracy). This section covers the import and environment issues.

### Common causes of pytesseract import errors

1. Incorrect installation
   - Ensure pytesseract is installed in the correct Python environment.
   - Verify installation by running:

   ```bash

   pip show pytesseract
   ```

   If it’s not installed, install it using:

   ```bash

   pip install pytesseract
   ```

2. Multiple Python versions

   If you have multiple versions of Python installed, ensure `pytesseract` is installed in the environment corresponding to the Python version you’re using.

   - Check your Python version with:

   ```bash

   python3 --version
   ```

   - Use the correct pip version:

   ```bash

   python3 -m pip install pytesseract
   ```

3. Environment issues
   - If you’re using virtual environments, activate the correct environment before installing or running your script.
   - Check if the environment is activated:

   ```bash

   source your_env_name/bin/activate
   ```

   Install `pytesseract` within the activated environment.

4. System path issues
   - Ensure the Python and pip paths are correctly set in your system environment variables.
   - Check your current Python path:

   ```bash

   which python3
   ```

### Additional tips

- **Reinstall `pytesseract`** — If problems persist, try uninstalling and reinstalling `pytesseract`:

```bash

pip uninstall pytesseract
pip install pytesseract

```

- **Check the Tesseract installation** — Verify with:

```bash

tesseract --version

```

- **Upgrade pip** — Upgrading pip can resolve issues:

```bash

python3 -m pip install --upgrade pip

```

- **Install packages on managed environments** — For externally managed environments (like macOS with Homebrew):
  - Use a virtual environment:

  ```bash

  python3 -m venv myenv
  source myenv/bin/activate
  pip install pytesseract
  ```

  - Use [`pipx`](https://github.com/pypa/pipx) for isolated environments:

  ```bash

  brew install pipx
  pipx install pytesseract
  ```

  - Override the restriction (not recommended):

  ```bash

  python3 -m pip install pytesseract --break-system-packages
  ```

Check [PEP 668](https://peps.python.org/pep-0668/) for details.

## Limitations of Tesseract

- Accuracy varies with image quality, language, and document complexity. Output may contain errors or miss text.

- Non-standard fonts and handwriting require custom training data.

- Complex layouts, graphics, and tables reduce accuracy.

- Not all languages and scripts are supported.

- No built-in preprocessing. You must handle resizing, skew correction, and noise removal separately.

If you need to [extract text from PDFs](https://www.nutrient.io/blog/extract-text-from-pdf-using-python.md) without OCR, libraries like [PyMuPDF](https://www.nutrient.io/blog/extract-text-from-pdf-pymupdf/) can read the embedded text layer directly — which is faster and more accurate for digital PDFs.

## pytesseract vs. Nutrient OCR API: Which to use

Use pytesseract for free, local text extraction and prototypes. Use the Nutrient OCR API to produce searchable PDFs, batch-process scanned documents, or get consistent results without preprocessing each image. The table below compares them across output, setup, and cost.

| Feature          | pytesseract (Tesseract)           | Nutrient OCR API                 |
| ---------------- | --------------------------------- | -------------------------------- |
| Output format    | Plain text string                 | Searchable PDF with text layer   |
| Installation     | Local engine + Python wrapper     | No installation (cloud API)      |
| Preprocessing    | Manual (grayscale, threshold)     | Automatic                        |
| Languages        | 100+ (install language packs)     | 20 languages built in            |
| Batch processing | Write your own code               | Single API call                  |
| PDF support      | Requires pdf2image conversion     | Native PDF input/output          |
| Cost             | Free (open source)                | 50 free credits/month, then paid |
| Best for         | Local text extraction, prototypes | Production searchable PDFs       |

## Nutrient API for OCR

Tesseract extracts text. [Nutrient’s OCR API](https://www.nutrient.io/api/pdf-ocr-api/) creates searchable PDFs — the text layer is embedded in the PDF so users can search, select, and copy text.

When to use Nutrient instead of Tesseract:

- You need searchable PDFs, not just raw text

- You’re processing batches of scanned documents

- You want to merge multiple scanned pages into one PDF

- You need 20 languages without installing language packs

- You want consistent results without preprocessing each image

The API is SOC 2-audited, stores no document data, and offers 50 free credits/month to start.

## Requirements

You need:

- A [Nutrient API key](https://www.nutrient.io/api/) (sign up for a [free account](https://dashboard.nutrient.io/sign_up/?product=processor), and then find your key in [Dashboard > API keys](https://dashboard.nutrient.io/api_keys/))

- Python 3.x

- [pip](https://pip.pypa.io/en/stable/installation/)

- The [Requests library](https://docs.python-requests.org/en/latest/)

Install the `requests` library:

```bash

python3 -m pip install requests

```

## Using the OCR API

The following steps walk through sending a scanned image to the Nutrient OCR API and saving the searchable PDF output.

### 1. Import required modules

```python

import requests
import json

```

### 2. Define the OCR instructions

```python

data = {
  'instructions': json.dumps({
    'parts': [
      {
        'file': 'scanned'
      }
    ],
    'actions': [
      {
        'type': 'ocr',
        'language': 'english'
      }
    ]
  })
}

```

- `"file": "scanned"` references the uploaded file

- `"type": "ocr"` applies OCR

- `"language": "english"` sets the OCR language

### 3. Send the OCR request to the Nutrient API

Make a `POST` request to the `https://api.nutrient.io/build` endpoint:

```python

response = requests.request(
  'POST',
  'https://api.nutrient.io/build',
  headers = {
    'Authorization': 'Bearer your_api_key_here'
  },
  files = {
    'scanned': open('image.png', 'rb')
  },
  data = {
    'instructions': json.dumps({
      'parts': [
        {
          'file': 'scanned'
        }
      ],
      'actions': [
        {
          'type': 'ocr',
          'language': 'english'
        }
      ]
    })
  },
  stream = True
)

```

Replace `'your_api_key_here'` with your actual API key. The request sends the file with OCR instructions. Streaming the response avoids loading the full PDF into memory.

You can use the [sample OCR document](https://github.com/PSPDFKit/PSPDFKit/blob/master/hosted/assets/static/downloads/samples/ocr/page1.jpg) to test the API.

### 4. Save the OCR result to a file

Write the result to disk if successful:

```python

if response.ok:
  with open('result.pdf', 'wb') as fd:
    for chunk in response.iter_content(chunk_size=8096):
      fd.write(chunk)
else:
  print(response.text)
  exit()

```

This streams the OCR output into `result.pdf` and prints error messages if the request fails.

## Advanced OCR with Python: Merge multiple scanned pages into a searchable PDF using Nutrient API

The Nutrient OCR API merges batches of scanned pages into a single searchable PDF in one API call, unlike pytesseract, which requires processing each page and merging afterward.

### Example: Merge four scanned images with OCR enabled

```python

import requests
import json

response = requests.request(
  'POST',
  'https://api.nutrient.io/build',
  headers={
    'Authorization': 'Bearer your_api_key_here'
  },
  files={
    'page1': open('page1.jpg', 'rb'),
    'page2': open('page2.jpg', 'rb'),
    'page3': open('page3.jpg', 'rb'),
    'page4': open('page4.jpg', 'rb')
  },
  data={
    'instructions': json.dumps({
      'parts': [
        { 'file': 'page1' },
        { 'file': 'page2' },
        { 'file': 'page3' },
        { 'file': 'page4' }
      ],
      'actions': [
        {
          'type': 'ocr',
          'language': 'english'
        }
      ]
    })
  },
  stream=True
)

if response.ok:
  with open('merged_scanned.pdf', 'wb') as fd:
    for chunk in response.iter_content(chunk_size=8096):
      fd.write(chunk)
else:
  print(response.text)
  exit()

```

### When to use this instead of pytesseract

pytesseract: Extract text from individual images, handle preprocessing yourself, write code to merge results.

Nutrient API: Upload images, get a searchable PDF back. One API call handles OCR, merging, and PDF creation.

## Conclusion

Tesseract with pytesseract handles basic text extraction. Preprocess images (grayscale, resize, threshold) for better accuracy. For searchable PDFs or batch processing, use the [Nutrient OCR API](https://www.nutrient.io/api/pdf-ocr-api/).

If you’re building a [document scanner](https://www.nutrient.io/blog/creating-a-document-scanner-with-ocr-in-python.md) or need to [automate OCR workflows](https://www.nutrient.io/blog/how-to-create-automated-pdf-ocr-workflows/) at scale, explore our related guides. You can also [generate PDFs in Python](https://www.nutrient.io/blog/top-10-ways-to-generate-pdfs-in-python/) for downstream document processing.

## FAQ

#### What is Tesseract OCR?

Tesseract OCR is an open source engine for recognizing text from images and scanned documents. Developed by Hewlett-Packard and now sponsored by Google, it supports more than 100 languages and various text styles.

#### How do I install Tesseract OCR in Python?

To install Tesseract OCR, download the installer from [GitHub for Windows](https://github.com/UB-Mannheim/tesseract/wiki), use `brew install tesseract` on macOS, or run `sudo apt install tesseract-ocr` on Debian/Ubuntu.

#### How do I install pytesseract?

Install pytesseract using pip: `pip install pytesseract`. You also need Tesseract OCR installed on your system. On Windows, download from GitHub. On macOS, use `brew install tesseract`. On Linux, use `sudo apt install tesseract-ocr`.

#### What is the difference between Tesseract and pytesseract?

Tesseract is the OCR engine (written in C++) that performs text recognition. pytesseract is a Python wrapper library that provides a simple interface to use Tesseract from Python code. You need both: Tesseract for the OCR functionality and pytesseract for the Python API.

#### Why is pytesseract not recognizing text?

Common causes include poor image quality, incorrect PSM mode, or missing preprocessing. Try converting to grayscale, increasing image resolution, applying thresholding, and using the correct `--psm` value for your document type. Also verify Tesseract is properly installed with `tesseract --version`.

#### How do I OCR a PDF with pytesseract?

pytesseract doesn’t directly support PDFs. First convert PDF pages to images using `pdf2image` library: `from pdf2image import convert_from_path; images = convert_from_path('file.pdf')`. Then run `pytesseract.image_to_string()` on each image. For native PDF OCR, use Nutrient’s OCR API instead.

#### How can I improve OCR accuracy?

Convert the image to grayscale, resize to increase text pixel density, and apply adaptive thresholding. These steps are covered in detail above.

#### Can Tesseract OCR handle multiple languages?

Yes. Tesseract supports multiple languages. Use a plus sign (`+`) in the configuration string, like `-l eng+fra` for English and French.

#### What are the limitations of Tesseract OCR?

Tesseract’s limitations include varying accuracy based on image quality, difficulty with non-standard fonts, and limited support for complex layouts and languages. It also lacks built-in image preprocessing.

#### How does Nutrient’s OCR API work?

Upload scanned images or PDFs and get searchable PDFs back. The API supports 20 languages, preserves layout, and handles multipage documents. It’s SOC 2-audited with 50 free credits/month.

#### How do I use Nutrient’s OCR API?

Install the `requests` library and send a `POST` request to `https://api.nutrient.io/build` with your API key and document. The response is the searchable PDF.

#### Can I merge multiple scanned pages into one searchable PDF using Nutrient?

Yes. You can merge multiple images into a single searchable PDF. Adjust the file handling and instructions in your API request to include all pages.

#### What is pytesseract in Python?

pytesseract is a Python wrapper for the open source Tesseract OCR engine. It enables developers to extract text from images using a simple Python API.

#### How do I use pytesseract to extract text from an image?

Install the `pytesseract` and `Pillow` libraries, open the image using `PIL.Image.open()`, and pass it to `pytesseract.image_to_string()` to extract text.

#### How do I fix <code>TesseractNotFoundError</code> in Python?

This error means Python can’t find the Tesseract executable. Either add Tesseract to your system PATH, or set the path explicitly in Python: `pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'` (Windows) or `pytesseract.pytesseract.tesseract_cmd = '/usr/local/bin/tesseract'` (macOS/Linux).

#### How do I extract only numbers with pytesseract?

Use the `--psm 6` mode with a digits-only allowlist: `config = '--psm 6 -c tessedit_char_whitelist=0123456789'` and pass it to `pytesseract.image_to_string(image, config=config)`. Alternatively, extract all text and filter with regex: `re.findall(r'\d+', text)`.

#### Is pytesseract free to use?

Yes. Both Tesseract OCR and pytesseract are free and open source under the Apache 2.0 license. You can use them in commercial projects without licensing fees. However, accuracy and preprocessing are your responsibility.
---

## Related pages

- [The business case for accessibility: Five ways it drives enterprise value](/blog/5-ways-accessibility-drives-enterprise-value.md)
- [Accessibility Untangled Why It Matters Guide](/blog/accessibility-untangled-why-it-matters-guide.md)
- [Advanced Techniques For React Native Ui Components](/blog/advanced-techniques-for-react-native-ui-components.md)
- [`vector_store` holds your indexed documents (see the multimodal RAG post](/blog/agentic-rag.md)
- [Ai Document Automation Extraction To Action](/blog/ai-document-automation-extraction-to-action.md)
- [Ai Legal Assistant Document Authoring](/blog/ai-legal-assistant-document-authoring.md)
- [Angular File Viewer Pdf Image Office Files](/blog/angular-file-viewer-pdf-image-office-files.md)
- [Auto Tagging And Document Accessibility In Dotnet Sdk](/blog/auto-tagging-and-document-accessibility-in-dotnet-sdk.md)
- [Best Document Viewers](/blog/best-document-viewers.md)
- [The CEO’s AI playbook: Why decision architecture beats model selection](/blog/ceo-ai-playbook-decision-architecture.md)
- [Complete Guide To Pdfjs](/blog/complete-guide-to-pdfjs.md)
- [Construction Document Data Extraction](/blog/construction-document-data-extraction.md)
- [Convert One Drive Files To Pdf In Sharepoint](/blog/convert-one-drive-files-to-pdf-in-sharepoint.md)
- [Create And Edit Pdfs In Flutter](/blog/create-and-edit-pdfs-in-flutter.md)
- [Create Pdfs With React](/blog/create-pdfs-with-react.md)
- [Creating A Document Scanner With Ocr In Python](/blog/creating-a-document-scanner-with-ocr-in-python.md)
- [Creating And Filling Pdf Forms Programmatically In Javascript](/blog/creating-and-filling-pdf-forms-programmatically-in-javascript.md)
- [The CTO’s AI playbook: Why accountability architecture beats orchestration](/blog/cto-ai-playbook-accountability-architecture.md)
- [Digital Signatures](/blog/digital-signatures.md)
- [Digital Workflow Automation](/blog/digital-workflow-automation.md)
- [Document Ai Vs Ocr](/blog/document-ai-vs-ocr.md)
- [Document Viewer](/blog/document-viewer.md)
- [Document Watermarking](/blog/document-watermarking.md)
- [Emerging threats: Your logging system may be an agentic threat vector](/blog/emerging-threats-your-logging-system.md)
- [app.py](/blog/extract-text-from-pdf-using-python.md)
- [How To Add Digital Signature To Pdf Using React](/blog/how-to-add-digital-signature-to-pdf-using-react.md)
- [How To Build A Dotnet Maui Pdf Viewer](/blog/how-to-build-a-dotnet-maui-pdf-viewer.md)
- [How To Build A Flutter Pdf Viewer](/blog/how-to-build-a-flutter-pdf-viewer.md)
- [or](/blog/how-to-build-a-javascript-pdf-viewer-with-pdfjs.md)
- [How To Build A Javascript Pdf Viewer](/blog/how-to-build-a-javascript-pdf-viewer.md)
- [or](/blog/how-to-build-a-nextjs-pdf-viewer.md)
- [How To Build A Powerpoint Viewer Using Javascript](/blog/how-to-build-a-powerpoint-viewer-using-javascript.md)
- [Using Yarn](/blog/how-to-build-a-react-excel-viewer.md)
- [How To Build A React Native Pdf Viewer](/blog/how-to-build-a-react-native-pdf-viewer.md)
- [How To Build A React Powerpoint Viewer](/blog/how-to-build-a-react-powerpoint-viewer.md)
- [How To Build A Reactjs File Viewer](/blog/how-to-build-a-reactjs-file-viewer.md)
- [or](/blog/how-to-build-a-reactjs-pdf-viewer-with-react-pdf.md)
- [or](/blog/how-to-build-a-reactjs-pdf-viewer.md)
- [How To Build A Reactjs Viewer With Pdfjs](/blog/how-to-build-a-reactjs-viewer-with-pdfjs.md)
- [How To Build A Vuejs Pdf Viewer With Pdfjs](/blog/how-to-build-a-vuejs-pdf-viewer-with-pdfjs.md)
- [How To Build A Vuejs Pdf Viewer](/blog/how-to-build-a-vuejs-pdf-viewer.md)
- [How To Build An Android Pdf Viewer](/blog/how-to-build-an-android-pdf-viewer.md)
- [How To Build An Angular Pdf Viewer With Ng2 Pdf Viewer](/blog/how-to-build-an-angular-pdf-viewer-with-ng2-pdf-viewer.md)
- [How To Build An Angular Pdf Viewer With Pdfjs](/blog/how-to-build-an-angular-pdf-viewer-with-pdfjs.md)
- [How To Convert Docx To Pdf Using Javascript](/blog/how-to-convert-docx-to-pdf-using-javascript.md)
- [How To Convert Docx To Pdf Using Python](/blog/how-to-convert-docx-to-pdf-using-python.md)
- [How To Convert Html To Pdf Using Html2pdf](/blog/how-to-convert-html-to-pdf-using-html2pdf.md)
- [or](/blog/how-to-convert-html-to-pdf-using-react.md)
- [or](/blog/how-to-convert-html-to-pdf-using-wkhtmltopdf-and-python.md)
- [How To Convert Word To Pdf In Nodejs](/blog/how-to-convert-word-to-pdf-in-nodejs.md)
- [or](/blog/how-to-create-a-react-js-signature-pad.md)
- [How To Create Pdfs With React To Pdf](/blog/how-to-create-pdfs-with-react-to-pdf.md)
- [How To Edit Pdfs Using Ios Pdf Library](/blog/how-to-edit-pdfs-using-ios-pdf-library.md)
- [How To Embed A Pdf Viewer In Your Website](/blog/how-to-embed-a-pdf-viewer-in-your-website.md)
- [How To Generate Pdf From Html With Nodejs](/blog/how-to-generate-pdf-from-html-with-nodejs.md)
- [base_url tells WeasyPrint where to resolve relative asset paths](/blog/how-to-generate-pdf-reports-from-html-in-python.md)
- [From an HTML string.](/blog/html-in-pdf-format.md)
- [Javascript Pdf Libraries](/blog/javascript-pdf-libraries.md)
- [Linearized Pdf](/blog/linearized-pdf.md)
- [Swift Package Manager](/blog/mobile-pdf-sdk.md)
- [`elements` come from your document parser — each has a type and content.](/blog/multimodal-rag.md)
- [Nutrient Vs Conga Composer](/blog/nutrient-vs-conga-composer.md)
- [Online Document Viewer](/blog/online-document-viewer.md)
- [Open Pdf In Your Web App](/blog/open-pdf-in-your-web-app.md)
- [Pdf Page Labels](/blog/pdf-page-labels.md)
- [Pdf Sdk Compliance Security Checklist](/blog/pdf-sdk-compliance-security-checklist.md)
- [Pdf Sdk Performance Benchmark](/blog/pdf-sdk-performance-benchmark.md)
- [Pdf Ua Compliance Guide](/blog/pdf-ua-compliance-guide.md)
- [Pdfjs Annotation Editor Layer](/blog/pdfjs-annotation-editor-layer.md)
- [Pdfjs Area Annotations Canvas Capture](/blog/pdfjs-area-annotations-canvas-capture.md)
- [Pdfjs Coordinate Systems Pdf To Screen](/blog/pdfjs-coordinate-systems-pdf-to-screen.md)
- [Pdfjs Eventbus Guide](/blog/pdfjs-eventbus-guide.md)
- [Pdfjs Limitations Commercial Upgrade](/blog/pdfjs-limitations-commercial-upgrade.md)
- [Pdfjs Native Annotation Layer Forms](/blog/pdfjs-native-annotation-layer-forms.md)
- [Pdfjs Navigation Zoom Rotation](/blog/pdfjs-navigation-zoom-rotation.md)
- [Pdfjs Pdf Page Manipulation Pdf Lib](/blog/pdfjs-pdf-page-manipulation-pdf-lib.md)
- [Pdfjs React Viewer Setup](/blog/pdfjs-react-viewer-setup.md)
- [Pdfjs Rendering Overlays React Portals](/blog/pdfjs-rendering-overlays-react-portals.md)
- [Pdfjs Server Side Text Extraction](/blog/pdfjs-server-side-text-extraction.md)
- [Pdfjs Sticky Note Annotations](/blog/pdfjs-sticky-note-annotations.md)
- [Pdfjs Text Highlight Annotations](/blog/pdfjs-text-highlight-annotations.md)
- [Pdfjs Text Search Pdffindcontroller](/blog/pdfjs-text-search-pdffindcontroller.md)
- [Pdfjs Thumbnail Sidebar](/blog/pdfjs-thumbnail-sidebar.md)
- [Process Flows](/blog/process-flows.md)
- [React Native Pdf Annotation](/blog/react-native-pdf-annotation.md)
- [or](/blog/sample-blog-updated.md)
- [Open an image file.](/blog/tesseract-python-guide.md)
- [Top 5 Javascript Pdf Viewers](/blog/top-5-javascript-pdf-viewers.md)
- [Convert an HTML file to PDF.](/blog/top-ten-ways-to-convert-html-to-pdf.md)
- [Vector Pdf](/blog/vector-pdf.md)
- [Wcag2 Accessibility Requirements Documents](/blog/wcag2-accessibility-requirements-documents.md)
- [Web Sdk Is Now Headless](/blog/web-sdk-is-now-headless.md)
- [What Are Annotations](/blog/what-are-annotations.md)
- [What Is A Vpat](/blog/what-is-a-vpat.md)
- [What Is Pdf Ua](/blog/what-is-pdf-ua.md)
- [Why Pdfium Is A Trusted Platform For Pdf Rendering](/blog/why-pdfium-is-a-trusted-platform-for-pdf-rendering.md)
- [Why Your Ai Agent Hallucinates Pdf Table Data](/blog/why-your-ai-agent-hallucinates-pdf-table-data.md)

