Spaces:
Running
Running
Upload 2 files
Browse files
app.py
CHANGED
|
@@ -47,16 +47,24 @@ def get_image_text(image_files):
|
|
| 47 |
try:
|
| 48 |
# Open image using PIL
|
| 49 |
image = Image.open(image_file)
|
| 50 |
-
|
| 51 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 52 |
# Extract text using EasyOCR with parameters optimized for math/handwriting
|
| 53 |
results = reader.readtext(
|
| 54 |
-
|
| 55 |
detail=1,
|
| 56 |
paragraph=False,
|
| 57 |
contrast_ths=0.1,
|
| 58 |
adjust_contrast=0.5,
|
| 59 |
-
text_threshold=0.
|
|
|
|
| 60 |
)
|
| 61 |
# Combine all detected text with confidence filtering
|
| 62 |
extracted_text = ' '.join([result[1] for result in results if result[2] > 0.3])
|
|
@@ -110,21 +118,42 @@ def render_math_as_image(text):
|
|
| 110 |
Returns tuple: (has_math, processed_text_or_image)
|
| 111 |
"""
|
| 112 |
# Check if text contains LaTeX math patterns
|
| 113 |
-
math_patterns = [
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 114 |
has_complex_math = any(re.search(pattern, text, re.DOTALL) for pattern in math_patterns)
|
| 115 |
|
| 116 |
-
if has_complex_math
|
| 117 |
try:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 118 |
# Create figure
|
| 119 |
-
fig, ax = plt.subplots(figsize=(10,
|
| 120 |
ax.axis('off')
|
| 121 |
|
| 122 |
-
# Clean the text for rendering
|
| 123 |
-
clean_text = text.replace('$$', '$').replace('\\[', '$').replace('\\]', '$')
|
| 124 |
-
|
| 125 |
# Render text with math
|
| 126 |
ax.text(0.5, 0.5, clean_text,
|
| 127 |
-
fontsize=
|
| 128 |
ha='center',
|
| 129 |
va='center',
|
| 130 |
wrap=True,
|
|
@@ -132,13 +161,14 @@ def render_math_as_image(text):
|
|
| 132 |
|
| 133 |
# Save to bytes
|
| 134 |
buf = BytesIO()
|
| 135 |
-
plt.savefig(buf, format='png', bbox_inches='tight', dpi=
|
| 136 |
buf.seek(0)
|
| 137 |
plt.close(fig)
|
| 138 |
|
| 139 |
return True, buf
|
| 140 |
except Exception as e:
|
| 141 |
-
# If rendering fails, return text
|
|
|
|
| 142 |
return False, text
|
| 143 |
|
| 144 |
return False, text
|
|
|
|
| 47 |
try:
|
| 48 |
# Open image using PIL
|
| 49 |
image = Image.open(image_file)
|
| 50 |
+
|
| 51 |
+
# Preprocess image for better OCR (convert to grayscale and enhance contrast)
|
| 52 |
+
image = image.convert('L') # Grayscale
|
| 53 |
+
# Simple contrast enhancement using numpy
|
| 54 |
+
img_np = np.array(image)
|
| 55 |
+
# Normalize
|
| 56 |
+
img_np = (img_np - np.min(img_np)) / (np.max(img_np) - np.min(img_np)) * 255
|
| 57 |
+
img_np = img_np.astype(np.uint8)
|
| 58 |
+
|
| 59 |
# Extract text using EasyOCR with parameters optimized for math/handwriting
|
| 60 |
results = reader.readtext(
|
| 61 |
+
img_np,
|
| 62 |
detail=1,
|
| 63 |
paragraph=False,
|
| 64 |
contrast_ths=0.1,
|
| 65 |
adjust_contrast=0.5,
|
| 66 |
+
text_threshold=0.4, # Lower threshold to catch faint handwriting
|
| 67 |
+
low_text=0.3
|
| 68 |
)
|
| 69 |
# Combine all detected text with confidence filtering
|
| 70 |
extracted_text = ' '.join([result[1] for result in results if result[2] > 0.3])
|
|
|
|
| 118 |
Returns tuple: (has_math, processed_text_or_image)
|
| 119 |
"""
|
| 120 |
# Check if text contains LaTeX math patterns
|
| 121 |
+
math_patterns = [
|
| 122 |
+
r'\$\$.*?\$\$', r'\$.*?\$',
|
| 123 |
+
r'\\frac', r'\\sqrt', r'\\sum', r'\\int',
|
| 124 |
+
r'\\begin\{.*?\}', r'\\\[.*?\\\]',
|
| 125 |
+
r'\[\s*\\begin' # Catch [\begin cases
|
| 126 |
+
]
|
| 127 |
has_complex_math = any(re.search(pattern, text, re.DOTALL) for pattern in math_patterns)
|
| 128 |
|
| 129 |
+
if has_complex_math:
|
| 130 |
try:
|
| 131 |
+
# Clean the text for rendering
|
| 132 |
+
clean_text = text
|
| 133 |
+
|
| 134 |
+
# Normalize delimiters
|
| 135 |
+
clean_text = clean_text.replace('$$', '$')
|
| 136 |
+
clean_text = clean_text.replace(r'\[', '$').replace(r'\]', '$')
|
| 137 |
+
clean_text = clean_text.replace(r'\(', '$').replace(r'\)', '$')
|
| 138 |
+
|
| 139 |
+
# Fix specific issue seen in screenshot: [\begin -> $\begin
|
| 140 |
+
clean_text = re.sub(r'\[\s*\\begin', r'$\n\\begin', clean_text)
|
| 141 |
+
clean_text = re.sub(r'\\end\{.*?\}\s*\]', r'\\end{cases}$', clean_text) # Simplified fix for end
|
| 142 |
+
|
| 143 |
+
# Remove spacing arguments like \\[2mm] -> \\
|
| 144 |
+
clean_text = re.sub(r'\\\\\[.*?\]', r'\\\\', clean_text)
|
| 145 |
+
|
| 146 |
+
# Estimate height based on text length (rough approximation)
|
| 147 |
+
lines = clean_text.count('\n') + (len(clean_text) // 60)
|
| 148 |
+
fig_height = max(4, lines * 0.5)
|
| 149 |
+
|
| 150 |
# Create figure
|
| 151 |
+
fig, ax = plt.subplots(figsize=(10, fig_height))
|
| 152 |
ax.axis('off')
|
| 153 |
|
|
|
|
|
|
|
|
|
|
| 154 |
# Render text with math
|
| 155 |
ax.text(0.5, 0.5, clean_text,
|
| 156 |
+
fontsize=12,
|
| 157 |
ha='center',
|
| 158 |
va='center',
|
| 159 |
wrap=True,
|
|
|
|
| 161 |
|
| 162 |
# Save to bytes
|
| 163 |
buf = BytesIO()
|
| 164 |
+
plt.savefig(buf, format='png', bbox_inches='tight', dpi=200, facecolor='#f5f2e8')
|
| 165 |
buf.seek(0)
|
| 166 |
plt.close(fig)
|
| 167 |
|
| 168 |
return True, buf
|
| 169 |
except Exception as e:
|
| 170 |
+
# If rendering fails, return text but try to clean it for markdown
|
| 171 |
+
print(f"Rendering failed: {e}")
|
| 172 |
return False, text
|
| 173 |
|
| 174 |
return False, text
|