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 pygame
from pygame.locals import *
# Initialisation de la fenêtre d'affichage
pygame.init()
fenetre = pygame.display.set_mode((870,522))
pygame.display.set_caption("La Vie de Marc Chagall")
# Interrogation de l'utilisateur
p=int(input("Entrer votre degré de pixellisation (supérieur à 1) :"))
# Traitement de l'image
fond = pygame.image.load("lavie.jpg").convert()
# Création d'une image vide
blank_surface = pygame.Surface((870,522))
# Lecture et remplacement de la couleur de chaque pixel
for 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 principale
continuer = 1
while 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 pygame
from pygame.locals import *
# Initialisation de la fenêtre d'affichage
pygame.init()
fenetre = pygame.display.set_mode((870,522))
pygame.display.set_caption("La Vie de Marc Chagall")
# Affichage de l'image départ
fond = pygame.image.load("lavie.jpg").convert()
fenetre.blit(fond,(0,0))
pygame.display.flip()
# Interrogation de l'utilisateur
continuer=1
while 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 vide
blank_surface = pygame.Surface((870,522))
# Lecture et remplacement de la couleur de chaque pixel
for 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 principale
continuer = 1
while 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 pygame
from pygame.locals import *
# Matrice de convolution
mat=[[0,1,0],[0,1,0],[0,0,0]]
# Initialisation de la fenêtre d'affichage
pygame.init()
fenetre = pygame.display.set_mode((870,522))
pygame.display.set_caption("La Vie Convoluée de Marc Chagall")
# Traitement de l'image
fond = pygame.image.load("lavie.jpg").convert()
blank_surface = pygame.Surface((870,522))
# Affichage de l'image départ
fenetre.blit(fond,(0,0))
pygame.display.flip()
pygame.time.wait(1000)
# Lecture et remplacement de la couleur de chaque pixel
for 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 fond
fenetre.blit(blank_surface,(0,0))
pygame.display.flip()
# Sauvegarde de l'image dans un fichier
pygame.image.save(blank_surface,"lavieconvolueedemarcchagall.jpg")
# Boucle principale
continuer = 1
while 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 !