TP MP* n°6 (SCILAB et MAPLE) SVD et traitements linéaires d'images

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 TP au format PDF et TEX.

Le fichier lena.csv contenant la matrice de taille 512x512 des niveaux de gris du visage de Lena.

Une proposition de corrigé:

SciLab
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))

courtesy of webmatter.de