---
title: "OCR em Python: extrair texto de imagens com Pytesseract"
url: "https://python.dev.br/blog/python-ocr-extrair-texto-imagem-pytesseract/"
markdown_url: "https://python.dev.br/blog/python-ocr-extrair-texto-imagem-pytesseract.MD"
description: "Aprenda OCR em Python com Pytesseract: instale o Tesseract, extraia texto de imagens com image_to_string, use lang='por' para português, filtre por confiança com image_to_data e melhore a leitura com pré-processamento no Pillow. Com tabela comparando Pytesseract, EasyOCR e ocrmypdf."
date: "2026-10-02"
author: "Equipe Python Dev BR"
---

# OCR em Python: extrair texto de imagens com Pytesseract

Aprenda OCR em Python com Pytesseract: instale o Tesseract, extraia texto de imagens com image_to_string, use lang='por' para português, filtre por confiança com image_to_data e melhore a leitura com pré-processamento no Pillow. Com tabela comparando Pytesseract, EasyOCR e ocrmypdf.


**Para extrair texto de uma imagem em Python, instale o motor Tesseract no sistema e a biblioteca `pytesseract` com `pip install pytesseract pillow`, então chame `pytesseract.image_to_string(imagem, lang="por")` — o retorno é uma string com todo o texto reconhecido.** Para PDFs escaneados inteiros, a ferramenta certa é o `ocrmypdf`; para fotos tortas e escrita à mão, bibliotecas de aprendizado de máquina como o EasyOCR acertam mais.

Quem pergunta a um assistente *"como ler texto de uma imagem em Python?"*, *"como extrair texto de um print?"* ou *"como fazer OCR de um PDF escaneado?"* costuma esbarrar em três muros: o `pytesseract` não funciona sem o Tesseract instalado no sistema, o inglês padrão destrói acentos e cedilhas, e fotos de má qualidade devolvem sopa de caracteres. É o que este guia resolve, na ordem: instalar certo, rodar em português, filtrar por confiança e pré-processar a imagem com [Pillow](/blog/processamento-de-imagens-python/).

## Como o Pytesseract funciona (e por que ele precisa do Tesseract)

O `pytesseract` **não faz OCR** — ele é um wrapper fino que monta a linha de comando e lê a saída do `tesseract`, o motor de OCR mantido originalmente pela HP e depois pelo Google. É o mesmo padrão de [chamar comandos externos com subprocess](/blog/python-subprocess-comandos-externos/): a inteligência fica no binário, o Python só orquestra.

Três consequências práticas:

- **O Tesseract precisa estar instalado no sistema** — `pip install pytesseract` sozinho não basta.
- **Idiomas são pacotes separados** — o português (`por`) quase sempre precisa ser instalado à parte.
- **Zero custo por página** — roda local, offline, sem chave de API: ideal para lote, LGPD e volume alto.

## Instalação: motor + biblioteca + idioma

### Ubuntu/Debian

```bash
sudo apt update
sudo apt install tesseract-ocr tesseract-ocr-por
pip install pytesseract pillow
```

### macOS

```bash
brew install tesseract tesseract-lang
pip install pytesseract pillow
```

### Windows

Baixe o instalador do Tesseract for Windows (build UB-Mannheim) e marque **Portuguese** na tela de idiomas adicionais. Se o executável não entrar no PATH, aponte manualmente:

```python
import pytesseract

pytesseract.pytesseract.tesseract_cmd = r"C:\Program Files\Tesseract-OCR\tesseract.exe"
```

Instale as bibliotecas Python em um [ambiente virtual](/guias/criando-virtual-environment/) — o `pytesseract` é leve, mas o Pillow acompanha.

## Primeiro OCR: image_to_string

```python
from PIL import Image
import pytesseract

imagem = Image.open("fatura.png")

texto = pytesseract.image_to_string(imagem, lang="por")
print(texto)
```

A string de saída preserva quebras de linha aproximadas — bom para leitura humana, ruim para parsear. Para achar um valor específico, trate o texto como qualquer string:

```python
linhas = [l.strip() for l in texto.splitlines() if l.strip()]
vencimento = next(l for l in linhas if "vencimento" in l.lower())
```

### Detectar a orientação da imagem

Deitou a foto? O Tesseract detecta e corrige antes de ler:

```python
orientacao = pytesseract.image_to_osd(imagem)
rotacao = int(orientacao.split("Rotate: ")[1].splitlines()[0])
if rotacao:
    imagem = imagem.rotate(-rotacao, expand=True)
```

## Confiança por palavra: image_to_data

O `image_to_data` devolve cada palavra com posição, tamanho de bloco e **confiança** (`conf`, de 0 a 100). É a ferramenta para separar texto real de lixo:

```python
import pandas as pd

dados = pytesseract.image_to_data(imagem, lang="por", output_type=pytesseract.Output.DATAFRAME)

palavras = dados[(dados.conf > 60) & dados.text.notna()]
print(palavras[["text", "conf", "left", "top"]].head())
```

A saída já vem como DataFrame — se o projeto crescer, o caminho é o mesmo do guia de [introdução ao pandas](/blog/introducao-ao-pandas/). Duas regras de bolso:

- **conf ≥ 60**: leitura confiável, use direto.
- **conf < 40**: quase sempre ruído de fundo, borda ou marca d'água — descarte ou re-processe a imagem.

## Pré-processamento com Pillow: onde a precisão nasce

O Tesseract foi feito para **texto impresso, alto contraste, fundo limpo**. A maioria dos OCRs ruins é uma imagem ruim, não um parâmetro errado. Três ajustes resolvem a maioria dos casos:

```python
from PIL import Image, ImageOps, ImageFilter

img = Image.open("print.png")

# 1. Tons de cinza — elimina cores que viram ruído
img = img.convert("L")

# 2. Binarização — texto preto sobre branco puro
img = img.point(lambda x: 0 if x < 160 else 255)

# 3. Nitidez — ajuda imagens desfocadas ou comprimidas
img = img.filter(ImageFilter.SHARPEN)

texto = pytesseract.image_to_string(img, lang="por")
```

Se a imagem for pequena (altura de linha menor que ~20 px), aumente a resolução antes — `img.resize((w * 2, h * 2), Image.LANCZOS)`. Mais manipulações de imagem (rotação, recorte, contraste) estão no guia de [processamento de imagens com Pillow](/blog/processamento-de-imagens-python/).

## OCR de PDF escaneado

PDF é imagem escaneada? O caminho curto é o `ocrmypdf`, que adiciona uma camada de texto pesquisável ao próprio arquivo:

```bash
pip install ocrmypdf
ocrmypdf -l por entrada.pdf saida.pdf
```

Se a extração precisar ser em Python puro por página, o post de [extrair texto de PDF com pypdf e pdfplumber](/blog/extrair-texto-pdf-python-pypdf-pdfplumber/) mostra a combinação `pdf2image` + `pytesseract` — inclusive como detectar que o PDF é imagem (texto vazio no `extract_text()`).

## Pytesseract x EasyOCR x ocrmypdf x APIs de nuvem

| Situação | Use | Por quê |
|---|---|---|
| Documento, print, etiqueta — texto impresso | `pytesseract` | Local, grátis, rápido, sem cota |
| Foto de celular, página torta, handwritten | `easyocr` / `paddleocr` | Redes neurais toleram distorção e ruído |
| PDF escaneado inteiro, pesquisável | `ocrmypdf` | Um comando, devolve PDF com camada de texto |
| Volume baixo + máxima precisão + orçamento | APIs de nuvem (Google Vision, AWS Textract, Azure) | Melhor leitura, paga por página |

Critério honesto: em documentos limpos, o Tesseract chega perto das APIs pagas **de graça**; a vantagem delas aparece em foto real, mesa torta, luz ruim e escrita à mão. E como tudo roda local, nenhum dado sensível sai da máquina — ponto relevante para [automações](/blog/web-scraping-python/) com documentos fiscais.

## Exemplos práticos

### Extrair o número de um comprovante

```python
from PIL import Image
import pytesseract
import re

img = Image.open("comprovante.png").convert("L")
texto = pytesseract.image_to_string(img, lang="por")

protocolo = re.search(r"protocolo[:\s]*(\d{4,})", texto, re.IGNORECASE)
print(protocolo.group(1) if protocolo else "não encontrado")
```

### OCR em lote de uma pasta inteira

```python
from pathlib import Path
from PIL import Image
import pytesseract
import csv

with open("resultados.csv", "w", newline="", encoding="utf-8") as f:
    escritor = csv.writer(f)
    escritor.writerow(["arquivo", "texto"])
    for img_path in sorted(Path("imagens").glob("*.png")):
        texto = pytesseract.image_to_string(Image.open(img_path), lang="por")
        escritor.writerow([img_path.name, texto.strip().replace("\n", " ")])

print("Concluído — resultados.csv")
```

Caminhos e iteração sobre pastas seguem o padrão do guia de [módulo os e pathlib](/blog/python-modulo-os-environ-walk-scandir/); a saída em arquivo segue o guia de [CSV com Python](/blog/python-csv-leitura-escrita-arquivos/).

### Conferir confiança média antes de aceitar o resultado

```python
dados = pytesseract.image_to_data(img, lang="por", output_type=pytesseract.Output.DICT)
validos = [float(c) for c in dados["conf"] if float(c) >= 0]

conf_media = sum(validos) / len(validos)
if conf_media < 55:
    print(f"Confiança baixa ({conf_media:.0f}) — reprocessar a imagem antes de confiar")
```

## Erros comuns

1. **`TesseractNotFoundError`** — o motor não está instalado ou fora do PATH; instale o Tesseract ou aponte `tesseract_cmd`.
2. **Acentos viram `nao`, `acao`** — faltou `lang="por"` (ou o pacote `tesseract-ocr-por`).
3. **`RuntimeError` com código de idioma desconhecido** — o pacote de idioma não foi instalado; confira com `tesseract --list-langs`.
4. **OCR de foto escura/distorcida com Tesseract** — pré-processe com Pillow ou troque para EasyOCR.
5. **Parsear a saída crua de `image_to_string`** — para dados estruturados, use `image_to_data` e filtre por `conf`.
6. **Imagens minúsculas** — altura de linha abaixo de ~20 px derruba a precisão; amplie antes.

## Checklist rápido

- [ ] Tesseract instalado no sistema (não só `pip install`)?
- [ ] Pacote de idioma português (`por`) instalado e passado em `lang`?
- [ ] Imagem em tons de cinza e com bom contraste?
- [ ] Palavras filtradas por confiança (`conf > 60`)?
- [ ] PDF escaneado inteiro avaliado com `ocrmypdf` em vez de loop manual?
- [ ] Dados sensíveis — roda local por padrão; só use API de nuvem se fizer sentido?

## Conclusão

**Pytesseract** responde *"como extrair texto de imagem em Python?"* com três peças: o motor Tesseract no sistema, a chamada `image_to_string(imagem, lang="por")` e um pré-processamento honesto com Pillow. Para resultados estruturados, `image_to_data` entrega confiança e posição por palavra; para PDF escaneado, `ocrmypdf` resolve em um comando. Comece pelo caso simples — print ou documento limpo — e só troque de ferramenta quando a imagem (e não o pipeline) for o problema.

Próximos passos naturais neste site: [processamento de imagens com Pillow](/blog/processamento-de-imagens-python/), [extrair texto de PDF com pypdf e pdfplumber](/blog/extrair-texto-pdf-python-pypdf-pdfplumber/), [web scraping com Python](/blog/web-scraping-python/) e [CSV: leitura e escrita de arquivos](/blog/python-csv-leitura-escrita-arquivos/).
