approximés.
%%%%%%%%%%%%%%% Approximation Polygonale par des segments de droite %%%%%%
%%% Cette fonction effectue l'approximation polygonale par des segments %%%
%%% de droite. Elle appelle tab1 (liste de tous les pixels issus du %%%
%%% chaînage et tableaufin, liste de tous les pixels successifs formant %%%
%%% des segments de droites inférieurs à une erreur donnée. %%% %%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function tableauapprox = polygon (tab1,tableaufin,final)
figure(5);
imshow(final);
title('Approximation Polygonale par des Segments de Droites');
hold on;
axis ij;
grid;
%%%%%%calcul des dimensions de tab1 et tableaufin
[ligne,colonne]=size(tableaufin);
[lignetab,colonnetab]=size(tab1);
L=1; %%% L : indice de ligne sur tableaufin
while L
if (tableaufin(L,1)~=0)
indice1=tableaufin(L,7); %%% indice1 : indice de ligne sur tab1
indice2=tableaufin(L,8); %%% indice2 : indice de ligne sur tab1
nb=abs(indice1-indice2-1); %%% nombre de pixels du segment scruté
%%% seg : tampon contenant le segment issu de tab1
seg(1:nb,1:2)=tab1(indice1:indice2,1:2);
x1=tableaufin(L,1); %%% x1,x2,y1,y2 : extremités du segment
y1=tableaufin(L,2);
x2=tableaufin(L,3);
y2=tableaufin(L,4);
phin=tableaufin(L,5);
%%% appel de la fonction approximant cette chaine de pixels
[phi,d,x1,y1,x2,y2,d1] = approxdroite(seg, nb, x1, y1, x2, y2,phin);
if (x2~=x1 & phi~=pi/2) %% cas ou le segment est quelconque
xmin=min(x1,x2);
xmax=max(x1,x2);
x=xmin:.05:xmax;
y11=-(tan(phin)*x)+d/cos(phin);
y21=-(tan(phi)*x)+d1/cos(phi);
[a,b]=size(y11);
lim1=y11(a,1);
lim2=y11(a,b);
j=1;y3=0;
if (abs(lim1-y21(1,1))>5 | abs(lim2-y21(1,b))>5)
%%% cas ou le segment possède une pente quasi égale à pi/2
ymin=min(y1,y2);
ymax=max(y1,y2);
y31=ymin:.05:ymax;
[i1,j1]=size(y31);
x2=(y31-(d1/cos(phi)))/(-tan(phi));
figure(5);
plot(x2,y31,'r-');
tableauapprox(L,1)=x2(1);tableauapprox(L,2)=y31(1,1);
tableauapprox(L,3)=x2(j1);tableauapprox(L,4)=y31(1,j1);
tableauapprox(L,5)=phi;tableauapprox(L,6)=d1;
else %%% cas general
figure(5);
plot(x,y21,'r-');
tableauapprox(L,1)=x(1);tableauapprox(L,2)=y21(1,1);
tableauapprox(L,3)=x(b);tableauapprox(L,4)=y21(1,b);
tableauapprox(L,5)=phi;tableauapprox(L,6)=d1;
end
else %%% cas ou le segment est vertical
ymin=min(y1,y2);
ymax=max(y1,y2);
y=ymin:.05:ymax;
x2=(y-(d1/cos(phi)))/(-tan(phi));
figure(5);
plot(x2,y,'r-');
[i2,j2]=size(y);
tableauapprox(L,1)=x2(1);tableauapprox(L,2)=y(1,1);
tableauapprox(L,3)=x2(j2);tableauapprox(L,4)=y(1,j2);
tableauapprox(L,5)=phi;tableauapprox(L,6)=d1;
end
clear seg
end
L=L+1;
end
La fonction 'approxdroite' est utilisée pour approximer un nuage de pixel par une droite passant au plus près de chaque pixel.
%%%%%%%%%%%%% Approximation d'un nuage de pixel par une droite %%%%%%%%%%%
function [phi,d,x1,y1,x2,y2,d1]=approxdroite(seg, nb, x1, y1, x2, y2,phin)
%%%%%%%%%%%%%%%%%%% Coord théorique du segments par calcul de la droite
%%%%%%%%%%%%%%%%%%% passant par ces extremités
if (x1==x2)
phin = (pi/2);
else
phin = atan((y2-y1)/(x1-x2));
end
d = x1*sin(phin)+y1*cos(phin);
%%%%%%%%%%%%%%%%% coord approximées de la droite idéale passant
%%%%%%%%%%%%%%%%% au plus près de tous les pixels de la chaine
nb2=nb;
Vx = sum(seg(1:nb2,1))/nb2;
Vy = sum(seg(1:nb2,2))/nb2;
Vxx = 0;
Vyy = 0;
Vxy = 0;
for i=1:nb2
Vxx = Vxx + ((seg(i,1)-Vx)^2);
Vyy = Vyy + ((seg(i,2)-Vy)^2);
Vxy = Vxy + ((seg(i,1)-Vx)*(seg(i,2)-Vy));
end;
if (Vxx==Vyy)&(Vxy>0)
phi=-pi/4;
elseif (Vxx==Vyy)&(Vxy<0)
phi=pi/4;
elseif Vyy==0
phi = 0;
elseif Vxx==0
phi = pi/2;
else
if phin>-pi/4 & phin<0
phi = (0.5*atan(2*Vxy/(Vyy-Vxx)));
elseif phin>0 & phin
phi = (0.5*atan(2*Vxy/(Vyy-Vxx)));
elseif phin > pi/4 & phin
phi = (0.5*atan(2*Vxy/(Vyy-Vxx)))+pi/2;
elseif phin>pi/2 & phin<3*(pi/4)
phi = (0.5*atan(2*Vxy/(Vyy-Vxx)));
elseif phin<-pi/4 & phin>-pi/2
phi = (0.5*atan(2*Vxy/(Vyy-Vxx)))-pi/2;
elseif phin<-pi/2
phi = (0.5*atan(2*Vxy/(Vyy-Vxx)))+pi/2;
else
phi=phin;
end
end
if abs(phin-phi)>pi/3
phi=phi+pi/2;
end
d1 = (Vx*sin(phi)) + (Vy*cos(phi));
%%%% Calcul du facteur d'évaluation e1 pour le segment de droite %%%%
%%% calcul des paramètres cpt et longmax %%%%%%
%%% cpt : nombre de changements de signe de la séquence %%%%%%
%%% des vecteurs d'erreur %%%%%%
%%% longmax : longueur de la plus grande séquence de vecteurs %%%%%%
%%% d'erreurs ayant le même signe %%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
m=-tan(phi);% m: pente de la droite modélisés par les extremitès du seg
p=d1/cos(phi);
cpt=0;
long=1;
longmax=1;
for i=1:nb2-1
signe=sign(m*seg(i,1)+p-seg(i,2));
if sign(m*seg(i+1,1)+p-seg(i+1,2))~=signe
cpt=cpt+1;
long=1;
end
if sign(m*seg(i+1,1)+p-seg(i+1,2))==signe
long=long+1;
end
if longmaxlongmax=long;
end
end
e1=(cpt/nb)*(1-(longmax/nb));%facteur d'évaluation sur les seg de droite
La fonction 'approxcercle' est utilisée pour approximer un nuage de pixel par un arc de cercle passant au plus près de chaque pixel.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%% approx d'arc de cercles %%%%%%%%%%%%%%%%%%%%
%% fonction permettant d'approximer un arc de cercle à partir d'un nuage %
%% de pixels %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [a,b,r,cptc,longmaxc,P1,P2,tableaupixel]= approxcercle (seg)
hold on;
axis ij;
grid;
[li,co]=size(seg);
%%%%%%%%% Calcul du cercle approximé %%%%%%%%%%%%%%%%%%%%%%%%%%%
%
Ux = sum(seg(1:li,1)); %
Uy = sum(seg(1:li,2)); %
Uxx = sum(seg(1:li,1).*seg(1:li,1)); %
Uyy = sum(seg(1:li,2).*seg(1:li,2)); %
Uxy = sum(seg(1:li,1).*seg(1:li,2)); %
Uxxx = sum(seg(1:li,1).*seg(1:li,1).*seg(1:li,1)); %
Uxxy = sum(seg(1:li,1).*seg(1:li,1).*seg(1:li,2)); %
Uxyy = sum(seg(1:li,1).*seg(1:li,2).*seg(1:li,2)); %
Uyyy = sum(seg(1:li,2).*seg(1:li,2).*seg(1:li,2)); %
%%%% Calcul des paramètres A,B,C utilisés pour le calcul de %
%%%% l'équation (x-a)²+(y-b)²=r² où A=-2a, B=-2b, C=a²+b²-r² %
M = [Uxx Uxy Ux ; Uxy Uyy Uy ; Ux Uy li]; %
X = [-Uxxx-Uxyy -Uxxy-Uyyy -Uxx-Uyy]'; %
P = inv(M)*X; %
%
a=P(1)/(-2);% a= coord x du centre du cercle %
b=P(2)/(-2);% b= coord y du centre du cercle %
r=sqrt(a^2+b^2-P(3));% r= ryon du cercle %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% Calcul des points (x,y) constituant ce cercle %%%%%%%%
if (r~=inf & r<500 & imag(r)==0 & a~=inf)
xmin = a-r;% borne de calcul xmin
xmax = a+r;% borne de calcul ymin
i=1;
for x=xmin:0.1:xmax
Y(i)=r^2-(x-a)^2;%calcul de (y-b)²=r²-(x-a)²
i=i+1;
end
k=1;
for j=1:i-1
temp=(2*b-sqrt(4*Y(j)))/2;
temp2=(2*b+sqrt(4*Y(j)))/2;
if imag(temp)==0
yi(k)=temp;%calcul de y par rapport à (y-b)²=Y(i)
yii(k)=temp2;
xi(k)=xmin+(j-1)*0.1;
k=k+1;
end
end
%%% Création du tableau 'tableaupixel' contenant les coords
%%% (x,y) des points constituants le cercle approximé
XI=rot90(xi);
YI=rot90(yii);
tableaupixel=[xi' yi';xi(k-1) b; XI YI];
[lignetableau,colonnetableau]=size(tableaupixel);
tableaupixel(lignetableau+1,:)=tableaupixel(1,:);
lignetableau=lignetableau+1;
%plot(tableaupixel(:,1),tableaupixel(:,2),'k');
%%%% Calcul des pixels les plus éloignés de la chaine de pixel seg %%%
distmax=1;
for i=1:li
for j=1:li
dist=((abs(seg(i,1)-seg(j,1)))^2+(abs(seg(i,2)-seg(j,2)))^2);
if dist > distmax
indice1=i;
indice2=j;
distmax=dist;
end
end
end
x1=seg(indice1,1);
x2=seg(indice2,1);
y1=seg(indice1,2);
y2=seg(indice2,2);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%% calcul des points d'intersections entre cercle et droite %%%%
[phin,d] = coefdroite(x1,y1,x2,y2);
if (phin~=pi/2)%% cas ou la droite est quelconque
m=-tan(phin);%m:pente de la droite modélisée par les extremités du seg
p=d/cos(phin);%p:ordonnée à l'origine
%% résolution de (x-a)²+(y-b)²-r² avec y=m*x+p %%
c1=1+m^2;
c2=(-2*a)+(2*m*(p-b));
c3=a^2+p^2-2*p*b+b^2-r^2;
delta=((c2^2)-(4*(c1*c3)));
xi=(-c2-sqrt(delta))/(2*c1);
yi=m*xi+p;
xii=(-c2+sqrt(delta))/(2*c1);
yii=m*xii+p;
P1=[xi,yi];%% 1° intersection
P2=[xii,yii];%% 2° intersection
else %%% cas ou la droite est verticale
c1=1;
c2=-2*b;
c3=b^2+(x1-a)^2-r^2;
delta=((c2^2)-(4*(c1*c3)));
yi=(-c2-sqrt(delta))/(2*c1);
yii=(-c2+sqrt(delta))/(2*c1);
P1=[x1,yi];%% 1° intersection
P2=[x1,yii];%% 2° intersection
end
%plot(P1(1),P1(2),'go');
%plot(P2(1),P2(2),'go');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%% calcul des paramètres cptc et longmaxc %%%%%%%%%%%%%%%%%%%%%%
%%% cptc : nombre de changements de signe de la séquence %%%%%%
%%% des vecteurs d'erreur %%%%%%
%%% longmaxc : longueur de la plus grande séquence de vecteurs %%%%%%
%%% d'erreurs ayant le même signe %%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if imag(P1)==0 & imag(P2)==0%(imag(delta) == 0 &
cptc=0;
longc=1;
longmaxc=1;
for i=1:li-1
intersection = intersec (a,b,r,seg,li,i);
if intersection ==1
cptc=cptc+1;
longc=1;
end
if intersection ==0
longc=longc+1;
end
if longmaxc
longmaxc=longc;
end
end
e2=(cptc/nb)*(1-(longmaxc/nb));%facteur d'évaluation sur les seg de droite
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
else%% si pas d'intersection entre le cercle et la droite %%
a=0;b=0;r=0;longarc=0;cptc=0;
longmaxc=0;P1=0;P2=0;tableaupixel=0;
end
else%% si cercle avec rayon à partie imaginaire ou infinie
a=0;b=0;r=0;longarc=0;cptc=0;longmaxc=0;
P1=0;P2=0;tableaupixel=0;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
A.Chedebois : Traitements d'images appliqués à la supervision d'un processus d'usinage
500>0>
Dostları ilə paylaş: |