When You Need OCR
There are plenty of situations that call for OCR: scanned PDFs, HWP files with embedded images, text inside charts, and more. Contextifier exposes multiple OCR engines through a unified interface.
OCR Module Architecture
graph TD
A[이미지 입력] --> B{OCR Engine}
B --> C[Tesseract]
B --> D[GPT-4o Vision]
B --> E[Claude Vision]
B --> F[Gemini Vision]
C --> G[텍스트 결과]
D --> G
E --> G
F --> G
G --> H[후처리]
H --> I[정제된 텍스트]
Why Use LLM Vision for OCR?
Traditional OCR (Tesseract) loses accuracy on Korean documents, especially with:
- Small text inside tables
- Mixed Korean–English text
- Handwriting or stamps
LLM Vision models maintain high accuracy even in these cases.
Implementation
class OCREngine:
def __init__(self, provider: str = "tesseract", **kwargs):
self.provider = provider
if provider == "llm_vision":
self.model = kwargs.get("model", "gpt-4o")
self.client = self._init_llm_client()
def extract_text(self, image_path: str) -> str:
if self.provider == "tesseract":
return self._tesseract_ocr(image_path)
elif self.provider == "llm_vision":
return self._llm_vision_ocr(image_path)
def _llm_vision_ocr(self, image_path: str) -> str:
# Encode the image as base64 and send it to the LLM
image_data = self._encode_image(image_path)
response = self.client.chat(
messages=[{
"role": "user",
"content": [
{"type": "text", "text": "이 이미지의 모든 텍스트를 정확히 추출해주세요."},
{"type": "image", "data": image_data}
]
}]
)
return response.text
Image Hashing System
To avoid redundant OCR on the same image, the module uses an image hashing system. In v0.1.5, the hash length was increased to 32 characters to reduce collision probability.
Performance Optimization Tips
- Batch processing: Handle multiple images in a single pass
- Caching: Cache results keyed by image hash
- Cost management: LLM Vision is expensive — try Tesseract first and fall back to an LLM only if the quality is insufficient
This module was developed intensively between 2025-01-15 and 2026-01-20.