PDF에는 OCR이 필요합니까? 전체 재인식 대신 PyMuPDF를 사용하여 페이지별 프리플라이트 수행

PDF를 OCR하려는 경우 전체 PDF를 다시 인식할 필요가 없습니다. PyMuPDF를 사용하여 페이지별로 텍스트 레이어가 있는지, 전체 페이지 이미지인지 확인하고, 실제로 인식에 필요한 페이지만 전송하세요. 실행 가능한 샘플, 회전 페이지 테스트 및 분기 경계 지침이 첨부되어 있습니다.

많은 팀이 PDF 번역이나 보관을 처리할 때 입구에서 전체 문서에 "스캔됨" 또는 "복사 가능"이라는 라벨을 붙이는 데 익숙합니다. 300페이지 PDF에는 처음 280페이지에 텍스트 레이어가 있고 마지막 20페이지만 스캔된 첨부 파일로 포함될 수 있습니다. 전체 부분으로 분류하면 전체 OCR이 대기 시간을 늘리게 되며, 원래 정확한 번호를 잘못 식별할 수도 있습니다. 반면, 홈 페이지의 텍스트만 복사하고 모든 페이지에서 OCR을 건너뛸 수 있다면 역시 위험합니다.

보다 안정적인 접근 방식은 각 페이지가 프리플라이트 결과에 따라 다음 단계로 진행되도록 하는 것입니다. 이 문서에서는 직접 추출, OCR 후보 대기열로 보내기, 수동 검사라는 보수적인 3방향 분할을 구현합니다. 이는 텍스트 품질을 판단하기 위한 보편적 분류자가 아니라 해석 가능한 엔지니어링 휴리스틱입니다. 읽고 나면 실행 가능한 페이지별 프리플라이트 프로그램과 전환 경계 및 일반적인 오류 처리 아이디어를 얻을 수 있습니다.

한 문장 결론

PDF에 OCR이 필요한지 여부를 판단할 필요가 없습니다. PyMuPDF를 사용하여 페이지별로 사전 확인하고 실제로 인식이 필요한 페이지만 OCR로 보내세요.

당신의 상황권장 사례이유
단일 페이지에서 공백이 아닌 문자를 40개 이상 추출합니다.직접 추출(TEXT_CANDIDATE)이미 문자가 충분하지만 여전히 숨겨진 잘못된 OCR 레이어가 있는지 확인해야 합니다.
40단어 미만, 페이지의 최소 70%를 차지하는 단일 이미지OCR 후보 대기열로 보내기전체 페이지 스캔은 식별에 적합하지만 순수한 사진으로도 충분합니다.
빈 페이지, 벡터 유형, 희박한 제목 또는 복잡한 퍼즐수동 점검(검토)이러한 상황은 처음 두 범주로 확실하게 분류할 수 없으며 자동으로 건너뛰거나 삭제할 수 없습니다.
300페이지 분량의 하이브리드 문서페이지별로 프리플라이트(처리가 완료되지 않음)스캔한 첨부 파일이 몇 개 있기 때문에 모든 페이지를 OCR하거나 홈페이지에 텍스트가 있기 때문에 모든 OCR을 건너뛰지 마세요.

참고: 사진의 내용은 고객 파일이나 OmniDoc 인터페이스가 아닌 아래 코드로 생성된 합성 PDF에서 가져온 것입니다. 이미지 페이지의 텍스트는 래스터 픽셀입니다. 텍스트 페이지의 텍스트에는 실제 텍스트 레이어가 있습니다.

먼저 확인할 사항을 결정하세요

여기에는 공백을 제거한 후의 텍스트 문자 수와 페이지에서 가장 큰 그림이 차지하는 페이지 영역의 비율이라는 두 가지 신호가 사용됩니다. 전자는 "충분한 문자가 추출되었습니까?"라고 대답합니다. 후자는 전체 페이지 스캔과 빈 페이지를 구별하는 데 도움이 됩니다. 페이지의 이미지 확대 비율을 초과하지 않도록 이미지 영역이 먼저 자르기 상자와 교차합니다.

관찰이 기사의 전환여전히 주의가 필요합니다
최소 40개의 빈칸이 아닌 문자가 필요합니다TEXT_CANDIDATE숨겨진 나쁜 OCR 레이어에는 단어가 많을 수도 있습니다
40단어 미만, 단일 이미지의 최소 70% 커버리지가 있어야 합니다OCR_CANDIDATE순수 사진도 요구 조건을 충족합니다; OCR은 의미가 없을 수 있습니다
나머지 상황REVIEW빈 공간, 벡터 텍스트, 드문드문 제목, 복잡한 퍼즐 등이 모두 포함될 수 있습니다

40과 0.70의 임계값은 이 테스트 세트를 감사하기 쉽게 만들기 위한 것이지, 다언어 표준이 아닙니다. 중국어, 공식, 표지, 단축형은 별도로 라벨링해야 합니다. 여기서는 단순히 겹치는 이미지의 영역을 추가하는 것이 아니라 영역별로 가장 큰 이미지를 선택합니다. 따라서 여러 이미지로 구성된 스캔된 페이지는 REVIEW에 포함될 수 있습니다. 이것은 의도적으로 보존된 경계입니다.

완전 실행 가능한 샘플

샘플은 PyMuPDF==1.28.0를 사용하며, 테서랙트에 의존하지 않고, 온라인 OCR이나 번역 서비스를 호출하지 않습니다. example.py로 저장하고 빈 디렉터리에서 실행하세요. 생성되는 파일 이름은 routing-fixture.pdf로 고정되어 있습니다. 실제 프로젝트의 경우, 입력 파일을 덮어쓰지 마세요.

import json
import pymupdf

def inspect_page(page):
    chars = len("".join(page.get_text().split()))
    bounds = page.cropbox
    # 图片坐标与文本坐标都是未旋转坐标;不要混用旋转后的 page.rect。
    bounds = pymupdf.Rect(0, 0, bounds.width, bounds.height)
    ratios = []
    for image in page.get_image_info():
        rect = pymupdf.Rect(image["bbox"]) & bounds
        ratios.append(max(0, rect.get_area()) / bounds.get_area())
    largest = max(ratios, default=0.0)
    route = ("TEXT_CANDIDATE" if chars >= 40 else
             "OCR_CANDIDATE" if largest >= 0.70 else "REVIEW")
    return {"page": page.number + 1, "chars": chars,
            "largest_image_ratio": round(largest, 3), "route": route}

with pymupdf.open() as source:
    page = source.new_page(width=360, height=480)
    page.insert_text((28, 60), "Sample invoice 2026-09-26", fontsize=16)
    page.insert_text((28, 100), "Quantity 12   Unit price USD 15.00", fontsize=12)
    page.insert_text((28, 132), "Amount USD 180.00   Checked manually", fontsize=12)
    scan = page.get_pixmap(matrix=pymupdf.Matrix(2, 2)).tobytes("png")
    page = source.new_page(width=360, height=480)
    page.insert_image(page.rect, stream=scan)
    source.new_page(width=360, height=480)
    source.save("routing-fixture.pdf")

with pymupdf.open("routing-fixture.pdf") as pdf:
    result = [inspect_page(page) for page in pdf]
    assert [r["route"] for r in result] == [
        "TEXT_CANDIDATE", "OCR_CANDIDATE", "REVIEW"]
    assert result[1]["chars"] == 0
    assert result[1]["largest_image_ratio"] == 1.0
    pdf[1].set_rotation(90)
    assert inspect_page(pdf[1])["route"] == "OCR_CANDIDATE"
print(json.dumps(result, indent=2))

OCR에 접근할 때는 성공 표시가 아닌 텍스트페이지를 캐시하세요

PyMuPDF의 OCR 인터페이스는 page.get_textpage_ocr(...)입니다. 테서랙트와 해당 언어 데이터는 별도로 준비되어야 합니다. 텍스트 페이지를 얻은 후, 이후 추출 시 동일한 페이지에서 중복 인식을 방지하기 위해 textpage 매개변수로 전달해야 합니다. 구체적인 설치 방법과 매개변수는 PyMuPDF OCR 문서를 참조해 주십시오.

이 글은 OCR 엔진을 사용하지 않으므로 테스트 결과는 분포 논리와 좌표 사용이 올바름을 증명할 뿐, 중국어 인식률, 표 복원률, 번역 품질을 나타내지 않습니다. 운영 환경에서는 OCR 엔진 버전, 언어 팩, 페이지 번호, 입력 파일 요약, 수동 샘플링 결과가 기록되어야 합니다. 마지막 문자열만 남기지 마세요. 그렇지 않으면 숫자가 어느 페이지에서 나왔는지 해석하기 어렵습니다.

가장 쉽게 간과되는 세 가지 유형의 결함

숨겨진 텍스트 레이어는 텍스트가 뒤섞일 수 있습니다. 문자 수를 충족한다는 것은 "추출 시도를 계속할 수 있다"는 의미일 뿐입니다. 또한 교체된 문자, 중복 라인, 키 필드가 렌더링과 일치하는지 확인해야 합니다. 계약 번호와 금액과 같은 핵심 항목은 무작위로 검사해야 합니다.

벡터 경로에 의해 그려지는 텍스트도 이미지도 아닙니다. 그들은 검토 항목에 진입할 것입니다. 페이지를 자동으로 빈칸으로 표시하지 말고, 조용히 페이지를 드롭하지 마세요.

문서를 닫은 후 페이지를 사용하면 유효하지 않은 객체가 생성됩니다. with pymupdf.open(...)의 범위를 유지하시고, 사전 검사, 렌더링, 추출 후에만 파일을 해제해 주세요. 좌표, 이미지 정보, 페이지 수명 주기에 대한 자세한 내용은 PyMuPDF Page API를 참조하세요.

신뢰할 수 없는 PDF는 독립 실행형 프로세스에서 파일 크기, 페이지 수, 렌더링 픽셀, 시간, 메모리 제한도 설정해야 합니다. 이 예시는 작은 파일만 테스트하며 악성 파일에 대한 샌드박스를 제공하지 않습니다. PyMuPDF를 제작하고 사용하기 전에 라이선스 조건과 배포 방식을 반드시 확인해야 합니다.

스트림에서 번역 워크플로우로의 전환

적격 출력물은 텍스트 문자열이 아니라 페이지 번호와 결정 이유가 적힌 기록입니다. 번역하기 전에 어떤 페이지를 신뢰성 있게 추출할 수 있는지 확인하세요; 번역 후에는 내용, 번호, 레이아웃을 검토합니다. 옴니닥 제품 항목에서 문서 처리 서비스를 볼 수 있습니다. 이 글의 로컬 프로그램은 독립적으로 실행되며 OmniDoc 계정에 의존하지 않으며, 내부 제품 알고리즘이라는 의미도 아닙니다.

📊 핵심 비교

노선트리거 조건적합한 페이지주요 위험
직접 추출 (TEXT_CANDIDATE)최소 40개의 빈칸 문자가 필요합니다기존 텍스트 레이어의 본문 페이지숨겨진 나쁜 OCR 레이어에는 뒤섞인 텍스트가 포함될 수 있습니다
OCR 후보자 (OCR_CANDIDATE)40단어 미만, 한 장의 이미지가 최소 70%를 차지하는 경우입니다전체 페이지 스캔본순수 사진도 요구 조건을 충족하지만, OCR 결과가 의미가 없을 수 있습니다
수동 검사 (검토)위의 두 가지 범주를 충족하지 못합니다빈 페이지, 벡터 텍스트, 드문드문 제목, 복잡한 퍼즐수동 판단이 필요하며, 건너뛰거나 폐기하는 것은 자동으로 할 수 없습니다

🎯 어떤 방법이 당신에게 맞나요?

만약 네가 ......

  • 앞뒤 페이지 품질 차이가 큰 혼합 문서 처리: 페이지별 사전 확인, 각각 다른 경로로 진입.
  • 주로 계약서, 재무 문서 및 주요 번호가 포함된 기타 문서를 다룹니다: 페이지 TEXT_CANDIDATE의 경우, 숫자와 렌더링 간의 대응 관계를 무작위로 확인합니다.
  • 스캔의 배치 처리: OCR 결과에 대한 엔진 버전, 언어 팩, 페이지 번호를 기록하여 쉽게 추적할 수 있습니다.
  • 출처가 알려지지 않은 PDF를 수신: 독립 실행형 프로세스에서 자원 한도를 설정하며; 메인 프로세스에서 직접 처리하지 마십시오.

❓ 자주 묻는 질문 (FAQ)

1. 홈페이지는 텍스트를 복사할 수 있는데, 전체 PDF에 대해 OCR 과정을 건너뛸 수 있나요?

아니, 그럴 수 없어. 첫 페이지에 텍스트 레이어가 있다고 해서 다음 페이지에도 그런 레이어가 있다는 뜻은 아니며; 페이지별로 판단해야 합니다.

2. 왜 이미지 영역을 직접 합산하지 않나요?

겹치는 이미지를 면적별로 추가하면 커버리지 속도를 과대평가할 수 있습니다. 이 글은 면적별로 가장 큰 이미지를 사용하므로, 여러 이미지를 이어 붙인 스캔 페이지는 의도된 경계인 리뷰(REVIEW) 섹션에 포함될 수 있습니다.

3. 글자 수가 40개에 도달하면 텍스트 품질이 괜찮다는 뜻인가요?

그렇게 결론 내릴 수 없다. 숨겨진 나쁜 OCR 레이어는 문자가 많을 수도 있으니, 대체 문자가 없는지 확인하고, 중복된 줄이 있는지, 키 필드를 찾아야 합니다.

4. 벡터 경로로 그려진 텍스트는 어떻게 처리해야 하나요?

텍스트나 이미지가 아니며, REVIEW를 입력하고 수동으로 심사됩니다; 자동으로 빈 페이지나 조용히 삭제된 페이지로 표시되어서는 안 됩니다.

5. 지역 프로그램이 OmniDoc 계정을 사용하나요?

의존하지 않습니다. 이 글에 나오는 지역 프로그램은 독립적으로 운영되며 온라인 OCR이나 번역 서비스를 호출하지 않습니다.

📝 요약

먼저, OCR을 실시할지 결정하기 전에 증거를 페이지별로 남겨두세요. 불확실한 페이지를 대기열에 남기는 것이 불확실한 결과를 성공으로 위장하는 것보다 더 효과적입니다.

지금 경험해보세요: 원본 형식을 유지하면서 번역을 시작하려면 문서를 업로드하세요

업데이트: 2026-11-15