Vous êtes sur la page 1sur 9

15/9/2015

7.1.2. Mini-tutoriel de traitement dimages Python scientifique - ENS Paris

7.1.2.Minitutorieldetraitementdimages
Le module skimage est organis en plusieurs sousmodules correspondant plusieurs
branches du traitement dimages : segmentation, filtrage, gestion des formats dimage, etc.
Pour viter davoir des noms trop longs, on importe souvent directement les sousmodules
danslenamespaceprincipal
>>> from skimage import data
>>> coins_image = data.coins()
>>> from skimage import io
>>> io.imshow(coins_image)
>>> from skimage import filter
>>> edges = filter.sobel(coins_image)
Lagrandemajoritdesfonctionsde skimagesetrouventdonclintrieurdunsousmodule:il
yadeuxniveauxhirarchiques.

7.1.2.1.Input/output:desfichiersauxtableauxnumpy
>>> import os
>>> import skimage
>>> current_dir = os.getcwd() # so that we can go back to current
dir.
>>> os.chdir(skimage.data_dir)
On peut ouvrir un fichier image (jpg, png, tiff...) comme un tableau numpy en passant le
chemindufichierlafonction skimage.io.imread
>>> from skimage import io
>>> coins_image = io.imread('coins.png')
Unelargegammedeformatsdefichierestsupporte:jpg,png,tiff,bmp,etc.
On peut ouvrir des images en couleur ou en noir et blanc. Les images en couleur ont trois
dimensions,lesimagesennoiretblancenontdeux
>>> coins_image.shape
(303, 384)
>>> lena_image = io.imread('lena.png')
>>> lena_image.shape
(512, 512, 3)
>>> io.imshow(lena_image) # color image
>>> io.imshow(lena_image[..., 0]) # grayscale image
Laffichageduneimagesefaitgrcelafonction skimage.io.imshow.
Onpeutaussiouvriruneimagecouleurcommeuneimageennoiretblanc
>>> lena_gray = io.imread('lena.png', as_grey=True)
>>> lena_gray.shape
(512, 512)
>>> os.chdir(current_dir)
http://python-prepa.github.io/ateliers/image_tuto.html

1/9

15/9/2015

7.1.2. Mini-tutoriel de traitement dimages Python scientifique - ENS Paris

Typedestableauxdimage
Lestableauxdimagespeuventtresoitdestableauxdentier,soitdestableauxdeflottants.
La plupart des formats dimage stockent les valeurs des pixels sous forme dentiers le
formatleplusclassiquecorresponddesentierscodssur8bits(entre0,et255),cequi
correspondautype np.uint8denumpy(entiernonsignsur8bits).
Il est par contre naturel dutiliser des flottants ds quon fait des oprations sur les pixels
dans lespace des rels, comme des multiplications ou des divisions par des rels. Par
consquent,certainesfonctionsde skimagerenvoientuntableaudetypediffrentdutableau
dentre
>>> from skimage import data
>>> coins_image = data.coins()
>>> coins_image.dtype
dtype('uint8')
>>> median_filter_coins = median_filter(coins_image)
>>> median_filter_coins.dtype # median of integers is an integer
dtype('uint8')
>>> from skimage import exposure
>>> equalize_coins = exposure.equalize(coins_image)
>>> equalize_coins.dtype
dtype('float64')
Dans skimage, par convention les images en flottant sont valeur entre 1 et 1, afin
dassurerquetouteslesimagesaientlammeplagedevaleurs.Laplagedevaleursdune
imageretourneparunefonctionpeutdonctretrsdiffrentedecelledelimagedentre,
danslecasoletypeatmodifi
>>> print coins.min(), coins.max()
1 252
>>> print equalize_coins.min(), equalize_coins.max()
8.59460946095e-06 1.0
Les fonctions skimage.img_as_float et skimage.img_as_ubyte permettent de faire la
conversionentrelestypessanssesoucierdeschangementsdchelle.
Delammemanirequonpeutouvrirunfichierimagecommetableaunumpy,onpeutfaire
lopration contraire : sauver un tableau numpy correspondant une image en un fichier
image.Pourcela,onutiliselafonction skimage.io.imsave
>>> io.imsave('equalize_coins.png', equalize_coins)
Letypedufichierimageestautomatiquementdduitdelextensiondelachanedecaractres
http://python-prepa.github.io/ateliers/image_tuto.html

2/9

15/9/2015

7.1.2. Mini-tutoriel de traitement dimages Python scientifique - ENS Paris

(.png,.jpg).

7.1.2.2.Quelquesoprationsdebaseavec numpy
Unefoisquenotreimageestuntableaunumpy,lesoprationsdenumpysurleslmentsdu
tableaucorrespondentdesoprationssurlespixels.
>>> path = os.path.join(skimage.data_dir, 'lenagray.png')
>>> lena = io.imread(path)
>>> # Pixel value
>>> lena[20, 32]
110
>>> # Slicing
>>> lena[20:22, 32:34]
Image([[110, 113],
[110, 111]], dtype=uint8)
>>> lena[50:60] = 255
>>>
>>> lx, ly = lena.shape
>>> X, Y = np.ogrid[0:lx, 0:ly]
>>> mask = (X - lx/2)**2 + (Y - ly/2)**2 > lx*ly/4
>>> # Using masks
>>> lena[mask] = 0

Attention:pourlindexation,la1edimension(axe0)correspondauxlignesindicesdehaut
en bas, et la 2e dimension (axe 1) correspond aux colonnes de gauche droite. Cest la
conventiondestableauxnumpy.

Exercice
Cet exercice a pour but de sentraner 1) au slicing des tableaux numpy et 2) la
reprsentationdimagescouleurssouslaformedetableauxnumpytroiscanaux.

http://python-prepa.github.io/ateliers/image_tuto.html

3/9

15/9/2015

7.1.2. Mini-tutoriel de traitement dimages Python scientifique - ENS Paris

Exercice:raliseruneimageressemblantlimagecidessus,souslaformeduntableau
numpy.Onpourraparexempleprendrelimagedeforme32x32,etdetype np.uint8(entiers
de0255).
Indices:
LestroiscanauxdecouleursontdanslordreR,V,B(rougevertbleu).
Lejaunecorrespondautriplet(R,V,B)=(255,185,15)
Voirlasolution:
[Pythonsourcecode]

7.1.2.3.Filtragedimage
Le filtrage consiste (au sens large) transformer une image par une autre image, en
remplaant la valeur dun pixel par une fonction de cette valeur mais aussi des valeurs des
autrespixelsdelimage.Onditquelefiltreestlocalsicesontlesvaleursdespixelsvoisins
quisontutilises,nonlocalsinon:
>>> from skimage import filter
Ilexisteenparticulieruncertainnombredefonctionsquivontmoyennerensembledespixels
proches.Celapeuttreutiledansdesapplicationsdedbruitage,oonveutrduirelebruit
surlespixels:
>>> coins_zoom = coins[10:80, 300:370]
>>> median_coins = filter.median_filter(coins_zoom)
>>> tv_coins = filter.tv_denoise(coins_zoom, weight=0.1)
Attention:lefiltregaussiennesetrouvepasdans scikit-image,maisdans scipy.ndimage
>>> from scipy import ndimage
http://python-prepa.github.io/ateliers/image_tuto.html

4/9

15/9/2015

7.1.2. Mini-tutoriel de traitement dimages Python scientifique - ENS Paris

>>> gaussian_coins = ndimage.gaussian_filter(coins, sigma=2)

Un autre type de filtrage trs pratique est la morphologie mathmatique : ce sont des
oprationslogiqueslocalessurdesensemblesdepixels.Cesoprationspeuventfonctionner
sur des images dentiers (0 255), mais par simplicit nous allons uniquement voir des
oprations qui fonctionnent sur des images binaires de 0 et de 1 (False et True) : cest la
morphologiemathmatiquebinaire.
Laplupartdesoprationsreposentsurunlmentstructurant,quivaservirsonderlimage
binaire.
>>> morphology.disk(1)
array([[0, 1, 0],
[1, 1, 1],
[0, 1, 0]], dtype=uint8)
>>> morphology.disk(3)
array([[0, 0, 0, 1, 0, 0, 0],
[0, 1, 1, 1, 1, 1, 0],
[0, 1, 1, 1, 1, 1, 0],
[1, 1, 1, 1, 1, 1, 1],
[0, 1, 1, 1, 1, 1, 0],
[0, 1, 1, 1, 1, 1, 0],
[0, 0, 0, 1, 0, 0, 0]], dtype=uint8)
Lopration drosion va venir roder les objets (de valeur 1) de limage : quand on centre
llmentstructurantsurunpixeldonn,onmetcepixel0sitouslespixelsrecouvertspar
llmentstructurantnesontpas1.
>>> a = np.zeros((7, 7))
>>> a[1:-1, 1:-1] = 1
>>> a
array([[ 0., 0., 0., 0., 0., 0., 0.],
[ 0., 1., 1., 1., 1., 1., 0.],
[ 0., 1., 1., 1., 1., 1., 0.],
[ 0., 1., 1., 1., 1., 1., 0.],
[ 0., 1., 1., 1., 1., 1., 0.],
[ 0., 1., 1., 1., 1., 1., 0.],
[ 0., 0., 0., 0., 0., 0., 0.]])
>>> erosion_a = morphology.binary_erosion(a, morphology.disk(1))
>>> erosion_a
array([[False, False, False, False, False, False, False],
[False, False, False, False, False, False, False],
[False, False, True, True, True, False, False],
[False, False, True, True, True, False, False],
[False, False, True, True, True, False, False],
http://python-prepa.github.io/ateliers/image_tuto.html

5/9

15/9/2015

7.1.2. Mini-tutoriel de traitement dimages Python scientifique - ENS Paris

[False, False, False, False, False, False, False],


[False, False, False, False, False, False, False]], dtype=bool)
>>> morphology.binary_erosion(a, morphology.disk(3))
array([[False, False, False, False, False, False, False],
[False, False, False, False, False, False, False],
[False, False, False, False, False, False, False],
[False, False, False, False, False, False, False],
[False, False, False, False, False, False, False],
[False, False, False, False, False, False, False],
[False, False, False, False, False, False, False]], dtype=bool)
Loprationcontrairesappelleladilatation:ladilatationmet1touslespixelspourlesquels
llmentsstructurantcentraupixelrecouvreaumoinsunpixelvalant1
dilation_erosion_a = morphology.binary_dilation(erosion_a,
morphology.disk(1))
On voit que la composition dune rosion puis dune rosion redonne presque limage
dorigine,lexceptiondescoinsquiontdisparu.Cetteoprationsappelleuneouverture.De
mme, une ouverture va faire disparatre les petits objets, qui disparatront lrosion et ne
pourrontdoncpastredilatslorsdeltapededilatation.

7.1.2.4.Extractiondobjetsdintrt
Unetcheclassiqueconsistespareruneimageenunnombrefinidergions,enattribuant
chaquepixelunetiquette(unlabel)correspondantaunumrodelargion.
Parexemple,onpeutvouloirbinariseruneimageenrgionsclairesetsombres.Ilexistedans
scikit-imageunefonctioncalculantautomatiquementleseuilleplusdiscriminantentredeux
populationsdepixels:lafonction skimage.filter.threshold_otsu qui implmente lalgorithme
http://python-prepa.github.io/ateliers/image_tuto.html

6/9

15/9/2015

7.1.2. Mini-tutoriel de traitement dimages Python scientifique - ENS Paris

deseuillagedOtsu
from skimage import data
from skimage import filter
camera = data.camera()
val = filter.threshold_otsu(camera)
mask = camera < val

Parfois, un simple seuillage sur toute limage ne donne pas un rsultat satisfaisant cest
notamment le cas lorsque lclairage de limage ntait pas homogne. Il existe donc une
fonctionquivacalculerleseuildansunvoisinagelocal,etpeutdoncbinariseruneimagede
faonplussatisfaisante
simple_threshold = coins > filter.threshold_otsu(coins)
adaptive_threshold = filter.threshold_adaptive(coins, 151)
Limage adaptive_threshold a bien spar les pices du fond, pour supprimer les petites
tachesblanchesetlabandeenhautdelimageonpeututiliserdeuxfonctionsduscikitimage
dontlenomdonnelafonction: remove_small_objectset clear_border:
from skimage import segmentation
from skimage import morphology
filter_res = morphology.remove_small_objects(adaptive_threshold)
clear_image = segmentation.clear_border(filter_res)

http://python-prepa.github.io/ateliers/image_tuto.html

7/9

15/9/2015

7.1.2. Mini-tutoriel de traitement dimages Python scientifique - ENS Paris

Ilexistedans scikit-imagedesalgorithmesdesegmentationbeaucoupplussophistiqusque
les seuillages, par exemple des algorithmes de croissance de rgion partir de pixels
marqueurs, ou des dcompositions automatiques de limage en superpixels. La meilleure
manire de se familiariser avec ces algorithmes consiste consulter les exemples de la
gallerieduscikitimage.
Une fois quon a binaris limage, on peut donner un indice diffrent chaque objet spar
(composanteconnexe)grcelafonction morphology.label
labels = morphology.label(clear_image, background=0)

7.1.2.5.Mesuredespropritsdesobjets
Unefoisquonasparuneimageenrgions avec diffrentsindices,onpeutallercalculer
diffrentespropritsdecesrgionsgrcelafonction skimage.measure.regionprops
from skimage import measure
props = measure.regionprops(labels, ['Area'])
>>> props[0]
{'Area': 1652.0, 'Label': 1}
>>> (labels == 1).sum()
1652

7.1.2.6.Etautres
Onnafaiticiqueffleurercertainsaspectsdutraitementdimages,ilexistedansscikitimage
bien dautres possibilits pour aller reconnatre des formes dans une image, appliquer des
dformations des images, extraire des descripteurs dimages pour les classifier
automatiquement, etc. On peut dj en apprendre pas mal en allant lire (et faire !) les
exemplesduscikitimage.

http://python-prepa.github.io/ateliers/image_tuto.html

8/9

15/9/2015

7.1.2. Mini-tutoriel de traitement dimages Python scientifique - ENS Paris

http://python-prepa.github.io/ateliers/image_tuto.html

168526pagesvisites

9/9