Annexe 4 : Listing du programme Matlab de la détection de PFCs par la méthode de Harris
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%% Calcul des PFCs par la méthode de harris %%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
close all
clear all
s = input('Fichier image initiale:','s');
image1=imread(s);
figure(1);
colormap(gray);
imshow(image1);
title('image source origine');
%%%% Définition de la fenêtre de calcul %%%%%
[a b] =ginput(2);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% elargissement de cette fenêtre de 2 pixels dans ttes %%
%%%% directions pour calcul des dérivées %%
ima=double(image1(fix(b(1)):fix(b(2)),fix(a(1)):fix(a(2))));
[tail1,tail2]=size(ima);
ima2(1:tail1+4,1:tail2+4)=0 ;
ima2(3:tail1+2,3:tail2+2)=ima;
ima1(1:tail1+4,1:tail2+4)=ima2(1:tail1+4,1:tail2+4);
clear ima2;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% acquisition du paramètre alpha %%%%%%%%%%
alpha = input('entrez la valeur de alpha :');%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%% Calcul des dérivées premières suivant x et y %%%%%%%%
yx = derivx(ima1,tail1,tail2,alpha); %
yy = derivy(ima1,tail1,tail2,alpha); %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% Calcul de l'opérateur de Harris R=det(C)-k*trace²(C) %%%
cpinit =(((yx.^2).*(yy.^2))-(yx.*yy)) -0.04*(yx.^2+yy.^2).^2;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
cp=cpinit(3:tail1+2,3:tail2+2);
%%%% calcul du seuil scp pour l'extraction des PFCs
scp=max(max((cpinit(4:tail1-3,4:tail2-3))))/250;
%[i1,j1]=find(cp==max(max(cp(3:tail1-2,3:tail2-2))));
%%%%% initialisation des variables
cpmax(1:tail1,1:tail2)=0;
cpmax1(1:tail1,1:tail2)=0;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Pour tous les PFCs détectés, inscription dans cpmax et cpmax1
[i,j]=find((cp>scp));
for t=1: size(i)
m=i(t);
n=j(t);
if ((m>4)&(n>4)&(m (cp(m,n-1)))...
&( (cp(m,n)) > (cp(m,n+1)))...
&( (cp(m,n)) > (cp(m-1,n)))...
&( (cp(m,n)) > (cp(m+1,n)))...
&( (cp(m,n)) > (cp(m-1,n-1)))...
&( (cp(m,n)) > (cp(m+1,n+1)))...
&( (cp(m,n)) > (cp(m+1,n-1)))...
&( (cp(m,n)) > (cp(m-1,n+1))))
cpmax(m,n)=256;
cpmax1(m,n)=cp(m,n);
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% Calcul du point de forte courbure maximum %%%%%%%%%%%%%
[i2,j2]=find(cpmax1==max(max(cpmax1(3:tail1-2,3:tail2-2))));%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% enregistrement dans matcr des coordonnées %%%%%%%%%%%%%%
%%%% des points de fortes courbures de la fenêtre %%%%%%%%%%%
[i3,j3]=find(cpmax>0); %
matcr = [fix(a(1))+j3-1,fix(b(1))+i3-1]; %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Affichage de la fenêtre sélectionnée et des PFCs %%%%%%%%
figure
imshow(cpmax,[1,256]);
title('PFCs détectés');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Affichage des PFCs sur l'image source %%%%%%%%%%%%%%%%%%%
figure
colormap(gray);
imshow(image1,[1,256]);
title('PFCs sur image source origine');
hold on
plot(matcr(:,1),matcr(:,2),'x')
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Annexe 5 : Listing du programme Matlab sur le chaînage et l'approximation polygonale de contours
%%%%%%%%%%%%% Chaînage des Contours %%%%%%%%%%
%%%%%%%%%%%%%% et découpage récursif des contours %%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% ce programme effectue un chaînage des pixels d'une image de contour %%
%%% il supprime les pixels isolés et amincie les contours %%
%%% il utilise un masque 3*3 gradué de 0 à 7 en fonction des directions %%
%%% privilégiées de déplacement du masque. ce masque subie une rotation %%
%%% dès que sa valeur d'orientation est supérieure à 2. %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clear all
close all
s = input('Fichier image initiale:','s');
ima = imread (s);
%définition de la méthode de chaînage : meth%
meth = input('\n 1:Rotation simple du masque - 2:Rotation améliorée:');
%visualisation de l'image source (image des contours)issue du filtrage%
figure;
imshow (ima);
title('Image Source');
ima1=ima;
[taily,tailx]=size(ima);
% taily : nb de ligne de ima et tailx : nb de colonne %
%%%% extension de l'image originale de 2 pixels dans les 4 directions %%%%
ima2(1:taily+4,1:tailx+4)=0 ;
ima2(3:taily+2,3:tailx+2)=ima1;
ima1(1:taily+4,1:tailx+4)=ima2(1:taily+4,1:tailx+4);
%%%%%% initialisation des 4 cas de figure possibles et de D%%%%%%%%%%%%%%%
F1=0;
F2=0;
F3=0;
F4=0;
D=0;
%%%initialisation du tableau de coord des pixels %%%
%chaine(1:1000000,1:2)=0;
%%% initialisation du masque en position 0 %%%
mask=rotation (0,meth);
cpt=1; %%% cpt : indicateur de ligne sur le tableau 'chaine' %%%
for y = 3 : taily+2
for x = tailx+2: -1 : 3
F1=0;
F2=0;
F3=0;
F4=0;
if (ima1(y,x)~=0) %%%%%%%%%tests des différentes configs%%%%%%%%%%%
if ima1(y,x-1)~=0
F1=1; %%%% prochain pixel voisin à gauche ? %%%%
end
if ima1(y+1,x-1)~=0
F2=1; %%%% prochain pixel voisin en bas à gauche ? %%%%
end
if ima1(y+1,x)~=0
F3=1; %%%% prochain pixel voisin en bas ? %%%%
end
if ima1(y+1,x+1)~=0
F4=1; %%%% prochain pixel voisin en bas à droite ? %%%%
end
end
if ((F1==1)|(F2==1)|(F3==1)|(F4==1))
ima1(y,x)=0; %effacement du premier pixel rencontré%
chaine(cpt,1)=x; %enregistrement du pixel dans le tableau chaine%
xpp=x; %xpp : tampon sur x%
chaine(cpt,2)=y; %enregistrement du pixel dans le tableau chaine%
ypp=y; %ypp: tampon sur y%
cpt = cpt+1;
if F1==1 & ima1(ypp,xpp-1)~=0 %%%%%% Cas 1 valide %%%%%%%
i=xpp-1;
j=ypp;
ima1(j,i)=0; %effacement du 2° pixel rencontré%
chaine(cpt,1)=i; %enregistrement des coords de ce pixel%
chaine(cpt,2)=j;
cpt = cpt+1; %incrementation de ligne sur chaine%
it=i; %it : tampon sur i%
jt=j; %jt : tampon sur j%
D=7; %position de D pour le cas de figure F1%
mask = rotation (D,meth);%inialisation du masque %
D=0; %initalisation de D%
ind=0;
while (D<=7)%test des differentes valeurs du tableau des
directions
if (D==0&(ima1(jt+mask(2,ind+1),it+
mask(1,ind+1)))~=0) ...
|(D==1&meth==1&(ima1(jt+mask(2,ind+1),it+
mask(1,ind+1)))~=0) ...
|(D==2&meth==1&(ima1(jt+mask(2,ind+1),it+
mask(1,ind+1)))~=0) ...
|(D==1&meth==2&(ima1(jt+mask(2,ind+1),it+
mask(1,ind+1)))~=0) ...
|(D==2&meth==2&(ima1(jt+mask(2,ind+1),it+
mask(1,ind+1)))~=0)
i= it + mask(1,ind+1);
j= jt + mask(2,ind+1);
ima1 (j,i)=0; %effacement du point%
chaine(cpt,1)=i;%enregistrement du point dans chaîne
chaine(cpt,2)=j;
cpt=cpt+1;
it=i;
jt=j;
ind=0;
else %%% test des pixels voisins en fonction
i=it+ mask(1,ind+1); %des priorités du masque utilisé
j=jt+ mask(2,ind+1); %pour les autres valeurs de D %%%
if ima1(j,i)~=0
ima1 (j,i)=0;
chaine(cpt,1)=i;
chaine(cpt,2)=j;
cpt=cpt+1;
xi=i-it;
yi=j-jt;
it=i;
jt=j;
if D>2 %%% rotation du masque si D>2 %%%%
D=mouvement(xi,yi,meth);%appel de la fonction
mouvement
mask=rotation(D,meth);%appel de la fonction
rotation
D=-1;
ind=-1;
end
end
D=D+1;
ind=ind+1;
end
end
chaine(cpt,1)=0;% séparation des segments dans chaine
chaine(cpt,2)=0;% par mise en place d'une ligne à 0
cpt=cpt+1;
elseif F2==1 & ima1( ypp+1,xpp-1)~=0 %%%%%% Cas 2 valide %%%%%%%
i=xpp-1;
j=ypp+1;
ima1(j,i)=0;
chaine(cpt,1)=i;
chaine(cpt,2)=j;
cpt = cpt+1;
it=i;
jt=j;
D=5;
mask = rotation (D,meth);
D=0;
ind=0;
while (D<=7)
if (D==0 & (ima1(jt + mask(2,ind+1),it +
mask(1,ind+1)))~=0) ...
|(D==1 & (ima1(jt + mask(2,ind+1),it +
mask(1,ind+1)))~=0) ...
|(D==2 & (ima1(jt + mask(2,ind+1),it +
mask(1,ind+1)))~=0) ...
| (D==1 & meth==2 & (ima1(jt + mask(2,ind+1),it +
mask(1,ind+1)))~=0) ...
|(D==2 & meth==2 & (ima1(jt + mask(2,ind+1),it +
mask(1,ind+1)))~=0)
i= it + mask(1,ind+1);
j= jt + mask(2,ind+1);
ima1 (j,i)=0;
chaine(cpt,1)=i;
chaine(cpt,2)=j;
cpt=cpt+1;
it=i;
jt=j;
ind=0;
else
i= it + mask(1,ind+1);
j= jt + mask(2,ind+1);
if ima1(j,i)~=0
ima1 (j,i)=0;
chaine(cpt,1)=i;
chaine(cpt,2)=j;
cpt=cpt+1;
xi=i-it;
yi=j-jt;
it=i;
jt=j;
if D>2
D= mouvement(xi,yi,meth);
mask = rotation (D,meth);
D=-1;
ind=-1;
end
end
D=D+1 ;
ind=ind+1;
end
end
chaine(cpt,1)=0;%séparation des segments dans chaine
chaine(cpt,2)=0;%par mise en place d'une ligne à 0
cpt=cpt+1;
elseif F3==1 & ima1(ypp+1,xpp)~=0 %%%%%% Cas 3 valide %%%%%%%
i=xpp;
j=ypp+1;
ima1(j,i)=0;
chaine(cpt,1)=i;
chaine(cpt,2)=j;
cpt = cpt+1;
it=i;
jt=j;
if meth==1
D=3;
else
D=1;
end
mask = rotation (D,meth);
D=0;
ind=0;
while (D<=7)
if (D==0 & (ima1(jt + mask(2,ind+1),it +
mask(1,ind+1)))~=0) ...
|(D==1 & (ima1(jt + mask(2,ind+1),it +
mask(1,ind+1)))~=0) ...
|(D==2 & (ima1(jt + mask(2,ind+1),it +
mask(1,ind+1)))~=0) ...
| (D==1 & meth==2 & (ima1(jt + mask(2,ind+1),it +
mask(1,ind+1)))~=0) ...
|(D==2 & meth==2 & (ima1(jt + mask(2,ind+1),it +
mask(1,ind+1)))~=0)
i= it + mask(1,ind+1);
j= jt + mask(2,ind+1);
ima1 (j,i)=0;
chaine(cpt,1)=i;
chaine(cpt,2)=j;
cpt=cpt+1;
it=i;
jt=j;
ind=0;
else
i= it + mask(1,ind+1);
j= jt + mask(2,ind+1);
if ima1(j,i)~=0
ima1 (j,i)=0;
chaine(cpt,1)=i;
chaine(cpt,2)=j;
cpt=cpt+1;
xi=i-it;
yi=j-jt;
it=i;
jt=j;
if D>2
D = mouvement(xi,yi,meth);
mask = rotation (D,meth);
D=-1;
ind=-1;
end
end
D=D+1;
ind=ind+1;
end
end
chaine(cpt,1)=0;% séparation des segments dans chaine
chaine(cpt,2)=0;% par mise en place d'une ligne à 0
cpt=cpt+1;
elseif F4==1 & ima1(ypp+1,xpp+1)~=0 %%%%%% Cas 4 valide %%%%%%%
i=xpp+1;
j=ypp+1;
ima1(i,j)=0;
chaine(cpt,1)=i;
chaine(cpt,2)=j;
cpt = cpt+1;
it=i;
jt=j;
if meth==1
D=1;
else
D=3;
end
mask = rotation (D,meth);
D=0;
ind=0;
while (D<=7)
if (D==0 & (ima1(jt + mask(2,ind+1),it +
mask(1,ind+1)))~=0) ...
|(D==1 & (ima1(jt + mask(2,ind+1),it +
mask(1,ind+1)))~=0) ...
|(D==2 & (ima1(jt + mask(2,ind+1),it +
mask(1,ind+1)))~=0) ...
| (D==1 & meth==2 & (ima1(jt + mask(2,ind+1),it +
mask(1,ind+1)))~=0) ...
|(D==2 & meth==2 & (ima1(jt + mask(2,ind+1),it +
mask(1,ind+1)))~=0)
i= it + mask(1,ind+1);
j= jt + mask(2,ind+1);
ima1 (j,i)=0;
chaine(cpt,1)=i;
chaine(cpt,2)=j;
cpt=cpt+1;
it=i;
jt=j;
ind=0;
else
i= it + mask(1,ind+1);
j= jt + mask(2,ind+1);
if ima1(j,i)~=0
ima1 (j,i)=0;
chaine(cpt,1)=i;
chaine(cpt,2)=j;
cpt=cpt+1;
xi=i-it;
yi=j-jt;
it=i;
jt=j;
if D>2
D = mouvement(xi,yi,meth);
mask = rotation (D,meth);
D=-1;
ind=-1;
end
end
D=D+1;
ind=ind+1;
end
end
chaine(cpt,1)=0;% séparation des segments dans chaine
chaine(cpt,2)=0;% par mise en place d'une ligne à 0
cpt=cpt+1;
end
end
end
end
%%%%%%%% Affichage des points non détectés %%%%%%%%%%%%%%%
figure; %
ima11(1:taily,1:tailx)=ima1(3:taily+2,3:tailx+2); %
imshow(ima11); %
title ('Points non détectés par chaînage'); %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% Affichage de l'image Résultante du chaînage %%%%%%%%%
figure; %
final1(1:taily+4,1:tailx+4)=0; %
for l=1:cpt-1 %
if (chaine(l,2)~=0 & chaine (l,1)~=0) %
final1(chaine(l,2),chaine(l,1))=256; %
end %
end %
final(1:taily,1:tailx)=final1(3:taily+2,3:tailx+2); %
imshow(final); %
title('Image après chaînage'); %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%% Remise à l'échelle (tailY,tailx) %%%%%%%%%%%%%%%
for h=1:cpt-2 %
if (chaine(h,2)~=0 & chaine (h,1)~=0) %
chaine(h,1) = chaine(h,1)-2; %
chaine(h,2) = chaine(h,2)-2; %
end %
end %
chaine=chaine(1:cpt-2,1:2); %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% appel de la fonction permettant la jonction des listes de pixels %%
%% ayant des coordonneées voisines et donc pouvant être jointes %%
tab1 = jonction (chaine,cpt); %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% appel de la fonction effectuant la segmentation récursive %%%%%%%%%
%% des contours à partir du tableau des coord pixels des contours %%%%
tableaufin = approximation(tab1); %%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% appel de la fonction effectuant l'approximation polygonale %%%%%%%%
%%%%%% de l'image par des segments de droite %%%%%%%%%%%%%
tableauapprox= polygon(tab1,tableaufin,final); %%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Les fonctions 'approximation' et 'polygon' sont détaillées dans les pages suivantes, la fonction approximation effectue la lecture du tableau contenant les coordonnées pixels des contours de l'image et découpe ces contours en fonction d'une erreur maximale entrée par l'opérateur.
La fonction polygon récupère toutes les coordonnées des segments obtenus et les stocke dans un tableau, elle effectue aussi l'affichage du résultat.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%% Approximation Polygonale par des segments de droite %%%%%%%%%%%%%%
%%%%%%%%% Récupération de tab (tableau des coordonnées %%%%
%%%%%%%%% pixels des différents contours de l'image) et découpage des %%%%
%%%%%%%%% contours en segments en fonction d'une erreur %%%%
%%%%%%%%% entrée par l'opérateur %%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function tableaufin= approximation (tab)
[L,C]=size(tab);
carac(1:L,1:6)=0;%% L : nb de ligne du tableau carac%
m=1;
Em = input('Entrer Erreur mini:');%distance mini du pixel au segment
Lm = input('Entrer Nb mini de pixels (sup a 1) :');%Lm:longueur mini
%% du segment
figure;
hold on;
axis ij; % passage dans un axe image (axe y inversé)
tab1(1:L+1,1:2)=0; % initialisation de tab1 : tableau tampon de tab
for i=1:L
tab1(i,1)=tab(i,1);
tab1(i,2)=tab(i,2);
end
pointeur = 1;
%%%%% Lecture du tableau 'tab' listant les coord pixels des contours %%%%%
while (pointeur<=L+1)
l=pointeur;
i=1;
while tab1(l,1)~=0 & tab1(l,2)~=0
%%%%%%%%%%% récupération de chaque segment dans un tampon :'seg'%%%%%
seg(i,1)=tab1(l,1);
seg(i,2)=tab1(l,2);
i=i+1; %i : indice de ligne sur seg%
l=l+1; %l : indice de ligne sur tab1%
end
nb=i-1; %nb de pixel se seg (== nb de ligne de seg%
%%%%%%%%%% Définition des extrémités du segment %%%%%%%%%%%%%%%%%%
if nb >= Lm %%%% chaque segments est séparé par une ligne de zéro%%%%
x1= seg(1,1); % x1 : coord x d'une des 2 extrémité du segment
y1= seg(1,2); % y1 : coord y d'une des 2 extrémités du segment
x2= seg(i-1,1); % x2 : coord x d'une des 2 extrémités du segment
y2= seg(i-1,2); % y2 : coord y d'une des 2 extrémités du segment
%%%%%%%%%%%%%%%% Calcul de la droite entre (x1,y1) et (x2,y2) %%%%%%
%%%%%%%%%%%%%%%% les coords des extrémités du segment %%%%%%%%%%%%%
[phin,d] = coefdroite(x1,y1,x2,y2);
x2p=x2; %%%% (x2p,y2p) : sommet final du segment
y2p=y2;
deb=1; % pointeur sur début de seg
fin=nb; % pointeur sur fin de seg
%%%%%% le cas 1 correspond à un segment parfaitement %%%%%%%%%%%%%%%%
%%%%%% vertical ou horizontal%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%% le cas 2 correspond à un segment quelconque %%%%%%%%%%%%%%%%%%
cas=0;a=0;z=0;
for k=1:nb-1 % test si segment parfaitement vertical %
if (seg(k,1)==seg(k+1,1) & k
a=a+1;
end
end
for k=1:nb-1 % test si segment parfaitement horizontal
if (seg(k,2)==seg(k+1,2) & k
z=z+1;
end
end
if (a==nb-1 | z==nb-1)
cas=1; % cas ou segment horizontal ou vertical %
else
cas=2; % cas ou segment quelconque %
end
if cas==1
% calcul des paramètres de la droite entre (x1,y1) et (x2,y2)%
[phin,d] = coefdroite(x1,y1,x2,y2); %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
carac(m,1)=x1;carac(m,2)=y1;
carac(m,3)=x2p;carac(m,4)=y2p;
carac(m,5)=phin;carac(m,6)=d;
elseif cas==2
s=0;cpt=0;
%%%%%%%% appel de la procédure de découpage récursif %%%%%%%%%%%%
[indice,carac,m,s]=decoupage(phin,d,seg,Em,deb,fin,Lm,nb,carac,m,s,cpt,pointeur);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
end
m=m+1; %variable nécessaire pour l'indiçage de carac%
end
pointeur=l+1;%incrementation du pointeur de ligne sur tab de la valeur l+1%
x1=0; %initialisation des variables correspondant au segment traiter%
x2=0;
y1=0;
y2=0;
x2p=0;
y2p=0;
nb=0;
d=0;
phi=0;
clear seg;
end
while (carac(L,1:8)==0 & L>1)
L=L-1;
end
caract(1:L,1:8)=carac(1:L,1:8);
caracteristique=carac;
%%%%%%%%%% ce passage supprime les segments redondants du tableau %%%%%%%%%
%%%%%%%%%% 'caracteristique' qui contient les caractéristiques %%%%%%%%%%%%
%%%%%%%%%% de tous les segments découpés. Il y a des segments %%%%%%%%%%%%%
%%%%%%%% redondants à cause de la récursivité de la fonction découpage %%%
[b,c]=size(caracteristique);%b:nb de ligne de caracteristique;c:nb colonnes
caracteristique(b+1,1:c)=0; %ajout d'une ligne à caracteristique%
l=1; %pointeur sur les lignes de tableaufin : tableau final des segments
ligne=1; %pointeur scrutant les lignes de caracteristique%
while (ligne
if caracteristique(ligne,1:4)~=0
%pointeur sur lignes de caracteristique définissant le début d'1 segment
pointeur=ligne;
%pointeur sur lignes de caracteristique définissant la fin d'un segment%
pointeurfin=0;
while caracteristique(ligne,1:4)~=0 & (ligne
ligne=ligne+1;
end
pointeurfin=ligne;
if pointeurfin-pointeur>2 %cas ou le segmentpère est définie par
%%plus d'un ou 2 segmentsfils (redondance
for i=pointeur:pointeurfin %sur la définition des segemntsfils)%
if caracteristique(i,1)~=0
for k=i+1:pointeurfin
if (caracteristique(i,1)==caracteristique(k,1) ...
& caracteristique(i,2)==caracteristique(k,2)) ...
| (caracteristique(i,3)==caracteristique(k,3) ...
& caracteristique(i,4)==caracteristique(k,4))
%effacement des lignes de caracteristique surperflux%
caracteristique(i,1:8)=0;
end
end
end
end
for i=pointeur:pointeurfin
if caracteristique(i,1:4)~=0%recopie des lignes intéressante
tableaufin(l,1:8)=caracteristique(i,1:8); ¨%dans tableaufin%
l=l+1; %incrémentation de l'indice de ligne sur tableaufin%
end
end
if pointeurfin~=b;
tableaufin(l,1:8)=0; %écriture d'une ligne à zéro ds tableaufin
l=l+1; % pour séparé les segments issus de segments différents%
end
else %cas ou le segmentpère est définie par un ou
for i=pointeur:pointeurfin % 2 segmentsfils (pas de redondance)
tableaufin(l,1:8)=caracteristique(i,1:8);
l=l+1;
end
ligne=pointeurfin+1;
end
else
ligne=ligne+1;
end
end
tableaufin;
%%%% Affichage graphique des segments du tableau final : tableaufin' %%%%%
for i=1:l-1 %
if tableaufin(i,1)~=0 %
line([tableaufin(i,1),tableaufin(i,3)],[tableaufin(i,2),tableaufin(i,4)]);
end %
end %
title('Estimation de l approximation polygonale par les droites'); %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
La fonction découpage est appelée par la fonction approximation, c'est elle qui, de façon récursive, découpe les segments de contours en fonction de l'erreur définie par l'opérateur.
%%%%%%%%%%%%% Procédure récursive de découpage %%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Ce programme découpe chaque segments en fonction de sa longueur mini Lm %
% et de l'écart de position entre la droite définie par les extrémités du %
% segment de base et chaque pixel appartenant à ce segment %
% phin : orientation de la droite , d : paramètre de la droite %
% seg : tableau contenant les coord des pixels du segment courant %
% Em : ecart mini entre position de la droite et pixel courant %
% Lm : longueur mini d'un segment, deb : indice de ligne sur tableau seg %
% fin : indice de ligne sur seg indiquant la fin d'un segment %
% carac : tableau contenant les caracteristiques des différents segments %
% découpés ou non, les 4premieres lignes indiquent les coords x,y des %
% extrémités du segments, ligne 5 et 6, les param phi et d du segment %
% ligne 7 et 8, les indices de lignes sur le tableau global 'tab' %
% m : indicateur de ligne sur carac, s et cpt : compteurs %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [indice,carac,m,s,cpt]= decoupage
(phin,d,seg,Em,deb,fin,Lm,nb,carac,m,s,cpt,pointeur)
%%%% calcul de l'erreur maxi par rapport à la droite et en chaque pixel %%
%%%% et comparaison de cette erreur avec l'erreur mini %%
maxE=0;
if (fin-deb)>=Lm %cas ou le segment est superieur au nb de pixel mini%
cpt=cpt+1;
for j1=deb+1:fin-1 %E1 : erreur calculée en chaque pixel%
E1=abs(seg(j1,2)+(tan(phin)*seg(j1,1))-(d/cos(phin)))/((1+(-
tan(phin))*(-tan(phin)))^0.5);
if (E1>Em) & (E1>maxE) %maxE : erreur maximale%
maxE=E1;
X=seg(j1,1); %X : coord du point ou l'erreur est maxi%
Y=seg(j1,2); %Y : coord du point ou l'erreur est maxi%
indice=j1; %indice de ligne
indic=indice;
else
indice=0;
end
end
%%%%découpage récursif et inscription des résultat dans le tableau carac %%
if maxE>Em %%%% cas ou l'erreur est supérieure à la limite %%%%%%%%%%%%%
x1= seg(deb,1); %definition du debut en x du segment%
y1= seg(deb,2); %definition du debut en y du segment%
%calcul des coeff du segment [(x1,y1),(X,Y)]
[phin,d] = coefdroite(x1,y1,X,Y);
%enregistrement du segment découpé dans le tableau carac
arac(m,1)=x1;carac(m,2)=y1;carac(m,3)=X;carac(m,4)=Y;carac(m,5)=phin;
carac(m,6)=d;carac(m,7)=pointeur+deb-1;carac(m,8)=pointeur+indic-1;
m=m+1;
x2p=seg(fin,1); %définition de la fin en x du segment%
y2p=seg(fin,2); %définition de la fin en y du segment%
%calcul des coeff. du segment [(X,Y),(x2p,y2p)]
[phin,d] = coefdroite(X,Y,x2p,y2p);
%enregistrement du segment découpé dans le tableau carac
carac(m,1)=X;carac(m,2)=Y;carac(m,3)=x2p;carac(m,4)=y2p;
carac(m,5)=phin;carac(m,6)=d;
carac(m,7)=pointeur+indic-1;carac(m,8)=pointeur+fin-1;
m=m+1;
indice1=m-s-2;%defintion des indices de ligne sur carac pour
indice2=m-s-1; %appliquer le nouveau découpage sur le bon segment%
i=1;
while seg(i,1)~=carac(indice1,1) | seg(i,2)~=carac(indice1,2)
i=i+1;
end
deb=i; %definition du nouveau debut de segment%
i=1;
while seg(i,1)~=carac(indice1,3) | seg(i,2)~=carac(indice1,4)
i=i+1;
end
fin=i; %définition de la nouvelle fin de segment%
phi=carac(indice1,5);
d=carac(indice1,6);
% nouvelle procédure de découpage sur segment fils%
[indice,carac,m,s,cpt] = decoupage
(phi,d,seg,Em,deb,fin,Lm,nb,carac,m,s,cpt,pointeur);
i=1;
while seg(i,1)~=carac(indice2,1) | seg(i,2)~=carac(indice2,2)
i=i+1;
end
deb=i; %définition du nouveau début de segment%
i=1;
while seg(i,1)~=carac(indice2,3) | seg(i,2)~=carac(indice2,4)
i=i+1;
end
fin=i; %définition de la nouvelle fin de segment%
phi=carac(indice2,5);
d=carac(indice2,6);
% nouvelle procédure de découpage sur segment fils%
[indice,carac,m,s,cpt]= decoupage
(phi,d,seg,Em,deb,fin,Lm,nb,carac,m,s,cpt,pointeur);
elseif maxE==0 & cpt==1;% cas ou l'erreur est inférieure à la limite %
s=s+1;%s:compteur du nb de cas ou l'erreur est < à l'erreur mini%
x1=seg(deb,1);%s est important car il permet de bien recalculer
y1=seg(deb,2);%indice1 et indice2%
x2p=seg(fin,1);
y2p=seg(fin,2);
carac(m,1)=x1;carac(m,2)=y1;carac(m,3)=x2p;
carac(m,4)=y2p;carac(m,5)=phin;carac(m,6)=d;
carac(m,7)=pointeur+deb-1;carac(m,8)=pointeur+fin-1;
m=m+1;
end
end
La fonction 'polygon' est appelée dans 'chainage' après la fonction 'approximation', c'est elle qui permet l'affichage du résultat et la récupération des caractéristiques des différents segments de contours découpés puis
Dostları ilə paylaş: |