MasteredUltraInstinct commited on
Commit
088b5a9
Β·
verified Β·
1 Parent(s): e13d997

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +120 -41
app.py CHANGED
@@ -10,6 +10,48 @@ model = LatexOCR()
10
  def preprocess_handwritten_image(pil_img):
11
  return pil_img.convert('RGB')
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  def clean_latex2(latex):
14
  latex = latex.replace('\\ ', '')
15
  latex = latex.replace('\\\\', '\\')
@@ -34,59 +76,96 @@ def clean_latex2(latex):
34
  latex = re.sub(wrong, right, latex)
35
  return latex.strip()
36
 
37
- def solve_from_multiple_images(img1, img2, img3):
 
38
  try:
39
- images = [img for img in [img1, img2, img3] if img is not None]
40
- if len(images) < 2:
41
- return "❌ Please upload at least 2 images (each with one equation)."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
 
43
- raw_latexes = []
44
- cleaned_eqs = []
45
- for img in images:
 
 
 
 
 
 
46
  img = preprocess_handwritten_image(img)
47
  latex = model(img)
48
- raw_latexes.append(latex)
49
  cleaned = clean_latex2(latex)
50
- if '=' in cleaned:
51
- try:
52
- parsed = parse_latex(cleaned)
53
- if isinstance(parsed, sp.Equality):
54
- cleaned_eqs.append(parsed)
55
- except:
56
- continue
57
 
58
- if len(cleaned_eqs) < 2:
59
- return "❌ Could not parse enough valid equations."
60
 
61
- symbols = set()
62
- for eq in cleaned_eqs:
63
- symbols.update(eq.free_symbols)
64
 
65
- solution = sp.solve(cleaned_eqs, list(symbols), dict=True)
66
- output = "## 🧾 Extracted Equations\n"
67
- for latex in raw_latexes:
68
- output += f"```latex\n{latex}\n```\n"
69
- output += "---\n## ✏️ Parsed & Cleaned:\n"
70
- for eq in cleaned_eqs:
71
- output += f"$$ {sp.latex(eq)} $$\n"
72
- output += "---\n## βœ… Solution:\n"
73
- if solution:
74
- output += "$$" + sp.latex(solution[0]) + "$$"
75
- else:
76
- output += "❌ No solution found or system is inconsistent."
77
- return output
78
- except Exception as e:
79
- return f"❌ Error: {str(e)}"
80
 
 
81
  with gr.Blocks() as demo:
82
- gr.Markdown("## πŸ“ Solve System from Multiple Equation Images")
83
- with gr.Row():
 
 
 
 
 
 
 
84
  img1 = gr.Image(type="pil", label="πŸ“· Equation 1")
85
  img2 = gr.Image(type="pil", label="πŸ“· Equation 2")
86
- img3 = gr.Image(type="pil", label="πŸ“· (Optional) Equation 3")
87
- solve_btn = gr.Button("πŸ“Œ Solve System")
88
- output = gr.Markdown()
89
- solve_btn.click(fn=solve_from_multiple_images, inputs=[img1, img2, img3], outputs=output)
90
 
91
  if __name__ == "__main__":
92
  demo.launch()
 
10
  def preprocess_handwritten_image(pil_img):
11
  return pil_img.convert('RGB')
12
 
13
+ # --- Tab 1 cleaner (UNCHANGED) ---
14
+ def clean_latex(latex):
15
+ latex = latex.replace('\\ ', '')
16
+ latex = latex.replace('\\\\', '\\')
17
+ latex = re.sub(r'\\[ \t\n\r\f\v]*', '', latex)
18
+ latex = re.sub(r'\\([+\-=])', r'\1', latex)
19
+ replacements = {
20
+ r'\\chi': 'x', r'chi': 'x',
21
+ r'\\xi': 'x', r'xi': 'x',
22
+ r'\\alpha': 'x', r'alpha': 'x',
23
+ r'\\beta': 'b', r'beta': 'b',
24
+ r'\\gamma': 'y', r'gamma': 'y',
25
+ r'\\vartheta': '3', r'vartheta': '3',
26
+ r'\\mathcalW': 'x', r'mathcalW': 'x',
27
+ r'\\pi': 'pi', r'pi': 'pi',
28
+ r'\\mathrm': '', r'mathrm': '',
29
+ }
30
+ for wrong, correct in replacements.items():
31
+ latex = re.sub(wrong, correct, latex)
32
+ latex = re.sub(r'\\(cal|mathcal)\s*\{?\s*[Xx]\s*\}?', 'x', latex)
33
+ latex = re.sub(r'\\(cal|mathcal)\s*\{?\s*[Yy]\s*\}?', 'y', latex)
34
+ latex = re.sub(r'\\(cal|mathcal)\s*\{?\s*[Zz]\s*\}?', 'z', latex)
35
+ latex = latex.replace('cal x', 'x').replace('cal X', 'x')
36
+ latex = latex.replace('mathcal x', 'x').replace('mathcal X', 'x')
37
+ latex = latex.replace('{', '').replace('}', '')
38
+ latex = latex.strip().rstrip(',.')
39
+ latex = re.sub(r'(?<![a-zA-Z0-9])e(?![a-zA-Z0-9])', 'E', latex)
40
+ latex = re.sub(r'(\d)([a-zA-Z])', r'\1*\2', latex)
41
+ latex = re.sub(r'(\d+)\s*i', r'\1*I', latex)
42
+ latex = re.sub(r'(?<![a-zA-Z0-9])i(?![a-zA-Z0-9])', 'I', latex)
43
+ latex = re.sub(r'\(([^()]+?)\)\s*([a-zA-Z](\^\d+)?)', r'(\1)*\2', latex)
44
+ latex = latex.replace(r'\cdot', '*')
45
+ latex = latex.replace('βˆ’', '-')
46
+ latex = re.sub(r'[^\w\s^=+*\-().]', '', latex)
47
+ if '=' not in latex:
48
+ latex += '=0'
49
+ latex = latex.replace('pi', '3.1416')
50
+ latex = latex.replace('e', '2.7183')
51
+ latex = latex.replace('E', '2.7183')
52
+ return latex
53
+
54
+ # --- Tab 2 cleaner ---
55
  def clean_latex2(latex):
56
  latex = latex.replace('\\ ', '')
57
  latex = latex.replace('\\\\', '\\')
 
76
  latex = re.sub(wrong, right, latex)
77
  return latex.strip()
78
 
79
+ # --- Polynomial Solver (unchanged) ---
80
+ def solve_polynomial(image):
81
  try:
82
+ img = preprocess_handwritten_image(image)
83
+ latex_result = model(img)
84
+ if not latex_result or len(latex_result.strip()) < 2:
85
+ return "❌ Could not extract valid LaTeX from image.", "", ""
86
+ cleaned_latex = clean_latex(latex_result)
87
+ expr = parse_latex(cleaned_latex)
88
+ expr = expr.subs(sp.pi, sp.Float(3.1416)).subs(sp.E, sp.Float(2.7183))
89
+ if not isinstance(expr, sp.Equality):
90
+ raise ValueError("Expression is not an equation.")
91
+ lhs = expr.lhs - expr.rhs
92
+ if not lhs.is_polynomial():
93
+ raise ValueError("Not a polynomial")
94
+ output = f"## πŸ“„ Extracted LaTeX\n```latex\n{latex_result}\n```\n"
95
+ output += f"---\n## 🧹 Cleaned LaTeX\n```latex\n{cleaned_latex}\n```\n"
96
+ output += f"---\n## 🧠 Parsed Expression\n$$ {sp.latex(expr)} $$\n"
97
+ factor = sp.factor(lhs)
98
+ output += f"---\n## ✏️ Standard Form\n$$ {sp.latex(lhs)} = 0 $$\n"
99
+ output += f"---\n## 🧩 Factorized\n$$ {sp.latex(factor)} = 0 $$\n"
100
+ x = next(iter(lhs.free_symbols))
101
+ roots = sp.solve(lhs, x)
102
+ output += "## βœ… Roots\n"
103
+ output += "$$\n\\begin{aligned}\n"
104
+ for i, r in enumerate(roots, 1):
105
+ root_val = sp.N(r, 6)
106
+ output += f"\\text{{Root {i}}}:\\quad x &\\approx {sp.latex(root_val)} \\\\\n"
107
+ output += "\\end{aligned}\n$$\n"
108
+ return output, cleaned_latex, ""
109
+ except Exception as e:
110
+ return f"❌ Error: {str(e)}", "", ""
111
 
112
+ # --- NEW Multi-image System Solver ---
113
+ def solve_system_multi(img1, img2, img3):
114
+ images = [img1, img2, img3]
115
+ cleaned_equations = []
116
+ raw_outputs = []
117
+ for img in images:
118
+ if img is None:
119
+ continue
120
+ try:
121
  img = preprocess_handwritten_image(img)
122
  latex = model(img)
123
+ raw_outputs.append(latex)
124
  cleaned = clean_latex2(latex)
125
+ parsed = parse_latex(cleaned)
126
+ if isinstance(parsed, sp.Equality):
127
+ cleaned_equations.append(parsed)
128
+ except:
129
+ continue
 
 
130
 
131
+ if len(cleaned_equations) < 2:
132
+ return f"❌ Could not parse enough valid equations."
133
 
134
+ symbols = set()
135
+ for eq in cleaned_equations:
136
+ symbols.update(eq.free_symbols)
137
 
138
+ sol = sp.solve(cleaned_equations, list(symbols), dict=True)
139
+ output = "## πŸ“„ Raw LaTeX:\n"
140
+ for latex in raw_outputs:
141
+ output += f"- ```latex\n{latex}\n```\n"
142
+ output += "---\n## ✏️ Parsed Equations:\n"
143
+ for eq in cleaned_equations:
144
+ output += f"$$ {sp.latex(eq)} $$\n"
145
+ output += "---\n## βœ… Solution:\n"
146
+ if sol:
147
+ output += "$$" + sp.latex(sol[0]) + "$$"
148
+ else:
149
+ output += "❌ No solution found or system may be inconsistent."
150
+ return output
 
 
151
 
152
+ # === UI ===
153
  with gr.Blocks() as demo:
154
+ with gr.Tab("πŸ–ΌοΈ Parse from Image"):
155
+ image_input = gr.Image(type="pil", label="πŸ“· Upload Image of Polynomial")
156
+ hidden_latex = gr.Textbox(visible=False)
157
+ explanation_prompt = gr.Textbox(visible=False)
158
+ output_box = gr.Markdown(label="πŸ“‹ Step-by-step Solution")
159
+ submit_btn = gr.Button("πŸ” Solve")
160
+ submit_btn.click(fn=solve_polynomial, inputs=[image_input], outputs=[output_box, hidden_latex, explanation_prompt])
161
+
162
+ with gr.Tab("πŸ“ Solve System (Multi-Image)"):
163
  img1 = gr.Image(type="pil", label="πŸ“· Equation 1")
164
  img2 = gr.Image(type="pil", label="πŸ“· Equation 2")
165
+ img3 = gr.Image(type="pil", label="πŸ“· Equation 3 (Optional)")
166
+ sys_output = gr.Markdown(label="πŸ“‹ Solved System Output")
167
+ sys_btn = gr.Button("πŸ“Œ Solve System")
168
+ sys_btn.click(fn=solve_system_multi, inputs=[img1, img2, img3], outputs=[sys_output])
169
 
170
  if __name__ == "__main__":
171
  demo.launch()