Bonjour,
j'ai programmé un filtrage gaussien sur une image couleurs, mais je ne suis pas satisfait du résultat.
Quelqu'un peut-il m'aider à trouver mon erreur ?
J'utilise pyplot pour l'affichage de l'image et imageo comme module d'image.
Résultat :
![]()
Bonjour,
j'ai programmé un filtrage gaussien sur une image couleurs, mais je ne suis pas satisfait du résultat.
Quelqu'un peut-il m'aider à trouver mon erreur ?
J'utilise pyplot pour l'affichage de l'image et imageo comme module d'image.
Résultat :
![]()
Sans aucun doute, si tu y postes ton code !!!
Merci.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 def filtrer1(filtreA,matB): """filtreA est une matrice carree filtrage sur une couleur seulement """ nA=filtreA.shape[0] # taille de filtreA nb_ligneB=matB.shape[0] # nb de lignes de matB nb_colonneB=matB.shape[1] C=matB.copy() # on copie matB bordure=nA//2 ## taille du bord for i in range(bordure,nb_ligneB-bordure): # on eclut les lignes du bord for j in range(bordure,nb_colonneB-bordure): # idem pour les colonnes Bij=matB[i-bordure:i+bordure+1,j-bordure:j+bordure+1] # on crée la matrice autour de l'élément central bij C[i,j]=np.sum(np.dot(Bij,filtreA)) # on calcule le terme Cij return(C) def filtrer(filtreA,matB): nA=filtreA.shape[0] nb_ligneB=matB.shape[0] nb_colonneB=matB.shape[1] C=np.zeros((nb_ligneB,nb_colonneB,3),dtype='uint8') for k in range(3): Ck=filtrer1(filtreA,matB[:,:,k]) for i in range(nb_ligneB): for j in range(nb_colonneB): C[i,j,k]=Ck[i,j] return(C) def matriceFlouGaussien(taille,sigma): """ taille : taille de la matrice impaire sigma : ecart-type retourne un niveau gaussien """ mat=np.zeros([taille,taille]) taille=taille//2 for x in range(-taille,taille+1): for y in range(-taille,taille+1): mat[taille+x,taille+y]=np.exp(-(x**2+y**2)/(2*sigma**2)) s=np.sum(mat) return((1/s)*mat) def FloutageGaussien(tabPix,taille,sigma): filtreA=matriceFlouGaussien(taille,sigma) return(filtrer(filtreA,tabPix)) picture_floute=FloutageGaussien(Picture,5,0.9) plt.figure(3) plt.imshow(picture_floute) plt.show()
Erreur déjà chez moi dans la fonction filtrer :
[edit] C'est moi qui suis en cause.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 nb_ligneB=matB.shape[0] AttributeError: 'str' object has no attribute 'shape'
Par contre, tu ne montres pas ce qu'est Picture...
Perso, j'utilise PIL pour ouvrir une image, ce n'est apparemment pas ton cas.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 import imageio as mg picture=mg.imread('modele.png') Picture=np.array(picture)
Ligne 14
Ton nouveau point c'est une moyenne sur les points voisins. Bij, contient l'ensemble des points du voisinage. FiltreA les coefficient à appliquer pour calculer cette moyenne. np.dot va te calculer un produit matriciel, qui ici, je doute fort que ce soit cela que tu veux. Il te faut un produit terme à terme.
Code : Sélectionner tout - Visualiser dans une fenêtre à part C[i,j]=np.sum(np.dot(Bij,filtreA)) # on calcule le terme Cij
En numpy cela se fait de manière assez trivial mais tu semble pas trop maitriser numpy. Ce qui me le fait dire c'est notemment cela :
alors qu'en numpy justement on a plein de chose bien faites pour éviter de faire des boucles sur tous les indices :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 for i in range(nb_ligneB): for j in range(nb_colonneB): C[i,j,k]=Ck[i,j]
Un petit tour vers un bon tuto numpy semble donc inévitable pour toi. Et concernant ton problème isole ta ligne de code, donne toi un filtre (meme simple, avec des 1/9 partout), et un exemple de Bij, et voit si ca correspond au résultat attendu (que tu peux calculer à la main, ou bien aussi, en écrivant la moyenne pondérée de manière explicitée en python vu que là tu connais la dimension)
Code : Sélectionner tout - Visualiser dans une fenêtre à part C[:,:,k]=Ck
Je n'ai pas tout compris dans ton programme).
Je pense qu'il serait préférable de procéder par étapes :
commencer par une image en niveaux de gris (un seul canal) de petite taille (10 * 8 par exemple) de façon à pouvoir afficher les valeurs de pixels.
Voici ce que je fais de mon côté :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 from PIL import Image noyau0 =\ [1, 4, 7, 4, 1,\ 4, 16, 26, 16, 4,\ 7, 26, 41, 26, 7,\ 4, 16, 26, 16, 4,\ 1, 4, 7, 4, 1 ] def conv_gris(image1): image2 = Image.new("RGB",image1.size) # conversion en niveaux de gris, mode RGB for ligne in range(image1.size[1]): for colonne in range(image1.size[0]): pix = image1.getpixel((colonne,ligne)) rouge = int((pix[0]+pix[1]+pix[2])/3) vert = rouge bleu = rouge image2.putpixel((colonne,ligne),(rouge,vert,bleu)) return image2 def flou_gaussien(image2,noyau): # filtrage de l'image en niveaux de gris image3 = Image.new("RGB",image2.size) for ligne in range(2,image2.size[1]-2): for colonne in range(2,image2.size[0]-2): liste_pix=[] for x in range(colonne-2,colonne+3): for y in range(ligne-2,ligne+3): liste_pix.append(image2.getpixel((x,y))) gris=0 for i in range(25): gris=gris+noyau[i]*liste_pix[i][0] rouge = vert = bleu = int(gris/273) image3.putpixel((colonne,ligne),(rouge,vert,bleu)) return image3 nom = "billes.jpg" mon_image = Image.open(nom) # affichage de l'image en niveaux de gris gris = conv_gris(mon_image) gris.show() # flou gaussien de l'image en niveaux de gris flou = flou_gaussien(conv_gris(mon_image),noyau0) flou.show()
Merci à tous. J'avais en effet fait une confusion entre le produit matriciel et le produit de tableaux coeff par coeff sous numpy.
J'ai corrigé mon problème.
Partager