Spaces:
Sleeping
Sleeping
Pointf5ive commited on
Commit ·
f7a5a9f
1
Parent(s): 9f024f9
Speed up fallback OCR rendering and keep progress moving
Browse files- smoke_signal_tab.py +55 -20
smoke_signal_tab.py
CHANGED
|
@@ -726,9 +726,9 @@ try:
|
|
| 726 |
except Exception:
|
| 727 |
SS_RENDER_DPI_SURYA = 300
|
| 728 |
try:
|
| 729 |
-
SS_RENDER_DPI_FALLBACK = max(72, int(os.environ.get("SS_RENDER_DPI_FALLBACK", "
|
| 730 |
except Exception:
|
| 731 |
-
SS_RENDER_DPI_FALLBACK =
|
| 732 |
|
| 733 |
|
| 734 |
def _load_surya_runtime():
|
|
@@ -978,6 +978,7 @@ def run_ocr(progress=gr.Progress(track_tqdm=False)) -> tuple:
|
|
| 978 |
log.append(log_line(f"⚠ Surya unavailable ({surya_error}) — using Tesseract fallback for this run"))
|
| 979 |
|
| 980 |
total_pages_planned = 0
|
|
|
|
| 981 |
for _, row in eligible.iterrows():
|
| 982 |
profile_path = PROFILES_DIR / f"{row['book_id']}_page_profile.json"
|
| 983 |
if not profile_path.exists():
|
|
@@ -985,13 +986,16 @@ def run_ocr(progress=gr.Progress(track_tqdm=False)) -> tuple:
|
|
| 985 |
try:
|
| 986 |
with open(profile_path, encoding="utf-8") as f:
|
| 987 |
profile = json.load(f)
|
| 988 |
-
|
|
|
|
|
|
|
| 989 |
except Exception:
|
| 990 |
continue
|
| 991 |
total_pages_planned = max(total_pages_planned, 1)
|
| 992 |
-
|
| 993 |
rendered_pages = 0
|
| 994 |
-
|
|
|
|
| 995 |
|
| 996 |
for _, row in eligible.iterrows():
|
| 997 |
book_id = row["book_id"]
|
|
@@ -1035,14 +1039,37 @@ def run_ocr(progress=gr.Progress(track_tqdm=False)) -> tuple:
|
|
| 1035 |
render_path = None
|
| 1036 |
if doc is not None:
|
| 1037 |
try:
|
| 1038 |
-
|
| 1039 |
-
|
| 1040 |
-
|
| 1041 |
-
|
| 1042 |
-
|
| 1043 |
-
|
| 1044 |
-
|
| 1045 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1046 |
except Exception as e:
|
| 1047 |
log.append(log_line(f" ⚠ {book_id} p{page_num}: render failed ({e})"))
|
| 1048 |
|
|
@@ -1111,10 +1138,20 @@ def run_ocr(progress=gr.Progress(track_tqdm=False)) -> tuple:
|
|
| 1111 |
"confidence": conf,
|
| 1112 |
"method": "surya",
|
| 1113 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1114 |
else:
|
| 1115 |
fallback_preds = _run_tesseract_batch(batch_images)
|
| 1116 |
for item, pred in zip(batch_items_with_images, fallback_preds):
|
| 1117 |
ocr_lookup[item["page_num"]] = pred
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1118 |
except Exception as e:
|
| 1119 |
# If Surya batch fails, try Tesseract for this batch before giving up.
|
| 1120 |
if surya is not None:
|
|
@@ -1122,6 +1159,11 @@ def run_ocr(progress=gr.Progress(track_tqdm=False)) -> tuple:
|
|
| 1122 |
fallback_preds = _run_tesseract_batch(batch_images)
|
| 1123 |
for item, pred in zip(batch_items_with_images, fallback_preds):
|
| 1124 |
ocr_lookup[item["page_num"]] = pred
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1125 |
else:
|
| 1126 |
for item in batch_items_with_images:
|
| 1127 |
ocr_lookup[item["page_num"]] = {
|
|
@@ -1142,11 +1184,6 @@ def run_ocr(progress=gr.Progress(track_tqdm=False)) -> tuple:
|
|
| 1142 |
page_num = page_data["page_number"]
|
| 1143 |
route = page_data["route"]
|
| 1144 |
|
| 1145 |
-
progress(
|
| 1146 |
-
(total_pages_planned + processed_pages, total_work_units),
|
| 1147 |
-
desc=f"OCR {book_id} p{page_num}/{len(profile.get('pages', []))}",
|
| 1148 |
-
)
|
| 1149 |
-
|
| 1150 |
if route == "embedded_text":
|
| 1151 |
try:
|
| 1152 |
if doc is None:
|
|
@@ -1211,8 +1248,6 @@ def run_ocr(progress=gr.Progress(track_tqdm=False)) -> tuple:
|
|
| 1211 |
"reason_code": "",
|
| 1212 |
})
|
| 1213 |
|
| 1214 |
-
processed_pages += 1
|
| 1215 |
-
|
| 1216 |
if doc is not None:
|
| 1217 |
try:
|
| 1218 |
doc.close()
|
|
|
|
| 726 |
except Exception:
|
| 727 |
SS_RENDER_DPI_SURYA = 300
|
| 728 |
try:
|
| 729 |
+
SS_RENDER_DPI_FALLBACK = max(72, int(os.environ.get("SS_RENDER_DPI_FALLBACK", "200")))
|
| 730 |
except Exception:
|
| 731 |
+
SS_RENDER_DPI_FALLBACK = 200
|
| 732 |
|
| 733 |
|
| 734 |
def _load_surya_runtime():
|
|
|
|
| 978 |
log.append(log_line(f"⚠ Surya unavailable ({surya_error}) — using Tesseract fallback for this run"))
|
| 979 |
|
| 980 |
total_pages_planned = 0
|
| 981 |
+
total_ocr_targets_planned = 0
|
| 982 |
for _, row in eligible.iterrows():
|
| 983 |
profile_path = PROFILES_DIR / f"{row['book_id']}_page_profile.json"
|
| 984 |
if not profile_path.exists():
|
|
|
|
| 986 |
try:
|
| 987 |
with open(profile_path, encoding="utf-8") as f:
|
| 988 |
profile = json.load(f)
|
| 989 |
+
pages = profile.get("pages", [])
|
| 990 |
+
total_pages_planned += len(pages)
|
| 991 |
+
total_ocr_targets_planned += sum(1 for p in pages if p.get("route") != "embedded_text")
|
| 992 |
except Exception:
|
| 993 |
continue
|
| 994 |
total_pages_planned = max(total_pages_planned, 1)
|
| 995 |
+
total_ocr_targets_planned = max(total_ocr_targets_planned, 1)
|
| 996 |
rendered_pages = 0
|
| 997 |
+
ocr_processed_pages = 0
|
| 998 |
+
total_work_units = max(total_pages_planned + total_ocr_targets_planned, 1)
|
| 999 |
|
| 1000 |
for _, row in eligible.iterrows():
|
| 1001 |
book_id = row["book_id"]
|
|
|
|
| 1039 |
render_path = None
|
| 1040 |
if doc is not None:
|
| 1041 |
try:
|
| 1042 |
+
existing_rel = page_data.get("render_path")
|
| 1043 |
+
existing_dpi = int(page_data.get("render_dpi", 0) or 0)
|
| 1044 |
+
existing_abs = (SS_ROOT / existing_rel) if existing_rel else None
|
| 1045 |
+
if existing_abs and existing_abs.exists() and existing_dpi == render_dpi:
|
| 1046 |
+
render_path = existing_abs
|
| 1047 |
+
else:
|
| 1048 |
+
page = doc[page_num - 1]
|
| 1049 |
+
render_start = time.time()
|
| 1050 |
+
if surya is None:
|
| 1051 |
+
pix = page.get_pixmap(
|
| 1052 |
+
dpi=render_dpi,
|
| 1053 |
+
alpha=False,
|
| 1054 |
+
annots=False,
|
| 1055 |
+
colorspace=fitz.csGRAY,
|
| 1056 |
+
)
|
| 1057 |
+
else:
|
| 1058 |
+
pix = page.get_pixmap(
|
| 1059 |
+
dpi=render_dpi,
|
| 1060 |
+
alpha=False,
|
| 1061 |
+
annots=False,
|
| 1062 |
+
colorspace=fitz.csRGB,
|
| 1063 |
+
)
|
| 1064 |
+
render_dir = RENDERS_DIR / book_id
|
| 1065 |
+
render_dir.mkdir(exist_ok=True)
|
| 1066 |
+
render_path = render_dir / f"{book_id}_page_{page_num:04d}_{render_dpi}dpi.png"
|
| 1067 |
+
pix.save(str(render_path))
|
| 1068 |
+
render_secs = round(time.time() - render_start, 2)
|
| 1069 |
+
if render_secs >= 4.0:
|
| 1070 |
+
log.append(log_line(f" ⚠ {book_id} p{page_num}: slow render {render_secs}s at {render_dpi}dpi"))
|
| 1071 |
+
page_data["render_path"] = str(render_path.relative_to(SS_ROOT))
|
| 1072 |
+
page_data["render_dpi"] = render_dpi
|
| 1073 |
except Exception as e:
|
| 1074 |
log.append(log_line(f" ⚠ {book_id} p{page_num}: render failed ({e})"))
|
| 1075 |
|
|
|
|
| 1138 |
"confidence": conf,
|
| 1139 |
"method": "surya",
|
| 1140 |
}
|
| 1141 |
+
ocr_processed_pages += 1
|
| 1142 |
+
progress(
|
| 1143 |
+
(total_pages_planned + ocr_processed_pages, total_work_units),
|
| 1144 |
+
desc=f"OCR {book_id} p{item['page_num']}",
|
| 1145 |
+
)
|
| 1146 |
else:
|
| 1147 |
fallback_preds = _run_tesseract_batch(batch_images)
|
| 1148 |
for item, pred in zip(batch_items_with_images, fallback_preds):
|
| 1149 |
ocr_lookup[item["page_num"]] = pred
|
| 1150 |
+
ocr_processed_pages += 1
|
| 1151 |
+
progress(
|
| 1152 |
+
(total_pages_planned + ocr_processed_pages, total_work_units),
|
| 1153 |
+
desc=f"Tesseract {book_id} p{item['page_num']}",
|
| 1154 |
+
)
|
| 1155 |
except Exception as e:
|
| 1156 |
# If Surya batch fails, try Tesseract for this batch before giving up.
|
| 1157 |
if surya is not None:
|
|
|
|
| 1159 |
fallback_preds = _run_tesseract_batch(batch_images)
|
| 1160 |
for item, pred in zip(batch_items_with_images, fallback_preds):
|
| 1161 |
ocr_lookup[item["page_num"]] = pred
|
| 1162 |
+
ocr_processed_pages += 1
|
| 1163 |
+
progress(
|
| 1164 |
+
(total_pages_planned + ocr_processed_pages, total_work_units),
|
| 1165 |
+
desc=f"Tesseract retry {book_id} p{item['page_num']}",
|
| 1166 |
+
)
|
| 1167 |
else:
|
| 1168 |
for item in batch_items_with_images:
|
| 1169 |
ocr_lookup[item["page_num"]] = {
|
|
|
|
| 1184 |
page_num = page_data["page_number"]
|
| 1185 |
route = page_data["route"]
|
| 1186 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1187 |
if route == "embedded_text":
|
| 1188 |
try:
|
| 1189 |
if doc is None:
|
|
|
|
| 1248 |
"reason_code": "",
|
| 1249 |
})
|
| 1250 |
|
|
|
|
|
|
|
| 1251 |
if doc is not None:
|
| 1252 |
try:
|
| 1253 |
doc.close()
|