DavidNgoue commited on
Commit
0d48712
·
verified ·
1 Parent(s): 62ec819

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +183 -90
app.py CHANGED
@@ -8,14 +8,12 @@ from barcode.writer import ImageWriter
8
  import qrcode
9
  import tempfile
10
 
11
-
12
  def image_to_bytes(img):
13
  pil_image = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
14
  buffer = BytesIO()
15
  pil_image.save(buffer, format="PNG")
16
  return buffer.getvalue()
17
 
18
-
19
  def generate_barcode(link):
20
  code128 = barcode.get_barcode_class('code128')
21
  barcode_image = code128(link, writer=ImageWriter())
@@ -23,8 +21,6 @@ def generate_barcode(link):
23
  barcode_image.write(buffer)
24
  return Image.open(buffer)
25
 
26
-
27
-
28
  def generate_qrcode(link):
29
  qr = qrcode.QRCode(
30
  version=2,
@@ -36,17 +32,115 @@ def generate_qrcode(link):
36
  qr.make(fit=True)
37
  qr_image = qr.make_image(fill_color="black", back_color="white")
38
 
39
- small_qr_image = qr_image.resize((100, 100), Image.Resampling.LANCZOS)
40
 
41
  buffer = BytesIO()
42
  small_qr_image.save(buffer, format="PNG")
43
  return Image.open(buffer)
44
 
45
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
 
47
  def main():
48
- st.set_page_config(page_title="Application de Vision par Ordinateur", layout="wide")
49
- st.title("Application de Vision par Ordinateur")
 
 
 
 
 
 
 
 
 
50
 
51
  st.sidebar.header("Chargement de l'image")
52
  if "default_image" not in st.session_state:
@@ -63,49 +157,75 @@ def main():
63
  return
64
 
65
  st.sidebar.header("Fonctionnalités")
66
- menu_option = st.sidebar.selectbox("Choisissez une fonctionnalité", [
67
- "Accueil",
68
- "Transformations d'image",
69
- "Cropping",
70
- "Rotation",
71
- "Floutage",
72
- "Contours",
73
- "Génération de Code-barres et QR Code",
74
- "Détection Faciale"
75
- ])
 
 
 
 
76
 
77
  image_np = st.session_state["default_image"]
78
 
79
  if menu_option == "Accueil":
80
- st.header("Bienvenue sur l'application de Vision par Ordinateur")
81
- st.write(
82
- "Cette application utilise OpenCV pour effectuer diverses transformations "
83
- "et manipulations d'images. Charge une image depuis la barre latérale et explore les fonctionnalités."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  )
85
 
86
  elif menu_option == "Transformations d'image":
87
  st.subheader("Transformations d'image")
88
 
89
- col1, col2, col3, col4 = st.columns(4)
90
- with col1:
91
- if st.button("Transformer en gris"):
92
- gray = cv2.cvtColor(image_np, cv2.COLOR_BGR2GRAY)
93
- st.image(gray, caption="Image en Niveaux de Gris", use_container_width=True)
94
- with col2:
95
- if st.button("Couleur rouge"):
96
- red = image_np.copy()
97
- red[:, :, 1:] = 0
98
- st.image(red, caption="Image Rouge", use_container_width=True)
99
- with col3:
100
- if st.button("Couleur verte"):
101
- green = image_np.copy()
102
- green[:, :, [0, 2]] = 0
103
- st.image(green, caption="Image Verte", use_container_width=True)
104
- with col4:
105
- if st.button("Couleur jaune"):
106
- yellow = image_np.copy()
107
- yellow[:, :, 0] = 0
108
- st.image(yellow, caption="Image Jaune", use_container_width=True)
109
 
110
  elif menu_option == "Cropping":
111
  st.subheader("Cropping")
@@ -115,66 +235,58 @@ def main():
115
  x2 = st.number_input("x2", 1, image_np.shape[1], step=1)
116
  y2 = st.number_input("y2", 1, image_np.shape[0], step=1)
117
 
118
- if st.button("Cropper"):
119
- cropped = image_np[int(y1):int(y2), int(x1):int(x2)]
120
- st.image(cropped, caption="Image Croppée", use_container_width=True)
121
 
122
  elif menu_option == "Rotation":
123
  st.subheader("Rotation")
124
 
125
  angle = st.selectbox("Angle de rotation", [45, 90, 180])
126
 
127
- if st.button("Tourner"):
128
- rows, cols, _ = image_np.shape
129
- rotation_matrix = cv2.getRotationMatrix2D((cols / 2, rows / 2), angle, 1)
130
- rotated = cv2.warpAffine(image_np, rotation_matrix, (cols, rows))
131
- st.image(rotated, caption=f"Image Rotée de {angle} degrés", use_container_width=True)
132
 
133
  elif menu_option == "Floutage":
134
  st.subheader("Floutage")
135
 
136
  blur_level = st.slider("Niveau de flou (k)", min_value=1, max_value=51, step=2, value=15)
137
- if st.button("Appliquer le flou"):
138
- blurred = cv2.GaussianBlur(image_np, (blur_level, blur_level), 0)
139
- st.image(blurred, caption=f"Image Floutée (k={blur_level})", use_container_width=True)
140
 
141
  elif menu_option == "Contours":
142
  st.subheader("Contours")
143
 
144
- if st.button("Capturer les contours"):
145
- gray = cv2.cvtColor(image_np, cv2.COLOR_BGR2GRAY)
146
- edges = cv2.Canny(gray, 100, 200)
147
- st.image(edges, caption="Contours de l'Image", use_container_width=True)
148
 
149
  elif menu_option == "Génération de Code-barres et QR Code":
150
  st.subheader("Génération de Code-barres et QR Code")
151
  link = st.text_input("Entre un lien ou un texte pour générer le code-barres et le QR code")
152
- if st.button("Générer"):
153
- if link:
154
- barcode_image = generate_barcode(link)
155
- st.image(barcode_image, caption="Code-barres généré", use_container_width=True)
156
-
157
- qrcode_image = generate_qrcode(link)
158
- st.image(qrcode_image, caption="QR Code généré", use_container_width=True)
159
- else:
160
- st.error("Veuillez entrer un lien valide pour générer les codes.")
161
-
162
  elif menu_option == "Détection Faciale":
163
  st.subheader("Détection Faciale")
164
 
165
- # Charger le modèle Haarcascade pour la détection des visages
166
  face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_frontalface_default.xml")
167
 
168
- # Choix de la source
169
  detection_option = st.radio(
170
  "Choisis la source pour la détection faciale",
171
  options=["Webcam", "Vidéo téléversée"]
172
  )
173
 
174
  if detection_option == "Webcam":
175
- # Option pour utiliser la webcam
176
  if st.button("Lancer la détection via webcam"):
177
- cap = cv2.VideoCapture(0) # 0 pour la webcam par défaut
178
 
179
  if not cap.isOpened():
180
  st.error("Impossible d'accéder à la webcam, Hugging Face et le navigateur bloquent l'accès.")
@@ -188,27 +300,18 @@ def main():
188
  st.error("Erreur lors de la capture vidéo.")
189
  break
190
 
191
- # Convertir en niveaux de gris
192
  gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
193
-
194
- # Détecter les visages
195
  faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
196
 
197
- # Dessiner des rectangles autour des visages détectés
198
  for (x, y, w, h) in faces:
199
  cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2)
200
 
201
- # Convertir l'image pour Streamlit
202
  frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
203
-
204
- # Afficher l'image dans l'interface Streamlit
205
  frame_placeholder.image(frame, channels="RGB", use_container_width=True)
206
 
207
- # Libérer la webcam une fois le flux terminé
208
  cap.release()
209
 
210
  elif detection_option == "Vidéo téléversée":
211
- # Option pour téléverser une vidéo
212
  uploaded_video = st.file_uploader("Charge une vidéo", type=["mp4", "avi", "mov"])
213
  if uploaded_video is not None:
214
  video_bytes = uploaded_video.read()
@@ -224,26 +327,16 @@ def main():
224
  if not ret:
225
  break
226
 
227
- # Convertir en niveaux de gris
228
  gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
229
-
230
- # Détecter les visages
231
  faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
232
 
233
- # Dessiner des rectangles autour des visages détectés
234
  for (x, y, w, h) in faces:
235
  cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2)
236
 
237
- # Convertir l'image pour Streamlit
238
  frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
239
-
240
- # Afficher l'image dans l'interface Streamlit
241
  frame_placeholder.image(frame, channels="RGB", use_container_width=True)
242
 
243
  cap.release()
244
 
245
-
246
-
247
-
248
  if __name__ == "__main__":
249
  main()
 
8
  import qrcode
9
  import tempfile
10
 
 
11
  def image_to_bytes(img):
12
  pil_image = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
13
  buffer = BytesIO()
14
  pil_image.save(buffer, format="PNG")
15
  return buffer.getvalue()
16
 
 
17
  def generate_barcode(link):
18
  code128 = barcode.get_barcode_class('code128')
19
  barcode_image = code128(link, writer=ImageWriter())
 
21
  barcode_image.write(buffer)
22
  return Image.open(buffer)
23
 
 
 
24
  def generate_qrcode(link):
25
  qr = qrcode.QRCode(
26
  version=2,
 
32
  qr.make(fit=True)
33
  qr_image = qr.make_image(fill_color="black", back_color="white")
34
 
35
+ small_qr_image = qr_image.resize((60, 60), Image.Resampling.LANCZOS)
36
 
37
  buffer = BytesIO()
38
  small_qr_image.save(buffer, format="PNG")
39
  return Image.open(buffer)
40
 
41
+ def add_custom_css():
42
+ css = """
43
+ <style>
44
+ body {
45
+ background: linear-gradient(135deg, #a8dadc, #f1faee);
46
+ color: #1d3557;
47
+ font-family: 'Arial', sans-serif;
48
+ animation: backgroundAnimation 10s infinite alternate;
49
+ }
50
+
51
+ @keyframes backgroundAnimation {
52
+ 0% {
53
+ background: linear-gradient(135deg, #a8dadc, #f1faee);
54
+ }
55
+ 100% {
56
+ background: linear-gradient(135deg, #f1faee, #457b9d);
57
+ }
58
+ }
59
+
60
+ .stButton>button {
61
+ background-color: #457b9d;
62
+ color: white;
63
+ border-radius: 5px;
64
+ transition: transform 0.3s, background-color 0.3s;
65
+ box-shadow: 2px 2px 6px rgba(0,0,0,0.2);
66
+ }
67
+
68
+ .stButton>button:hover {
69
+ transform: scale(1.1);
70
+ background-color: #1d3557;
71
+ }
72
+
73
+ .stSidebar {
74
+ background: linear-gradient(135deg, #457b9d, #a8dadc);
75
+ color: white;
76
+ font-size: 16px;
77
+ }
78
+
79
+ .stImage {
80
+ animation: fadeIn 2s ease-in-out;
81
+ }
82
+
83
+ @keyframes fadeIn {
84
+ 0% {
85
+ opacity: 0;
86
+ }
87
+ 100% {
88
+ opacity: 1;
89
+ }
90
+ }
91
+
92
+ header, footer {
93
+ background: #457b9d;
94
+ color: white;
95
+ }
96
+
97
+ .stMarkdown {
98
+ animation: slideIn 1s ease-out;
99
+ }
100
+
101
+ @keyframes slideIn {
102
+ 0% {
103
+ transform: translateY(-20px);
104
+ opacity: 0;
105
+ }
106
+ 100% {
107
+ transform: translateY(0);
108
+ opacity: 1;
109
+ }
110
+ }
111
+ </style>
112
+ """
113
+ st.markdown(css, unsafe_allow_html=True)
114
+
115
+ def add_custom_js():
116
+ js = """
117
+ <script>
118
+ document.addEventListener('DOMContentLoaded', function() {
119
+ const elements = document.querySelectorAll('.stButton>button');
120
+ elements.forEach(button => {
121
+ button.addEventListener('click', () => {
122
+ button.style.backgroundColor = '#a8dadc';
123
+ button.style.transform = 'rotate(360deg)';
124
+ setTimeout(() => button.style.transform = 'rotate(0deg)', 300);
125
+ });
126
+ });
127
+ });
128
+ </script>
129
+ """
130
+ st.markdown(js, unsafe_allow_html=True)
131
 
132
  def main():
133
+ st.set_page_config(page_title="ADS VISOR - Un autre regard", layout="wide")
134
+
135
+ add_custom_css()
136
+ add_custom_js()
137
+
138
+
139
+ logo_path = "logo.jpg"
140
+ logo = Image.open(logo_path)
141
+ st.image(logo, width=150, caption="ADS VISOR")
142
+
143
+ st.title("ADS VISOR - Un autre regard")
144
 
145
  st.sidebar.header("Chargement de l'image")
146
  if "default_image" not in st.session_state:
 
157
  return
158
 
159
  st.sidebar.header("Fonctionnalités")
160
+ menu_option = st.sidebar.selectbox(
161
+ "Choisissez une fonctionnalité",
162
+ ["Accueil", "Transformations d'image", "Cropping", "Rotation", "Floutage", "Contours", "Génération de Code-barres et QR Code", "Détection Faciale"],
163
+ format_func=lambda x: {
164
+ "Accueil": "🏠 Accueil",
165
+ "Transformations d'image": "🖼️ Transformations",
166
+ "Cropping": "✂️ Cropping",
167
+ "Rotation": "🔄 Rotation",
168
+ "Floutage": "🌫️ Floutage",
169
+ "Contours": "🔍 Contours",
170
+ "Génération de Code-barres et QR Code": "📇 Codes",
171
+ "Détection Faciale": "��� Détection Faciale"
172
+ }.get(x, x)
173
+ )
174
 
175
  image_np = st.session_state["default_image"]
176
 
177
  if menu_option == "Accueil":
178
+ st.header("Bienvenue sur ADS VISOR")
179
+ st.markdown(
180
+ """
181
+ <div class="stMarkdown">
182
+ <h2>ADS VISOR est une application innovante pour analyser, transformer et explorer vos images. 🖼️✨</h2>
183
+ <p>Elle a été concu par un groupe de trois étudiants dans le contexte du contrôle continu de Computer Vision.</p>
184
+ <p>Que vous soyez un professionnel ou un passionné, découvrez un large éventail de fonctionnalités interactives !</p>
185
+ <ul>
186
+ <li><b>Transformations d'image :</b> Couleurs, niveaux de gris, etc.</li>
187
+ <li><b>Découpage & Rotation :</b> Ajustez vos images à la perfection.</li>
188
+ <li><b>Détection Faciale :</b> Identifiez les visages automatiquement.</li>
189
+ <li><b>Codes-barres & QR Codes :</b> Génération rapide pour vos projets.</li>
190
+ </ul>
191
+ </div>
192
+ """,
193
+ unsafe_allow_html=True
194
+ )
195
+
196
+ st.write("### Équipe :")
197
+ st.markdown(
198
+ """
199
+ | **Nom** | **Rôle** |
200
+ |------------------------|---------------------------|
201
+ | **Ngoue David** | Master 2 Intelligence Artificielle et Big Data |
202
+ | **Bidzanga Armel** | Master 2 Intelligence Artificielle et Big Data |
203
+ | **Nziou Serena** | Master 2 Administration de Systèmes d'Information |
204
+ """,
205
+ unsafe_allow_html=True
206
  )
207
 
208
  elif menu_option == "Transformations d'image":
209
  st.subheader("Transformations d'image")
210
 
211
+ tab1, tab2, tab3, tab4 = st.tabs([
212
+ "Gris 🖤", "Rouge ❤️", "Vert 💚", "Jaune 💛"
213
+ ])
214
+
215
+ with tab1:
216
+ st.image(cv2.cvtColor(image_np, cv2.COLOR_BGR2GRAY), caption="Image en Niveaux de Gris", use_container_width=True)
217
+ with tab2:
218
+ red = image_np.copy()
219
+ red[:, :, 1:] = 0
220
+ st.image(red, caption="Image Rouge", use_container_width=True)
221
+ with tab3:
222
+ green = image_np.copy()
223
+ green[:, :, [0, 2]] = 0
224
+ st.image(green, caption="Image Verte", use_container_width=True)
225
+ with tab4:
226
+ yellow = image_np.copy()
227
+ yellow[:, :, 0] = 0
228
+ st.image(yellow, caption="Image Jaune", use_container_width=True)
 
 
229
 
230
  elif menu_option == "Cropping":
231
  st.subheader("Cropping")
 
235
  x2 = st.number_input("x2", 1, image_np.shape[1], step=1)
236
  y2 = st.number_input("y2", 1, image_np.shape[0], step=1)
237
 
238
+ cropped = image_np[int(y1):int(y2), int(x1):int(x2)]
239
+ st.image(cropped, caption="Image Croppée", use_container_width=True)
 
240
 
241
  elif menu_option == "Rotation":
242
  st.subheader("Rotation")
243
 
244
  angle = st.selectbox("Angle de rotation", [45, 90, 180])
245
 
246
+ rows, cols, _ = image_np.shape
247
+ rotation_matrix = cv2.getRotationMatrix2D((cols / 2, rows / 2), angle, 1)
248
+ rotated = cv2.warpAffine(image_np, rotation_matrix, (cols, rows))
249
+ st.image(rotated, caption=f"Image Rotée de {angle} degrés", use_container_width=True)
 
250
 
251
  elif menu_option == "Floutage":
252
  st.subheader("Floutage")
253
 
254
  blur_level = st.slider("Niveau de flou (k)", min_value=1, max_value=51, step=2, value=15)
255
+ blurred = cv2.GaussianBlur(image_np, (blur_level, blur_level), 0)
256
+ st.image(blurred, caption=f"Image Floutée (k={blur_level})", use_container_width=True)
 
257
 
258
  elif menu_option == "Contours":
259
  st.subheader("Contours")
260
 
261
+ gray = cv2.cvtColor(image_np, cv2.COLOR_BGR2GRAY)
262
+ edges = cv2.Canny(gray, 100, 200)
263
+ st.image(edges, caption="Contours de l'Image", use_container_width=True)
 
264
 
265
  elif menu_option == "Génération de Code-barres et QR Code":
266
  st.subheader("Génération de Code-barres et QR Code")
267
  link = st.text_input("Entre un lien ou un texte pour générer le code-barres et le QR code")
268
+ if link:
269
+ barcode_image = generate_barcode(link)
270
+ st.image(barcode_image, caption="Code-barres généré", use_container_width=True)
271
+
272
+ qrcode_image = generate_qrcode(link)
273
+ st.image(qrcode_image, caption="QR Code généré", use_container_width=True)
274
+ else:
275
+ st.error("Veuillez entrer un lien valide pour générer les codes.")
276
+
 
277
  elif menu_option == "Détection Faciale":
278
  st.subheader("Détection Faciale")
279
 
 
280
  face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_frontalface_default.xml")
281
 
 
282
  detection_option = st.radio(
283
  "Choisis la source pour la détection faciale",
284
  options=["Webcam", "Vidéo téléversée"]
285
  )
286
 
287
  if detection_option == "Webcam":
 
288
  if st.button("Lancer la détection via webcam"):
289
+ cap = cv2.VideoCapture(0)
290
 
291
  if not cap.isOpened():
292
  st.error("Impossible d'accéder à la webcam, Hugging Face et le navigateur bloquent l'accès.")
 
300
  st.error("Erreur lors de la capture vidéo.")
301
  break
302
 
 
303
  gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
 
 
304
  faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
305
 
 
306
  for (x, y, w, h) in faces:
307
  cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2)
308
 
 
309
  frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
 
 
310
  frame_placeholder.image(frame, channels="RGB", use_container_width=True)
311
 
 
312
  cap.release()
313
 
314
  elif detection_option == "Vidéo téléversée":
 
315
  uploaded_video = st.file_uploader("Charge une vidéo", type=["mp4", "avi", "mov"])
316
  if uploaded_video is not None:
317
  video_bytes = uploaded_video.read()
 
327
  if not ret:
328
  break
329
 
 
330
  gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
 
 
331
  faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
332
 
 
333
  for (x, y, w, h) in faces:
334
  cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2)
335
 
 
336
  frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
 
 
337
  frame_placeholder.image(frame, channels="RGB", use_container_width=True)
338
 
339
  cap.release()
340
 
 
 
 
341
  if __name__ == "__main__":
342
  main()