Travaux Pratiques
Filtrage Spatial en Traitement d’Images
Année 2025-2026
Objectifs du TP
À la fin de ce TP, vous serez capable de :
— Implémenter et comparer différents filtres de lissage
— Détecter les contours avec plusieurs opérateurs
— Choisir le bon filtre selon le type de bruit
— Rehausser la netteté d’une image
— Évaluer quantitativement les résultats
Table des matières
1 Préparation de l’environnement 3
1.1 Installation des bibliothèques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2 Imports nécessaires . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.3 Fonctions utilitaires . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2 Partie 1 : Filtres de lissage 4
2.1 Exercice 1.1 : Filtre moyenneur . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.2 Exercice 1.2 : Filtre gaussien . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.3 Exercice 1.3 : Étude de la séparabilité . . . . . . . . . . . . . . . . . . . . . . . . 5
3 Partie 2 : Gestion des bordures 7
3.1 Exercice 2.1 : Comparaison des stratégies . . . . . . . . . . . . . . . . . . . . . . 7
4 Partie 3 : Détection de contours 8
4.1 Exercice 3.1 : Opérateurs de gradient . . . . . . . . . . . . . . . . . . . . . . . . . 8
4.2 Exercice 3.2 : Laplacien et LoG . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
5 Partie 4 : Filtres non-linéaires 11
5.1 Exercice 4.1 : Filtre médian vs Gaussien . . . . . . . . . . . . . . . . . . . . . . . 11
5.2 Exercice 4.2 : Filtres d’ordre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
6 Partie 5 : Rehaussement de netteté 14
6.1 Exercice 5.1 : Unsharp masking . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
6.2 Exercice 5.2 : Filtres de rehaussement directs . . . . . . . . . . . . . . . . . . . . 16
1
TP Filtrage Spatial Traitement d’Images
7 Partie 6 : Projet intégrateur 17
7.1 Exercice 6.1 : Pipeline complet de traitement . . . . . . . . . . . . . . . . . . . . 17
7.2 Exercice 6.2 : Évaluation quantitative comparative . . . . . . . . . . . . . . . . . 19
7.3 Exercice 6.3 : Application pratique - Amélioration OCR . . . . . . . . . . . . . . 21
8 Partie 7 : Questions de réflexion 22
8.1 Analyse théorique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
8.2 Cas pratiques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2
TP Filtrage Spatial Traitement d’Images
1 Préparation de l’environnement
1.1 Installation des bibliothèques
Assurez-vous d’avoir les bibliothèques suivantes installées :
1 # Installation avec pip
2 pip install opencv - python numpy matplotlib scikit - image
1.2 Imports nécessaires
Créez un nouveau fichier Python et ajoutez les imports suivants :
1 import cv2
2 import numpy as np
3 import matplotlib . pyplot as plt
4 from skimage . metrics import p e a k _ s i g n a l _ n o i s e _ r a t i o as psnr
5 from skimage . metrics import s t r u c t u r a l _ s i m i l a r i t y as ssim
6
7 # Configuration pour l ’ affichage
8 plt . rcParams [ ’ figure . figsize ’] = (12 , 8)
1.3 Fonctions utilitaires
Implémentez les fonctions d’affichage suivantes :
1 def afficher_images ( images , titres , cmap = ’ gray ’) :
2 " " " Affiche plusieurs images cote a cote " " "
3 n = len ( images )
4 fig , axes = plt . subplots (1 , n , figsize =(5* n , 5) )
5 if n == 1:
6 axes = [ axes ]
7 for i , ( img , titre ) in enumerate ( zip ( images , titres ) ) :
8 axes [ i ]. imshow ( img , cmap = cmap )
9 axes [ i ]. set_title ( titre )
10 axes [ i ]. axis ( ’ off ’)
11 plt . tight_layout ()
12 plt . show ()
13
14 def a j o u t e r _ b r u i t _ g a u s s i e n ( image , sigma =25) :
15 " " " Ajoute du bruit gaussien a une image " " "
16 bruit = np . random . normal (0 , sigma , image . shape )
17 image_bruitee = np . clip ( image + bruit , 0 , 255)
18 return image_bruitee . astype ( np . uint8 )
19
20 def a j o u t e r _ b r u i t _ p o i v r e _ s e l ( image , prob =0.05) :
21 " " " Ajoute du bruit poivre et sel " " "
22 image_bruitee = image . copy ()
23 # Poivre ( noir )
24 poivre = np . random . rand (* image . shape ) < prob /2
25 image_bruitee [ poivre ] = 0
26 # Sel ( blanc )
27 sel = np . random . rand (* image . shape ) < prob /2
28 image_bruitee [ sel ] = 255
29 return image_bruitee
3
TP Filtrage Spatial Traitement d’Images
2 Partie 1 : Filtres de lissage
2.1 Exercice 1.1 : Filtre moyenneur
Question
Implémentez un filtre moyenneur from scratch (sans utiliser les fonctions OpenCV de
filtrage).
Code à compléter :
1 def filtre_moyenneur ( image , taille =3) :
2 """
3 Applique un filtre moyenneur sur une image
4
5 Args :
6 image : image en niveaux de gris
7 taille : taille du noyau ( impaire )
8
9 Returns :
10 image_filtree : image apres filtrage
11 """
12 h , w = image . shape
13 pad = taille // 2
14
15 # TODO : Ajouter du padding a l ’ image ( utilisez np . pad )
16 image_padded = # VOTRE CODE ICI
17
18 # Initialiser l ’ image de sortie
19 image_filtree = np . zeros_like ( image , dtype = np . float32 )
20
21 # TODO : Parcourir chaque pixel et calculer la moyenne
22 for i in range ( h ) :
23 for j in range ( w ) :
24 # Extraire la fenetre
25 fenetre = # VOTRE CODE ICI
26 # Calculer la moyenne
27 image_filtree [i , j ] = # VOTRE CODE ICI
28
29 return image_filtree . astype ( np . uint8 )
30
31 # Test
32 img = cv2 . imread ( ’ image . jpg ’ , cv2 . IMREAD_GRAYSCALE )
33 img_bruitee = a j o u t e r _ b r u i t _ g a u s s i e n ( img , sigma =20)
34 img_filtree = filtre_moyenneur ( img_bruitee , taille =5)
35
36 afficher_images ([ img , img_bruitee , img_filtree ] ,
37 [ ’ Original ’ , ’ Bruitee ’ , ’ Filtree ’ ])
Question
1. Quel est l’effet du filtre moyenneur sur le bruit ?
2. Que se passe-t-il avec les contours ?
3. Comparez les résultats pour des tailles 3×3, 5×5 et 7×7.
4
TP Filtrage Spatial Traitement d’Images
2.2 Exercice 1.2 : Filtre gaussien
Implémentez et comparez le filtre gaussien avec le moyenneur :
1 # Utilisation du filtre gaussien OpenCV
2 def c o m p a r e r _ f i l t r e s _ l i s s a g e ( image , sigma_bruit =20) :
3 " " " Compare moyenneur et gaussien " " "
4
5 # Ajouter du bruit
6 img_bruitee = a j o u t e r _ b r u i t _ g a u s s i e n ( image , sigma_bruit )
7
8 # Filtre moyenneur
9 img_moyenne = cv2 . blur ( img_bruitee , (5 , 5) )
10
11 # Filtre gaussien
12 img_gaussien = cv2 . GaussianBlur ( img_bruitee , (5 , 5) ,
13 sigmaX =1.5)
14
15 # Calculer les metriques
16 psnr_moyenne = psnr ( image , img_moyenne )
17 psnr_gaussien = psnr ( image , img_gaussien )
18
19 print ( f " PSNR Moyenneur : { psnr_moyenne :.2 f } dB " )
20 print ( f " PSNR Gaussien : { psnr_gaussien :.2 f } dB " )
21
22 # Affichage
23 afficher_images ([ img_bruitee , img_moyenne , img_gaussien ] ,
24 [ ’ Bruitee ’ ,
25 f ’ Moyenneur ( PSNR ={ psnr_moyenne :.1 f }) ’ ,
26 f ’ Gaussien ( PSNR ={ psnr_gaussien :.1 f }) ’ ])
27
28 # Test
29 img = cv2 . imread ( ’ image . jpg ’ , cv2 . IMREAD_GRAYSCALE )
30 c o m p a r e r _ f i l t r e s _ l i s s a g e ( img )
Question
1. Quel filtre donne le meilleur PSNR ?
2. Visuellement, lequel préserve mieux les contours ?
3. Testez différentes valeurs de σ (0.5, 1.0, 2.0, 3.0). Qu’observez-vous ?
2.3 Exercice 1.3 : Étude de la séparabilité
Question
Mesurez le gain de temps obtenu avec un filtre séparable.
1 import time
2
3 def m e s u r e r _ p e r f o r m a n c e _ s e p a r a b i l i t e ( image , taille =11) :
4 " " " Mesure le gain de la separabilite " " "
5
6 # Methode 1: Filtre 2 D classique
7 kernel_2d = np . ones (( taille , taille ) ) / ( taille **2)
8
9 debut = time . time ()
5
TP Filtrage Spatial Traitement d’Images
10 for _ in range (10) : # 10 iterations
11 result_2d = cv2 . filter2D ( image , -1 , kernel_2d )
12 temps_2d = time . time () - debut
13
14 # Methode 2: Filtre separable
15 kernel_1d = np . ones ( taille ) / taille
16
17 debut = time . time ()
18 for _ in range (10) :
19 result_sep = cv2 . sepFilter2D ( image , -1 ,
20 kernel_1d , kernel_1d )
21 temps_sep = time . time () - debut
22
23 print ( f " Temps 2 D : { temps_2d :.3 f } s " )
24 print ( f " Temps separable : { temps_sep :.3 f } s " )
25 print ( f " Gain : { temps_2d / temps_sep :.2 f } x " )
26
27 return result_2d , result_sep
28
29 # Test
30 img = cv2 . imread ( ’ image . jpg ’ , cv2 . IMREAD_GRAYSCALE )
31 r1 , r2 = m e s u r e r _ p e r f o r m a n c e _ s e p a r a b i l i t e ( img )
6
TP Filtrage Spatial Traitement d’Images
3 Partie 2 : Gestion des bordures
3.1 Exercice 2.1 : Comparaison des stratégies
Question
Implémentez et comparez les différentes stratégies de gestion des bordures.
1 def c o m p a r e r _ s t r a t e g i e s _ b o r d u r e s ( image ) :
2 " " " Compare les differentes strategies de padding " " "
3
4 # Creer une petite image test
5 img_test = image [:100 , :100]
6
7 # Appliquer un filtre gaussien avec differentes strategies
8 strategies = {
9 ’ BORDER_CONSTANT ’: cv2 . BORDER_CONSTANT ,
10 ’ BORDER_REPLICATE ’: cv2 . BORDER_REPLICATE ,
11 ’ BORDER_REFLECT ’: cv2 . BORDER_REFLECT ,
12 ’ BORDER_WRAP ’: cv2 . BORDER_WRAP ,
13 }
14
15 resultats = []
16 titres = []
17
18 for nom , strategie in strategies . items () :
19 # Appliquer le filtre
20 filtered = cv2 . GaussianBlur ( img_test , (15 , 15) ,
21 sigmaX =3 ,
22 borderType = strategie )
23 resultats . append ( filtered )
24 titres . append ( nom . replace ( ’ BORDER_ ’ , ’ ’) )
25
26 # Afficher les resultats
27 afficher_images ([ img_test ] + resultats ,
28 [ ’ Original ’] + titres )
29
30 # Zoom sur les coins pour voir les differences
31 coins = []
32 for img in [ img_test ] + resultats :
33 coin = img [:20 , :20] # Coin superieur gauche
34 coins . append ( coin )
35
36 afficher_images ( coins , [ ’ Original ’] + titres )
37
38 # Test
39 img = cv2 . imread ( ’ image . jpg ’ , cv2 . IMREAD_GRAYSCALE )
40 c o m p a r e r _ s t r a t e g i e s _ b o r d u r e s ( img )
Question
1. Quelle stratégie crée des artefacts visibles aux bords ?
2. Laquelle recommanderiez-vous et pourquoi ?
3. Dans quel cas utiliseriez-vous WRAP ?
7
TP Filtrage Spatial Traitement d’Images
4 Partie 3 : Détection de contours
4.1 Exercice 3.1 : Opérateurs de gradient
Question
Implémentez et comparez les opérateurs Roberts, Prewitt et Sobel.
1 def d e t e c t e r _ c o n t o u r s _ c o m p a r a i s o n ( image ) :
2 " " " Compare Roberts , Prewitt et Sobel " " "
3
4 # Pre - lissage
5 img_smooth = cv2 . GaussianBlur ( image , (3 , 3) , 0)
6
7 # Roberts ( approximation avec Sobel 1 x1 )
8 roberts_x = cv2 . Sobel ( img_smooth , cv2 . CV_64F , 1 , 0 , ksize =1)
9 roberts_y = cv2 . Sobel ( img_smooth , cv2 . CV_64F , 0 , 1 , ksize =1)
10 roberts = np . sqrt ( roberts_x **2 + roberts_y **2)
11
12 # Prewitt ( pas directement disponible , utiliser un noyau )
13 kernel_prewitt_x = np . array ([[ -1 , 0 , 1] ,
14 [ -1 , 0 , 1] ,
15 [ -1 , 0 , 1]])
16 kernel_prewitt_y = np . array ([[ -1 , -1 , -1] ,
17 [ 0 , 0 , 0] ,
18 [ 1 , 1 , 1]])
19 prewitt_x = cv2 . filter2D ( img_smooth , cv2 . CV_64F ,
20 kernel_prewitt_x )
21 prewitt_y = cv2 . filter2D ( img_smooth , cv2 . CV_64F ,
22 kernel_prewitt_y )
23 prewitt = np . sqrt ( prewitt_x **2 + prewitt_y **2)
24
25 # Sobel
26 sobel_x = cv2 . Sobel ( img_smooth , cv2 . CV_64F , 1 , 0 , ksize =3)
27 sobel_y = cv2 . Sobel ( img_smooth , cv2 . CV_64F , 0 , 1 , ksize =3)
28 sobel = np . sqrt ( sobel_x **2 + sobel_y **2)
29
30 # Normalisation
31 roberts = np . uint8 (255 * roberts / np . max ( roberts ) )
32 prewitt = np . uint8 (255 * prewitt / np . max ( prewitt ) )
33 sobel = np . uint8 (255 * sobel / np . max ( sobel ) )
34
35 afficher_images ([ image , roberts , prewitt , sobel ] ,
36 [ ’ Original ’ , ’ Roberts ’ , ’ Prewitt ’ , ’ Sobel ’ ])
37
38 return roberts , prewitt , sobel
39
40 # Test
41 img = cv2 . imread ( ’ image . jpg ’ , cv2 . IMREAD_GRAYSCALE )
42 roberts , prewitt , sobel = d e t e c t e r _ c o n t o u r s _ c o m p a r a i s o n ( img )
8
TP Filtrage Spatial Traitement d’Images
Question
1. Quel opérateur détecte les contours les plus nets ?
2. Lequel est le plus sensible au bruit ?
3. Testez sur une image bruitée. Que se passe-t-il ?
9
TP Filtrage Spatial Traitement d’Images
4.2 Exercice 3.2 : Laplacien et LoG
1 def c o m p a r e r _ l a p l a c i e n _ l o g ( image ) :
2 " " " Compare Laplacien simple et LoG " " "
3
4 # Laplacien simple
5 laplacien = cv2 . Laplacian ( image , cv2 . CV_64F )
6 laplacien = np . uint8 ( np . abs ( laplacien ) )
7
8 # Laplacien de Gaussien
9 # Methode 1: Gaussien puis Laplacien
10 img_gauss = cv2 . GaussianBlur ( image , (5 , 5) , 1.4)
11 log_method1 = cv2 . Laplacian ( img_gauss , cv2 . CV_64F )
12 log_method1 = np . uint8 ( np . abs ( log_method1 ) )
13
14 # Methode 2: LoG direct ( approximation avec DoG )
15 gauss1 = cv2 . GaussianBlur ( image , (5 , 5) , 1.0)
16 gauss2 = cv2 . GaussianBlur ( image , (5 , 5) , 1.6)
17 log_method2 = cv2 . subtract ( gauss2 , gauss1 )
18 log_method2 = np . uint8 ( np . abs ( log_method2 ) )
19
20 # Image bruitee
21 img_bruitee = a j o u t e r _ b r u i t _ g a u s s i e n ( image , 20)
22 laplacien_bruit = cv2 . Laplacian ( img_bruitee , cv2 . CV_64F )
23 laplacien_bruit = np . uint8 ( np . abs ( laplacien_bruit ) )
24
25 log_bruit = cv2 . Laplacian (
26 cv2 . GaussianBlur ( img_bruitee , (5 , 5) , 1.4) ,
27 cv2 . CV_64F
28 )
29 log_bruit = np . uint8 ( np . abs ( log_bruit ) )
30
31 afficher_images ([ image , laplacien , log_method1 , log_method2 ] ,
32 [ ’ Original ’ , ’ Laplacien ’ ,
33 ’ LoG ( methode 1) ’ , ’ LoG ( DoG ) ’ ])
34
35 afficher_images ([ img_bruitee , laplacien_bruit , log_bruit ] ,
36 [ ’ Image bruitee ’ ,
37 ’ Laplacien sur bruit ’ ,
38 ’ LoG sur bruit ’ ])
39
40 # Test
41 img = cv2 . imread ( ’ image . jpg ’ , cv2 . IMREAD_GRAYSCALE )
42 c o m p a r e r _ l a p l a c i e n _ l o g ( img )
Question
1. Pourquoi le LoG est-il plus robuste au bruit ?
2. Testez différentes valeurs de σ (0.5, 1.0, 2.0). Qu’observez-vous ?
3. Implémentez la détection par passages par zéro.
10
TP Filtrage Spatial Traitement d’Images
5 Partie 4 : Filtres non-linéaires
5.1 Exercice 4.1 : Filtre médian vs Gaussien
Question
Comparez l’efficacité du filtre médian et gaussien sur différents types de bruit.
1 def c o m p a r e r _ f i l t r e s _ b r u i t ( image ) :
2 " " " Compare median et gaussien sur differents bruits " " "
3
4 # Bruit gaussien
5 img_gauss_noise = a j o u t e r _ b r u i t _ g a u s s i e n ( image , sigma =25)
6 gauss_sur_gauss = cv2 . GaussianBlur ( img_gauss_noise , (5 , 5) , 1)
7 median_sur_gauss = cv2 . medianBlur ( img_gauss_noise , 5)
8
9 # Bruit poivre et sel
10 img_sp_noise = a j o u t e r _ b r u i t _ p o i v r e _ s e l ( image , prob =0.1)
11 gauss_sur_sp = cv2 . GaussianBlur ( img_sp_noise , (5 , 5) , 1)
12 median_sur_sp = cv2 . medianBlur ( img_sp_noise , 5)
13
14 # Metriques pour bruit gaussien
15 psnr_gauss_gauss = psnr ( image , gauss_sur_gauss )
16 ps nr_med ian_ga uss = psnr ( image , median_sur_gauss )
17
18 # Metriques pour bruit poivre et sel
19 psnr_gauss_sp = psnr ( image , gauss_sur_sp )
20 psnr_median_sp = psnr ( image , median_sur_sp )
21
22 print ( " === BRUIT GAUSSIEN === " )
23 print ( f " Gaussien : { psnr_gauss_gauss :.2 f } dB " )
24 print ( f " Median : { ps nr_med ian_ga uss :.2 f } dB " )
25 print ( f " Meilleur : { ’ Gaussien ’ if psnr_gauss_gauss >
psn r_medi an_gau ss else ’ Median ’} " )
26
27 print ( " \ n === BRUIT POIVRE ET SEL === " )
28 print ( f " Gaussien : { psnr_gauss_sp :.2 f } dB " )
29 print ( f " Median : { psnr_median_sp :.2 f } dB " )
30 print ( f " Meilleur : { ’ Gaussien ’ if psnr_gauss_sp > psnr_median_sp
else ’ Median ’} " )
31
32 # Affichage
33 afficher_images (
34 [ img_gauss_noise , gauss_sur_gauss , median_sur_gauss ] ,
35 [ ’ Bruit Gaussien ’ ,
36 f ’ Gaussien ({ psnr_gauss_gauss :.1 f } dB ) ’ ,
37 f ’ Median ({ ps nr_med ian_ga uss :.1 f } dB ) ’]
38 )
39
40 afficher_images (
41 [ img_sp_noise , gauss_sur_sp , median_sur_sp ] ,
42 [ ’ Bruit Poivre / Sel ’ ,
43 f ’ Gaussien ({ psnr_gauss_sp :.1 f } dB ) ’ ,
44 f ’ Median ({ psnr_median_sp :.1 f } dB ) ’]
45 )
46
47 # Test
48 img = cv2 . imread ( ’ image . jpg ’ , cv2 . IMREAD_GRAYSCALE )
11
TP Filtrage Spatial Traitement d’Images
49 c o m p a r e r _ f i l t r e s _ b r u i t ( img )
Question
1. Quel filtre est le plus efficace pour le bruit gaussien ? Pourquoi ?
2. Quel filtre est le plus efficace pour le bruit impulsionnel ? Pourquoi ?
3. Proposez une stratégie pour un bruit mixte.
12
TP Filtrage Spatial Traitement d’Images
5.2 Exercice 4.2 : Filtres d’ordre
1 def t e s t e r _ f i l t r e s _ o r d r e ( image ) :
2 " " " Teste les filtres min , max et median " " "
3
4 # Ajouter du bruit
5 img_sel = a j o u t e r _ b r u i t _ p o i v r e _ s e l ( image , prob =0.05)
6
7 # Filtre min ( erosion morphologique )
8 kernel = np . ones ((5 , 5) , np . uint8 )
9 img_min = cv2 . erode ( img_sel , kernel )
10
11 # Filtre max ( dilatation morphologique )
12 img_max = cv2 . dilate ( img_sel , kernel )
13
14 # Filtre median
15 img_median = cv2 . medianBlur ( img_sel , 5)
16
17 afficher_images ([ img_sel , img_min , img_max , img_median ] ,
18 [ ’ Bruitee ’ , ’ Min ’ , ’ Max ’ , ’ Median ’ ])
19
20 return img_min , img_max , img_median
21
22 # Test
23 img = cv2 . imread ( ’ image . jpg ’ , cv2 . IMREAD_GRAYSCALE )
24 t e s t e r _ f i l t r e s _ o r d r e ( img )
Question
1. Quel est l’effet du filtre min sur le bruit ”sel” (blanc) ?
2. Quel est l’effet du filtre max sur le bruit ”poivre” (noir) ?
3. Pourquoi le médian est-il efficace sur les deux types ?
13
TP Filtrage Spatial Traitement d’Images
6 Partie 5 : Rehaussement de netteté
6.1 Exercice 5.1 : Unsharp masking
Question
Implémentez la technique d’unsharp masking et testez différents paramètres.
1 def unsharp_masking ( image , sigma =1.0 , k =1.5) :
2 """
3 Applique l ’ unsharp masking
4
5 Args :
6 image : image d ’ entree
7 sigma : parametre du gaussien
8 k : intensite du rehaussement
9 """
10 # Lissage
11 img_smooth = cv2 . GaussianBlur ( image , (0 , 0) , sigma )
12
13 # Extraction des details
14 details = cv2 . subtract ( image , img_smooth )
15
16 # Ajout des details amplifies
17 img_sharp = cv2 . addWeighted ( image , 1.0 , details , k , 0)
18
19 # Clipping
20 img_sharp = np . clip ( img_sharp , 0 , 255) . astype ( np . uint8 )
21
22 return img_sharp , img_smooth , details
23
24 def tester_unsharp ( image ) :
25 " " " Teste differents parametres d ’ unsharp masking " " "
26
27 # Creer une image legerement floue
28 img_floue = cv2 . GaussianBlur ( image , (5 , 5) , 2)
29
30 # Tester differentes valeurs de k
31 valeurs_k = [0.5 , 1.0 , 1.5 , 2.0]
32 resultats = [ img_floue ]
33 titres = [ ’ Image floue ’]
34
35 for k in valeurs_k :
36 img_sharp , _ , _ = unsharp_masking ( img_floue , sigma =1.0 , k = k )
37 resultats . append ( img_sharp )
38 titres . append ( f ’k = { k } ’)
39
40 # Affichage
41 afficher_images ( resultats , titres )
42
43 # Montrer les composantes
44 img_sharp , smooth , details = unsharp_masking ( img_floue , 1.0 , 1.5)
45 # Normaliser les details pour visualisation
46 details_vis = np . uint8 (128 + details /2)
47
48 afficher_images ([ img_floue , smooth , details_vis , img_sharp ] ,
49 [ ’ Floue ’ , ’ Lissee ’ , ’ Details ’ , ’ Rehaussee ’ ])
50
14
TP Filtrage Spatial Traitement d’Images
51 # Test
52 img = cv2 . imread ( ’ image . jpg ’ , cv2 . IMREAD_GRAYSCALE )
53 tester_unsharp ( img )
Question
1. Que contient l’image des détails ?
2. Quel est l’effet d’augmenter k ?
3. À partir de quelle valeur de k observe-t-on des artefacts ?
4. Testez sur une image bruitée. Que se passe-t-il ?
15
TP Filtrage Spatial Traitement d’Images
6.2 Exercice 5.2 : Filtres de rehaussement directs
1 def c o m p a r e r _ r e h a u s s e m e n t s ( image ) :
2 " " " Compare differentes methodes de rehaussement " " "
3
4 # Unsharp masking
5 unsharp , _ , _ = unsharp_masking ( image , sigma =1.0 , k =1.5)
6
7 # Laplacien 4 - voisins
8 kernel_lap4 = np . array ([[0 , -1 , 0] ,
9 [ -1 , 5 , -1] ,
10 [0 , -1 , 0]])
11 lap4 = cv2 . filter2D ( image , -1 , kernel_lap4 )
12
13 # Laplacien 8 - voisins
14 kernel_lap8 = np . array ([[ -1 , -1 , -1] ,
15 [ -1 , 9 , -1] ,
16 [ -1 , -1 , -1]])
17 lap8 = cv2 . filter2D ( image , -1 , kernel_lap8 )
18
19 # High - boost ( A =1.5)
20 img_smooth = cv2 . GaussianBlur ( image , (5 , 5) , 1)
21 high_boost = cv2 . addWeighted ( image , 1.5 , img_smooth , -0.5 , 0)
22 high_boost = np . clip ( high_boost , 0 , 255) . astype ( np . uint8 )
23
24 afficher_images ([ image , unsharp , lap4 , lap8 , high_boost ] ,
25 [ ’ Original ’ , ’ Unsharp ’ , ’ Lap4 ’ , ’ Lap8 ’ , ’ High -
boost ’ ])
26
27 # Test
28 img = cv2 . imread ( ’ image . jpg ’ , cv2 . IMREAD_GRAYSCALE )
29 c o m p a r e r _ r e h a u s s e m e n t s ( img )
Question
1. Quelle méthode donne les résultats les plus naturels ?
2. Quelle méthode amplifie le plus le bruit ?
3. Dans quel cas utiliseriez-vous chaque méthode ?
16
TP Filtrage Spatial Traitement d’Images
7 Partie 6 : Projet intégrateur
7.1 Exercice 6.1 : Pipeline complet de traitement
Question
Créez un pipeline complet pour améliorer une image dégradée.
1 def p i p e l i n e _ a m e l i o r a t i o n _ c o m p l e t e ( image_path ) :
2 """
3 Pipeline complet d ’ amelioration d ’ image
4
5 Etapes :
6 1. Analyse du bruit
7 2. Debruitage adaptatif
8 3. Rehaussement de nettete
9 4. Detection de contours
10 """
11
12 # Charger l ’ image
13 img = cv2 . imread ( image_path , cv2 . IMREAD_GRAYSCALE )
14
15 # Ajouter du bruit mixte pour simulation
16 img_degradee = a j o u t e r _ b r u i t _ g a u s s i e n ( img , sigma =15)
17 img_degradee = a j o u t e r _ b r u i t _ p o i v r e _ s e l ( img_degradee , prob =0.02)
18
19 print ( " = " *50)
20 print ( " PIPELINE DE TRAITEMENT D ’ IMAGE " )
21 print ( " = " *50)
22
23 # Etape 1: Analyse
24 print ( " \ n [ Etape 1] Analyse de l ’ image ... " )
25 hist = cv2 . calcHist ([ img_degradee ] , [0] , None , [256] , [0 , 256])
26 print ( f " - Intensite moyenne : { np . mean ( img_degradee ) :.1 f } " )
27 print ( f " - Ecart - type : { np . std ( img_degradee ) :.1 f } " )
28
29 # Etape 2: Debruitage
30 print ( " \ n [ Etape 2] Debruitage ... " )
31 # Median pour le bruit impulsionnel
32 img_median = cv2 . medianBlur ( img_degradee , 3)
33 # Gaussien pour le bruit residuel
34 img_debruitee = cv2 . GaussianBlur ( img_median , (3 , 3) , 0.8)
35 psnr_debruit = psnr ( img , img_debruitee )
36 print ( f " - PSNR apres debruitage : { psnr_debruit :.2 f } dB " )
37
38 # Etape 3: Rehaussement
39 print ( " \ n [ Etape 3] Rehaussement de nettete ... " )
40 img_rehaussee , _ , _ = unsharp_masking ( img_debruitee ,
41 sigma =1.0 , k =1.2)
42 psnr_final = psnr ( img , img_rehaussee )
43 print ( f " - PSNR final : { psnr_final :.2 f } dB " )
44
45 # Etape 4: Detection de contours
46 print ( " \ n [ Etape 4] Detection de contours ... " )
47 sobelx = cv2 . Sobel ( img_rehaussee , cv2 . CV_64F , 1 , 0 , ksize =3)
48 sobely = cv2 . Sobel ( img_rehaussee , cv2 . CV_64F , 0 , 1 , ksize =3)
49 contours = np . sqrt ( sobelx **2 + sobely **2)
50 contours = np . uint8 (255 * contours / np . max ( contours ) )
17
TP Filtrage Spatial Traitement d’Images
51
52 # Seuillage adaptatif
53 _ , contours_seuil = cv2 . threshold ( contours , 0 , 255 ,
54 cv2 . THRESH_BINARY +
55 cv2 . THRESH_OTSU )
56
57 print ( " \ n [ Termine ] Pipeline complete ! " )
58 print ( f " Amelioration PSNR : { psnr_final - psnr ( img , img_degradee )
:.2 f } dB " )
59
60 # Affichage des resultats
61 afficher_images (
62 [ img , img_degradee , img_debruitee , img_rehaussee ] ,
63 [ ’ Original ’ ,
64 ’ Degradee ’ ,
65 f ’ Debruitee ({ psnr_debruit :.1 f } dB ) ’ ,
66 f ’ Rehaussee ({ psnr_final :.1 f } dB ) ’]
67 )
68
69 afficher_images (
70 [ img_rehaussee , contours , contours_seuil ] ,
71 [ ’ Image finale ’ , ’ Contours ( Sobel ) ’ , ’ Contours seuilles ’]
72 )
73
74 return img_rehaussee , contours_seuil
75
76 # Test
77 img_finale , contours = p i p e l i n e _ a m e l i o r a t i o n _ c o m p l e t e ( ’ image . jpg ’)
18
TP Filtrage Spatial Traitement d’Images
7.2 Exercice 6.2 : Évaluation quantitative comparative
1 def e v a l u a t i o n _ c o m p a r a t i v e _ c o m p l e t e ( image ) :
2 """
3 Evaluation complete de differentes strategies
4 """
5
6 # Creer des images degradees
7 img_gauss = a j o u t e r _ b r u i t _ g a u s s i e n ( image , sigma =20)
8 img_sp = a j o u t e r _ b r u i t _ p o i v r e _ s e l ( image , prob =0.05)
9 img_mixte = a j o u t e r _ b r u i t _ p o i v r e _ s e l (
10 a j o u t e r _ b r u i t _ g a u s s i e n ( image , sigma =15) ,
11 prob =0.03
12 )
13
14 # Strategies de filtrage
15 strategies = {
16 ’ Gaussien 3 x3 ’: lambda x : cv2 . GaussianBlur (x , (3 ,3) , 1) ,
17 ’ Gaussien 5 x5 ’: lambda x : cv2 . GaussianBlur (x , (5 ,5) , 1.5) ,
18 ’ Median 3 x3 ’: lambda x : cv2 . medianBlur (x , 3) ,
19 ’ Median 5 x5 ’: lambda x : cv2 . medianBlur (x , 5) ,
20 ’ Bilateral ’: lambda x : cv2 . bilateralFilter (x , 9 , 75 , 75) ,
21 ’ Median + Gaussien ’: lambda x : cv2 . GaussianBlur (
22 cv2 . medianBlur (x , 3) , (3 ,3) , 0.8
23 ),
24 }
25
26 # Types de bruit
27 types_bruit = {
28 ’ Gaussien ’: img_gauss ,
29 ’ Poivre / Sel ’: img_sp ,
30 ’ Mixte ’: img_mixte
31 }
32
33 # Evaluation
34 resultats = {}
35
36 print ( " \ n " + " = " *70)
37 print ( " EVALUATION COMPARATIVE DES STRATEGIES DE FILTRAGE " )
38 print ( " = " *70)
39
40 for nom_bruit , img_bruitee in types_bruit . items () :
41 print ( f " \ n ### { nom_bruit } ### " )
42 print ( f " { ’ Strategie ’: <20} { ’ PSNR ( dB ) ’: <12} { ’ SSIM ’: <12} " )
43 print ( " -" * 50)
44
45 resultats [ nom_bruit ] = {}
46
47 for nom_strat , fonction in strategies . items () :
48 img_filtree = fonction ( img_bruitee )
49
50 psnr_val = psnr ( image , img_filtree )
51 ssim_val = ssim ( image , img_filtree )
52
53 resultats [ nom_bruit ][ nom_strat ] = {
54 ’ psnr ’: psnr_val ,
55 ’ ssim ’: ssim_val
56 }
19
TP Filtrage Spatial Traitement d’Images
57
58 print ( f " { nom_strat : <20} { psnr_val : <12.2 f } { ssim_val : <12.4
f}")
59
60 # Trouver la meilleure strategie
61 meilleur = max ( resultats [ nom_bruit ]. items () ,
62 key = lambda x : x [1][ ’ psnr ’ ])
63 print ( f " \ nMeilleure strategie : { meilleur [0]} " +
64 f " ( PSNR ={ meilleur [1][ ’ psnr ’]:.2 f } dB ) " )
65
66 # Visualisation
67 v i s u a l i s e r _ r e s u l t a t s _ e v a l u a t i o n ( image , types_bruit ,
68 strategies , resultats )
69
70 return resultats
71
72 def v i s u a l i s e r _ r e s u l t a t s _ e v a l u a t i o n ( image , types_bruit ,
73 strategies , resultats ) :
74 " " " Visualise les resultats sous forme de graphiques " " "
75
76 import matplotlib . pyplot as plt
77
78 # Graphique comparatif
79 fig , axes = plt . subplots (1 , 3 , figsize =(15 , 5) )
80
81 for idx , ( nom_bruit , _ ) in enumerate ( types_bruit . items () ) :
82 strategies_noms = list ( resultats [ nom_bruit ]. keys () )
83 psnr_vals = [ resultats [ nom_bruit ][ s ][ ’ psnr ’]
84 for s in strategies_noms ]
85
86 axes [ idx ]. bar ( range ( len ( strategies_noms ) ) , psnr_vals )
87 axes [ idx ]. set_xticks ( range ( len ( strategies_noms ) ) )
88 axes [ idx ]. set_xticklabels ( strategies_noms ,
89 rotation =45 , ha = ’ right ’)
90 axes [ idx ]. set_ylabel ( ’ PSNR ( dB ) ’)
91 axes [ idx ]. set_title ( f ’ Bruit { nom_bruit } ’)
92 axes [ idx ]. grid ( True , alpha =0.3)
93
94 plt . tight_layout ()
95 plt . show ()
96
97 # Test
98 img = cv2 . imread ( ’ image . jpg ’ , cv2 . IMREAD_GRAYSCALE )
99 resultats = e v a l u a t i o n _ c o m p a r a t i v e _ c o m p l e t e ( img )
20
TP Filtrage Spatial Traitement d’Images
7.3 Exercice 6.3 : Application pratique - Amélioration OCR
Question
Créez un pipeline pour améliorer une image de document avant OCR.
1 def pr etrait ement_ ocr ( image ) :
2 """
3 Pipeline de pretraitement pour OCR
4
5 Objectif : Obtenir une image binaire nette
6 """
7
8 # Etape 1: Debruitage
9 img_denoised = cv2 . f a s tN l M e a n s D e n o i s i n g ( image , None , 10 , 7 , 21)
10
11 # Etape 2: Augmentation du contraste
12 clahe = cv2 . createCLAHE ( clipLimit =2.0 , tileGridSize =(8 ,8) )
13 img_contrast = clahe . apply ( img_denoised )
14
15 # Etape 3: Binarisation adaptative
16 img_binary = cv2 . ad aptive Thresh old (
17 img_contrast , 255 ,
18 cv2 . ADAPTIVE_THRESH_GAUSSIAN_C ,
19 cv2 . THRESH_BINARY , 11 , 2
20 )
21
22 # Etape 4: Nettoyage morphologique
23 kernel = np . ones ((2 ,2) , np . uint8 )
24 img_clean = cv2 . morphologyEx ( img_binary , cv2 . MORPH_CLOSE ,
25 kernel )
26 img_clean = cv2 . morphologyEx ( img_clean , cv2 . MORPH_OPEN ,
27 kernel )
28
29 # Affichage
30 afficher_images (
31 [ image , img_denoised , img_contrast , img_binary , img_clean ] ,
32 [ ’ Original ’ , ’ Debruite ’ , ’ Contraste ’ ,
33 ’ Binaire ’ , ’ Nettoye ’]
34 )
35
36 return img_clean
37
38 # Test sur image de document
39 img_doc = cv2 . imread ( ’ document . jpg ’ , cv2 . IMREAD_GRAYSCALE )
40 img_ocr = pr etrait ement_ ocr ( img_doc )
41
42 # Si vous avez pytesseract installe :
43 # import pytesseract
44 # texte = pytesseract . image_to_string ( img_ocr , lang = ’ fra ’)
45 # print (" Texte extrait :")
46 # print ( texte )
21
TP Filtrage Spatial Traitement d’Images
8 Partie 7 : Questions de réflexion
8.1 Analyse théorique
Question
Répondez aux questions suivantes de manière détaillée :
1. Séparabilité :
— Quels filtres sont séparables ? Pourquoi ?
— Le filtre médian est-il séparable ? Justifiez.
— Calculez le gain théorique pour un noyau 9×9.
2. Choix de filtres :
— Vous avez une image médicale bruitée. Quel filtre utilisez-vous ? Pourquoi ?
— Pour détecter des lignes fines dans une image, quelle approche recommandez-
vous ?
— Comment choisir entre Sobel et LoG ?
3. Optimisation :
— Listez 5 techniques pour accélérer le filtrage spatial.
— Estimez le nombre d’opérations pour filtrer une image 1920×1080 avec un
noyau 7×7.
4. Problèmes pratiques :
— Que faire si le filtre gaussien ne réduit pas suffisamment le bruit ?
— Comment éviter les halos lors du rehaussement ?
— Proposez une stratégie pour un bruit variant spatialement.
22
TP Filtrage Spatial Traitement d’Images
8.2 Cas pratiques
Question
Pour chacun des scénarios suivants, proposez une solution complète :
Scénario 1 : Photographie nocturne
— Image avec fort bruit ISO
— Perte de détails dans les zones sombres
— Besoin de préserver les contours nets
Scénario 2 : Image satellite
— Bruit speckle important
— Détection de structures linéaires (routes, rivières)
— Contrainte temps réel
Scénario 3 : Radiographie médicale
— Faible contraste
— Bruit quantification
— Détection de fractures fines
— Qualité diagnostique critique
Bon courage !
23