Sunteți pe pagina 1din 10

Extragerea contururilor unei regiuni

O regiune este un set de pixeli conectat în care toţi pixelii au aceeaşi intensitate/culoare.

Definiţii 1a: Doi pixeli sunt vecini direcţi (vecini-d) dacă celulele lor au o latură comună

Extragerea contururilor unei regiuni O regiune este un set de pixeli conectat în care toţi pixelii

. 1b: Doi pixeli sunt vecini indirecţi (vecini-i) dacă celulele lor se ating numai într-un colţ

Extragerea contururilor unei regiuni O regiune este un set de pixeli conectat în care toţi pixelii

.

1c: Termenul vecin-N, 0≤N≤7, desemnează un pixel aflat în poziţia N faţă de un pixel P, ca în figura de mai jos:

3 2 1 4 P 0 5 6 7
3
2
1
4
P
0
5
6
7

vecini-d sunt vecini-N, cu N=par vecini-i sunt vecini-N, cu N=impar

2a: O cale este o secvenţă de pixeli A 1 , A 2 ,…, A n , astfel încât:

pentru k>1, A k-1 este un vecin al lui A k pentru k<n, A k+1 este un vecin al lui A k

2b: O cale-d este o cale în care toţi pixelii sunt vecini-d. 2c: O cale simplă este o cale în care toţi pixelii sunt distincti şi nici un pixel nu are mai mult de 2 vecini-d în cale. 2d: O cale închisă este o cale în care primul pixel coincide cu ultimul.

3: Un set de pixeli, S, este conectat (sau conectat-i), dacă pentru fiecare pereche de pixeli A şi B din S, există o cale în care A şi B sunt primul şi ultimul element, iar toţi ceilalţi pixeli ai căii aparţin lui S. Termenul set de pixeli conectat-d are înţelesul care rezultă, adică între fiecare pereche de pixeli există o cale-d.

Reprezentarea contururilor

1

Curs SPG - Copyright © 2005 Prof. dr. ing. Florica Moldoveanu

1)

Prin adresele absolute ale pixelilor care-l compun, sau adresa primului urmata de adrese

2)

relative Prin cod Freeman = cod de înlănţuire absolut

3)

Prin cod de înlănţuire diferenţial

Cod Freeman (cod de înlănţuire)

Cod de înlănţuire diferenţial

Cod Freeman (cod de înlănţuire) Cod de înlănţuire diferenţial Valorile codului Freeman sunt Valorile codului diferential
Cod Freeman (cod de înlănţuire) Cod de înlănţuire diferenţial Valorile codului Freeman sunt Valorile codului diferential

Valorile codului Freeman sunt

Valorile codului diferential sunt

directie in pasul curent.

valori absolute.

valori relative.

Ele exprima schimbarea de

Exemplu:

Exemplu:

Codul Freeman pentru exemplu:

Codul de înlănţuire diferential

0, +1, -1, -2, +2, -3

0, 1, 0, 6, 0, 5 Sunt necesari 3biţi/pixel.

pentru exemplu:

Pentru un contur neted, in codul diferential predomina 0, +1, -1. De aceea, pentru reprezentarea unui contur prin cod diferenţial se poate folosi un număr diferit de biţi pentru fiecare direcţie, rezultând o medie de 2biţi/pixel:

0

0

+1

01

2

Curs SPG - Copyright © 2005 Prof. dr. ing. Florica Moldoveanu

-1

011

+2

0111

-2

01111

+3

011111

-3

0111111

4

01111111

Traversarea contururilor regiunilor

Conturul unei regiuni este traversat pe o cale închisă, fiind posibil întotdeauna să se aleagă o astfel de cale. Un pixel de contur este un pixel care are cel puţin un vecin-d în afara regiunii.

Pixelul de start se poate alege, de exemplu, scanând imaginea de sus în jos şi de la stânga la dreapta: el este un pixel care aparţine regiunii considerate (are intensitatea pixelilor regiunii) şi este pixel de contur.

Traversarea constă într-o deplasare pixel cu pixel, în fiecare pas fiind ales ca pixel următor pixelul din regiune care este cel mai în dreapta faţă de pixelul curent. În acest fel, interiorul regiunii se afla întotdeauna în stânga pixelului selectat (conturului).

-1 011 +2 0111 -2 01111 +3 011111 -3 0111111 4 01111111 Traversarea contururilor regiunilor Conturul

Cu aceasta regula de traversare, contururile exterioare sunt parcurse in sens trigonometric, iar cele interioare in sensul acelor de ceas.

Algoritm de extragere a unui contur

3

Curs SPG - Copyright © 2005 Prof. dr. ing. Florica Moldoveanu

Punctul de start se alege astfel încât vecinul său 4 să nu aparţină regiunii.

Alegerea se bazează pe cunoaşterea intensităţii pixelilor din regiune. Punctul de start ales poate fi un pixel izolat.

Notaţii:

S - pixelul de start

  • C - pixelul curent

  • D - direcţia de căutare a urmatorului pixel de contur, unde 0≤D≤7, iar direcţiile

sunt codificate astfel: 3 2 1 4 P 0 5 6 7
sunt codificate astfel:
3
2
1
4
P
0
5
6
7

urm - pixelul din vecinatatea celui curent, care ar putea fi următorul pixel de frontieră (contur)

contur = vector în care se memorează direcţia de deplasare în fiecare pas; în final se va obţine reprezentarea prin cod de înlănţuire (Freeman) a conturului traversat.

urm in R = true, daca urm aparţine regiunii R (are intensitatea pixelilor regiunii).

Operatiile

si Θ sunt operatii “modulo”. Astfel:

daca D=0 atunci D Θ 1 = 7

daca D=6 atunci

D

2 =0

Iniţial D=6.

În fiecare iteraţie se caută următorul punct de contur printre vecinii D Θ 1, D, D 1 ai pixelului curent.

Algoritmul se termină când pixelul curent este cel de start.

4

Curs SPG - Copyright © 2005 Prof. dr. ing. Florica Moldoveanu

Este posibil ca pixelul de start sa fie un punct izolat. De aceea, daca dupa trei iteratii nu s-a gasit un alt punct de contur, inseamna ca punctul de start este punct izolat.

Functia PunctContur prezentata in continuare primeste ca parametru punctul de contur curent si intoarce urmatorul punct de contur, sau punctul curent daca in vecinatatile D Θ 1, D,

D 1 nu se gaseste un punct de contur. Directia in care s-a gasit urmatorul punct de contur este memorata in vectorul contur.

unsigned char * contur; int n=0, D;

Punct PunctContur (Punct C) { Punct urm; urm = vecin(C, D Θ 1); if (urm in R) { contur[n++] = (unsigned char) (D Θ 1); D = D Θ 2; return urm;

}

urm = vecin(C, D); if (urm in R) { contur[n++] = (unsigned char)D; return urm;

}

urm = vecin(C, D 1); if (urm in R) { contur[n++] = (unsigned char)(D 1); return urm;

}

D = D return C; }

2;

Functia ExtrageContur primeste ca parametru punctul de start contur.

int ExtrageContur (Punct S) { Punct C = S; D = 6; // directia de cautare initiala

// cauta al doilea punct de contur

5

Curs SPG - Copyright © 2005 Prof. dr. ing. Florica Moldoveanu

for (int k = 0; k<3; k++) { C = PunctContur(C); if (C !=S) break; }

if( k==3) return 0; // S este punct izolat

// traverseaza conturul while( C != S) C = PunctContur(C); return 1;

}

Extragerea tuturor contururilor unei regiuni

Pentru simplificare, vom considera ca:

o

pixelii regiunii au intensitatea =1;

o

pixelii din afară au intensitatea =0

Acestea nu sunt restrictii, algoritmul prezentat in continuare putand fi generalizat.

O regiune poate avea mai multe contururi interioare care marginesc „gauri” ale regiunii.

for (int k = 0; k<3; k++) { C = PunctContur(C); if (C !=S) break; }

Se incepe cu extragerea conturului exterior, executand algoritmul „ExtrageContur” modificat astfel încât:

o

punctul de start să fie memorat într-un vector PStart

o

codurile de înlănţuire să fie memorate în vectorul contur, în care delimitarea contururilor se face prin valoarea 8 (adică 8=sfarsit contur)

6

Curs SPG - Copyright © 2005 Prof. dr. ing. Florica Moldoveanu

o

la traversarea unui contur, valoarea pixelilor conturului se incrementeaza, devenind 2 sau > 2 in cazul in care un pixel este parcurs de mai multe ori la traversarea conturului. In acest fel se pot recunoaste contururile deja traversate.

Functia ExtrageContur modificata pentru traversarea tuturor contururilor este:

Punct * PStart; int ncont=0; unsigned char ** Img;

int ExtrageContur (Punct S) { Punct C = S; D = 6; // directia de cautare initiala

// cauta al doilea punct de contur for (int k = 0; k<3; k++) { C = PunctContur(C); if (C !=S) break; }

if( k==3) return 0; // S este punct izolat

PStart[ncont++] = S; Img[S.y][S.x]++; // traverseaza conturul while( C != S) { Img[C.y][C.x]++ ; C = PunctContur(C); } contur[n++] = 8; return 1;

}

Dupa ce toate contururile au fost traversate, vectorul P va conţine punctele de start pentru toate contururile, iar vectorul contur va conţine lista codurilor de inlantuire pentru toate contururile, separate prin valoarea 8

Pasii algoritmului:

1)

Se extrage conturul exterior.

2)

Se caută un punct pe contur din care va începe parcurgerea regiunii pentru găsirea contururilor interioare.

7

Curs SPG - Copyright © 2005 Prof. dr. ing. Florica Moldoveanu

Parcurgerea regiunii are loc întotdeauna spre dreapta, de aceea punctul de start pentru parcurgere se alege de pe un arc coborâtor. Condiţia ca un punct sa fie punct de start parcurgere este:

o

codul punctului de contur anterior să fie cuprins între 4-7

o

codul punctului de contur curent să fie cuprins între 5-7

Parcurgerea regiunii are loc întotdeauna spre dreapta , de aceea punctul de start pentru parcurgere se

3)

Se parcurge regiunea din punctul de start determinat, spre dreapta, căutând fie un punct de

start pentru un contur interior, fie marginea regiunii (ieşirea din regiune).

Parcurgerea regiunii are loc întotdeauna spre dreapta , de aceea punctul de start pentru parcurgere se

Parcurgerea regiunii pe linia curenta se termină la întâlnirea secvenţei 120 sau 01.

Secventa 120 marcheaza intalnirea unui contur deja traversat.

Secventa 01 marcheaza intalnirea unui contur interior netraversat. In acest moment se termina parcurgerea liniei curente si se extrage conturul interior. Dupa extragere, pixelii conturului vor avea valoarea 2, deci, pe liniile imagine urmatoare el va fi identificat ca un contur deja parcurs prin intalnirea secventei 120.

Atunci cand un contur interior are pixeli comuni cu un alt contur (cel exterior sau unul interior), dupa traversarea sa pixelii comuni vor avea o valoare >2.

8

Curs SPG - Copyright © 2005 Prof. dr. ing. Florica Moldoveanu

Exemple: curs

Implementarea in C a algoritmului:

Punct * PStart; int ncont=0; unsigned char ** Img; unsigned char * contur; int n=0, D;

int ExtrageToateContururile(Punct S) {

int A, B, C, l, c, c0; int ks =0; Punct P, PS;

if( ! ExtrageContur(S)) return 0;

l=0;

c0 = 6; // codul punctului de contur anterior P = S; // punctul de contur anterior

while( l< n-1) // ! sfarsit lista coduri de contururi {

c = contur[l++]; //codul punctului de contur urmator

if( c==8) // start contur nou

{

c0 = 6; P = PStart[ks++]; c = contur[l++];

} else P = PunctUrm(P,c); // calculeaza adresa urmatorului punct //de contur

if( c0 >=4 && c0 <= 7 && c>=5 && c <= 7) // P este punct de start // parcurgere spre dreapta

9

Curs SPG - Copyright © 2005 Prof. dr. ing. Florica Moldoveanu

{ x = P.x; y = P.y; gata = 0; while( ! gata) { A = (int)Img[y][x]; B = (int)Img[y][x+1]; C = (int)Img[y][x+2]; if( A==0 && B==1 || A==0 && B==2 && C==0) { // B este punct de start contur interior PS.y = y; PS.x = x+1; ExtrageContur(PS); gata =1;

} else if( A==0 && B>2 && C==0 // contur interior deja parcurs || A==1 && B==2 && C==0) // contur exterior regiune { //sfarsit parcurgere linie gata = 1;

} x++; }// while (! gata)

} c0 = c; }//while (l<n-1) – sfarsit lista contururi return 1; }

OBSERVATIE In cadrul implementarii algoritmului nu au fost prevazute unele cazuri particulare, cum ar fi:

- iesirea din spatiul imaginii, in ciclul de parcurgere spre dreapta a imaginii - posibile configuratii de contururi interioare lipite intre ele sau de conturul exterior, care nu satisfac sabloanele utilizate pentru a depista un contur interior neparcurs sau unul deja parcurs

10

Curs SPG - Copyright © 2005 Prof. dr. ing. Florica Moldoveanu