rehan953 commited on
Commit
162894b
·
verified ·
1 Parent(s): b0e24e3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +26 -9
app.py CHANGED
@@ -30,12 +30,17 @@ GLMOCR_BASE = os.path.dirname(glmocr.__file__)
30
  CONFIG_PATH = os.path.join(GLMOCR_BASE, "config.yaml")
31
  FORMATTER_PATH = os.path.join(GLMOCR_BASE, "postprocess", "result_formatter.py")
32
 
 
 
33
  DEFAULT_ZONE_FRAC = float(os.environ.get("GLMOCR_DEFAULT_ZONE_FRAC", "0.12"))
 
34
  MIN_CROP_HEIGHT = int(os.environ.get("GLMOCR_MIN_CROP_HEIGHT", "112"))
35
  MIN_CROP_PIXELS = int(os.environ.get("GLMOCR_MIN_CROP_PIXELS", "12544")) # 112*112
 
36
  PDF_HEADER_BAND_FRAC = float(os.environ.get("GLMOCR_PDF_HEADER_BAND", "0.15")) # top 15%
37
  PDF_FOOTER_BAND_FRAC = float(os.environ.get("GLMOCR_PDF_FOOTER_BAND", "0.85")) # bottom 15%
38
 
 
39
  _parser = None
40
 
41
  def get_parser():
@@ -133,7 +138,8 @@ def extract_zone_text_pdf(pdf_path, page_num, y_start_frac, y_end_frac):
133
 
134
 
135
  def extract_pdf_text_in_band(pdf_path, page_num, y_start_frac, y_end_frac):
136
- """Extract all text whose word bbox falls in the given vertical band (by position)."""
 
137
  try:
138
  import pymupdf as fitz
139
  doc = fitz.open(pdf_path)
@@ -155,7 +161,7 @@ def extract_pdf_text_in_band(pdf_path, page_num, y_start_frac, y_end_frac):
155
 
156
 
157
  def ocr_zone(image_path, y_start_frac, y_end_frac):
158
- """Run OCR on a horizontal band. Pads small crops to meet API minimum size."""
159
  zone_name = "header" if y_end_frac < 0.5 else "footer"
160
  try:
161
  from PIL import Image
@@ -167,6 +173,7 @@ def ocr_zone(image_path, y_start_frac, y_end_frac):
167
  return ""
168
  crop = img.crop((0, y0, w, y1))
169
  cw, ch = crop.size
 
170
  if ch < MIN_CROP_HEIGHT or (cw * ch) < MIN_CROP_PIXELS:
171
  need_h = max(ch, MIN_CROP_HEIGHT)
172
  need_w = max(cw, 1)
@@ -174,9 +181,9 @@ def ocr_zone(image_path, y_start_frac, y_end_frac):
174
  need_w = max(need_w, (MIN_CROP_PIXELS + need_h - 1) // need_h)
175
  canvas = Image.new("RGB", (need_w, need_h), (255, 255, 255))
176
  if zone_name == "header":
177
- canvas.paste(crop, (0, 0))
178
  else:
179
- canvas.paste(crop, (0, need_h - ch))
180
  crop = canvas
181
  cw, ch = crop.size
182
  fd, path = tempfile.mkstemp(suffix=".jpg")
@@ -218,6 +225,14 @@ def get_page_md_and_regions(page_result):
218
  return md, regions
219
 
220
 
 
 
 
 
 
 
 
 
221
  def run_ocr(uploaded_file):
222
  if uploaded_file is None:
223
  return "Please upload a file."
@@ -250,16 +265,17 @@ def run_ocr(uploaded_file):
250
  page_md, regions = get_page_md_and_regions(page_result)
251
  header_end_frac, footer_start_frac = get_header_footer_zones(regions, 1000)
252
 
 
253
  he = header_end_frac if header_end_frac is not None else DEFAULT_ZONE_FRAC
254
  fs = footer_start_frac if footer_start_frac is not None else (1.0 - DEFAULT_ZONE_FRAC)
255
  if he <= 0:
256
- he = DEFAULT_ZONE_FRAC
257
  if fs >= 1.0:
258
- fs = 1.0 - DEFAULT_ZONE_FRAC
259
 
260
  parts = []
261
 
262
- # Always run header band (top 8-12% of page)
263
  if page_num < len(page_images):
264
  img_path = page_images[page_num]
265
  hdr = ""
@@ -275,7 +291,7 @@ def run_ocr(uploaded_file):
275
  if page_md:
276
  parts.append(page_md)
277
 
278
- # Always run footer band (bottom 8-12% of page)
279
  if page_num < len(page_images):
280
  img_path = page_images[page_num]
281
  ftr = ""
@@ -285,7 +301,8 @@ def run_ocr(uploaded_file):
285
  ftr = extract_pdf_text_in_band(path, page_num, PDF_FOOTER_BAND_FRAC, 1.0)
286
  if not (ftr and ftr.strip()):
287
  ftr = ocr_zone(img_path, fs, 1.0)
288
- if ftr and ftr.strip():
 
289
  parts.append(ftr.strip())
290
 
291
  if parts:
 
30
  CONFIG_PATH = os.path.join(GLMOCR_BASE, "config.yaml")
31
  FORMATTER_PATH = os.path.join(GLMOCR_BASE, "postprocess", "result_formatter.py")
32
 
33
+ # When MaaS is enabled, the cloud API ignores local layout config and does not return
34
+ # header/footer regions. We always run client-side OCR on top/bottom bands as fallback.
35
  DEFAULT_ZONE_FRAC = float(os.environ.get("GLMOCR_DEFAULT_ZONE_FRAC", "0.12"))
36
+ # MaaS rejects very small images (400). Only send crops that meet minimum dimensions.
37
  MIN_CROP_HEIGHT = int(os.environ.get("GLMOCR_MIN_CROP_HEIGHT", "112"))
38
  MIN_CROP_PIXELS = int(os.environ.get("GLMOCR_MIN_CROP_PIXELS", "12544")) # 112*112
39
+ # Wider PDF bands for position-based extraction (capture account numbers etc. in top/bottom)
40
  PDF_HEADER_BAND_FRAC = float(os.environ.get("GLMOCR_PDF_HEADER_BAND", "0.15")) # top 15%
41
  PDF_FOOTER_BAND_FRAC = float(os.environ.get("GLMOCR_PDF_FOOTER_BAND", "0.85")) # bottom 15%
42
 
43
+ # Single shared parser to avoid "GLM-OCR initialized" per request and asyncio cleanup issues.
44
  _parser = None
45
 
46
  def get_parser():
 
138
 
139
 
140
  def extract_pdf_text_in_band(pdf_path, page_num, y_start_frac, y_end_frac):
141
+ """Extract all text whose word bbox falls in the given vertical band (by position).
142
+ Use a wider band (e.g. top 15% / bottom 15%) to capture header/footer that clip might miss."""
143
  try:
144
  import pymupdf as fitz
145
  doc = fitz.open(pdf_path)
 
161
 
162
 
163
  def ocr_zone(image_path, y_start_frac, y_end_frac):
164
+ """Run OCR on a horizontal band. Pads small crops to meet API minimum size instead of skipping."""
165
  zone_name = "header" if y_end_frac < 0.5 else "footer"
166
  try:
167
  from PIL import Image
 
173
  return ""
174
  crop = img.crop((0, y0, w, y1))
175
  cw, ch = crop.size
176
+ # Pad to minimum size so MaaS accepts the image (avoids 400 on tiny strips)
177
  if ch < MIN_CROP_HEIGHT or (cw * ch) < MIN_CROP_PIXELS:
178
  need_h = max(ch, MIN_CROP_HEIGHT)
179
  need_w = max(cw, 1)
 
181
  need_w = max(need_w, (MIN_CROP_PIXELS + need_h - 1) // need_h)
182
  canvas = Image.new("RGB", (need_w, need_h), (255, 255, 255))
183
  if zone_name == "header":
184
+ canvas.paste(crop, (0, 0)) # crop at top
185
  else:
186
+ canvas.paste(crop, (0, need_h - ch)) # crop at bottom
187
  crop = canvas
188
  cw, ch = crop.size
189
  fd, path = tempfile.mkstemp(suffix=".jpg")
 
225
  return md, regions
226
 
227
 
228
+ def is_duplicate(text, existing_text):
229
+ """Check if text is already contained in existing_text using first 100 chars as fingerprint."""
230
+ if not text or not existing_text:
231
+ return False
232
+ fingerprint = text[:100].strip()
233
+ return fingerprint in existing_text
234
+
235
+
236
  def run_ocr(uploaded_file):
237
  if uploaded_file is None:
238
  return "Please upload a file."
 
265
  page_md, regions = get_page_md_and_regions(page_result)
266
  header_end_frac, footer_start_frac = get_header_footer_zones(regions, 1000)
267
 
268
+ # MaaS does not return header/footer regions; always use at least default bands
269
  he = header_end_frac if header_end_frac is not None else DEFAULT_ZONE_FRAC
270
  fs = footer_start_frac if footer_start_frac is not None else (1.0 - DEFAULT_ZONE_FRAC)
271
  if he <= 0:
272
+ he = DEFAULT_ZONE_FRAC # ensure we always OCR a top band
273
  if fs >= 1.0:
274
+ fs = 1.0 - DEFAULT_ZONE_FRAC # ensure we always OCR a bottom band
275
 
276
  parts = []
277
 
278
+ # Always run header band (top 812% of page)
279
  if page_num < len(page_images):
280
  img_path = page_images[page_num]
281
  hdr = ""
 
291
  if page_md:
292
  parts.append(page_md)
293
 
294
+ # Always run footer band (bottom 812% of page)
295
  if page_num < len(page_images):
296
  img_path = page_images[page_num]
297
  ftr = ""
 
301
  ftr = extract_pdf_text_in_band(path, page_num, PDF_FOOTER_BAND_FRAC, 1.0)
302
  if not (ftr and ftr.strip()):
303
  ftr = ocr_zone(img_path, fs, 1.0)
304
+ # Only append footer if NOT already present in page_md (avoids duplication)
305
+ if ftr and ftr.strip() and not is_duplicate(ftr, page_md):
306
  parts.append(ftr.strip())
307
 
308
  if parts: