PACWIN2027/Form_Summary_Extraction
0
1# -*- coding: utf-8 -*-
2"""Tesseract fallback for scanned pages.
3
4Most Punjab electoral PDFs published since ~2019 carry a real text layer, which
5is both faster and far more accurate than OCR. This module only runs for pages
6where :attr:`extractor.pdfsource.Page.has_text_layer` is False.
7"""
8
9import os
10
11OCR_LANG = os.environ.get('OCR_LANG', 'pan+eng')
12OCR_DPI = int(os.environ.get('OCR_DPI', '300'))
13OCR_PSM = os.environ.get('OCR_PSM', '6')
14
15
16def available():
17 """True when both pytesseract and a rendering backend are importable."""
18 try:
19 import pypdfium2 # noqa: F401
20 import pytesseract
21 pytesseract.get_tesseract_version()
22 return True
23 except Exception:
24 return False
25
26
27def languages():
28 try:
29 import pytesseract
30 return pytesseract.get_languages(config='')
31 except Exception:
32 return []
33
34
35def ocr_pages(pdf_path, page_numbers):
36 """OCR the given 1-based page numbers, returning ``{page_no: [line, ...]}``."""
37 if not page_numbers or not available():
38 return {}
39
40 import pypdfium2
41 import pytesseract
42
43 lang = OCR_LANG
44 if 'pan' in lang and 'pan' not in languages():
45 # Punjabi model missing - fall back to English so the page is not lost.
46 lang = 'eng'
47
48 out = {}
49 doc = pypdfium2.PdfDocument(pdf_path)
50 try:
51 scale = OCR_DPI / 72.0
52 for number in page_numbers:
53 page = doc[number - 1]
54 image = page.render(scale=scale).to_pil()
55 text = pytesseract.image_to_string(
56 image, lang=lang, config='--oem 1 --psm %s' % OCR_PSM)
57 out[number] = [l.strip() for l in text.splitlines() if l.strip()]
58 finally:
59 doc.close()
60 return out
61
62
63def scanned_page_numbers(pages):
64 return [p.number for p in pages if not p.has_text_layer]
65 