Adjoumani commited on
Commit
a7be5b0
·
verified ·
1 Parent(s): fb6752d

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +250 -0
app.py ADDED
@@ -0,0 +1,250 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ #from streamlit_image_zoom import image_zoom # Import de la bibliothèque pour le zoom
3
+ import base64
4
+ import os
5
+ from dotenv import load_dotenv
6
+ #from anthropic import Anthropic
7
+ from openai import OpenAI
8
+ from PIL import Image, ImageOps
9
+ import tempfile
10
+
11
+ load_dotenv()
12
+
13
+
14
+ client = OpenAI(
15
+
16
+ base_url="https://api.x.ai/v1",
17
+ )
18
+ #client = Anthropic()
19
+ #MODEL_NAME ="claude-3-opus-20240229"
20
+ # Définir le style global
21
+ st.set_page_config(
22
+ page_title="Le Radiologue Virtuel",
23
+ page_icon="🩺",
24
+ layout="centered",
25
+ )
26
+
27
+ # CSS personnalisé pour styliser l'interface
28
+ st.markdown("""
29
+ <style>
30
+ body {
31
+ background-color: #f4f4f9;
32
+ color: #333333;
33
+ font-family: 'Arial', sans-serif;
34
+ }
35
+ .stButton>button {
36
+ background-color: #007bff;
37
+ color: white;
38
+ border-radius: 8px;
39
+ padding: 0.5em 1.5em;
40
+ font-size: 1em;
41
+ border: none;
42
+ transition: all 0.3s ease-in-out;
43
+ }
44
+ .stButton>button:hover {
45
+ background-color: #0056b3;
46
+ transform: scale(1.05);
47
+ }
48
+ .st-expander-header {
49
+ font-weight: bold;
50
+ font-size: 1.2em;
51
+ color: #007bff;
52
+ }
53
+ .stMarkdown {
54
+ font-size: 1.1em;
55
+ }
56
+ </style>
57
+ """, unsafe_allow_html=True)
58
+
59
+ sample_prompt = """
60
+ Vous êtes un professionnel de santé, expert dans l'analyse des images médicales (échographie, radiographie standard, TDM, IRM, ...), travaillant pour un hôpital de renom. Votre tâche consiste à examiner des images médicales afin d'identifier les anomalies, maladies ou problèmes de santé éventuels. Vous devez fournir des résultats détaillés, incluant toutes vos observations, les prochaines étapes, ainsi que des recommandations.
61
+ Votre analyse reste dans le cadre éducatif d'étudiants en radiologie médicale et ne sera en aucun cas publique. L'objectif est d'initier ces étudiants à l'interpretation des clichés radiologique.
62
+ **Instructions :**
63
+ 1. Analysez uniquement les images liées au corps humain et aux problèmes de santé.
64
+ 2. Rédigez votre réponse de manière structurée, détaillant :
65
+ - Les anomalies identifiées (le cas échéant).
66
+ - Les pathologies suspectées ou confirmées.
67
+ - Les recommandations et étapes suivantes.
68
+ 3. Si certains éléments ne sont pas clairs sur l'image, indiquez : *"Impossible de déterminer à partir de l'image fournie."*
69
+ 4. Terminez toujours votre réponse par une mention : *"Consultez un médecin avant de prendre toute décision."*
70
+ """
71
+
72
+ # Initialisation des variables d'état
73
+ if 'uploaded_file' not in st.session_state:
74
+ st.session_state.uploaded_file = None
75
+ if 'result' not in st.session_state:
76
+ st.session_state.result = None
77
+ if 'clinical_info' not in st.session_state:
78
+ st.session_state.clinical_info = "" # Pour stocker les renseignements cliniques
79
+
80
+
81
+
82
+ def encode_image(image_path):
83
+ with open(image_path, "rb") as image_file:
84
+ return base64.b64encode(image_file.read()).decode("utf-8")
85
+
86
+
87
+ def call_groq_model_for_analysis(filename: str, clinical_info: str, sample_prompt=sample_prompt):
88
+ # Récupérer l'extension du fichier pour définir le media_type
89
+ file_extension = os.path.splitext(filename)[1].lower() # Obtenir l'extension en minuscule
90
+ if file_extension == ".jpg" or file_extension == ".jpeg":
91
+ media_type = "image/jpeg"
92
+ elif file_extension == ".png":
93
+ media_type = "image/png"
94
+ else:
95
+ raise ValueError("Format de fichier non pris en charge.")
96
+ base64_image = encode_image(filename)
97
+ # Ajouter les renseignements cliniques au prompt
98
+ full_prompt = sample_prompt + f"\n\n**Renseignements cliniques du patient :** {clinical_info}\n"
99
+
100
+
101
+
102
+
103
+ messages_list=[
104
+ {
105
+ "role": "user",
106
+ "content": [
107
+ {
108
+ "type": "text",
109
+ "text": full_prompt,
110
+ },
111
+ {
112
+ "type": "image_url",
113
+ "image_url": {"url": f"data:{media_type};base64,{base64_image}"},
114
+ },
115
+ ],
116
+ }
117
+ ]
118
+
119
+ response = client.chat.completions.create(
120
+ model="grok-2-vision-1212",
121
+ temperature=0.01,
122
+ messages=messages_list,
123
+ )
124
+
125
+ return response.choices[0].message.content
126
+
127
+
128
+ def chat_eli(query):
129
+ eli5_prompt = "Tu dois expliquer l'information ci-dessous à un enfant de cinq ans. \n" + query
130
+ messages = [
131
+ {
132
+ "role": "user",
133
+ "content": eli5_prompt
134
+ }
135
+ ]
136
+
137
+ """response = client.messages.create(
138
+ model="claude-3-5-sonnet-20241022",
139
+ max_tokens=1024,
140
+ messages=messages
141
+ )"""
142
+
143
+ completion = client.chat.completions.create(
144
+ model="grok-2-latest",
145
+ messages=messages
146
+ )
147
+
148
+ return completion.choices[0].message.content
149
+
150
+
151
+ # Titre de l'application
152
+ st.title("🩺 **Le Radiologue Virtuel**")
153
+ st.subheader("Une IA avancée pour l'analyse des images médicales")
154
+
155
+ with st.expander("📖 A-Propos de cette Application"):
156
+ st.markdown("""
157
+ **Bienvenue sur LE RADIOLOGUE VIRTUEL**, votre assistant intelligent conçu pour fournir une analyse approfondie et précise des images médicales.
158
+
159
+ ### Fonctionnalités principales :
160
+ - **Analyse d'images médicales** : Téléchargez des clichés d'échographie, de radiographie, d'IRM ou de TDM, et laissez l'IA détecter les anomalies et fournir des recommandations détaillées.
161
+ - **Explications simplifiées** : Grâce à la fonction ELI5, comprenez les résultats complexes sous une forme adaptée à un public non expert.
162
+ - **Traitement d'image avancé** : Explorez l'image téléchargée avec des outils comme l'inversion pour une visualisation plus claire.
163
+
164
+ ### Cas d'utilisation :
165
+ - **Éducation médicale** : Destiné aux étudiants en radiologie, cet outil aide à se familiariser avec l'interprétation des images diagnostiques.
166
+ - **Support clinique** : Bien que non conçu pour remplacer un professionnel de santé, cet assistant peut fournir des indications utiles pour guider les analyses.
167
+ - **Recherche et apprentissage** : Une plateforme idéale pour expérimenter et apprendre l'impact de l'IA dans le domaine médical.
168
+
169
+ ### Technologie utilisée :
170
+ - **Modèle d'IA puissant** : L'IA utilise la technologie avancée de Llama 3.2 90B Vision, spécialisée dans l'analyse d'images complexes.
171
+ - **Interaction intuitive** : Développé avec Python et Streamlit pour une interface simple et conviviale.
172
+ - **Sécurité et confidentialité** : Toutes les analyses sont effectuées localement ou sur des serveurs sécurisés, garantissant la confidentialité des données médicales.
173
+
174
+ **⚠️ Avertissement** :
175
+ - Cet assistant n'est pas un outil médical certifié et ne remplace en aucun cas l'avis d'un médecin ou d'un spécialiste. Il est destiné à des fins éducatives et de support. Consultez toujours un professionnel de santé pour un diagnostic ou une décision médicale.
176
+ """)
177
+
178
+ # Champ d'entrée pour les renseignements cliniques
179
+ clinical_info = st.text_area(
180
+ "Renseignements cliniques du patient (facultatif)",
181
+ placeholder="Exemple : Patient présentant une douleur thoracique depuis 3 jours."
182
+ )
183
+
184
+ # Stocker les renseignements cliniques dans la session
185
+ st.session_state['clinical_info'] = clinical_info
186
+
187
+ # Téléchargement de l'image
188
+ st.markdown("### 📂 Téléchargez une image médicale")
189
+ uploaded_file = st.file_uploader("Formats acceptés : JPG, JPEG, PNG", type=["jpg", "jpeg", "png"])
190
+
191
+ # Gestion temporaire des fichiers
192
+ if uploaded_file is not None:
193
+ with tempfile.NamedTemporaryFile(delete=False, suffix=os.path.splitext(uploaded_file.name)[1]) as tmp_file:
194
+ tmp_file.write(uploaded_file.getvalue())
195
+ st.session_state['filename'] = tmp_file.name
196
+
197
+ st.image(uploaded_file, caption='Image Téléchargée')
198
+
199
+ # Charger l'image avec PIL
200
+ image = Image.open(uploaded_file)
201
+
202
+ # Ajouter un bouton pour afficher l'image en négatif
203
+ st.markdown("### 🔍 Explorez l'image")
204
+ col1, col2, col3 = st.columns([1, 2, 1]) # colonnes avec différentes proportions
205
+ col1.write("") # Espace dans la première colonne
206
+ col3.write("") # Espace dans la troisième colonne
207
+ col1.write("") # Espace dans la première colonne
208
+ col3.write("") # Espace dans la troisième colonne
209
+ if st.button("Afficher l'image en négatif"):
210
+ # Créer une version négative de l'image
211
+ negative_image = ImageOps.invert(image.convert("RGB")) # Convertir en RGB avant inversion
212
+
213
+ # Afficher l'image en négatif
214
+ st.subheader("Image en négatif :")
215
+ st.image(negative_image, caption="Image en négatif")
216
+ col1, col2, col3 = st.columns([1, 2, 1]) # colonnes avec différentes proportions
217
+ col1.write("") # Espace dans la première colonne
218
+ col3.write("") # Espace dans la troisième colonne
219
+ col1.write("") # Espace dans la première colonne
220
+ col3.write("") # Espace dans la troisième colonne
221
+
222
+ # Bouton pour analyser l'image
223
+ if st.button("Analyse l'Image"):
224
+ if 'filename' in st.session_state and os.path.exists(st.session_state['filename']):
225
+ with st.spinner("Analyse en cours... Veuillez patienter."):
226
+ st.session_state['result'] = call_groq_model_for_analysis(
227
+ st.session_state['filename'],
228
+ st.session_state['clinical_info']
229
+ )
230
+ st.success("Analyse terminée avec succès !")
231
+ st.markdown(st.session_state['result'], unsafe_allow_html=True)
232
+ os.unlink(st.session_state['filename']) # Supprimer le fichier temporaire après le traitement
233
+
234
+ # ELI5 Explanation
235
+ # Explication simplifiée
236
+ st.markdown("### 🤓 Explication Simplifiée")
237
+ if 'result' in st.session_state and st.session_state['result']:
238
+ st.info("Ci-dessous, vous avez une option pour ELI5 afin de comprendre en termes simples.")
239
+ if st.radio("ELI5 - Explique-moi comme si j'avais 5 ans", ('NON', 'OUI')) == 'OUI':
240
+ st.markdown("_Voici une explication simplifiée pour les non-initiés._")
241
+ simplified_explanation = chat_eli(st.session_state['result'])
242
+ st.markdown(simplified_explanation, unsafe_allow_html=True)
243
+
244
+ # Pied de page
245
+ st.markdown("""
246
+ <hr>
247
+ <footer style="text-align: center; font-size: 0.9em;">
248
+ © 2024 - Le Radiologue Virtuel | Propulsé par M. ADJOUMANI
249
+ </footer>
250
+ """, unsafe_allow_html=True)