Classical image-processing digit-CAPTCHA solver (no ML, no GPU needed). C++ backend + Python shell.
Project description
CaptchaConda
머신러닝 없이 고전 이미지 처리만으로 숫자 캡챠를 푸는 솔버. 학습 데이터도, GPU도, 프레임워크도 필요 없다. 매칭 코어는 C++ 백엔드로 이식돼 있고, Python은 얇은 껍데기 (전처리·세그멘테이션·오케스트레이션)로 남는다. 각 환경에 맞는 백엔드는 설치 후 한 번만 빌드한다.
설치
pip install CaptchaConda
python -m CaptchaConda init # 이 환경에 맞게 C++ 백엔드 빌드 (CPU)
# 또는 GPU 환경:
python -m CaptchaConda init --cuda # nvcc 로 CUDA 백엔드 빌드
init은 대화형 마법사로 진행된다(화살표 ↑/↓ 선택, Enter 확정):
- 빌드 방식 선택 — C++ (권장) / Python(빌드 없이 종료)
- 디바이스 선택 — CPU / CUDA
- 현재 라이브러리·컴파일러 검색(스피너)
- 빌드 바이너리 상태 판단 — 없으면 빌드 / 예전 버전이면 업그레이드 확인 / 최신이면 재빌드 확인
- 컴파일러 선택(하나여도 확인) — 없으면 다운로드 여부를 묻고 자동 설치(
build-essential/nvidia-cuda-toolkit등) - 빌드 프로그레스 바
비대화형(파이프/CI) 환경에서는 안전한 기본값(C++/CPU)으로 자동 진행된다. 컴파일러가 전혀 없고 설치도 거부하면 순수 Python 폴백으로 실행할 수 있다(동일 결과, 조금 느림).
사용
from CaptchaConda import CaptchaConda
device = "cuda" # 또는 "cpu"
cc = CaptchaConda(devices=device) # 처음 1회만
cc.init() # 처음 1회만 (백엔드 빌드+로드)
print(cc.solve("captcha.png")) # -> "39825"
print(cc.solve(pil_image, expected_n=5))
CaptchaConda(devices="cpu"|"cuda")— 백엔드 종류 선택init(force=False)— 백엔드 빌드/로드(캐시됨;force=True로 재빌드)solve(image, expected_n=None)— 이미지(경로 또는 PIL) → 숫자 문자열
델타트레이스 (DeltaTrace) — 흐름 기반 분류기
정적 필터 매칭 대신, 형상을 주파수 변환으로 표현해 코사인 유사도로 분류한다. 기본 표현은 글리프의 2D DCT 좌상단 8×8 블록 + 구멍 y위치다. DCT는 형상 에너지를 저차 계수에 모으므로(JPEG 원리) 작은 블록이 곧 압축 특징 — PCA가 필요 없다. 6/9처럼 회전으로 겹치는 숫자는 구멍 y위치로 가르고, 구멍 수로 게이팅한다.
cc.solve(img, expected_n=5, method="deltatrace") # 기본 = 2D DCT (PCA 불필요)
cc.solve(img, expected_n=5, color="green", seg_mode="cluster", method="deltatrace")
d, conf, scores = cc.classify_glyph(glyph, method="deltatrace")
성능(합성): 자리당 easy 100% / medium 99.8% — 필터 백엔드(99.7/97.5)와 다른 표현 모두를 넘어선다. 참고: 분류 시간의 대부분은 변환이 아니라 구멍(위상) 계산이 차지하므로, 순수 속도가 중요하면 C++ 필터 백엔드(자리당 ~34µs)가 여전히 가장 빠르다.
표현 선택 (dt_repr): "dct"(기본, 위) / "fft2d"(2D FFT+PCA, 99.5%·더 느림) /
"fourier"(윤곽 1D 복소 FFT, 99.2/98.8) / "turning"(방향 변화량 1D, ~88%). "turning"은
dt_topo로 위상 게이팅 선택 — 구멍 수(기본)가 분기 수(실험용·불안정 57%)보다 훨씬 낫다.
상호운용 & 신뢰도 (다른 라이브러리와 조합)
통짜 솔버가 아니라 파이프라인 단계를 노출해, 다른 OCR/ML 라이브러리와 섞어 쓸 수 있다.
# 1) 문자별 상세(바운딩박스 + 신뢰도)로 후처리/라우팅
for ch in cc.solve(img, expected_n=5, return_detail=True):
print(ch["digit"], ch["bbox"], ch["confidence"]) # confidence = 1등-2등 마진
# 2) 세그멘테이션만 쓰고 분류는 다른 라이브러리에 맡기기
for bbox, glyph in cc.segment(img, expected_n=5): # glyph: 정규화 (36,28)
digit = my_other_model.predict(glyph) # 외부 분류기
# 3) 외부에서 잘라온 글리프를 CaptchaConda 분류기로
digit, conf, scores = cc.classify_glyph(my_glyph)
confidence(1등-2등 점수 마진)가 낮으면 애매하거나 실패한 인식이다. 이를 임계로 걸어
저신뢰 문자는 다른 라이브러리로 폴백하는 하이브리드 구성이 가능하다.
색 타깃 + 클러스터링 세그멘테이션 (컬러 캡챠용)
실제 캡챠는 숫자와 방해선의 색이 다른 경우가 많다(예: 초록 숫자 + 보라 물결선). 배경 대비 대신 숫자 색만 타깃하면 다른 색 방해선이 통째로 사라진다. 또 숫자가 붙어 있으면 연결 성분이 뭉치므로, 잉크 x좌표를 k=기대 자리수로 클러스터링해 강제 분리한다(1D k-means, 외부 의존성 없음).
cc.solve(img, expected_n=5, color="green") # 초록 숫자만, 다른색 선 제거
cc.solve(img, expected_n=5, color="green", seg_mode="cluster")# 붙은 숫자 강제 5분할
cc.solve(img, expected_n=5, color="auto", seg_mode="cluster")# 숫자 색 자동 추정
cc.solve(img, expected_n=5, color=(40,112,57)) # 정확한 RGB 지정
color:None(기본, 배경 대비) ·"green"/"red"/"blue"·(r,g,b)·"auto"seg_mode:"connected"(기본) ·"cluster"(x좌표 k-means 강제 분할)enhance:True면 노출·대비·채도 강조로 흐린 색 숫자를 또렷하게 전처리color="green"은 틸(teal, 초록≈파랑) 숫자까지 잡되 파란 선(B≫G)은 제외한다deline=True: 색 숫자를 관통하는 다른 색 선을 인페인팅으로 제거(선이 끊은 획을 주변색으로 복원). 겹친 숫자를 완전히 살리진 못한다
한계: 숫자가 매우 흐리거나 얇은 윤곽이라 색으로도 온전히 못 뽑히는 캡챠는 여전히
낮게 나온다(입력 신호 자체의 한계). 이럴 때는 return_detail의 confidence가 낮게
찍히므로, 저신뢰 케이스만 ML 폴백으로 넘기는 하이브리드를 권장한다.
한계 및 대응 (정직하게)
- 얇은 방해선(1~2px): 같은 색이어도 잘 처리된다(자리당 95~98%).
- 두꺼운 방해선(≥3~4px)이 숫자를 관통·융합하는 경우: 성능이 급락한다. 색이 숫자와 같으면 분리 신호가 없고, 선이 여러 숫자를 이어 붙이면 세그멘테이션이 하나로 병합돼 잘못 쪼개진다(예측이 한두 숫자로 퇴화). 이는 학습 없는 고전 이미지 처리의 근본 한계다.
- 대응: 위
confidence로 실패를 감지하고,segment()로 얻은 글리프를 ML OCR 등 다른 라이브러리로 폴백하는 하이브리드를 권장한다. CaptchaConda는 빠른 1차 필터 (대부분의 깨끗/얇은선 캡챠를 CPU로 즉시 처리)로 쓰고, 저신뢰 케이스만 무거운 모델로 넘기면 전체 비용을 크게 아낄 수 있다.
왜 이런 구조인가
- Python은 그대로 배포 → 이식성. 무거운 계산은 C++ 백엔드가 담당.
- 백엔드는 소스로 배포되고
init때 각 환경에 맞게 컴파일 → 배포 바이너리 호환성 문제를 피하고, CUDA가 있으면 GPU 백엔드로 빌드. - 학습이 없으므로 모델 파일·GPU·데이터셋 비용이 0. 필터 데이터(수십 KB)만 동봉.
동작 개요
이미지 → 배경 분리 → 숫자 분리 → (C++) 필터 매칭 + 위상 라우팅 + 이중필터 → 시퀀스. 정확도는 타깃 캡챠 분포에 맞춰 동봉 필터를 튜닝할수록 올라간다.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file captchaconda-1.2.0.tar.gz.
File metadata
- Download URL: captchaconda-1.2.0.tar.gz
- Upload date:
- Size: 426.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3fdac8bf978224f6d7c32ac3bd924a0983b95dac438543b6ee0f0a75a5272969
|
|
| MD5 |
8d34e2d636fa8cf243bf8232c27497ca
|
|
| BLAKE2b-256 |
780dbe7b24151eeae087cde7c9e896454361dc5cf7927d18873b10adfe5fd6dd
|
File details
Details for the file captchaconda-1.2.0-py3-none-any.whl.
File metadata
- Download URL: captchaconda-1.2.0-py3-none-any.whl
- Upload date:
- Size: 428.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
811972a05c2d57f09080b023755d4f6560b9783665fe1291a3c78134e9505e96
|
|
| MD5 |
1994d7dc66bcca2607fa108134f643b3
|
|
| BLAKE2b-256 |
44fce99e076e08d9293f8871667f198086f6570cd8571fc4881ae32d95aae104
|