jp22082001 commited on
Commit
8b4e2a1
·
1 Parent(s): d0b9b19

Auto-update via watch script

Browse files
Files changed (1) hide show
  1. app.py +60 -0
app.py CHANGED
@@ -220,6 +220,66 @@ def _spinner(msg: str, color: str = "#3b82f6", bg: str = "rgba(59,130,246,0.08)"
220
  # Main processing functions
221
  # ---------------------------------------------------------------------------
222
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
  def extract_full_article(image: Image.Image, hf_token: str) -> tuple[str, str]:
224
  """
225
  Hybrid extraction:
 
220
  # Main processing functions
221
  # ---------------------------------------------------------------------------
222
 
223
+ def _preprocess_image(image: Image.Image) -> Image.Image:
224
+ img = image.convert("L")
225
+ w, h = img.size
226
+ if w < 1800:
227
+ scale = 1800 / w
228
+ img = img.resize((int(w * scale), int(h * scale)), getattr(Image, "Resampling", Image).LANCZOS)
229
+ img = ImageEnhance.Contrast(img).enhance(1.8)
230
+ img = ImageEnhance.Sharpness(img).enhance(2.0)
231
+ return img.convert("RGB")
232
+
233
+
234
+ def _column_aware_ocr(image: Image.Image) -> str:
235
+ data = pytesseract.image_to_data(image, config="--psm 11 -l eng", output_type=pytesseract.Output.DICT)
236
+ img_width = image.size[0]
237
+
238
+ words = []
239
+ for i, text in enumerate(data["text"]):
240
+ text = text.strip()
241
+ if not text or data["word_num"][i] == 0 or int(data["conf"][i]) < 30:
242
+ continue
243
+ words.append({"text": text, "x": data["left"][i], "y": data["top"][i]})
244
+
245
+ if not words:
246
+ return ""
247
+
248
+ gap_threshold = img_width * 0.15
249
+ sorted_x = sorted(set(w["x"] for w in words))
250
+ col_starts = [0]
251
+ for idx in range(1, len(sorted_x)):
252
+ if sorted_x[idx] - sorted_x[idx - 1] > gap_threshold:
253
+ col_starts.append(sorted_x[idx])
254
+
255
+ def assign_col(x):
256
+ col = 0
257
+ for j, start in enumerate(col_starts):
258
+ if x >= start:
259
+ col = j
260
+ return col
261
+
262
+ for word in words:
263
+ word["col"] = assign_col(word["x"])
264
+
265
+ result_parts = []
266
+ for col_idx in range(len(col_starts)):
267
+ col_words = sorted([w for w in words if w["col"] == col_idx], key=lambda w: (w["y"], w["x"]))
268
+ if not col_words:
269
+ continue
270
+ lines, current = [], [col_words[0]]
271
+ for word in col_words[1:]:
272
+ if abs(word["y"] - current[0]["y"]) <= 8:
273
+ current.append(word)
274
+ else:
275
+ lines.append(current)
276
+ current = [word]
277
+ lines.append(current)
278
+ result_parts.append("\n".join(" ".join(w["text"] for w in line) for line in lines))
279
+
280
+ return "\n\n".join(result_parts)
281
+
282
+
283
  def extract_full_article(image: Image.Image, hf_token: str) -> tuple[str, str]:
284
  """
285
  Hybrid extraction: