이미지 속에 포함된 전화번호, 주민등록번호, 금액처럼 형식이 명확한 숫자를 정확하게 추출하려면, 단순 OCR만으로는 부족할 때가 많습니다.
특히 스캔 품질, 글씨체, 배경 노이즈, 숫자 간격 등이 제각각일 경우, 결과가 틀리거나 불필요한 문자가 섞이는 문제가 발생합니다.
이럴 때는 이미지의 특성과 추출하려는 데이터의 규칙을 잘 이해하고, 그에 맞는 접근법을 선택하는 것이 중요합니다.
이번 가이드에서는 실무에서 자주 사용하는 세 가지 주요 방법을 정리했습니다. 각 방법은 이미지 종류, 데이터 형태, 환경 제약 조건에 따라 장단점이 있으므로, 상황에 맞게 선택하면 됩니다.
또한 마지막에는 정확도 향상을 위한 전처리 팁과, 바로 테스트해볼 수 있는 간단한 파이썬 코드 예시를 함께 제공하여, OCR 초보자부터 실무 담당자까지 바로 적용할 수 있도록 구성했습니다.
이 글을 읽고 나면, 단순히 이미지에서 텍스트를 읽어들이는 수준을 넘어, 형식 기반 데이터 인식을 체계적으로 처리할 수 있는 실전 감각을 갖출 수 있을 것입니다.
OCR + 정규식(Regex) 후처리: 가장 범용적이고 쉬운 기본기
이 방법은 OCR 엔진으로 이미지 전체 텍스트를 추출한 후, 정규식(Regular Expression)을 사용해 원하는 패턴의 숫자만 걸러내는 방식입니다.
- 장점: 구현이 간단하고, 다양한 형태의 이미지에 범용적으로 적용할 수 있습니다. 유지보수가 쉽고, 별도의 복잡한 모델링이 필요 없습니다.
- 단점: OCR 인식 오류(예: ‘0’을 ‘O’로, ‘1’을 ‘I’로 잘못 인식)에 직접적인 영향을 받습니다. 이미지 품질이 낮거나 폰트, 배경이 복잡할 경우 정확도가 떨어질 수 있습니다.
- 적합한 케이스: 명함, 폰으로 촬영한 문서, 스크린샷 등에서 전화번호, 날짜, 이메일 주소처럼 명확한 패턴을 가진 정보를 추출할 때 효과적입니다.
구현 순서:
- 전처리: 이미지의 해상도를 높이고, 기울기를 보정하며, 대비를 강화해 글자가 선명하게 보이도록 만듭니다.
- OCR: Tesseract 같은 OCR 엔진을 사용해 이미지 전체 텍스트를 추출합니다. 한국어와 영어가 혼합된 경우
-l kor+eng
옵션을 사용하면 인식률이 높아집니다. - 정규식 후처리: 추출된 텍스트에서 원하는 패턴에 맞는 정규식을 적용해 숫자만을 필터링합니다.
- 전화번호:
(01[016-9])[-.\s]?\d{3,4}[-.\s]?\d{4}
- 금액(원):
(?:(?:\d{1,3}(?:,\d{3})+)|\d+)\s*원
- 전화번호:
위치 기반 레이아웃 + OCR: 표·영수증에 강한 방법
이 방법은 추출하려는 숫자가 이미지 내의 항상 일정한 위치에 있거나, 특정 라벨(예: “합계”, “주문번호”) 옆에 있는 경우에 효과적입니다.
- 장점: OCR이 이미지 전체를 읽지 않고 특정 영역에만 집중하므로, 배경의 잡음이나 다른 텍스트의 영향을 덜 받습니다. 따라서 정확도가 매우 높습니다.
- 단점: 문서의 양식이 바뀌거나 레이아웃이 틀어지면 좌표를 다시 설정해야 합니다. 초기 설정에 약간의 수고가 필요합니다.
- 적합한 케이스: 영수증의 총액, 세금계산서의 합계 금액, 송장번호 등 문서 폼이 고정되어 있을 때 매우 유용합니다.
구현 방법:
- 영역 탐지: 템플릿 매칭이나 OpenCV를 사용해 ‘총합계’ 같은 라벨을 먼저 찾고, 그 옆에 있는 영역의 좌표를 얻습니다.
- 영역 전처리 및 OCR: 해당 영역(ROI, Region of Interest)만 잘라내어 전처리 과정을 거친 후 OCR을 실행합니다.
- 패턴 검증: 추출된 결과가 올바른지 정규식이나 길이, 체크섬(checksum) 등으로 다시 한번 확인합니다.
비전+NLP 하이브리드: 숫자 의미까지 구분하는 고정밀 방법
이 방법은 OCR 결과에 더해 NLP(자연어 처리) 기술을 활용하여 추출된 숫자가 어떤 의미를 가지는지 판단합니다. 한 이미지에 여러 개의 숫자가 있을 때 ‘진짜’ 필요한 숫자를 찾아내는 데 탁월합니다.
- 장점: 단순히 패턴에 맞는 숫자를 찾는 것을 넘어, ‘최종 결제 금액’, ‘주문번호’처럼 의미를 기반으로 정확하게 숫자를 추출할 수 있습니다. 운영 환경에서 발생하는 다양한 노이즈를 효과적으로 줄일 수 있습니다.
- 단점: 초기에 의미를 판별하기 위한 규칙(Rule)이나 분류 모델을 설계해야 합니다.
- 적합한 케이스: 여러 개의 금액이 표기된 영수증에서 최종 결제 금액만 골라내야 하거나, 여러 전화번호 중 대표 번호만 추출해야 할 때 유용합니다.
구현 방법:
- OCR: Tesseract로 텍스트와 함께 각 텍스트의 좌표(바운딩 박스)를 추출합니다.
- 후보 생성: 추출된 텍스트 중에서 정규식 등을 사용해 숫자 형태의 ‘후보’들을 찾아냅니다.
- 의미 판별: 각 후보 주변의 텍스트(예: “합계”, “총액”, “VAT”)나 위치, 폰트 크기 등을 분석하여 어떤 의미를 가지는지 판단합니다.
- 최종 검증: 유효성 검사 규칙(예: 주민등록번호 체크섬, 금액의 총합 검증)을 적용해 최종적으로 올바른 숫자를 선택합니다.
정확도를 높이는 전처리 및 튜닝 팁
- 이미지 품질: 가로 1200px 이상, 글자 높이 24px 이상을 목표로 이미지를 준비하세요.
- 대비: 컬러 이미지보다 고대비의 흑백 이미지가 OCR 인식률이 높습니다.
OpenCV
의cv2.threshold
함수로 배경과 글자를 명확하게 분리할 수 있습니다. - Tesseract 옵션:
psm
(Page Segmentation Mode
) 옵션을 변경하며 테스트해 보세요.psm 6
(단일 균일 블록)이나psm 7
(단일 텍스트 라인)이 특정 영역 OCR에 효과적입니다. - 후처리 보정: OCR이 자주 틀리는 오류(예: ‘O’ → ‘0’, ‘l’ → ‘1’)를 미리 정의해 두고, 추출된 결과에 1차 보정 규칙을 적용하면 정확도를 높일 수 있습니다.
Disclaimer: 본 블로그의 정보는 개인의 단순 참고 및 기록용으로 작성된 것이며, 개인적인 조사와 생각을 담은 내용이기에 오류가 있거나 편향된 내용이 있을 수 있습니다.