심층 분석

OCR 심층 분석: 컴퓨터가 이미지에서 텍스트를 읽는 방법

koboshiCo-founder
·16분 읽기
OCR 심층 분석: 컴퓨터가 이미지에서 텍스트를 읽는 방법
요약

컴퓨터에게 문서 사진은 단지 색상 픽셀의 격자일 뿐이다. 그 픽셀을 검색 및 편집 가능한 텍스트로 바꾸려면 이미지 전처리, 레이아웃 분석, 문자 인식을 아우르는 파이프라인이 필요하며, 각 단계마다 수십 년간의 연구가 축적되어 있다. 이 글은 Otsu 이진화부터 Vision Transformer까지 OCR의 전 과정을 해설한다.

아무 이미지나 헥스 에디터로 열어보자. 거리 표지판 사진, 영수증, PDF 스크린샷. 오프셋 0에는 포맷 헤더가 있다. 몇 킬로바이트 지나면 픽셀 데이터가 나온다. RGB로 픽셀당 3바이트, (128, 52, 19)는 벽돌 벽이고 (240, 238, 220)은 종이일 수 있는 숫자 격자다. 그 격자 어딘가에 빨간 바탕에 흰색 Highway Gothic 폰트로 "STOP"이라고 쓰인 정지 표지판이 있다. 사람은 네 글자를 본다. 컴퓨터는 R 채널이 200 근처에서 맴돌고 G와 B가 40 아래로 떨어지는, 빨간색에 가까운 픽셀 값의 47 × 19 패치를 본다. 그 패치를 문자열 "STOP"에 대응시키는 것이 광학 문자 인식(Optical Character Recognition)이며, 1929년 Gustav Tauschek가 최초의 독서 기계 특허를 낸 이후로 줄곧 열린 연구 문제다.

OCR은 읽기가 믿기 어려울 정도로 쉽기 때문에 믿기 어려울 정도로 어렵다. 여섯 살 아이라면 다양한 폰트, 다양한 크기, 고르지 않은 조명, 약간의 회전, 부분적 가림, 연필로 쓴 글씨에서도 문자 A를 알아볼 수 있다. 컴퓨터에는 파이프라인이 필요하다. 이미지를 정리하고, 텍스트 영역을 찾고, 문자나 글리프 시퀀스를 분할하고, 각각을 분류하는 것이다. 각 단계에는 실패 모드가 있고, 실패는 누적된다.

OCR이 어려운 이유

핵심 문제는 분류(classification) 자체가 아니다. 미리 분할된 28 × 28 문자 이미지를 62개 클래스(A–Z, a–z, 0–9)로 분류하는 것은 1990년대 LeNet으로도 99% 정확도로 해결할 수 있는 과제다. 어려운 부분은 분류기 이전의 모든 단계다.

폰트 변이. 문자 "g"는 최소한 네 가지 일반적인 구조 변형이 있다. 단층형(필기체), 이층형(대부분의 세리프 서체), Helvetica에서 볼 수 있는 루프-테일, Futura의 오픈-테일이다. Tahoma로 훈련된 모델은 Univers를 일정 비율로 잘못 읽는다. 실제 OCR은 수백 종의 서체와 더불어 일관된 획 구조(topology)조차 없는 필기체까지 다룬다.

기하학적 왜곡. 문서 사진은 평판 스캔과는 거리가 멀다. 영수증을 휴대폰으로 찍으면 원근 왜곡(perspective skew), 곡률(curvature), 불균일한 축척이 발생한다. 책등 근처의 텍스트는 휘어진다. 화이트보드 사진에는 촬영자의 그림자가 찍힌다. 10도 기울기는 표준 벤치마크에서 Tesseract의 정확도를 ~97%에서 85% 이하로 떨어뜨린다. 기울기 보정 알고리즘(Hough 선 검출, Radon 변환, 투영 프로파일 분석)은 그 손실의 일부를 회복하지만 전부는 아니다.

조명과 노이즈. 고르지 않은 조명은 균일한 배경을 그라데이션으로 만들어 전역 이진화(global thresholding)를 깨뜨린다. JPEG 압축 아티팩트는 날카로운 가장자리 주변에 링잉(ringing)을 만든다. OCR 관점에서는 글자 획 주변의 링잉이다. 저조도 센서의 소금-후추 노이즈(salt-and-pepper noise)는 빈 공간을 문장 부호처럼 보이는 어두운 픽셀로 채운다. 복사본을 다시 복사하면 얇은 획이 뭉개져 "rn"이 "m"으로, "cl"이 "d"로 합쳐진다.

레이아웃 복잡성. 문서에는 열, 캡션, 표, 머리글, 각주, 사이드바가 있다. 텍스트는 이미지 주위를 흘러간다. 어떤 언어는 오른쪽에서 왼쪽으로 쓴다. 또 어떤 언어는 같은 문단 안에서 방향을 섞는다. 읽기 순서(어떤 텍스트 블록이 어떤 블록 다음에 오는지)를 식별하는 것은 인식과는 별개의 레이아웃 분석 문제이며, 이를 잘못 파악하면 모든 문자가 올바르게 분류되었더라도 출력이 뒤죽박죽된다.

문맥적 모호성. 픽셀 패턴만 보면 "0"(숫자 0), "O"(대문자 O), "o"(소문자 o)는 많은 산세리프 폰트에서 동일하다. "1", "l", "I", "|"도 수직 획을 공유한다. 해상도는 또 다른 차원을 추가한다. 12픽셀 높이에서 "e"와 "c"는 3픽셀 너비의 수평 획 하나만 다르다. 인간 독자는 문맥을 통해 이를 해결한다. 기계는 통계적 또는 학습된 언어 모델로 같은 판단을 내려야 한다.

전통적인 OCR 파이프라인

딥러닝 이전에 OCR은 수작업으로 설계된 단계들의 연속이었다. 각 단계는 서로 다른 연구 그룹에 의해 독립적으로 개발되고 특정 유형의 열화에 맞춰 튜닝되었다. 파이프라인은 다음과 같았다.

원본 이미지 → 전처리 → 이진화 → 기울기 보정 → 레이아웃 분석
  → 문자 분할 → 특징 추출 → 분류
  → 후처리(언어 모델) → 텍스트 출력

전처리와 이진화

컬러 이미지는 그레이스케일로 변환된다. 노이즈 제거는 임계값 처리 전에 신호를 평활화한다. 중간값 필터(median filtering)는 소금-후추 노이즈를 처리한다. 가우시안 블러(Gaussian blur)는 센서 노이즈를 처리한다. 가장자리 보존이 중요할 때는 양방향 필터(bilateral filtering)가 사용된다.

이진화(binarization)는 그레이스케일 이미지를 흰색 배경에 검은 텍스트로 변환한다. 표준 알고리즘은 Otsu 방법(1979)이다. 전경과 배경 픽셀 분포 간의 클래스 내 분산(intra-class variance)을 최소화하는 임계값을 전수 탐색으로 찾는다. Otsu는 이중 모드 히스토그램(bimodal histogram)을 가정하는데(텍스트 픽셀은 한 강도에, 배경 픽셀은 다른 강도에 모인다), 이는 통제된 조명의 평판 스캔에는 잘 작동하지만 그림자가 있는 휴대폰 사진에서는 실패한다. 국부 적응형 방법(Sauvola, Niblack)은 이웃 통계에 기반해 픽셀마다 다른 임계값을 계산하며, 가장자리 근처의 아티팩트를 대가로 불균일한 조명을 처리한다.

기울기 보정과 레이아웃 분석

문서 기울기는 선을 찾아 감지한다. 가장자리 픽셀에 Hough 변환을 적용하거나, 문서를 각도 범위로 회전시켜 수평 투영 피크가 가장 날카로운 각도를 선택하는 투영 프로파일 분석(projection profile analysis)을 사용한다. 기울기 각도가 파악되면 아핀 변환(affine transform)으로 이미지를 다시 회전시킨다.

레이아웃 분석은 페이지를 텍스트 블록으로 분할한다. 고전적인 접근법은 연결 요소 분석(Connected-Component Analysis, CCA)으로 전경 픽셀 덩어리를 찾고, 근접성 기준으로 단어로 묶은 다음, 단어를 행으로, 행을 블록으로 묶는다. XY-cut 알고리즘은 수평 및 수직 투영을 따라 여백 간격을 찾아 페이지를 재귀적으로 분할하고 영역 트리를 만든다. 현대 구현은 하이브리드를 사용한다. CCA로 초기 블롭을 찾고, 학습된 모델로 각 블롭을 텍스트, 이미지, 표, 구분선으로 분류한다.

문자 분할

기계 인쇄 텍스트의 경우, 분할(segmentation)은 단어 이미지를 개별 문자로 자르는 것을 의미한다. 수직 투영 프로파일(열별 전경 픽셀 개수 히스토그램)은 문자 중심에서 피크를, 문자 경계에서 골짜기를 만든다. 이 방식은 두 문자가 맞닿거나 한 문자가 분리된 부분("i", "j", ":", "%")을 포함할 때까지 작동한다. 과분할(over-segmentation) 후 분류기 신뢰도에 기반한 병합이 한 가지 해결책이다. 또 다른 방법은 분할을 완전히 건너뛰고 단어 전체를 인식하는 것인데, 이것이 현대 시퀀스 기반 방식이 하는 일이다.

특징 추출과 분류

문자 이미지가 준비되면 분류기를 위해 수치적으로 기술해야 한다. 딥러닝 이전의 특징(feature)에는 다음이 포함되었다.

  • 원시 픽셀 값: 평탄화된 벡터(단순하지만 이동과 축척에 취약)
  • 조닝(Zoning): 문자 바운딩 박스를 N × N 그리드로 나누고 셀당 전경 픽셀 수를 세어 특징으로 사용
  • 그래디언트 기반 특징(HOG): 방향성 그래디언트 히스토그램(Histogram of Oriented Gradients)은 가장자리 방향을 포착하며 작은 이동에 강건
  • 스케일 불변 특징 변환(SIFT): 축척, 회전, 조명에 불변하는 키포인트를 감지하고 기술

분류기는 일반적으로 RBF 커널의 서포트 벡터 머신(SVM)이었으며, 폰트당 수만 개의 레이블링된 문자 이미지로 훈련되었다. 잘 튜닝된 SVM + HOG 파이프라인은 깨끗한 인쇄 텍스트에서 문자당 ~98% 정확도를 달성할 수 있었다. 같은 파이프라인에 노이즈가 있거나 기울어졌거나 필기된 입력을 넣으면 정확도는 70–80%로 떨어졌다.

Tesseract: HP 연구소에서 LSTM까지

Tesseract는 대표적인 오픈소스 OCR 엔진이다. 1980년대 HP Labs Bristol에서 박사 과정 프로젝트로 시작되어 2005년에 오픈소스로 공개되었고, 2006년부터 Google이 유지보수하고 있다. 그 아키텍처는 명확히 두 시대로 나뉜다.

버전 3: 고전적 파이프라인

Tesseract 3는 몇 가지 혁신을 더해 전통적인 파이프라인을 구현했다. 레이아웃 분석에는 탭 정지 감지(tab-stop detection) 알고리즘을 사용했는데, 단어 바운딩 박스를 정렬하여 열 경계를 찾는 방식으로, HP가 1990년대에 스캔하던 유형의 문서에 맞춰 튜닝된 실용적 휴리스틱이었다. 문자 분할에는 chopper/associator 로직을 사용했다. chopper는 단어 이미지를 후보 절단점으로 과분할하고, associator는 분류기 신뢰도와 사전을 사용하여 어떤 절단을 병합할지 결정했다.

분류기는 2-패스 시스템이었다. 첫 번째 패스(정적 분류기)는 최근접 이웃 검색(nearest-neighbor search)으로 분할된 블롭을 프로토타입(클러스터링된 훈련 샘플)과 매칭했다. 두 번째 패스(적응형 분류기)는 문서 자체로 파인튜닝하여 해당 이미지에 사용된 특정 폰트를 학습했다. 적응형 분류기는 효과를 발휘하는 데 대략 한 페이지 분량의 텍스트가 필요했는데, 이것이 Tesseract 3가 거리 표지판이나 캡션 같은 단일 단어 이미지에서 성능이 좋지 않았던 이유다.

Tesseract 3는 .traineddata 파일을 제공했다. 프로토타입 클러스터, 문자 집합 정의, 단어 빈도 사전, 혼동 가능한 문자 쌍을 매핑한 unichar 모호성 테이블을 포함하는 아카이브였다. 새로운 언어를 훈련하려면 정답 텍스트와 쌍을 이룬 텍스트 이미지를 Tesseract에 제공하고, 각 문자에 박스를 치고, 훈련 도구를 실행해야 했다. 언어당 여러 시간이 걸리는 과정이었다.

버전 4/5: LSTM으로 파이프라인 교체

Tesseract 4(2018)는 전체 인식 경로를 단일 LSTM 신경망으로 교체했다. LSTM은 텍스트 줄 이미지의 수직 슬라이스 시퀀스에 대해 작동하며, 각 슬라이스는 1픽셀 너비에 텍스트 줄 전체 높이다. 각 슬라이스는 양방향 LSTM 레이어 스택에 입력된다. 출력은 문자 확률 시퀀스이며, CTC(Connectionist Temporal Classification) 손실 함수가 가변 길이 출력 시퀀스를 정답 텍스트에 정렬한다. 사전 분할된 문자 위치가 필요하지 않다.

LSTM 모델은 chopper/associator 장치 없이도 가변 너비 문자, 맞닿은 문자, 폰트 변이를 처리한다. 텍스트 줄을 찾는 데는 여전히 Tesseract의 레거시 레이아웃 분석에 의존하지만, 줄 단위 인식은 엔드투엔드 뉴럴 방식이다. ICDAR 2017 벤치마크에서 Tesseract 4는 인쇄된 영어에서 4.4% 문자 오류율(CER)을 달성했으며, Tesseract 3의 7.2%와 비교된다. 훈련 과정은 레거시 박싱 도구에서 텍스트 줄과 트랜스크립션을 결합하는 방식으로 전환되었다. 여전히 지도 학습이지만 문자당이 아닌 줄당 하나의 레이블로 가능하다.

.traineddata 형식은 LSTM 모델 가중치(수 MB)를 레거시 데이터(사전, unichar 테이블)와 함께 단일 파일에 저장하도록 확장되었다. fast LSTM 모델을 처음부터 훈련하는 데는 약 100개 문자 클래스를 가진 라틴 스크립트 언어의 경우 최신 GPU로 대략 24시간이 걸린다. CJK 언어는 더 큰 문자 집합 때문에 더 오래 걸린다.

정확도 특성

Tesseract 5는 더 큰 훈련 코퍼스와 개선된 기본 매개변수로 버전 4를 개선했지만, 아키텍처는 동일하다. 정확도는 입력에 크게 의존한다.

입력 조건Tesseract 4 CERTesseract 5 CER
깨끗한 300 DPI 스캔, 영어, 단일 열2.1%1.8%
150 DPI 휴대폰 사진, 영어5.8%4.9%
혼합 폰트의 깨끗한 스캔7.3%6.1%
역사적 문서(불규칙한 활자)18.4%16.2%
필기체(IAM 데이터셋)28.7%26.3%

LSTM 모델은 버전 3의 폰트 민감도 문제 대부분을 제거했지만, 엔진은 여전히 낮은 해상도(200 DPI 이하에서는 LSTM의 픽셀 슬라이스 입력이 획 디테일을 잃는다), 필기 텍스트(모델이 인쇄 폰트로 훈련되었으며, 필기체는 근본적으로 다른 획 통계를 가진다), 복잡한 레이아웃(레이아웃 분석이 여전히 뉴럴 방식이 아닌 레거시 코드 경로다)에서 성능이 저하된다.

현대 딥러닝 접근법

학계에서 OCR은 2019년경 CTC + LSTM 패러다임을 넘어섰다. 현재 문헌을 지배하는 세 가지 아키텍처가 있다.

CRNN + CTC

합성곱 순환 신경망(Convolutional Recurrent Neural Network, CRNN)은 Shi 등이 2015년에 발표했으며, CNN 특징 추출기를 RNN 시퀀스 모델 및 CTC 디코딩과 결합한다. CNN은 이미지에서 공간적 특징을 추출하며, 본질적으로 Tesseract의 LSTM이 수작업으로 입력받던 것(수직 슬라이스 표현)을 학습한다. RNN은 추출된 특징 전반의 시퀀스 의존성을 모델링한다. CTC가 정렬을 처리한다. CRNN-CTC는 표준 베이스라인이 되었다. 엔드투엔드 훈련 가능, 좋은 일반화, 빠른 추론(GPU에서 줄당 ~20 ms).

Attention 기반 인코더-디코더

Attention 기반 모델은 기계 번역의 seq2seq 패러다임을 OCR에 적용했다. CNN 또는 비전 인코더가 이미지의 특징 맵을 생성한다. RNN 디코더는 한 번에 한 문자씩 출력 텍스트를 생성하며, 각 단계에서 특징 맵의 관련 공간 영역에 attention을 가한다. Attention 메커니즘은 CTC의 단조성 제약(monotonic constraint)을 제거한다. 언어 모델이 반복 패턴을 예상할 때 디코더가 이미지의 이전 부분으로 돌아갈 수 있지만, 이러한 유연성은 판독 불가능한 입력에 대해 환각(hallucination) 위험도 도입한다. Attention 기반 디코더는 깨끗한 인쇄 영어에서 ~1.5–3% CER을 달성하며, 긴 시퀀스와 불규칙한 레이아웃에서 CTC 전용 모델을 능가한다.

Vision Transformer (TrOCR, Donut)

TrOCR(Microsoft, 2021)은 Transformer 아키텍처를 OCR에 적용했다. 이미지를 패치로 분할하고, ViT(Vision Transformer) 인코더로 인코딩하며, Transformer 텍스트 디코더가 자기회귀적으로(autoregressively) 디코딩한다. 이는 OCR 전용으로 훈련된 표준 멀티모달 모델의 아키텍처다. TrOCR은 CNN 전처리, 명시적 언어 모델, 문자 수준 분할 없이 인쇄 텍스트에서 최첨단 결과(깨끗한 스캔에서 1% 미만 CER)를 달성한다.

Donut(NAVER, 2022)은 이 접근법을 문서 이해로 확장했다. 입력은 문서 이미지 전체이고, 출력은 시각적 특징에서 직접 추출된 구조화된 JSON으로, OCR → NLP 파이프라인을 완전히 건너뛴다. 이는 실제 애플리케이션에서 중요한 방식으로 OCR과 문서 파싱의 경계를 흐린다. 송장 총액, 여권 번호, 연구 논문의 표를 추출하는 것이 OCR + 정규식 + 휴리스틱이 아닌 단일 모델 호출이 된다.

성능 비교 (인쇄 영어, 깨끗한 300 DPI)

방식CER추론 속도(초당 줄)필요한 훈련 데이터
Tesseract 3 (고전적)7.2%~2 (CPU)~10만 문자 이미지
Tesseract 5 (LSTM)1.8%~15 (CPU)~50만 텍스트 줄
CRNN + CTC2.5%~120 (GPU)~200만 텍스트 줄
Attention seq2seq1.8%~60 (GPU)~200만 텍스트 줄
TrOCR (ViT + 디코더)0.8%~20 (GPU)~1천만 텍스트 줄
Donut (ViT + 디코더)1.2%~15 (GPU)~1천2백만 문서 이미지

Tesseract와 최고의 Transformer 모델 간 격차는 벤치마크상으로는 실재한다. 실제로는 대부분의 배포 시스템이 Tesseract에 깨끗하고 조명이 좋은 300 DPI 입력을 제공하기 때문에 격차가 좁아지며, 그 입력에서 1.8% CER은 55문자당 하나의 오류를 의미한다. 검색 인덱싱에는 허용 가능하지만, 법률 문서 트랜스크립트에는 부족하다.

비영어 OCR: 더 어려운 이유

영어 OCR은 해결된 문제다. 대문자 26자, 소문자 26자, 숫자 10자, 약간의 문장 부호로 약 70개 클래스다. 1990년대 LeNet의 용량으로도 충분히 감당할 수 있는 다중 클래스 분류 문제다. 세계의 나머지 문자 체계들은 덜 관대하다.

CJK: 문자 집합 폭발

중국어, 일본어, 한국어(CJK)는 문자 집합 크기만으로도 가장 어려운 OCR 도전 과제다. 중국어 간체는 약 3,500개의 상용 문자와 6,000개 이상의 일반 텍스트 문자를 사용한다. 중국어 번체는 또 다른 1,000개 이상의 변형을 추가한다. 일본어는 두 가지 음절 문자(히라가나, 카타카나: 각 46자)와 약 2,000개의 상용 한자에 라틴 영숫자까지 같은 문장에서 혼용한다. 한국어 한글은 음성학적으로 규칙적이지만(24개의 기본 자모가 음절 블록으로 결합), 시각적으로 밀집되어 있다. 하나의 블록은 최대 6개의 개별 자모 성분을 라틴 문자 두 개 정도의 공간에 압축할 수 있다.

CJK OCR 시스템은 인식을 70-way 분류로 취급할 수 없다. 일본어는 최소 4,000-way, 중국어 간체는 6,000-way, 중국어 번체는 10,000-way 이상의 분류다. softmax 출력 레이어만으로도 전체 라틴 스크립트 OCR 모델보다 더 많은 파라미터를 가진다. 훈련 데이터 필요량은 문자 집합에 비례한다. 수용 가능한 정확도를 위해 클래스당 ~100개의 레이블링된 샘플이 필요하므로, 중국어 훈련 세트는 60만 텍스트 줄 이미지에서 시작한다.

Tesseract는 CJK traineddata 파일(chi_sim, chi_tra, jpn, kor)을 제공하지만, 라틴 모델보다 훨씬 크다. chi_sim.traineddata는 ~50 MB인 반면 eng.traineddata는 ~15 MB이며, 출력 공간이 더 크기 때문에 인식 속도도 느리다. 깨끗한 인쇄 CJK 텍스트에서 Tesseract 5의 정확도는 2–5% CER로, 동등한 조건에서 영어 오류율의 약 2–3배다.

아랍어와 오른쪽에서 왼쪽으로 쓰는 문자

아랍어는 문자 집합(단어 내 위치에 따라 형태가 변하는 문맥형을 가진 28자) 외에 두 가지 문제를 추가한다. 첫째, 오른쪽에서 왼쪽으로 쓰기 때문에 OCR 엔진이 텍스트 방향을 감지하고 출력 순서를 반전시켜야 한다. 둘째, 아랍어는 필기체(cursive)다. 단어 내 문자들은 베이스라인 획으로 연결되기 때문에, 대체로 분리된 문자 형태를 가진 라틴 및 키릴 문자보다 분할이 본질적으로 더 어렵다. 아랍어 단어 이미지는 하나의 연속된 블롭이다. 문자 기반 분할은 사실상 불가능하며, 이것이 LSTM/CTC 접근법(문자 분할 없이 단어 이미지에서 작동)이 영어 OCR보다 아랍어 OCR에서 더 큰 돌파구였던 이유다.

히브리어, 우르두어, 페르시아어, 파슈토어도 이러한 도전 과제의 일부 조합을 공유한다. Tesseract는 아랍어 traineddata를 제공하지만, 깨끗한 인쇄 텍스트에서 정확도는 약 5–8% CER로, 동일 조건에서 영어보다 약 4배 나쁘다.

인도계 문자: 결합자(conjunct) 문제

데바나가리(힌디어, 마라티어, 네팔어) 및 기타 브라흐미계 문자는 독특한 도전 과제를 제시한다. 쓰기 단위가 문자가 아니라 결합자(conjunct), 즉 자음, 모음 수정자, 그리고 때로는 추가 자음이 시각적으로 융합된 클러스터다. 유니코드 데바나가리 블록은 128개의 코드 포인트를 가지지만, 가능한 결합자의 수는 1,000개를 넘는다. "시로레카(shirorekha, 단어의 문자들을 연결하는 수평 헤드라인)"는 헤드라인이 인접 문자를 하나의 시각적 단위로 병합하기 때문에 분할을 더 어렵게 만든다.

Tesseract의 힌디어 traineddata(hin)는 일반적인 결합자를 커버하지만, 인쇄 텍스트에서 정확도는 영어보다 3–4배 뒤진다. 타밀어, 텔루구어, 벵골어 및 기타 인도 언어들은 지원이 덜하며, 일부는 공식 traineddata 파일이 전혀 없다. 근본 원인은 훈련 데이터의 양이다. 힌디어의 고품질 주석 텍스트 줄 이미지는 수백만 개 존재하지만, 칸나다어의 가용 데이터셋은 수만 개 수준이다.

수직 텍스트와 혼합 방향 레이아웃

일본어와 중국어 번체는 때때로 세로쓰기로 설정되며, 줄은 위에서 아래로, 열은 오른쪽에서 왼쪽으로 진행된다. Tesseract의 레이아웃 분석은 가로쓰기를 가정한다. 세로 텍스트는 사전 회전 또는 별도 엔진이 필요하다. 일본 신문과 만화에서 흔한 동일 페이지 내 가로 및 세로 텍스트 혼합은 단일 방향 가정을 완전히 깨뜨리며, 인식 전에 영역별 방향 감지가 필요하다.

소수 언어와 훈련 데이터

화자 1천만 명 미만의 언어의 경우, 고품질 OCR 훈련 데이터는 거의 존재하지 않는다. 유니코드 컨소시엄은 150개 이상의 문자 체계를 인코딩했지만, Tesseract가 제공하는 traineddata는 약 120개 언어이며, 그중 상당수는 깨끗한 배경에 표준 폰트로 렌더링된 합성 텍스트로 생성되었다. 합성 데이터는 일반 폰트의 인쇄 텍스트에는 작동하지만, 해당 언어의 실제 문서에서 발견되는 폰트, 종이, 인쇄 품질에서는 실패한다. 300 DPI의 합성 Arial로 훈련된 모델은 1970년대 타자기로 작성된 암하라어 문서를 읽지 못할 것이다.

Tesseract.js를 이용한 브라우저 측 OCR

브라우저에서 OCR을 실행하는 것은 WebAssembly가 출시되기 전까지 실용적이지 않았다. Tesseract.js는 Tesseract 5(LSTM)를 Emscripten을 통해 WebAssembly로 컴파일하며, 인식 작업당 Web Worker를 실행하는 JavaScript API로 C++ 엔진을 감싼다. 엔진, 언어 데이터, 워커는 정적 자산에서 로드된다. 이미지 데이터에 대한 서버 왕복이 없다.

API 표면은 직관적이다. 하나 이상의 언어 코드로 워커를 생성하고, 이미지를 제공하면, 문자별 신뢰도 점수와 함께 인식된 텍스트를 반환받는다. 가용 CPU 코어 수에 따라 여러 워커를 병렬로 실행할 수 있다. 일반적인 소비자 노트북에서는 약 4개의 병렬 인식 작업, 최신 휴대폰에서는 6–8개다.

성능은 세 가지 요소에 의해 제한된다. 첫째, WebAssembly는 네이티브 속도의 약 50–70%로 실행된다. 네이티브 Tesseract에서 100 ms 걸리는 텍스트 줄이 브라우저에서는 약 160 ms 걸린다. 둘째, traineddata 파일은 네트워크를 통해 로드된다. eng.traineddata는 ~15 MB, chi_sim.traineddata는 ~50 MB이며, 인식이 시작되기 전에 모두 완전히 다운로드되어야 한다. 셋째, 이미지 디코딩(JPEG/PNG/WebP/HEIC에서 원시 픽셀 데이터로)은 브라우저의 내장 디코더를 사용하는데, 빠르지만 형식과 기기에 따라 다르다.

프라이버시 이점은 구조적이다. 클라이언트 측 OCR은 이미지가 기기를 떠나지 않음을 의미한다. 여권 사진, 은행 명세서, 의료 기록. 픽셀은 브라우저에서 디코딩되고, Textract에 해당하는 것이 Web Worker에서 실행되며, 결과는 사용자가 복사하거나 저장할 수 있는 텍스트 문자열이다. 이미지를 처리하는 데이터 센터는 없다. 이는 기능이 아니라 서버의 부재이며, "보지 않겠다"고 약속하는 개인정보 처리방침과는 범주적으로 다르다.

저희 이미지를 텍스트로 도구는 바로 이 스택을 실행한다. LSTM 인식의 Tesseract.js, 병렬 처리를 위한 Web Workers, 12개 언어(영어, 스페인어, 프랑스어, 독일어, 포르투갈어, 이탈리아어, 중국어 간체 및 번체, 일본어, 한국어, 힌디어, 러시아어)에 대한 traineddata. 사진을 드롭하고 언어를 선택하면 텍스트를 얻을 수 있다. 이 도구는 JPEG, PNG, WebP, BMP, GIF 입력을 읽고, 해상도 인식 사전 스케일링(긴 쪽 3,000픽셀 초과 이미지는 인식 지연 시간을 합리적으로 유지하기 위해 축소)을 적용하며, 이미지별 평문 텍스트와 문자별 신뢰도를 출력한다.

이미지 형식 선택은 실제 OCR 품질에 영향을 미친다. iPhone의 HEIC 사진은 OCR 전에 JPEG로 변환하면 텍스트 가장자리 주변에 압축 아티팩트가 생겨 인식 정확도가 감소한다. HEIC를 먼저 PNG로 변환하면(무손실, 양자화 아티팩트 없음) LSTM이 의존하는 날카로운 가장자리가 보존된다. 저희 HEIC를 JPG로HEIC를 PNG로 변환기는 이 전처리 단계를 브라우저에서 직접 처리한다. 마찬가지로, 저조도에서 찍은 사진은 임계값 처리 전에 전체 톤 범위를 보존하는 형식으로 변환하면 이점이 있다. JPG를 PNG로는 JPEG 소스를 재인코딩할 때 누적되는 2세대 JPEG 아티팩트를 피한다.

브라우저 OCR 스택은 처리량 측면에서 GPU 가속 서버 측 모델과 경쟁할 수 없다. 네이티브 C++로 32 CPU 코어에서 Tesseract를 실행하는 서버가 항상 브라우저 탭보다 빠르다. 프라이버시, 인프라 제로, 요청당 비용 제로라는 점에서 승리한다. 몇 페이지, 영수증 한 장, 표지판 몇 개를 스캔하는 경우, 200 ms와 50 ms의 지연 시간 차이는 체감되지 않는다.

OCR의 미래

OCR은 2022년경 독립적인 연구 분야로서의 정체성을 멈추고 더 넓은 문서 AI 및 멀티모달 모델 공간에 통합되었다. 세 가지 전환이 진행 중이다.

멀티모달 LLM을 제로샷 OCR로 사용. GPT-4V, Claude, Gemini는 명시적인 OCR 훈련 없이도 이미지에서 텍스트를 읽을 수 있다. 문서 사진을 주고 텍스트를 요청하면 모델이 반환한다. 전용 OCR 헤드가 있어서가 아니라, 수십억 개의 이미지-텍스트 쌍 훈련에서 텍스트 인식이 발현(emerge)되기 때문이다. 품질은 균일하지 않다. 깨끗한 인쇄 영어에서 GPT-4V는 ~1% CER을 달성하여 파인튜닝된 TrOCR과 비슷하다. 저해상도 휴대폰 중국어 영수증 사진에서는, 픽셀 수준 증거에만 의존하지 않고 문맥을 활용(영수증이 어떻게 생겼는지, 어떤 숫자를 예상해야 하는지 알기 때문)하므로 Tesseract를 능가할 수 있다. 필기체에서는, 훈련 분포에 충분한 필기 이미지가 포함되지 않아 파인튜닝된 인식기보다 성능이 떨어진다.

트레이드오프는 비용과 지연 시간이다. OCR을 위한 GPT-4V API 호출은 토큰 수에 따라 페이지당 1–3센트, 1–3초가 소요된다. Tesseract는 로컬에서 100–500 ms에 실행되며 페이지당 비용이 들지 않는다. 200페이지 문서를 스캔할 때의 차이는 $2–6와 몇 분의 실제 대기 시간 대비 0달러와 1분 미만이다. 일회성 사용(영수증 한 장, 화이트보드 사진)의 경우, 멀티모달 모델이 더 간단하고 종종 더 정확하다.

온디바이스 추론. 서버 OCR을 구동하는 모델은 작아지고 있다. ONNX Runtime Web은 양자화된 CRNN과 소형 ViT 모델을 WebGPU 상에서 텍스트 줄당 50–100 ms로 브라우저에서 실행한다. Apple의 Vision 프레임워크는 iOS 및 macOS 기기에서 VNRecognizeTextRequest로 접근 가능한 소형 OCR 모델을 온디바이스로 제공하며, 네트워크 호출이 없다. "서버 GPU 모델"과 "브라우저 모델" 간의 격차는 좁혀지고 있다. 둘 다 동일한 아키텍처의 최적점, 즉 경량 디코더를 갖춘 소형 ViT 인코더(~20–50M 파라미터)에 INT8 또는 FP16으로 양자화된 형태로 수렴하고 있기 때문이다.

텍스트 변환(transcription)을 넘어 문서 이해로. OCR의 출력은 문자열이다. 대부분의 실제 작업은 그 문자열에서 구조화된 정보(송장 번호, 날짜, 총액, 이름, 주소)를 추출하는 것이다. 전통적인 접근법은 OCR을 정규식, 개체명 인식(NER), 스키마 매핑과 연결한다. 각 단계는 고유한 실패 모드를 가진 별도 모델이다. 엔드투엔드 문서 이해 모델(Donut, LayoutLMv3, Pix2Struct)은 OCR을 건너뛰고 문서 이미지를 구조화된 출력에 직접 매핑한다. 영수증으로 파인튜닝된 Donut 모델은 텍스트 트랜스크립트를 생성한 후 파싱하지 않는다. 픽셀 입력에서 직접 {"total": "42.50", "date": "2026-07-27", "vendor": "..."}를 생성한다. OCR 단계, 즉 이 글이 다루는 부분은 보이지 않는 구현 세부사항이 된다.

그렇다고 OCR이 쓸모없어지는 것은 아니다. 빌딩 블록이 되는 것이다. 파이프라인은 여전히 엣지 케이스를 처리해야 한다. 어두운 레스토랑에서 비스듬히 찍은 영수증, 누런 종이에 찍힌 50년 된 타자기 문서, 대규모 멀티모달 모델이 훈련되지 않은 언어의 표지판. 그러한 특정 분포에 훈련된 특화된 OCR 엔진은 수년간 범용 모델을 속도와 성능에서 능가할 것이다. 왜냐하면 인터넷 전체로 훈련된 범용 모델은 1970년대 암하라어 타자기 출력을 읽는 데 자체 용량의 극히 일부만 할당하기 때문이다.

OCR은 세계 대부분의 언어와 대부분의 실제 촬영 조건에서 해결된 문제가 아니다. 깨끗한 300 DPI, 영어, 단일 열, 기계 인쇄 텍스트 — 문제 공간의 가장 좁고 자금이 가장 풍부한 일부 — 에 대해서만 해결된 문제다. 나머지는 여전히 열려 있다.

더 읽을 블로그 글