import streamlit as st from PIL import Image import cv2 import pydicom import numpy as np from streamlit_image_zoom import image_zoom import time import pandas as pd import os import subprocess import sys try: import torchmcubes import torch import torchvision import fpdf except ImportError: subprocess.check_call(['pip', 'install', 'git+https://github.com/tatsy/torchmcubes.git']) subprocess.check_call(['pip', 'install','fpdf']) from fpdf import FPDF ############### Import PATH script_dir = os.path.dirname(os.path.abspath(__file__)) chestXray14_path = os.path.join(script_dir, '..', 'chestXray14') sys.path.append(chestXray14_path) @st.cache_resource def convert_dcm_to_png(input_image_path, output_image_path='a.png'): ds = pydicom.dcmread(input_image_path) img = ds.pixel_array img = cv2.normalize(img, None, 0, 255, cv2.NORM_MINMAX).astype(np.uint8) cv2.imwrite(output_image_path, img) from chestXray14.test import process_image def predictAll(image_path): result, segment_result_path, cam_result_path = process_image(image_path) print("Prediction Results:", result) print(f"Segmentation Result Saved to: {segment_result_path}") print(f"CAM Result Saved to: {cam_result_path}") def load_report(): df = pd.read_csv('pages/images/prediction_results.csv') df.columns = ['Bệnh lý', 'Xác suất'] translation_dict = { 'Infiltration': 'Thâm nhiễm', 'Nodule': 'Nốt', 'Pleural Thickening': 'Dày màng phổi', 'Cardiomegaly': 'Tim to', 'Effusion': 'Tràn dịch', 'Pneumonia': 'Viêm phổi', 'Atelectasis': 'Xẹp phổi', 'Mass': 'Khối u', 'Fibrosis': 'Xơ phổi', 'Pneumothorax': 'Tràn khí màng phổi' } df['Bệnh lý'] = df['Bệnh lý'].map(translation_dict) df['Xác suất'] = df['Xác suất'].astype(float) * 100 df['Xác suất'] = df['Xác suất'].round(2).astype(str) + '%' def highlight_rows(row): if row.name == 0: return ['background-color: darkred; color: white'] * len(row) if row.name == 1: return ['background-color: darkblue; color: white'] * len(row) if row.name == 2: return ['background-color: lightblue; color: white'] * len(row) else: return [''] * len(row) df_styled = df.style.apply(highlight_rows, axis=1).set_table_styles( [{'selector': 'thead th', 'props': [('background-color', '#d3d3d3')]}] ) return df_styled st.markdown("

Welcome to Thoracic Classification 🎈

", unsafe_allow_html=True) with st.sidebar: st.markdown("## Upload your scans") uploaded_files = st.file_uploader("Choose scans...", type=["jpg", "jpeg", "png", "dicom"], accept_multiple_files=True) with st.expander("Hướng dẫn"): st.markdown("1. Tải lên ảnh Scan của bạn bằng cách ấn vào **Browse files** hoặc có thể **Kéo và thả** file ảnh của bạn vào phần browse files. Các định dạng cho phép bao gồm **DICOM, PNG, JPG, JPEG**, các định dạng khác cần phải chuyển về các định dạng được chấp nhận.") st.markdown("2. Sau đó ảnh sẽ tự được mở lên") st.markdown("3. Để phóng to ảnh, bạn chuyển chuột trái vào trong ảnh, dùng lăn chuột để thực hiện phóng to- thu nhỏ ảnh") st.markdown("4. Để kéo xuống xem ảnh phía dưới, bạn di chuột ra ngoài vùng ảnh và dùng lăn chuột cuộn trang như bình thường.") status_images=False col_1, col_2 = st.columns([7, 5.5]) with col_1: if uploaded_files: for uploaded_file in uploaded_files: file_type = uploaded_file.name.split('.')[-1].lower() if file_type in ["jpg", "jpeg", "png"]: img = Image.open(uploaded_file) img.save('temp_image.png') st.markdown("
", unsafe_allow_html=True) width, height = img.size image_zoom(img, mode="both") st.markdown("
", unsafe_allow_html=True) status_images=True elif file_type in ["dicom", "dcm"]: convert_dcm_to_png(uploaded_file) img = Image.open('a.png').convert('RGB') img.save('temp_image.png') st.markdown("
", unsafe_allow_html=True) width, height = img.size image_zoom(img, mode="both",size=(width//4, height//4), keep_aspect_ratio=True, zoom_factor=4.0, increment=0.2) st.markdown("
", unsafe_allow_html=True) status_images=True else: st.info("Please upload some scans to view them.") ############ CREATE PDF import io def generate_pdf(name, age, gender, address, phone): pdf = FPDF() pdf.add_page() pdf.set_font("Arial", size=12) # Title pdf.set_font("Arial", style='B', size=16) pdf.cell(200, 10, txt="Patient Report", ln=True, align='C') pdf.ln(10) # Patient details pdf.set_font("Arial", size=12) pdf.cell(200, 10, txt=f"Name: {name}", ln=True, align='L') pdf.cell(200, 10, txt=f"Age: {age}", ln=True, align='L') pdf.cell(200, 10, txt=f"Gender: {gender}", ln=True, align='L') pdf.cell(200, 10, txt=f"Address: {address}", ln=True, align='L') pdf.cell(200, 10, txt=f"Phone: {phone}", ln=True, align='L') pdf.ln(10) # Placeholder for additional content pdf.cell(200, 10, txt="Predicted Disease Probabilities:", ln=True, align='L') pdf.ln(10) # Simulate adding prediction data (replace this with actual data) diseases = ['Disease A', 'Disease B', 'Disease C'] probabilities = ['70%', '50%', '30%'] for disease, probability in zip(diseases, probabilities): pdf.cell(200, 10, txt=f"{disease}: {probability}", ln=True, align='L') # Add image (optional) pdf.ln(10) pdf.cell(200, 10, txt="Class Activation Map (CAM):", ln=True, align='L') image_path = 'pages/images/cam_result.png' # Adjust this path as necessary if os.path.exists(image_path): pdf.image(image_path, x=10, y=pdf.get_y(), w=100) # Save the PDF to a bytes buffer pdf_buffer = io.BytesIO() pdf.output(pdf_buffer) pdf_buffer.seek(0) # Move the cursor to the beginning of the buffer return pdf_buffer def download_report(name, age, gender, address, phone): st.markdown("

Patient Report

", unsafe_allow_html=True) st.write(f"**Name:** {name}") st.write(f"**Age:** {age}") st.write(f"**Gender:** {gender}") st.write(f"**Address:** {address}") st.write(f"**Phone:** {phone}") # Load the prediction report df_styled = load_report() st.markdown("
", unsafe_allow_html=True) st.write(df_styled.to_html(), unsafe_allow_html=True) # Simulating the addition of an image with a caption img = Image.open('pages/images/cam_result.png').convert('RGB') st.image(img, caption="Class Activation Map (CAM) Visualization", use_column_width=True) # Provide a link to download the report st.markdown( "Click here to download the report", unsafe_allow_html=True) if(status_images): with col_2: st.markdown("

Function

", unsafe_allow_html=True) btn_predictAll_Scans = st.button("Predict All Scans") btn_CAM_Visualization = st.button("CAM Visualization") btn_Segment_Lung = st.button("Segmentation Visualization for Lung") btn_View_Report = st.button("View Report") btn_Download_Report = st.button("Download Report") if btn_predictAll_Scans: start_time = time.time() predictAll('temp_image.png') elapsed_time = time.time() - start_time st.success(f"Predicted all Scans success - ⏳ {int(elapsed_time)} seconds. You can use CAM, Segmentation, View, and Download Report", icon="✅") button_status=True st.divider() col_3, col_4, col_5 = st.columns([4,7.5, 6]) with col_4: if btn_Segment_Lung: st.markdown("

Segmentation Image for Lung

", unsafe_allow_html=True) img = Image.open('pages/images/segment_result.png').convert('RGB') st.markdown("
", unsafe_allow_html=True) width, height = img.size image_zoom(img, mode="both", size=(width // 4, height // 4), keep_aspect_ratio=True, zoom_factor=4.0, increment=0.2) with col_4: if btn_CAM_Visualization: st.markdown("

Class Activation Map(CAM) Visualization

", unsafe_allow_html=True) img = Image.open('pages/images/cam_result.png').convert('RGB') st.markdown("
", unsafe_allow_html=True) width, height = img.size image_zoom(img, mode="both", size=(width // 4, height // 4), keep_aspect_ratio=True, zoom_factor=4.0, increment=0.2) with col_4: if btn_Download_Report: with st.form("patient_info_form"): st.write("Please provide patient details before downloading the report:") name = st.text_input("Name") age = st.number_input("Age", min_value=0, max_value=130) gender = st.selectbox("Gender", ["Male", "Female", "Other"]) address = st.text_input("Address") phone = st.text_input("Phone") submit = st.form_submit_button("Submit") if submit: pdf_buffer = generate_pdf(name, age, gender, address, phone) print(pdf_buffer) st.download_button( label="Download Report", data=pdf_buffer, file_name="patient_report.pdf", mime="application/pdf" ) col_6, col_7, col_8 = st.columns([7.8, 4.5, 8]) with col_7: if btn_View_Report: st.markdown("

Prediction Report

", unsafe_allow_html=True) df_styled = load_report() st.markdown("
", unsafe_allow_html=True) st.write(df_styled.to_html(), unsafe_allow_html=True)