1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
|
%% Nettoyage
clear all; close all; clc;
%% Définitions
TYPE = 'int32';
img = imread('peppers.tif');
img_ycbcr = rgb2ycbcr(img);
img_Y = int32(img_ycbcr(:,:,1));
H = numel(img_Y(:,1));
W = numel(img_Y(1,:));
mat = 1/159*[2,4,5,4,2;4,9,12,9,4;5,12,15,12,5;4,9,12,9,4;2,4,5,4,2];
% Filtrage de l'image de base afin de réduire le bruit de l'image
img_f = my_Filter(img_Y, mat);
%img_f = img_Y;
% Balayage de l'image pour filtrage
G_y = zeros(size(img_Y), TYPE);
G_x = zeros(size(img_Y), TYPE);
G = zeros(size(img_Y), TYPE);
G_max = zeros(size(img_Y), TYPE);
G_bin = zeros(size(img_Y), TYPE);
theta = zeros(size(img_Y), TYPE);
theta_p = zeros(size(img_Y), TYPE);
for ind_y = 2 : H-1
for ind_x = 2 : W-1
% Filtre de Sobel
% Application du filtre horozontal
G_x(ind_y, ind_x) = (...
+1*img_f(ind_y-1,ind_x-1) + 0*img_f(ind_y-1,ind_x) - 1*img_f(ind_y-1,ind_x+1) + ...
+2*img_f(ind_y ,ind_x-1) - 0*img_f(ind_y ,ind_x) - 2*img_f(ind_y ,ind_x+1) + ...
+1*img_f(ind_y+1,ind_x-1) + 0*img_f(ind_y+1,ind_x) - 1*img_f(ind_y+1,ind_x+1) );
% Application du filtre vertical
G_y(ind_y, ind_x) = (...
+1*img_f(ind_y-1,ind_x-1) + 2*img_f(ind_y-1,ind_x) + 1*img_f(ind_y-1,ind_x+1) + ...
0*img_f(ind_y ,ind_x-1) - 0*img_f(ind_y ,ind_x) + 0*img_f(ind_y ,ind_x+1) + ...
-1*img_f(ind_y+1,ind_x-1) - 2*img_f(ind_y+1,ind_x) - 1*img_f(ind_y+1,ind_x+1) );
% Calcul de l'angle du gradient
theta(ind_y, ind_x) = (180/pi)*atan2(double(G_y(ind_y, ind_x)), double(G_x(ind_y, ind_x)));
% Arrondi de l'angle pour obtenir une direction par palier de 45°
if (theta(ind_y, ind_x)>=0-22.5 && theta(ind_y, ind_x)<0+22.5) ...
|| (theta(ind_y, ind_x)>=180-22.5 && theta(ind_y, ind_x)<-180+22.5)
theta_p(ind_y, ind_x) = 0;
elseif (theta(ind_y, ind_x)>=45-22.5 && theta(ind_y, ind_x)<45+22.5) ...
|| (theta(ind_y, ind_x)>=-135-22.5 && theta(ind_y, ind_x)<-135+22.5)
theta_p(ind_y, ind_x) = 45;
elseif (theta(ind_y, ind_x)>=90-22.5 && theta(ind_y, ind_x)<90+22.5) ...
|| (theta(ind_y, ind_x)>=-90-22.5 && theta(ind_y, ind_x)<-90+22.5)
theta_p(ind_y, ind_x) = 90;
elseif (theta(ind_y, ind_x)>=135-22.5 && theta(ind_y, ind_x)<135+22.5) ...
|| (theta(ind_y, ind_x)>=-45-22.5 && theta(ind_y, ind_x)<-45+22.5)
theta_p(ind_y, ind_x) = 135;
end
% Module de G_x
if G_x(ind_y, ind_x) < 0
G_x(ind_y, ind_x) = -G_x(ind_y, ind_x);
end
% Module de G_y
if G_y(ind_y, ind_x) < 0
G_y(ind_y, ind_x) = -G_y(ind_y, ind_x);
end
% Calcul du gradient global
G(ind_y, ind_x) = G_x(ind_y, ind_x) + G_y(ind_y, ind_x);
%G(ind_y, ind_x) = sqrt(double(G_y(ind_y, ind_x)^2)+double(G_x(ind_y, ind_x)^2));
end
end
% Recherche des maximum locaux (Thinning)
G_max = G; % Recopie pour Debug
for ind_y = 2 : H-1
for ind_x = 2 : W-1
if theta_p(ind_y, ind_x) == 0
if G(ind_y, ind_x)<G(ind_y, ind_x-1) || G(ind_y, ind_x)<G(ind_y, ind_x+1)
G_max(ind_y, ind_x) = 0;
end
elseif theta_p(ind_y, ind_x) == 45
if G(ind_y, ind_x)<G(ind_y-1, ind_x-1) || G(ind_y, ind_x)<G(ind_y+1, ind_x+1)
G_max(ind_y, ind_x) = 0;
end
elseif theta_p(ind_y, ind_x) == 90
if G(ind_y, ind_x)<G(ind_y-1, ind_x) || G(ind_y, ind_x)<G(ind_y+1, ind_x)
G_max(ind_y, ind_x) = 0;
end
elseif theta_p(ind_y, ind_x) == 135
if G(ind_y, ind_x)<G(ind_y+1, ind_x-1) || G(ind_y, ind_x)<G(ind_y-1, ind_x+1)
G_max(ind_y, ind_x) = 0;
end
end
end
end
% Seuillage pour binarisation
max_G = max(max(G_max));
t_low = 0.0312*max_G;
t_high = 0.0781*max_G;
for ind_y = 2+1 : H-2 % décallage de 2 car matrice 5x5 dans le cas incertain test2
for ind_x = 2+1 : W-2
if G_max(ind_y, ind_x) < t_low
G_bin(ind_y, ind_x) = 0;
elseif G_max(ind_y, ind_x) >= t_high
G_bin(ind_y, ind_x) = 1;
else
% Recherche de valeur sup. à t_high dans ses 3x3 voisins
if G_max(ind_y-1, ind_x-1)>=t_high || G_max(ind_y-1, ind_x)>=t_high || G_max(ind_y-1, ind_x+1)>=t_high || ...
G_max(ind_y , ind_x-1)>=t_high || G_max(ind_y , ind_x+1)>=t_high || ...
G_max(ind_y+1, ind_x-1)>=t_high || G_max(ind_y+1, ind_x)>=t_high || G_max(ind_y+1, ind_x+1)>=t_high
G_bin(ind_y, ind_x) = 1;
elseif (G_max(ind_y-1, ind_x-1)>=t_low && G_max(ind_y-1, ind_x-1)<t_high) || ...
(G_max(ind_y-1, ind_x )>=t_low && G_max(ind_y-1, ind_x )<t_high) || ...
(G_max(ind_y-1, ind_x+1)>=t_low && G_max(ind_y-1, ind_x+1)<t_high) || ...
(G_max(ind_y , ind_x-1)>=t_low && G_max(ind_y , ind_x-1)<t_high) || ...
(G_max(ind_y , ind_x+1)>=t_low && G_max(ind_y , ind_x+1)<t_high) || ...
(G_max(ind_y+1, ind_x-1)>=t_low && G_max(ind_y+1, ind_x-1)<t_high) || ...
(G_max(ind_y+1, ind_x )>=t_low && G_max(ind_y+1, ind_x )<t_high) || ...
(G_max(ind_y+1, ind_x+1)>=t_low && G_max(ind_y+1, ind_x+1)<t_high)
% Si on est en zone incertaine ( t_low <= G < t_high)
% On test les voisins avec une matrice 5x5 (les voisins 3x3
% sont déjà testé.
if G_max(ind_y-2, ind_x-2)>=t_high || G_max(ind_y-2, ind_x-1)>=t_high || G_max(ind_y-2, ind_x)>=t_high || G_max(ind_y-2, ind_x+1)>=t_high || G_max(ind_y-2, ind_x+2)>=t_high || ...
G_max(ind_y-1, ind_x-2)>=t_high || G_max(ind_y-1, ind_x+2)>=t_high || ...
G_max(ind_y , ind_x-2)>=t_high || G_max(ind_y , ind_x+2)>=t_high || ...
G_max(ind_y+1, ind_x-2)>=t_high || G_max(ind_y+1, ind_x+2)>=t_high || ...
G_max(ind_y+2, ind_x-2)>=t_high || G_max(ind_y+2, ind_x-1)>=t_high || G_max(ind_y+2, ind_x)>=t_high || G_max(ind_y+2, ind_x+1)>=t_high || G_max(ind_y+2, ind_x+2)>=t_high
G_bin(ind_y, ind_x) = 1;
else
% Si aucun des 5x5 voisins n'est supérieur à t_high il
% ne s'agit pas d'un contour
G_bin(ind_y, ind_x) = 0;
end
else
% Si on est inférieur à t_low il ne sagit pas d'un contour
G_bin(ind_y, ind_x) = 0;
end
end
end
end
%% Affichage Canny
figure;
subplot(2,2,1);
imshow(img_f, [min(min(img_f)) max(max(img_f))]);
title('Image filtrée par un filtre passe bas');
subplot(2,2,2);
imshow(G, [min(min(G)) max(max(G))]);
title('Gradient de l''image');
subplot(2,2,3);
imshow(G_max, [min(min(G_max)) max(max(G_max))]);
title('Maximum du gradient (Thinning)');
subplot(2,2,4);
imshow(G_bin, [0 1]);
title('Application d''un seuil avec Hysthérésis');
%% Comparaison avec matlab
figure;
subplot(1,2,1);
imshow(edge(double(img_f), 'canny'), [0 1]);
title('Résultat Matlab');
subplot(1,2,2);
imshow(G_bin, [0 1]);
title('Résultat à BIBI'); |
Partager