FAQ MATLAB
FAQ MATLABConsultez toutes les FAQ
Nombre d'auteurs : 11, nombre de questions : 172, dernière mise à jour : 29 septembre 2022
- Comment convertir une image RGB en niveaux de gris ?
- Comment obtenir le symétrique d'une image ?
- Comment obtenir la transposée d'une image RGB ?
- Comment redimensionner une image ?
- Pourquoi imshow affiche une image toute blanche et/ou noire ?
- Comment travailler sur les blocs d'une image ?
- Comment décomposer/reconstituer une image selon ses canaux ?
Pour convertir une image RGB en une image en niveaux de gris, vous pouvez utiliser la fonction rgb2grayDocumentation de la fonction rgb2gray de l'Image Processing Toolbox.
Si vous ne possédez pas de cette Toolbox, vous pouvez utiliser la formule de conversion du standard NTSC pour le calcul de la luminance :
Intensité = 0.2989*rouge + 0.5870*vert + 0.1140*bleu
Ce qui donne avec MATLAB :
Im_gris = 0.2989 * rgb(:,:,1) + 0.5870 * rgb(:,:,2) + 0.1140 * rgb(:,:,3);
Lien : How do I convert my RGB image to grayscale without using the Image Processing Toolbox?
Le symétrique d'une image s'obtient en manipulant l'indexage de la matrice 2D (image indexée) ou 3D (image RGB).
%% Symétrie d'image 2D
figure('Name'
,'Symétrie d''image 2D'
,...
'numbertitle'
,'off'
)
load mandrill
colormap(map)
% Symétrie verticale
symV = X(end:-1:1,:);
% Symétrie horizontale
symH = X(:,end:-1:1);
% Symétrie première diagonale
symDiag1 = X.';
% Symétrie seconde diagonale
symDiag2 = X(end:-1:1,:);
symDiag2 = symDiag2.';
symDiag2 = symDiag2(end:-1:1,:);
% Image originale 2D
subplot(2,3,[1 4])
imagesc(X);
axis image off
title('Image originale 2D'
)
% Symétrie verticale
subplot(2,3,2)
imagesc(symV);
axis image off
title('Verticale'
)
% Symétrie horizontale
subplot(2,3,3)
imagesc(symH);
axis image off
title('Horizontale'
)
% Symétrie première diagonale
subplot(2,3,5)
imagesc(symDiag1);
axis image off
title('Première diagonale'
)
% Symétrie seconde diagonale
subplot(2,3,6)
imagesc(symDiag2);
axis image off
title('Seconde diagonale'
)
%% Symétrie d'image 3D
figure('Name'
,'Symétrie d''image 3D'
,...
'numbertitle'
,'off'
)
X = imread('ngc6543a.jpg'
,'jpg'
);
% Symétrie verticale
symV = X(end:-1:1,:,:);
% Symétrie horizontale
symH = X(:,end:-1:1,:);
% Symétrie première diagonale
symDiag1 = cat(3,X(:,:,1).',X(:,:,2).',X(:,:,3).');
% Symétrie seconde diagonale
symDiag2 = X(end:-1:1,:,:);
symDiag2 = cat(3,symDiag2(:,:,1).',symDiag2(:,:,2).',symDiag2(:,:,3).');
symDiag2 = symDiag2(end:-1:1,:,:);
% Image originale 3D
subplot(2,3,[1 4])
imagesc(X);
axis image off
title('Image originale 3D'
)
% Symétrie verticale
subplot(2,3,2)
imagesc(symV);
axis image off
title('Verticale'
)
% Symétrie horizontale
subplot(2,3,3)
imagesc(symH);
axis image off
title('Horizontale'
)
% Symétrie première diagonale
subplot(2,3,5)
imagesc(symDiag1);
axis image off
title('Première diagonale'
)
% Symétrie seconde diagonale
subplot(2,3,6)
imagesc(symDiag2);
axis image off
title('Seconde diagonale'
)
L'opérateur de transposition ne fonctionne que pour des matrices de dimension inférieure ou égale à 2.
Pour obtenir la transposée d'une image RGB, il faut donc faire la transposée de chaque composante (R,G et B) puis les concaténer.
% Image originale
img = rand(5,8,3);
% Image transposée
imgtr = cat(3, img(:,:,1).', img(:,:,2).', img(:,:,3).');
% Vérification
figure
subplot(2,1,1)
imagesc(img);
axis image
subplot(2,1,2)
imagesc(imgtr);
axis image
Une autre solution avec la fonction permuteDocumentation de la fonction permute :
imgtr = permute(img, [2 1 3]);
Il existe trois solutions pour changer les dimensions (en pixels) d'une image.
La première solution consiste à utiliser la fonction imresizeDocumentation de la fonction imresize contenue dans l'Image Processing Toolbox.
La deuxième solution utilise l'indexage des matrices. Puisqu'une image est une matrice 2D ou 3D (RGB), il est très simple de diminuer la taille d'une image en jouant sur l'indexage. Par exemple, pour diminuer par deux la taille d'une image 2D, il suffit de ne conserver qu'un pixel sur deux :
img = rand(150,200); % Une image 2D aléatoire
size(img)
ans =
150 200
img = img(1:2:end, 1:2:end);
size(img)
ans =
75 100
Pour une image 3D (RGB), le code devient :
img = rand(150,200,3); % Une image 3D (RGB) aléatoire
size(img)
ans =
150 200 3
img = img(1:2:end, 1:2:end,:);
size(img)
ans =
75 100 3
On remarque que cette solution utilisant l'indexage se limite à des facteurs de réduction/agrandissement entiers.
La troisième solution utilise les fonctions d'interpolation.
Soit interp2Documentation de la fonction interp2 pour diminuer par deux la taille d'une image 2D :
img = rand(150,200); % Une image 2D aléatoire
size(img)
ans =
150 200
[c,r] = size(img); % Récupération des 2 dimensions de l'image
[ci,ri] = meshgrid(1:2:r, 1:2:c); % Génération de la grille d'interpolation
img = interp2(img,ci,ri); % Interpolation des valeurs des pixels
size(img)
ans =
75 100
Soit interp3Documentation de la fonction interp3 pour diminuer par deux la taille d'une image 3D :
img = rand(150,200,3); % Une image 3D (RGB) aléatoire
size(img)
ans =
150 200 3
[c,r,p] = size(img); % Récupération des 3 dimensions de l'image
[ci,ri,pi] = meshgrid(1:2:r, 1:2:c, 1:p); % Génération de la grille d'interpolation
img = interp3(img,ci,ri,pi); % Interpolation des valeurs des pixels du plan R
size(img)
ans =
ans =
75 100 3
Les images sous MATLAB sont stockées le plus souvent sous le format uintX à la lecture avec la fonction imreadDocumentation de la fonction imread et converties en double ou single à fin de traitement. Mais il faut garder en tête que si le format uintX a ses valeurs dans l'intervalle [0 2^X-1], la conversion en double ou single doit se faire dans l'intervalle [0 1].
En conséquence si l'on rentre une image de type double ou single dans la fonction imshowDocumentation de la fonction imshow, celle-ci les considèrera dans cet intervalle [0 1] et il en résultera une saturation pour toute valeur en dehors de cet intervalle. Toute valeur supérieure à 1 sera ramenée à 1 (équivalent généralement au blanc); inversement toute valeur inférieure à 0 sera ramenée à 0 (équivalent généralement au noir).
Le plus souvent on aura :
-
fait un simple cast avec la fonction double
SélectionnezI = imread(…); I = double(I);
-
initialisé un tableau de type double et assigné des valeurs de type uintX
SélectionnezI = imread(…); J = zeros(size(I));
% paramètre classname non spécifié => double par défaut
J(i,j) = I(i,j)% Valeurs de I dans [0 255] directement converties en double
- effectué un traitement qui donne des valeurs qui sortent de cet intervalle.
Deux choix s'offrent alors :
-
Normaliser les valeurs dans l'intervalle [0 1] :
-
si les valeurs proviennent de valeurs de type uintX, une simple division par la valeur maximale du type d'origine suffit. Par exemple pour le type uint8 :
Sélectionnezimshow(I/255)
- sinon, si l'image a subi des traitements ou autres, voir Comment normaliser les valeurs d'une matrice dans l'intervalle [0 1] ?
-
-
Ajuster le deuxième argument de la fonction imshow :
Sélectionnezimshow(I,[])
% Ajuste l'intervalle [minimum maximum] selon celles de I
Note 1 : cette dernière manipulation ne marche que pour des images en niveaux de gris.
Note 2 : pour des images ne comportant qu'un seul niveau de gris, ce dernier point ne fonctionnera évidemment pas (minimum et maximum étant égaux). On pourra fixer alors « manuellement » les valeurs :Sélectionnezimshow(I, [minimum maximum])
% exemple : imshow(I, [0 255])
Il existe principalement deux procédés de traitement par blocs :
- Opération par blocs : on prélève un bloc et on retourne un bloc de même taille (ex. : DCT dans la compression JPEG) ;
- Opération par voisinage : on travaille sur le voisinage d'un pixel central pour obtenir sa « nouvelle » valeur (ex. : convolution).
Pour ce faire, on peut utiliser les simples boucles for ou la fonction blockprocDocumentation de la fonction blockproc (ou blkproc dans les versions antérieures à MATLAB R2009b) de l'Image Processing Toolbox.
-
Opération par blocs
Pour commencer, nous allons fixer les variables communes de départ :
SélectionnezIm
% Notre image de départ
blocSize = [8 8];% La taille des blocs qui seront traités
et notre fonction à appliquer sur chaque bloc :
Sélectionnezfunction
bloc_traite = traitement(bloc)Note : on supposera ici que la taille de l'image est un multiple de celle des blocs.
-
Méthode n° 1 : boucles for
Sélectionnezresultat = zeros(size(Im));
% preallocation de notre image résultante
% Suivant le type voulu, on ajoutera l'argument CLASSNAME de la fonction ZEROS qui est mis à DOUBLE par défaut
for
i = 1:blocSize(1):size(Im,1)for
j = 1:blocSize(2):size(Im,2) bloc = Im(i:i+blocSize(1)-1 , j:j+blocSize(2)-1);% Prélèvement du bloc
bloc_traite = traitement(bloc);% Traitement du bloc
resultat(i:i+blocSize(1)-1 , j:j+blocSize(2)-1) = bloc_traite;% Stockage du bloc résultat
end
end
-
Méthode n° 2 : fonction blkproc (versions antérieures à MATLAB R2009b)
Sélectionnezresultat = blkproc(Im, blocSize, @traitement);
-
Méthode n° 2 bis : fonction blockproc (à partir de MATLAB R2009b)
Cette nouvelle version passe une structure ayant les champs :
- block_struct.data : notre bloc à traiter MxN ou MxNxP selon l'image de départ ;
- block_struct.imageSize : la taille de l'image entière ;
- block_struct.location : la position [i j] (haut gauche) du bloc en cours de traitement (sans compter le bord ajouté par la propriété
'BorderSize'
) ; - block_struct.blockSize : la taille de notre bloc MxN (sans compter le bord ajouté par la propriété
'BorderSize'
) ; - block_struct.border : la taille des bords ajoutés avec la propriété
'BorderSize'
.
On adaptera alors notre fonction traitement en conséquence.
Sélectionnezresultat = blockproc(Im, blocSize, @traitement);
-
-
Opération par voisinage
Note : les effets de bord ne seront pas traités ici.
De même, nous fixons l'image de départ et la taille du voisinage :
SélectionnezIm
% Notre image de départ
borderSize = [1 1];% => bloc de 3x3
et notre fonction à appliquer sur chaque bloc :
Sélectionnezfunction
bloc_traite = traitement(bloc)-
Méthode n° 1 : boucles for
Sélectionnezresultat = zeros(size(Im));
% preallocation de notre image résultante
% Suivant le type voulu, on ajoutera l'argument CLASSNAME de la fonction ZEROS qui est mis à DOUBLE par défaut
for
i = borderSize(1)+1:size(Im,1)-borderSize(1)for
j = borderSize(2)+1:size(Im,2)-borderSize(2) bloc = Im(i-borderSize(1):i+borderSize(1) , j-borderSize(2):j+borderSize(2));% Prélèvement du bloc
pixel_res = traitement(bloc);% Traitement du bloc
resultat(i , j) = pixel_res;% Stockage du pixel résultat
end
end
-
Méthode n° 2 : fonction blkproc (versions antérieures à MATLAB R2009b)
Sélectionnezresultat = blkproc(Im, [1 1], borderSize ,@traitement)
% [1 1] désigne le pixel central.
-
Méthode n° 2 bis : fonction blockproc (à partir de MATLAB R2009b)
Sélectionnezresultat = blockproc(Im, [1 1], @traitement,...
'BorderSize'
,blocSize,...'TrimBorder'
,false);
-
Une image en vraies couleurs est stockée dans un tableau à trois dimensions MxNx3 :
- M correspond au nombre de lignes de l'image ;
- N correspond au nombre de colonnes de l'image ;
- et le 3 au nombre de canaux (Rouge-Vert-Bleu par exemple pour une image dans l'espace RVB ; RGB en anglais).
En supposant que l'image initiale de taille MxNx3 soit nommée rvb, sa décomposition se fait comme suit :
r = rvb(:,:,1);
v = rvb(:,:,2);
b = rvb(:,:,3);
et sa reconstitution à l'aide de la fonction catDocumentation de la fonction cat :
rvb = cat(3, r, v, b);
À noter que cette manipulation est évidemment applicable à n'importe quel espace couleur.