rehan953 commited on
Commit
133ecf3
Β·
verified Β·
1 Parent(s): 0141b9f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +37 -39
app.py CHANGED
@@ -4,8 +4,8 @@ import re
4
  import os
5
 
6
  import glmocr
7
- GLMOCR_BASE = os.path.dirname(glmocr.__file__)
8
- config_path = os.path.join(GLMOCR_BASE, "config.yaml")
9
  formatter_path = os.path.join(GLMOCR_BASE, "postprocess", "result_formatter.py")
10
 
11
  # ── STEP 1: Fix config ────────────────────────────────────────
@@ -14,7 +14,6 @@ with open(config_path, "r") as f:
14
 
15
  config["pipeline"]["maas"]["enabled"] = True
16
  config["pipeline"]["maas"]["api_key"] = "4570c28bdea5493c9efae9dae68edc66.sGbA9DLlcX1GlvqV"
17
-
18
  config["pipeline"]["result_formatter"]["abandon"] = [
19
  "number", "footnote", "aside_text",
20
  "reference", "footer_image", "header_image",
@@ -34,7 +33,7 @@ labels_to_remove = [
34
  '"header"', "'header'",
35
  '"footer"', "'footer'",
36
  '"doc_header"', "'doc_header'",
37
- '"doc_footer"', "'doc_footer'"
38
  ]
39
  for label in labels_to_remove:
40
  source = re.sub(r',\s*' + re.escape(label), '', source)
@@ -46,37 +45,42 @@ with open(formatter_path, "w") as f:
46
 
47
  print("βœ… result_formatter.py fixed")
48
 
49
- # ── STEP 3: Helper functions ──────────────────────────────────
50
- def get_top_gap(regions, img_height):
51
  """
52
- Find the top gap the API missed using bbox_2d coordinates.
53
- Only extracts header (top gap) β€” never bottom β€” to avoid
54
- duplicating body content the API already captured correctly.
55
  """
 
 
56
  y_tops = []
 
57
  for r in regions:
58
  bbox = r.get("bbox_2d")
59
  if bbox and len(bbox) == 4:
60
  y_tops.append(bbox[1])
 
61
  if not y_tops:
62
- return None
63
- first_y = min(y_tops)
64
- return (first_y / img_height) if first_y > img_height * 0.08 else None
 
65
 
66
 
67
  def extract_zone_text(pdf_path, page_num, y_start_frac, y_end_frac):
68
  """Extract text from a vertical slice of a PDF page."""
69
  import pymupdf as fitz
70
- doc = fitz.open(pdf_path)
71
  page = doc[page_num]
72
  h, w = page.rect.height, page.rect.width
73
- text = page.get_text(clip=fitz.Rect(0, h * y_start_frac, w, h * y_end_frac)).strip()
 
74
  doc.close()
75
  return text
76
 
77
 
78
  def get_page_data(page_result):
79
- """Extract markdown and raw regions from one PipelineResult."""
80
  regions = []
81
  if hasattr(page_result, "json_result"):
82
  jr = page_result.json_result
@@ -90,7 +94,7 @@ def get_page_data(page_result):
90
  return md, regions
91
 
92
 
93
- # ── STEP 4: Main OCR function ─────────────────────────────────
94
  def run_ocr(uploaded_file):
95
  if uploaded_file is None:
96
  return "Please upload a file."
@@ -99,26 +103,22 @@ def run_ocr(uploaded_file):
99
  from glmocr import parse
100
  import pymupdf as fitz
101
 
102
- path = uploaded_file.name if hasattr(uploaded_file, "name") else str(uploaded_file)
103
  is_pdf = path.lower().endswith(".pdf")
104
 
105
  if is_pdf:
106
- doc = fitz.open(path)
107
- page_images = []
108
- page_heights = []
109
  for i in range(len(doc)):
110
- pix = doc[i].get_pixmap(matrix=fitz.Matrix(1.5, 1.5), alpha=False)
111
  img_path = f"/tmp/maas_page_{i}.png"
112
  pix.save(img_path)
113
  page_images.append(img_path)
114
- # Image height at 1.5x matches bbox_2d coordinate space
115
- page_heights.append(doc[i].rect.height * 1.5)
116
  doc.close()
117
  results = parse(page_images)
118
  if not isinstance(results, list):
119
  results = [results]
120
  else:
121
- page_heights = []
122
  results = parse(path)
123
  if not isinstance(results, list):
124
  results = [results]
@@ -129,21 +129,21 @@ def run_ocr(uploaded_file):
129
  page_md, regions = get_page_data(page_result)
130
  parts = []
131
 
132
- if is_pdf and page_num < len(page_heights):
133
- top_gap = get_top_gap(regions, page_heights[page_num])
134
 
135
- # HEADER at TOP β€” from PDF text layer (API misses this zone)
136
- if top_gap is not None:
137
- hdr = extract_zone_text(path, page_num, 0, top_gap)
138
- if hdr:
139
- parts.append(hdr)
140
 
141
- # BODY β€” from API (includes all content + footer text correctly)
142
  if page_md:
143
  parts.append(page_md)
144
 
145
- # No bottom zone extraction β€” API already captures footer content.
146
- # Extracting bottom zone causes duplication of body content.
 
 
147
  else:
148
  if page_md:
149
  parts.append(page_md)
@@ -151,7 +151,6 @@ def run_ocr(uploaded_file):
151
  if parts:
152
  all_pages_md.append("\n\n".join(parts))
153
 
154
- # Exactly like original SDK output format
155
  final = "\n\n---\n\n".join(all_pages_md) if all_pages_md else "(No content)"
156
  return final
157
 
@@ -164,17 +163,16 @@ def run_ocr(uploaded_file):
164
  with gr.Blocks(title="GLM-OCR") as demo:
165
  gr.Markdown("""
166
  # πŸ” GLM-OCR
167
- Upload a PDF or image to extract text.
168
- Headers included at top of each page.
169
  """)
170
 
171
  file_input = gr.File(
172
  label="Upload PDF or Image",
173
  file_types=[".pdf", ".png", ".jpg", ".jpeg", ".tiff", ".bmp"]
174
  )
175
- run_btn = gr.Button("β–Ά Run OCR", variant="primary", size="lg")
176
  output_box = gr.Textbox(lines=40, label="Output")
177
 
178
  run_btn.click(fn=run_ocr, inputs=file_input, outputs=output_box)
179
 
180
- demo.launch()
 
4
  import os
5
 
6
  import glmocr
7
+ GLMOCR_BASE = os.path.dirname(glmocr.__file__)
8
+ config_path = os.path.join(GLMOCR_BASE, "config.yaml")
9
  formatter_path = os.path.join(GLMOCR_BASE, "postprocess", "result_formatter.py")
10
 
11
  # ── STEP 1: Fix config ────────────────────────────────────────
 
14
 
15
  config["pipeline"]["maas"]["enabled"] = True
16
  config["pipeline"]["maas"]["api_key"] = "4570c28bdea5493c9efae9dae68edc66.sGbA9DLlcX1GlvqV"
 
17
  config["pipeline"]["result_formatter"]["abandon"] = [
18
  "number", "footnote", "aside_text",
19
  "reference", "footer_image", "header_image",
 
33
  '"header"', "'header'",
34
  '"footer"', "'footer'",
35
  '"doc_header"', "'doc_header'",
36
+ '"doc_footer"', "'doc_footer'",
37
  ]
38
  for label in labels_to_remove:
39
  source = re.sub(r',\s*' + re.escape(label), '', source)
 
45
 
46
  print("βœ… result_formatter.py fixed")
47
 
48
+ # ── STEP 3: Helpers ───────────────────────────────────────────
49
+ def get_header_footer_zones(regions, norm_height=1000):
50
  """
51
+ From API regions' bbox_2d (normalized 0 to norm_height), return
52
+ (header_end_frac, footer_start_frac). No hardcoded percentages.
 
53
  """
54
+ if not regions:
55
+ return None, None
56
  y_tops = []
57
+ y_bottoms = []
58
  for r in regions:
59
  bbox = r.get("bbox_2d")
60
  if bbox and len(bbox) == 4:
61
  y_tops.append(bbox[1])
62
+ y_bottoms.append(bbox[3])
63
  if not y_tops:
64
+ return None, None
65
+ header_end = min(y_tops) / norm_height
66
+ footer_start = max(y_bottoms) / norm_height
67
+ return header_end, footer_start
68
 
69
 
70
  def extract_zone_text(pdf_path, page_num, y_start_frac, y_end_frac):
71
  """Extract text from a vertical slice of a PDF page."""
72
  import pymupdf as fitz
73
+ doc = fitz.open(pdf_path)
74
  page = doc[page_num]
75
  h, w = page.rect.height, page.rect.width
76
+ rect = fitz.Rect(0, h * y_start_frac, w, h * y_end_frac)
77
+ text = page.get_text(clip=rect).strip()
78
  doc.close()
79
  return text
80
 
81
 
82
  def get_page_data(page_result):
83
+ """Return (markdown, regions) for one PipelineResult."""
84
  regions = []
85
  if hasattr(page_result, "json_result"):
86
  jr = page_result.json_result
 
94
  return md, regions
95
 
96
 
97
+ # ── STEP 4: Main OCR ─────────────────────────────────────────
98
  def run_ocr(uploaded_file):
99
  if uploaded_file is None:
100
  return "Please upload a file."
 
103
  from glmocr import parse
104
  import pymupdf as fitz
105
 
106
+ path = uploaded_file.name if hasattr(uploaded_file, "name") else str(uploaded_file)
107
  is_pdf = path.lower().endswith(".pdf")
108
 
109
  if is_pdf:
110
+ doc = fitz.open(path)
111
+ page_images = []
 
112
  for i in range(len(doc)):
113
+ pix = doc[i].get_pixmap(matrix=fitz.Matrix(1.5, 1.5), alpha=False)
114
  img_path = f"/tmp/maas_page_{i}.png"
115
  pix.save(img_path)
116
  page_images.append(img_path)
 
 
117
  doc.close()
118
  results = parse(page_images)
119
  if not isinstance(results, list):
120
  results = [results]
121
  else:
 
122
  results = parse(path)
123
  if not isinstance(results, list):
124
  results = [results]
 
129
  page_md, regions = get_page_data(page_result)
130
  parts = []
131
 
132
+ if is_pdf:
133
+ header_end, footer_start = get_header_footer_zones(regions, 1000)
134
 
135
+ if header_end is not None and header_end > 0:
136
+ hdr = extract_zone_text(path, page_num, 0, header_end)
137
+ if hdr and hdr.strip():
138
+ parts.append(hdr.strip())
 
139
 
 
140
  if page_md:
141
  parts.append(page_md)
142
 
143
+ if footer_start is not None and footer_start < 1.0:
144
+ ftr = extract_zone_text(path, page_num, footer_start, 1.0)
145
+ if ftr and ftr.strip():
146
+ parts.append(ftr.strip())
147
  else:
148
  if page_md:
149
  parts.append(page_md)
 
151
  if parts:
152
  all_pages_md.append("\n\n".join(parts))
153
 
 
154
  final = "\n\n---\n\n".join(all_pages_md) if all_pages_md else "(No content)"
155
  return final
156
 
 
163
  with gr.Blocks(title="GLM-OCR") as demo:
164
  gr.Markdown("""
165
  # πŸ” GLM-OCR
166
+ Upload a PDF or image. Headers and footers from the PDF text layer (all PDFs).
 
167
  """)
168
 
169
  file_input = gr.File(
170
  label="Upload PDF or Image",
171
  file_types=[".pdf", ".png", ".jpg", ".jpeg", ".tiff", ".bmp"]
172
  )
173
+ run_btn = gr.Button("β–Ά Run OCR", variant="primary", size="lg")
174
  output_box = gr.Textbox(lines=40, label="Output")
175
 
176
  run_btn.click(fn=run_ocr, inputs=file_input, outputs=output_box)
177
 
178
+ demo.launch()