Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -41,10 +41,6 @@ def generate_qrcode(link):
|
|
| 41 |
def add_custom_css():
|
| 42 |
css = """
|
| 43 |
<style>
|
| 44 |
-
stApp {
|
| 45 |
-
background: linear-gradient(to bottom, #87CEEB, #FFFFFF); /* Dégradé du bleu clair (#87CEEB) vers le blanc (#FFFFFF) */
|
| 46 |
-
}
|
| 47 |
-
|
| 48 |
body {
|
| 49 |
background: linear-gradient(135deg, #a8dadc, #f1faee);
|
| 50 |
color: #1d3557;
|
|
@@ -75,7 +71,7 @@ def add_custom_css():
|
|
| 75 |
}
|
| 76 |
|
| 77 |
.stSidebar {
|
| 78 |
-
background: linear-gradient(
|
| 79 |
color: white;
|
| 80 |
font-size: 16px;
|
| 81 |
}
|
|
@@ -197,13 +193,32 @@ def main():
|
|
| 197 |
unsafe_allow_html=True
|
| 198 |
)
|
| 199 |
|
|
|
|
| 200 |
elif menu_option == "Niveaux de couleurs":
|
| 201 |
st.subheader("Niveaux de couleurs")
|
| 202 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 203 |
tab1, tab2, tab3, tab4 = st.tabs([
|
| 204 |
"Gris 🖤", "Rouge ❤️", "Vert 💚", "Jaune 💛"
|
| 205 |
])
|
| 206 |
|
|
|
|
| 207 |
with tab1:
|
| 208 |
gray_image = cv2.cvtColor(image_np, cv2.COLOR_BGR2GRAY)
|
| 209 |
st.image(gray_image, caption="Image en Niveaux de Gris", use_container_width=True)
|
|
@@ -213,9 +228,11 @@ def main():
|
|
| 213 |
file_name="image_gris.png",
|
| 214 |
mime="image/png"
|
| 215 |
)
|
|
|
|
|
|
|
| 216 |
with tab2:
|
| 217 |
red = image_np.copy()
|
| 218 |
-
red[:, :, 1:] = 0
|
| 219 |
st.image(red, caption="Image Rouge", use_container_width=True)
|
| 220 |
st.download_button(
|
| 221 |
label="Télécharger l'image rouge",
|
|
@@ -223,9 +240,11 @@ def main():
|
|
| 223 |
file_name="image_rouge.png",
|
| 224 |
mime="image/png"
|
| 225 |
)
|
|
|
|
|
|
|
| 226 |
with tab3:
|
| 227 |
green = image_np.copy()
|
| 228 |
-
green[:, :, [0, 2]] = 0
|
| 229 |
st.image(green, caption="Image Verte", use_container_width=True)
|
| 230 |
st.download_button(
|
| 231 |
label="Télécharger l'image verte",
|
|
@@ -233,9 +252,11 @@ def main():
|
|
| 233 |
file_name="image_verte.png",
|
| 234 |
mime="image/png"
|
| 235 |
)
|
|
|
|
|
|
|
| 236 |
with tab4:
|
| 237 |
yellow = image_np.copy()
|
| 238 |
-
yellow[:, :, 0] = 0
|
| 239 |
st.image(yellow, caption="Image Jaune", use_container_width=True)
|
| 240 |
st.download_button(
|
| 241 |
label="Télécharger l'image jaune",
|
|
@@ -245,16 +266,26 @@ def main():
|
|
| 245 |
)
|
| 246 |
|
| 247 |
elif menu_option == "Cropping":
|
| 248 |
-
st.subheader("Cropping")
|
| 249 |
|
| 250 |
# Explications pour les paramètres
|
| 251 |
st.markdown(
|
| 252 |
"""
|
| 253 |
### Légende : Fonctionnement du recadrage
|
|
|
|
|
|
|
| 254 |
- **`x1` (Coordonnée x du coin supérieur gauche)** : Position horizontale du début du rectangle (0 ≤ `x1` < largeur-1).
|
| 255 |
- **`y1` (Coordonnée y du coin supérieur gauche)** : Position verticale du début du rectangle (0 ≤ `y1` < hauteur-1).
|
| 256 |
- **`x2` (Coordonnée x du coin inférieur droit)** : Position horizontale de la fin du rectangle (1 ≤ `x2` ≤ largeur).
|
| 257 |
- **`y2` (Coordonnée y du coin inférieur droit)** : Position verticale de la fin du rectangle (1 ≤ `y2` ≤ hauteur).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 258 |
"""
|
| 259 |
)
|
| 260 |
|
|
@@ -271,32 +302,62 @@ def main():
|
|
| 271 |
elif y1 >= y2:
|
| 272 |
st.error("`y2` doit être strictement supérieur à `y1`. Veuillez corriger vos entrées.")
|
| 273 |
else:
|
| 274 |
-
#
|
| 275 |
-
|
| 276 |
-
|
| 277 |
-
|
| 278 |
-
# Bouton
|
| 279 |
-
st.
|
| 280 |
-
|
| 281 |
-
|
| 282 |
-
|
| 283 |
-
|
| 284 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 285 |
|
| 286 |
except Exception as e:
|
| 287 |
st.error(f"Une erreur est survenue : {e}")
|
| 288 |
|
|
|
|
| 289 |
elif menu_option == "Rotation":
|
| 290 |
st.subheader("Rotation")
|
| 291 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 292 |
angle = st.selectbox("Angle de rotation", [45, 90, 180])
|
| 293 |
|
|
|
|
| 294 |
rows, cols, _ = image_np.shape
|
| 295 |
rotation_matrix = cv2.getRotationMatrix2D((cols / 2, rows / 2), angle, 1)
|
| 296 |
rotated = cv2.warpAffine(image_np, rotation_matrix, (cols, rows))
|
|
|
|
|
|
|
| 297 |
st.image(rotated, caption=f"Image Rotée de {angle} degrés", use_container_width=True)
|
| 298 |
-
|
| 299 |
-
# Bouton de téléchargement
|
| 300 |
st.download_button(
|
| 301 |
label="Télécharger l'image rotée",
|
| 302 |
data=image_to_bytes(rotated),
|
|
@@ -304,14 +365,34 @@ def main():
|
|
| 304 |
mime="image/png"
|
| 305 |
)
|
| 306 |
|
|
|
|
| 307 |
elif menu_option == "Floutage":
|
| 308 |
st.subheader("Floutage")
|
| 309 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 310 |
blur_level = st.slider("Niveau de flou (k)", min_value=1, max_value=51, step=2, value=15)
|
|
|
|
|
|
|
| 311 |
blurred = cv2.GaussianBlur(image_np, (blur_level, blur_level), 0)
|
|
|
|
|
|
|
| 312 |
st.image(blurred, caption=f"Image Floutée (k={blur_level})", use_container_width=True)
|
| 313 |
-
|
| 314 |
-
# Bouton de téléchargement
|
| 315 |
st.download_button(
|
| 316 |
label="Télécharger l'image floutée",
|
| 317 |
data=image_to_bytes(blurred),
|
|
@@ -319,13 +400,32 @@ def main():
|
|
| 319 |
mime="image/png"
|
| 320 |
)
|
| 321 |
|
|
|
|
| 322 |
elif menu_option == "Contours":
|
| 323 |
st.subheader("Contours")
|
| 324 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 325 |
gray = cv2.cvtColor(image_np, cv2.COLOR_BGR2GRAY)
|
| 326 |
edges = cv2.Canny(gray, 100, 200)
|
|
|
|
|
|
|
| 327 |
st.image(edges, caption="Contours de l'Image", use_container_width=True)
|
| 328 |
-
|
|
|
|
| 329 |
st.download_button(
|
| 330 |
label="Télécharger l'image avec contours",
|
| 331 |
data=image_to_bytes(edges),
|
|
|
|
| 41 |
def add_custom_css():
|
| 42 |
css = """
|
| 43 |
<style>
|
|
|
|
|
|
|
|
|
|
|
|
|
| 44 |
body {
|
| 45 |
background: linear-gradient(135deg, #a8dadc, #f1faee);
|
| 46 |
color: #1d3557;
|
|
|
|
| 71 |
}
|
| 72 |
|
| 73 |
.stSidebar {
|
| 74 |
+
background: linear-gradient(to bottom, #87CEEB, #FFFFFF);
|
| 75 |
color: white;
|
| 76 |
font-size: 16px;
|
| 77 |
}
|
|
|
|
| 193 |
unsafe_allow_html=True
|
| 194 |
)
|
| 195 |
|
| 196 |
+
# Niveaux de couleurs
|
| 197 |
elif menu_option == "Niveaux de couleurs":
|
| 198 |
st.subheader("Niveaux de couleurs")
|
| 199 |
|
| 200 |
+
# Instructions générales sur les niveaux de couleurs
|
| 201 |
+
st.markdown("""
|
| 202 |
+
### Légende : Fonctionnement des niveaux de couleurs
|
| 203 |
+
- **Les niveaux de couleurs** permettent de manipuler les différentes composantes d'une image : **Rouge**, **Vert**, **Bleu**.
|
| 204 |
+
- L'édition des canaux colorimétriques permet de visualiser une image en mettant en valeur une couleur spécifique.
|
| 205 |
+
|
| 206 |
+
### Options disponibles :
|
| 207 |
+
- **Niveaux de Gris** : Convertit l'image en une seule nuance de gris, supprimant les informations de couleur.
|
| 208 |
+
- **Rouge** : Filtre l'image pour ne conserver que la composante rouge.
|
| 209 |
+
- **Vert** : Filtre l'image pour ne conserver que la composante verte.
|
| 210 |
+
- **Jaune** : Combine les composantes rouge et verte pour donner une teinte jaune.
|
| 211 |
+
|
| 212 |
+
### Exemple :
|
| 213 |
+
- Si vous choisissez l'option **Rouge**, vous obtiendrez une image où seules les nuances rouges sont visibles, les autres couleurs étant supprimées.
|
| 214 |
+
""")
|
| 215 |
+
|
| 216 |
+
# Création des onglets pour afficher les images dans différentes couleurs
|
| 217 |
tab1, tab2, tab3, tab4 = st.tabs([
|
| 218 |
"Gris 🖤", "Rouge ❤️", "Vert 💚", "Jaune 💛"
|
| 219 |
])
|
| 220 |
|
| 221 |
+
# Onglet 1 : Gris
|
| 222 |
with tab1:
|
| 223 |
gray_image = cv2.cvtColor(image_np, cv2.COLOR_BGR2GRAY)
|
| 224 |
st.image(gray_image, caption="Image en Niveaux de Gris", use_container_width=True)
|
|
|
|
| 228 |
file_name="image_gris.png",
|
| 229 |
mime="image/png"
|
| 230 |
)
|
| 231 |
+
|
| 232 |
+
# Onglet 2 : Rouge
|
| 233 |
with tab2:
|
| 234 |
red = image_np.copy()
|
| 235 |
+
red[:, :, 1:] = 0 # On met les canaux vert et bleu à zéro
|
| 236 |
st.image(red, caption="Image Rouge", use_container_width=True)
|
| 237 |
st.download_button(
|
| 238 |
label="Télécharger l'image rouge",
|
|
|
|
| 240 |
file_name="image_rouge.png",
|
| 241 |
mime="image/png"
|
| 242 |
)
|
| 243 |
+
|
| 244 |
+
# Onglet 3 : Vert
|
| 245 |
with tab3:
|
| 246 |
green = image_np.copy()
|
| 247 |
+
green[:, :, [0, 2]] = 0 # On met les canaux rouge et bleu à zéro
|
| 248 |
st.image(green, caption="Image Verte", use_container_width=True)
|
| 249 |
st.download_button(
|
| 250 |
label="Télécharger l'image verte",
|
|
|
|
| 252 |
file_name="image_verte.png",
|
| 253 |
mime="image/png"
|
| 254 |
)
|
| 255 |
+
|
| 256 |
+
# Onglet 4 : Jaune
|
| 257 |
with tab4:
|
| 258 |
yellow = image_np.copy()
|
| 259 |
+
yellow[:, :, 0] = 0 # On supprime la composante bleue
|
| 260 |
st.image(yellow, caption="Image Jaune", use_container_width=True)
|
| 261 |
st.download_button(
|
| 262 |
label="Télécharger l'image jaune",
|
|
|
|
| 266 |
)
|
| 267 |
|
| 268 |
elif menu_option == "Cropping":
|
| 269 |
+
st.subheader("Cropping - Recadrage d'Image")
|
| 270 |
|
| 271 |
# Explications pour les paramètres
|
| 272 |
st.markdown(
|
| 273 |
"""
|
| 274 |
### Légende : Fonctionnement du recadrage
|
| 275 |
+
Le recadrage d'une image consiste à extraire une portion rectangulaire de celle-ci. Pour cela, nous définissons les coordonnées des coins du rectangle :
|
| 276 |
+
|
| 277 |
- **`x1` (Coordonnée x du coin supérieur gauche)** : Position horizontale du début du rectangle (0 ≤ `x1` < largeur-1).
|
| 278 |
- **`y1` (Coordonnée y du coin supérieur gauche)** : Position verticale du début du rectangle (0 ≤ `y1` < hauteur-1).
|
| 279 |
- **`x2` (Coordonnée x du coin inférieur droit)** : Position horizontale de la fin du rectangle (1 ≤ `x2` ≤ largeur).
|
| 280 |
- **`y2` (Coordonnée y du coin inférieur droit)** : Position verticale de la fin du rectangle (1 ≤ `y2` ≤ hauteur).
|
| 281 |
+
|
| 282 |
+
### Exemple illustratif :
|
| 283 |
+
Imaginons que vous avez une image de 300x300 pixels. Si vous entrez `x1=50`, `y1=50`, `x2=200`, et `y2=200`, l'image sera recadrée en un rectangle de taille 150x150 pixels, commençant à partir du pixel (50, 50) jusqu'à (200, 200).
|
| 284 |
+
|
| 285 |
+
### Étapes :
|
| 286 |
+
1. Saisissez les coordonnées du rectangle que vous souhaitez extraire.
|
| 287 |
+
2. Vous verrez une prévisualisation de la zone sélectionnée avant de la confirmer.
|
| 288 |
+
3. Téléchargez l'image recadrée.
|
| 289 |
"""
|
| 290 |
)
|
| 291 |
|
|
|
|
| 302 |
elif y1 >= y2:
|
| 303 |
st.error("`y2` doit être strictement supérieur à `y1`. Veuillez corriger vos entrées.")
|
| 304 |
else:
|
| 305 |
+
# Calcul des dimensions du recadrage
|
| 306 |
+
cropped_width = x2 - x1
|
| 307 |
+
cropped_height = y2 - y1
|
| 308 |
+
|
| 309 |
+
# Bouton pour générer l'image recadrée
|
| 310 |
+
if st.button("Générer le Recadrage"):
|
| 311 |
+
# Recadrage de l'image
|
| 312 |
+
cropped = image_np[int(y1):int(y2), int(x1):int(x2)]
|
| 313 |
+
|
| 314 |
+
# Affichage de l'image recadrée
|
| 315 |
+
st.image(cropped, caption="Image Croppée", use_container_width=True)
|
| 316 |
+
|
| 317 |
+
# Affichage des informations sur la taille du rectangle
|
| 318 |
+
st.write(f"Le rectangle recadré mesure {cropped_width} pixels de large et {cropped_height} pixels de haut.")
|
| 319 |
+
|
| 320 |
+
# Bouton de téléchargement pour l'image recadrée
|
| 321 |
+
st.download_button(
|
| 322 |
+
label="⬇️ Télécharger l'image croppée",
|
| 323 |
+
data=image_to_bytes(cropped),
|
| 324 |
+
file_name="image_cropped.png",
|
| 325 |
+
mime="image/png"
|
| 326 |
+
)
|
| 327 |
|
| 328 |
except Exception as e:
|
| 329 |
st.error(f"Une erreur est survenue : {e}")
|
| 330 |
|
| 331 |
+
# Rotation
|
| 332 |
elif menu_option == "Rotation":
|
| 333 |
st.subheader("Rotation")
|
| 334 |
|
| 335 |
+
# Instructions sur la rotation
|
| 336 |
+
st.markdown("""
|
| 337 |
+
### Légende : Fonctionnement de la rotation
|
| 338 |
+
- La **rotation** d'une image consiste à tourner l'image autour de son centre selon un angle défini.
|
| 339 |
+
- Vous pouvez choisir un angle prédéfini pour faire pivoter l'image à gauche ou à droite.
|
| 340 |
+
|
| 341 |
+
### Options disponibles :
|
| 342 |
+
- Choisissez un angle parmi les options proposées : **45°, 90° ou 180°**.
|
| 343 |
+
- L'image sera ensuite tournée dans le sens des aiguilles d'une montre.
|
| 344 |
+
|
| 345 |
+
### Exemple :
|
| 346 |
+
- Si vous choisissez un angle de **90°**, l'image sera pivotée de 90 degrés dans le sens des aiguilles d'une montre par rapport à son centre.
|
| 347 |
+
""")
|
| 348 |
+
|
| 349 |
+
# Sélection de l'angle de rotation
|
| 350 |
angle = st.selectbox("Angle de rotation", [45, 90, 180])
|
| 351 |
|
| 352 |
+
# Calcul des dimensions et application de la rotation
|
| 353 |
rows, cols, _ = image_np.shape
|
| 354 |
rotation_matrix = cv2.getRotationMatrix2D((cols / 2, rows / 2), angle, 1)
|
| 355 |
rotated = cv2.warpAffine(image_np, rotation_matrix, (cols, rows))
|
| 356 |
+
|
| 357 |
+
# Affichage de l'image après rotation
|
| 358 |
st.image(rotated, caption=f"Image Rotée de {angle} degrés", use_container_width=True)
|
| 359 |
+
|
| 360 |
+
# Bouton de téléchargement pour l'image rotée
|
| 361 |
st.download_button(
|
| 362 |
label="Télécharger l'image rotée",
|
| 363 |
data=image_to_bytes(rotated),
|
|
|
|
| 365 |
mime="image/png"
|
| 366 |
)
|
| 367 |
|
| 368 |
+
# Floutage
|
| 369 |
elif menu_option == "Floutage":
|
| 370 |
st.subheader("Floutage")
|
| 371 |
|
| 372 |
+
# Instructions sur le floutage
|
| 373 |
+
st.markdown("""
|
| 374 |
+
### Légende : Fonctionnement du floutage
|
| 375 |
+
- Le **floutage** est utilisé pour adoucir une image en réduisant les détails fins, ce qui est utile pour l'anonymisation ou pour appliquer des effets esthétiques.
|
| 376 |
+
- Vous pouvez ajuster l'intensité du flou en fonction du niveau choisi.
|
| 377 |
+
|
| 378 |
+
### Options disponibles :
|
| 379 |
+
- Le **Niveau de flou (k)** détermine l'intensité du flou appliqué. Plus la valeur est élevée, plus l'image sera floutée.
|
| 380 |
+
- Les valeurs sont comprises entre 1 (très léger flou) et 51 (flou maximal), et doivent être des nombres impairs.
|
| 381 |
+
|
| 382 |
+
### Exemple :
|
| 383 |
+
- Si vous choisissez **k = 15**, l'image sera floutée de manière modérée, et vous pourrez voir l'effet de réduction de détails.
|
| 384 |
+
""")
|
| 385 |
+
|
| 386 |
+
# Sélection du niveau de flou
|
| 387 |
blur_level = st.slider("Niveau de flou (k)", min_value=1, max_value=51, step=2, value=15)
|
| 388 |
+
|
| 389 |
+
# Application du flou sur l'image
|
| 390 |
blurred = cv2.GaussianBlur(image_np, (blur_level, blur_level), 0)
|
| 391 |
+
|
| 392 |
+
# Affichage de l'image floutée
|
| 393 |
st.image(blurred, caption=f"Image Floutée (k={blur_level})", use_container_width=True)
|
| 394 |
+
|
| 395 |
+
# Bouton de téléchargement pour l'image floutée
|
| 396 |
st.download_button(
|
| 397 |
label="Télécharger l'image floutée",
|
| 398 |
data=image_to_bytes(blurred),
|
|
|
|
| 400 |
mime="image/png"
|
| 401 |
)
|
| 402 |
|
| 403 |
+
# Détection des contours
|
| 404 |
elif menu_option == "Contours":
|
| 405 |
st.subheader("Contours")
|
| 406 |
|
| 407 |
+
# Instructions sur la détection des contours
|
| 408 |
+
st.markdown("""
|
| 409 |
+
### Légende : Fonctionnement de la détection de contours
|
| 410 |
+
- La **détection de contours** consiste à identifier les bords distincts de l'image, ce qui permet de mieux comprendre les structures présentes.
|
| 411 |
+
- Elle est souvent utilisée dans des traitements d'image avancés comme la reconnaissance d'objets ou l'analyse d'images.
|
| 412 |
+
|
| 413 |
+
### Options disponibles :
|
| 414 |
+
- L'image sera convertie en niveaux de gris, et ensuite un algorithme de détection de contours (Canny) sera appliqué pour extraire les bords de l'image.
|
| 415 |
+
- Cela permet de visualiser les contours dans des images complexes.
|
| 416 |
+
|
| 417 |
+
### Exemple :
|
| 418 |
+
- Après l'application de l'algorithme Canny, l'image ne contient que les contours des objets, ce qui peut être utilisé pour détecter des formes, des objets ou d'autres détails visuels importants.
|
| 419 |
+
""")
|
| 420 |
+
|
| 421 |
+
# Conversion de l'image en niveaux de gris pour la détection des contours
|
| 422 |
gray = cv2.cvtColor(image_np, cv2.COLOR_BGR2GRAY)
|
| 423 |
edges = cv2.Canny(gray, 100, 200)
|
| 424 |
+
|
| 425 |
+
# Affichage de l'image avec les contours détectés
|
| 426 |
st.image(edges, caption="Contours de l'Image", use_container_width=True)
|
| 427 |
+
|
| 428 |
+
# Bouton de téléchargement pour l'image avec contours
|
| 429 |
st.download_button(
|
| 430 |
label="Télécharger l'image avec contours",
|
| 431 |
data=image_to_bytes(edges),
|