OCR dla skanowanych dokumentów
Tesseract za pośrednictwem pytesseract, wstępne przetwarzanie obrazów i poprawa dokładności.
OCR dla skanowanych dokumentów to bezpłatna lekcja AI Agents na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej AI Agents, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs AI Agents zawiera 4 lekcji w sumie.
Kiedy potrzebne jest OCR
Nie wszystkie dokumenty to pliki PDF utworzone cyfrowo. Dokumenty zeskanowane, zdjęcia tekstu, odręczne notatki i pliki PDF oparte na obrazach wymagają optycznego rozpoznawania znaków (OCR) w celu wyodrębnienia tekstu.
OCR przekształca obrazy tekstu zapisane w pikselach w znaki możliwe do odczytania przez komputer. Dwie wiodące biblioteki Pythona to: pytesseract (Google Tesseract) i EasyOCR (głębokie uczenie, obsługa wielu języków).
Podstawy pytesseract
pytesseract to nakładka Pythona na silnik OCR Tesseract firmy Google. Najpierw należy zainstalować Tesseract na poziomie systemu operacyjnego, a następnie wykonać pip install pytesseract Pillow.
import pytesseract
from PIL import Image
# Simple text extraction
image = Image.open('scanned_document.png')
text = pytesseract.image_to_string(image)
print(text)
# Specify language (default: English)
text_fr = pytesseract.image_to_string(
Image.open('french_doc.png'),
lang='fra'
)
# Get detailed output with bounding boxes
data = pytesseract.image_to_data(
image,
output_type=pytesseract.Output.DICT
)
for i, word in enumerate(data['text']):
if word.strip():
conf = data['conf'][i]
print(f'Word: {word!r:20} Confidence: {conf}')Wstępne przetwarzanie obrazu: skala szarości
Dokładność OCR w dużej mierze zależy od jakości obrazu. Pierwszym krokiem wstępnego przetwarzania jest konwersja do skali szarości — kolor dodaje szum, nie pomagając w rozpoznawaniu znaków.
Do wstępnego przetwarzania należy użyć Pillow lub OpenCV. Skala szarości zmniejsza szum i poprawia wykrywanie granic znaków przez Tesseract.
from PIL import Image, ImageOps
import numpy as np
def preprocess_grayscale(image_path):
img = Image.open(image_path)
# Convert to grayscale
img = img.convert('L') # 'L' = 8-bit grayscale
# Optionally resize for better OCR (Tesseract works best at ~300 DPI)
# Scale up small images
width, height = img.size
if width < 800:
scale = 800 / width
new_size = (int(width * scale), int(height * scale))
img = img.resize(new_size, Image.LANCZOS)
return img
img = preprocess_grayscale('scan.jpg')
text = pytesseract.image_to_string(img)
print(text[:300])Wstępne przetwarzanie obrazu: progowanie
Progowanie przekształca obraz w skali szarości w obraz czarno-biały. Usuwa szare cienie, nierównomierne oświetlenie i szum tła, dzięki czemu tekst wyraźnie odcina się od tła na potrzeby OCR.
from PIL import Image, ImageFilter
import numpy as np
def apply_threshold(img):
# Method 1: Simple fixed threshold
img_array = np.array(img)
threshold = 128
binary = np.where(img_array > threshold, 255, 0).astype(np.uint8)
return Image.fromarray(binary)
def adaptive_threshold(img):
# Method 2: Otsu's method via OpenCV (better for uneven lighting)
try:
import cv2
img_array = np.array(img)
_, binary = cv2.threshold(
img_array, 0, 255,
cv2.THRESH_BINARY + cv2.THRESH_OTSU
)
return Image.fromarray(binary)
except ImportError:
return apply_threshold(img)
img = preprocess_grayscale('uneven_scan.png')
img_clean = adaptive_threshold(img)
text = pytesseract.image_to_string(img_clean)
print(text[:300])Wstępne przetwarzanie obrazu: prostowanie
Zeskanowane dokumenty często są lekko obrócone. Nawet odchylenie o 2 stopnie znacznie zmniejsza dokładność OCR. Prostowanie wykrywa kąt obrotu i koryguje go przed przekazaniem obrazu do silnika OCR.
import numpy as np
from PIL import Image
def deskew(img):
try:
import cv2
img_array = np.array(img)
# Find rotation angle using Hough line transform
edges = cv2.Canny(img_array, 50, 150, apertureSize=3)
lines = cv2.HoughLines(edges, 1, np.pi/180, threshold=100)
if lines is None:
return img # no lines detected, return unchanged
angles = []
for line in lines:
rho, theta = line[0]
angle = np.degrees(theta) - 90
if -45 < angle < 45:
angles.append(angle)
if not angles:
return img
median_angle = np.median(angles)
if abs(median_angle) > 0.5: # only deskew if significant tilt
print(f'Deskewing by {median_angle:.2f} degrees')
return img.rotate(-median_angle, expand=True, fillcolor=255)
return img
except ImportError:
return img # OpenCV not available — skip deskewOpcje językowe Tesseract
Tesseract obsługuje ponad 100 języków. Pakiety językowe należy pobrać za pomocą menedżera pakietów systemu operacyjnego. W przypadku dokumentów wielojęzycznych należy określić wiele języków, rozdzielając je znakiem +.
import pytesseract
from PIL import Image
# List available languages
import subprocess
result = subprocess.run(['tesseract', '--list-langs'], capture_output=True, text=True)
print('Available languages:')
print(result.stdout)
# Single language
text_en = pytesseract.image_to_string(Image.open('doc.png'), lang='eng')
# Multiple languages (auto-detect best match)
text_multi = pytesseract.image_to_string(
Image.open('doc.png'),
lang='eng+fra+deu' # English + French + German
)
# Tesseract config options for better accuracy
custom_config = r'--oem 3 --psm 6' # OEM 3=LSTM, PSM 6=assume uniform block of text
text_tuned = pytesseract.image_to_string(
Image.open('doc.png'),
config=custom_config
)EasyOCR: oparte na głębokim uczeniu
EasyOCR korzysta z modeli głębokiego uczenia i przewyższa Tesseract w przypadku obrazów o obniżonej jakości, tekstu zakrzywionego oraz alfabetów innych niż łaciński. Nie wymaga instalacji na poziomie systemu operacyjnego.
Należy zainstalować bibliotekę za pomocą polecenia pip install easyocr. Przy pierwszym uruchomieniu pobierane są wagi modelu (około 200 MB).
import easyocr
# Initialize reader (downloads model on first run)
reader = easyocr.Reader(
['en', 'tr'], # list of languages
gpu=False # set True if CUDA available
)
# Read text from image
results = reader.readtext('scanned_page.png')
for (bbox, text, confidence) in results:
print(f'Text: {text!r:30} Confidence: {confidence:.2f}')
# bbox = [[x1,y1],[x2,y2],[x3,y3],[x4,y4]] (four corners)
# Get plain text only
text_only = ' '.join(result[1] for result in results)
print('Full text:', text_only[:300])EasyOCR w dokumentach wielojęzycznych
EasyOCR dobrze radzi sobie z dokumentami zawierającymi wiele języków — jest przydatny w przypadku umów międzynarodowych, publikacji naukowych z podpisami w różnych językach oraz dokumentów zawierających terminy techniczne zapisane innym alfabetem.
import easyocr
# For Arabic-English mixed document
reader_ar = easyocr.Reader(['ar', 'en'], gpu=False)
results = reader_ar.readtext('arabic_contract.png')
# For CJK languages
reader_cjk = easyocr.Reader(['ch_sim', 'en'], gpu=False) # Simplified Chinese + English
results_cjk = reader_cjk.readtext('chinese_report.png')
# Filter by confidence threshold
HIGH_CONFIDENCE = 0.7
def filter_confident_results(results, threshold=HIGH_CONFIDENCE):
return [
(bbox, text, conf)
for bbox, text, conf in results
if conf >= threshold
]Pełny potok wstępnego przetwarzania
Wszystkie kroki wstępnego przetwarzania — konwersję do skali szarości, progowanie i prostowanie — należy połączyć w jednej funkcji potoku. Następnie należy uruchomić OCR na oczyszczonym obrazie i zwrócić zarówno tekst, jak i miary pewności.
import pytesseract
from PIL import Image
def ocr_pipeline(image_path, lang='eng', engine='tesseract'):
print(f'Processing: {image_path}')
# 1. Load
img = Image.open(image_path)
# 2. Preprocess
img = img.convert('L') # grayscale
img = adaptive_threshold(img) # binarize
img = deskew(img) # correct rotation
# 3. OCR
if engine == 'easyocr':
reader = easyocr.Reader([lang], gpu=False)
results = reader.readtext(image_path)
text = ' '.join(r[1] for r in results if r[2] > 0.5)
else:
config = f'--oem 3 --psm 6 -l {lang}'
text = pytesseract.image_to_string(img, config=config)
# 4. Clean
text = '\n'.join(
line.strip() for line in text.splitlines()
if line.strip()
)
return text
text = ocr_pipeline('invoice_scan.jpg')
print(text[:500])Obsługa plików PDF opartych na obrazach
Niektóre pliki PDF zawierają zeskanowane strony zapisane jako obrazy wewnątrz kontenera PDF. Należy wykrywać takie „pliki PDF obrazowe”, a następnie stosować OCR dla każdej strony, najpierw wyodrębniając obrazy za pomocą PyMuPDF.
import fitz
from PIL import Image
import io
import pytesseract
def is_image_pdf(doc):
# Check if first page has very little extractable text
text = doc[0].get_text().strip()
return len(text) < 50
def ocr_pdf(filepath):
doc = fitz.open(filepath)
if not is_image_pdf(doc):
# Native text — no OCR needed
return '\n'.join(doc[i].get_text() for i in range(len(doc)))
print('Image PDF detected — running OCR')
all_text = []
for page_num in range(len(doc)):
page = doc[page_num]
# Render page as image at 300 DPI
mat = fitz.Matrix(300/72, 300/72) # scale to 300 DPI
pix = page.get_pixmap(matrix=mat)
img = Image.open(io.BytesIO(pix.tobytes('png')))
text = pytesseract.image_to_string(img)
all_text.append(f'--- Page {page_num+1} ---\n{text}')
doc.close()
return '\n'.join(all_text)Filtrowanie według pewności i przetwarzanie końcowe
Wyniki OCR zawierają błędy, szczególnie w przypadku obrazów o obniżonej jakości. Tekst należy przetworzyć końcowo, odfiltrowując słowa o niskim poziomie pewności, poprawiając typowe błędy OCR (0 zamiast O, 1 zamiast l) oraz normalizując odstępy.
import re
COMMON_OCR_ERRORS = {
r'\b0([a-z])\b': r'O\1',
r'\bl([0-9])\b': r'1\1',
r'\|': 'I',
r' +': ' ',
}
def post_process_ocr(text):
for pattern, replacement in COMMON_OCR_ERRORS.items():
text = re.sub(pattern, replacement, text)
lines = [line.strip() for line in text.splitlines()]
return '\n'.join(line for line in lines if line)
def high_confidence_ocr(words_with_conf, min_confidence=60):
words = [w for w, conf in words_with_conf if w.strip() and conf >= min_confidence]
return post_process_ocr(' '.join(words))
fake_ocr_output = [('0range', 90), ('|s', 40), ('l5', 85), ('good', 95)]
print(high_confidence_ocr(fake_ocr_output))Sprawdzenie wiedzy
What is the purpose of applying a threshold (binarization) to an image before OCR?
Podsumowanie: OCR dla zeskanowanych dokumentów
OCR przekształca zeskanowane obrazy w tekst możliwy do odczytania przez komputer. pytesseract jest nakładką na Google Tesseract — szybki i dojrzały silnik obsługujący ponad 100 pakietów językowych. EasyOCR korzysta z głębokiego uczenia i lepiej radzi sobie z obrazami o obniżonej jakości oraz tekstem wielojęzycznym.
Zawsze należy wykonywać wstępne przetwarzanie: konwertować obraz do skali szarości, stosować progowanie metodą Otsu w celu binaryzacji oraz prostować obraz, aby skorygować obrót. W przypadku plików PDF opartych na obrazach należy renderować strony jako obrazy o wysokiej rozdzielczości DPI za pomocą PyMuPDF, a następnie uruchamiać OCR. Wyniki należy filtrować według progu pewności, aby wykluczyć szum.
Często zadawane pytania
Czy lekcja „OCR dla skanowanych dokumentów” jest bezpłatna?
Tak — pełny tekst „OCR dla skanowanych dokumentów” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu AI Agents, przejdź na CoddyKit PRO. Kurs AI Agents zawiera 4 lekcji w sumie.
Co nauczysz się w „OCR dla skanowanych dokumentów”?
Tesseract za pośrednictwem pytesseract, wstępne przetwarzanie obrazów i poprawa dokładności. Ćwiczysz AI Agents z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć AI Agents?
Nie wymagamy żadnego doświadczenia. AI Agents w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.
Ile czasu zajmuje lekcja „OCR dla skanowanych dokumentów”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji AI Agents?
Tak. Każda lekcja AI Agents zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Parsowanie PDF za pomocą PyMuPDF i pdfplumber
- OCR dla skanowanych dokumentów
- Agenci pytań i odpowiedzi dla wielu dokumentów
- Klasyfikacja i routing dokumentów