ucaslcl Tonic commited on
Commit
c4f4fdf
1 Parent(s): 8474636

add HTML renders (#2)

Browse files

- add html rendering (eaedd343fb7a8659e5b2bc25015121ce6f839c01)
- add latex display (fc2b70dc3a6292b1061737e74496aa30814fae38)


Co-authored-by: Joseph Pollack <[email protected]>

Files changed (2) hide show
  1. app.py +71 -30
  2. requirements.txt +3 -1
app.py CHANGED
@@ -4,36 +4,72 @@ from transformers import AutoModel, AutoTokenizer
4
  from PIL import Image
5
  import numpy as np
6
  import os
 
 
 
 
 
 
 
7
 
8
  tokenizer = AutoTokenizer.from_pretrained('ucaslcl/GOT-OCR2_0', trust_remote_code=True)
9
  model = AutoModel.from_pretrained('ucaslcl/GOT-OCR2_0', trust_remote_code=True, low_cpu_mem_usage=True, device_map='cuda', use_safetensors=True)
10
  model = model.eval().cuda()
11
- html_file = './demo.html'
 
 
 
 
 
 
 
 
 
 
 
12
 
13
  @spaces.GPU
14
- def run_GOT(image_array, got_mode, fine_grained_mode="", ocr_color="", ocr_box=""):
15
- image = image_array
16
- if got_mode == "plain texts OCR":
17
- res = model.chat(tokenizer, image, ocr_type='ocr')
18
- elif got_mode == "format texts OCR":
19
- res = model.chat(tokenizer, image, ocr_type='format', render=True, save_render_file=html_file)
20
- elif got_mode == "plain multi-crop OCR":
21
- res = model.chat_crop(tokenizer, image, ocr_type='ocr')
22
- elif got_mode == "format multi-crop OCR":
23
- res = model.chat_crop(tokenizer, image, ocr_type='format', render=True, save_render_file=html_file)
24
- elif got_mode == "plain fine-grained OCR":
25
- res = model.chat(tokenizer, image, ocr_type='ocr', ocr_box=ocr_box, ocr_color=ocr_color)
26
- elif got_mode == "format fine-grained OCR":
27
- res = model.chat(tokenizer, image, ocr_type='format', ocr_box=ocr_box, ocr_color=ocr_color, render=True, save_render_file=html_file)
 
 
 
 
 
 
 
 
 
 
 
28
 
29
- # print("res:\n", res)
30
- if "format" in got_mode:
31
- with open(html_file, 'r') as f:
32
- demo_html = f.read()
33
- # print("demo_html: \n", demo_html)
34
- print(os.path.abspath(html_file))
35
- return res, demo_html
36
- return res, None
 
 
 
 
 
 
 
37
 
38
  def task_update(task):
39
  if "fine-grained" in task:
@@ -61,6 +97,12 @@ def fine_grained_update(task):
61
  gr.update(visible=False, value = ""),
62
  ]
63
 
 
 
 
 
 
 
64
 
65
  title_html = """
66
  <h2> <span class="gradient-text" id="text">General OCR Theory</span><span class="plain-text">: Towards OCR-2.0 via a Unified End-to-end Model</span></h2>
@@ -75,7 +117,6 @@ with gr.Blocks() as demo:
75
  "🔥🔥🔥This is the official online demo of GOT-OCR-2.0 model!!!"
76
 
77
  ### Demo Guidelines
78
-
79
  You need to upload your image below and choose one mode of GOT, then click "Submit" to run GOT model. More characters will result in longer wait times.
80
  - **plain texts OCR & format texts OCR**: The two modes are for the image-level OCR.
81
  - **plain multi-crop OCR & format multi-crop OCR**: For images with more complex content, you can achieve higher-quality results with these modes.
@@ -115,12 +156,10 @@ with gr.Blocks() as demo:
115
  submit_button = gr.Button("Submit")
116
 
117
  with gr.Column():
118
- ocr_result = gr.Textbox(label="GOT output")
119
-
120
 
121
  with gr.Column():
122
- html_result = gr.HTML(
123
- label="rendered html", show_label=True)
124
 
125
  gr.Examples(
126
  examples=[
@@ -134,7 +173,7 @@ with gr.Blocks() as demo:
134
  ],
135
  inputs=[image_input, task_dropdown, fine_grained_dropdown, color_dropdown, box_input],
136
  outputs=[ocr_result, html_result],
137
- fn = run_GOT,
138
  label="examples",
139
  )
140
 
@@ -155,4 +194,6 @@ with gr.Blocks() as demo:
155
  outputs=[ocr_result, html_result]
156
  )
157
 
158
- demo.launch()
 
 
 
4
  from PIL import Image
5
  import numpy as np
6
  import os
7
+ import base64
8
+ import io
9
+ import uuid
10
+ import tempfile
11
+ import time
12
+ import shutil
13
+ from pathlib import Path
14
 
15
  tokenizer = AutoTokenizer.from_pretrained('ucaslcl/GOT-OCR2_0', trust_remote_code=True)
16
  model = AutoModel.from_pretrained('ucaslcl/GOT-OCR2_0', trust_remote_code=True, low_cpu_mem_usage=True, device_map='cuda', use_safetensors=True)
17
  model = model.eval().cuda()
18
+
19
+ UPLOAD_FOLDER = "./uploads"
20
+ RESULTS_FOLDER = "./results"
21
+
22
+ for folder in [UPLOAD_FOLDER, RESULTS_FOLDER]:
23
+ if not os.path.exists(folder):
24
+ os.makedirs(folder)
25
+
26
+ def image_to_base64(image):
27
+ buffered = io.BytesIO()
28
+ image.save(buffered, format="PNG")
29
+ return base64.b64encode(buffered.getvalue()).decode()
30
 
31
  @spaces.GPU
32
+ def run_GOT(image, got_mode, fine_grained_mode="", ocr_color="", ocr_box=""):
33
+ unique_id = str(uuid.uuid4())
34
+ image_path = os.path.join(UPLOAD_FOLDER, f"{unique_id}.png")
35
+ result_path = os.path.join(RESULTS_FOLDER, f"{unique_id}.html")
36
+
37
+ shutil.copy(image, image_path)
38
+
39
+ try:
40
+ if got_mode == "plain texts OCR":
41
+ res = model.chat(tokenizer, image_path, ocr_type='ocr')
42
+ return res, None
43
+ elif got_mode == "format texts OCR":
44
+ res = model.chat(tokenizer, image_path, ocr_type='format', render=True, save_render_file=result_path)
45
+ elif got_mode == "plain multi-crop OCR":
46
+ res = model.chat_crop(tokenizer, image_path, ocr_type='ocr')
47
+ return res, None
48
+ elif got_mode == "format multi-crop OCR":
49
+ res = model.chat_crop(tokenizer, image_path, ocr_type='format', render=True, save_render_file=result_path)
50
+ elif got_mode == "plain fine-grained OCR":
51
+ res = model.chat(tokenizer, image_path, ocr_type='ocr', ocr_box=ocr_box, ocr_color=ocr_color)
52
+ return res, None
53
+ elif got_mode == "format fine-grained OCR":
54
+ res = model.chat(tokenizer, image_path, ocr_type='format', ocr_box=ocr_box, ocr_color=ocr_color, render=True, save_render_file=result_path)
55
+
56
+ res_markdown = f"$$ {res} $$"
57
 
58
+ if "format" in got_mode and os.path.exists(result_path):
59
+ with open(result_path, 'r') as f:
60
+ html_content = f.read()
61
+ encoded_html = base64.b64encode(html_content.encode('utf-8')).decode('utf-8')
62
+ iframe_src = f"data:text/html;base64,{encoded_html}"
63
+ iframe = f'<iframe src="{iframe_src}" width="100%" height="600px"></iframe>'
64
+ download_link = f'<a href="data:text/html;base64,{encoded_html}" download="result_{unique_id}.html">Download Full Result</a>'
65
+ return res_markdown, f"{download_link}<br>{iframe}"
66
+ else:
67
+ return res_markdown, None
68
+ except Exception as e:
69
+ return f"Error: {str(e)}", None
70
+ finally:
71
+ if os.path.exists(image_path):
72
+ os.remove(image_path)
73
 
74
  def task_update(task):
75
  if "fine-grained" in task:
 
97
  gr.update(visible=False, value = ""),
98
  ]
99
 
100
+ def cleanup_old_files():
101
+ current_time = time.time()
102
+ for folder in [UPLOAD_FOLDER, RESULTS_FOLDER]:
103
+ for file_path in Path(folder).glob('*'):
104
+ if current_time - file_path.stat().st_mtime > 3600: # 1 hour
105
+ file_path.unlink()
106
 
107
  title_html = """
108
  <h2> <span class="gradient-text" id="text">General OCR Theory</span><span class="plain-text">: Towards OCR-2.0 via a Unified End-to-end Model</span></h2>
 
117
  "🔥🔥🔥This is the official online demo of GOT-OCR-2.0 model!!!"
118
 
119
  ### Demo Guidelines
 
120
  You need to upload your image below and choose one mode of GOT, then click "Submit" to run GOT model. More characters will result in longer wait times.
121
  - **plain texts OCR & format texts OCR**: The two modes are for the image-level OCR.
122
  - **plain multi-crop OCR & format multi-crop OCR**: For images with more complex content, you can achieve higher-quality results with these modes.
 
156
  submit_button = gr.Button("Submit")
157
 
158
  with gr.Column():
159
+ ocr_result = gr.Markdown(label="GOT output")
 
160
 
161
  with gr.Column():
162
+ html_result = gr.HTML(label="rendered html", show_label=True)
 
163
 
164
  gr.Examples(
165
  examples=[
 
173
  ],
174
  inputs=[image_input, task_dropdown, fine_grained_dropdown, color_dropdown, box_input],
175
  outputs=[ocr_result, html_result],
176
+ fn=run_GOT,
177
  label="examples",
178
  )
179
 
 
194
  outputs=[ocr_result, html_result]
195
  )
196
 
197
+ if __name__ == "__main__":
198
+ cleanup_old_files()
199
+ demo.launch()
requirements.txt CHANGED
@@ -6,4 +6,6 @@ tiktoken
6
  verovio
7
  opencv-python
8
  accelerate
9
- numpy==1.26.4
 
 
 
6
  verovio
7
  opencv-python
8
  accelerate
9
+ numpy==1.26.4
10
+ shutils
11
+ pillow