radpid / app.py
yassonee's picture
Update app.py
ebfde4d verified
raw
history blame
7.19 kB
import streamlit as st
from transformers import pipeline, AutoImageProcessor
from PIL import Image, ImageDraw
import torch
st.set_page_config(
page_title="Fraktur Detektion",
layout="wide",
initial_sidebar_state="collapsed"
)
st.markdown("""
<style>
.stApp {
background-color: transparent !important;
padding: 0 !important;
}
[data-theme="light"] {
--background-color: #ffffff;
--text-color: #1f2937;
--border-color: #e5e7eb;
--button-color: #2563eb;
--button-hover: #1d4ed8;
}
[data-theme="dark"] {
--background-color: #1f2937;
--text-color: #f3f4f6;
--border-color: #4b5563;
--button-color: #3b82f6;
--button-hover: #2563eb;
}
.stButton > button {
background-color: var(--button-color) !important;
color: white !important;
border: none !important;
padding: 0.5rem 1rem !important;
border-radius: 0.375rem !important;
font-weight: 500 !important;
transition: background-color 0.2s !important;
}
.stButton > button:hover {
background-color: var(--button-hover) !important;
}
.block-container {
padding: 0.5rem !important;
max-width: 100% !important;
}
.stImage > img {
max-height: 250px !important;
width: auto !important;
margin: 0 auto !important;
}
.result-box {
padding: 0.375rem;
border-radius: 0.375rem;
margin: 0.25rem 0;
background: var(--background-color);
border: 1px solid var(--border-color);
color: var(--text-color);
}
h2, h3, h4 {
margin: 0.5rem 0 !important;
color: var(--text-color) !important;
font-size: 1rem !important;
}
#MainMenu, footer, header {
display: none !important;
}
.uploadedFile {
border: 1px dashed var(--border-color);
border-radius: 0.375rem;
padding: 0.25rem;
}
.row-widget.stButton {
text-align: center;
margin: 1rem 0;
}
div[data-testid="stFileUploader"] {
width: 100%;
}
</style>
""", unsafe_allow_html=True)
@st.cache_resource
def load_models():
return {
"KnochenAuge": pipeline("object-detection", model="D3STRON/bone-fracture-detr"),
"KnochenWächter": pipeline("image-classification",
model="Heem2/bone-fracture-detection-using-xray",
image_processor=AutoImageProcessor.from_pretrained("Heem2/bone-fracture-detection-using-xray")),
"RöntgenMeister": pipeline("image-classification",
model="nandodeomkar/autotrain-fracture-detection-using-google-vit-base-patch-16-54382127388",
image_processor=AutoImageProcessor.from_pretrained("nandodeomkar/autotrain-fracture-detection-using-google-vit-base-patch-16-54382127388"))
}
def draw_boxes(image, predictions):
draw = ImageDraw.Draw(image)
for pred in predictions:
if pred['label'].lower() == 'fracture' and pred['score'] > 0.6:
box = pred['box']
label = f"Fraktur ({pred['score']:.2%})"
color = "#2563eb"
draw.rectangle(
[(box['xmin'], box['ymin']), (box['xmax'], box['ymax'])],
outline=color,
width=2
)
text_bbox = draw.textbbox((box['xmin'], box['ymin']-15), label)
draw.rectangle(text_bbox, fill=color)
draw.text((box['xmin'], box['ymin']-15), label, fill="white")
return image
def main():
models = load_models()
st.markdown("### 📤 Röntgenbilder Upload")
# File uploader avec label caché
uploaded_files = st.file_uploader(
"Wählen Sie Röntgenbilder aus",
type=['png', 'jpg', 'jpeg'],
accept_multiple_files=True,
label_visibility="collapsed"
)
if uploaded_files:
# Bouton d'analyse
if st.button("Bilder analysieren", key="analyze_button"):
col1, col2 = st.columns([1, 1])
for idx, uploaded_file in enumerate(uploaded_files):
image = Image.open(uploaded_file)
# Analyse avec KnochenAuge (localisierung)
predictions = models["KnochenAuge"](image)
fractures_found = any(p['label'].lower() == 'fracture' and p['score'] > 0.6 for p in predictions)
# Afficher uniquement si des fractures sont détectées
if fractures_found:
with col1 if idx % 2 == 0 else col2:
result_image = image.copy()
result_image = draw_boxes(result_image, predictions)
st.image(result_image, caption=f"Bild {idx + 1}", use_column_width=True)
# Analyse KnochenWächter et RöntgenMeister
pred_wachter = models["KnochenWächter"](image)[0]
pred_meister = models["RöntgenMeister"](image)[0]
if pred_wachter['score'] > 0.6 or pred_meister['score'] > 0.6:
st.markdown(f"""
<div class='result-box'>
<span style='color: #2563eb'>KnochenWächter:</span> {pred_wachter['score']:.1%}<br>
<span style='color: #2563eb'>RöntgenMeister:</span> {pred_meister['score']:.1%}
</div>
""", unsafe_allow_html=True)
# Script pour la synchronisation du thème
st.markdown("""
<script>
// Fonction pour mettre à jour le thème
function updateTheme(isDark) {
document.documentElement.setAttribute('data-theme', isDark ? 'dark' : 'light');
// Mise à jour des styles en fonction du thème
const root = document.documentElement;
if (isDark) {
root.style.setProperty('--background-color', '#1f2937');
root.style.setProperty('--text-color', '#f3f4f6');
root.style.setProperty('--border-color', '#4b5563');
} else {
root.style.setProperty('--background-color', '#ffffff');
root.style.setProperty('--text-color', '#1f2937');
root.style.setProperty('--border-color', '#e5e7eb');
}
}
// Écouter les messages du parent
window.addEventListener('message', function(e) {
if (e.data.type === 'theme-change') {
updateTheme(e.data.theme === 'dark');
}
});
// Thème initial basé sur les préférences système
updateTheme(window.matchMedia('(prefers-color-scheme: dark)').matches);
</script>
""", unsafe_allow_html=True)
if __name__ == "__main__":
main()