Dans ce TP, des mathématiques concrètes vont nous permettre de réduire, agrandir, assombrir, éclaircir, compresser, bruiter, quantifier,... une photo. Pour cela, il existe des méthodes provenant de la théorie du signal et des mathématiques continues. Nous nous pencherons plutôt sur des méthodes plus légères basées sur l'algèbre linéaire et l'analyse matricielle. Une image sera pour nous une matrice carrée de taille $2^9$ à coefficients dans $\lbrack! | 0, 2^9-1| !\rbrack$. Cela manque de charme? C'est sans compter sur Lena qui depuis quarante ans rend les maths sexy (la population hantant les laboratoires mathématiques et surtout informatiques est plutôt masculine ...).
Nous étudierons pour cela la Décomposition en Valeurs Singulières qui apparaît de nos jours comme un couteau suisse des problèmes linéaires: en traitement de l'image et de tout signal en général, en reconnaissance des formes, en robotique, en statistique, en étude du langage naturel, en géologie, en météorologie, en dynamique des structures, en....
Dans quel domaine travaille-t-on alors: algèbre linéaire, analyse, probabilités, topologie,...? Un peu de tout cela et d'autres choses encore: cela s'appelle la mathématique.
Le fichier lena.csv contenant la matrice de taille 512x512 des niveaux de gris du visage de Lena.
Une proposition de corrigé:
funcprot(0); l = read('~/lena.csv',512,512); lena = l'; x = [1:512]; y = [512:-1:1]; xset('colormap',graycolormap(256)); isoview(0,512,0,512); //grayplot(x,y,lena) function M = retourne(m) n = length(m(1,:)); M = zeros(n,n); for i = 1:n for j = 1:n M(i,j) = m(i,n + 1 - j) end end endfunction function M = miroir(m) n = length(m(1,:)); M = zeros(n,n); for i = 1:n for j = 1:n M(i,j) = m(n + 1 - i,j) end end endfunction //grayplot(x,y,retourne(lena)) //grayplot(x,y,miroir(lena)) //grayplot(x,y,255-lena) function C = comp_svd(m,k) [U,S,V] = svd(m); V = V' n = length(m(1,:)); C = zeros(k,k); for p = 1:k C = C + S(p,p)*(U(1:k,p) * V(k,1:k)) end C = floor(C) endfunction //plot(x,diag(S)/S(1,1)) //grayplot(x,y,comp_svd(lena,50)) function R = resolution(m,k) n = floor(length(m(1,:))/k); R = zeros(n,n); for i = 1:n for j = 1:n R(i,j) = m(k*i,k*j) end end endfunction //clf(); //isoview(0,256,0,256); grayplot((1:512/2),(512/2:-1:1),resolution(lena,2)) function Q = quantification(m,k) Q = floor(m ./ k) endfunction //grayplot(x,y,quantification(lena,64)) //grayplot(x,y,quantification(lena,64)) function C = contraste(m,f) C = f(m) endfunction deff('[f] = f(x)', 'f = x .* x'); //deff('[f] = f(x)', 'f = floor(sqrt(x))'); //deff('[f] = f(x)', 'f = 255 - x'); //xset('colormap',graycolormap(512^2)); //grayplot(x,y,contraste(lena,sqrt)) //xset('colormap',graycolormap(512)); function F = fcontour(i,j,m) F = floor(sqrt((m(i,j-1)-m(i,j+1))^2 + (m(i-1,j)-m(i+1,j))^2)) endfunction function C = contour(m) n = length(m(1,:)); C = zeros(n,n); for i = 2:n-1 for j = 2:n-1 C(i,j) = 255 - fcontour(i,j,m) end end endfunction //grayplot(x,y,contour(lena)) function M = fmed(i,j,m,k) M = floor(median(m(i-k:i+k,j-k:j+k))) endfunction function C = mediane(m,k) n = length(m(1,:)); C = zeros(n,n); for i = 1+k:n-k for j = 1+k:n-k C(i,j) = fmed(i,j,m,k) end end endfunction //grayplot(x,y,mediane(lena,3)) function M = fmean(i,j,m,k) M = floor(mean(m(i-k:i+k,j-k:j+k))) endfunction function C = moyenne(m,k) n = length(m(1,:)); C = zeros(n,n); for i = 1+k:n-k for j = 1+k:n-k C(i,j) = fmean(i,j,m,k) end end endfunction //grayplot(x,y,moyenne(lena,3)) function B = bruit(m,ratio) n = length(m(1,:)); B = m + 75*grand(n,n,'bin',1,ratio/100) endfunction //grayplot(x,y,bruit(lena,20)) //grayplot(x,y,moyenne(bruit(lena,20),2))