OCR이 소수점과 통화 기호를놓치는 이유: 5가지 오류 유형과 해결 방법

문서에 분명 "$156.00"라고 적혀 있는데, 추출 결과는 "15600"이 나왔습니다. 소수점은 사라지고, 통화 기호는 증발했으며, 이제 스프레드시트에는 156달러 비용 대신 15,600달러의 오류가 생겼습니다. 바로 이러한 작은 기호들이 가장 먼저 깨지는 이유와 각 오류 유형에 대처하는 방법을 정확히 알려드립니다.

수작업 입력은 그만 — AI가 대신 읽어드립니다
이미지나 PDF를 업로드하세요 — 10초 만에 정형 데이터로
지금 체험하기
회원가입 불필요 · 카드 불필요 · 10초 내 결과
OCR이 소수점과 통화 기호를 놓치는 현상 — 추출 오류로 인한 계산 오류를 보여주는 회계 계산기 이미지

핵심 요약

  1. 추출 과정에서 경고 하나 없이 송장 금액이 100배로 늘어났습니다. $156.00은 15600이 되었지만, 공급업체명, 날짜, 품목 등은 모두 정확하게 추출되었습니다. 가장 중요한 숫자만 틀린 것입니다.
  2. 소수점은 저해상도(DPI)에서 먼지로 필터링되고(2픽셀 너비), 통화 기호는 첫 번째 숫자와 붙어 사라지며, 유럽식 쉼표는 소수점 위치를 바꾸고, 대변 메모의 괄호는 무시되며, 위첨자 센트는 별도의 텍스트 줄로 사라집니다. 이는 무작위 소프트웨어 버그처럼 보이는 다섯 가지 물리적 문제입니다.
  3. 추출된 총액을 품목 합계와 비교하는 하나의 검증 규칙만으로도 100배 오류가 총계정원장에 도달하기 전에 잡아낼 수 있습니다. 새 도구나 전처리 없이, 추출 후 실행되는 검사 하나면 충분합니다.

소수점 하나가 빠지는 것은 단순한 오류가 아니라 10배의 오차를 만듭니다. 더 frustrating한 점은 추출 결과의 나머지 부분은 깔끔해 보인다는 것입니다. 공급업체명, 날짜, 품목 항목은 모두 정확하게 추출됩니다. 그러나 가장 중요한 숫자들—합계, 세액, 단가—만 조용히 한두 자릿수씩 틀어집니다. 그 영향은 추상적이지 않습니다. $156 대신 $15,600으로 기장된 지급은 현금을 묶어두고, 조정 작업을 유발하며, 자동화 프로세스에 대한 신뢰를 떨어뜨립니다.

문서 처리 연구의 핵심 통찰은 일관됩니다: 소수점, 통화 기호, 마이너스 기호와 같은 작은 기호들은 더 큰 문자들보다 먼저 실패합니다. 이는 OCR 엔진의 해상도 임계값 경계에서 작동하기 때문입니다. 이는 무작위 오류가 아닙니다. 각각 알려진 근본 원인이 있는 예측 가능한 실패 모드를 따릅니다. 어떤 모드를 다루고 있는지 식별하는 것이 빠른 정규식 수정과 ERP에 탐지되지 않고 도달하는 데이터 재앙 사이의 차이를 만듭니다.

이 글에서는 소수점 및 통화 기호 누락에 대한 다섯 가지 뚜렷한 실패 모드를 다룹니다. 각각 특정 진단 신호와 특정 수정 방법이 있습니다. 텍스트가 명확하게 읽힐 때도 추출 도구가 잘못된 숫자를 반환하는 더 넓은 그림에 대해서는 잘못된 추출 숫자를 유발하는 필드 설계 실수에 관한 동반 기사를 참조하십시오. 해당 기사는 모호한 열 이름 지정에 초점을 맞추고, 이 기사는 기호 수준의 실패에 초점을 맞춥니다.

실패 모드 1: 소수점이 엔진이 인식하기에 너무 작음

증상: "3.50"이 "350" 또는 "3 50"으로 추출됩니다. "19.99"는 "1999"가 됩니다. 숫자 자체는 완벽하게 읽을 수 있지만 소수점이 단순히 존재하지 않습니다. 누락된 점은 스프레드시트의 모든 숫자를 두 자릿수씩 이동시킵니다.

발생 이유: 기존 OCR 엔진은 문자를 읽기 전에 노이즈 필터, 대비 조정, 이진화를 적용하여 이미지를 전처리합니다. 열전사 영수증, 저해상도 스캔, 팩스 문서에서 흔히 볼 수 있는 높이 8~10픽셀의 소수점은 이러한 전처리 단계의 노이즈 임계값 아래에 있습니다. 엔진의 필터는 두 숫자 사이의 작은 점을 보고 먼지, 종이 섬유 또는 압축 아티팩트로 분류합니다. 72 DPI에서 소수점은 너비가 약 2~3픽셀을 차지합니다. 이 크기에서는 모든 이진화 알고리즘에 대해 먼지 입자와 시각적으로 구별할 수 없습니다.

이는 인식의 실패가 아니라 전처리의 실패입니다. 소수점은 엔진이 살펴보기 전에 제거되었기 때문에 인식 단계에 도달하지 못합니다.

수정 방법: 가장 신뢰할 수 있는 수정은 OCR 엔진의 전처리를 변경하려고 시도하는 대신 추출 후 검증입니다. 예상 패턴에 대해 추출된 모든 금액을 검증하는 필드 수준 정규식 검사를 구현하십시오:

# 확인: 이 값에 정확히 소수점 두 자리가 있습니까?
pattern = r'^\d+\.\d{2}$'
if not re.match(pattern, extracted_value):
    flag_for_review(extracted_value)

정규식 이상으로, 추출된 값을 예상되는 규모와 비교하세요. 송장 총액이 일반적으로 50~5,000달러 사이인데 추출 결과가 500,000달러라면, 이상치 검사가 회계 시스템에 도달하기 전에 오류를 잡아냅니다. ImageToTable.ai를 포함한 많은 추출 도구는 추출 중 금액을 표준화하는 출력 형식 규칙을 정의할 수 있습니다. 소수점 위치가 원시 OCR 출력이 유지해야 하는 것이 아니라 출력 스키마의 일부가 됩니다.

소수점이 물리적으로 6픽셀보다 작은 초저해상도 스캔의 경우, 후처리 수정으로 완전히 신뢰할 수 있는 방법은 없습니다. 솔직히 말해, 원본 이미지에 정확한 추출에 필요한 정보가 포함되어 있지 않습니다. 이러한 경우 300DPI 이상으로 다시 스캔하는 것이 유일한 확실한 해결책입니다.

오류 유형 2: 숫자에 붙은 통화 기호가 누락됨

증상: "$156.00"이 "156.00"(기호 누락)으로 추출되거나, 더 나쁜 경우 "$15600"(기호와 숫자가 병합되어 소수점이 사라짐)으로 추출됩니다. 통화 맥락이 사라지고 다운스트림 시스템이 USD 금액을 단위 없는 숫자로 처리합니다.

발생 원인: 통화 기호($, €, £, ¥, R$)는 숫자와 활자체가 다릅니다. 종종 다른 서체나 굵기로 설정되며, 숫자와 같은 기준선에 있지만 시각적 프로필이 다릅니다. OCR 엔진이 줄을 토큰화할 때 "$"를 숫자의 일부로 볼지 별도 개체로 볼지 결정해야 합니다. 근접 기반 토크나이저는 기호를 선행 숫자와 병합하여 "$156"과 같은 단일 토큰을 생성하는 경우가 많습니다. 그러면 엔진은 내부 문자 분류기가 뒤따르는 숫자보다 "$" 기호에 대한 신뢰도가 낮기 때문에 이를 잘못 읽습니다. 엔진은 신뢰도가 낮은 문자(통화 기호)를 버리고 신뢰도가 높은 숫자를 유지하여 혼동을 해결합니다.

일부 비전 기반 추출 엔진은 문자 단위로 토큰화하는 대신 전체 시각적 맥락을 처리하기 때문에 기존 OCR보다 이 문제를 더 잘 처리합니다. 그러나 통화 기호와 첫 번째 숫자가 단단히 결합된 경계 상자를 공유하거나, 일부 영수증 프린터의 말린 "$"와 같이 드문 서체로 기호가 나타나는 경우 최신 모델도 어려움을 겪을 수 있습니다.

해결 방법: 추출 후 단계로 통화 기호 정규화 맵을 구현하세요. 금액 필드에 대해 예상 출력 형식(예: "USD 156.00" 또는 "$156.00")을 정의하고 추출된 값을 해당 형식으로 정규화하세요:

# 문서 컨텍스트별 알려진 통화 기호
currency_map = {
    'USD': r'[\$]',
    'EUR': r'[€]',
    'GBP': r'[£]',
    'JPY': r'[¥]'
}
# 추출된 값에 숫자는 있지만 기호가 없는 경우,
# 문서 메타데이터에서 예상 통화 할당
if re.match(r'^\d+\.\d{2}$', value) and not has_currency_prefix(value):
    normalized = f"{doc_currency} {value}"

핵심은 OCR이 기호의 소속을 결정하도록 의존하지 않는 것입니다. 추출 스키마 수준에서 정의하고 이에 대해 검증하세요.

고장 모드 3: 천 단위 구분 기호 혼동으로 인한 소수점 역전

증상: 미국 송장의 "1,234.56"이 "1.23456" 또는 "1234.56"으로 추출됩니다(쉼표 손실). 유럽 문서의 "1.234,56"은 "1.23456" 또는 "1234.56"으로 추출됩니다. 마침표가 소수점으로 처리되어 값이 1,000배 부풀려집니다. 동일한 구두점이 로케일에 따라 정반대의 의미를 가지지만, OCR 엔진은 어떤 규칙을 적용해야 할지 알지 못합니다.

발생 원인: OCR 엔진은 구두점을 수학적 표기법이 아닌 문자로 처리합니다. 마침표와 쉼표는 시각적 프로필이 뚜렷이 다른 문자이지만, 엔진은 문서 로케일에서 어느 것이 소수 구분 기호인지에 대한 기본 지식을 가지고 있지 않습니다. 이는 단일 엔진의 한계가 아닙니다. Tesseract부터 상용 클라우드 API까지 모든 주류 OCR 도구는 구두점을 동일하게 처리합니다. 즉, 보이는 그대로 출력하고, 해당 구두점의 해석은 다운스트림 로직에 맡깁니다. 결과적으로 동일한 추출 파이프라인이 미국 송장에서는 $1,234.56을, 독일 송장에서는 1,234.56€을 생성할 수 있으며, 다운스트림 시스템이 어떤 규칙을 기대해야 하는지 모르면 둘 다 잘못 파싱됩니다.

이 문제는 여러 국가의 송장을 처리할 때 더욱 악화됩니다. 미국, 독일, 프랑스 공급업체의 송장 50장이 포함된 단일 배치에는 세 가지 다른 소수점 규칙이 존재할 수 있습니다. 추출 엔진은 어떤 규칙이 어떤 문서에 적용되는지 자동으로 감지하지 않습니다.

해결 방법: 두 가지 접근 방식이 있습니다. 첫 번째는 스키마 수준 접근 방식입니다. 추출 실행 전에 공급업체 또는 문서 유형별로 예상 소수점 형식을 정의합니다. 독일 공급업체의 송장이 쉼표 소수점을 사용한다는 것을 알고 있다면, 해당 문서 그룹에 대해 쉼표를 소수 구분 기호로, 마침표를 천 단위 구분 기호로 해석하는 파싱 규칙을 구성합니다.

두 번째 접근 방식은 크기 검증입니다. 이는 다국어 추출 정확도 저하에 대한 기사에서 자세히 설명된 기술로, 문서 출처 간 형식 차이가 어떻게 연쇄 오류를 생성하는지 다룹니다. 실제로는 추출된 총액이 라인 항목 합계의 합리적인 범위 내에 있는지 확인합니다. 라인 항목 합계가 $12,345.67일 때 총액이 $1,234,567.89라면 소수점-천 단위 구분 기호 역전의 명확한 지표입니다.

# 검증: 총액이 라인 항목 합계와 일치하는가?
# 합리적인 허용 오차 내에서?
line_sum = sum(line_items)
total = extracted_total
# 총액이 line_sum의 약 1000배이면 소수점이 천 단위 구분 기호로 읽힌 것
if abs(total - line_sum) / max(line_sum, 1) > 100:
    flag_decimal_ambiguity(extracted_total)

고장 모드 4: 음수 부호와 괄호 — 보이지 않는 지표

증상: "(156.00)"으로 표시된 대변 메모가 음수 부호 없이 "156.00"으로 추출됩니다. 은행 거래 명세서 잔액 "1,247.30-"은 후행 마이너스가 누락되어 "1,247.30"으로 추출됩니다. 숫자 자체는 기술적으로 정확하지만 부호가 잘못되어 대변이 차변으로, 환불이 청구로 바뀝니다.

발생 원인: OCR 엔진은 괄호를 독립적인 문장 부호로 처리합니다. 음수 값을 나타내는 표준 회계 표기법인 괄호로 숫자가 묶여 있을 때, 여는 괄호는 첫 번째 숫자 앞의 별도 문자로, 닫는 괄호는 마지막 숫자 뒤의 별도 문자로 읽힙니다. 데이터 추출 과정에서 이 괄호들은 숫자 필드의 예상 문자 클래스와 일치하지 않아 종종 폐기됩니다. 후행 마이너스 부호도 마찬가지입니다. 숫자 뒤에 위치하여 숫자 토큰 밖에 있으므로 별도의 텍스트 조각으로 분류되어 추출 로직이 숫자와 연관시키지 못합니다.

해결 방법: 필드 수준의 부호 감지 규칙을 정의합니다. 추출된 값이 일반적으로 대변, 할인 또는 음수 조정이 포함된 필드에 나타나거나 원본 문서에 달러 금액 주위에 괄호가 있는 경우, 추출 후 부호 반전을 적용합니다. 이를 필드 명명 규칙과 결합합니다. "대변 금액" 또는 "할인"이라는 열은 절대값을 예상하고 OCR이 반환한 내용과 관계없이 자동으로 음수 부호를 적용해야 합니다.

# 문서 컨텍스트가 음수 크기 필드를 나타내고
# 추출된 값이 양수인 경우 부호 반전
negative_context_fields = ['credit_memo', 'discount', 'refund', 'adjustment']
if field_name in negative_context_fields and extracted_value > 0:
    extracted_value = -extracted_value

오류 유형 5: 위첨자와 아래첨자 — 줄 사이로 사라지는 센트

증상: "$9999"(센트를 위첨자로 표시한 $99.99) 형태의 가격표가 "$99" 또는 "$9900"으로 추출됩니다. 소계 옆에 작은 위첨자로 인쇄된 세액이 완전히 사라집니다. 기본 숫자는 정확하지만 정확한 금액을 결정하는 소수 부분이 사라집니다.

발생 원인: 위첨자 문자는 기본 숫자와 동일한 가로 영역을 공유하지만 기준선 위에 기본 숫자 포인트 크기의 40~60% 크기로 위치합니다. OCR 엔진은 수직 위치가 기본 기준선과 다르기 때문에 이를 별도의 텍스트 줄이나 조각으로 감지합니다. 텍스트 추출 시 이 조각은 다른 출력 줄에 할당되거나 레이아웃 분석 중 이상값으로 삭제됩니다. 소매 가격표와 일부 청구서 항목에서 흔히 볼 수 있는 센트 표기가 가장 빈번하게 손실됩니다.

아래첨자 값(통화 맥락에서는 덜 일반적이지만 세율 및 참조 코드에서 자주 사용됨)은 반대 방향으로 동일한 문제에 직면합니다. 기준선 아래의 문자가 독립적인 텍스트 영역으로 분할되어 기본 숫자와의 연결이 끊어집니다.

해결 방법: 가장 실용적인 방법은 좁은 수직 범위 내에서 동일한 가로 위치를 공유하는 모든 텍스트 조각을 결합한 다음 결합된 값을 예상되는 통화 패턴과 비교하여 검증하는 것입니다. 기본 숫자가 "99"이고 동일한 열 영역에 위첨자 "99"가 있는 경우 "99.99" 조합은 유효한 통화 값입니다. 이를 공간 병합 규칙으로 구현합니다. 기본 숫자의 X좌표 범위 150% 이내이고 정의된 수직 오프셋 내에 있는 모든 텍스트 조각을 추출된 필드 값에 병합합니다.

# 동일한 가로 영역 내 조각 병합
# 좁은 수직 범위 내에서
def merge_superscript(main_number, fragments, y_threshold=15):
    """주요 숫자 클러스터를 주변 조각과 결합합니다."""
    combined = main_number
    for frag in fragments:
        if abs(frag.y - main_y) < y_threshold and \
           abs(frag.x - main_x) < main_width * 0.5:
            combined += frag.text
    # 병합 후 검증
    if re.match(r'^\d+\.\d{2}$', combined):
        return combined
    return main_number  # 병합이 유효하지 않으면 원본으로 대체

전문가에게 문의해야 할 때: 자동 수정의 명확한 한계

위의 다섯 가지 수정 방법은 대부분의 소수점 및 통화 기호 오류를 해결합니다. 하지만 어떤 후처리 규칙으로도 값을 안정적으로 복구할 수 없는 문서 범주가 있습니다. 바로 캡처 방식이 재현할 수 있는 최소 해상도보다 소수점이 물리적으로 더 작은 문서입니다. 72 DPI 열전사 영수증의 소수점은 약 2픽셀 너비입니다. 이 크기에서는 기존 OCR이나 비전 AI 엔진 모두 이미지에 정보가 물리적으로 존재하지 않기 때문에 안정적으로 읽을 수 없습니다.

열전사 영수증, 팩스 문서, 2세대 복사본을 처리하는 경우 일부 소수점은 수동 확인이 필요하다는 점을 받아들이십시오. 실용적인 접근 방식은 규모 검사에 실패하는 모든 추출 금액(예상 범위를 벗어난 총액, 품목 합계와 일치하지 않는 총액, 통화와 일치하지 않는 소수점 자릿수)에 플래그를 지정하고 이를 사람 검토자에게 전달하는 것입니다. 플래그가 지정된 값을 30초 동안 검토하는 것이 캡처 시점에 손실된 정보를 복구하기 위해 후처리를 조정하는 것보다 더 빠르고 안정적입니다.

일관되게 저해상도로 문서가 유입되는 팀을 처리하는 경우, 가장 효과적인 투자는 더 나은 추출 도구가 아니라 유입 문서에 300 DPI 이상을 요구하는 스캔 표준입니다. 300 DPI에서 소수점은 8~10픽셀을 차지하며, 이는 모든 최신 추출 엔진의 노이즈 임계값보다 높습니다.

수작업 입력은 그만 — AI가 대신 읽어드립니다
이미지나 PDF를 업로드하세요 — 10초 만에 정형 데이터로
지금 체험하기
회원가입 불필요 · 카드 불필요 · 10초 내 결과

자주 묻는 질문

AI 추출 도구가 열전사 영수증의 소수점을 읽을 수 있나요?

최신 비전 AI 도구는 인쇄 품질이 좋고 이미지가 충분한 해상도(이상적으로 300 DPI 이상)로 캡처된 경우 열전사 영수증의 소수점을 읽을 수 있습니다. 그러나 열전사 영수증은 본질적으로 대비가 낮고 시간이 지남에 따라 인쇄가 희미해집니다. 8포인트 미만의 인쇄 크기에서는 소수점이 물리적으로 너무 작아 어떤 시스템도 배경 노이즈와 구분할 수 없습니다. 솔직한 답변: 사람이 영수증 사진에서 소수점을 보기 위해 눈을 가늘게 떠야 한다면 AI도 놓칠 것입니다.

OCR이 추출된 금액에서 $ 기호를 계속 누락하는 이유는 무엇인가요?

통화 기호는 공백 구분자 없이 첫 번째 숫자에 매우 가깝게 나타나거나 주변 숫자와 다른 서체를 사용할 때 가장 자주 누락됩니다. OCR 엔진은 기호 문자에 대한 신뢰도가 낮아 신뢰도가 높은 숫자는 유지하고 신뢰도가 낮은 기호는 버리는 방식으로 해결합니다. 추출 스키마에서 통화 기호 정규화 규칙을 정의하여 이 문제를 해결하세요. 문서 소스별로 예상 통화를 지정하고 OCR이 기호를 보존하는 데 의존하지 않고 추출된 모든 금액에 자동으로 적용되도록 합니다.

추출 후 정규식을 사용하면 모든 소수점 오류를 수정할 수 있나요?

정규식은 많은 소수점 오류를 잡을 수 있지만 모두 수정할 수는 없습니다. OCR 캡처 중에 소수점이 손실되어 추출된 값이 "156.00" 대신 "15600"인 경우, 정규식은 추가 컨텍스트 없이 소수점이 어디에 속하는지 확인할 수 없습니다. 값은 원본 문서에 따라 15.600, 156.00 또는 1560.0이 될 수 있습니다. 정규식은 크기 유효성 검사(라인 항목 합계 또는 예상 범위와 비교)와 결합하거나 문서 형식을 미리 알고 있는 경우(예: 모든 가격에 소수점 이하 두 자리가 있는 경우) 잘 작동합니다. 형식을 알 수 없는 문서의 경우 정규식은 수정 메커니즘이 아니라 플래그 지정 메커니즘입니다.

소수점 손실을 방지하려면 어떤 해상도로 스캔해야 하나요?

300 DPI는 인쇄 문서의 안정적인 OCR을 위한 업계 표준입니다. 300 DPI에서 10포인트 소수점은 너비가 약 8-10픽셀을 차지하며 최신 OCR 및 AI 추출 엔진의 노이즈 임계값을 훨씬 웃돕니다. 150 DPI(팩스 및 아카이브 스캔에 일반적)에서는 동일한 소수점이 4-5픽셀로 떨어져 경계선이 됩니다. 72 DPI(문서의 모바일 폰 스크린샷에 일반적)에서는 소수점이 2픽셀에 불과할 수 있으며 모든 추출 시스템에 사실상 보이지 않습니다. 소수점이 지속적으로 누락되는 경우 먼저 스캔 해상도를 확인하세요.

다음 단계: 진단에서 예방으로

소수점 하나의 누락은 우연이 아닙니다. 이는 다섯 가지 알려진 실패 모드 중 하나의 예측 가능한 결과입니다. 이러한 오류를 잡아내는 팀과 그렇지 못한 팀의 차이는 사용하는 도구가 아니라 진단 프레임워크의 유무에 있습니다. 어떤 실패 모드를 다루고 있는지 알면, 해결책은 대개 다른 AI 엔진이 아닌 후처리 규칙입니다.

간단한 감사부터 시작하세요: 파이프라인에서 추출한 최근 50개의 금액 값을 가져와 각 오류를 실패 모드별로 분류하세요. 오류의 80%가 한두 가지 범주에 속한다면, 몇 줄의 검증 로직만으로 비용 없이 집중적인 수정이 가능합니다. 오류가 다섯 가지 모드에 걸쳐 분산되어 있다면, 문제는 캡처 품질일 가능성이 높으며, 해결책은 도구 변경이 아닌 스캔 표준입니다.

문서 형식에 따른 추출 정확도 차이와 모호성을 최소화하는 필드 설계 방법에 대해 더 깊이 알아보려면, 잘못된 숫자를 추출하게 만드는 필드 설계 실수에 대한 가이드와 문서 출처 간 형식 차이가 정확도 저하를 일으키는 방식에 대한 분석을 참조하세요. 필드 설계, 형식 차이, 그리고 이제 기호 수준의 실패 모드라는 세 가지 진단 도구를 통해 파이프라인의 모든 수준에서 추출 정확도를 디버깅하는 완전한 프레임워크를 갖추게 됩니다.

수작업 입력은 그만 — AI가 대신 읽어드립니다
이미지나 PDF를 업로드하세요 — 10초 만에 정형 데이터로
지금 체험하기
회원가입 불필요 · 카드 불필요 · 10초 내 결과
📮 contact email: [email protected]