import streamlit as st import numpy as np import joblib import os from PIL import Image from tensorflow.keras.applications import ResNet50 from tensorflow.keras.applications.resnet50 import preprocess_input from tensorflow.keras.preprocessing.image import img_to_array # Konfigurasi halaman st.set_page_config(page_title="Deteksi Kanker Payudara", page_icon="๐Ÿฉบ", layout="wide") # Fungsi untuk mencari file secara rekursif import pathlib def find_file(filename): root = pathlib.Path(".") for path in root.rglob(filename): return str(path) return None # Load model bawaan ResNet50 dan model LightGBM @st.cache_resource def load_models(): resnet = ResNet50(weights="imagenet", include_top=False, pooling="avg") lgb_path = find_file("lightgbm11_classifier_optimized.pkl") if not lgb_path: raise FileNotFoundError("File lightgbm11_classifier_optimized.pkl tidak ditemukan di direktori mana pun.") lgb = joblib.load(lgb_path) return resnet, lgb resnet_model, lgb_model = load_models() class_labels = {0: "Benign", 1: "Malignant", 2: "Normal"} # Sidebar st.sidebar.image("https://cdn-icons-png.flaticon.com/512/3774/3774299.png", width=100) st.sidebar.markdown("### ๐Ÿงฌ Aplikasi Deteksi Kanker Payudara") st.sidebar.markdown("**Mata Kuliah: Kecerdasan Buatan** \n**Kelompok 8**") st.sidebar.info( "๐Ÿ” Model CNN (ResNet50) digunakan untuk ekstraksi fitur dari gambar mamografi, " "kemudian diklasifikasikan menggunakan LightGBM. Optimasi dilakukan dengan algoritma " "**Root Mean Square Propagation (RMSProp)**." ) # Header st.markdown("

๐Ÿ“ท Sistem Deteksi Otomatis Kanker Payudara

", unsafe_allow_html=True) st.markdown("

Unggah gambar mamografi untuk mengklasifikasi: Benign, Malignant, atau Normal.

", unsafe_allow_html=True) st.markdown("---") # Formulir Pasien with st.expander("๐Ÿงพ Formulir Pasien"): nama = st.text_input("๐Ÿ‘ค Nama Pasien") usia = st.number_input("๐ŸŽ‚ Usia", min_value=1, max_value=120, value=30) tanggal = st.date_input("๐Ÿ“… Tanggal Pemeriksaan") # Upload gambar uploaded_file = st.file_uploader("๐Ÿ“ค Upload Gambar Mamografi", type=["jpg", "jpeg", "png"]) if uploaded_file: try: col1, col2 = st.columns([1, 2]) with col1: image = Image.open(uploaded_file).convert("RGB") st.image(image, caption="๐Ÿ–ผ๏ธ Gambar Mamografi", use_column_width=True) with col2: st.info("๐Ÿ”Ž Gambar sedang diproses...") image = image.resize((224, 224)) img_array = img_to_array(image) img_array = np.expand_dims(img_array, axis=0) img_array = preprocess_input(img_array) features = resnet_model.predict(img_array, verbose=0) prediction = lgb_model.predict(features) result_index = int(prediction[0]) result = class_labels.get(result_index, "Unknown") st.subheader("๐Ÿง  Hasil Klasifikasi") if result == "Benign": st.success("๐ŸŸข Hasil: Benign (Jinak)") st.markdown("Tumor jinak umumnya tidak menyebar dan tidak bersifat agresif. Tetap lakukan pemeriksaan berkala.") elif result == "Malignant": st.error("๐Ÿ”ด Hasil: Malignant (Ganas)") st.markdown("Tumor ganas dapat menyebar cepat. Segera konsultasikan ke dokter spesialis.") elif result == "Normal": st.success("โœ… Hasil: Normal") st.markdown("Tidak ditemukan indikasi kelainan. Pemeriksaan rutin tetap disarankan.") # Confidence Score if st.checkbox("๐Ÿ“ˆ Tampilkan Confidence Score (%)", value=True): if hasattr(lgb_model, "predict_proba"): proba = lgb_model.predict_proba(features)[0] persentase = np.round(proba * 100, 2) st.markdown("#### ๐Ÿ”ฌ Probabilitas Klasifikasi") for label, score in zip(class_labels.values(), persentase): emoji = "๐ŸŸข" if label == result else "โšช" st.markdown(f"{emoji} **{label}**: {score:.2f}%") st.progress(float(score) / 100) st.markdown("#### ๐Ÿ“‹ Tabel Confidence Score") st.table({ "Kelas": list(class_labels.values()), "Probabilitas (%)": [f"{p:.2f}%" for p in persentase] }) else: st.warning("โš ๏ธ Model tidak mendukung probabilitas prediksi.") except Exception as e: st.error(f"โŒ Terjadi kesalahan saat prediksi: {str(e)}") else: st.warning("๐Ÿ‘ˆ Silakan unggah gambar terlebih dahulu.") # Edukasi tambahan with st.expander("โ„น๏ธ Tentang Kanker Payudara"): st.markdown(""" - **Benign**: Tumor tidak ganas, tidak menyebar. Tetap perlu pemantauan. - **Malignant**: Kanker ganas. Butuh penanganan medis segera. - **Normal**: Tidak ada indikasi kelainan. ๐Ÿ‘‰ Lakukan pemeriksaan rutin dan konsultasikan dengan tenaga medis profesional. """)