Spaces:
Sleeping
Sleeping
import os | |
os.environ["CUDA_VISIBLE_DEVICES"] = "-1" # Force TensorFlow to use CPU | |
import gradio as gr | |
import numpy as np | |
from PIL import Image | |
from reportlab.lib.pagesizes import letter | |
from reportlab.pdfgen import canvas | |
from reportlab.lib import colors | |
from reportlab.platypus import Table, TableStyle | |
import requests | |
import smtplib | |
from email.mime.multipart import MIMEMultipart | |
from email.mime.text import MIMEText | |
from email.mime.base import MIMEBase | |
from email import encoders | |
import io | |
import base64 | |
# FastAPI server URL | |
FASTAPI_URL = "http://localhost:7860/analyze" # Adjust if your FastAPI server is running elsewhere | |
# Email credentials | |
SENDER_EMAIL = "[email protected]" | |
SENDER_PASSWORD = "1w3r5y7i9pW$" | |
# Read HTML content from `re.html` | |
with open("templates/re.html", "r", encoding="utf-8") as file: | |
html_content = file.read() | |
# List of sample images | |
sample_images = [f"samples/{img}" for img in os.listdir("samples") if img.endswith((".png", ".jpg", ".jpeg"))] | |
def image_to_base64(image_path): | |
with open(image_path, "rb") as image_file: | |
return base64.b64encode(image_file.read()).decode('utf-8') | |
# Function to process X-ray and generate a PDF report | |
def generate_report(name, age, gender, weight, height, allergies, cause, xray, email): | |
image_size = (224, 224) | |
# Send X-ray to FastAPI for analysis | |
try: | |
with open(xray, 'rb') as f: | |
files = {'file': (os.path.basename(xray), f)} | |
response = requests.post(FASTAPI_URL, files=files) | |
response.raise_for_status() # Raise an exception for bad status codes | |
fastapi_results_html = response.text | |
except requests.exceptions.RequestException as e: | |
return f"Error connecting to FastAPI server: {e}" | |
# Extract prediction from FastAPI response (you might need to adjust this based on the exact HTML structure) | |
diagnosed_class = "normal" | |
severity = "Not Available" | |
try: | |
# Simple string matching for now - improve this if the HTML structure is complex | |
if "KnochenWächter" in fastapi_results_html: | |
if "Kein Knochenbruch" in fastapi_results_html: | |
diagnosed_class = "normal" | |
elif "Knochenbruch" in fastapi_results_html or "Auffällig" in fastapi_results_html: | |
diagnosed_class = "Fractured" | |
if diagnosed_class == "Fractured": | |
if "score-high" in fastapi_results_html: | |
severity = "Severe" | |
elif "score-medium" in fastapi_results_html: | |
severity = "Moderate" | |
else: | |
severity = "Mild" | |
else: | |
severity = "Mild" # Assuming normal is mild | |
except Exception as e: | |
print(f"Error parsing FastAPI response: {e}") | |
# Treatment details table | |
treatment_data = [ | |
["Severity Level", "Recommended Treatment", "Recovery Duration"], | |
["Mild", "Rest, pain relievers, and follow-up X-ray", "4-6 weeks"], | |
["Moderate", "Plaster cast, minor surgery if needed", "6-10 weeks"], | |
["Severe", "Major surgery, metal implants, physiotherapy", "Several months"] | |
] | |
# Estimated cost & duration table | |
cost_duration_data = [ | |
["Hospital Type", "Estimated Cost", "Recovery Time"], | |
["Government Hospital", f"₹{2000 if severity == 'Mild' else 8000 if severity == 'Moderate' else 20000} - ₹{5000 if severity == 'Mild' else 15000 if severity == 'Moderate' else 50000}", "4-12 weeks"], | |
["Private Hospital", f"₹{10000 if severity == 'Mild' else 30000 if severity == 'Moderate' else 100000}+", "6 weeks - Several months"] | |
] | |
# Save X-ray image for report | |
img = Image.open(xray).resize((300, 300)) | |
img_path = f"{name}_xray.png" | |
img.save(img_path) | |
# Generate PDF report | |
report_path = f"{name}_fracture_report.pdf" | |
c = canvas.Canvas(report_path, pagesize=letter) | |
# Report title | |
c.setFont("Helvetica-Bold", 16) | |
c.drawString(200, 770, "Bone Fracture Detection Report") | |
# Patient details table | |
patient_data = [ | |
["Patient Name", name], | |
["Age", age], | |
["Gender", gender], | |
["Weight", f"{weight} kg"], | |
["Height", f"{height} cm"], | |
["Allergies", allergies if allergies else "None"], | |
["Cause of Injury", cause if cause else "Not Provided"], | |
["Diagnosis", diagnosed_class], | |
["Injury Severity", severity] | |
] | |
# Format and align tables | |
def format_table(data): | |
table = Table(data, colWidths=[270, 270]) # Set 90% width | |
table.setStyle(TableStyle([ | |
('BACKGROUND', (0, 0), (-1, 0), colors.darkblue), | |
('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke), | |
('ALIGN', (0, 0), (-1, -1), 'CENTER'), | |
('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'), | |
('BOTTOMPADDING', (0, 0), (-1, 0), 12), | |
('GRID', (0, 0), (-1, -1), 1, colors.black), | |
('VALIGN', (0, 0), (-1, -1), 'MIDDLE') | |
])) | |
return table | |
# Draw patient details table | |
patient_table = format_table(patient_data) | |
patient_table.wrapOn(c, 480, 500) | |
patient_table.drawOn(c, 50, 620) | |
# Load and insert X-ray image | |
c.drawInlineImage(img_path, 50, 320, width=250, height=250) | |
c.setFont("Helvetica-Bold", 12) | |
c.drawString(120, 290, f"Fractured: {'Yes' if diagnosed_class == 'Fractured' else 'No'}") | |
# Draw treatment and cost tables | |
treatment_table = format_table(treatment_data) | |
treatment_table.wrapOn(c, 480, 200) | |
treatment_table.drawOn(c, 50, 200) | |
cost_table = format_table(cost_duration_data) | |
cost_table.wrapOn(c, 480, 150) | |
cost_table.drawOn(c, 50, 80) | |
c.save() | |
# Send email with the report | |
subject = "Bone Fracture Detection Report" | |
body = f"Dear {name},\n\nPlease find attached your bone fracture detection report.\n\nSincerely,\nYour Bone Fracture Detection System" | |
msg = MIMEMultipart() | |
msg['From'] = SENDER_EMAIL | |
msg['To'] = email | |
msg['Subject'] = subject | |
msg.attach(MIMEText(body)) | |
with open(report_path, "rb") as attachment: | |
part = MIMEBase('application', "octet-stream") | |
part.set_payload(attachment.read()) | |
encoders.encode_base64(part) | |
part.add_header('Content-Disposition', f"attachment; filename= {os.path.basename(report_path)}") | |
msg.attach(part) | |
try: | |
with smtplib.SMTP_SSL('smtp.gmail.com', 465) as server: | |
server.login(SENDER_EMAIL, SENDER_PASSWORD) | |
server.sendmail(SENDER_EMAIL, email, msg.as_string()) | |
print(f"Report sent successfully to {email}") | |
return report_path # Return path for auto-download | |
except Exception as e: | |
return f"Error sending email: {e}" | |
# Function to select a sample image | |
def use_sample_image(sample_image_path): | |
return sample_image_path # Returns selected sample image filepath | |
# Define Gradio Interface | |
with gr.Blocks() as app: | |
gr.HTML(html_content) # Display `re.html` content in Gradio | |
gr.Markdown("## Bone Fracture Detection System") | |
with gr.Row(): | |
name = gr.Textbox(label="Patient Name") | |
age = gr.Number(label="Age") | |
gender = gr.Radio(["Male", "Female", "Other"], label="Gender") | |
with gr.Row(): | |
weight = gr.Number(label="Weight (kg)") | |
height = gr.Number(label="Height (cm)") | |
with gr.Row(): | |
allergies = gr.Textbox(label="Allergies (if any)") | |
cause = gr.Textbox(label="Cause of Injury") | |
with gr.Row(): | |
xray = gr.Image(type="filepath", label="Upload X-ray Image") | |
with gr.Row(): | |
sample_selector = gr.Dropdown(choices=sample_images, label="Use Sample Image") | |
select_button = gr.Button("Load Sample Image") | |
email = gr.Textbox(label="Patient Email Address") | |
submit_button = gr.Button("Generate Report and Send Email") | |
output_file = gr.File(label="Download Report") | |
select_button.click(use_sample_image, inputs=[sample_selector], outputs=[xray]) | |
submit_button.click( | |
generate_report, | |
inputs=[name, age, gender, weight, height, allergies, cause, xray, email], | |
outputs=[output_file], | |
) | |
# Launch the Gradio app | |
if __name__ == "__main__": | |
app.launch() | |