0Pricing
AI Agents · 강의

스캔 문서를 위한 OCR

pytesseract를 통한 Tesseract 사용, 이미지 전처리, 정확도 향상을 다룹니다.

스캔 문서를 위한 OCR은(는) CoddyKit의 무료 AI Agents 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 AI Agents 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. AI Agents 강의에는 총 4개의 강의가 포함되어 있습니다.

OCR이 필요한 경우

모든 문서가 디지털 방식으로 생성된 PDF인 것은 아닙니다. 스캔한 문서, 텍스트를 촬영한 사진, 손글씨 메모, 이미지 기반 PDF에서 텍스트를 추출하려면 광학 문자 인식(Optical Character Recognition, OCR)이 필요합니다.

OCR은 텍스트가 포함된 픽셀 이미지를 기계가 읽을 수 있는 문자로 변환합니다. 대표적인 두 파이썬 라이브러리는 pytesseract(Google Tesseract)와 EasyOCR(딥 러닝 기반, 다국어 지원)입니다.

pytesseract 기초

pytesseract는 Google의 Tesseract OCR 엔진을 위한 Python 래퍼입니다. 먼저 Tesseract를 OS 수준에서 설치한 다음 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}')

이미지 전처리: 회색조 변환

OCR의 정확도는 이미지 품질에 크게 좌우됩니다. 첫 번째 전처리 단계는 회색조로 변환하는 것입니다. 색상은 문자 인식에 도움이 되지 않으면서 노이즈만 추가합니다.

전처리에는 Pillow 또는 OpenCV를 사용하세요. 회색조 변환은 노이즈를 줄이고 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])

이미지 전처리: 임계값 처리

임계값 처리는 회색조 이미지를 순수한 흑백 이미지로 변환합니다. 이렇게 하면 회색 그림자, 고르지 않은 조명, 배경 노이즈가 제거되어 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])

이미지 전처리: 기울기 보정

스캔한 문서는 약간 기울어져 있는 경우가 많습니다. 2도만 기울어져도 OCR 정확도가 크게 떨어집니다. 기울기 보정은 이미지를 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 deskew

Tesseract 언어 옵션

Tesseract는 100개가 넘는 언어를 지원합니다. OS 패키지 관리자를 사용해 언어 팩을 다운로드하세요. 다국어 문서에서는 + 구분자로 여러 언어를 지정하세요.

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: 딥 러닝 기반

EasyOCR는 딥 러닝 모델을 사용하며, 품질이 저하된 이미지, 곡선형 텍스트, 라틴 문자가 아닌 문자 체계에서 Tesseract보다 뛰어난 성능을 보입니다. OS 수준의 설치가 필요하지 않습니다.

pip install easyocr로 설치하세요. 처음 실행할 때 모델 가중치(약 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 사용하기

EasyOCR는 언어가 섞인 문서를 잘 처리합니다. 따라서 국제 계약서, 여러 언어로 캡션이 작성된 연구 논문, 다른 문자 체계의 기술 용어가 포함된 문서에 유용합니다.

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
    ]

전체 전처리 과정

회색조 변환, 임계값 처리, 기울기 보정 등 모든 전처리 단계를 하나의 처리 함수로 연결하세요. 정제된 이미지에서 OCR을 실행하고 텍스트와 신뢰도 지표를 모두 반환하세요.

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])

이미지 기반 PDF 처리하기

일부 PDF는 PDF 컨테이너 내부에 이미지로 저장된 스캔 페이지를 포함합니다. 이러한 '이미지 PDF'를 감지한 후, 먼저 PyMuPDF를 사용해 이미지를 추출하고 페이지별로 OCR을 적용하세요.

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)

신뢰도 필터링 및 후처리

OCR 결과에는 특히 품질이 저하된 이미지에서 오류가 포함됩니다. 신뢰도가 낮은 단어를 필터링하고, 일반적인 OCR 오류(0과 O, 1과 l)를 수정하며, 공백을 정규화해 텍스트를 후처리하세요.

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))

지식 확인

OCR 전에 이미지에 임계값 처리(이진화)를 적용하는 목적은 무엇입니까?

복습: 스캔 문서를 위한 OCR

OCR은 스캔한 이미지를 기계가 읽을 수 있는 텍스트로 변환합니다. pytesseract는 Google Tesseract를 감싼 도구로, 100개가 넘는 언어 팩을 지원하며 빠르고 성숙한 기술입니다. EasyOCR는 딥 러닝을 사용하며 품질이 저하된 이미지와 다국어 텍스트를 더 잘 처리합니다.

항상 전처리를 수행하세요. 회색조로 변환하고, 이진화를 위해 Otsu 임계값 처리를 적용하며, 회전을 바로잡도록 기울기를 보정하세요. 이미지 기반 PDF의 경우 PyMuPDF로 페이지를 높은 DPI의 이미지로 렌더링한 다음 OCR을 실행하세요. 신뢰도 임계값으로 결과를 필터링해 노이즈를 제외하세요.

자주 묻는 질문

“스캔 문서를 위한 OCR” 강의는 무료인가요?

네 — “스캔 문서를 위한 OCR” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 AI Agents 강의 전체를 잠금 해제할 수 있습니다. AI Agents 강의에는 총 4개의 강의가 포함되어 있습니다.

“스캔 문서를 위한 OCR”에서 뭘 배우나요?

pytesseract를 통한 Tesseract 사용, 이미지 전처리, 정확도 향상을 다룹니다. 브라우저에서 직접 실행하는 실습 코드로 AI Agents을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

AI Agents을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 AI Agents은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.

“스캔 문서를 위한 OCR” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 AI Agents 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 AI Agents 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. PyMuPDF 및 pdfplumber로 PDF 파싱
  2. 스캔 문서를 위한 OCR
  3. 다중 문서 질의응답 에이전트
  4. 문서 분류 및 라우팅
← AI Agents(으)로 돌아가기