Un principe de compression d’image
description
Transcript of Un principe de compression d’image
S.S.I.I. 2015-16, cours n°10 : Un principe de compression d’imageS.S.I.I. 2015-16, cours n°10 : Un principe de compression d’image Page Page 11
Un principe de compression d’imageCours S.S.I.I. n° 10, décembre 2015, durée : 50 mn,
Jean-Paul Stromboni pour les élèves SI3
Après cette séance, vous devriez savoir :
• Décrire le principe de la compression JPEG des images numériques
• Expliquer ce qu’on entend par composition fréquentielle d’une image
• Comparer transformée en cosinus discret et Transformée de Fourier Discrète
• Donner la signification des coefficients DCT
• Compresser une image en négligeant les coefficients DCT les plus faibles
Ce cours a été rédigé à partir de plusieurs sources, dont le cours de Pierre Nerzic
à l’Université de Rennes et à l’IUT de Lannion : ‘S3P3 – Codages et compression.html’ cliquer ici pour récupérer le document au format pdf
TD 11 : Application avec SIVP et les scripts Scilab ‘madct.sci’ et ‘idct.sci’ au besoin
On appliquera la DCT, puis une quantification et la DCT inverse, à une image de niveaux de gris tirée d’une image couleur à choisir librement, on veillera simplement à découper une image suffisamment petite (par exemple 64x64 pixels) pour alléger les calculs.
S.S.I.I. 2015-16, cours n°10 : Un principe de la compression d’imageS.S.I.I. 2015-16, cours n°10 : Un principe de la compression d’image Page Page 22
Schéma de principe de la compression JPEG (d’après Wikipédia)
1. Découpage de l’image en blocs de 8x8 pixels
2. Séparation de chaque bloc en plans Y (luminance), Cr et Cb (chrominances rouge et bleu)
3. Sous échantillonnage de Cr et Cb dans un rapport 2 suivant la hauteur et suivant la largeur
4. DCT (Discrete Cosine Transform) des blocs : pour chaque bloc, on obtient 8x8 coefficients qui définissent la composition fréquentielle spatiale du bloc
5. Quantification : les coefficients DCT les plus faibles en valeur absolue sont annulés ou codés sur un nombre de bits plus faible (le pas de quantification augmente)
6. Codage RLE (Run Length Encoding) et codage de Huffman (Variable Length Coding) pour compresser davantage
S.S.I.I. 2015-16, cours n°10 : Un principe de la compression d’imageS.S.I.I. 2015-16, cours n°10 : Un principe de la compression d’image
Transformation de couleurs et sous échantillonnage
On a vu déjà (d’après Wikipédia) : De RVB à YUV :
Y = 0,299⋅R + 0,587⋅G + 0,114⋅B U = Cb = 0,492 (⋅ B − Y) = −0,14713⋅R − 0,28886⋅G + 0,436⋅B V = Cr = 0,877 (⋅ R − Y) = 0,615⋅R − 0,51498⋅G- 0,10001⋅B
De YUV à RVB : R = Y + 1,13983⋅V G = Y − 0,39465⋅U − 0,58060⋅V B = Y + 2,03211⋅U
Compression par sous échantillonnage de Cb (U) et Cr (V) (d’après http://www-ljk.imag.fr/membres/Valerie.Perrier/SiteWeb/node8.html)
C= 3/1.5= 2
S.S.I.I. 2015-16, cours n°10 : Un principe de la compression d’imageS.S.I.I. 2015-16, cours n°10 : Un principe de la compression d’image Page Page 44
DCT (Discrete Cosine Transform) est une forme de la Transformée de Fourier discrète (TFD) utilisée pour la compression JPEG (Joint Picture Expert
Group)
//Frequency components of a signal //---------------------------------- // build a sampled at 1000hz containing// pure frequencies at 50 and 70 Hz sample_rate=1000; t = 0:1/sample_rate:0.6; N=size(t,'*'); //number of samples s=sin(2*%pi*50*t)+sin(2*%pi*70*t+%pi/4); d=dct(s); //dct// zero low energy components D(abs(d)<1)= 0;//compression par seuilsize(find(d<>0),'*') // 20 nonzero coefficients out of 600 clf;plot(s,'b'),plot(dct(d,1),'r') //dct inverseplot2d(f,d) f=[0:N-1]*sample_rate/(2*N);xtitle('coefficients de dct(s)',...'freq (Hz)', 'd') xgrid
Ci-dessous un exemple fourni par Scilab dans l’aide de la fonction ‘dct’ (faire : help dct): noter que s est de taille 601 échantillons, d= dct(s) de même taille, contient la composition fréquentielle de s, et c’est un vecteur réel d(abs(d))<1)= 0 annule les composantes de ‘d’ inférieures à 1 en valeur absolue restent 20 composantes non nulles, le taux de compression C= 601/20 ‘dct(d,1)’ ou ‘idct(d)’ calculent la dct inverse du vecteur d. voir ci-dessous s en bleu et dct(d,1) en rouge
S.S.I.I. 2015-16, cours n°10 : Un principe de la compression d’imageS.S.I.I. 2015-16, cours n°10 : Un principe de la compression d’image Page Page 55
Comparaison des fonctions dct et fft de Scilab
• Soit le signal s= [sn, n=0 .. N-1], avec sn=s(n/fe)
• S=fft(s)=[Sk, k=0..N-1], de taille N
• D= dct(s)= [Dm, m= 0 .. N-1],
• Comparaison :1. D est un vecteur réel, S est un vecteur complexe
2. Les fréquences des termes Sk et Dm calculés sont différentes• Pour fft, Sk=S(fk) :
• Pour dct, Dm=D(fm):
NNavecN
mns
N
fmDD m
N
n nme
m /2,/1,)2
)12(cos()
2( 00
1
0
ekeee
ek fffN
N
N
f
N
ffNkf
N
kf
0,1
,...2
,,01..0,
,)(1
0
/2
N
n
Nknin
ek es
N
fkSS
20,
2)1(,...
22,
2,01..0,
2e
meeee
m
ff
N
fN
N
f
N
ffNm
N
fmf
S.S.I.I. 2015-16, cours n°10 : Un principe de la compression d’imageS.S.I.I. 2015-16, cours n°10 : Un principe de la compression d’image
Fréquence spatiale dans une image (loi d’intensité sinusoïdale)
h(x)=(1+cos(2*f*x))/2 N pixels sur la longueur L L/N =Te, période d’échantillonnage N/L= fe, fréquence d’échantillonnage (ou résolution en ppp ou dpi) Si P pixels dans une période de h(x) :
(P*L)/N= T, période de h(x) N/(L*P)= f, fréquence de h(x)
Fréquences normalisées: on choisit L= N unités de longueur fe= N/L= 1 pixel par unité de longueur Te=1 unité de longueur par pixel N/(L*P)= 1/P = f, fréquence de h(x) h(x)= (1+cos(2*x/P))/2, x= 0 … N-1, avec 0=< x < L (puisque N = L)
Image élémentaire : Soit v(y) = (1+cos(2*y/Q))/2, y= 0 … M-1, avec 0=< y < H M/H=1, fréquence d’échantillonnage (ou résolution verticale en ppp ou dpi) Im= v’*h; définit une image élémentaire Im dotée
d’une fréquence horizontale : 1/P et d’une fréquence verticale : 1/Q
S.S.I.I. 2015-16, cours n°10 : Un principe de la compression d’imageS.S.I.I. 2015-16, cours n°10 : Un principe de la compression d’image Page Page 77
Application : créer et afficher une image de niveaux de gris contenant une unique fréquence spatiale horizontale
//Image sinusoïdale xset("window",0) N=32 L=N; fx=N/L x=0:N-1; y=0:N-1; P=7 h= 0.5*(1+cos(2*%pi*x/P)); sy=ones(1,N); Ims=sy'*h; //imshow(Ims) xset("colormap",graycolormap(256)); grayplot(x,y,Ims',strf="041"); xtitle(["N=",string(N),"pixels","période P=",... string(P),"pixels"],["x, pour fx=",string(fx)],... "y, fy= fx") xset("window",1)" plot2d3(x, h) xtitle(["plot2d3 de h=(1+cos(2*\pi*x/P))/2, x varie de 0 à ",... string(N-1),"P=",string(P)],"x","intensité h(x), entre 0 et 1")
S.S.I.I. 2015-16, cours n°10 : Un principe de la compression d’imageS.S.I.I. 2015-16, cours n°10 : Un principe de la compression d’image Page Page 88
Utilisation de la DCT 2D dans le principe de compression JPEG L’image à compresser est découpée en blocs de 8x8 pixels, auxquels on applique la DCT
bidimensionnelle suivante, avec N=8 :
C(i) vaut 1 pour i non nul, et sqrt(2) pour i = 0 (de même pour C(j) et j)pixel(x, y), avec x=0..7, et y=0.. 7 définit un bloc de 8x8 pixelsDCT(i, j), i=0..7, j=0..7, contient la composition fréquentielle du bloc
DCT(i, j) est l’amplitude de la composante fréquentielle du bloc aux fréquences normalisées j/16 horizontale et i/16 verticale (fréquences variant entre 0 et 0.5 -- fe/2= 0.5)
8x8 pixels donnent 8x8 coefficients DCT, le taux de compression est C=1 Calcul et tracé de la dct de l’image sinusoïdale précédente et calcul de la dct inverse
// transformée de l'image précédente D=dct(Ims) xset("colormap",hsvcolormap(256)); // grayplot ne lisse pas le tracé grayplot(x,y,D',strf="041"); colorbar(min(D),max(D)) imshow(D) //dct inverse Imrec=idct(D) // ou encore Imrec= dct(D, 1) xset("colormap", graycolormap(256)); // Sgrayplot opère un lissage Sgrayplot(x,y,Imrec',strf="041"); colorbar(min(Imrec),max(Imrec))
S.S.I.I. 2015-16, cours n°10 : Un principe de la compression d’imageS.S.I.I. 2015-16, cours n°10 : Un principe de la compression d’image
Une image de niveaux de gris avec une fréquence spatiale verticale
//Image sinusoïdale verticale xset("window",0) M=64 H=M; fy=M/H; x=0:N-1; y=0:M-1; Q=24 v=0.5*(1+cos(2*%pi*y/Q)); sx=ones(1,N); Ims=v'*sx; xset("colormap",graycolormap(256)); grayplot(x,y,Ims',strf="041"); xtitle(["M=",string(M),"pixels", … "période Q=", string(Q),"pixels"],"x "… ,["y, pour fy=",string(fy)])
S.S.I.I. 2015-16, cours n°10 : Un principe de la compression d’imageS.S.I.I. 2015-16, cours n°10 : Un principe de la compression d’image
Une image ‘élémentaire’ dotée d’une fréquence horizontale et d’une fréquence verticalexset("window",0) N=64 M=N H=M;L=N; fy=M/H;fx=N/L x=0:N-1; y=0:M-1; P=16; Q=24 h=0.5*(1+cos(2*%pi*x/P)); v=0.5*(1+cos(2*%pi*y/Q)); Ims=v'*h; xset("colormap",graycolormap(256)); grayplot(x,y,Ims',strf="041"); xtitle(["M=N=",string(M),"pixels"], ... ["x, période P=",string(P)],… ["y, période Q=",string(Q)])
S.S.I.I. 2015-16, cours n°10 : Un principe de la compression d’imageS.S.I.I. 2015-16, cours n°10 : Un principe de la compression d’image Page Page 1111
La fonction DCT inverse (idct en Scilab) reconstitue le bloc de pixels initial en faisant une somme pondérée des 64 images élémentaires ci-dessousChaque image élémentaire contient une fréquence horizontale et une fréquence verticale. Les coefficients de pondération sont les DCT(i,j), i=0..7, j=0 .. 7.
Correspondance entre i, j et les fréquences normalisées : fv = i/(2*N)=j/16, et fh= j/(2N)=j/16.
j=0 j=1 j=7
i=0
i=1
i=7
j
i
0.5
0
fv
fh
0.50
S.S.I.I. 2015-16, cours n°10 : Un principe de la compression d’imageS.S.I.I. 2015-16, cours n°10 : Un principe de la compression d’image Page Page 1212
Pour compresser un bloc, il faut négliger des coefficients DCT
0,0
Les coefficients DCT diminuent quand la fréquence augmente, on parcourt le tableau DCT en zigzag pour s’éloigner progressivement de l’origine des fréquences en haut et à gauche : Codage en zigzag : on parcourt les coefficients DCT(i,j) à (i+j) croissant :
i=j=0, le coefficient DCT(0,0)i=1, j=0, puis i=0, j=1, les coefficients DCT(1,0) puis DCT(0,1), i=2, j=0, puis i=1, j=1, puis i=0, j=2, etc …
On note le dernier coefficient non nul, soit K, et on transmet uniquement les K coefficients non nuls : le taux de compression du bloc est alors C=64/K
i=0
i=1
j=0 j=1 j=7 j
i=7
i
D(0,0) D(0,1) D(1,0) D(2,0) D(1,1) D(0,2) …
S.S.I.I. 2015-16, cours n°10 : Un principe de la compression d’imageS.S.I.I. 2015-16, cours n°10 : Un principe de la compression d’image Page Page 1313
Pour augmenter le taux de compression, il faut annuler les coefficients les plus faibles, ou augmenter le pas de quantification utilisé pour les coder en
binaire Compression par zonage : on décrit la matrice D
des coefficients en ‘zigzag’, et on annule les coefficients à partir d’une distance fixée :
à partir du second, pour i+j >0 (C=64)à partir du quatrième, pour i+j >1 (C=64/3)à partir du septième (C=64/6), etc …on peut procéder en multipliant D par la
matrice ci contre pour (i+j) > 2 Compression par seuil : D(abs(D)<seuil)=0; Compression par quantification : on crée une
matrice Q contenant un pas de quantification Q(i,j) pour chacun des coefficients D(i,j), par exemple en faisant : Q(i,j)= 1+ (i+j)*q
On fait la division entière de D par Q, soit Dq= floor(D./Q);
On comptabilise les K coefficients non nuls restants, et C=64/K
On décompresse en multipliant Dq par Q, puis en appliquant la DCT inverse
0,0
1 1 1 0 0 ..
1 1 0 0 ..
1 0 0 ..
0 0 ..
0 ..
..
i=0
i=1
j=0 j=1 j=7 j
i=7
i
1+q 1+q 1+2q …
1+q 1+2q … …
1+2q … … …
… … … …
Q
i=0
i=1
i=0
i=1
j=0 j=1
S.S.I.I. 2015-16, cours n°10 : Un principe de la compression d’imageS.S.I.I. 2015-16, cours n°10 : Un principe de la compression d’image Page Page 1414
Application à l’aide de Scilab : un exemple sur une image de niveaux de gris
// compressionTest.sceexec('quantzone.sci');// test de compressionfichier='cameraman.png';im=imread(fichier);imshow(im);// image de niveaux de grisimg=rgb2gray(im); // découper image 64x64 pixelsssim=imcrop(img,[96,32,64,64]);imshow(ssim)// format réel (0.0< intensité< 1.0)imd=im2double(ssim);imshow(imd)// ‘dct’ de blocs de 8x8 pixels// extraits de imd X=size(ssim,'c')Y=size(ssim,'r')D=zeros(X,Y);sim=[ ]dctim=[ ]for i=1:8:Y-1 for j=1:8:X-1 sim=imd(i:i+7,j:j+7); dctim=dct(sim); D(i:i+7,j:j+7)=dctim; endend
function [pas]=quanta(d, fq) // compression par quantification // quanta.sci pas=[]; for i=0:7 for j=0:7 pas(i+1,j+1)=1+fq*(i+j+1); end end endfunction
// affichage de D dans un plotX=size(D,'c'); Y=size(D,'r'); y=Y:-1:1; x=1: X; xset("colormap", jetcolormap(256)) grayplot(x, y, D, strf="041");colorbar(min(abs(D)), max(abs(D)))// quantification par zonage[Q,C]=quantzone(sim,6);ssimrec=zeros(X,Y);for i=1:8:Y-1 for j=1:8:X-1 sim=D(i:i+7,j:j+7); sim=sim.*Q; // ici on approxime dctim=dct(sim,1); // dct inverse ssimrec(i:i+7,j:j+7)=dctim; endendC // taux de compression// affichage de imd dans un plotX=size(ssimrec,'c') Y=size(ssimrec,'r') x=X:-1:1; y=1:Y; xset("colormap",graycolormap(256)) Sgrayplot(y,x,imd',strf="041");colorbar(0,1) // affichage de l’image décompresséescf(2);xset("colormap",graycolormap(256)) Sgrayplot(y,x,ssimrec',strf="041");colorbar(0,1)
function [pas, compr]=quantzone(q, zone) //compression par zonage : quantzone.sci H=size(q,'r'); L=size(q,'c'); pas=ones(H,L); zone=max(zone,1); zone=min(zone, 2*H); compr=H*L; for i=0:H-1 for j=0:L-1 if(i+j)>=zone, pas(i+1,j+1)=0; compr=compr-1; end end end compr=H*L/compr; endfunction
S.S.I.I. 2015-16, cours n°10 : Un principe de la compression d’imageS.S.I.I. 2015-16, cours n°10 : Un principe de la compression d’image
Illustration sur l’image 64x64 suivante tirée de ‘cameraman.jpg
Page Page 1515
Résultat avec la fonction [Q,C]=quantzone(sim, 6), C= 3.047
64x 64 Coefficients DCTssim=imcrop(img,[96,32,64,64]);
S.S.I.I. 2015-16, cours n°10 : Un principe de la compression d’imageS.S.I.I. 2015-16, cours n°10 : Un principe de la compression d’image Page Page 1616
Principe des codages RLE et VLC ( p. ex. code de Huffman)
1 2 3 0 0 0 0 0
2 3 0 0 0 0 0 0
3 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
Ici, la matrice des coefficients de Fourier décrite en zigzag vaut D=[1, 2 , 2, 3, 3, 3, 0, …, 0] avec 58 ‘0’ terminaux
RLE (pour Run Length Encoding) propose de coder ainsi la matrice des 64 coefficients :D= [<1> 1, <2> 2, <3> 3, <58> 0] soient 8 octets au lieu de 64en JPEG, on utilise même un caractère EoB au lieu du <58> 0 terminal
VLC (pour Variable Length Code), compte les occurrences de chaque code nécessaire et module le nombre de bits en fonction de la fréquence d’apparition des codes, par exemple
ici 0 apparaît 58 fois, 1 une fois, 2 deux fois et 3 trois fois on pourrait coder 0 sur deux bits, ‘1O’, puis 3 sur trois bits, ‘110’, 2 par ‘1110’ et 1 par
‘1111’ par exemple