Reseña de EasyOCR: muy buen rendimiento con texto limpio, un techo brusco por tamaño y un proceso CPU de 1 GB

Última actualización: August 17, 2026
Reseña de EasyOCR: muy buen rendimiento con texto limpio, un techo brusco por tamaño y un proceso CPU de 1 GB
Resumen con IA
EasyOCR es la biblioteca OCR lista para usar de JaidedAI para Python: pip install easyocr, dos líneas de código y el texto incrustado en una imagen vuelve convertido en cadenas. Tiene licencia Apache-2.0, presume compatibilidad con más de 80 idiomas y funciona como una canalización de dos modelos PyTorch: un detector CRAFT que dibuja cajas alrededor de lo que cree que es texto y, después, un reconocedor que lee los caracteres dentro de cada caja. Los pesos preentrenados se descargan automáticamente la primera vez que lo llamas. En la práctica, es una alternativa autogestionada a Tesseract y PaddleOCR, no una API OCR en la nube por página.

EasyOCR은 JaidedAI가 Python용으로 바로 쓸 수 있게 만든 OCR 라이브러리다: pip install easyocr, 코드 두 줄이면 이미지 안에 박혀 있던 텍스트가 문자열로 돌아온다. Apache-2.0 라이선스를 쓰고, 80개가 넘는 언어를 지원한다고 내세우며, 실제로는 PyTorch 모델 2개로 돌아가는 파이프라인이다. 먼저 CRAFT 감지기가 텍스트라고 판단한 영역 주변에 박스를 그리고, 그다음 인식기가 각 박스 안의 글자를 읽는다. 사전 학습 가중치는 처음 호출할 때 자동으로 내려받는다. 실무 관점에서는 페이지당 과금되는 클라우드 OCR API가 아니라, Tesseract나 PaddleOCR의 자가 운영 대안에 가깝다.

기본 API는 아주 짧다: Reader(['en'])를 만든 다음 readtext()를 호출하면 된다. 다만 배포 쪽은 더 무겁다. 이 환경에서는 PyTorch만 해도 약 2 GB였고, 깨끗한 프로세스 기준 최대 상주 메모리는 대략 1 GB였다. 영어 PNG fixture 36개를 렌더링해서 CPU에서 easyocr 1.7.2를 돌리고, 생성된 정답과 문자 단위로 비교했다. 크기와 방향이 CER 하락을 가장 크게 만들었고, 패널 테스트에서는 짧은 토큰 검출 실패와 달러 기호 인식 오류도 드러났다.

가장 분명한 실패는 모두가 추천하는 그 매개변수에서 나왔다. rotation_info는 회전된 이미지를 해결하는 만능 열쇠처럼 이슈 트래커에서 자주 언급돼서, 같은 문장을 직교 방향으로 세 번 돌린 이미지에 직접 시험해 봤다. 270°에서는 약속한 대로 CER를 0.83에서 0.10으로 크게 낮췄다. 180°에서는 절반 정도만 먹혔다: 0.85에서 0.67로 내려갔지만, 한 문장이 통째로 빠졌다. 90°에서는 오히려 역효과였다: 0.81에서 0.92로 악화했고, 인식기는 거울에 비춘 듯한 텍스트를 내놨다. 같은 매개변수, 같은 각도 목록인데 결과는 세 가지가 달랐다. 이걸 켠다고 해서 “회전 문제는 이제 끝”이라는 뜻은 절대 아니다. 같은 36개 fixture에서도 글자 크기 한계가 꽤 뚜렷했고, 달러 기호에 대한 체계적인 혼동, 그리고 내가 완전히 틀린 예측 하나도 확인됐다.

두 모델이 한 벌로 묶여 있다

EasyOCR은 하나의 모델이 아니다. 두 단계로 된 파이프라인이고, 어느 단계에서 실패했는지를 알면 디버깅 방식도 완전히 달라진다.

첫 번째 단계는 CRAFT, 즉 감지기다. 이 단계의 일은 오직 위치를 찾는 것이다. 이미지에서 텍스트가 어디 있는지 판단하고 박스를 돌려준다. 글자는 읽지 않는다. 두 번째 단계는 CRNN 인식기다. ResNet으로 특징을 뽑고, 그다음 BiLSTM을 거쳐, CTC의 greedy decoding으로 박스 안 글자를 읽는다. 둘 다 PyTorch 위에서 돌아간다. CPU에서는 인식기가 기본적으로 int8 동적 양자화를 쓰기 때문에, 파라미터 수만 보면 예상되는 것보다 더 빠르고 더 가볍다.

System diagram: Detection Before Recognition

실무적으로는 이 구조 때문에 EasyOCR의 실패도 두 종류로 갈린다. 하나는 감지기가 아예 박스를 못 그리는 경우고, 다른 하나는 박스는 있는데 문자열이 틀린 경우다. 첫 번째라면 인식기 설정을 아무리 바꿔도 소용없다. 글자가 파이프라인에 들어오지도 않았기 때문이다. 두 번째라면 인식이나 전처리 쪽에서 살릴 여지가 있다. 내가 읽은 “EasyOCR이 내 텍스트를 건너뛰었다”는 글 대부분은 이 둘을 섞어서 이야기하고 있었다.

2026년 7월 27일 기준으로 확인한 프로젝트 상태는 별 29,825개, 열린 이슈 528개, Apache-2.0 라이선스, 그리고 v1.7.2는 2024년 9월 버전이다. master에 대한 마지막 push는 2025년 12월이었다. 이 날짜들이 아키텍처 안정성이나 유지보수 건강 상태를 증명해 주는 건 아니다. 채택하기 전에 Python/PyTorch 스택과의 호환성, 최근 유지보수 반응 속도, 그리고 네 입력에 관련된 이슈를 꼭 확인해야 한다.

OCR은 종종 CAPTCHA 우회와 연결되지만, 여기서는 그 얘기가 아니다. anti-bot challenge를 상대로 뭘 해보지도 않았고, 자동화된 탐지를 피하는 방법을 이 분석이 정당화하지도 않는다. 여기서 다루는 건 당신이 읽을 권한이 있는 이미지와 스크린샷에서 텍스트를 읽는 일이다.

무엇을 측정했고, 이 숫자가 말해주지 않는 것

테스트 세트는 36개의 직접 생성한 PNG로 구성했다. 35개는 한 줄짜리 이미지로, 7개 글꼴, 8개 글자 크기, 7개 대비 수준, 7개 기울기, 3개 직교 회전, 3개 배경을 돌려 가며 만들었다. 나머지 하나는 개별 라벨이 붙은 19개 요소로 이루어진 패널의 합성 스크린샷이었다. 모든 이미지는 고정된 문자열(Sphinx of black quartz, judge my vow. 1234567890 — 48자, 대문자와 소문자, 숫자, 구두점 포함 —)에서 생성했고, 같은 단계에서 정답 라벨도 함께 썼기 때문에 이미지와 라벨이 물리적으로 분리될 수 없었다.

정확도는 **문자 오류율(CER)**로 잰다. 문자를 기준으로 한 Levenshtein 거리와 정답 길이를 나눈 값이다. CER 0은 완벽한 판독을 뜻한다. CER 0.10은 대략 열 글자 중 하나가 틀렸다는 의미다. 주요 결과는 대소문자에 민감한 CER로 제시하고, 대소문자 무시 버전도 함께 둔다. 왜냐하면 실제 “오류”의 상당수가 바로 대소문자에서 발생하기 때문이다.

숫자보다 더 중요한 건 한계다:

  • 영어만 사용. 인식기는 english_g2를 썼다. EasyOCR은 80개가 넘는 언어를 지원한다고 하지만, 나는 하나만 시험했다. 이 결과는 비라틴 문자에 대해서는 아무 말도 하지 못한다. 그런데 바로 그 영역이 OCR 학술 비교의 중심인 경우가 많다.
  • 합성 데이터만 사용. 사진이 아니라 렌더링된 텍스트다. 카메라 노이즈도, JPEG 아티팩트도, 조명도, 원근도 없다.
  • 손글씨 제외. 프로젝트 자체가 아직 지원하지 않는다고 말한다.
  • CPU만 사용. macOS arm64, gpu=False. 이 머신에는 MPS가 있었지만, EasyOCR은 CUDA가 아니면 CPU를 쓴다. GPU 성능은 아예 측정하지 않았으니 여기에는 GPU 수치가 없다.
  • 한 대의 기계, 한 버전. easyocr 1.7.2, torch 2.13.0, Python 3.12.

요약하면, 이것은 렌더된 라틴 문자에서 어디서 정확도가 무너지는지 보여주는 통제 실험이다. 실제 코퍼스 점수는 아니고, 대체할 수도 없다.

증거는 노트북 안에 숨겨 두지 않았다. fixture 생성기와 정확한 문자열은 tests/build_fixtures.pytests/fixtures/ground_truth.json에 있고, 인식·시간·자원 캡처는 tests/run_easyocr.py에 있다. tests/metrics.py는 원시 출력으로부터 보고된 오류율을 계산한다. 인식 로그와 집계 메트릭은 artifacts/raw/에 저장된다. 이 흐름을 다시 돌리면 이 머신과 이 버전을 검증할 수 있다. 그래도 모바일 사진, 다른 언어, 다른 레이아웃, 네 자체 전처리 체인에서 어떻게 동작할지는 알려주지 못하므로, 운영 반영 여부는 이 fixture만 믿지 말고 대표 입력을 따로 넣어 확인해야 한다.

하나 짚고 갈 함정이 있다. 이게 거의 잘못된 헤드라인을 만들 뻔했다. 처음 메트릭을 돌렸을 때, 깨끗한 검은 Arial에서 CER 0.375가 나왔다. 가장 쉬운 입력에서 이런 수치는 아주 나쁘다. 그런데 EasyOCR 탓이 아니었다. 감지기가 한 줄을 단어 박스와 숫자 박스로 나눴고, 내가 단순히 y 다음 x로 정렬해서 합치는 바람에 숫자가 앞에 와 버렸다. 수직 겹침 기준으로 줄 단위로 묶고, 그다음 왼쪽에서 오른쪽으로 읽도록 바꾸자 깨끗한 글꼴들은 0.04–0.10 정도로 떨어졌다. 직접 OCR 평가를 만든다면, 같은 함정이 너를 기다리고 있다.

설치: 패키지는 작고, 의존성은 크다

System diagram: Setup: the install is small, the dependency is not

pip install easyocr

끝이다. 그리고 이 말은 꽤 솔직하다. 패키지 자체는 단순하지만, 따라오는 건 PyTorch 약 2 GB다. 그다음 readtext()를 처음 호출하면 EasyOCR은 조용히 가중치를 ~/.EasyOCR/model/에 내려받는다. 총 93.7 MiB이며, CRAFT 감지기용 79.30 MiB (craft_mlt_25k.pth)와 영어 인식기용 14.44 MiB (english_g2.pth)로 나뉜다.

튜토리얼에는 잘 안 나오는 부분이다. 첫 실행에는 네트워크 접근이 필요하고 다운로드를 위해 멈춘다. 컨테이너 배포라면 이 가중치를 이미지에 포함시키거나, 콜드 스타트 때 내려받는 방식을 감수해야 한다. 캐시에 한 번 올라가면 그 뒤로는 오프라인으로도 동작한다.

Reader()의 초기 콜드 스타트 — 디스크에서 모델을 RAM으로 올리고 int8 양자화를 적용하는 과정 — 는 여러 번 실행했을 때 1.3–1.7초 걸렸다. 그 뒤에는:

import easyocr
reader = easyocr.Reader(['en'], gpu=False)
result = reader.readtext('screenshot.png')

이렇게 쓰면 된다. 두 줄이고, 설정할 것도 거의 없고, 체크포인트를 찾을 필요도 없다. 이름 속 “easy”는 이 단계에서는 충분히 납득된다. 불편함은 API가 아니라 의존성 무게에 있다.

깨끗한 텍스트의 바닥선: 글자는 거의 완벽, 대소문자는 아쉬움

시스템 글꼴 7개, 흰 바탕에 검은 글자, 32 px, 같은 문자열만 사용했다:

글꼴CER(대소문자 민감)CER(대소문자 무시)
Georgia0.06250.0000
Times0.04170.0417
Comic Sans0.04170.0208
Arial0.08330.0208
Verdana0.08330.0208
Impact0.08330.0208
Courier0.10420.0417
평균0.07140.0238

평균 CER는 0.071이고, 대소문자를 무시하면 0.024까지 내려간다. 여기서 핵심은 꽤 분명하다. EasyOCR은 깨끗한 라틴 텍스트에서 글자를 놓치는 게 아니라, 형태는 맞추고 대소문자는 틀린다는 점이다.

구체적으로는 여섯 글꼴에서 vow를 소문자 대신 VOW로 읽었고, Comic Sans만 Vow였다. Impact는 ofOf로도 바꿨다. 또 다른 반복 오류는 구두점이다. 문장 끝의 마침표가 여러 글꼴에서 :_로 돌아왔다. Georgia는 대소문자만 신경 쓰지 않으면 완벽한 판독이었다.

이건 꽤 쓸모 있다. 후단이 퍼지 매칭, 키워드 검색, 또는 언어 모델 입력이라면 대소문자 변화는 거의 공짜다. 반대로 정확한 문자열을 데이터베이스 키와 바로 비교한다면 얘기가 달라진다. 비교 전에 대소문자를 정규화하면 EasyOCR의 체감 오류 절반쯤은 사라진다.

Courier가 가장 나빴던 것(0.1042)도 납득된다. 고정폭 글꼴은 글자 사이 간격이 자연스럽지 않아서, 일반적인 문자 간격을 학습한 CTC 디코더에 더 불리하다.

크기 한계는 문서에 적힌 그대로다

Measured results chart: Character error rate by glyph height

readtext()에는 문서화된 매개변수 min_size=10이 있다. 감지된 박스 중 10픽셀보다 작은 것은 버린다. 대부분 이걸 그냥 넘어간다. 하지만 스크린샷이나 PDF를 뽑는 사람에게는 API에서 가장 중요한 숫자다. 렌더된 글자 높이를 바꿔 가며 시험한 결과는 이렇다:

렌더 픽셀 수CER무슨 일이 있었나
80.7708붕괴: 박스가 min_size 필터 아래로 떨어져 버려서 일부 조각만 남음
100.1458경계선: 딱 한계라서 감지기가 한 줄을 3개 박스로 쪼갬
120.0417회복
160.0000완벽한 판독
200.0208양호
280.0208양호
400.0625양호(다시 대소문자 변화가 등장)
640.0625양호(대소문자 변화)

12 px에서 8 px로 내려갈 때 CER가 0.04에서 0.77로 뛰는 건 점진적 악화가 아니다. 문서에 적힌 대로 정확히 동작하는 필터가 만든 결과다. 결국 대략 10 px 아래의 텍스트는 기본 설정에서 사실상 EasyOCR에게 보이지 않는다.

가장 좋은 구간은 12~28 px이고, 16 px에서는 CER 0이다. 40 px를 넘기면 CER가 조금 다시 오른다. 글자를 못 읽어서가 아니라 vowVOW 변화가 다시 나타나기 때문이다. 큰 텍스트가 더 어려운 게 아니라, 16 px가 잘 먹혔던 분리 효과가 사라질 뿐이다.

스크린샷에서 텍스트를 추출하는 사람이라면: 모델 탓하기 전에 글자 높이부터 확인해라. HiDPI 화면을 1×로 캡처했거나, PDF를 72 DPI로 래스터화했으면 본문 글자가 10 px 아래로 떨어지는 일이 흔하다. 2×로 캡처하거나 OCR 전에 다시 스케일링하면 “EasyOCR이 페이지 절반을 무시했다”는 류의 오류를 많이 피할 수 있다. 그게 어렵다면 min_size를 낮출 수는 있지만, 잡음도 같이 늘어날 각오는 해야 한다. 그 필터가 괜히 있는 게 아니기 때문이다.

회전: 10° 정도만 버티고, 보정은 비대칭이다

먼저 기울기부터 보자. 작은 각도, Arial 32 px, 기본 설정과 rotation_info=[90,180,270] 비교:

기울기 각도CER(기본)CER(rotation_info 사용)
0.08330.0833
0.04170.0417
10°0.02080.0833
15°0.29170.3750
20°0.75000.7708
30°0.89580.8750
45°0.89580.8750

EasyOCR은 기본 상태에서 대략 10° 정도의 기울기는 크게 흔들리지 않고 버틴다(CER ≤ 0.083). 15°쯤부터 무너지기 시작하고, 20° 정도면 거의 읽지 못한다. rotation_info는 기울기에는 아무 효과가 없다. 이유를 알면 당연하다. 이 매개변수는 네가 지정한 각도만 다시 시도할 뿐이고, 15° 기울기는 90, 180, 270이 아니기 때문이다. 10°에서는 오히려 조금 나빴다(0.021 → 0.083). 틀린 각도로 다시 시도한 결과가 신뢰도 투표에서 이겨 버릴 수 있기 때문이다.

직교 회전에서는 더 이상해진다:

회전CER(기본)CER(rotation_info 사용)복구됐나?
90°0.81250.9167아니오 — 더 나빠짐
180°0.85420.6667부분적
270°0.83330.1042

같은 매개변수, 같은 각도 목록, 세 가지 서로 다른 결과다.

270°에서는 rotation_info이슈 스레드에서 말하는 대로 정확히 작동한다. CER가 0.83에서 0.10으로 내려가며, 실제로 쓸 수 있는 판독이 된다. 180°에서는 절반만 성공한다. CER는 0.67로 좋아지지만, my vow. 문장이 통째로 사라진다. 90°에서는 오히려 역행한다. 0.81에서 0.92로 나빠지고, 원시 출력을 보면 이유가 보인다. 인식기가 거꾸로 읽은 문자열을 내놓는다. VOWMOA로 바뀌고, quartzzuuenb로 돌아온다. 거울에 비춰 읽으면 맞지만, 데이터 채널로는 쓸 수 없다.

이건 집계 메트릭이 아니라 원시 예측으로 확인했다. 처음에는 내가 박스 병합 순서를 잘못 짠 줄 알았기 때문이다. 하지만 그건 병합 아티팩트가 아니었다. EasyOCR이 실제로 그렇게 돌려줬다.

메커니즘은 가설일 뿐이고, 회전 컨벤션에 대한 별도 실험은 하지 않았다. Pillow는 양의 각도를 반시계 방향으로 렌더링하므로, 270°로 렌더된 이미지가 우연히 인식기가 잘 다루는 방향과 맞아떨어질 수 있다. 반면 90°에서는 가장 점수가 좋은 재시도가 뒤집힌 방향에 걸릴 수 있다. 원인이 무엇이든 운영상 교훈은 변하지 않는다:

이 fixture는 rotation_info가 서로 다른 방향에 대해 대칭적으로 동작한다고 가정하면 안 된다는 걸 보여준다. 입력에 맞는 회전 방향을 직접 검증해라. 필요하다면 상류 단계에서 방향 정규화를 해도 좋지만, 그걸 이 세 가지 예시만으로 “반드시 해야 하는 일”이라고 말할 수는 없다.

내가 틀렸던 예측

처음엔 저대비가 EasyOCR의 약점일 거라고 생각했다. 흰 바탕에 흐릿한 회색 글자는 전형적인 OCR 실패 사례다. 그리고 문서에는 그런 경우를 위한 복구 경로도 있다: contrast_ths=0.1adjust_contrast=0.5를 쓰면 저대비 박스를 다시 증폭한 버전으로 돌려 보고, 신뢰도가 더 높은 쪽을 고른다.

하지만 그 기능은 한 번도 발동하지 않았다. 필요가 없었기 때문이다.

전경 회색Weber 대비CER(기본)CER(adjust_contrast=1.0)
0 (검정)1.0000.08330.0833
640.7490.08330.0833
1100.5690.08330.0833
1500.4120.10420.1042
1800.2940.06250.0625
2000.2160.04170.0417
2200.1370.04170.0417

CER는 Weber 0.14, 즉 흰 바탕에 회색 220 수준까지도 깨끗한 구간을 벗어나지 않는다. 나는 그 텍스트가 있는지 확인하려고 눈을 가늘게 뜰 정도였다. 게다가 대비 증폭 컬럼은 전 구간에서 기본값과 완전히 동일했다. 기본 설정으로 이미 잘 읽혔기 때문이다.

배경도 같은 이야기를 했다. 검은 텍스트 기준:

배경CER
단색 연한 파란 패널0.083
세로 그라디언트0.021
가우시안 노이즈(μ200, σ22)0.000

이 세트에서 가장 시끄러운 fixture가 오히려 완벽한 판독을 보였다.

다만 범위는 좁다. 여기서 말하는 건 노이즈 없는 단색 저대비 이미지이지, 센서 노이즈와 JPEG 압축이 섞인 영수증 사진이 아니다. 이 테스트 세트에서는 기하학과 짧은 토큰이 가장 큰 실패를 만들었고, 색 변화와 합성 노이즈는 그렇지 않았다.

실제 사례: 패널 캡처에서 숫자 빼내기

이게 Python OCR 작업에서 가장 자주 나오는 유형이다. 누군가 내부 대시보드 스크린샷을 보내주거나, 차트로 가득한 분석 페이지를 대상으로 Python web scraping 파이프라인을 돌리는데 숫자는 렌더된 픽셀로만 존재하고, 너는 그 값을 데이터로 가져오고 싶다.

나는 어두운 헤더에 제목과 원형 아바타 배지, KPI 패널 3개, 버튼 3개, 2×3 표로 구성된 “Sales Dashboard” 창을 렌더링했고, 19개 텍스트 요소를 정확한 문자열과 픽셀 박스와 함께 라벨링한 뒤, 박스 겹침을 기준으로 EasyOCR 출력과 매칭했다.

검출 재현율: 19개 중 16개. 놓친 3개는 다음과 같다:

  • 한 글자짜리 배지 "A"
  • 표 셀 "Q1"
  • 표 셀 "Q2"

반면 **"Q3"**는 잡혔다. 같은 글꼴, 같은 크기, 같은 열인데도 검출기는 두 글자 토큰 하나는 살리고 다른 두 개는 버렸다. 시각적으로 비슷한 셀들 사이에서 검출이 일관되지 않았다. 실행 결과가 결정적이었기 때문에, 이건 랜덤한 동전 던지기식 행동의 증거가 아니다. 관련된 캡처 품질 문제는 #460에 기록돼 있다.

잡힌 16개 요소에서는 텍스트가 거의 완벽했다. 평균 CER는 0.027이었고, 16개 중 13개가 완전 일치였다. 제목, 라벨, 버튼("Save", "Cancel", "Export CSV"), 열 머리글, 쉼표가 포함된 숫자 모두 CER 0였다. 1,284도 쉼표까지 정확히 읽혔다.

불완전한 3개 판독은 전부 같은 오류였다. 달러 금액:

정답EasyOCR 판독
$57,912S57,912
$18,330S18,330
$25,178S25,178
$12,004$12,004 (정상)

4개 중 3개의 달러 기호가 대문자 S로 바뀌었다. 눈으로 보면 비슷해 보일 수 있지만, 네 추출 결과의 통화 필드는 각각 한 글자 차이로 쓰레기가 된다. 그리고 순진한 float()는 모두 실패한다.

스크린샷 기반 파이프라인에 짧은 라벨이나 통화가 들어간다면, 리스케일링, 여백을 둔 크롭, 필드 기대값 제한, 기호 민감한 후처리 같은 완화책을 꼭 검증해야 한다. 이 글에서는 그 어떤 것도 평가하지 않았고, 처음 글자에 붙은 S를 무작정 고치는 정규식은 정상값까지 망가뜨릴 수 있다. 스키마와 검증 규칙이 그 수정을 안전하게 만들 때만 적용해라.

실행 비용은 어느 정도인가

같은 머신에서 잰 수치다(macOS arm64, CPU, 단일 호스트, 동시 부하 가능성 있음. 보편적 벤치마크라기보다 참고용으로 봐라):

지표
디스크상의 모델 가중치93.7 MiB (감지기 79.30 + 인식기 14.44)
깨끗한 CPU 프로세스의 최대 상주 메모리984.5 MiB
Reader() 콜드 스타트1.3–1.7초
깨끗한 48자 한 줄의 핫 레이턴시(p50)약 0.062초 (p25–p75: 0.059–0.067초, n=20)
detail=0 vs detail=1거의 동일 (중앙값 0.062 vs 0.063초)

진짜 비용은 94 MB짜리 가중치가 아니라, 작업 프로세스당 약 1 GB의 상주 메모리와 약 2 GB의 torch 설치 용량이다. 이게 컨테이너에 들어가느냐를 결정하는 숫자고, 보통 아무도 잘 말해주지 않는 숫자이기도 하다.

속도는 쉬운 케이스에서는 괜찮다. CPU에서 깨끗한 한 줄을 핫 상태로 0.1초도 안 걸려 처리하는 건 충분히 쓸 만하다. 하지만 그건 어디까지나 쉬운 케이스다: 짧고 대비가 높은 한 줄뿐이다. “EasyOCR이 CPU에서 수십 초 걸린다”는 식의 불만은 큰 문서와 여러 영역을 포함한 상황을 말하는데, 나는 그 상황을 재현하지 않았다. 다른 부하이기 때문이다. 여기서는 내 실험이 아니라, 그런 사례가 있다는 점만 인용한다.

작지만 꼭 깨고 가야 할 미신 하나: detail=0은 EasyOCR을 더 빠르게 만들지 않는다. 반환값에서 박스와 신뢰도 점수만 뺄 뿐이다. 계산은 이미 끝난 뒤다. 중앙값 차이는 1밀리초 수준인데, 이건 그냥 잡음이다.

장단점

장점

  • 렌더된 깨끗한 라틴 텍스트에서 문자 인식이 거의 완벽하다. 대소문자 민감 기준 평균 CER 0.071, 무시 기준 0.024, 16 px에서는 완전 무오류도 가능하다.
  • 진짜로 두 줄짜리 API다. Reader(['en'])readtext()만 호출하면 되고, 설정이나 모델 선택이 거의 없다.
  • 소문자 텍스트에서 흔히 말하는 것보다 대비에 훨씬 강하다. 깨끗한 텍스트는 Weber 0.14까지 무너지지 않았고, 색 배경·그라디언트·노이즈 배경도 성능을 깎지 않았다(가우시안 노이즈 fixture는 완전 판독).
  • 검출만 되면 스크린샷 요소에서도 거의 완벽하다. 평균 CER 0.027, 16개 중 13개 정확, 쉼표가 있는 숫자도 포함된다.
  • 결정적이다. 여기 나온 정확도 수치는 서로 완전히 독립적인 두 프로세스 실행에서 byte 단위로 같았고, 달라진 건 시간뿐이었다.
  • Apache-2.0이고 자가 운영 가능해서 공급자 사용료가 없다. 대신 연산, 메모리, 저장소, 큐 운영비는 직접 부담해야 한다.

단점

  • 문서화된 min_size=10 아래에서 크게 무너진다. 8 px에서는 CER 0.77. 작은 UI 텍스트는 기본 설정에서 사라진다.
  • 기울기 허용 범위는 대략 10°에서 끝나고 20° 부근이면 무너진다.
  • rotation_info는 대칭적인 교정이 아니다. 270°는 복구되지만, 180°는 절반만, 90°는 더 나빠지며 거울 텍스트를 돌려준다.
  • 감지기가 짧은 토큰을 놓친다. 한 글자 배지와 2글자 셀 두 개는 사라졌고, 똑같이 생긴 다른 셀 하나는 남았다.
  • 달러 기호가 금액에서 체계적으로 S로 바뀐다(4개 중 3개).
  • 프로세스당 상주 메모리 약 1 GB, torch 의존성 약 2 GB.
  • 최신 버전이 2024년 9월이다. 프로젝트는 활발히 바뀐다기보다 안정된 상태에 가깝다.

누가 써야 하고, 누가 피해야 하나

입력이 적당한 크기로 렌더된 깨끗한 수평 텍스트라면 EasyOCR을 검토해 볼 만하다. 예를 들면 스크린샷, UI, 래스터화된 PDF, 생성형 리포트 같은 경우다. 공급자 과금 없이 자가 운영되는 Python 파이프라인이 필요하다면 더 그렇다. 여기서 나온 영어 합성 데이터 결과는 그런 상황에 잘 맞는다. 사진, 손글씨, 다른 문자 체계는 별도 테스트가 필요하다.

다음 중 하나라도 해당하면 거리를 두는 편이 낫다. 사진 — 내 수치는 합성 렌더 텍스트 기준이라 카메라 노이즈, 원근, 조명에 대해 말해주지 않는다. 손글씨 — 프로젝트도 그걸 약속하지 않는다. 비라틴 문자 — EasyOCR은 80개 넘는 언어를 지원하지만, 나는 하나만 시험했다. 그런 영역에서는 합성 영어 스윕보다 공개된 학술 비교가 기준이어야 한다. 아무 방향이나 돌아간 입력 — 먼저 자체적인 방향 보정이 없다면. 메모리가 빠듯한 배포 환경 — 워커당 1 GB면 금방 쌓인다.

OCR을 고르기 전에 DOM과 네트워크 응답부터 확인해라. 필요한 값이 이미 구조화된 텍스트로 존재한다면, 그 소스를 뽑는 편이 OCR의 감지·인식 오류를 피할 수 있다. OCR은 픽셀이 유일한 표현 방식일 때 쓰는 도구다.

대안과 우리 스택에서의 위치

EasyOCR은 Apache-2.0이고 자가 운영 가능해서 공급자 요금은 없지만, 계산 비용과 운영 비용은 실제로 든다. PaddleOCR, Tesseract, 비전-언어 모델은 이 벤치마크에서 실행하지 않았으므로, 여기서는 그들과 직접 결론을 내리지 않는다.

가장 흥미로운 비교는 OCR끼리의 비교가 아니다. OCR을 아예 해야 하느냐는 질문이다.

내가 보는 스크린샷 추출 작업의 상당수는 사실 까다로운 웹페이지를 긁어내기 위한 비상수단이다. JavaScript로 그려진 표, 로그인 뒤 대시보드, 버티는 사이트 같은 것들이다. 캡처해서 OCR을 돌리는 건 가장 쉬워 보이지만, 이미 구조화된 텍스트를 버리고 더 나쁜 버전을 되찾기 위해 달러 기호 세금까지 내는 셈이 된다.

작성자 주: Thunderbit은 웹페이지 데이터 추출용 관리형 선택지다. 이 이미지 fixture들로는 테스트하지 않았다. 중요한 경계는 소스 표현 방식이다. 웹 데이터가 구조화된 텍스트로 존재하면 DOM/네트워크 추출을 쓰고, 픽셀이 유일한 소스일 때 OCR을 평가해라.

같은 벤치마크의 관련 읽을거리로는 오픈소스 스크래퍼 전체 비교, Crawl4AI 리뷰, 그리고 셀렉터가 잘 안 먹히는 페이지를 위한 AI 기반 추출 개요가 있다.

웹 데이터 추출을 위해 Thunderbit 사용해 보기

결론

EasyOCR을 써야 할까? 이미지가 곧고, 글자 높이가 최소 12픽셀이며, 라틴 문자를 읽는다면 그렇다. 그 범위 안에서는 꽤 잘한다. 깨끗한 텍스트에서 평균 CER 0.071, 대소문자 정규화 후 0.024, 16 px에서 무오류, 그리고 평판보다 훨씬 나은 대비 강인성을 보여 준다. API는 진짜로 두 줄짜리고, 출력도 결정적이다. 디버깅하는 파이프라인에서는 이게 생각보다 훨씬 중요하다.

그 범위를 벗어나면, 실패 방식도 구체적이고 배울 수 있는 형태로 나타난다. 10 px 아래 텍스트는 min_size 필터에서 사라진다. 20°를 넘는 기울기는 읽기를 망가뜨린다. rotation_info는 한 직교 방향은 고치고, 다른 하나는 절반만 고치고, 세 번째는 거울 텍스트를 돌려주며 더 나쁘게 만든다. 한 글자와 두 글자 토큰은 감지기에서 빠지고, 이웃은 살아남는다. 달러 기호는 S로 바뀐다.

이 fixture들의 실패는 두 단계 모두에서 나왔다. 기하학 쪽에서는 박스를 놓치거나 방향이 틀렸고, 인식 쪽에서는 달러 기호가 헷갈렸다. 리스케일링, 방향 정규화, 여백을 둔 크롭, 스키마를 아는 기호 복구는 모두 검증해야 할 후보지, 결코 만능 안전장치가 아니다.

다만 나처럼 평가 하네스를 망가뜨린 채 이해도 못 하는 숫자를 붙잡고 시험하지는 마라. 네 own fixture를 만들고, 정답을 정확히 알고, 네 데이터의 절벽이 어디인지 직접 찾아라.

웹 데이터 추출을 위해 Thunderbit 사용해 보기 Get Started Free

자주 묻는 질문

EasyOCR은 스크린샷 텍스트를 실무에서 뽑을 만큼 정확한가? 합성 패널에서는 매칭된 요소들의 평균 CER가 0.027이었고, 16개 중 13개가 정확했다. 하지만 19개 요소 중 3개는 검출되지 않았고, 달러 기호 4개 중 3개가 S로 바뀌었다. 이런 정도가 허용 가능한지, 또 리스케일링이나 스키마 인식 후처리가 도움이 되는지는 실제 레이아웃에서 시험해야 한다.

EasyOCR이 읽을 수 있는 최소 글자 크기는 얼마인가? 실제로는 렌더된 글자 높이 기준 약 12픽셀 정도다. readtext()min_size=10은 10 px보다 작은 박스를 버리고, 효과는 완만한 하강이 아니라 절벽에 가깝다. 8 px에서 CER 0.77, 10 px에서 0.15, 12 px에서 0.04, 16 px에서 0이었다. 내 스윕에서 깨끗한 구간은 12–28 px였다. HiDPI 화면을 1×로 캡처했거나 PDF를 72 DPI로 래스터화했다면, min_size를 낮추기보다 OCR 전에 다시 스케일링해라. 그 필터는 잡음 박스를 억제하려고 있는 것이다.

rotation_info가 EasyOCR의 회전 이미지를 고쳐 주나? 신뢰할 수 있게, 그리고 대칭적으로는 아니다. 같은 문장을 직교 방향으로 세 번 회전한 이미지에 rotation_info=[90,180,270]를 줬더니, 270° 이미지는 깔끔하게 복구됐고(CER 0.83 → 0.10), 180°는 절반만 복구됐으며(0.85 → 0.67, 문장 하나 누락), 90°는 오히려 악화됐다(0.81 → 0.92) — VOWMOA처럼 거울 텍스트가 나왔다. 게다가 이 매개변수는 작은 기울기에는 아무 효과가 없는데, 지정한 각도만 다시 시도하기 때문이다. EasyOCR에 맡기기 전에 방향을 먼저 보정해라.

EasyOCR은 메모리와 디스크를 얼마나 쓰나? 모델 가중치는 93.7 MiB이고, 첫 사용 시 ~/.EasyOCR/model/에 내려받는다. 감지기 79.30 MiB, 영어 인식기 14.44 MiB다. 측정한 깨끗한 CPU 프로세스의 최대 상주 메모리는 984.5 MiB였고, torch 설치 용량은 약 2 GB였다. Reader()의 콜드 스타트는 1.3–1.7초, 이후 깨끗한 한 줄은 이 머신에서 p50 약 0.062초였다. detail=0은 응답 모양만 바꾸고, 측정된 시간은 바꾸지 않았다.

EasyOCR은 상업적 사용이 무료이고 아직 유지보수되나? 라이선스는 Apache-2.0이라 상업적 사용에 허용적이다. 2026년 7월 27일 기준으로 저장소에는 별 29,825개, 열린 이슈 528개가 있고, 최신 버전은 2024년 9월의 v1.7.2, master에 대한 마지막 push는 2025년 12월이었다. 폐기됐다기보다 안정된 상태로 읽는 게 맞다. 아키텍처는 크게 바뀌지 않았고, 활동은 이슈 트래커 쪽으로 옮겨 갔다. 실제로 쓰기 전에 라이선스와 버전 상태를 직접 확인해라.

Ke
Ke
CTO en Thunderbit | Científico de datos sénior y experto en ML Con casi una década de experiencia en aprendizaje automático y ciencia de datos, Ke Shen es exalumno de la Universidad de Columbia y antiguo científico de datos sénior en Walmart Labs. Con una sólida experiencia, reconocida por sus pares, en Python, R, Java y estadística, comparte conocimientos probados en el campo sobre cómo llevar algoritmos complejos de IA desde la teoría hasta una arquitectura lista para producción.
Tabla de contenidos
Thunderbit · Agente de datos web con IA

Extrae datos de cualquier página en 1 clic

Con la confianza de más de 250,000 usuarios
plan gratuito disponible
De la página web a la hoja de cálculo
Describe lo que necesitas: el agente de IA de Thunderbit lo extrae y lo exporta a Excel, Google Sheets, Airtable o Notion. Empieza gratis.
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week