이미지·텍스트 captcha OCR: 왜곡된 captcha 읽는 법
이미지 captcha는 짧은 문자열을 그림으로 보여주며, 때로는 노이즈, 회전, 물결 선이 함께 들어갑니다. 광학 문자 인식(OCR)은 Tesseract 같은 오픈소스 엔진으로 단순한 형태의 captcha를 읽을 수 있습니다. 정확도는 이미지가 얼마나 깨끗한지에 따라 달라지므로, 작업의 대부분은 전처리입니다. 이 가이드는 동작하는 Python 설정을 보여주고, 어디서 실패하는지 설명하며, 한 가지를 분명히 합니다. Scarnox의 실시간 API는 PopularCaptcha 위젯 토큰을 해결하며, 이미지-텍스트 captcha는 해결하지 않습니다. OCR은 API 호출이 아니라 직접 작성하는 코드로 계획하세요.
OCR이 작동할 때와 작동하지 않을 때
텍스트가 다음과 같을 때 OCR은 합리적인 첫 시도입니다.
- 한 줄에 있고 간격이 고르게 배치된 경우.
- 명암 대비가 높은 경우, 즉 밝은 배경에 어두운 글자인 경우.
- 심한 왜곡, 겹치는 문자, 교차하는 선이 없는 경우.
회전된 글자, 서로 맞닿은 글자, 배경 질감, 글리프를 가로지르는 선에서는 어려움을 겪습니다. 각각은 특정한 전처리 단계가 필요하고, 일부는 아예 다른 모델이 필요합니다. 정확도를 가정하지 말고 측정할 준비를 하세요.
도구 설치
Python, Tesseract 바이너리, 그리고 두 개의 Python 패키지가 필요합니다.
pip install pillow pytesseract
Tesseract는 별도로 설치해야 합니다. Windows에서는 Tesseract 프로젝트의 설치 프로그램을 사용하고, 실행 파일이 PATH에 있도록 하거나 pytesseract.pytesseract.tesseract_cmd가 그 파일을 가리키도록 설정하세요.
전처리한 뒤 읽기
정확도의 대부분은 깨끗한 입력에서 나옵니다. 아래 순서는 그레이스케일로 변환하고, 대비를 높이고, 강한 임계값을 적용하고, 이미지를 확대한 뒤, captcha가 사용하는 문자만 출력으로 허용합니다.
from PIL import Image, ImageOps
import pytesseract
# captcha가 사용할 수 있는 문자. captcha가 쓰지 않는다면 0/O, 1/I 같은 혼동되는 문자는 뺍니다.
ALLOWED = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789"
def read_text(path: str) -> str:
img = Image.open(path)
gray = ImageOps.grayscale(img)
gray = ImageOps.autocontrast(gray)
# 강한 임계값: 140보다 밝은 픽셀은 흰색, 나머지는 검은색이 됩니다.
bw = gray.point(lambda p: 255 if p > 140 else 0)
# Tesseract는 글리프가 클수록 잘 인식합니다.
bw = bw.resize((bw.width * 3, bw.height * 3))
config = f"--psm 7 -c tessedit_char_whitelist={ALLOWED}" # psm 7: 텍스트 한 줄
return pytesseract.image_to_string(bw, config=config).strip()
if __name__ == "__main__":
print(read_text("sample_captcha.png"))
임계값 140은 출발점일 뿐입니다. 처리된 이미지를 출력해 원본과 비교하고, 글자가 선명하고 배경이 깨끗해질 때까지 조정하세요.
의존하기 전에 정확도를 측정하기
이미지 한 장을 한 번 맞혔다고 해서 아무것도 증명되지 않습니다. 정답을 알고 있는 captcha 세트를 저장하고, 모든 이미지에 함수를 실행해 일치 개수를 세세요.
def accuracy(samples: dict[str, str]) -> float:
# samples는 파일 경로에서 실제 텍스트로 가는 매핑입니다
hits = sum(read_text(path) == truth for path, truth in samples.items())
return hits / len(samples)
labelled = {
"samples/0001.png": "K7PQ2",
"samples/0002.png": "M3XN9",
}
print(f"정확도: {accuracy(labelled):.0%}")
전처리를 바꿀 때마다 이 수치를 기록하세요. 여러 번 바꾼 뒤에도 수치가 낮다면, 그 captcha 스타일에는 OCR이 적절한 도구가 아닐 가능성이 높으니 다른 접근법을 검토해야 합니다.
어디서 깨지는가
- 노이즈와 선. 모폴로지 연산으로 선을 제거하거나, 낮은 성공률을 받아들이세요.
- 회전. 각도를 추정하고 읽기 전에 이미지를 회전하세요.
- 맞닿은 글자. 전체 줄을 읽기보다 열 단위로 문자를 나눠 하나씩 읽으면 종종 더 잘 작동합니다.
- 시간에 따른 변화. 사이트가 예고 없이 스타일을 바꿔 하룻밤 사이에 정확도가 떨어질 수 있습니다. 정답이 있는 세트를 유지하고 정기적으로 다시 실행하세요.
전처리 체크리스트
읽기가 실패하면 다음 항목을 순서대로 점검하세요. 어떤 단계가 도움이 됐는지 알 수 있도록 한 번에 한 가지씩만 바꾸세요.
- 입력 크기를 확인하세요. 아주 작은 captcha는 3배 확대 후에 더 잘 읽히는 경우가 많습니다.
- 그레이스케일로 변환하고 대비를 늘려 글자가 두드러지게 하세요.
- 임계값을 적용하세요. 하나를 고르기 전에 여러 값을 시험해 보세요.
- 중간값 필터로 점 노이즈를 제거하고, 필요하면 다시 임계값을 적용하세요.
- 배경이 엔진을 혼란스럽게 하지 않도록 이미지를 텍스트 영역으로 자르세요.
- 문자 집합을 captcha가 사용하는 것으로 제한하세요.
- 텍스트가 넓게 퍼져 있거나 여러 줄로 쌓여 있다면 다른 페이지 분할 모드를 시도하세요.
순서와 설정은 라벨이 달린 샘플과 함께 버전 관리에 보관하세요. 전처리 파이프라인도 코드이므로 코드처럼 검토해야 합니다.
OCR 또는 직접 실행하는 모델
클래식 OCR은 빠르고 노트북에서도 돌아가지만, captcha의 스타일이 바뀌면 쉽게 깨집니다. 직접 라벨링한 세트로 학습한 이미지 모델은 더 많은 변형을 다룰 수 있지만, 데이터를 모으고 추론을 실행해야 하는 비용이 듭니다. 둘 다 여러분이 직접 만들고 유지해야 합니다. 현재 Scarnox의 호스팅 엔드포인트는 둘 중 어느 것도 아니므로, 하나를 선택하기 전에 인프라를 계획하세요.
여기서 Scarnox가 하는 일과 하지 않는 일
Scarnox의 실시간 API는 PopularCaptcha 위젯 토큰을 해결합니다. 요청은 POST https://api.scarnox.com/api/tasks/create에 PopularCaptcha 작업 유형, sitekey, 페이지 URL을 담아 보내며, 응답은 폼 필드에 넣을 토큰입니다. 이는 이미지 속 텍스트를 읽는 것과는 전혀 다른 작업이며, Scarnox는 현재 이미지-텍스트 엔드포인트를 제공하지 않습니다. 이미지 captcha가 문제라면 OCR이나 직접 실행하는 모델을 사용하고, Scarnox가 다루는 범위는 다른 가이드를 참고하세요. Scarnox가 지원하는 PopularCaptcha 흐름은 계정을 만들고 무료 체험 크레딧으로 카드 없이 시작할 수 있습니다. 현재 요금은 요금 페이지에서 확인할 수 있습니다.
적법한 사용 사례
- 스캔한 문서, 스크린샷, 또는 직접 만든 테스트 이미지에서 텍스트를 읽기.
- 시각 장애가 있는 사용자가 사이트가 제공하는 대체 경로를 쓸 수 있도록, captcha를 설명하거나 읽어 주는 접근성 도구.
- 자동화 도구가 얼마나 쉽게 읽을 수 있는지 확인하고 더 강하게 만들기 위한, 자신의 captcha 설계 테스트.
자동화 접근을 허용하지 않는 사이트의 captcha를 우회하는 데 OCR을 쓰지 마세요. 이미지 captcha는 바로 그런 접근을 늦추기 위해 존재합니다.