OCR för skannade dokument
Tesseract via pytesseract, bildförbehandling och förbättring av träffsäkerheten.
OCR för skannade dokument är en gratis lektion i AI-agenter på CoddyKit. Detta är lektion 2 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för AI-agenter, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i AI-agenter innehåller totalt 4 lektioner.
När OCR behövs
Alla dokument är inte digitalt skapade PDF-filer. Skannade dokument, fotografier av text, handskrivna anteckningar och bildbaserade PDF-filer kräver Optical Character Recognition (OCR) för att text ska kunna extraheras.
OCR omvandlar pixlar som föreställer text till maskinläsbara tecken. Två ledande Python-bibliotek är pytesseract (Google Tesseract) och EasyOCR (djupinlärning, flera språk).
Grunderna i pytesseract
pytesseract är ett Python-omslag runt Googles OCR-motor Tesseract. Installera först Tesseract på operativsystemnivå och kör sedan 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}')Bildförbehandling: gråskala
OCR-precisionen beror i hög grad på bildkvaliteten. Det första förbehandlingssteget är att konvertera bilden till gråskala — färg tillför brus utan att hjälpa teckenigenkänningen.
Använd Pillow eller OpenCV för förbehandlingen. Gråskala minskar bruset och förbättrar Tesseracts detektering av teckengränser.
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])Bildförbehandling: tröskling
Tröskling konverterar en gråskalebild till rent svart och vitt. Det tar bort grå skuggor, ojämn belysning och bakgrundsbrus, så att texten framträder tydligt för 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])Bildförbehandling: räta upp bilden
Skannade dokument är ofta något roterade. Även en lutning på 2 grader minskar OCR-precisionen avsevärt. Genom att räta upp bilden identifieras och korrigeras rotationsvinkeln innan bilden skickas till OCR-motorn.
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 deskewTesseracts språkalternativ
Tesseract stöder fler än 100 språk. Hämta språkpaket med operativsystemets pakethanterare. För dokument på flera språk anger du flera språk med en +-avgränsare.
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: baserat på djupinlärning
EasyOCR använder modeller för djupinlärning och överträffar Tesseract på försämrade bilder, böjd text och icke-latinska skriftsystem. Det kräver ingen installation på operativsystemnivå.
Installera med pip install easyocr. Vid den första körningen hämtas modellvikter (~200MB).
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 för dokument på flera språk
EasyOCR hanterar dokument med blandade språk väl — vilket är användbart för internationella avtal, forskningsartiklar med bildtexter på flera språk eller dokument med tekniska termer i ett annat skriftsystem.
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
]Fullständig förbehandlingspipeline
Kedja ihop alla förbehandlingssteg — gråskala, tröskling och upprätning — i en enda pipeline-funktion. Kör OCR på den rensade bilden och returnera både texten och konfidensmåtten.
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])Hantera bildbaserade PDF-filer
Vissa PDF-filer innehåller skannade sidor som lagras som bilder inuti PDF-behållaren. Identifiera dessa ”bild-PDF-filer” och använd OCR sida för sida genom att först extrahera bilderna med 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)Konfidensfiltrering och efterbehandling
OCR-resultat innehåller fel, särskilt för försämrade bilder. Efterbehandla texten genom att filtrera bort ord med låg konfidens, korrigera vanliga OCR-fel (0 kontra O, 1 kontra l) och normalisera blanksteg.
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))Kunskapskontroll
Vad är syftet med att tillämpa en tröskel (binärisering) på en bild före OCR?
Sammanfattning: OCR för skannade dokument
OCR omvandlar skannade bilder till maskinläsbar text. pytesseract är ett omslag runt Google Tesseract — snabbt och moget, med språkpaket för fler än 100 språk. EasyOCR använder djupinlärning och hanterar försämrade bilder och flerspråkig text bättre.
Förbehandla alltid: konvertera till gråskala, använd Otsu-tröskling för binärisering och räta upp bilden för att korrigera rotation. För bildbaserade PDF-filer ska sidorna renderas som bilder med hög DPI med PyMuPDF, varefter OCR körs. Filtrera resultaten med ett konfidensgränsvärde för att utesluta brus.
Lär dig AI-agenter med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 60
- Lektioner
- 239
Vanliga frågor
Är lektionen ”OCR för skannade dokument” gratis?
Ja – hela texten till ”OCR för skannade dokument” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i AI-agenter, kan Ni uppgradera till CoddyKit PRO. Kursen i AI-agenter innehåller totalt 4 lektioner.
Vad lär jag mig i ”OCR för skannade dokument”?
Tesseract via pytesseract, bildförbehandling och förbättring av träffsäkerheten. Ni övar på AI-agenter med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig AI-agenter?
Du behöver inga förkunskaper. Utbildningen i AI-agenter på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 2 av 4.
Hur lång tid tar lektionen ”OCR för skannade dokument”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här AI-agenter-lektionen?
Ja. Varje AI-agenter-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Parsa PDF med PyMuPDF och pdfplumber
- OCR för skannade dokument
- Agenter för frågor och svar över flera dokument
- Dokumentklassificering och routing