yassonee commited on
Commit
aae61a3
·
verified ·
1 Parent(s): f700114

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +52 -135
app.py CHANGED
@@ -11,85 +11,61 @@ st.set_page_config(
11
 
12
  st.markdown("""
13
  <style>
14
- /* Reset et base */
15
  .stApp {
16
- background-color: var(--background-color) !important;
17
  padding: 0 !important;
18
- overflow: hidden !important;
19
  }
20
 
21
- /* Variables de thème */
22
  [data-theme="light"] {
23
  --background-color: #ffffff;
24
  --text-color: #1f2937;
25
  --border-color: #e5e7eb;
26
- --secondary-bg: #f3f4f6;
27
  }
28
 
29
  [data-theme="dark"] {
30
  --background-color: #1f2937;
31
  --text-color: #f3f4f6;
32
  --border-color: #4b5563;
33
- --secondary-bg: #374151;
34
  }
35
 
36
- /* Layout principal */
37
  .block-container {
38
  padding: 0.5rem !important;
39
  max-width: 100% !important;
40
  }
41
 
42
- /* Contrôles et upload */
43
- .uploadedFile {
44
- border: 1px dashed var(--border-color);
45
- border-radius: 0.375rem;
46
- padding: 0.25rem;
47
- background: var(--secondary-bg);
48
- }
49
-
50
- /* Ajustement des colonnes */
51
- [data-testid="column"] {
52
- padding: 0 0.5rem !important;
53
- }
54
-
55
- /* Images adaptatives */
56
  .stImage > img {
57
- width: 100% !important;
58
- height: auto !important;
59
- max-height: 400px !important;
60
- object-fit: contain !important;
61
  }
62
 
63
- /* Résultats */
64
  .result-box {
65
  padding: 0.375rem;
66
  border-radius: 0.375rem;
67
  margin: 0.25rem 0;
68
- background: var(--secondary-bg);
69
  border: 1px solid var(--border-color);
70
  color: var(--text-color);
71
  }
72
 
73
- /* Titres */
74
- h2, h3 {
75
- margin: 0 !important;
76
- padding: 0.5rem 0 !important;
77
- font-size: 1rem !important;
78
  color: var(--text-color) !important;
 
79
  }
80
 
81
- /* Nettoyage des éléments inutiles */
82
- #MainMenu, footer, header, .viewerBadge_container__1QSob, .stDeployButton {
83
  display: none !important;
84
  }
85
 
86
- /* Ajustements espacement */
87
- div[data-testid="stVerticalBlock"] {
88
- gap: 0.5rem !important;
 
89
  }
90
 
91
- .element-container {
92
- margin: 0.25rem 0 !important;
93
  }
94
  </style>
95
  """, unsafe_allow_html=True)
@@ -99,121 +75,62 @@ def load_models():
99
  return {
100
  "KnochenAuge": pipeline("object-detection", model="D3STRON/bone-fracture-detr"),
101
  "KnochenWächter": pipeline("image-classification", model="Heem2/bone-fracture-detection-using-xray"),
102
- "RöntgenMeister": pipeline("image-classification",
103
- model="nandodeomkar/autotrain-fracture-detection-using-google-vit-base-patch-16-54382127388")
104
  }
105
 
106
- def translate_label(label):
107
- translations = {
108
- "fracture": "Knochenbruch",
109
- "no fracture": "Kein Bruch",
110
- "normal": "Normal",
111
- "abnormal": "Auffällig"
112
- }
113
- return translations.get(label.lower(), label)
114
-
115
  def draw_boxes(image, predictions):
116
  draw = ImageDraw.Draw(image)
117
  for pred in predictions:
118
- box = pred['box']
119
- label = f"{translate_label(pred['label'])} ({pred['score']:.2%})"
120
- color = "#2563eb" if pred['score'] > 0.7 else "#eab308"
121
-
122
- draw.rectangle(
123
- [(box['xmin'], box['ymin']), (box['xmax'], box['ymax'])],
124
- outline=color,
125
- width=2
126
- )
127
-
128
- # Label plus compact
129
- text_bbox = draw.textbbox((box['xmin'], box['ymin']-15), label)
130
- draw.rectangle(text_bbox, fill=color)
131
- draw.text((box['xmin'], box['ymin']-15), label, fill="white")
132
  return image
133
 
134
  def main():
135
  models = load_models()
136
-
137
- # Disposition en deux colonnes principales
138
- col1, col2 = st.columns([1, 2])
139
-
140
- with col1:
141
- st.markdown("### 📤 Röntgenbild Upload")
142
- uploaded_file = st.file_uploader("", type=['png', 'jpg', 'jpeg'])
143
 
144
- if uploaded_file:
145
- conf_threshold = st.slider(
146
- "Konfidenzschwelle",
147
- min_value=0.0, max_value=1.0,
148
- value=0.60, step=0.05
149
- )
150
-
151
- with col2:
152
- if uploaded_file:
153
  image = Image.open(uploaded_file)
154
 
155
- st.markdown("### 🔍 Meinung der KI-Experten")
156
-
157
  # Analyse avec KnochenAuge (localisierung)
158
- st.markdown("#### 👁️ Das KnochenAuge - Lokalisation")
159
  predictions = models["KnochenAuge"](image)
160
- filtered_preds = [p for p in predictions if p['score'] >= conf_threshold]
161
-
162
- if filtered_preds:
163
- result_image = image.copy()
164
- result_image = draw_boxes(result_image, filtered_preds)
165
- st.image(result_image, use_container_width=True)
166
 
167
- # Autres modèles
168
- st.markdown("#### 🎯 KI-Analyse")
169
- col_left, col_right = st.columns(2)
170
-
171
- with col_left:
172
- st.markdown("**🛡️ Der KnochenWächter**")
173
- predictions = models["KnochenWächter"](image)
174
- for pred in predictions:
175
- if pred['score'] >= conf_threshold:
176
- score_color = "#22c55e" if pred['score'] > 0.7 else "#eab308"
 
 
177
  st.markdown(f"""
178
  <div class='result-box'>
179
- <span style='color: {score_color}; font-weight: 500;'>
180
- {pred['score']:.1%}
181
- </span> - {translate_label(pred['label'])}
182
  </div>
183
  """, unsafe_allow_html=True)
184
-
185
- with col_right:
186
- st.markdown("**🎓 Der RöntgenMeister**")
187
- predictions = models["RöntgenMeister"](image)
188
- for pred in predictions:
189
- if pred['score'] >= conf_threshold:
190
- score_color = "#22c55e" if pred['score'] > 0.7 else "#eab308"
191
- st.markdown(f"""
192
- <div class='result-box'>
193
- <span style='color: {score_color}; font-weight: 500;'>
194
- {pred['score']:.1%}
195
- </span> - {translate_label(pred['label'])}
196
- </div>
197
- """, unsafe_allow_html=True)
198
- else:
199
- st.info("Bitte laden Sie ein Röntgenbild hoch (JPEG, PNG)")
200
-
201
- # Script pour la synchronisation du thème
202
- st.markdown("""
203
- <script>
204
- function updateTheme(isDark) {
205
- document.documentElement.setAttribute('data-theme', isDark ? 'dark' : 'light');
206
- }
207
-
208
- window.addEventListener('message', function(e) {
209
- if (e.data.type === 'theme-change') {
210
- updateTheme(e.data.theme === 'dark');
211
- }
212
- });
213
-
214
- updateTheme(window.matchMedia('(prefers-color-scheme: dark)').matches);
215
- </script>
216
- """, unsafe_allow_html=True)
217
 
218
  if __name__ == "__main__":
219
  main()
 
11
 
12
  st.markdown("""
13
  <style>
 
14
  .stApp {
15
+ background-color: transparent !important;
16
  padding: 0 !important;
 
17
  }
18
 
 
19
  [data-theme="light"] {
20
  --background-color: #ffffff;
21
  --text-color: #1f2937;
22
  --border-color: #e5e7eb;
 
23
  }
24
 
25
  [data-theme="dark"] {
26
  --background-color: #1f2937;
27
  --text-color: #f3f4f6;
28
  --border-color: #4b5563;
 
29
  }
30
 
 
31
  .block-container {
32
  padding: 0.5rem !important;
33
  max-width: 100% !important;
34
  }
35
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  .stImage > img {
37
+ max-height: 250px !important;
38
+ width: auto !important;
39
+ margin: 0 auto !important;
 
40
  }
41
 
 
42
  .result-box {
43
  padding: 0.375rem;
44
  border-radius: 0.375rem;
45
  margin: 0.25rem 0;
46
+ background: var(--background-color);
47
  border: 1px solid var(--border-color);
48
  color: var(--text-color);
49
  }
50
 
51
+ h2, h3, h4 {
52
+ margin: 0.5rem 0 !important;
 
 
 
53
  color: var(--text-color) !important;
54
+ font-size: 1rem !important;
55
  }
56
 
57
+ #MainMenu, footer, header {
 
58
  display: none !important;
59
  }
60
 
61
+ .uploadedFile {
62
+ border: 1px dashed var(--border-color);
63
+ border-radius: 0.375rem;
64
+ padding: 0.25rem;
65
  }
66
 
67
+ .row-widget.stButton {
68
+ text-align: center;
69
  }
70
  </style>
71
  """, unsafe_allow_html=True)
 
75
  return {
76
  "KnochenAuge": pipeline("object-detection", model="D3STRON/bone-fracture-detr"),
77
  "KnochenWächter": pipeline("image-classification", model="Heem2/bone-fracture-detection-using-xray"),
78
+ "RöntgenMeister": pipeline("image-classification", model="nandodeomkar/autotrain-fracture-detection-using-google-vit-base-patch-16-54382127388")
 
79
  }
80
 
 
 
 
 
 
 
 
 
 
81
  def draw_boxes(image, predictions):
82
  draw = ImageDraw.Draw(image)
83
  for pred in predictions:
84
+ if pred['label'].lower() == 'fracture' and pred['score'] > 0.6:
85
+ box = pred['box']
86
+ label = f"Fraktur ({pred['score']:.2%})"
87
+ color = "#2563eb"
88
+
89
+ draw.rectangle(
90
+ [(box['xmin'], box['ymin']), (box['xmax'], box['ymax'])],
91
+ outline=color,
92
+ width=2
93
+ )
94
+
95
+ text_bbox = draw.textbbox((box['xmin'], box['ymin']-15), label)
96
+ draw.rectangle(text_bbox, fill=color)
97
+ draw.text((box['xmin'], box['ymin']-15), label, fill="white")
98
  return image
99
 
100
  def main():
101
  models = load_models()
102
+
103
+ st.markdown("### 📤 Röntgenbilder Upload")
104
+ uploaded_files = st.file_uploader("", type=['png', 'jpg', 'jpeg'], accept_multiple_files=True)
105
+
106
+ if uploaded_files:
107
+ col1, col2 = st.columns([1, 1])
 
108
 
109
+ for idx, uploaded_file in enumerate(uploaded_files):
 
 
 
 
 
 
 
 
110
  image = Image.open(uploaded_file)
111
 
 
 
112
  # Analyse avec KnochenAuge (localisierung)
 
113
  predictions = models["KnochenAuge"](image)
114
+ fractures_found = any(p['label'].lower() == 'fracture' and p['score'] > 0.6 for p in predictions)
 
 
 
 
 
115
 
116
+ # Afficher uniquement si des fractures sont détectées
117
+ if fractures_found:
118
+ with col1 if idx % 2 == 0 else col2:
119
+ result_image = image.copy()
120
+ result_image = draw_boxes(result_image, predictions)
121
+ st.image(result_image, caption=f"Bild {idx + 1}", use_column_width=True)
122
+
123
+ # Analyse KnochenWächter et RöntgenMeister
124
+ pred_wachter = models["KnochenWächter"](image)[0]
125
+ pred_meister = models["RöntgenMeister"](image)[0]
126
+
127
+ if pred_wachter['score'] > 0.6 or pred_meister['score'] > 0.6:
128
  st.markdown(f"""
129
  <div class='result-box'>
130
+ <span style='color: #2563eb'>KnochenWächter:</span> {pred_wachter['score']:.1%}<br>
131
+ <span style='color: #2563eb'>RöntgenMeister:</span> {pred_meister['score']:.1%}
 
132
  </div>
133
  """, unsafe_allow_html=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134
 
135
  if __name__ == "__main__":
136
  main()