Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -6,6 +6,7 @@ import time
|
|
6 |
import io
|
7 |
import subprocess
|
8 |
import sys
|
|
|
9 |
|
10 |
# Install required packages
|
11 |
def install_packages():
|
@@ -13,7 +14,8 @@ def install_packages():
|
|
13 |
"transformers",
|
14 |
"accelerate",
|
15 |
"timm",
|
16 |
-
"easyocr"
|
|
|
17 |
]
|
18 |
for package in packages:
|
19 |
try:
|
@@ -135,17 +137,49 @@ Generate a complete, professional SOAP note:"""
|
|
135 |
except Exception as e:
|
136 |
return f"β SOAP generation failed: {str(e)}"
|
137 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
138 |
def extract_text_from_image(image):
|
139 |
-
"""Extract text using EasyOCR"""
|
140 |
if ocr_reader is None:
|
141 |
return "β OCR not available"
|
142 |
|
143 |
try:
|
144 |
-
|
145 |
-
|
146 |
-
img_array = np.array(image)
|
147 |
|
148 |
-
results = ocr_reader.readtext(
|
149 |
if results:
|
150 |
return ' '.join(results).strip()
|
151 |
else:
|
@@ -197,41 +231,35 @@ EKG: ST elevation in leads II, III, aVF"""
|
|
197 |
|
198 |
with gr.Blocks(title="Medical OCR SOAP Generator", theme=gr.themes.Soft()) as demo:
|
199 |
|
200 |
-
|
201 |
gr.HTML("""
|
202 |
-
<h1>π₯ Medical OCR SOAP Generator - LIVE DEMO</h1>
|
203 |
-
<h2>π― For Competition Judges - Quick 2-Minute Demo:</h2>
|
204 |
|
205 |
-
<div style="background-color: #e6f3ff; padding: 15px; border-radius: 10px; margin: 10px 0;">
|
206 |
-
<h3>π
|
207 |
-
<p><strong
|
208 |
-
<p><strong>
|
209 |
-
</div>
|
210 |
|
211 |
-
<h3>Demo Steps:</h3>
|
212 |
-
<ol>
|
213 |
-
<li><strong>
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
</li>
|
219 |
-
<li><strong>Click "Generate SOAP Note"</strong></li>
|
220 |
-
<li><strong>Wait ~2-3 minutes</strong> for AI processing (model loading + generation)</li>
|
221 |
-
<li><strong>See professional SOAP note</strong> generated by Gemma 3n</li>
|
222 |
-
</ol>
|
223 |
|
224 |
-
<h3>β
What This Demo Shows:</h3>
|
225 |
-
<ul>
|
226 |
-
<li><strong>Real OCR</strong> extraction from handwritten medical notes
|
227 |
-
<li><strong>AI-powered medical reasoning</strong> with Gemma 3n
|
228 |
-
<li><strong>Professional SOAP formatting</strong> (Subjective, Objective, Assessment, Plan)</li>
|
229 |
-
<li><strong>HIPAA-compliant</strong> local processing</li>
|
230 |
-
</ul>
|
231 |
|
232 |
-
<p><strong>β οΈ Note:</strong> First generation takes ~
|
233 |
-
<hr>
|
234 |
-
""")
|
235 |
|
236 |
with gr.Row():
|
237 |
with gr.Column():
|
|
|
6 |
import io
|
7 |
import subprocess
|
8 |
import sys
|
9 |
+
import cv2
|
10 |
|
11 |
# Install required packages
|
12 |
def install_packages():
|
|
|
14 |
"transformers",
|
15 |
"accelerate",
|
16 |
"timm",
|
17 |
+
"easyocr",
|
18 |
+
"opencv-python"
|
19 |
]
|
20 |
for package in packages:
|
21 |
try:
|
|
|
137 |
except Exception as e:
|
138 |
return f"β SOAP generation failed: {str(e)}"
|
139 |
|
140 |
+
def preprocess_image_for_ocr(image):
|
141 |
+
"""Preprocess image for better OCR results using CLAHE"""
|
142 |
+
try:
|
143 |
+
if hasattr(image, 'convert'):
|
144 |
+
image = image.convert('RGB')
|
145 |
+
img_array = np.array(image)
|
146 |
+
|
147 |
+
# Convert to grayscale
|
148 |
+
if len(img_array.shape) == 3:
|
149 |
+
gray = cv2.cvtColor(img_array, cv2.COLOR_RGB2GRAY)
|
150 |
+
else:
|
151 |
+
gray = img_array
|
152 |
+
|
153 |
+
# Resize if too small
|
154 |
+
height, width = gray.shape
|
155 |
+
if height < 300 or width < 300:
|
156 |
+
scale = max(300/height, 300/width)
|
157 |
+
new_height = int(height * scale)
|
158 |
+
new_width = int(width * scale)
|
159 |
+
gray = cv2.resize(gray, (new_width, new_height), interpolation=cv2.INTER_CUBIC)
|
160 |
+
|
161 |
+
# Enhance image with CLAHE
|
162 |
+
gray = cv2.medianBlur(gray, 3)
|
163 |
+
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
|
164 |
+
gray = clahe.apply(gray)
|
165 |
+
_, gray = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
|
166 |
+
|
167 |
+
return gray
|
168 |
+
except Exception as e:
|
169 |
+
print(f"β οΈ Image preprocessing failed: {e}")
|
170 |
+
# Fallback to original image if preprocessing fails
|
171 |
+
return np.array(image)
|
172 |
+
|
173 |
def extract_text_from_image(image):
|
174 |
+
"""Extract text using EasyOCR with CLAHE preprocessing"""
|
175 |
if ocr_reader is None:
|
176 |
return "β OCR not available"
|
177 |
|
178 |
try:
|
179 |
+
# Apply CLAHE preprocessing for better OCR
|
180 |
+
processed_img = preprocess_image_for_ocr(image)
|
|
|
181 |
|
182 |
+
results = ocr_reader.readtext(processed_img, detail=0, paragraph=True)
|
183 |
if results:
|
184 |
return ' '.join(results).strip()
|
185 |
else:
|
|
|
231 |
|
232 |
with gr.Blocks(title="Medical OCR SOAP Generator", theme=gr.themes.Soft()) as demo:
|
233 |
|
|
|
234 |
gr.HTML("""
|
235 |
+
<h1>π₯ Medical OCR SOAP Generator - LIVE DEMO</h1>
|
236 |
+
<h2>π― For Competition Judges - Quick 2-Minute Demo:</h2>
|
237 |
|
238 |
+
<div style="background-color: #e6f3ff; padding: 15px; border-radius: 10px; margin: 10px 0;">
|
239 |
+
<h3>π SAMPLE IMAGE PROVIDED:</h3>
|
240 |
+
<p><strong>π Download "docs-note-to-upload.jpg" from the Files tab above, then upload it below</strong></p>
|
241 |
+
<p><strong>OR</strong> click "Try Sample Medical Text" button for instant text demo</p>
|
242 |
+
</div>
|
243 |
|
244 |
+
<h3>Demo Steps:</h3>
|
245 |
+
<ol>
|
246 |
+
<li><strong>Upload the sample image</strong> (docs-note-to-upload.jpg from Files tab) <strong>OR</strong> click sample text button</li>
|
247 |
+
<li><strong>Click "Generate SOAP Note"</strong></li>
|
248 |
+
<li><strong>Wait ~60-90 seconds</strong> for AI processing (first time only)</li>
|
249 |
+
<li><strong>See professional SOAP note</strong> generated by Gemma 3n</li>
|
250 |
+
</ol>
|
|
|
|
|
|
|
|
|
|
|
251 |
|
252 |
+
<h3>β
What This Demo Shows:</h3>
|
253 |
+
<ul>
|
254 |
+
<li><strong>Real OCR</strong> extraction from handwritten medical notes</li>
|
255 |
+
<li><strong>AI-powered medical reasoning</strong> with Gemma 3n</li>
|
256 |
+
<li><strong>Professional SOAP formatting</strong> (Subjective, Objective, Assessment, Plan)</li>
|
257 |
+
<li><strong>HIPAA-compliant</strong> local processing</li>
|
258 |
+
</ul>
|
259 |
|
260 |
+
<p><strong>β οΈ Note:</strong> First generation takes ~60-90 seconds as model loads. Subsequent ones are faster.</p>
|
261 |
+
<hr>
|
262 |
+
""")
|
263 |
|
264 |
with gr.Row():
|
265 |
with gr.Column():
|