Spaces:
Paused
Paused
File size: 2,685 Bytes
41bc097 1da72c8 41bc097 1da72c8 41bc097 1da72c8 41bc097 1da72c8 41bc097 1da72c8 41bc097 1da72c8 41bc097 1da72c8 41bc097 1da72c8 41bc097 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | """
PHASE 7: OCR module for screenshot/image claim input.
Extracts text from uploaded images (e.g. WhatsApp forward screenshots) using
EasyOCR so claims that arrive as pictures -- not just typed text -- can be
verified.
The OCR path now supports the same language selections as the checker UI.
"""
from functools import lru_cache
import easyocr
# Below this confidence, EasyOCR's guess is unreliable enough that including
# it does more harm than good to the downstream claim text.
MIN_CONFIDENCE = 0.4
SUPPORTED_LANGUAGES = {"en", "hi", "mr", "es"}
@lru_cache(maxsize=8)
def _get_reader(language_code: str):
"""Create and cache an EasyOCR reader for the requested language."""
normalized = (language_code or "en").lower()
if normalized not in SUPPORTED_LANGUAGES:
normalized = "en"
candidate_langs = [normalized]
if normalized != "en":
candidate_langs.append("en")
last_error = None
for langs in candidate_langs:
try:
return easyocr.Reader([langs], gpu=False)
except Exception as exc: # pragma: no cover - depends on runtime model availability
last_error = exc
# Final fallback to English if the requested language pack is unavailable.
return easyocr.Reader(["en"], gpu=False)
def extract_text_from_image(image_bytes: bytes, language_code: str = "en") -> str:
"""
Runs OCR on raw image bytes and returns the concatenated recognized text,
in reading order top-to-bottom as EasyOCR detects it.
Returns an empty string if nothing readable was found above the
confidence threshold -- callers should treat that as "OCR failed" and
not silently pass empty text further down the pipeline.
"""
reader = _get_reader(language_code)
results = reader.readtext(image_bytes)
lines = [text.strip() for (_bbox, text, confidence) in results if confidence >= MIN_CONFIDENCE]
if not lines and language_code != "en":
fallback_reader = _get_reader("en")
fallback_results = fallback_reader.readtext(image_bytes)
lines = [text.strip() for (_bbox, text, confidence) in fallback_results if confidence >= MIN_CONFIDENCE]
return " ".join(lines).strip()
if __name__ == "__main__":
# Quick manual test -- run: python ocr_utils.py path/to/screenshot.png
import sys
if len(sys.argv) < 2:
print("Usage: python ocr_utils.py <path_to_image>")
sys.exit(1)
with open(sys.argv[1], "rb") as f:
image_bytes = f.read()
text = extract_text_from_image(image_bytes)
if text:
print(f"Extracted text:\n{text}")
else:
print("No readable text found above confidence threshold.")
|