Tous les logiciels de retouche d'image offrent des possibilités de traitement de l'image, que ce soit l'application de filtres, de seuils, la modifications des niveaux de couleurs, etc... Nous allons voir ici quelques exemples de traitements de l'image, accessibles à l'aide des fonctionnalités vues précédemment.
Pixellisation d'une image
Même si le phénomène de pixellisation est souvent perçu comme une dégradation de l'image, il peut être réalisé de manière contrôlée à l'aide du programme suivant :
import pygamefrom pygame.locals import *# Initialisation de la fenêtre d'affichagepygame.init()fenetre = pygame.display.set_mode((870,522))pygame.display.set_caption("La Vie de Marc Chagall")# Interrogation de l'utilisateurp=int(input("Entrer votre degré de pixellisation (supérieur à 1) :"))# Traitement de l'imagefond = pygame.image.load("lavie.jpg").convert()# Création d'une image videblank_surface = pygame.Surface((870,522))# Lecture et remplacement de la couleur de chaque pixelfor i in range(1,870,p): for j in range(1,522,p): color=fond.get_at((i,j)) for k in range(p-1): for l in range(p-1): blank_surface.set_at((i+k,j+l),color)fenetre.blit(blank_surface,(0,0))pygame.display.flip()# Boucle principalecontinuer = 1while continuer: for event in pygame.event.get(): # Quitter if event.type == QUIT: continuer = 0 pygame.quit()L'algorithme de pixellisation choisi est très simple : on détermine la couleur du pixel de coordonnées (i , j) et on applique ensuite cette couleur aux pixels de coordonnées i+1, i+2, i+p, ..., j+1, j+2, j+p de la surface créée avant de l'afficher.
A noter :
p=int(input("Entrer votre degré de pixellisation (supérieur à 1) :"))for k in range(p-1): for l in range(p-1): blank_surface.set_at((i+k,j+l),color)Voici le résultat d'une pixellisation de degré 4 et de degré 10 sur notre image de départ.
Filtration par Seuil (Threshold)
L'outil Seuil transforme une image en noir et blanc, où les pixels blancs représentent les pixels dont la Valeur est supérieure à l'intervalle de seuil fixé, et les pixels noirs représentent les pixels en dehors de cet intervalle. Cette technique peut être utilisée pour améliorer le rendu des images en noir et blanc.
Le programme suivant réalise cette opération en permettant de régler le seuil utilisé.
import pygamefrom pygame.locals import *# Initialisation de la fenêtre d'affichagepygame.init()fenetre = pygame.display.set_mode((870,522))pygame.display.set_caption("La Vie de Marc Chagall")# Affichage de l'image départfond = pygame.image.load("lavie.jpg").convert()fenetre.blit(fond,(0,0))pygame.display.flip()# Interrogation de l'utilisateurcontinuer=1while continuer: seuil=int(input("Entrer votre seuil (compris entre 0 et 255 :")) if seuil>=0 and seuil<=255: continuer=0# Création d'une image videblank_surface = pygame.Surface((870,522))# Lecture et remplacement de la couleur de chaque pixelfor i in range(870): for j in range(522): color=list(fond.get_at((i,j))) moyenne=int((color[0]+color[1]+color[2])/3) if moyenne<seuil: moyenne=0 else : moyenne=255 color[0],color[1],color[2]=moyenne,moyenne,moyenne color=tuple(color) blank_surface.set_at((i,j),color)fenetre.blit(blank_surface,(0,0))pygame.display.flip()# Boucle principalecontinuer = 1while continuer: for event in pygame.event.get(): # Quitter if event.type == QUIT: continuer = 0 pygame.quit()A noter :
while continuer qui permet de "piéger" l'utilisateur pour le forcer à saisir une valeur utilisable par le programmeVoici les résultats obtenus sur l'image de départ à l'aide du code présenté ci-dessus pour des seuils respectivement égaux à 50 et 100 :
Détection des contours
La détection des contours consiste à appliquer à chaque pixel une combinaison linéaire de lui même et de ses 8 voisins. Cette technique correspond à l'utilisation d'un tableau à deux dimensions (appelé matrice de convolution ou noyau) qui permet de traiter l'image de départ (c'est à dire la matrice de pixels initiale). Par exemple pour une matrice de convolution 3x3, le programme doit multiplier la valeur du pixel traité ainsi que des 8 pixels qui l'entourent par la valeur correspondante dans le noyau.
Voici un exemple d'image traitée par convolution à l'aide d'un matrice de convolution faisant la moyenne des couleurs d'un pixel et de celui située juste-au dessus
Voici le programme permettant de réaliser l'opération :
import pygamefrom pygame.locals import *# Matrice de convolutionmat=[[0,1,0],[0,1,0],[0,0,0]]# Initialisation de la fenêtre d'affichagepygame.init()fenetre = pygame.display.set_mode((870,522))pygame.display.set_caption("La Vie Convoluée de Marc Chagall")# Traitement de l'imagefond = pygame.image.load("lavie.jpg").convert()blank_surface = pygame.Surface((870,522))# Affichage de l'image départfenetre.blit(fond,(0,0))pygame.display.flip()pygame.time.wait(1000)# Lecture et remplacement de la couleur de chaque pixelfor i in range(870): for j in range(522): if i!=0 and i!=869 and j!=0 and j!=521: newcolor=[0,0,0] for k in range(3): for l in range(3): for m in range(3): color=list(fond.get_at((i-1+k,j-1+l))) newcolor[m]=newcolor[m]+color[m]*mat[k][l] for m in range(3): newcolor[m]=int(newcolor[m]/2) else : newcolor=list(fond.get_at((i,j))) newcolor=tuple(newcolor) blank_surface.set_at((i,j),newcolor) # Collage du fondfenetre.blit(blank_surface,(0,0))pygame.display.flip()# Sauvegarde de l'image dans un fichierpygame.image.save(blank_surface,"lavieconvolueedemarcchagall.jpg")# Boucle principalecontinuer = 1while continuer: for event in pygame.event.get(): # Quitter if event.type == QUIT: continuer = 0 pygame.quit()Détaillons un peu le programme :
mat=[[0,1,0],[0,1,0],[0,0,0]] , il s'agit de la même que celle traitée en exemple précédemmentif i!=0 and i!=869 and j!=0 and j!=521 sert à éviter de traiter le cas des pixels situés au bord de l'image, on peut l'enlever si on modifie pour ces pixels la dimension de la matrice de convolution. L'instruction else couplée permet de copier la couleur de ces pixels dans la nouvelle imagefor k in range(3) et for l in range(3) permettent de traiter chacun des pixels de l'image correspondant à un des éléments de la matrice de convolutioncolor=list(fond.get_at((i-1+k,j-1+l))) sert à récupérer la couleur de chaque pixel entourant le pixel de l'image traité, les indices i-1+ k et j-1+l servant à repérer leurs positionsnewcolor[m]=newcolor[m]+color[m]*mat[k][l] permet de stocker la couleur issue du produit entre un des éléments de la matrice de convolution et la couleur du pixel correspondant sur l'image traitée. Intégrée dans les deux boucles for, elle assure le calcul correct du produit de convolution.for m in range(3): newcolor[m]=int(newcolor[m]/2) permet de re-normaliser la valeur de la couleur. Il est à noter que le diviseur 2 doit être modifié si vous changez les éléments de la matrice de convolution...Voici l'image de départ et le résultat de la convolution : on peut constater que l'opération a amélioré les contours de l'image...
Exemple d'exercice d'appropriation : créer un deuxième script permettant d'éliminer le "bruit" sur une image à l'aide d'un filtre médian, filtre pour lequel chaque pixel est remplacé par la médiane de la série constituée du pixel et de ses huit voisins.
La correction du script est ici.
Voici l'image de départ et le résultat de l'application du filtre médian. A vous de comparer avec le résultat précédent !