ariankhalfani commited on
Commit
7008805
1 Parent(s): acbef3a

Update app2.py

Browse files
Files changed (1) hide show
  1. app2.py +91 -163
app2.py CHANGED
@@ -3,17 +3,26 @@ from ultralytics import YOLO
3
  import cv2
4
  import numpy as np
5
  from PIL import Image, ImageDraw, ImageFont
6
- import sqlite3
7
  import base64
8
  from io import BytesIO
9
  import tempfile
10
- import pandas as pd
11
  import os
12
  from pathlib import Path
 
13
 
14
  # Load YOLOv8 model
15
  model = YOLO("best.pt")
16
 
 
 
 
 
 
 
 
 
 
 
17
  def predict_image(input_image, name, age, medical_record, sex):
18
  if input_image is None:
19
  return None, "Please Input The Image"
@@ -55,6 +64,18 @@ def predict_image(input_image, name, age, medical_record, sex):
55
 
56
  # Draw the bounding box
57
  cv2.rectangle(image_with_boxes, (xmin, ymin), (xmax, ymax), color, 2)
 
 
 
 
 
 
 
 
 
 
 
 
58
 
59
  # Enlarge font scale and thickness
60
  font_scale = 1.0
@@ -77,6 +98,11 @@ def predict_image(input_image, name, age, medical_record, sex):
77
  # Add text and watermark
78
  pil_image_with_boxes = add_text_and_watermark(pil_image_with_boxes, name, age, medical_record, sex, label)
79
 
 
 
 
 
 
80
  return pil_image_with_boxes, raw_predictions_str
81
 
82
  # Function to add watermark
@@ -109,7 +135,7 @@ def add_text_and_watermark(image, name, age, medical_record, sex, label):
109
  draw = ImageDraw.Draw(image)
110
 
111
  # Load a larger font (adjust the size as needed)
112
- font_size = 48 # Example font size
113
  try:
114
  font = ImageFont.truetype("font.ttf", size=font_size)
115
  except IOError:
@@ -139,110 +165,40 @@ def add_text_and_watermark(image, name, age, medical_record, sex, label):
139
 
140
  return image_with_watermark
141
 
142
- # Function to initialize the database
143
- def init_db():
144
- conn = sqlite3.connect('results.db')
145
- c = conn.cursor()
146
- c.execute('''CREATE TABLE IF NOT EXISTS results
147
- (id INTEGER PRIMARY KEY, name TEXT, age INTEGER, medical_record INTEGER, sex TEXT, input_image BLOB, predicted_image BLOB, result TEXT)''')
148
- conn.commit()
149
- conn.close()
150
-
151
- # Function to submit result to the database
152
- def submit_result(name, age, medical_record, sex, input_image, predicted_image, result):
153
- conn = sqlite3.connect('results.db')
154
- c = conn.cursor()
155
-
156
- input_image_np = np.array(input_image)
157
- _, input_buffer = cv2.imencode('.png', cv2.cvtColor(input_image_np, cv2.COLOR_RGB2BGR))
158
- input_image_bytes = input_buffer.tobytes()
159
 
160
- predicted_image_np = np.array(predicted_image)
161
- predicted_image_rgb = cv2.cvtColor(predicted_image_np, cv2.COLOR_RGB2BGR) # Ensure correct color conversion
162
- _, predicted_buffer = cv2.imencode('.png', predicted_image_rgb)
163
- predicted_image_bytes = predicted_buffer.tobytes()
 
 
 
164
 
165
- c.execute("INSERT INTO results (name, age, medical_record, sex, input_image, predicted_image, result) VALUES (?, ?, ?, ?, ?, ?, ?)",
166
- (name, age, medical_record, sex, input_image_bytes, predicted_image_bytes, result))
167
- conn.commit()
168
- conn.close()
169
- return "Result submitted to database."
170
-
171
- # Function to load and view database in HTML format
172
- def view_database():
173
- conn = sqlite3.connect('results.db')
174
- c = conn.cursor()
175
- c.execute("SELECT name, age, medical_record, sex, input_image, predicted_image, result FROM results")
176
- rows = c.fetchall()
177
- conn.close()
178
-
179
- # Prepare the HTML content
180
- html_content = "<table border='1'><tr><th>Name</th><th>Age</th><th>Medical Record</th><th>Sex</th><th>Input Image</th><th>Predicted Image</th><th>Result</th></tr>"
181
 
182
- for row in rows:
183
- name, age, medical_record, sex, input_image_bytes, predicted_image_bytes, result = row
184
-
185
- # Decode the images
186
- input_image = Image.open(BytesIO(input_image_bytes))
187
- predicted_image = Image.open(BytesIO(predicted_image_bytes))
188
-
189
- # Convert images to base64 for display in HTML
190
- buffered_input = BytesIO()
191
- input_image.save(buffered_input, format="PNG")
192
- input_image_base64 = base64.b64encode(buffered_input.getvalue()).decode('utf-8')
193
-
194
- buffered_predicted = BytesIO()
195
- predicted_image.save(buffered_predicted, format="PNG")
196
- predicted_image_base64 = base64.b64encode(buffered_predicted.getvalue()).decode('utf-8')
197
-
198
- # Add a row to the HTML table
199
- html_content += f"<tr><td>{name}</td><td>{age}</td><td>{medical_record}</td><td>{sex}</td><td><img src='data:image/png;base64,{input_image_base64}' width='100'></td><td><img src='data:image/png;base64,{predicted_image_base64}' width='100'></td><td>{result}</td></tr>"
200
-
201
- html_content += "</table>"
202
-
203
- return html_content
204
-
205
- # Function to download database or HTML file
206
- def download_file(file_format):
207
- directory = tempfile.gettempdir()
208
- db_file_path = os.path.join(directory, 'results.db')
209
 
210
- if file_format == "Database (.db)":
211
- # Simulate creating or writing to the database file here
212
- if not os.path.exists(db_file_path):
213
- # Create a dummy database file for demonstration
214
- conn = sqlite3.connect(db_file_path)
215
- conn.execute('CREATE TABLE IF NOT EXISTS results (id INTEGER PRIMARY KEY, name TEXT)')
216
- conn.commit()
217
- conn.close()
218
- return db_file_path
219
 
220
- elif file_format == "HTML (.html)":
221
- # Connect to the SQLite database
222
- conn = sqlite3.connect(db_file_path)
223
-
224
- try:
225
- # Attempt to read the results table into a DataFrame
226
- df = pd.read_sql_query("SELECT * FROM results", conn)
227
- except pd.errors.DatabaseError as e:
228
- conn.close()
229
- raise ValueError("Table 'results' does not exist in the database.") from e
230
-
231
- # Close the database connection
232
- conn.close()
233
-
234
- # Define the path for the HTML file
235
- html_file_path = os.path.join(directory, "results.html")
236
-
237
- # Save the DataFrame as an HTML file
238
- df.to_html(html_file_path, index=False)
239
-
240
- return html_file_path
241
- else:
242
- raise ValueError("Invalid file format specified.")
243
-
244
- # Initialize the database
245
- init_db()
246
 
247
  # Gradio Interface
248
  def interface(name, age, medical_record, sex, input_image):
@@ -250,65 +206,37 @@ def interface(name, age, medical_record, sex, input_image):
250
  return None, "Please upload an image.", None
251
 
252
  output_image, raw_result = predict_image(input_image, name, age, medical_record, sex)
253
- submit_status = submit_result(name, age, medical_record, sex, input_image, output_image, raw_result)
254
-
255
- return output_image, raw_result, submit_status
256
-
257
- # View Database Function (Updated)
258
- def view_db_interface():
259
- html_content = view_database()
260
- return html_content
261
-
262
- # Download Function
263
- def download_interface(choice):
264
- try:
265
- # Get the file path
266
- file_path = download_file(choice)
267
-
268
- # Return the file path (string) directly for the Gradio component to handle
269
- return file_path
270
- except (FileNotFoundError, ValueError) as e:
271
- # Display error message in Gradio output
272
- return str(e)
273
-
274
- # Gradio Blocks
275
- with gr.Blocks() as demo:
276
- with gr.Column():
277
- gr.Markdown("# Cataract Detection System")
278
- gr.Markdown("Upload an image to detect cataract and add patient details.")
279
- gr.Markdown("This application uses YOLOv8 with mAP=0.981")
280
 
281
- with gr.Column():
282
- name = gr.Textbox(label="Name")
283
- age = gr.Number(label="Age")
284
- medical_record = gr.Number(label="Medical Record")
285
- sex = gr.Radio(["Male", "Female"], label="Sex")
286
- input_image = gr.Image(type="pil", label="Upload an Image", image_mode="RGB")
287
-
288
- with gr.Column():
289
- submit_btn = gr.Button("Submit")
290
- output_image = gr.Image(type="pil", label="Predicted Image")
291
-
292
- with gr.Row():
293
- raw_result = gr.Textbox(label="Raw Result", lines=5)
294
- submit_status = gr.Textbox(label="Submission Status")
295
-
296
- submit_btn.click(fn=interface, inputs=[name, age, medical_record, sex, input_image], outputs=[output_image, raw_result, submit_status])
297
-
298
- with gr.Column():
299
- view_db_btn = gr.Button("View Database")
300
- db_output = gr.HTML(label="Database Records")
301
-
302
- view_db_btn.click(fn=view_db_interface, inputs=[], outputs=[db_output])
303
-
304
- with gr.Column():
305
- download_choice = gr.Radio(["Database (.db)", "Database (.html)"], label="Choose the file to download:")
306
- download_btn_db = gr.Button("Download Database (.db)")
307
- download_btn_html = gr.Button("Download HTML (.html)")
308
- download_file_output = gr.File(label="Download File")
309
-
310
- download_btn_db.click(lambda: download_file("Database (.db)"), outputs=download_file_output)
311
- download_btn_html.click(lambda: download_file("HTML (.html)"), outputs=download_file_output)
312
-
313
- # Launch the Gradio app
314
- demo.launch()
 
3
  import cv2
4
  import numpy as np
5
  from PIL import Image, ImageDraw, ImageFont
 
6
  import base64
7
  from io import BytesIO
8
  import tempfile
 
9
  import os
10
  from pathlib import Path
11
+ import shutil
12
 
13
  # Load YOLOv8 model
14
  model = YOLO("best.pt")
15
 
16
+ # Create directories if not present
17
+ uploaded_folder = Path('Uploaded_Picture')
18
+ predicted_folder = Path('Predicted_Picture')
19
+ uploaded_folder.mkdir(parents=True, exist_ok=True)
20
+ predicted_folder.mkdir(parents=True, exist_ok=True)
21
+
22
+ # Path to store accumulated HTML data
23
+ html_file_path = Path(tempfile.gettempdir()) / 'patient_data.html'
24
+
25
+ # Function to predict image and add bounding box, text, circle, and watermark
26
  def predict_image(input_image, name, age, medical_record, sex):
27
  if input_image is None:
28
  return None, "Please Input The Image"
 
64
 
65
  # Draw the bounding box
66
  cv2.rectangle(image_with_boxes, (xmin, ymin), (xmax, ymax), color, 2)
67
+
68
+ # Calculate the center of the bounding box
69
+ center_x = (xmin + xmax) // 2
70
+ center_y = (ymin + ymax) // 2
71
+
72
+ # Calculate the radius (1/12 of the average of the width and height of the bounding box)
73
+ box_width = xmax - xmin
74
+ box_height = ymax - ymin
75
+ radius = int((box_width + box_height) / 24) # Average of width and height divided by 12
76
+
77
+ # Draw a white circle at the center of the bounding box
78
+ cv2.circle(image_with_boxes, (center_x, center_y), radius, (255, 255, 255), thickness=2)
79
 
80
  # Enlarge font scale and thickness
81
  font_scale = 1.0
 
98
  # Add text and watermark
99
  pil_image_with_boxes = add_text_and_watermark(pil_image_with_boxes, name, age, medical_record, sex, label)
100
 
101
+ # Save images to directories
102
+ image_name = f"{name}-{age}-{sex}-{medical_record}.png"
103
+ input_image.save(uploaded_folder / image_name)
104
+ pil_image_with_boxes.save(predicted_folder / image_name)
105
+
106
  return pil_image_with_boxes, raw_predictions_str
107
 
108
  # Function to add watermark
 
135
  draw = ImageDraw.Draw(image)
136
 
137
  # Load a larger font (adjust the size as needed)
138
+ font_size = 24 # Example font size
139
  try:
140
  font = ImageFont.truetype("font.ttf", size=font_size)
141
  except IOError:
 
165
 
166
  return image_with_watermark
167
 
168
+ # Function to save patient info in HTML and accumulate data
169
+ def save_patient_info_to_html(name, age, medical_record, sex, result):
170
+ html_content = f"""
171
+ <html>
172
+ <body>
173
+ <h1>Patient Information</h1>
174
+ <p><strong>Name:</strong> {name}</p>
175
+ <p><strong>Age:</strong> {age}</p>
176
+ <p><strong>Medical Record:</strong> {medical_record}</p>
177
+ <p><strong>Sex:</strong> {sex}</p>
178
+ <p><strong>Result:</strong> {result}</p>
179
+ <hr>
180
+ </body>
181
+ </html>
182
+ """
 
 
183
 
184
+ # Check if the HTML file already exists
185
+ if html_file_path.exists():
186
+ with open(html_file_path, 'a') as f:
187
+ f.write(html_content)
188
+ else:
189
+ with open(html_file_path, 'w') as f:
190
+ f.write(html_content)
191
 
192
+ return str(html_file_path)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
193
 
194
+ # Function to download the folders
195
+ def download_folder(folder):
196
+ zip_path = os.path.join(tempfile.gettempdir(), f"{folder}.zip")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
197
 
198
+ # Zip the folder
199
+ shutil.make_archive(zip_path.replace('.zip', ''), 'zip', folder)
 
 
 
 
 
 
 
200
 
201
+ return zip_path
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
202
 
203
  # Gradio Interface
204
  def interface(name, age, medical_record, sex, input_image):
 
206
  return None, "Please upload an image.", None
207
 
208
  output_image, raw_result = predict_image(input_image, name, age, medical_record, sex)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
209
 
210
+ if output_image is None:
211
+ return None, raw_result, None
212
+
213
+ # Save patient info to HTML
214
+ html_file_path = save_patient_info_to_html(name, age, medical_record, sex, raw_result)
215
+
216
+ # Encode the image to display in Gradio
217
+ buffered = BytesIO()
218
+ output_image.save(buffered, format="PNG")
219
+ img_str = base64.b64encode(buffered.getvalue()).decode("utf-8")
220
+
221
+ # Provide the zip file path for download
222
+ zip_file = download_folder(predicted_folder)
223
+
224
+ return f'<img src="data:image/png;base64,{img_str}" alt="Processed Image"/>', raw_result, zip_file
225
+
226
+ # Define Gradio interface
227
+ gr.Interface(
228
+ fn=interface,
229
+ inputs=[
230
+ gr.Textbox(label="Name"),
231
+ gr.Textbox(label="Age"),
232
+ gr.Textbox(label="Medical Record"),
233
+ gr.Dropdown(label="Sex", choices=["Male", "Female", "Other"]),
234
+ gr.Image(source="upload", tool="editor", label="Upload an Image")
235
+ ],
236
+ outputs=[
237
+ gr.HTML(label="Processed Image"),
238
+ gr.Textbox(label="Raw Predictions"),
239
+ gr.File(label="Download ZIP")
240
+ ],
241
+ title="Patient Image Analysis"
242
+ ).launch()