21.07.2013 Views

Detektering og klassificering af kimplanter ved brug af computer vision

Detektering og klassificering af kimplanter ved brug af computer vision

Detektering og klassificering af kimplanter ved brug af computer vision

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

<strong>Detektering</strong> <strong>og</strong> <strong>klassificering</strong><br />

<strong>af</strong> <strong>kimplanter</strong> <strong>ved</strong> <strong>brug</strong> <strong>af</strong> <strong>computer</strong> <strong>vision</strong><br />

Afgangsprojekt:<br />

Kursus: 7. semester elektroteknol<strong>og</strong>i, data (E-AFP1)<br />

Periode: 01.09.2006 – 19.12.2006<br />

Gruppe 7E1:<br />

Anders Due Schwartz<br />

Kasper Broegaard Simonsen<br />

Mads Johannes Thorsted Nielsen<br />

Vejleder:<br />

John Immerkær<br />

Projekt udarbejdet <strong>ved</strong>:<br />

Syddansk Universitet<br />

Teknisk Fakultet<br />

Institut for Sensorer, Signaler <strong>og</strong> Elektroteknol<strong>og</strong>i


1 Indledning 1.1 Indledning<br />

Synopsis<br />

Problemstillingerne detektering <strong>og</strong> <strong>klassificering</strong> <strong>af</strong> <strong>kimplanter</strong> er begge forsøgt løst i projektet. For<br />

at detektere de enkelte kim er der udviklet algoritmer så de fritliggende kim identificeres, <strong>og</strong> deres<br />

placering samt orientering i planet findes. Til <strong>klassificering</strong>en er der identificeret fire<br />

kvalitetsparametre samt forskellige udvælgelsesmodeller. <strong>Detektering</strong>en <strong>af</strong> kim anses som løst,<br />

hvorimod <strong>klassificering</strong>en stadig har åbne problemstillinger.<br />

Forord<br />

Rapporten er skrevet som et <strong>af</strong>gangsprojekt på elektroingeniør data-retningen <strong>ved</strong> Det Tekniske<br />

Fakultet på Syddansk Universitet (SDU). Projektet er påbegyndt d. 1. september 2006 <strong>og</strong> er <strong>af</strong>sluttet<br />

d. 19. december 2006. Gruppen har h<strong>af</strong>t John Immerkær som vejleder.<br />

Projektet er en del <strong>af</strong> HiTec Elitetræer-projektet <strong>ved</strong> Robocluster, som er et kompetencenetværk i<br />

den syddanske region for robotter, intelligente mekaniske systemer <strong>og</strong> automationsteknol<strong>og</strong>iske løsninger.<br />

Selve HiTec Elitetræer-projektet omhandler: udvikling <strong>af</strong> nye robot- <strong>og</strong> visualiseringsteknol<strong>og</strong>ier<br />

til automatiseret planteproduktion.<br />

Hensigten med rapporten er at videregive løsninger, samt belyse eventuelle problemstillinger for<br />

styregruppen for HiTec Elitetræer-projektet <strong>og</strong> andre interesserede.<br />

Under udarbejdelsen <strong>af</strong> rapporten har det været nødvendigt at konsultere flere eksperter, der <strong>og</strong>så<br />

selv er tilknyttet HiTec Elitetræer-projektet: Jens Iver Find, biol<strong>og</strong> <strong>ved</strong> Københavns Universitet;<br />

Lars Sommer fra Vitroform A/S, samt projektleder for HiTec Elitetræer-projektet fra Robocluster<br />

Niels Korsager. Ydermere har gruppen samarbejdet med resten <strong>af</strong> styregruppen for HiTec<br />

Elitetræer-projektet.<br />

Odense d. 19. december 2006,<br />

Kasper B. Simonsen Mads T. Nielsen Anders D. Schwartz<br />

Side 1 <strong>af</strong> 131


1 Indledning 1.1 Indledning<br />

Læsevejledning<br />

Ho<strong>ved</strong>rapporten er overordnet opdelt i to dele:<br />

Del I: <strong>Detektering</strong> <strong>af</strong> <strong>kimplanter</strong> <strong>og</strong> Del II: Klassificering <strong>af</strong> <strong>kimplanter</strong>. Opdelingen udspringer<br />

direkte <strong>af</strong> overskriften for projektet. Overskrifterne dækker over hver deres opgave, som vil blive<br />

forsøgt løst i de to dele. Udover de to ho<strong>ved</strong>dele er der <strong>og</strong>så en række kapitler, der er fælles for<br />

begge dele. Der hvor der er funktionalitet, som er implementeret i C++, har kapitlerne fået samme<br />

navn, som den tilhørende C++-klasse. På denne måde er der skabt en direkte sammenhæng mellem<br />

rapport <strong>og</strong> det tilhørende produkt. Disse kapitler er bygget op som følgende:<br />

1. Indledning<br />

Kort introduktion til den opgave klassen skal løse<br />

2. Teori<br />

Her beskrives den teori, der skal til for at klassen kan løse opgaven<br />

3. Test<br />

Her beskrives, hvordan testen skal udføres samt testresultaterne<br />

4. Sammenfatning<br />

En kort konklusion der samler op på resultatet <strong>af</strong> testen, samt hvorvidt klassen løser<br />

opgaven som ønsket<br />

Kapitlerne uden for Del I <strong>og</strong> Del II <strong>af</strong>viger fra denne opbygning.<br />

Alle litteraturhenvisninger er skrevet på følgende måde: Forfatter [XX:YY]. Tallet på XX-pladsen angiver<br />

kildenummeret i litteraturlisten. YY angiver sidetallet i den respektive kilde.<br />

I Appendiks 18.1 Klasseoversigt s. 84 findes en klasseoversigt, der viser indholdet <strong>af</strong> klasserne et samlet<br />

sted. Ydermere er det muligt i Appendiks 18.9 Implementering s. 102 at læse, hvordan alle klasserne i<br />

rapporten er implementeret i C++-kode.<br />

DVD<br />

I løbet <strong>af</strong> rapporten vil der blive henvist til den <strong>ved</strong>lagte DVD. På denne findes kildekoden til<br />

pr<strong>og</strong>rammet, samt testbilleder, resultater <strong>og</strong> MatLab-scripts m.m. Henvises der i et kapitel til<br />

DVD’en, findes de relevante filer i det tilsvarende kapitel-bibliotek.<br />

Det udviklede pr<strong>og</strong>ram, kan findes på DVD’en i biblioteket ”Pr<strong>og</strong>ram”. Det er muligt i<br />

underbiblioteket ”Kildekode”, at finde kildekoden til pr<strong>og</strong>rammet. Kildekoden ligger i en mappe,<br />

der har navn efter følgende skabelon: ”Vision NNN III”, hvor NNN er det tre cifredekodeversionsnummer,<br />

<strong>og</strong> III er initialerne på den person, der har lavet den version. Inde i mappen<br />

er der yderligere to mapper:<br />

• Debug<br />

o Indeholder det eksekvérbare pr<strong>og</strong>ram<br />

• Vision<br />

o Indeholder selve C++-kildekoden<br />

I mange <strong>af</strong> kapitel-bibliotekerne findes der mapper, der indeholder testresultater samt den kildekode,<br />

der blev anvendt i testen.<br />

Side 2 <strong>af</strong> 131


1 Indledning 1.1 Indledning<br />

Indholdsfortegnelse<br />

1 Indledning ............................................... 5<br />

1.1 Indledning ............................................. 5<br />

1.2 Målformulering....................................... 5<br />

1.3 Kravspecifikation .................................... 6<br />

1.3.1 Del I: <strong>Detektering</strong> <strong>af</strong> <strong>kimplanter</strong> 6<br />

1.3.2 Del II: Klassificering <strong>af</strong> <strong>kimplanter</strong> 6<br />

1.3.3 Afgrænsning 6<br />

2 Opbygning <strong>og</strong> planlægning..................... 7<br />

2.1 Opbygning ............................................ 7<br />

2.1.1 Pr<strong>og</strong>ram 8<br />

2.2 Planlægning......................................... 10<br />

3 Beskrivelse <strong>af</strong> kim ................................. 11<br />

3.1 Indledning ........................................... 11<br />

3.2 Kim ..................................................... 11<br />

3.3 Miljø ................................................... 11<br />

3.4 Klassificering........................................ 12<br />

3.4.1 Første klasse – veldannede 12<br />

3.4.2 Anden klasse – lette misdannelser 12<br />

3.4.3 Tredje klasse – misdannede 12<br />

3.4.4 Fjerde klasse – abnorme 13<br />

3.5 Værdi.................................................. 13<br />

4 Kamera ................................................. 14<br />

4.1 Indledning ........................................... 14<br />

4.2 Tilgængelige kameraer.......................... 14<br />

4.2.1 Opløsning 15<br />

4.2.2 Afstand <strong>og</strong> linse 15<br />

4.3 Fire-i API.............................................. 15<br />

4.3.1 Fire-i ubCore 15<br />

4.3.2 WDM 15<br />

4.3.3 Implementering <strong>af</strong> Fire-i 15<br />

4.4 Sammenfatning .................................... 16<br />

Del I: <strong>Detektering</strong> <strong>af</strong> <strong>kimplanter</strong> 17<br />

5 Color ..................................................... 18<br />

5.1 Indledning ........................................... 18<br />

5.2 Teori ................................................... 18<br />

5.2.1 Koordinatsystem 18<br />

5.2.2 BMP-filer 18<br />

5.2.3 Billedtilgang 19<br />

5.3 Test ..................................................... 19<br />

5.3.1 Fremgangsmetode 19<br />

5.3.2 Testresultater 20<br />

5.4 Sammenfatning .................................... 20<br />

6 GrayScale.............................................. 21<br />

6.1 Indledning ........................................... 21<br />

6.2 Forskelle fra Color-klassen ..................... 21<br />

6.3 Konvertering fra farve- til gråtonebilleder. 21<br />

6.4 Test..................................................... 21<br />

6.4.1 Fremgangsmetode 21<br />

6.4.2 Testresultater 22<br />

6.5 Sammenfatning .................................... 22<br />

7 Binary ................................................... 23<br />

7.1 Indledning ........................................... 23<br />

7.2 Teori ................................................... 23<br />

7.2.1 Hist<strong>og</strong>ram 23<br />

7.2.2 Iterativ thresholding-teknik 24<br />

7.3 Test..................................................... 26<br />

7.4 Sammenfatning .................................... 27<br />

8 BlobDetection ........................................ 28<br />

8.1 Indledning ........................................... 28<br />

8.2 Teori ................................................... 28<br />

8.2.1 Knytning <strong>af</strong> pixels til subblobs 28<br />

8.2.2 Knytning <strong>af</strong> subblobs 29<br />

8.2.3 Blob sammensætning 30<br />

8.2.4 Boundingbox 30<br />

8.2.5 Seed generering 30<br />

8.3 Test..................................................... 30<br />

8.3.1 Deltest 1 31<br />

8.3.2 Deltest 2 32<br />

8.4 Sammenfatning .................................... 33<br />

9 EllipseApproximation ............................ 34<br />

9.1 Indledning ........................................... 34<br />

9.2 Teori ................................................... 34<br />

9.2.1 Massemidtpunkt 35<br />

9.2.2 Orientering i planet 35<br />

9.2.3 Vigtige tilfælde 36<br />

9.2.4 Bestemmelse <strong>af</strong> ellipseparametre 37<br />

9.3 Test..................................................... 38<br />

9.3.1 Beskrivelse 38<br />

9.3.2 Testresultater 40<br />

9.4 Sammenfatning .................................... 41<br />

Del II: Klassificering <strong>af</strong> <strong>kimplanter</strong> 43<br />

10 ExpandShrink 44<br />

10.1 Indledning ......................................... 44<br />

10.2 Teori ................................................. 44<br />

10.2.1 Expand 44<br />

10.2.2 Shrink 45<br />

10.2.3 Expand <strong>og</strong> Shrink 46<br />

10.3 Test................................................... 47<br />

10.3.1 expand() 47<br />

10.3.2 shrink() 47<br />

Side 3 <strong>af</strong> 131


1 Indledning 1.1 Indledning<br />

10.3.3 expand() <strong>og</strong> shrink() 47<br />

10.4 Sammenfatning .................................. 48<br />

11 TopDetection........................................ 49<br />

11.1 Indledning ......................................... 49<br />

11.2 Teori ................................................. 49<br />

11.2.1 Arealforskel 49<br />

11.3 Test ................................................... 51<br />

11.3.1 Testresultater 51<br />

11.4 Sammenfatning .................................. 53<br />

12 Symmetry............................................ 54<br />

12.1 Indledning ......................................... 54<br />

12.2 Teori ................................................. 54<br />

12.2.1 Rotation <strong>af</strong> pixels 56<br />

12.2.2 Bestemmelse <strong>af</strong> løsningsmodel 56<br />

12.3 Test ................................................... 57<br />

12.4 Sammenfatning .................................. 59<br />

13 Quality ................................................ 60<br />

13.1 Indledning ......................................... 60<br />

13.2 Teori ................................................. 60<br />

13.2.1 Bestemmelse <strong>af</strong> Kvalitetsparametre 60<br />

13.2.2 Manuel inspektion 61<br />

13.2.3 Bestemmelse <strong>af</strong> grænser 62<br />

13.2.4 Variable grænser 65<br />

13.3 Test ................................................... 65<br />

13.3.1 Første del 65<br />

13.3.2 Anden del 66<br />

13.4 Sammenfatning .................................. 68<br />

14 Implementering ................................... 69<br />

14.1 Indledning ......................................... 69<br />

14.2 Valg <strong>af</strong> implementeringsmiljø ............... 69<br />

14.3 Pr<strong>og</strong>ramstruktur .................................. 69<br />

14.3.1 Vision.cpp 69<br />

14.4 User interface..................................... 72<br />

15 Sammenfatning ................................... 73<br />

15.1 Samlet test ......................................... 73<br />

15.1.1 Fremgangsmetode 73<br />

15.1.2 Test 1 – detektering <strong>af</strong> kim 73<br />

15.1.3 Test 2 – <strong>klassificering</strong> 73<br />

15.1.4 Test 3 – User interface 75<br />

15.2 Diskussion ......................................... 77<br />

15.3 Konklusion......................................... 78<br />

15.3.1 Del I: <strong>Detektering</strong> <strong>af</strong> <strong>kimplanter</strong> 78<br />

15.3.2 Del II: Klassificering <strong>af</strong> <strong>kimplanter</strong> 78<br />

15.4 Videreudvikling .................................. 79<br />

15.4.1 Kamera 79<br />

15.4.2 EllipseApproksimation 80<br />

15.4.3 TopDetection 80<br />

15.4.4 Quality 80<br />

15.4.5 Implementering 81<br />

16 Litteraturliste ....................................... 82<br />

17 Ordliste ............................................... 83<br />

18 Appendiks........................................... 84<br />

18.1 Klasseoversigt .................................... 84<br />

18.2 Projektoplæg...................................... 87<br />

18.3 Procesbeskrivelse................................ 87<br />

18.4 Tidsplan ............................................ 88<br />

18.5 Orientering i planet ............................ 89<br />

18.6 Bestemmelse <strong>af</strong> ellipseparametre .......... 91<br />

18.7 Valg <strong>af</strong> TopDetection-algoritme ............ 93<br />

18.7.1 Brainstorm 93<br />

18.7.2 Rating <strong>af</strong> idéer 97<br />

18.8 Kodestandard .................................... 99<br />

18.8.1 Indledning 99<br />

18.8.2 Navngivning 99<br />

18.8.3 Udseende 100<br />

18.8.4 Pr<strong>og</strong>rammeringsregler 101<br />

18.9 Implementering ................................ 102<br />

18.9.1 Color 102<br />

18.9.2 Binary 103<br />

18.9.3 Seed 105<br />

18.9.4 BlobDetection 106<br />

18.9.5 EllipseApproximation 109<br />

18.9.6 ExpandShrink 111<br />

18.9.7 TopDetection 114<br />

18.9.8 Symmetry 116<br />

18.9.9 Quality 117<br />

18.9.10 Draw 121<br />

18.9.11 Utilities 122<br />

18.10 Test <strong>af</strong> Binary................................. 124<br />

18.11 Test <strong>af</strong> TopDetection........................ 127<br />

18.11.1 Billede 1 127<br />

18.11.2 Billede 2 128<br />

18.11.3 Billede 3 130<br />

Side 4 <strong>af</strong> 131


1 Indledning 1.1 Indledning<br />

1 Indledning<br />

1.1 Indledning<br />

Dette <strong>af</strong>gangsprojekt skal indgå som en del <strong>af</strong> det større projekt HiTec Elitetræer, som har til formål<br />

at klone juletræer (<strong>og</strong> andre træer på længere sigt). Ved at anvende kloning skabes en stabil<br />

produktion <strong>af</strong> planter <strong>af</strong> høj, ensartet kvalitet, der samtidigt øger den gennemsnitlige salgspris pr.<br />

produceret træ, da planterne vil have meget ens arvelige egenskaber. Det er altså muligt at begrænse<br />

den tilfældighed der spiller ind, når juletræer plantes i naturen på traditionel vis. Det vurderes, at der<br />

er store økonomiske gevinster <strong>ved</strong> at producere juletræer på denne måde.<br />

Gruppen skal indgå i arbejdet på HiTec Elitetræer med det formål at udvikle <strong>computer</strong>algoritmer,<br />

der <strong>ved</strong> hjælp <strong>af</strong> <strong>computer</strong><strong>vision</strong> kan identificere <strong>og</strong> klassificere samt kvalitetsvurdere <strong>kimplanter</strong>.<br />

Det er ikke endeligt <strong>af</strong>gjort, om <strong>klassificering</strong>en skal anvendes, på det stadie gruppen skal<br />

implementere sin løsning i processen, men gruppen skal under alle omstændigheder udvikle metoder<br />

til at løse <strong>klassificering</strong>en.<br />

I den samlede beplantningsproces vil gruppens arbejde indgå relativt tidligt i forløbet. Indledende<br />

skal <strong>kimplanter</strong>ne klones i et næringsmedium. Herefter skal de tages ud <strong>af</strong> næringsmediet, <strong>og</strong> der<br />

foretages yderligere modning <strong>af</strong> kimene. Det er efter denne modningsperiode, at gruppen skal<br />

identificere <strong>og</strong> klassificere <strong>kimplanter</strong>ne. Efter kimene er blevet lokaliseret skal de placeres i et nyt<br />

vækstmedie, hvor de skal modnes yderligere. Herefter er de spiret kr<strong>af</strong>tigt, <strong>og</strong> en ny<br />

<strong>computer</strong><strong>vision</strong>proces skal udvælge de kim, der skal anvendes i den egentlige <strong>og</strong> traditionelle<br />

beplantningsproces. Dette sidste trin håndteres <strong>af</strong> firmaerne T&O Stelectric A/S <strong>og</strong> Bila A/S.<br />

1.2 Målformulering<br />

Formålet med projektet er at arbejde med <strong>og</strong> udvikle <strong>vision</strong>systemer.<br />

Det er gruppens opgave, at fremstille et system der <strong>ved</strong> hjælp <strong>af</strong> visualiseringsteknol<strong>og</strong>i kan<br />

lokalisere kimene i vækstmediet, således de kan indgå i en udplantningsprocess. Der skal anvendes et<br />

kamera, der tager et billede <strong>af</strong> vækstmediet med kimene i. Dette billede skal derefter processeres i en<br />

<strong>computer</strong> med algoritmer udviklet <strong>af</strong> gruppen. Det er målet med algoritmerne at danne en snitflade,<br />

hvor en robot vil kunne tilkobles <strong>computer</strong>systemet. Robotten vil kunne modtage information om<br />

kimenes placering <strong>og</strong> orientering i vækstmediet. Det er kun gruppens opgave at bestemme placering<br />

<strong>og</strong> orientering, men ikke at håndtere en eventuel robot.<br />

Generelt vil gruppen danne en forsøgsopstilling til fot<strong>og</strong>r<strong>af</strong>ering <strong>af</strong> <strong>kimplanter</strong>, der vil have en sort<br />

baggrund, med en uniform belysning <strong>af</strong> baggrunden. Derudover vil gruppen undersøge, udvikle <strong>og</strong><br />

pr<strong>og</strong>rammere algoritmer der kan identificere kimenes placering <strong>og</strong> orientering i vækstmediet.<br />

Gruppen får stillet kamera <strong>og</strong> <strong>computer</strong> til rådighed til opgaven.<br />

Side 5 <strong>af</strong> 131


1 Indledning 1.3 Kravspecifikation<br />

1.3 Kravspecifikation<br />

1.3.1 Del I: <strong>Detektering</strong> <strong>af</strong> <strong>kimplanter</strong><br />

1. Indlæse billede fra disk<br />

a. Kunne modtage billede i 3x8-bit RGB BMP-format<br />

2. Kunne identificere <strong>kimplanter</strong><br />

a. Enkelte fritliggende<br />

b. Deres placering <strong>og</strong> længdeaksers orientering i planet<br />

c. Ikke fritliggende <strong>kimplanter</strong> accepteres d<strong>og</strong> <strong>og</strong> sorteres evt. fra i kvalitetsvurderingen<br />

1.3.2 Del II: Klassificering <strong>af</strong> <strong>kimplanter</strong><br />

3. Kvalitetsvurdering<br />

a. Det skal bestemmes hvilke parametre, der skal <strong>brug</strong>es til at udvælge godkendte <strong>og</strong><br />

ikke-godkendte kim med<br />

b. Det skal være muligt kun at udvælge alle 1. klasses <strong>kimplanter</strong> vha. de parametre angivet<br />

i punkt a.<br />

c. Det skal være muligt med algoritmer at udvælge kim hvis parametre falder indenfor<br />

<strong>brug</strong>erspecificerede grænser<br />

d. Projektet skal som resultat outputte x,y koordinat i pixels (på kimplantens midtpunkt)<br />

<strong>og</strong> θ (vinkel i forhold til det vandrette plan) på de <strong>kimplanter</strong> der ligge inden<br />

for grænserne<br />

4. User Interface<br />

a. Konsol baseret<br />

b. Bruger skal kunne sætte grænser for kvalitetsparametre<br />

1.3.3 Afgrænsning<br />

5. Afgrænsning<br />

a. Kimplanter i grupper vil ikke blive forsøgt separeret i pr<strong>og</strong>rammet<br />

b. Systemet skal kun understøtte en mørk baggrund <strong>og</strong> lys forgrund<br />

c. Der må ikke være n<strong>og</strong>en betydelig variation i billedets belysning<br />

Side 6 <strong>af</strong> 131


2 Opbygning <strong>og</strong> planlægning 2.1 Opbygning<br />

2 Opbygning <strong>og</strong> planlægning<br />

2.1 Opbygning<br />

Formålet med <strong>af</strong>snittet er, at give et overblik over hvordan det samlede system skal bygges op.<br />

Overordnet set skal der laves et system, der består <strong>af</strong> et kamera <strong>og</strong> en <strong>computer</strong>. Computeren skal<br />

interfaces med kameraet, som skal tage billeder <strong>af</strong> kimene. Billederne overføres fra kameraet til<br />

<strong>computer</strong>en, <strong>og</strong> på <strong>computer</strong>en <strong>af</strong>vikles et pr<strong>og</strong>ram, som har til formål at analysere billedet. I<br />

projektet skal der laves en forsøgsopstilling, der ikke er optimeret, så den kan indgå i produktionssammenhæng.<br />

Der skal laves et pr<strong>og</strong>ram, der har til formål at analysere kimene i billedet. Dette skal skrives i C++,<br />

da det vurderes at være hurtigt i <strong>af</strong>viklingen <strong>af</strong> koden <strong>og</strong> er objekt-orienteret. Samtidigt har gruppen<br />

erfaring med C++, <strong>og</strong> på den måde undgås det at <strong>brug</strong>e tid på den overhead, der ligger i at lære nye<br />

spr<strong>og</strong>. MatLab vil <strong>brug</strong>es til at supplere i opbygning <strong>og</strong> debugging <strong>af</strong> algoritmer, hvor det findes<br />

nødvendigt. Gruppen skal udvikle, undersøge <strong>og</strong> pr<strong>og</strong>rammere alle algoritmer, der kan være relevante<br />

i løsning <strong>af</strong> opgaven. Ydermere skal der <strong>og</strong>så udvikles et user interface, hvor en <strong>brug</strong>er kan ændre<br />

indstillinger <strong>og</strong> se resultater fra pr<strong>og</strong>rammet. Interfacet skal være konsolbaseret <strong>og</strong> kun implementere<br />

de mest simple funktionaliteter. Det er ikke gruppens fokus at udarbejde et avanceret GUI.<br />

Kamera<br />

Figur 2.1<br />

Generel opbygning<br />

FireWire<br />

protokol<br />

Computer:<br />

Afvikling <strong>af</strong><br />

C++-pr<strong>og</strong>ram<br />

Det er <strong>af</strong>talt, sammen med vejleder, at anvende et<br />

kamera, der benytter FireWire-protokollen. Samtidigt<br />

anvendes der software <strong>af</strong> navnet ”Fire-i API”.<br />

Denne software kan interface med kameraer, der<br />

anvender FireWire-protokollen (figur 2.1). Fordelen<br />

<strong>ved</strong> at anvende dette kamera, er at det er muligt at<br />

tilgå kamer<strong>af</strong>unktioner, som f.eks. at tage et billede,<br />

direkte via et API i skrevet i C++.<br />

Gruppen tildeles indledende et 640x480 pixel S/Hkamera,<br />

som kan anvendes til opsætnings- <strong>og</strong><br />

interfacing-test med Fire-i API. Gruppen vil d<strong>og</strong><br />

senere i projektforløbet blive tildelt et 1280x960 pixel farve-kamera, som forventes at være det<br />

primære kamera.<br />

Side 7 <strong>af</strong> 131


2 Opbygning <strong>og</strong> planlægning 2.1 Opbygning<br />

2.1.1 Pr<strong>og</strong>ram<br />

I projektets begyndelse er pr<strong>og</strong>rammets vigtigste komponenter blevet bestemt i samarbejde med<br />

vejleder. Årsagen til dette er, at gruppen har en meget begrænset viden inden for <strong>computer</strong> <strong>vision</strong>.<br />

Senere i forløbet har gruppen tilføjet komponenter <strong>og</strong> processer, som har vist sig at være<br />

nødvendige for pr<strong>og</strong>rammet. Der er ikke lavet en metodisk gennemgang <strong>af</strong> alternative<br />

sammensætninger <strong>af</strong> algoritmer <strong>og</strong> pr<strong>og</strong>ramkonstruktioner, da dette blev vurderet som værende for<br />

stor en opgave, set i lyset <strong>af</strong> gruppens begrænsede tid i projektet. Pr<strong>og</strong>ramstrukturen er blevet<br />

bestemt til at være følgende (figur 2.2):<br />

1. I Del I skal pr<strong>og</strong>rammet<br />

kunne loade et farvebillede<br />

ind fra harddisken. Dette er<br />

nødvendigt, for at kunne<br />

udvikle på pr<strong>og</strong>rammet, uden<br />

at der anvendes kamera.<br />

Billedet skal kunne gøres<br />

tilgængeligt for alle andre<br />

dele <strong>af</strong> pr<strong>og</strong>rammet, som<br />

kan have <strong>brug</strong> for tilgang til<br />

det. Det skal på samme<br />

måde være muligt, at hente<br />

billedet direkte fra kameraet.<br />

Dette billede skal herefter<br />

gøres tilgængeligt på samme<br />

måde som med billeder<br />

hentet ind fra harddisken.<br />

Når et billede er hentet ind,<br />

enten på den ene eller anden<br />

måde, skal det være muligt at<br />

gemme det på disken igen,<br />

således det kan <strong>brug</strong>es som<br />

dokumentation eller i forbindelse<br />

med debugging. Det<br />

skal være muligt på et hvert<br />

tidspunkt i løbet <strong>af</strong> pr<strong>og</strong>rammet<br />

at kunne gemme billedet.<br />

2. Når billedet er hentet ind <strong>og</strong><br />

gjort tilgængeligt, er det næste<br />

skridt, at det skal konverteres<br />

til et gråtonebillede.<br />

3. Gråtonebilledet skal danne<br />

grundlag for et binært billede,<br />

hvor baggrunden er sort<br />

<strong>og</strong> kimene i forgrunden er<br />

hvide. Der skal altså sættes<br />

Figur 2.2<br />

Blokdiagram over pr<strong>og</strong>rammets opbygning<br />

en grænse, for hvilket gråtoneniveau der er baggrund <strong>og</strong> hvilket der er forgrund. Hertil<br />

anvendes et hist<strong>og</strong>ram. Alt som enten ligger over eller under denne grænse bliver<br />

Side 8 <strong>af</strong> 131


2 Opbygning <strong>og</strong> planlægning 2.1 Opbygning<br />

henholdsvis hvidt eller sort. Det ønskes at fastlæggelsen <strong>af</strong> denne grænse sker dynamisk, da<br />

lysforholdene i billedet kan variere. Grænsen bliver på denne måde ikke givet på forhånd.<br />

4. I det binære billede skal alle de hvide forgrundspixels, som rører <strong>ved</strong> hinanden, sættes<br />

sammen sådan, at man kan referere til en samlet pixelgruppe med et nummer. En sådan pixelgruppe<br />

refereres som ”blob”. Udover at danne blobs skal det <strong>og</strong>så fastlægges, hvor disse<br />

ligger i det binære billede. Der skal altså opsættes en grænse, som omslutter hver enkel blob.<br />

Dette gøres <strong>ved</strong> at ramme dem ind med en firkant, med koordinater til alle fire hjørner, en<br />

såkaldt ”bounding box”. Alle informationer om hver enkel blob gemmes i et objekt ”seed” i<br />

pr<strong>og</strong>rammet.<br />

5. Næste skridt er at udføre ellipseapproksimation på alle blobsne. Det udnyttes her, at det er<br />

givet på forhånd, at <strong>kimplanter</strong>ne vil være <strong>af</strong>lange <strong>af</strong> form. Det er ellipseapproksimationens<br />

formål, at bestemme stor- <strong>og</strong> lilleaksernes længder, samt de vinkler de danner med det<br />

horisontale plan. På denne måde <strong>af</strong>grænses det til to ender, hvor top <strong>og</strong> bund på kimet kan<br />

ligge. Enten i den ene eller anden ende <strong>af</strong> storaksen. Ellipseapproksimationen resulterer<br />

yderligere i centerkoordinater for kimplanten, som kan <strong>brug</strong>es i den videre analyse. Alle disse<br />

informationer gemmes, sammen med dem der allerede står der fra blobsne, i seed-strukturen.<br />

6. I Del II <strong>af</strong> projektet skal kimene kvalitetssorteres. Som et led i det skal kimenes top <strong>og</strong> bund<br />

først findes. Dette gøres for, at man kan placere kimene med korrekt orientering i deres<br />

næringsmiljø.<br />

7. En interessant parameter for kimene er, hvor symmetriske de er omkring deres længdeakse.<br />

Det er tanken, at undersøge hvor symmetrisk hvert kim er omkring dets længdeakse. Et mål<br />

for den symmetri skal herefter vægtes i forhold til kimets størrelse, <strong>og</strong> på den måde kan<br />

kimene sammenlignes indbyrdes. Det er altså herefter muligt, at frasortere kim der er<br />

asymmetriske.<br />

8. Det næstsidste trin bliver at udføre selve sorteringen. Indtil videre er der i Del II kun blevet<br />

samlet oplysninger ind. I trin 8 gennemgås hvert kim, <strong>og</strong> det skal vurderes om kimet falder<br />

inden for de grænser der sættes <strong>af</strong> <strong>brug</strong>eren.<br />

9. I trin 9 skal der udskrives data om alle kimene. Når pr<strong>og</strong>rammet kører i ”Debug”-mode<br />

udskrives al tilgængelig information omkring kimene. Når pr<strong>og</strong>rammet kører i normal<br />

funktionsmode, udskrives kun det absolut nødvendige. I ”Debug”-mode laves der billeder,<br />

der gr<strong>af</strong>isk viser hvilke kim, der er blevet fundet i billedet. Fra trin 5, Ellipseapproksimation,<br />

tegnes alle ellipserne på det originale billede, der bliver anvendt som input til pr<strong>og</strong>rammet.<br />

På den måde vil det være nemt at sammenligne det originale billede, med hvad algoritmen<br />

har fundet frem til. Ydermere tegnes alle blobs, <strong>og</strong> der laves <strong>og</strong>så et billede, der viser alle<br />

toppe <strong>og</strong> bunde på kimene, ud fra det originale billede. Derudover udskrives der 3 tekstfiler:<br />

a. ”Hist<strong>og</strong>ram.m” er en m-fil til MatLab, der direkte kan plotte hist<strong>og</strong>rammet, der<br />

bliver udregnet undervejs<br />

b. ”blobData.txt” viser næsten al tilgængelig data på kimene<br />

c. ”robotData.txt” viser kun (x, y, θ) for alle godkendte kim. Det er tanken, at en robot<br />

kan interface med denne tekstfil, <strong>og</strong> på den måde finde kimene i planet. Når<br />

pr<strong>og</strong>rammet ikke kører i ”Debug”-mode, <strong>og</strong> altså <strong>ved</strong> normal funktionsmode,<br />

udskrives kun ”robotData.txt”<br />

Side 9 <strong>af</strong> 131


2 Opbygning <strong>og</strong> planlægning 2.2 Planlægning<br />

2.2 Planlægning<br />

Projektet er <strong>af</strong> natur uforudsigeligt. Der er ikke n<strong>og</strong>en mulighed for at støtte sig til tidligere skrevne<br />

rapporter eller manualer om emnet, så vidt gruppen kan se, <strong>og</strong> derfor er det heller ikke enkelt at<br />

tidsestimere hvert enkelt emne beskrevet i opbygningen <strong>af</strong> pr<strong>og</strong>rammet (2.1.1 Pr<strong>og</strong>ram s. 8). Gruppen<br />

indgår i en større helhed, <strong>og</strong> derfor vil fremgangen i projektet til dels <strong>af</strong>hænge <strong>af</strong> de andre grupper.<br />

F.eks. skal gruppen <strong>brug</strong>e kim i forsøg <strong>og</strong> udvikling <strong>af</strong> kode, men da andre skal levere disse vil der<br />

være ventetider i forbindelse med bestillingen. Ydermere skal der anvendes kameraer, der skal<br />

rekvireres, <strong>og</strong> i denne situation er mange parter involverede. Derfor skal gruppen arbejde fleksibelt<br />

<strong>og</strong> være indstillet på at kunne flytte fokus, <strong>af</strong>hængigt <strong>af</strong> hvad der er tilgængeligt på tidspunktet.<br />

Derfor besluttes det at anvende riskorn i stedet for <strong>kimplanter</strong> i forbindelse med udvikling <strong>af</strong> de<br />

første algoritmer. Det vurderes at disse, med succes, vil kunne anvendes som erstatning for kim i<br />

test <strong>af</strong> de 5 første algoritmer i Del I. På samme måde anvendes en substitut for et kamera, i form <strong>af</strong><br />

mobiltelefonkamera, der sagtens kan <strong>brug</strong>es i tidlige test.<br />

For at planlægge projektet har gruppen baseret sig på 6-fasemodellen (AIPA [1:1-4]), som er den der<br />

anvendes på elektroretningen:<br />

1. Problemanalyse<br />

2. Idefase<br />

3. Planlægning<br />

4. Problemløsning<br />

5. Konklusion<br />

6. Formidling<br />

Det vurderes d<strong>og</strong> på forhånd, at det ikke er hensigtsmæssigt at have en adskilt problemløsnings- <strong>og</strong><br />

analysefase grundet projektets forskningsprægede natur. For at holde styr på tiden har gruppen<br />

opstillet 3 milepæle. Disse skal være <strong>af</strong>sluttet inden for tidsrammerne, da det ellers vurderes at<br />

projektet, vil komme ud <strong>af</strong> kurs. Disse er:<br />

1. Problemløsnings- <strong>og</strong> analysefase<br />

2. Dokumentationsfase<br />

3. Aflevering <strong>af</strong> rapport<br />

Selve problemløsningsfasen kan ikke planlægges mere detaljeret, ud over at alle punkterne i 2.1.1<br />

Pr<strong>og</strong>ram s. 8 skal løses her inden for. Dokumentationsfasen skal påbegyndes på et bestemt tidspunkt,<br />

<strong>og</strong> er planlagt ud fra en tidsplan (18.4 Tidsplan s. 88), der sikrer at det står klart undervejs hvor langt<br />

gruppen er nået, da det kan være svært at overskue, mens den forløber. Samlet skal de 2 første<br />

milepæle sikre, at den 3. <strong>og</strong> <strong>af</strong>gørende milepæl ”Aflevering <strong>af</strong> rapport” kan overholdes.<br />

Side 10 <strong>af</strong> 131


3 Beskrivelse <strong>af</strong> kim 3.1 Indledning<br />

3 Beskrivelse <strong>af</strong> kim<br />

3.1 Indledning<br />

Den danske eksport <strong>af</strong> juletræer er Europas største med omkring 10 mio. træer årligt til en værdi <strong>af</strong><br />

omkring 1 mia. kr. Denne er ho<strong>ved</strong>sageligt baseret på nordmandsgran, hvilket betyder at det er det<br />

træ i Danmark, der har størst økonomisk betydning. Derfor er det kim <strong>af</strong> denne type der arbejdes<br />

med i projektet.<br />

3.2 Kim<br />

Et kim er, på stadiet hvor gruppen skal arbejde med det, ca. 1-5 mm langt <strong>og</strong> fra 0,5 -1 mm bredt.<br />

Det er gulligt i farven. Denne skifter d<strong>og</strong> langsomt til grøn, efterhånden som kimet bliver udsat for<br />

lys <strong>og</strong> luft. I toppen har kimet en begyndende kimbladsstruktur. I bunden kan roden <strong>af</strong> <strong>og</strong> til anes<br />

som en knold eller andre gange som en lille hale (figur 3.3). Pga. den måde hvorpå kimene er klonet,<br />

har de ikke alle præcis samme alder. Der kan derfor være stor variation i størrelse, <strong>og</strong> hvor langt<br />

kimblade <strong>og</strong> rod har udviklet sig.<br />

3.3 Miljø<br />

Kimene ligger efter de er blevet klonet <strong>og</strong> modnet i en<br />

næringsmasse. I denne masse ligger de klumpet sammen<br />

<strong>og</strong> klistrer kr<strong>af</strong>tigt til hinanden (figur 3.1).<br />

Efter et givent stykke tid skal kimene ud <strong>af</strong> denne masse<br />

<strong>og</strong> flyttes enkeltvis over i et nyt næringsmedie. For at<br />

separere kimene fra hinanden omrøres de kr<strong>af</strong>tigt i et<br />

vandkar. Herefter trækkes der et net op <strong>af</strong> vandkaret,<br />

hvorpå kimene vil ligge spredt ud. Et eksempel på et<br />

sådan net er vist på figur 3.2. Det ligger ikke inden for<br />

gruppens område at designe dette net. Det er d<strong>og</strong> med<br />

dette net som baggrund, at kimene vil komme til at ligge i<br />

en endelig produktion. Nettet vil være matteret sort, <strong>og</strong><br />

det antages at genskin fra vand vil være minimalt.<br />

Der vil blive anvendt prøver med kim, som leveres fra<br />

Jens Iver Find fra Københavns Universitet. Disse kim vil<br />

indgå i test, <strong>og</strong> opbevares på SDU, Det Tekniske Fakultet,<br />

i køleskab. Det skal d<strong>og</strong> gøres klart, at gruppen ikke har<br />

mulighed for at arbejde under sterile forhold, <strong>og</strong> derfor vil<br />

prøver, efter de er åbnede blive udsat for bakterier, <strong>og</strong><br />

dette vil markant begrænse deres holdbarhed. Dermed<br />

bliver den periode hvor gruppen kan foretage test, efter<br />

åbning, meget begrænset.<br />

Figur 3.1<br />

Kimene mens de ligger klumpet sammen<br />

Figur 3.2<br />

Et eksempel på et net, hvor billedet er taget på<br />

nært hold<br />

Side 11 <strong>af</strong> 131


3 Beskrivelse <strong>af</strong> kim 3.4 Klassificering<br />

3.4 Klassificering<br />

Som det ses på figur 3.3 er der stor forskel på kimenes udseende. N<strong>og</strong>le<br />

er meget krumme, andre har ingen kimblade, mens n<strong>og</strong>le er tykke, <strong>og</strong><br />

andre er tynde. Dette giver anledning til en opdeling <strong>og</strong> <strong>klassificering</strong>.<br />

Det viser sig nemlig, at det ikke er alle kim, der bliver til et pænt juletræ.<br />

Kimene inddeles i 4 klasser (Find [2]).<br />

• 1. klasse – veldannede<br />

• 2. klasse – lette misdannelser<br />

• 3. klasse – misdannede<br />

• 4. klasse - abnorme<br />

De bedste kim falder inden for 1. klasse.<br />

3.4.1 Første klasse – veldannede<br />

I en skål med klonede kim vil 8 – 10 % være <strong>af</strong> 1. klasse (figur 3.4). Af disse bliver 100 % til<br />

veldannede <strong>og</strong> gode planter. For at et kim kan blive betragtet som et 1. klasses kim, skal det opfylde<br />

følgende krav:<br />

• 4-7 kimblade<br />

• 3-5 mm lange<br />

• Have en hvid-gul farve<br />

• Være lige<br />

Figur 3.4<br />

Skitse <strong>af</strong> 1.klasses veldannede kim<br />

Hver gang der laves en ny kloning kan der forekomme variation. Når der senere i denne rapport<br />

tales om godkendte kim, så er dette ensbetydende med, at kimene er <strong>af</strong> 1. klasse.<br />

3.4.2 Anden klasse – lette misdannelser<br />

I en skål med klonede kim vil 8 – 10 % være <strong>af</strong> 2. klasse<br />

(figur 3.5). Af disse bliver 75 % til veldannede <strong>og</strong> gode<br />

planter. For at et kim kan blive betragtet som et 2. klasses<br />

kim, skal det opfylde et <strong>af</strong> følgende krav:<br />

• Et kimblad længere end de øvrige<br />

• Indsnævret stængel<br />

• 2-3 kimblade<br />

3.4.3 Tredje klasse – misdannede<br />

I en skål med klonede kim vil 8 – 10 % være <strong>af</strong> 3. klasse<br />

(figur 3.6). Af disse bliver 50 % til veldannede <strong>og</strong> gode planter. For at et kim kan blive betragtet som<br />

et 3. klasses kim, skal det opfylde et <strong>af</strong> følgende krav:<br />

• Et dominerende kimblad<br />

Figur 3.3<br />

Viser et udsnit <strong>af</strong> de forskellige<br />

former et kim kan antage<br />

Figur 3.5<br />

Skitse <strong>af</strong> de forskellige krav der stilles til 2.<br />

klasses planter<br />

Side 12 <strong>af</strong> 131


3 Beskrivelse <strong>af</strong> kim 3.5 Værdi<br />

• Stumpet<br />

• Ekstra rodspids<br />

• Tvilling<br />

• Krum<br />

• Opsvulmet stængel<br />

Figur 3.6<br />

Skitser <strong>af</strong> de forskellige misdannelser som kan forekomme <strong>og</strong> gør at kimene falder inden for 3. klasse<br />

3.4.4 Fjerde klasse – abnorme<br />

I en skål med klonede kim vil ca. 75 % være <strong>af</strong> 4. klasse (figur 3.7). Af disse bliver 0 % til veldannede<br />

<strong>og</strong> gode planter. For at et kim kan blive betragtet som et 4. klasses kim, skal det opfylde et <strong>af</strong><br />

følgende krav:<br />

• Klumper<br />

• Ingen kimblade<br />

3.5 Værdi<br />

Figur 3.7<br />

Skitse <strong>af</strong> 4. klasses kim<br />

Kostprisen på et kim på dette stadie er endnu ukendt, <strong>og</strong> det er derfor ikke muligt med sikkerhed, at<br />

sige om det kan betale sig at plante alle kimklasser, selvom man <strong>ved</strong> at de ikke alle bliver til gode<br />

træer, eller om man skal frasortere alle dårlige <strong>og</strong> kun koncentrere sig om de gode, eller om der skal<br />

findes en mellemvej. D<strong>og</strong> tyder tidlige vurderinger fra Jens Iver Find <strong>og</strong> Lars Sommer på, at det er<br />

mest økonomisk at fjerne dårlige kim tidligt i beplantningsprocessen.<br />

Side 13 <strong>af</strong> 131


4 Kamera 4.1 Indledning<br />

4 Kamera<br />

4.1 Indledning<br />

For at det er muligt at detektere kim, er det nødvendigt med et kamera, der kan tage et billede, som<br />

pr<strong>og</strong>rammet herefter kan analysere. Det er ønskeligt, at kameraet kan interfaces i et kodeprojekt, så<br />

der kan kommunikeres direkte, uden at skulle anvende proprietær software.<br />

I samarbejde med vejleder blev det besluttet at anvende et kamera, der benytter FireWireprotokollen.<br />

I den forbindelse anbefalede vejleder, at gruppen anvendte produktet Fire-i fra firmaet<br />

Unibrain. Denne softwarepakke indeholder mange løsninger til at kommunikere med et FireWirekompatibelt<br />

kamera. Overordnet set er disse løsninger delt ind i 2 kategorier (figur 4.1):<br />

1. Kompilér-bar C++-kode (Fire-i API)<br />

2. Prekompileret software<br />

Fire-i API indeholder klasser skrevet i C++,<br />

som pr<strong>og</strong>rammører kan anvende i deres egen<br />

kode. På den måde kan man direkte interface<br />

sit eget kodeprojekt med kameraet.<br />

Den prekompilerede software er applikationer<br />

skrevet <strong>af</strong> Unibrain, som kan eksekveres<br />

<strong>og</strong> igennem dem, kan man anvende kameraet.<br />

Selvsagt giver dette ikke mulighed for at<br />

indarbejde dette i sit kodeprojekt, da der er<br />

tale om beskyttet proprietær software.<br />

Gruppen har fra starten bestemt sig for at<br />

indarbejde kameraet direkte i koden, <strong>ved</strong> at<br />

anvende Fire-i API.<br />

4.2 Tilgængelige kameraer<br />

Til projektet blev der stillet to forskellige FireWire-kameraer til rådighed:<br />

1. SONY XCD-V50 640x480 Gråtonekamera<br />

2. SONY DFW-SX910 1280x960 Farvekamera<br />

Figur 4.1<br />

Oversigt over muligheder med Fire-i<br />

Det har fra starten været hensigten, at kamera nr. 2 (farvekamera) skulle være gruppens primære<br />

kamera. Dette kamera var d<strong>og</strong> ikke indkøbt fra starten <strong>af</strong> projektet, <strong>og</strong> derfor blev gruppen tildelt<br />

kamera nr. 1 (gråtonekameraet), så det var muligt at arbejde på implementering <strong>af</strong> FireWire-kameraet<br />

i kodeprojektet.<br />

Det kan oplyses, at begge kameraer opererer med en gamma-værdi på 1. Det betyder, at det ikke er<br />

nødvendigt for gruppen at indarbejde metoder for gamma-korrektion.<br />

Side 14 <strong>af</strong> 131


4 Kamera 4.3 Fire-i API<br />

4.2.1 Opløsning<br />

<strong>Detektering</strong> <strong>af</strong> toppen på de enkelte kim dikterer kravet til opløsningen, da algoritmerne bygger på,<br />

at der er synlig bladstruktur på kimene. De enkelte kim skal være minimum 10 pixels brede i toppen,<br />

for at der er en detektérbar bladstruktur på billedet. Da godkendte kim er minimum én millimeter<br />

brede, giver det et krav om en opløsning på minimum 10 pixels/mm, hvilket giver et synsfelt på<br />

64x48 mm eller 128x96 mm <strong>af</strong>hængigt <strong>af</strong> kameraopløsning.<br />

4.2.2 Afstand <strong>og</strong> linse<br />

Gruppen anvender en linse fra Pentax (6 mm F/1.2 H612A C60607TH). Denne linse giver ikke<br />

mulighed for zoom, men <strong>ved</strong> at placere den med den rigtige <strong>af</strong>stand til kimene, har gruppen fundet<br />

frem til en løsning, der giver 11 pixels/mm. D<strong>og</strong> er denne <strong>af</strong>stand uden for linsens normale<br />

fokusområde, men dette er løst <strong>ved</strong> at lægge en mellemring imellem kamera <strong>og</strong> linse, så linsen kan<br />

fokusere på objekter tættere på.<br />

4.3 Fire-i API<br />

Fire-i kan anvendes på 2 måder:<br />

4.3.1 Fire-i ubCore<br />

Denne model bygger på ”Firei.dll” fra Unibrain. Igennem dette bibliotek kan Unibrain-driverne<br />

(ubCore) tilgås direkte, hvilket minimerer belastningen <strong>af</strong> systemressourcer, samtidigt med at<br />

systemet er bagudkompatibelt med Windows 98 <strong>og</strong> NT.<br />

4.3.2 WDM<br />

Denne model bygger på Windows Driver Model (WDM), hvor softwaren, igennem DirectShow<br />

(multimedieframework der <strong>brug</strong>es til lyd <strong>og</strong> billeder i Windows), tilgår Unibrain-driverne. Denne<br />

metode anbefales <strong>af</strong> Unibrain til alle nyere systemer, da den er mere fleksibel <strong>og</strong> fremtidssikker. D<strong>og</strong><br />

er denne metode ikke bagudkompatibel med Windows 98 <strong>og</strong> NT, <strong>og</strong> kræver flere systemressourcer,<br />

da alle kald skal igennem flere applikationslag.<br />

4.3.3 Implementering <strong>af</strong> Fire-i<br />

Gruppen har forsøgt at interface med kameraet direkte, via et <strong>af</strong> de medfølgende Visual C++kodeprojekter<br />

fra Unibrain, både <strong>ved</strong> anvendelse <strong>af</strong> ubCore- <strong>og</strong> WDM-modellen. Kodeprojekterne<br />

skulle kun anvendes til test, <strong>og</strong> til at danne forståelse for hvordan en implementering skulle foretages<br />

i gruppens eget kodeprojekt.<br />

Gruppen har forsøgt at kompilere begge typer <strong>af</strong> kodeprojekteter, uden succes. Både i forbindelse<br />

med ubCore- <strong>og</strong> WDM-modellen, har gruppen h<strong>af</strong>t uoverkommelige problemer med at kompilere<br />

de medfølgende kodeprojekter. I WDM-modellen anvendes der Microsoft DirectShow.<br />

Dokumentationen til Fire-i biblioteket beskriver, at Microsofts ”Platform SDK” skal installeres, for<br />

at det er muligt at kompilere software, der benytter sig <strong>af</strong> DirectShow. Gruppen installerede derfor<br />

Microsofts ”Platform SDK” version 2006, men dette løste ikke kompileringsproblemerne, da der<br />

Side 15 <strong>af</strong> 131


4 Kamera 4.4 Sammenfatning<br />

stadig var problemer pga. manglende header-filer (f.eks. streams.h), <strong>og</strong> at der blev anvendt forældede<br />

(”deprecated”) funktionskald.<br />

Det er senere i forløbet konstateret, at Microsoft har fjernet DirectShow i version 2006 <strong>af</strong> Platform<br />

SDK. At DirectShow ikke længere er en del <strong>af</strong> Platform SDK’et, kan være den væsentlige faktor til,<br />

at gruppen ikke har kunnet kompilere softwaren. Årsagen til at gruppen ikke var klar over denne fejl<br />

er, at DirectShow er fjernet fra Platform SDK i løbet <strong>af</strong> 2006, mens dokumentationen til kameraet er<br />

skrevet i 2005, hvor der ikke er angivet n<strong>og</strong>en version <strong>af</strong> hvilket Platform SDK der skulle anvendes.<br />

Problemerne, med anvendelse <strong>af</strong> Fire-i API, har resulteret i, at gruppen har været nødsaget til at tage<br />

billeder vha. den medfølgende prekompilerede software til kameraet: ”Fire-i Application v. 3.51.0.3”.<br />

Denne software er proprietær, <strong>og</strong> kan altså ikke interfaces direkte med gruppens eget kodeprojekt.<br />

Det vurderes d<strong>og</strong> ikke at være en væsentlig hindring, da gruppen kun skal demonstrere at projektet<br />

fungerer på konceptform, <strong>og</strong> ikke til produktionsmæssigt <strong>brug</strong>. ”Fire-i Application v. 3.51.0.3” giver<br />

mulighed for, at <strong>brug</strong>eren kan se hvad kameraet filmer, <strong>og</strong> lave ”screendumps” <strong>af</strong> dette. Disse<br />

screendumps kan herefter gemmes i et valgfrit bibliotek på <strong>computer</strong>en.<br />

4.4 Sammenfatning<br />

Samlet set kan det konkluderes, at interfacingen med kameraerne har h<strong>af</strong>t en begrænset succes.<br />

De anvendte kameraer har i sig selv været udmærkede valg til opgaven, <strong>og</strong> har ikke medført direkte<br />

problemer.<br />

Det kan konstateres, at det ikke har været muligt at interface kameraet på den ønskede måde. Der<br />

var meget store problemer med at kompilere de medfølgende kodeprojekter fra Unibrain. I tilfældet<br />

med ubCore-modellen, er det uvist hvad problemet skyldes, hvorimod med WDM-modellen har<br />

gruppen en idé om, at der kan være problemer med anvendelsen <strong>af</strong> den nyeste version <strong>af</strong> Microsofts<br />

Platform SDK. Gruppen har som alternativ besluttet, at anvende den medfølgende prekompilerede<br />

software, der d<strong>og</strong> ikke giver mulighed for direkte tilgang til kameraet fra gruppens eget kodeprojekt.<br />

Dette har d<strong>og</strong> ikke væsentlige konsekvenser, da der i forvejen skal udvikles metoder til at indlæse<br />

BMP-filer i gruppens kodeprojekt.<br />

Side 16 <strong>af</strong> 131


4 Kamera 4.4 Sammenfatning<br />

Del I: <strong>Detektering</strong> <strong>af</strong> <strong>kimplanter</strong><br />

Første del <strong>af</strong> rapporten omhandler detektering <strong>af</strong> <strong>kimplanter</strong>. I denne del vil der blive udviklet<br />

algoritmer, der har til formål alene at finde alle kim i billedet uden hensyn til kvaliteten <strong>af</strong> disse. Først<br />

behandles Color- <strong>og</strong> GrayScale-klasserne, der har til formål at indlæse henholdsvis farve-, <strong>og</strong><br />

gråtonebilleder, <strong>og</strong> gøre dem tilgængelige for andre klasser. Dernæst gennemgås Binary- <strong>og</strong><br />

BlobDetection-klasserne, der vil henholdsvis thresholde, <strong>og</strong> finde alle blobs i billedet. Til sidst vises<br />

klassen EllipseApproximation, som har til formål at finde kimenes massemidtpunkt, <strong>og</strong><br />

approksimere en ellipse hertil.<br />

Side 17 <strong>af</strong> 131


5 Color 5.1 Indledning<br />

5 Color<br />

5.1 Indledning<br />

Formålet med denne klasse er at give pr<strong>og</strong>rammet et interface til at styre al I/O-billedbehandling<br />

igennem. Klassen skal kunne indlæse BMP-filer, samt kunne gemme dem igen. Samtidigt skal<br />

klassen stille et interface til rådighed til de andre klasser, som kan tilgå, ændre <strong>og</strong> gemme BMP-filer<br />

simpelt.<br />

5.2 Teori<br />

5.2.1 Koordinatsystem<br />

Figur 5.1<br />

Koordinatsystem hvor ykoordinaten<br />

peger nedad<br />

5.2.2 BMP-filer<br />

Hver pixel i et billede har et koordinatsæt. I et billedebehandlingspr<strong>og</strong>ram<br />

angives disse i et koordinatsystem<br />

hvor y-aksen peger nedad (figur 5.1).<br />

I matematiske sammenhænge <strong>og</strong> i BMP-filer <strong>brug</strong>es et<br />

koordinatsystem hvor y-aksen peger opad (figur 5.2).<br />

Gruppen har valgt at benytte sig <strong>af</strong> dette koordinatsystem.<br />

En BMP-fil består <strong>af</strong> en header, evt. en palette <strong>og</strong> selve<br />

dataene i nævnte rækkefølge (figur 5.3).<br />

5.2.2.1 Header<br />

Headeren ligger i starten <strong>af</strong> BMP-filen. Der findes flere<br />

versioner <strong>af</strong> denne header, men det er valgt kun at arbejde<br />

med 54-bytes versionen, ligesom det er valgt ikke at<br />

komprimere eller dekomprimere billeder.<br />

Figur 5.3<br />

BMP-filers opbygning<br />

Figur 5.2<br />

Koordinatsystem hvor ykoordinaten<br />

peger opad<br />

Headeren er delt i to dele: en fil-header <strong>og</strong> en infomations-header. Fil-headeren gemmer<br />

informationer omkring filstørrelse <strong>og</strong> offset ned til selv billede-dataene. Offsettets størrelse er<br />

<strong>af</strong>hængigt <strong>af</strong> om der er en palette, <strong>og</strong> hvor stor den evt. er. Informationsheaderen angiver<br />

oplysninger som højde <strong>og</strong> bredde <strong>af</strong> billedet, far<strong>ved</strong>ybde, kompressionsmetode m.m.<br />

Side 18 <strong>af</strong> 131


5 Color 5.3 Test<br />

5.2.2.2 Palette<br />

Paletten <strong>brug</strong>es kun på billeder med en far<strong>ved</strong>ybde på 8 bit <strong>og</strong> der under. Paletten ligger på den 54.<br />

byte <strong>og</strong> frem efter i BMP-filen. For hver farve gemmes 4 bytes: De første 3 bytes er intensiteten for<br />

henholdsvis den blå, grønne <strong>og</strong> røde farve. Den fjerde byte <strong>brug</strong>es ikke.<br />

5.2.2.3 Data<br />

I datadelen gemmes selve billedet linie for linie, hvor den nederste linie i billedet er den, der ligger<br />

først i filen, derefter kommer den næste linie osv. Pixelene gemmes enkeltvis hvor den pixel, længst<br />

til venstre, er den der ligger først i filen. Hvis billedets far<strong>ved</strong>ybde er over 8 bit <strong>brug</strong>es paletten ikke,<br />

<strong>og</strong> de enkelte pixels gemmes i 3 bytes. Den første byte er farveintensiteten <strong>af</strong> den blå farve, den<br />

anden er den grønne farve, <strong>og</strong> den tredje er den røde farve. Hvis billedets far<strong>ved</strong>ybde er 8 bit eller<br />

der under, <strong>brug</strong>es der en enkelt byte til at henvise til paletten.<br />

BMP-standarden kræver, at det antal bytes en linie består <strong>af</strong>, skal være multiplum <strong>af</strong> 4. Da det ikke<br />

vil passe med alle bredder <strong>af</strong> billeder, tilføjes 0-3 tomme bytes efter hver linie, så antallet <strong>af</strong> bytes er<br />

multiplum <strong>af</strong> 4.<br />

5.2.3 Billedtilgang<br />

Når billedet er blevet loadet ind i et Color-objekt, er der mulighed for at gemme det som en fil eller<br />

ændre det. Der kan laves ændringer i billedet på de følgende to måder:<br />

• Normal tilgang<br />

• Hurtig tilgang<br />

Med den normale tilgang er der en fejlkontrol, der sikrer, at der skrives/læses indenfor billedet. Med<br />

den hurtige tilgang anvendes der ikke fejlkontrol, men til gengæld kan der skrives <strong>og</strong> læses hurtigere.<br />

5.3 Test<br />

Da det er svært at lave en fuldstændigt dækkende test <strong>af</strong> color-klassen, er der foretaget en simpel<br />

stikprøvekontrol. Kontrollen tester med et enkelt billede, om klassen kan hente <strong>og</strong> gemme billeder,<br />

samt hvordan interfacing med andre klasser virker.<br />

5.3.1 Fremgangsmetode<br />

For at teste klassen er denne blevet implementeret<br />

i et særskilt Visual C++-kodeprojekt. Dette kodeprojekt<br />

tester klassens metoder til at hente billeder<br />

fra disken <strong>og</strong> gemme dem til disken igen. Samtidigt<br />

tester kodeprojektet <strong>og</strong>så klassens metoder til at<br />

hente enkelte RGB-værdier i billedet, samt ændre<br />

disse.<br />

Testen udføres <strong>ved</strong> at billedet ”input.bmp” (figur<br />

5.4), bliver loadet ind med execute()-funktionen.<br />

Figur 5.4<br />

input.bmp – inputfilen til testen <strong>af</strong> color-klassen. Billedets<br />

opløsning er 14x6 pixel<br />

Side 19 <strong>af</strong> 131


5 Color 5.4 Sammenfatning<br />

Herefter udskriver pr<strong>og</strong>rammet billedets størrelse til prompten.<br />

For at teste den normale tilgang bliver farven i koordinatet (3,1) kopieret til variablerne red, green<br />

<strong>og</strong> blue samt skrevet til skærmen. Efterfølgende bliver farven i variablerne red, green <strong>og</strong> blue<br />

kopieret til koordinaterne (3,2), (3,3) <strong>og</strong> (3,4).<br />

For teste den hurtige billedetilgang (uden kontrol <strong>af</strong> om der skrives/læses inden for billedet),<br />

kopieres pointeren til det grønne farve array over i ppGreenArray, som <strong>brug</strong>es til at tegne en grøn<br />

streg fra punktet (4,4) <strong>og</strong> ud til højre side <strong>af</strong> billedet.<br />

Til sidst gemmes billedet som filen ”color.bmp” (figur 5.5), så gemmefunktionaliteten <strong>og</strong>så testes:<br />

Color color;<br />

color.execute("input.bmp");<br />

printf("Picture size: %dx%d\n", color.getWidth(), color.getHeight());<br />

unsigned char red, green, blue;<br />

color.getValue(3,1, red, green, blue);<br />

printf("RGB(3,1): %d %d %d\n", red, green, blue);<br />

color.setValue(3,2, red, green, blue);<br />

color.setValue(3,3, red, green, blue);<br />

color.setValue(3,4, red, green, blue);<br />

unsigned char **ppGreenArray;<br />

ppGreenArray = color.getGreenPointer();<br />

for (int i = 4; i < color.getWidth(); i++)<br />

{<br />

ppGreenArray[4][i] = 255;<br />

}<br />

color.save("output.bmp");<br />

5.3.2 Testresultater<br />

Pr<strong>og</strong>rammet skriver følgende til prompten:<br />

Picture size: 14x6<br />

RGB(3,1): 255 255 0<br />

Billedet vist i figur 5.5 bliver gemt til disken.<br />

Billedets størrelse (14x6 pixel) er læst fra filen.<br />

Samtidigt er RGB-koden for farven i koordinatsæt 3,1<br />

indlæst til at være 255, 255, 0, hvilket svarer til gul.<br />

Som det ses på billedet er farven (gul), fra pixel (3,1),<br />

kopieret til pixelene (3,2), (3,3) <strong>og</strong> (3,4). Ligeledes er<br />

der tegnet en streg fra pixelen i (4,4).<br />

5.4 Sammenfatning<br />

Figur 5.5<br />

Figuren viser color.bmp som er resultatet <strong>af</strong> testen <strong>af</strong><br />

color-klassen<br />

Det kan konkluderes, at andre klasser i pr<strong>og</strong>rammet med succes kan tilgå BMP-billedet med det<br />

interface, der er stillet til rådighed igennem denne klasse. Testen viser, at klassen korrekt henter,<br />

ændrer <strong>og</strong> gemmer billedet som ønsket.<br />

Side 20 <strong>af</strong> 131


6 GrayScale 6.1 Indledning<br />

6 GrayScale<br />

6.1 Indledning<br />

Der ønskes en simpel måde at interface med gråtonebilleder, hvor det er let at loade, ændre, oprette<br />

<strong>og</strong> gemme gråtonebilleder.<br />

Da koden i GrayScale-klassen bygger på koden i Color-klassen, minder de to klasser meget om<br />

hinanden. I stedet for at dokumentere hele GrayScale-klassen på samme måde som Color-klassen,<br />

har gruppen valgt kun at dokumentere de forskelle, der er på de to klasser i dette kapitel.<br />

6.2 Forskelle fra Color-klassen<br />

Da der arbejdes med et gråtonebillede er antallet <strong>af</strong> farvekanaler reduceret til én enkelt i GrayScaleklassen.<br />

Da der kun er én farvekanal, simplificeres metoderne til at hente <strong>og</strong> ændre pixelintensiteten.<br />

6.3 Konvertering fra farve- til gråtonebilleder<br />

Ved konvertering <strong>af</strong> farvebilleder til gråtonebilleder skal farvekoden, for de enkelte pixels konverteres<br />

til en gråtone lysintensitet. De tre farverkanaler i RGB-billedet bør vægtes forskelligt (tabel 6.1)<br />

<strong>ved</strong> konverteringen til gråtoner.<br />

Da den grønne farvekanal er den mest dominerende hvad angår<br />

lysintensitet, <strong>og</strong> da kimene er gul-grønne, har gruppen valgt at konvertere<br />

fra et farvebillede til et gråtonebillede, <strong>ved</strong> kun at <strong>brug</strong>e den grønne<br />

farvekanal. Med denne metode bliver konverteringen simplere <strong>og</strong> hurtigere,<br />

samtidigt med at grønne objekter bliver tydeligere i gråtonebilledet.<br />

Dette gør selvfølgelig, at algoritmen ikke vil virke på rent røde <strong>og</strong> blå<br />

objekter.<br />

6.4 Test<br />

6.4.1 Fremgangsmetode<br />

Denne test kontrollerer konverteringen <strong>af</strong> et farvebillede til<br />

gråtonebillede. Testen udføres <strong>ved</strong> at indlæse billedet<br />

”color.bmp” fra testen <strong>af</strong> Color-klassen <strong>og</strong> konvertere det<br />

til et gråtone billede <strong>og</strong> sammenligne de to billeder:<br />

Color color;<br />

GrayScale grayScale;<br />

color.execute("color.bmp");<br />

grayScale.execute(color);<br />

grayScale.save("grayscale.bmp");<br />

Figur 6.1<br />

color.bmp<br />

Farve Vægtning<br />

Rød 0,299<br />

Grøn 0,587<br />

Blå 0,114<br />

Tabel 6.1<br />

Vægtning <strong>af</strong> de forskellige<br />

farver <strong>ved</strong> konvertering til<br />

gråtone<br />

Side 21 <strong>af</strong> 131


6 GrayScale 6.5 Sammenfatning<br />

6.4.2 Testresultater<br />

På figur 6.1 ses det oprindelige billede, som er blevet loadet<br />

ind i figuren. I figur 6.2 ses resultatet <strong>af</strong> konverteringen. Det<br />

ses her, at det kun er den grønne farve, der bliver overført<br />

til gråtonebilledet.<br />

6.5 Sammenfatning<br />

Figur 6.2<br />

grayscale.bmp<br />

Der er med succes lavet en klasse, som stiller et interface til rådighed. Dette interface gør det muligt<br />

for andre klasser at loade, oprette, ændre <strong>og</strong> gemme gråtonebilleder på samme måde som med<br />

Color-klassen. Konverteringen fra farvebillede til gråtonebillede foregår <strong>ved</strong> kun at <strong>brug</strong>e den<br />

grønne farvekanal, da kimene er gul-grønne <strong>og</strong> da den grønne farvekanal, er den mest dominerende<br />

<strong>af</strong> de 3 farvekanaler i forhold til lysintensitet.<br />

Side 22 <strong>af</strong> 131


7 Binary 7.1 Indledning<br />

7 Binary<br />

7.1 Indledning<br />

Det er formålet med Binary-klassen, at skabe en måde hvorpå det kan <strong>af</strong>gøres, hvad der er for- <strong>og</strong><br />

baggrund i billedet. Billedet, som skal behandles, kommer som et objekt fra GrayScale-klassen. Det<br />

ønskes at opstille automatiserede metoder til, hvordan man får adskilt lyse kim i forgrunden fra den<br />

mørke baggrund. I denne forbindelse opereres der med en term som thresholdværdi, som er den<br />

pixelintensitetsværdi, der angiver skellet mellem for- <strong>og</strong> baggrund.<br />

7.2 Teori<br />

Det ønskes altså at have en automatiseret proces, der kan finde thresholdværdien automatisk. Til<br />

dette <strong>brug</strong>es et hist<strong>og</strong>ram <strong>og</strong> Ridler <strong>og</strong> Calvards iterative thresholding-teknik (Ridler <strong>og</strong> Calvard [6:630-<br />

632]). Metoden er delt i to processer:<br />

1. Hist<strong>og</strong>ram dannes <strong>ved</strong> at billedet traverseres, hvor der løbende tælles op hvor mange pixels,<br />

der er <strong>af</strong> hver pixelintensitet<br />

2. Efter et antal iterationer bestemmes billedets thresholdingværdi. Denne værdi vil <strong>af</strong>gøre hvad<br />

der er forgrund <strong>og</strong> baggrund i billedet<br />

Hist<strong>og</strong>rammet <strong>brug</strong>es til, at vurdere hvor de største fordelinger i pixelintensitet er placeret. Derefter<br />

skal den iterative thresholding-teknik <strong>brug</strong>es til at bestemme selve thresholdværdien ud fra<br />

hist<strong>og</strong>rammet.<br />

7.2.1 Hist<strong>og</strong>ram<br />

Hist<strong>og</strong>rammet er et plot <strong>af</strong> hyppigheden (frekvens) <strong>af</strong> alle pixelintensiteter (pixel intensitet) i et<br />

gråtonebillede (figur 7.1). Det er givet på forhånd i pr<strong>og</strong>rammet, at alle pixelintensiteter skal kunne<br />

være i en byte, så derfor skal hist<strong>og</strong>rammet gå fra 0-255 pixels. Figur 7.1 viser et realistisk eksempel<br />

på et hist<strong>og</strong>ram <strong>af</strong> et billede med kim:<br />

Figur 7.1<br />

Billede med tilhørende hist<strong>og</strong>ram<br />

Side 23 <strong>af</strong> 131


7 Binary 7.2 Teori<br />

Som det ses <strong>af</strong> hist<strong>og</strong>rammet, er der en meget stor peak <strong>ved</strong> de lavere pixelintensiteter, som kommer<br />

<strong>af</strong> den dominerende mørke baggrund i billedet. Ydermere er der en mindre peak omkring 150 i<br />

pixelintensitet, som kommer <strong>af</strong> de lyse kim i forgrunden. Det er tydeligt at se fra hist<strong>og</strong>rammet, at<br />

vælger man en pixelintensitet omkring 70, vil man skelne forgrunden fra baggrunden. Det er d<strong>og</strong><br />

ikke altid at en thresholdværdi på 70 vil være rigtigt, da ændringer i lysforhold <strong>og</strong> kimtyper kan gøre<br />

at begge peaks vil ligge andetsteds i hist<strong>og</strong>rammet. Derfor vil det være hensigtsmæssigt at anvende<br />

en automatiseret proces der kan finde ”dalen” i hist<strong>og</strong>rammet mellem de to peaks.<br />

Hist<strong>og</strong>rammets udseende <strong>af</strong>hænger <strong>af</strong> mange faktorer. På billedet, der er anvendt som eksempel, er<br />

følgende tilstande gældende:<br />

1. Ensartet belysning i hele billedet<br />

2. Der er stor kontrastforskel mellem forgrund <strong>og</strong> baggrund<br />

3. Der er meget lidt genskin fra lyskilder<br />

4. Der er mere baggrund end forgrund i billedet<br />

En ændring i hver <strong>af</strong> disse parametre (1-4) vil give hver sin type <strong>af</strong> ændring (a-d) i hist<strong>og</strong>rammet:<br />

a) Forestiller man sig f.eks. at et hjørne er mere belyst end de andre vil de lyse områder, der er<br />

større end thresholdværdien, blive opfattet som forgrund. For at løse dette kunne man lave<br />

et gradient-map. Dette map gør at det er muligt at have forskellige thresholdværdier<br />

forskellige steder i billedet. På den måde er der ikke én fast thresholdværdi for hele billedet<br />

men thresholdværdier for områder i stedet. Dette gør, at selvom dele <strong>af</strong> billedet er mere lyse<br />

end andre, så vil disse områder ikke nødvendigvis blive betragtet som forgrund, da der<br />

eksisterer en relativ thresholdværdi for det område, der sikrer at thresholdingen matcher<br />

lysforholdene i det område.<br />

b) Hvis der ikke eksisterer et stort kontrastforhold mellem kimene <strong>og</strong> baggrunden, vil den<br />

mindre peak mod højre ligge længere til venstre. Ved særligt lave pixelintensiteter vil den lille<br />

peak, som kommer fra tilstedeværelsen <strong>af</strong> kimene, være sammenfaldende med den store<br />

peak <strong>og</strong> det vil være svært algoritmemæssigt at skelne forgrund fra baggrund <strong>ved</strong> <strong>brug</strong> <strong>af</strong><br />

hist<strong>og</strong>rammet.<br />

c) Ved genskin vil det give ”falske kim” i billedet. Genskinnet vil sandsynligvis ligge over<br />

thresholdværdien <strong>og</strong> vil derfor blive betragtet som forgrund. Dermed vil den mindre peak<br />

fra kimene være større på et falskt grundlag, <strong>og</strong> den store peak med baggrundspixels være<br />

tilsvarende mindre.<br />

d) Skulle det være tilfældet at der er mere forgrund end baggrund i billedet, vil hist<strong>og</strong>rammet se<br />

ud som det i eksemplet, bare spejlet omkring midten (127 pixelintensitet), dvs. den store<br />

peak vil ligge mod højre.<br />

Punkterne beskrevet i a-d er alle emner, der regnes for ikke at være gældende i de billeder, der skal<br />

analyseres <strong>af</strong> algoritmen.<br />

7.2.2 Iterativ thresholding-teknik<br />

Ridler <strong>og</strong> Calvards iterative thresholding-teknik, har til formål at finde ”dalen” imellem de 2 store<br />

peaks i hist<strong>og</strong>rammet. Trussel [5:311] beskriver en matematisk løsning på Ridler <strong>og</strong> Calvards teknik<br />

som:<br />

Side 24 <strong>af</strong> 131


7 Binary 7.2 Teori<br />

, hvor:<br />

T<br />

Tk<br />

∑<br />

bn() b<br />

b=<br />

0<br />

b= Tk+<br />

1<br />

k + 1 = T +<br />

k<br />

N<br />

∑<br />

2 nb ( )<br />

b=<br />

0<br />

N<br />

∑<br />

∑<br />

b= Tk+<br />

1<br />

bn() b<br />

2 nb ( )<br />

T k Thresholdværdien <strong>ved</strong> k’te iteration<br />

N Antal pixelintensiteter (i gråtonebillede er N = 255 )<br />

b Pixelintensitet ( 0 ≤b ≤ N)<br />

nb () Antal forekomster <strong>af</strong> b<br />

H. J. Trussels formel <strong>og</strong> Ridler <strong>og</strong> Calvards iterative thresholding-tekniks virkemåde kan beskrives<br />

som (figur 7.2):<br />

1. Den indledende thresholdværdi ( T 0 ) sættes til 127<br />

2. Det undersøges for hver pixelintensitet i hist<strong>og</strong>rammet, om denne ligger over eller under den<br />

aktuelle thresholdværdi:<br />

a. Under er baggrundspixel, <strong>og</strong> indgår i summering <strong>af</strong> arealerne <strong>af</strong> baggrundspixelene<br />

(tæller i venstre led i ligning (7.1)), <strong>og</strong> summering <strong>af</strong> antallet <strong>af</strong> forekomster for den på<br />

gældende pixelintensitet (nævner i venstre led i ligningen)<br />

b. Over er forgrundspixel, <strong>og</strong> samme retorik for forgrundspixels gælder som beskrevet i<br />

punkt a.<br />

3. Efter endt summering findes der en gennemsnitsværdi for både baggrunds- <strong>og</strong><br />

forgrundsarealet (optræder som di<strong>vision</strong>en med tæller- <strong>og</strong> nævnersummeringerne)<br />

4. Herefter findes gennemsnitsværdi for baggrunds- <strong>og</strong> forgrundsgennemsnitsværdierne.<br />

Denne værdi er den nye thresholdværdi T k (optræder som den halve der er ganget på begge<br />

led i ligningen)<br />

5. Processen gentages fra trin 2 til <strong>og</strong> med 4 indtil thresholdværdien ikke ændrer sig mere<br />

(7.1)<br />

Side 25 <strong>af</strong> 131


7 Binary 7.3 Test<br />

7.3 Test<br />

Figur 7.2<br />

Implementering <strong>af</strong> H. J. Trussels formel<br />

Det er formålet med testen, at undersøge hvorledes den udviklede kode, vil udregne<br />

thresholdværdien for et billede. Der <strong>brug</strong>es i alt 11 billeder i testen (ligger på DVD’en i ”7.<br />

Binary\Inputbilleder til test”). For hvert billede der testes registreres gennemsnitsværdierne for baggrunds-<br />

<strong>og</strong> forgrundsarealet (punkt 3 i 7.2.2 Iterativ thresholding-teknik s. 24), <strong>og</strong> thresholdværdien for<br />

hver iteration. Ydermere udprinter klassen automatisk hist<strong>og</strong>rammet for billedet i MatLab-kode, så<br />

der nemt kan tegnes en gr<strong>af</strong> ud fra dataene (disse findes som ”hist<strong>og</strong>ram.m” i ”Data”-biblioteket).<br />

Billedet herunder (figur 7.3) beskriver iterationsprocessen på hist<strong>og</strong>rammet ud fra data fra test på det<br />

første billede ”blandet1”. B K beskriver baggrundsarealets gennemsnitsværdi for k’te iteration, <strong>og</strong> på<br />

samme måde med F for forgrundsarealet. T k beskriver thresholdværdien for k’te iteration.<br />

Side 26 <strong>af</strong> 131


7 Binary 7.4 Sammenfatning<br />

Det ses på figur 7.3, at som der<br />

itereres placeres thresholdværdien<br />

længere <strong>og</strong> længere mod venstre <strong>og</strong><br />

konvergerer til en threshold på 87 i<br />

pixelintensitet.<br />

Testresultater for alle 11 billeder<br />

findes i Appendiks 18.10 Test <strong>af</strong> Binary<br />

s. 124.<br />

7.4 Sammenfatning<br />

Det kan overordnet konkluderes, at<br />

det har været muligt at skabe en<br />

klasse, der med succes kan thresholde<br />

et billede.<br />

Klassen indeholder en funktion, der<br />

kan skabe et hist<strong>og</strong>ram over et givent<br />

billede, hefter en funktion der kan<br />

anvende hist<strong>og</strong>rammet <strong>og</strong> evaluere en<br />

thresholdværdi, der passer til billedet.<br />

Til sidst er der lavet en funktion, der<br />

kan anvende thresholdværdien på det<br />

oprindelige billede, <strong>og</strong> skabe et nyt<br />

binært billede der er thresholdet med<br />

thresholdværdien.<br />

Figur 7.3<br />

Demonstration <strong>af</strong> algoritme med billedet ”blandet1” som eksempel<br />

Testen viser, at implementeringen <strong>af</strong> koden virker som den skal. Thresholdværdien lægger sig<br />

imellem de to peaks i hist<strong>og</strong>rammet som ønsket, <strong>og</strong> <strong>ved</strong> visuel inspektion <strong>af</strong> de thresholdede billeder,<br />

er det klart at mindre mængder genskin <strong>og</strong> andet ”støj” bliver sorteret fra som ønsket.<br />

Det vurderes, at det ikke har n<strong>og</strong>en væsentlig effekt, hvad det indledende gæt på thresholdværdien<br />

T 0 er ud fra gruppens forsøg. Dvs. det betyder ikke n<strong>og</strong>et, om det vælges at starte yderst fra højre<br />

( 0 T = 255) eller om 0 T = 127. Det eneste sted hvor der kan findes en forskel, er når T 0 = 0. Denne<br />

forskel er d<strong>og</strong> sjældent mere end 1 pixel i pixelintensitet. Derfor findes det mest l<strong>og</strong>isk <strong>og</strong> effektivt at<br />

vælge T 0 = 127, da dette er midten <strong>af</strong> skalaen, <strong>og</strong> samtidigt i nærheden <strong>af</strong> den resulterende thresholdværdi<br />

i langt det fleste tilfælde, hvilket vil give en potentielt kortere iterationsproces.<br />

Samlet kan det konkluderes, at klassen korrekt identificerer thresholdværdien, <strong>og</strong> anvender denne til<br />

at skabe et thresholdet billede fra det oprindelige gråtonebillede.<br />

Side 27 <strong>af</strong> 131


8 BlobDetection 8.1 Indledning<br />

8 BlobDetection<br />

8.1 Indledning<br />

Formålet med denne klasse er, at kunne detektere de enkelte objekter i et binært billede, <strong>og</strong> kunne<br />

videregive data om disse objekter til andre klasser. Objekter, der ligger i kanten <strong>af</strong> billedet, skal<br />

sorteres fra, da det ikke er sikkert, at hele objektet ligger inden for billedet. Ligeledes skal objekter,<br />

der er uden for givne arealgrænser, sorteres fra. I opbygning <strong>af</strong> algoritmen anvendes der principper<br />

fra Davies [3:159-167], der er blevet modificeret til gruppens behov.<br />

8.2 Teori<br />

En blob er en gruppering <strong>af</strong> en eller flere hvide forgrundspixels, som har kontakt med hinanden. Til<br />

de enkelte blobs knytter der sig oplysninger omkring størrelse <strong>og</strong> placering i billedet.<br />

En subblob er forstadiet til en blob. Hvis to eller flere subblobs viser sig at have<br />

kontakt med hinanden, vil disse blive knyttet sammen inden de bliver til en blob.<br />

Billedet bliver behandlet pixel for pixel. Den pixel der behandles på et givent<br />

tidspunkt kaldes A0. De omkringliggende pixels kaldes for A1-8 (figur 8.1). Hvis A0<br />

er tændt tilhører den en blob. De <strong>af</strong> dens naboer (A1-8), der er tændt, tilhører den<br />

samme blob.<br />

8.2.1 Knytning <strong>af</strong> pixels til subblobs<br />

Billedet bliver kontrolleret pixelvis, hvor alle tændte pixels bliver knyttet til en subblob efter<br />

følgende princip:<br />

• Hvis en eller flere <strong>af</strong> nabopixelene er knyttet til en subblob, knyttes A0 til den samme<br />

subblob<br />

• Hvis en eller flere <strong>af</strong> nabopixelene er knyttet til forskellige subblobs, forenes disse subblobs<br />

<strong>og</strong> A0 knyttes til disse<br />

• Hvis ingen <strong>af</strong> nabopixelene er knyttet til en subblob, oprettes der en ny subblob som A0<br />

knyttes til<br />

A5 A0<br />

A4 A3 A2<br />

Figur 8.2<br />

Den aktuelle<br />

pixel <strong>og</strong> de 4<br />

interessante<br />

naboer<br />

A6 A7 A8<br />

A5 A0 A1<br />

A4 A3 A2<br />

Figur 8.1<br />

Den aktuelle<br />

pixel <strong>og</strong> dens<br />

otte naboer<br />

Da billedet bliver kontrolleret pixelvis, vil kun de 4 <strong>af</strong> naboerne (A2-A5) til en given<br />

pixel have været kontrolleret forinden. Dette gør, at det kun er muligt at knytte en<br />

pixel til de subblobs, der ligger i A2-5. Dermed bliver kontrollen <strong>af</strong> A1 <strong>og</strong> A6-8 udsat,<br />

til når algoritmen når til næste pixel <strong>og</strong> næste linie, hvor de pixels så vil blive knyttet<br />

til deres naboer (A2-5). På dette grundlag undersøges kun A2-A5 (figur 8.2) <strong>og</strong> ikke<br />

A1 <strong>og</strong> A6-A8.<br />

Side 28 <strong>af</strong> 131


8 BlobDetection 8.2 Teori<br />

8.2.1.1 Eksempel<br />

Figur 8.3<br />

Billede på 5x6 pixel med to<br />

forgrundspixels<br />

Et simpelt billede i størrelsen 6x5 pixel, hvor<br />

alle pixels er slukket med undtagelse <strong>af</strong> de to<br />

midterste (figur 8.3). Algoritmen kontrollerer<br />

billedet nedefra <strong>og</strong> op, hvor den ikke vil finde<br />

n<strong>og</strong>en tændte pixels i de to første rækker.<br />

Først <strong>ved</strong> 3. pixel i 3. række (figur 8.4) finder<br />

den en tændt pixel. Det bliver kontrolleret,<br />

om dens 4 naboer (A2-5) er knyttet til en<br />

subblob. Da ingen <strong>af</strong> dem er tændte, er de<br />

heller ikke knyttet til en subblob. Derfor oprettes der en ny subblob, som<br />

den aktuelle pixel knyttes til. Når dette er gjort, forsætter algoritmen til<br />

næste pixel (figur 8.5). Denne pixel er <strong>og</strong>så tændt, <strong>og</strong> derfor kontrolleres<br />

<strong>og</strong>så dennes 4 naboer. Af dens naboer er den ene tændt (A5), <strong>og</strong> dermed<br />

knyttes A0 til samme subblob som A5. Resten <strong>af</strong> billedet løbes igennem,<br />

men der findes ikke flere tændte pixels. Nu har algoritmen fundet en<br />

subblob, som består <strong>af</strong> 2 pixels.<br />

8.2.2 Knytning <strong>af</strong> subblobs<br />

Under kontrollen <strong>af</strong> et billede, kan der forekomme situationer, hvor 2 eller flere subblobs har<br />

kontakt med hinanden. Disse situationer fremkommer, hvis 2 eller flere <strong>af</strong> A0s fire naboer er<br />

knyttet til forskellige subblobs.<br />

Sammenknytningen laves vha. en træstruktur, hvori det noteres hvilke subblobs der hænger sammen.<br />

Alle subblobs oprettes som deres egen rod i hvert deres rodsystem, uden at der er andre<br />

elementer i systemet. Hvis to subblobs knyttes sammen, gøres det <strong>ved</strong> at gøre den med det højeste<br />

subblobnummer til en gren i den andens rodsystem.<br />

Træstrukturen realiseres i en liste, hvor der er en plads til hver subblob. Når en subblob oprettes,<br />

skrives dens subblobnummer ind på dens plads. Hvis den senere knyttes til en anden subblob,<br />

ændres værdien på pladsen, så subblobben nu peger på dens rod.<br />

8.2.2.1 Eksempel<br />

Figur 8.6<br />

Billede med to blobs som bliver detekteret<br />

som flere subblobs<br />

Billedet (figur 8.6) viser et eksempel<br />

med to blobs som i algoritmen først<br />

vil blive detekteret som 4 subblobs,<br />

men hvor de 3 knyttes sammen, så<br />

der kun er 2 blobs.<br />

Billedet kontrolleres nedefra, hvor<br />

de enkelte pixels bliver knyttet til<br />

forskellige subblobs. Som det er vist<br />

på figur 8.7, bliver de enkelte pixels<br />

knyttet til de samme subblobs som<br />

deres naboer. Ved A- <strong>og</strong> B-pixelene<br />

er der to forskellige naboer, så der<br />

skal to subblob knyttes sammen.<br />

A5 A0<br />

A4 A3 A2<br />

Figur 8.4<br />

Naboerne til pixelen i (2,2)<br />

bliver undersøgt<br />

A5 A0<br />

A4 A3 A2<br />

Figur 8.5<br />

Naboerne til pixelen i (3,2)<br />

bliver undersøgt<br />

B 3<br />

0 2 A<br />

0 2 1 1<br />

0 1 1<br />

Figur 8.7<br />

Billede delt op i subblobsne 0, 1, 2 <strong>og</strong><br />

3, hvor pixelene i A <strong>og</strong> B sammenkæder<br />

de forskellige subblobs<br />

Side 29 <strong>af</strong> 131


8 BlobDetection 8.3 Test<br />

Figur 8.8<br />

De fire subblobs som ikke er<br />

knyttet sammen<br />

På figur 8.6 bliver der detekteret 4 subblobs,<br />

som sættes op som hver deres rod<br />

(figur 8.8).<br />

Nå algoritmen analyserer A-pixelen i figur<br />

8.7, opdages det at subblob 1 <strong>og</strong> 2 er den samme, <strong>og</strong> derefter knyttes<br />

subblob 2 til subblob 1 (figur 8.9).<br />

Senere, <strong>ved</strong> analysering <strong>af</strong> B-pixelen, opdages det, at subblob 2 <strong>og</strong><br />

subblob 0 <strong>og</strong>så skal kædes sammen. Men da subblob 2 allerede er<br />

knyttet til subblob 1, kan den ikke knyttes til subblob 0. I stedet<br />

knyttes subblob 1 (subblob 2’ rod) til subblob 0 (figur 8.10). På denne<br />

måde bliver alle de 3 subblobs knyttet sammen.<br />

8.2.3 Blob sammensætning<br />

Ud fra subblob-træstrukturen laves de endelige blobs. Der bliver lavet en liste med subblobs, som<br />

<strong>brug</strong>es til at knytte de enkelte subblobs til de forskellige blobs.<br />

8.2.4 Boundingbox<br />

For hver blob på billedet, findes det mindste rektangel, som hele blobben kan være indenfor. Dette<br />

rektangel kaldes for en boundingbox <strong>og</strong> består <strong>af</strong> 4 koordinater. Disse koordinater findes, <strong>ved</strong> at<br />

kontrollere samtlige pixels i billedet. Hvis pixelen er knyttet til en blob, kontrolleres det om den<br />

ligger inden i boundingboxen for den givne blob. Hvis den ikke ligger inden for boxen, udvides<br />

denne, så den aktuelle pixel kommer indenfor.<br />

8.2.5 Seed generering<br />

Alle blobs, hvis arealer er for små eller for store, i forhold til de <strong>brug</strong>erspecificerede grænser, sorteres<br />

fra. Dette gøres for at eliminere falske detekteringer fra f.eks. genskin <strong>og</strong> andet ”støj”. Blobs, som<br />

har kontakt med kanten sorteres <strong>og</strong>så fra, da det ikke er muligt at vide, om n<strong>og</strong>et <strong>af</strong> det enkelte<br />

objekt ligger uden for billedet. Der generes et binærtbillede <strong>af</strong> de enkelte blobs, så efterfølgende<br />

pr<strong>og</strong>ramkode kan tilgå et billede <strong>af</strong> de enkelte objekter. Da objekterne skal sendes videre til de andre<br />

dele <strong>af</strong> pr<strong>og</strong>rammet, laves her en liste, hvor der gemmes oplysninger om de enkelte objekter.<br />

8.3 Test<br />

Testen har til formål at vise, at BlobDetection kan:<br />

• lokalisere de enkelte objekter i billedet<br />

• frasortere objekter der ligger i kanten eller hvis areal er under en minimums- eller over en<br />

maksimumsgrænse<br />

De to delformål vil blive testet separat.<br />

0 1 3<br />

2<br />

Figur 8.9<br />

Subblob 2 knyttet til subblob 1<br />

0<br />

1<br />

2<br />

Figur 8.10<br />

Subblob 0, 1 <strong>og</strong> 2 er nu knyttet<br />

sammen<br />

3<br />

Side 30 <strong>af</strong> 131


8 BlobDetection 8.3 Test<br />

8.3.1 Deltest 1<br />

Denne tests formål er, at<br />

vise at BlobDetection kan<br />

lokalisere de enkelte objekter<br />

i et billede.<br />

Billedet på figur 8.11 består<br />

<strong>af</strong> 11 forskellige elementer<br />

i forskellige former <strong>og</strong><br />

størrelser. Øverst ses de fire<br />

forskellige måder, hvorpå<br />

en pixel (A0) kan være<br />

nabo til en anden pixel<br />

(A2-5). Det forventes at<br />

disse 4 objekter, hver bliver<br />

detekteret som en<br />

blob. I den midterste række<br />

vises objekter med forskellige<br />

størrelser samt<br />

elementer med huller i.<br />

Det forventes igen, at disse<br />

objekter bliver detekteret<br />

som hver deres blob. De<br />

nederste 3 objekters ud-<br />

seende gør, at de først vil blive detekteret som flere subblobs, men senere vil blive kædet sammen.<br />

Denne detektering <strong>og</strong> sammenknytning forventes at resultere i, at de tre objekter bliver detekteret<br />

som tre blobs.<br />

8.3.1.1 Testresultater<br />

Figur 8.11<br />

Testbillede som udsætter BlobDetection for forskellige situationer<br />

Algoritmen har, ud fra billedet i figur 8.11, fundet dataene i tabel 8.1:<br />

Number BoundsXMin BoundsXMax BoundsYMin BoundsYMax Area<br />

0 5 22 4 12 90<br />

1 29 31 8 9 3<br />

2 42 45 8 11 10<br />

3 5 5 22 22 1<br />

4 16 18 22 24 9<br />

5 28 32 22 26 25<br />

6 42 48 22 28 24<br />

7 11 12 37 37 2<br />

8 21 22 37 38 2<br />

9 33 33 37 38 2<br />

10 41 42 37 38 2<br />

Tabel 8.1<br />

Number er nummeret på den enkelte blob. Da billedet bliver analyseret fra bunden <strong>og</strong> op vil<br />

de nederste objekter have de laveste numre. BoundsXMin, BoundsXMax, BoundsYMin <strong>og</strong><br />

BoundsYMax koordinaterne for de enkelte objekters boundingboxes. Area er arealet på de forskellige<br />

objekter<br />

Med klassen Draw (Appendiks 18.9.10 Draw s. 121) plottes de forskellige blobs i forskellige farver, <strong>og</strong><br />

ydermere bliver der plottet en omkringliggende ramme til de enkelte blobs (figur 8.12). Disse rammer<br />

Side 31 <strong>af</strong> 131


8 BlobDetection 8.3 Test<br />

svarer næsten til boundingboxene, men de er udvidet med en pixel i alle retninger, for at de ikke skal<br />

dække for n<strong>og</strong>et <strong>af</strong> de enkelte objekter.<br />

8.3.2 Deltest 2<br />

Figur 8.12<br />

Resultat <strong>af</strong> første deltest<br />

Formålet med testen er at<br />

vise, at algoritmen kan<br />

frasortere de objekter, der<br />

ligger i kanten <strong>af</strong> billedet, <strong>og</strong><br />

de objekter, hvis areal er uden<br />

for <strong>brug</strong>er specificerede<br />

grænser.<br />

Testen <strong>af</strong>vikles <strong>ved</strong> at teste et<br />

billede (figur 8.13) <strong>af</strong> 16 forskellige<br />

objekter. Disse objekter<br />

er fordelt i billedet, så<br />

n<strong>og</strong>le ligger i kanten <strong>og</strong> andre<br />

ligger tilfældigt rundt i billedet.<br />

Samtidigt har de<br />

forskellige størrelser.<br />

Fire <strong>af</strong> disse objekter ligger i<br />

kanten <strong>af</strong> billedet. Algoritmen<br />

<strong>af</strong>vikles med en minimumsarealgrænse<br />

på 5 <strong>og</strong> en maksimumsarealgrænse<br />

på 100.<br />

Figur 8.13<br />

Testbillede til anden del <strong>af</strong> testen<br />

Side 32 <strong>af</strong> 131


8 BlobDetection 8.4 Sammenfatning<br />

Blandt de forskellige objekter i billedet, er der n<strong>og</strong>le, der er mindre end minimumsgrænsen, <strong>og</strong> n<strong>og</strong>le<br />

der er mellem de 2 grænser, mens der er andre der er større end maksimumsgrænsen.<br />

På figur 8.14 vises resultatet fra deltest 2 genereret via Draw-klassen:<br />

Figur 8.14<br />

Resultat <strong>af</strong> anden deltest<br />

8.4 Sammenfatning<br />

I deltest 1 fremgår det, at algoritmen har adskilt de forskellige objekter i billedet fra hinanden. Det<br />

ses <strong>og</strong>så at de enkelte objekters boundingboxkoordinater <strong>og</strong> areal er blevet optalt korrekt. I figur 8.12<br />

får de enkelte objekter hver deres farve, hvilket viser at algoritmen har adskilt dem. Ydermere ses<br />

det, at alle objekter er blevet detekteret korrekt.<br />

I resultaterne fra deltest 2 ses det, at antallet <strong>af</strong> objekter er blevet reduceret (figur 8.14). 4 <strong>af</strong> objekterne<br />

er fjernet pga. de ligger i kanten <strong>af</strong> billedet. 3 objekter er fjernet, da de er mindre en minimumgrænsen<br />

på 5, mens 2 objekter er fjernet, pga. de er større end maksimumsgrænsen på 100.<br />

Ud fra resultatet <strong>af</strong> deltest 2 kan det ses, at algoritmen er i stand til at fjerne de objekter, der ligger i<br />

kanten <strong>af</strong> billedet, <strong>og</strong> de objekter hvis areal er uden for <strong>brug</strong>erspecificerede grænser.<br />

Det kan konkluderes, at algoritmen kan finde de enkelte objekter i billedet. Ydermere frasorterer<br />

algoritmen de objekter, der ligger i kanten <strong>af</strong> billedet, <strong>og</strong> evt. de hvis arealer er over eller under<br />

<strong>brug</strong>erspecificerede grænser. Samtidigt finder algoritmen objekternes areal samt deres boundingboxkoordinater.<br />

Side 33 <strong>af</strong> 131


9 EllipseApproximation 9.1 Indledning<br />

9 EllipseApproximation<br />

9.1 Indledning<br />

Det er formålet med EllipseApproximation-klassen, at skabe en måde hvorpå et objekts (kims)<br />

midtpunkt <strong>og</strong> orientering i planet kan bestemmes (Horn [4:48-53]). En måde at gøre dette på er <strong>ved</strong><br />

at antage, at objektet har en <strong>af</strong>lang<br />

form, der kan sammenlignes med en<br />

ellipse. Dette gøres <strong>ved</strong> at undersøge<br />

det binære billede <strong>af</strong> hver blob. Herfra<br />

er det muligt at bestemme et midtpunkt<br />

x,y ) i objektet (figur 9.1). Herefter<br />

a<br />

( 0 0<br />

tilpasses en ellipse ud fra objektets udseende.<br />

Den resulterende ellipses stor-<br />

(a ) <strong>og</strong> lille-akse (b ) danner hver en<br />

vinkel θmajor<strong>og</strong> θ min or med det vandrette<br />

plan. Når disse 3 sæt <strong>af</strong> data er<br />

kendt, er det muligt at angive kimets<br />

placering <strong>og</strong> orientering i forhold til det<br />

vandrette plan.<br />

Ellipseapproksimationsalgoritmen skal<br />

ikke kun begrænses til at tilpasse<br />

ellipser til kim, men til enhver given<br />

form.<br />

9.2 Teori<br />

Som fundament til ellipseapproksimationen <strong>brug</strong>es et binært<br />

billede, som er resultatet <strong>af</strong> Binary-klassen. Det binære<br />

billede er et 2-dimensionelt array, hvor der på hver plads<br />

står enten 0 eller 255. På den måde er det entydigt <strong>af</strong>klaret,<br />

hvad der er forgrund <strong>og</strong> baggrund (figur 9.2). Funktionen<br />

bxy (, ) beskriver det binære array:<br />

⎧⎪<br />

255<br />

bxy (, ) = ⎨<br />

⎪⎩<br />

0<br />

(9.1)<br />

Dermed kan arealet <strong>af</strong> objektet bestemmes som:<br />

Figur 9.1<br />

3 sæt <strong>af</strong> interessante ellipseparametre<br />

θmin<br />

or<br />

θmajor<br />

x,y 0 0<br />

A = ∫∫ b(, x y) dx dy<br />

(9.2)<br />

y<br />

b<br />

Figur 9.2<br />

bxy (, ) definerer objektet<br />

b(x,y) = 255<br />

b(x,y) = 0<br />

x<br />

Side 34 <strong>af</strong> 131


9 EllipseApproximation 9.2 Teori<br />

9.2.1 Massemidtpunkt<br />

I forbindelse med udregningen <strong>af</strong> objektets orientering, er det nødvendigt at finde midten <strong>af</strong><br />

objektet. Der findes en anal<strong>og</strong>i imellem midtpunktet <strong>og</strong> fysikkens massemidtpunkt. Det kan antages<br />

at et objekts arealmidtpunkt, svarer til et objekt <strong>af</strong> samme forms massemidtpunkt, der har en<br />

konstant masse per arealenhed. I det 2-dimensionelle plan kan momenterne omkring x- <strong>og</strong> y-aksen<br />

bestemmes som koordinatet multipliceret med pixelintensiteten:<br />

I () x = xb(,) x y<br />

x<br />

I () y = yb(, x y)<br />

y<br />

Findes gennemsnittet <strong>af</strong> inertimomenterne i begge dimensioner, findes x- <strong>og</strong> y-koordinatet for<br />

massemidtpunktet <strong>af</strong> objektet ( , )<br />

xy :<br />

∫∫ ∫∫<br />

∫∫ ∫∫<br />

x b(, x y) dx dy yb(, x y) dx dy<br />

x = , y =<br />

b(, x y) dx dy b(, x y) dx dy<br />

Hermed er koordinaterne for massemidtpunktet i objektet fundet.<br />

9.2.2 Orientering i planet<br />

Formålet med dette <strong>af</strong>snit er at udvikle en metode til at<br />

bestemme orienteringen <strong>af</strong> objektet i planet i forhold til xaksen.<br />

Det forudsættes at objektet er <strong>af</strong>langt <strong>af</strong> form, <strong>og</strong> det<br />

er denne retning det ønskes at finde. Dette kan gøres <strong>ved</strong>, at<br />

bestemme den linie hvor inertimomentet i objektet er<br />

mindst. Dvs. det <strong>af</strong>gøres ikke, hvad der er top <strong>og</strong> bund, blot<br />

hvilken orientering objektet har i planet.<br />

Det ønskes at finde den linie der angiver, hvor inertimoment<br />

(I) er mindst. Dette ønskes altså at bestemme minimum <strong>af</strong><br />

flg. formel:<br />

2<br />

I = ∫∫ r b(, x y) dxdy (9.5)<br />

, hvor r er den korteste <strong>af</strong>stand fra et punkt (x,y) i objektet,<br />

til et punkt (x 0,y 0) på linien der ønskes fundet (figur 9.3).<br />

En detaljeret gennemgang <strong>af</strong> den bag<strong>ved</strong>liggende matematik kan findes i Appendiks 18.5 Orientering i<br />

planet s. 89. D<strong>og</strong> kan der her fremhæves to vigtige resultater fra gennemgangen. Ligningen for<br />

inertimomentet i objektet kan udtrykkes som:<br />

(9.3)<br />

(9.4)<br />

1 1 1<br />

I = ( A+ C) − ( A−C) cos2θ− Bsin<br />

2θ<br />

(9.6)<br />

2 2 2<br />

, hvor A, B <strong>og</strong> C er integraler der <strong>af</strong>hænger <strong>af</strong> objektets form.<br />

y<br />

(x,y)<br />

r<br />

(x0,y0)<br />

b(x,y)<br />

Figur 9.3<br />

(, xy) er et tilfældigt punkt i objektet<br />

bxy<br />

(, )<br />

x<br />

Side 35 <strong>af</strong> 131


9 EllipseApproximation 9.2 Teori<br />

Der findes en løsning til henholdsvis cos2θ <strong>og</strong> sin 2θ . Disse kan indsættes i ligning (9.6). Hver <strong>af</strong><br />

de to løsninger har hver en negativ <strong>og</strong> positiv løsning. Anvendes den negative løsning i både<br />

cos2θ <strong>og</strong> sin 2θ , fås det mindste inertimoment I min, <strong>og</strong> tilsvarende giver de positive løsninger det<br />

største inertimoment I max. Disse skal senere anvendes direkte til at bestemme længden på<br />

henholdsvis lille- <strong>og</strong> storaksen i ellipsen.<br />

Vinklen til storaksen i ellipsen kan bestemmes som:<br />

θ =<br />

major<br />

1 arcsin<br />

2<br />

9.2.3 Vigtige tilfælde<br />

( ) 2<br />

⎛<br />

B<br />

⎞<br />

⎜ ⎟<br />

⎜ 2<br />

B + A−C ⎟<br />

⎝ ⎠<br />

Det er nødvendigt at vurdere resultatet <strong>af</strong> udregningen <strong>af</strong> vinklen i forhold værdierne <strong>af</strong> integralerne<br />

A <strong>og</strong> C i Appendiks 18.5 Orientering i planet s. 89. Problemet kan illustreres, <strong>ved</strong> at forestille sig to<br />

ellipser der begge er roterede henholdsvis 22,5° <strong>og</strong> 67,5° (figur 9.4):<br />

Figur 9.4<br />

22,5° <strong>og</strong> 67,5° giver samme vinkelresultat<br />

Forskellen imellem de to ellipser er umiddelbart deres drejning i planet, men udregnes vinklen de er<br />

roterede med ligning (9.7) fås begge som resultat 22,5°. Dvs. en ellipse der er drejet 67,5° i planet<br />

detekteres til at være drejet 22,5°. Faktum er, at størrelsesforholdet mellem integralerne A <strong>og</strong> C<br />

<strong>af</strong>hænger <strong>af</strong> vinklingen i planet:<br />

A < C for θ < 45°<br />

major<br />

A = C for θ = 45°<br />

major<br />

A > C for θ > 45°<br />

major<br />

Dette er i sig selv godt nok, men da (A-C) kvadreres i nævneren i ligning (9.7), vil vinkler over <strong>og</strong><br />

under 45° give det samme resultat. Derfor skal størrelsesforholdet mellem A <strong>og</strong> C undersøges, hvis<br />

det vil vurderes, om den vinkel der er udregnet ligger over eller under 45°. Hvis vinklen ligger over<br />

45°, skal den udregnes som 90° - 45°. Dette svarer til en spejling omkring 45°.<br />

(9.7)<br />

(9.8)<br />

Side 36 <strong>af</strong> 131


9 EllipseApproximation 9.2 Teori<br />

Den anden problemstilling ligger i, hvis ellipsen er den særlige cirkelform, hvor excentriciteten er 0. I<br />

denne situation vil B=0 <strong>og</strong> A=C. Da ellipsen er helt cirkulær, giver det ikke mening at tale om en<br />

akse i cirklens længderetning.<br />

9.2.4 Bestemmelse <strong>af</strong> ellipseparametre<br />

Inertimomenterne <strong>og</strong> vinklen udregnet i foregående <strong>af</strong>snit skal <strong>brug</strong>es direkte til at bestemme de<br />

resterende ellipseparametre. Det ønskes, som beskrevet i indledningen, at finde længderne på stor-<br />

<strong>og</strong> lilleaksen samt excentriciteten.<br />

Det gælder at:<br />

2<br />

Imin b<br />

= (9.9)<br />

2<br />

I a<br />

max<br />

Længderne b <strong>og</strong> a kan herefter bestemmes ud fra 2 relationer:<br />

e =<br />

2<br />

b<br />

1 − 2<br />

a<br />

(9.10)<br />

A = abπ<br />

(9.11)<br />

, hvor e er excentriciteten <strong>og</strong> A er arealet <strong>af</strong> ellipsen. Det beskrives nærmere i Appendiks 18.6<br />

Bestemmelse <strong>af</strong> ellipseparametre s. 91, hvorledes længderne a <strong>og</strong> b, kan bestemmes som:<br />

a<br />

=<br />

π<br />

A<br />

I<br />

I<br />

min<br />

max<br />

(9.12)<br />

A<br />

b = (9.13)<br />

π a<br />

Hermed er der udledt udtryk for bestemmelse <strong>af</strong> længderne <strong>af</strong> stor- (a ) <strong>og</strong> lille-akse (b ) samt excentriciteten<br />

(e ).<br />

Side 37 <strong>af</strong> 131


9 EllipseApproximation 9.3 Test<br />

9.3 Test<br />

9.3.1 Beskrivelse<br />

Det ønskes, at teste hvorvidt ellipseapproksimationsalgoritmen virker efter hensigten. Det er<br />

beskrevet i indledningen, at ellipseapproksimationsalgoritmens formål er at på enhver given form at<br />

kunne approksimere en ellipse. Det kan være svært <strong>ved</strong> alene visuel inspektion, at <strong>af</strong>gøre hvorvidt<br />

ellipsen er korrekt approksimeret, når der arbejdes med irregulære former. Derfor er det besluttet, at<br />

første del <strong>af</strong> testen går på at anvende ellipser som input til algoritmen. Det må være således, at hvis<br />

algoritmen kan analysere en ellipse i inputbilledet, uden at ”være klar over” det er en ellipse, <strong>og</strong> så<br />

bestemme en ellipse, der med rimelighed passer på inputellipsen, så må algoritmen være<br />

funktionsduelig. Succeskriteriet er altså opnået såfremt algoritmen bestemmer en ellipse, der passer<br />

på inputellipsen. Det er ikke muligt, at <strong>af</strong>gøre hvor godt ellipsen skal tilpasses, da der ikke stilles krav<br />

herom fra n<strong>og</strong>en steder.<br />

Det vurderes, at det er interessant at teste algoritmens reaktion på forskellige varierende parametre:<br />

• Excentricitet<br />

• Størrelsen på figur<br />

• Vinkel med x-akse<br />

• Alle ovenstående kombineret<br />

Anden del <strong>af</strong> testen går på, at teste hvorvidt algoritmen kan tilpasse en ellipse til et objekt, der ikke<br />

er ellipseformet, heriblandt firkanter, trekanter <strong>og</strong> polygoner.<br />

For at anskueliggøre resultaterne <strong>af</strong> testen på en simpel <strong>og</strong> overskuelig måde, er det besluttet at<br />

anvende Draw- <strong>og</strong> Color-klassen til henholdsvis at tegne <strong>og</strong> udskrive de udregnede ellipser i et<br />

BMP-billede. Det skal derfor bemærkes, at der i er mulighed for at testresultaterne påvirkes, da<br />

andre algoritmer anvendes til at udskrive dem, men det vurderes <strong>af</strong> gruppen, at disse påvirkninger er<br />

minimale.<br />

Som input til algoritmen blev 2 billeder lavet (figur 9.5 <strong>og</strong> figur 9.6, vises her i nedskaleret form):<br />

Side 38 <strong>af</strong> 131


9 EllipseApproximation 9.3 Test<br />

Figur 9.5<br />

1. testbillede der var input til algoritmen. Her testes algoritmens evne til at approksimere en ellipse til en ellipse<br />

Figur 9.6<br />

2. testbillede med trekanter, firkanter <strong>og</strong> andre polygoner<br />

Side 39 <strong>af</strong> 131


9 EllipseApproximation 9.3 Test<br />

9.3.2 Testresultater<br />

Ved <strong>af</strong>vikling <strong>af</strong> algoritmen blev flg. billeder outputtet som resultat (figur 9.7 <strong>og</strong> figur 9.8). Det<br />

anbefales at nærstudere billederne <strong>ved</strong>lagt på DVD’en under ”9. EllipseApproximation<br />

\Testresultater”, da billedet er <strong>af</strong> høj opløsning <strong>og</strong> vises nedskaleret her:<br />

Figur 9.7<br />

Testresultater fra 1. billede<br />

Side 40 <strong>af</strong> 131


9 EllipseApproximation 9.4 Sammenfatning<br />

Figur 9.8<br />

Testresultater fra 2. testbillede<br />

9.4 Sammenfatning<br />

Det kan overordnet konkluderes, at det har været muligt at fremstille en algoritme, der kan<br />

approksimere en ellipse til en given form. Som beskrevet i indledningen til testen, <strong>af</strong>gøres det ikke<br />

kvantitativt, hvor godt ellipserne passer til figurerne, men kun rent kvalitativt.<br />

Det ses, at i den første del <strong>af</strong> testen, hvor inputtet til algoritmen er ellipseformer, tilpasses ellipserne<br />

med stor nøjagtighed til inputellipserne. Først er der bestemt et massemidtpunkt i figuren. Herfra<br />

har ellipsens to principale akser deres begyndelse. Det ses tydeligt, at de tilpassede ellipsers lille- <strong>og</strong><br />

storakser passer med inputellipsernes lille- <strong>og</strong> stor-akser. Ydermere ses det her, at ellipseapproksimationen<br />

fungerer lige vel <strong>ved</strong> forskellige excentriciteter, størrelser <strong>og</strong> vinkler <strong>og</strong> kombinationer her<strong>af</strong>.<br />

Ved nærundersøgelse <strong>af</strong> billedet (<strong>ved</strong> mange gange zoom) ses det, at <strong>ved</strong> mange <strong>af</strong> ellipserne (f.eks.<br />

20 til <strong>og</strong> med 30) er massemidtpunktet forskudt en smule. Dette ses i form <strong>af</strong>, at det sted, hvor de to<br />

akser i ellipsen krydser, ikke er det udregnede massemidtpunkt, men at massemidtpunktet ligger lige<br />

<strong>ved</strong> siden <strong>af</strong>. Dette skyldes <strong>af</strong>runding i forbindelse med tegningen <strong>af</strong> akserne, <strong>og</strong> har ikke n<strong>og</strong>et med<br />

ellipseapproksimationsalgoritmen som så at gøre, men problemet opstår i forbindelse med selve<br />

tegningen <strong>af</strong> akserne i Draw-klassen. Dette er et nødvendigt onde for at kunne præsentere<br />

resultaterne på denne mere overskuelige måde.<br />

I den anden del <strong>af</strong> testen ses det, at algoritmen tilpasser en ellipse med succes til forskellige andre<br />

typer <strong>af</strong> inputformer end ellipser. Som det fremgår, opnås der <strong>og</strong>så her gode resultater. Det ses, at<br />

ellipsens areal stemmer overens med objekternes areal, da det areal der ligger uden for objektet<br />

svarer til det areal <strong>af</strong> objektet, der ligger uden for ellipsens areal.<br />

Ellipserne med nr. 20, 21, 22 er alle tegnet med samme excentricitet. Men som det fremgår <strong>af</strong><br />

testresultaterne, så har nr. 20 <strong>og</strong> 22 en vinkel fra storaksen til det vandrette plan på 90°. Dette skyldes,<br />

at algoritmen har fundet en (meget lille) unøjagtighed i ellipsens form. Denne unøjagtighed gør,<br />

at integralerne A <strong>og</strong> C ikke er lige store, selvom det d<strong>og</strong> er tæt på. Som omtalt tidligere, vil en ellipse<br />

med excentricitet på 0 gøre at A=C <strong>og</strong> B=0. I tilfældet med nr. 20 <strong>og</strong> 22 er A d<strong>og</strong> meget tæt på at<br />

være lig C, men ikke helt, <strong>og</strong> dette giver derfor en vinkel på 90° <strong>og</strong> ikke 0°.<br />

På mange <strong>af</strong> ellipserne på det 2. testbillede (f.eks. nr. 37 <strong>og</strong> 39) ses et synsbedrag. Ellipsen der fittes<br />

til firkanten er faktisk cirkulær, men når den ses approksimeret til en firkant, ligner den nærmest en<br />

superellipse. Dette er d<strong>og</strong> ikke tilfældet i virkeligheden, <strong>og</strong> altså kun et synsbedrag. Det vurderes<br />

Side 41 <strong>af</strong> 131


9 EllipseApproximation 9.4 Sammenfatning<br />

<strong>og</strong>så her, at <strong>ved</strong> approksimering til forskellige andre former end ellipser, virker algoritmen efter<br />

hensigten.<br />

Samlet kan det konkluderes, at EllipseApproximation-klassen korrekt approksimerer en ellipse til<br />

inputobjektet.<br />

Side 42 <strong>af</strong> 131


9 EllipseApproximation 9.4 Sammenfatning<br />

Del II: Klassificering <strong>af</strong> <strong>kimplanter</strong><br />

Anden del <strong>af</strong> rapporten handler om <strong>klassificering</strong> <strong>af</strong> <strong>kimplanter</strong>. Overordnet set vil der i denne del<br />

blive udviklet algoritmer, der kan udvælge godkendte kim i forhold til <strong>klassificering</strong>sregler (3.4<br />

Klassificering s. 12) givet <strong>af</strong> Jens Iver Find (KU). I TopDetection- <strong>og</strong> ExpandShrink-klasserne<br />

gennemgås det, hvorledes toppen på et kim kan findes. Symmetry-klassen viser, hvordan det er<br />

muligt at bestemme symmetrien i et kim. Sidste klasse i Del II er Quality. I denne klasse gennemgås<br />

forskellige metoder, der kan anvendes til at adskille godkendte fra ikke-godkendte kim.<br />

Side 43 <strong>af</strong> 131


10 ExpandShrink 10.1 Indledning<br />

10 ExpandShrink<br />

10.1 Indledning<br />

Formålet med ExpandShrink-klassen er at skabe en måde hvorpå, det er muligt at udfylde indhak i<br />

et objekt. Behovet for klassen bliver først beskrevet i det næste kapitel om TopDetection-klassen,<br />

men gennemgås nu da klassens metoder skal anvendes i TopDetection.<br />

ExpandShrink-klassen indeholder to algoritmer. Disse har til formål, i samarbejde, udfylde skarpe<br />

indhak i et objekt. Dette kan gøres <strong>ved</strong> først at lægge et antal pixels til på objektet (”expande”) for<br />

derefter at trække et tilsvarende antal fra igen (”shrinke”), (Davies [3:33-34]).<br />

10.2 Teori<br />

10.2.1 Expand<br />

Expand-algoritmen lægger en pixel til rundt i kanten på et objekt. Algoritmen traverserer gennem<br />

billedet <strong>og</strong> undersøger hver enkel pixel. Når en hvid pixel er fundet, gøres alle dens naboer <strong>og</strong>så<br />

hvide. På figur 10.1 ses et 10 x 10 pixel stort billede, hvor objektet består <strong>af</strong> en enkel hvid pixel.<br />

Denne pixel ønskes expanded én gang. Resultatet <strong>af</strong> denne operation fremgår <strong>af</strong> figur 10.2. Figur 10.2<br />

er expanded én gang, da der er blevet lagt én pixel til rundt i kanten. Hvis der i stedet var blevet<br />

expanded to gange, ville der blive lagt én pixel mere til rundt i kanten, <strong>og</strong> firkanten var dermed<br />

blevet én pixel bredere i alle fire retninger:<br />

Figur 10.1<br />

En figur repræsenteret<br />

<strong>ved</strong> én pixel<br />

Figur 10.2<br />

Resultat med én gang<br />

expand<br />

Det er d<strong>og</strong> ikke nok bare at udvide den enkelte pixel. Hvis den hvide pixel ligger ude i kanten, er den<br />

<strong>af</strong>skåret fra at udvide sig i mindst en retning. Tages der igen udgangspunkt i et 10 x 10 pixel billede<br />

(figur 10.3), hvor objektet igen er en enkel pixel, men denne gang er pixelen placeret i øverste venstre<br />

hjørne (pixelen er gjort rød for lettere at følge den rundt i de forskellige figurer). Der ønskes stadig<br />

kun at expande én gang. For at kunne gøre alle dens naboer hvide, er det nødvendigt at udvide<br />

billedet. Dette er gjort på figur 10.4:<br />

Side 44 <strong>af</strong> 131


10 ExpandShrink 10.2 Teori<br />

Billedet udvides med antallet <strong>af</strong> gange det ønskes at expande gange to, i både i længde- <strong>og</strong> bredderetningen.<br />

Dette svarer til at udvide billedet det antal gange, der ønskes at expande i alle 4 retninger.<br />

Dvs. at hvis det ønskes at expande én gang i et 10 x 10 pixel billede, bliver det nye billede et 12 x 12<br />

pixel billede. (På figur 10.5 er figur 10.3 <strong>og</strong> figur 10.4 vist oveni i hinanden for at demonstrere<br />

princippet). Ønskes det derimod at expande to gange, bliver det nye billede derimod 14 x 14:<br />

10.2.2 Shrink<br />

Figur 10.6<br />

Resultatet <strong>af</strong> én shrink operation<br />

Figur 10.3<br />

En figur repræsenteret<br />

<strong>ved</strong> én pixel der ligger i<br />

hjørnet<br />

Figur 10.4<br />

Her er billedet blevet udvidet<br />

samtidig med at figuren er<br />

expanded én gang<br />

Figur 10.5<br />

Figur 10.3 <strong>og</strong> figur 10.4 vist<br />

oveni hinanden<br />

Shrink-algoritmen fjerner en pixel hele vejen rundt i kanten. Algoritmen<br />

fungerer lige modsat <strong>af</strong> expand-algoritmen. Den traverserer igennem et<br />

billede, <strong>og</strong> finder alle pixels der er sorte. Derefter tegnes alle naboer <strong>og</strong>så<br />

sorte. Udføres shrink-algoritmen på figur 10.5, hvor det ønskes at shrinke<br />

én gang, bliver resultatet som vist på figur 10.6. Det ses, at alle de hvide<br />

pixels, som havde en sort nabo, nu <strong>og</strong>så er blevet sorte.<br />

De to algoritmer expand <strong>og</strong> shrink vil i de fleste<br />

tilfælde blive kørt lige efter hinanden. Det kan<br />

derfor være ønskværdigt at formindske billedets<br />

dimensioner til den originale størrelse. Dette er<br />

gjort på figur 10.7.<br />

Det originale billede er nu genskabt. Operationen har i dette tilfælde ikke<br />

ført til n<strong>og</strong>en ændring. Det er det samme billede, som til at begynde med. I<br />

det næste <strong>af</strong>snit, bliver det beskrevet hvordan en kombination <strong>af</strong> de to<br />

algoritmer kan anvendes til n<strong>og</strong>et praktisk.<br />

Figur 10.7<br />

Resultatet <strong>af</strong> en trunkering<br />

Side 45 <strong>af</strong> 131


10 ExpandShrink 10.2 Teori<br />

10.2.3 Expand <strong>og</strong> Shrink<br />

Figur 10.8<br />

En figur med indhak<br />

Figur 10.10<br />

Samlet resultat <strong>af</strong><br />

expand <strong>og</strong> shrink<br />

kombineret hvor det ses<br />

at den ene pixel i<br />

toppen er udfyldt<br />

Det kan altså lade sig gøre at lægge x antal pixels<br />

på i kanten <strong>af</strong> et objekt, <strong>og</strong> derefter fjerne et<br />

tilsvarende antal igen. Dette vil blive udnyttet til<br />

udfylde skarpe knæk eller indhak. Et eksempel på<br />

et objekt ses på figur 10.8.<br />

Afvikles expand-algoritmen én gang på dette<br />

objekt, fås et nyt billede som det på figur 10.9.<br />

Det blå i figuren, viser de pixels, som er blevet<br />

tilføjet <strong>ved</strong> <strong>af</strong>vikling <strong>af</strong> expand-algoritmen.<br />

Afvikles shrink-algoritmen nu én gang på objektet, kommer resultatet til at<br />

se ud som på figur 10.10.<br />

Det ses, at der er en pixel ekstra på dette nye objekt i forhold til det originale.<br />

Hullet er altså blevet udfyldt. Denne ekstra pixel kaldes i resten <strong>af</strong> denne<br />

rapport en expand-shrink-pixel.<br />

Havde man i stedet for kun at expande <strong>og</strong> shrinke én gang gjort det to<br />

gange, ville der blive udfyldt endnu mere. Figur 10.11 viser, hvordan at 10 x<br />

10 pixel billedet er blevet udvidet til et 14 x 14 billede. De blå pixel viser igen<br />

dem, som er blevet tilføjet.<br />

Figur 10.11<br />

Resultatet <strong>af</strong> to gange expand<br />

Køres shrink-algoritmen nu to gange på figur 10.11, bliver resultatet, som det ses på figur 10.12.<br />

Figur 10.12<br />

Resultat efter to gange<br />

expand <strong>og</strong> to gange<br />

shrink<br />

Figur 10.9<br />

Resultat <strong>af</strong> én gang expand<br />

Det ses, at der denne gang er blevet tilføjet 4 expand-shrink-pixels i forhold til tidligere. Det ville på<br />

dette objekt ikke given n<strong>og</strong>en ændring at expande <strong>og</strong> shrinke mere end to gange, da der ikke er flere<br />

indhak, der kan blive udfyldt.<br />

Side 46 <strong>af</strong> 131


10 ExpandShrink 10.3 Test<br />

10.3 Test<br />

For at sikre, at de to algoritmer virker efter hensigten, er der udført tre test. De to <strong>af</strong> dem verificerer,<br />

at henholdsvis expand- <strong>og</strong> shrink-algoritmerne virker efter hensigten. Den sidste tester<br />

kombinationerne <strong>af</strong> de to. Alle test samt testresultater findes på DVD i mappen ”10.<br />

ExpandShrink”.<br />

10.3.1 expand()<br />

For at teste expand-algoritmen er figur 10.3 blevet benyttet. Denne er vist sammen med resultatet på<br />

figur 10.13:<br />

Originalbilledet var 10 x 10 pixel, hvor pixelen i øverste venstre hjørne var hvid. Resultatbilledet blev<br />

et 12 x 12 pixel billede, med alle nabopixelene omkring pixelen i hjørnet farvet hvide.<br />

10.3.2 shrink()<br />

Testen <strong>af</strong> shrink-algoritmen vises i figur 10.14, hvor både input- <strong>og</strong> outputbillede er vist sammen.<br />

Billedet som algoritmen blev kørt på, var et 12 x 12 pixel billede. Resultatbilledet blev et 10 x 10<br />

pixel billede magen til udgangsbilledet i figur 10.13.<br />

10.3.3 expand() <strong>og</strong> shrink()<br />

Figur 10.13<br />

Her ses udgangsbilledet samt resultatet <strong>af</strong> 1 gang expand<br />

Figur 10.14<br />

Viser billedet, som shrink-algoritmen blev udført på, samt<br />

resultatet<br />

For at se, hvordan de to algoritmer virker sammen, er der lavet en test på billedet figur 10.8 fra <strong>af</strong>snit<br />

10.2.3 Expand <strong>og</strong> Shrink s. 46.<br />

Side 47 <strong>af</strong> 131


10 ExpandShrink 10.4 Sammenfatning<br />

Figur 10.15 viser først det originale billede, som er 10 x 10 pixel, inden algoritmen er kørt på det.<br />

Derefter vises resultatet <strong>af</strong> expand-algoritmen, hvor billedet er blevet udvidet til 12 x 12 pixel, <strong>og</strong> der<br />

er lagt en pixel på hele vejen rundt i kanten. Efter shrink-algoritmen er billedet igen blevet 10 x 10<br />

pixel, <strong>og</strong> det ses at den sorte pixel i toppen <strong>af</strong> objektet er blevet hvid.<br />

10.4 Sammenfatning<br />

Figur 10.15<br />

På figuren ses inputbilledet, derefter vises expand-resultatet,<br />

<strong>og</strong> til sidst det endelige resultat efter shrink<br />

Det kan overordnet konkluderes, at det er lykkedes, at lave en klasse hvor det kan lade sig gøre at<br />

fjerne skarpe indhak eller knæk.<br />

Testen <strong>af</strong> expand-algoritmen viser, at resultatet er præcis som forventet, <strong>og</strong> i overensstemmelse med<br />

teorien. Alle naboer til hvide pixels bliver hvide, <strong>og</strong> billedet bliver udvidet to gange antallet <strong>af</strong> gange,<br />

det ønskes at expande. Med dette opnås det, at det altid kan lade sig gøre, at tegne nabopixelene<br />

hvide.<br />

Shrink-algoritmen blev testet på det billede, som var resultatet <strong>af</strong> expand-algoritmen. Efter billedet<br />

var blevet behandlet <strong>af</strong> shrink-algortimen, havde det den oprindelige størrelse, <strong>og</strong> med kun en hvid<br />

pixel i øverste venstre hjørne, hvilket var hvad der ønskedes at opnå.<br />

Kombinationen <strong>af</strong> expand <strong>og</strong> shrink blev testet på en figur, der havde et indhak i toppen. Efter<br />

begge algoritmer var blevet kørt på billedet, blev resultatet et nyt billede hvor indhakket i toppen var<br />

blevet udfyldt. Det kan hermed konkluderes, at det er lykkedes at lave en algoritme, der virker efter<br />

hensigten.<br />

Side 48 <strong>af</strong> 131


11 TopDetection 11.1 Indledning<br />

11 TopDetection<br />

11.1 Indledning<br />

Formålet med TopDetection er, at kunne finde enten top eller<br />

bund på kimene. Dette ønskes gjort, da en robot skal kunne gribe<br />

kimene, <strong>og</strong> lægge dem op på række <strong>ved</strong> siden <strong>af</strong> hinanden, således<br />

at toppene vender henholdsvis den ene eller den anden vej. På<br />

denne måde bliver der plads til, at kimene kan vokse på et mindre<br />

areal, <strong>og</strong> dermed udnyttes den skål, hvori de ligger, bedre.<br />

Algoritmen skal optimeres til at virke på kim, som ikke bliver sorteret<br />

fra pga. deres dårlige kvalitet (dette gennemgås nærmere i 13<br />

Quality s. 60).<br />

11.2 Teori<br />

Der er lavet en brainstorm som findes i Appendiks 18.7 Valg <strong>af</strong><br />

TopDetection-algoritme s. 93. Heri beskrives det, hvilke algoritmer gruppen i<br />

fællesskab, har fundet frem til i brainstormen. Ydermere gennemgås en<br />

særlig rating, der blev foretaget, for at kunne udvælge algoritmen, gruppen<br />

mente havde det største potentiale. Valget faldt på Arealforskel-algoritmen.<br />

11.2.1 Arealforskel<br />

Arealforskel-algoritmen bygger på at kimet har<br />

indhak, der hvor der er kimbladsstruktur. Når det<br />

forstørres <strong>og</strong> derefter mindskes igen med<br />

ExpandShrink, bliver disse indhak udfyldt. Det<br />

originale kim-objekt sammenlignes derefter med<br />

dette modificerede kim-objekt. Dette giver en<br />

arealforskel i toppen (figur 11.1).<br />

Ved at subtrahere de to objekter fra hinanden, opstår<br />

der små arealer, der hvor der er forskel mellem dem<br />

(figur 11.2). Man kan være uheldig, at der opstår arealer<br />

andre steder end i toppen, det kan derfor være<br />

nødvendigt at udglatte eventuelle urenheder langs<br />

kanten <strong>af</strong> objektet.<br />

Når delarealerne er fundet, beregnes deres massemidtpunkt,<br />

<strong>og</strong>så kaldet top-massemidtpunkt. For at<br />

undgå for megen vægtning <strong>af</strong> arealer, som ikke ligger<br />

i toppen, kan man i stedet vælge det enkelte delareal,<br />

der er størst. Dette skulle gerne ligge i toppen.<br />

Ud fra den linie, der opstår mellem top-massemidt-<br />

Massemidtpunkt fra<br />

ellipseapproksimation<br />

Figur 11.1<br />

Arealforskel<br />

Massemidtpunkt fra<br />

ellipseapproksimation<br />

Massemidtpunkt fundet<br />

<strong>ved</strong> subtrahering<br />

Figur 11.2<br />

Viser de delarealer der<br />

opstår<br />

Massemidtpunkt fundet<br />

<strong>ved</strong> subtrahering<br />

Figur 11.3<br />

Viser to forskellige scenarier hvor toppen detekteres i<br />

hver deres ende<br />

θ<br />

θ<br />

Side 49 <strong>af</strong> 131


11 TopDetection 11.2 Teori<br />

punktet, <strong>og</strong> massemidtpunktet fundet i ellipseapproksimationen,<br />

beregnes vinklen til det vandrette plan (figur 11.3).<br />

Det er <strong>af</strong>gørende på hvilken side <strong>af</strong> ellipsens lilleakse, top-<br />

massemidtpunktet ligger. Hvis vinklen til kimets top<br />

( θ topmassemidtpunkt ), detekteres til at ligge i samme ende som vinklen<br />

til storaksen ( θ major ), er følgende udsagn gældende (figur 11.4):<br />

θ ellipselilleakse > θ top massemidtpunkt > θellipselilleakse − π (11.1)<br />

Hvis udsagnet er opfyldt, ligger top-massemidtpunktet i det skraverede<br />

område i figur 11.4, <strong>og</strong> det tilføjes i seed-objektet, at toppen<br />

har samme vinkel som storaksen. Ligger toppen ikke i det skraverede<br />

område, lægges der 180 º til storaksens vinkel, inden dette tilføjes<br />

i seed-objektet. På denne måde er det muligt at fastlægge, i hvilken<br />

ende <strong>af</strong> kimet toppen er fundet.<br />

11.2.1.1 Beregning <strong>af</strong> vinkel<br />

For at kunne beregne θ top massemidtpunkt , som den-<br />

ne danner med det vandrette plan, tegnes en<br />

retvinklet trekant (figur 11.5). Hertil anvendes, at<br />

det gælder, at cosinus til en <strong>af</strong> de to ikke rette<br />

vinkler er det samme, som forholdet mellem<br />

hypotenuse <strong>og</strong> hosliggende katete. Hypotenusens<br />

længde kan beregnes vha. Pythagoras, <strong>og</strong><br />

katetens længde beregnes <strong>ved</strong> at trække koordinaterne<br />

fra hinanden.<br />

b<br />

cos( θ ) =<br />

c<br />

b<br />

θ= arccos<br />

⎛ ⎞<br />

⎜ ⎟<br />

⎝c⎠ (11.2)<br />

11.2.1.2 Subtrahering <strong>af</strong> billeder<br />

( ) ( )<br />

2 2<br />

M2 M1 M2 M1<br />

c = x − x + y −y<br />

( x , y )<br />

M1 M1<br />

Figur 11.5<br />

Beregning <strong>af</strong> vinkel<br />

top − massemidtpunkt<br />

storakse<br />

θtopmassemidtpunkt major θ<br />

Figur 11.4<br />

Figuren viser tilfældet hvor Ligning<br />

(11.1) er sand. Top-massemidtpunktet<br />

ligger i det skraverede område<br />

Subtraheringen, som tidligere beskrevet i dette <strong>af</strong>snit, bygger på, at billederne er lige store <strong>og</strong> er sorthvide.<br />

Resultatet <strong>af</strong> metoden er et nyt billede, med forskellene tegnet ind.<br />

Først oprettes der et nyt billede, med de samme dimensioner, som de to der ønskes sammenlignet.<br />

Derefter sammenlignes hver enkel pixel i de to billeder, <strong>og</strong> resultatet <strong>af</strong> denne sammenligning skrives<br />

i det nye billede. Hvis der ikke er n<strong>og</strong>en forskel, gøres den tilsvarende pixel, i det nye billede, sort.<br />

Hvis der er en forskel, markeres denne med hvid. Resultatet <strong>af</strong> en sådan operation på figur 11.6 <strong>og</strong><br />

figur 11.7, kan ses på figur 11.8.<br />

θ<br />

b = x − x<br />

M2 M1<br />

( x , y )<br />

M2 M2<br />

A C<br />

B<br />

a = y − y<br />

M2 M1<br />

Side 50 <strong>af</strong> 131


11 TopDetection 11.3 Test<br />

11.3 Test<br />

Det er formålet med testen, at bestemme hvilken kombination <strong>af</strong> parametre, der bedst finder toppen<br />

det rigtige sted. Algoritmen er anvendt på 3 billeder. På hvert billede er der 25-30 kim, som alle er<br />

godkendte. Algoritmen er kørt 30 gange på hvert billede, hvor følgende parametre varierer:<br />

• Den første ExpandShrink-operation, der fjerner urenheder<br />

• Den anden ExpandShrink-operation, der <strong>brug</strong>es til at finde forskel<br />

• Massemidtpunkt for det største eller summen <strong>af</strong> delarealerne der opstår <strong>ved</strong> subtrahering<br />

Det er testens formål, at finde den bedste kombination <strong>af</strong> ovenstående parametre. På DVD’en<br />

findes test samt testresulater i mappen ”11. TopDetection”.<br />

11.3.1 Testresultater<br />

Testresultaterne for et <strong>af</strong> billederne, fremgår <strong>af</strong> tabel 11.1. Resten <strong>af</strong> testresultaterne findes i<br />

Appendiks 18.11 Test <strong>af</strong> TopDetection s. 127. Kolonnen ”Arealer” indeholder enten værdien ”alle<br />

arealer”, eller ”største areal”. Dette skal indikere, om det er valgt at beregne top-massemidtpunktet<br />

ud fra alle delarealer, der opstår <strong>ved</strong> subtrahering <strong>af</strong> de to billeder, eller om det er det største <strong>af</strong> de<br />

enkelte delarealer, der skal <strong>brug</strong>es. Den næste kolonne er ”Antal udglatninger”. Denne værdi<br />

indikerer hvor kr<strong>af</strong>tigt kanten skal glattes ud, inden det bliver forsøgt at finde en forskel. ”Antal<br />

ExpandShrink” er det antal gange, der skal expandes <strong>og</strong> shrinkes, inden der foretages en<br />

sammenligning <strong>af</strong> de to billeder. ”Rigtigt fundne”-kolonnen indeholder antallet <strong>af</strong> kim, hvor toppen<br />

blev fundet det rigtige sted. ”Forkert fundne”-kolonnen indeholder antallet <strong>af</strong> kim, hvor toppen er<br />

fundet til at ligge i den forkerte ende <strong>af</strong> kimet.”Udefinerede”-kolonnen er hvor, der ikke har været<br />

n<strong>og</strong>en forskel mellem de to billeder, der skulle sammenlignes. Den sidste kolonne angiver i procent,<br />

hvor effektiv algoritmen har været til at finde toppen det rigtige sted.<br />

Kombination<br />

Figur 11.6<br />

Det første billede i subtraheringen<br />

Arealer Antal<br />

Udglatning<br />

Figur 11.7<br />

Det andet billede i subtraheringen<br />

Antal<br />

Expand-<br />

Shrink<br />

Antal<br />

rigtigt<br />

fundne<br />

Figur 11.8<br />

Resultat <strong>af</strong> subtraheringen<br />

Antal<br />

forkert<br />

fundne<br />

Antal<br />

udefinerede<br />

1 Alle arealer 0 1 19 3 3 76,00<br />

2 Alle arealer 0 2 23 1 1 92,00<br />

3 Alle arealer 0 3 24 1 0 96,00<br />

4 Alle arealer 0 4 24 1 0 96,00<br />

5 Alle arealer 0 5 24 1 0 96,00<br />

6 Alle arealer 1 1 16 2 7 64,00<br />

7 Alle arealer 1 2 19 4 2 76,00<br />

8 Alle arealer 1 3 19 5 1 76,00<br />

9 Alle arealer 1 4 19 5 1 76,00<br />

10 Alle arealer 1 5 19 5 1 76,00<br />

11 Alle arealer 2 1 5 5 15 20,00<br />

%<br />

Side 51 <strong>af</strong> 131


11 TopDetection 11.3 Test<br />

12 Alle arealer 2 2 8 6 11 32,00<br />

13 Alle arealer 2 3 8 6 11 32,00<br />

14 Alle arealer 2 4 8 6 11 32,00<br />

15 Alle arealer 2 5 7 7 11 28,00<br />

16 Største areal 0 1 14 6 5 56,00<br />

17 Største areal 0 2 21 2 2 84,00<br />

18 Største areal 0 3 22 2 1 88,00<br />

19 Største areal 0 4 23 1 1 92,00<br />

20 Største areal 0 5 23 1 1 92,00<br />

21 Største areal 1 1 13 5 7 52,00<br />

22 Største areal 1 2 17 6 2 68,00<br />

23 Største areal 1 3 19 5 1 76,00<br />

24 Største areal 1 4 19 5 1 76,00<br />

25 Største areal 1 5 19 5 1 76,00<br />

26 Største areal 2 1 5 5 15 20,00<br />

27 Største areal 2 2 7 6 12 28,00<br />

28 Største areal 2 3 8 5 12 32,00<br />

29 Største areal 2 4 8 5 12 32,00<br />

30 Største areal 2 5 7 6 12 28,00<br />

Tabel 11.1<br />

Testresultater<br />

Ved at tage gennemsnittet <strong>af</strong> kolonnen ”%” for de billeder testen blev udført på, findes den<br />

kombination, som giver det bedste resultat (tabel 11.2).<br />

Kombination Billede 1 [%] Billede 2 [%] Billede 3 [%] Gennemsnit [%]<br />

1 76,00 76,00 70,37 75,46<br />

2 92,00 92,00 92,59 92,20<br />

3 96,00 96,00 92,59 92,20<br />

4 96,00 96,00 92,59 92,20<br />

5 96,00 96,00 92,59 92,20<br />

6 64,00 64,00 62,96 67,65<br />

7 76,00 76,00 85,19 81,73<br />

8 76,00 76,00 85,19 81,73<br />

9 76,00 76,00 88,89 82,96<br />

10 76,00 76,00 88,89 82,96<br />

11 20,00 20,00 18,52 28,84<br />

12 32,00 32,00 37,04 40,35<br />

13 32,00 32,00 40,74 42,91<br />

14 32,00 32,00 44,44 42,81<br />

15 28,00 28,00 48,15 42,72<br />

16 56,00 56,00 70,37 68,79<br />

17 84,00 84,00 92,59 88,20<br />

18 88,00 88,00 88,89 88,30<br />

19 92,00 92,00 85,19 88,40<br />

20 92,00 92,00 85,19 88,40<br />

21 52,00 52,00 66,67 63,56<br />

22 68,00 68,00 85,19 79,06<br />

23 76,00 76,00 81,48 80,49<br />

24 76,00 76,00 81,48 80,49<br />

25 76,00 76,00 81,48 79,16<br />

26 20,00 20,00 22,22 30,07<br />

27 28,00 28,00 37,04 39,01<br />

28 32,00 32,00 40,74 42,91<br />

29 32,00 32,00 44,44 42,81<br />

30 28,00 28,00 48,15 41,38<br />

Tabel 11.2<br />

Gennemsnit <strong>af</strong> testresulatater<br />

Det ses at det er kombination 2, 3, 4 <strong>og</strong> 5, der giver det bedste resultat. De finder toppen det rigtige<br />

sted på 92,2 % <strong>af</strong> kimene.<br />

Side 52 <strong>af</strong> 131


11 TopDetection 11.4 Sammenfatning<br />

11.4 Sammenfatning<br />

Der fremkom en del idéer under brainstormingen, som er blevet vurderet, <strong>og</strong> undersøgt nærmere.<br />

Valget faldt på metoden Arealforskel, som der blev arbejdet videre med.<br />

Testen viser, at det ikke er nødvendigt at forsøge at udjævne kanten på kimene med den første<br />

ExpandShrink-operation. Det kan <strong>og</strong>så ud fra testen konkluderes, at det er mest fordelagtigt at<br />

anvende alle delarealer til beregning <strong>af</strong> top-massemidtpunktet. Den viser <strong>og</strong>så, at kombination 2, 3, 4<br />

<strong>og</strong> 5 er lige gode. Valget <strong>af</strong> den kombination, der skulle implementeres, faldt på kombination 4, da<br />

denne ligger imellem to, som giver det samme resultat.<br />

Det lykkedes, at lave en algoritme, der med omkring 90 % sikkerhed placerer toppen det rigtige sted.<br />

Da TopDetection mere er en ”nice to have feature” end et reelt krav, ser gruppen sig tilfreds med<br />

resultatet. Hvis dette skulle forøges, skal det undersøges om algoritmen kan forbedres, eller om man<br />

skal starte forfra med at finde på nye idéer.<br />

Side 53 <strong>af</strong> 131


12 Symmetry 12.1 Indledning<br />

12 Symmetry<br />

12.1 Indledning<br />

Det er formålet med Symmetry-klassen,<br />

at skabe en<br />

måde hvorpå det er muligt,<br />

at vurdere i hvor høj grad<br />

objektet er symmetrisk omkring<br />

dets længdeakse (figur<br />

12.1). Dette skal <strong>brug</strong>es i<br />

forbindelse med kvalitetsvurderingen<br />

<strong>af</strong> kimene. Bestemmelsen<br />

<strong>af</strong> symmetrien<br />

foregår lettest <strong>ved</strong> at traversere<br />

objektet på begge<br />

sider (a <strong>og</strong> b) <strong>af</strong> længdeaksen,<br />

<strong>og</strong> undersøge om hvert<br />

koordinat forefindes på den<br />

modsatte side <strong>af</strong> længdeaksen.<br />

På den måde er det<br />

muligt at tælle op hvor mange<br />

pixels, der ikke har en<br />

symmetripartner (symmetripixel),<br />

<strong>og</strong> vurdere hvor sym-<br />

metrisk objektet er. Herefter skal antallet <strong>af</strong> symmetripixels vægtes med arealet <strong>af</strong> objektet, for at det<br />

er muligt at vurdere kimenes symmetri med hinanden.<br />

12.2 Teori<br />

Figur 12.1<br />

Objektet traverseres på begge siden <strong>af</strong> længdeaksen<br />

Algoritmen skal kunne traversere igennem alle pixels i objektet, på begge sider <strong>af</strong> længdeaksen, <strong>og</strong><br />

undersøge om der findes en hvid pixel på den modsatte side <strong>af</strong> denne. Metoden for at bestemme<br />

antallet <strong>af</strong> symmetripixels i et objekt er som følger (figur 12.2 - figur 12.6):<br />

1. Algoritmen går alle pixels i objektet igennem. Hvis pixelen er en forgrundspixel fortsætter<br />

algoritmen. Punktet A er den aktuelle pixel i figuren, hvor det skal undersøges, om den har<br />

en symmetripartner på den modsatte side.<br />

2. Punkt A omregnes til B, som ligger i et koordinatsystem hvor massemidtpunktet CM er<br />

origo.<br />

3. B roteres nu, så figurens længdeakse er sammenfaldende med b.x-aksen, B bliver nu C.<br />

Herefter bestemmes symmetripartneren til C som D.<br />

4. D roteres tilbage igen, <strong>og</strong> bliver til E.<br />

5. E omregnes til F, således CM ikke længere er origo.<br />

6. Det undersøges om F er en hvid pixel. Hvis dette er tilfældet har A en symmetripartner i F.<br />

Figuren i illustrationerne er kun tegnet for at hjælpe på forståelsen, <strong>ved</strong> at illustrere hvordan A flytter<br />

rundt i koordinatsystemet i forhold til figuren. Det er ikke hensigten, at alle punkter i figuren skal<br />

indgå i udregningerne i hvert trin. Det er kun punkterne A-F, der skal udregnes i alt. Dette gør, at<br />

algoritmen vil være mulig at <strong>af</strong>vikle relativt hurtigt.<br />

y<br />

y<br />

x<br />

x<br />

Side 54 <strong>af</strong> 131


12 Symmetry 12.2 Teori<br />

y<br />

CM(x cm, y cm )<br />

(0, 0)<br />

A(x 1, y 1)<br />

Figur 12.2<br />

Trin 1: Det ønskes undersøgt om der findes et<br />

punkt modsat A på den anden side <strong>af</strong><br />

længdeaksen<br />

a.y<br />

(0, 0)<br />

B(a.x 1, a.y 1)<br />

?<br />

x<br />

(0, 0)<br />

(0, 0)<br />

D(b.x 2, b.y 2)<br />

Figur 12.4<br />

Trin 3: Objektet roteres ned <strong>og</strong> D bestemmes<br />

E(a.x 2, a.y 2)<br />

a.x<br />

Figur 12.5<br />

Trin 4: Der roteres op igen så D bliver til E<br />

B(a.x 1, a.y 1)<br />

Figur 12.3<br />

Trin 2: Koordinatsystem centreres omkring CM<br />

C(b.x 1, b.y 1)<br />

CM(x cm, y cm )<br />

(0, 0)<br />

A(x 1, y 1)<br />

F(x 2, y 2)<br />

Figur 12.6<br />

Trin 5: E bliver til F <strong>ved</strong> at koordinasystemet<br />

rykkes væk fra CM igen<br />

Side 55 <strong>af</strong> 131


12 Symmetry 12.2 Teori<br />

12.2.1 Rotation <strong>af</strong> pixels<br />

I trin 3 <strong>og</strong> 4 skal en pixel i objektet roteres en given vinkel. Til denne operation anvendes flg. ligning,<br />

der roterer et punkt imod omløbsretningen:<br />

x = x cos( −θ ) + ysin(<br />

−θ)<br />

2<br />

y = ycos( −θ) −x sin( −θ)<br />

2<br />

(12.1)<br />

I ligningen indgår koordinatsættet ( xy , ) , der ønskes roteret med vinklen θ . Resultatet er det<br />

x , y .<br />

roterede koordinatsæt ( )<br />

2 2<br />

12.2.2 Bestemmelse <strong>af</strong> løsningsmodel<br />

Algoritmens udformning er et resultat <strong>af</strong> mange andre mulige løsningsmodeller, der d<strong>og</strong> hver havde<br />

en brist. Én løsningsmodel, der ligger lige for er, at udføre trinnene 1-3 fra løsningsmodellen<br />

ovenover, hvor man d<strong>og</strong> roterer alle pixelene i hele objektet i samme omgang. På den måde er hele<br />

objektet roteret, <strong>og</strong> ligger med længdeaksen sammenfaldende med x-aksen. Herefter ville det være<br />

nærliggende at foretage sammenligningen på tværs <strong>af</strong> længdeaksen i dette objekt. Der er d<strong>og</strong> et<br />

problem <strong>ved</strong> det, da rotationen er en trigonometrisk<br />

funktion, der <strong>af</strong>hænger <strong>af</strong> vinklen der ønskes drejet (figur<br />

12.7). Figur 12.7 viser, at når objektet i billedet roteres til<br />

det vandrette plan, vil hver pixel i billedet få et nyt (x,y)koordinat.<br />

For at kunne foretage sammenligningen på<br />

tværs <strong>af</strong> den vandrette længdeakse, skal alle værdierne<br />

<strong>af</strong>rundes til heltal (pixels). Det er denne <strong>af</strong>runding <strong>af</strong> de<br />

roterede koordinater, der er problemet, fordi <strong>af</strong>rundingen<br />

gør at n<strong>og</strong>le koordinatpar vil være sammenfaldne. Derfor<br />

vil der opstå huller i det roterede objekt. Figur 12.8 viser et<br />

objekt (kim) inden den roteres, <strong>og</strong> figur 12.9 viser objektet<br />

efter rotationen. Billedet er et direkte udprint fra<br />

algoritmens array til en BMP-fil:<br />

Figur 12.8<br />

Objekt før rotation<br />

Figur 12.9<br />

Objekt efter rotation<br />

På figur 12.9 ses problemstillingen med sammenfaldne pixels tydeligt.<br />

For at undgå dette problem, skal <strong>af</strong>rundingen undgås, <strong>og</strong> det gøres<br />

<strong>ved</strong> at efter man har fundet pixelen på den modsatte side <strong>af</strong><br />

længdeaksen, roteres denne pixel tilbage i det oprindelige (x,y)domæne.<br />

Dvs. i stedet for at <strong>af</strong>runde pixelen <strong>og</strong> undersøge med det<br />

θ<br />

Figur 12.7<br />

Ved rotation anvendes en trigonometrisk funktion<br />

der giver nye x, <strong>og</strong> y-værdier<br />

Side 56 <strong>af</strong> 131


12 Symmetry 12.3 Test<br />

samme om pixelen er hvid, så roteres denne altså tilbage i det oprindelige (x,y)-domæne, <strong>og</strong> først her<br />

foretages undersøgelsen om de roterede koordinater peger på en hvid pixel. Dette er da <strong>og</strong>så<br />

fremgangsmetoden beskrevet i <strong>af</strong>snit 12.2 Teori s. 54.<br />

12.3 Test<br />

Testen blev foretaget på billedet nedenunder (figur 12.10):<br />

Testresultaterne er angivet i tabel 12.1. ”Symmetry”-kolonnen indeholder billeder, der er blevet<br />

udskrevet direkte fra Symmetry-klassen. Disse har sort baggrund, mens de pixels der har en<br />

symmetripartner på den modsatte side <strong>af</strong> længdeaksen er hvid. De pixels der ikke blev fundet en<br />

symmetripartner til er farvet grå. Testen bestås såfremt de hvide grupperinger i billederne i<br />

”Symmetry”-kolonnen er symmetriske omkring længdeaksen:<br />

Blobid EllipseApproximation Symmetry Symmetri [%]<br />

0<br />

1<br />

2<br />

3<br />

4<br />

5<br />

Figur 12.10<br />

Testbillede anvendt<br />

96<br />

94<br />

71<br />

34<br />

92<br />

77<br />

Side 57 <strong>af</strong> 131


12 Symmetry 12.3 Test<br />

Blobid EllipseApproximation Symmetry Symmetri [%]<br />

6<br />

7<br />

8<br />

9<br />

10<br />

11<br />

12<br />

13<br />

14<br />

15<br />

16<br />

17<br />

18<br />

19<br />

20<br />

42<br />

86<br />

88<br />

56<br />

55<br />

32<br />

79<br />

82<br />

80<br />

93<br />

64<br />

69<br />

89<br />

75<br />

60<br />

Side 58 <strong>af</strong> 131


12 Symmetry 12.4 Sammenfatning<br />

Blobid EllipseApproximation Symmetry Symmetri [%]<br />

21<br />

22<br />

23<br />

Tabel 12.1<br />

Testresultater, hvor det hvide i figurerne i ”Symmetry”-kolonnen, er symmetripixels<br />

12.4 Sammenfatning<br />

Det kan overordnet konkluderes, at det har været muligt at lave en klasse, der kan angive hvor<br />

symmetrisk et objekt er omkring dets længdeakse, vægtet i forhold til dets areal.<br />

Det ses i testen, at klassen kan opgøre hvor stor en procentdel <strong>af</strong> pixelene, der har en<br />

symmetripartner på den modsatte side <strong>af</strong> længdeaksen. De hvide pixels i billederne i ”Symmetry”kolonnen<br />

er alle symmetriske objekter, der ligger omkring længdeaksen. Dermed kan det<br />

konkluderes, at Symmetry-klassen korrekt finder symmetripixels i objektet.<br />

33<br />

45<br />

41<br />

Side 59 <strong>af</strong> 131


13 Quality 13.1 Indledning<br />

13 Quality<br />

13.1 Indledning<br />

Formålet med Quality-klassen er at skabe en måde, hvorpå det er muligt, at udvælge kim der er <strong>af</strong> 1.<br />

klasses kvalitet i henhold til 3.4 Klassificering s. 12. I Del I blev det vist, hvorledes det ukritisk er muligt<br />

at identificere alle kim. Del II omhandler som nævnt kvalitetsvurdering, <strong>og</strong> det er Quality-klassen,<br />

der rent praktisk skal sortere kimene. Klasser i Del I <strong>og</strong> II har evalueret kimene, <strong>og</strong> tilføjet deres<br />

resultater til seed-objektet, men det er altså først i her i Quality-klassen, at alle kimenes parametre<br />

bliver evalueret samlet. Opgaven er altså to-delt:<br />

1. Det skal undersøges, hvorledes det er muligt at udvælge 1. klasses kim<br />

2. Der skal udvikles pr<strong>og</strong>ramkode, der kan implementere de fundne metoder i 1<br />

13.2 Teori<br />

13.2.1 Bestemmelse <strong>af</strong> Kvalitetsparametre<br />

Som nævnt skal der foretages en kvalitetssortering <strong>af</strong> kimene. Indledningsvis er det undersøgt, hvad<br />

det er, der udgør et godt kim; hvilke parametre kan det være interessant at arbejde med. Gruppen<br />

har i samarbejde med biol<strong>og</strong> Jens Iver Find fra Københavns Universitet studeret kimene nærmere. I<br />

fællesskab er der fundet frem til 4 parametre, som det håbes at kunne <strong>brug</strong>e til at frasortere de ikkegodkendte<br />

kim:<br />

Den første parameter er arealet. Arealet er interessant <strong>af</strong> flere grunde. Den første er, at det giver<br />

mulighed, for at frasortere kim, der rører <strong>ved</strong> hinanden, da arealet <strong>af</strong> disse lagt sammen, vil være<br />

meget større end for et enkelt. Den anden grund er, at det giver muligheden for at frasortere helt<br />

små prikker eller mindre grupper <strong>af</strong> pixels i billedet, som ikke er kim.<br />

Den næste parameter, excentricitet, er interessant ud fra den betragtning, at kimenes form er <strong>af</strong>lang.<br />

Excentriciteten er et udtryk for bredde i forhold til længde. Excentriciteten blev tidligere omtalt i<br />

9.2.4 Bestemmelse <strong>af</strong> ellipseparametre s. 37. Ved <strong>brug</strong> <strong>af</strong> denne parameter, kan det lade sig gøre at<br />

frasortere former, som er mere cirkulære <strong>og</strong> der<strong>ved</strong> ikke ønskelige.<br />

Ved at studere kimene var det tydeligt, at det ville være hensigtsmæssigt med en parameter, der<br />

kunne give et udtryk for kimbladsstruktur. Det viste sig svært, at finde en parameter der netop kun<br />

gjorde dette. Til gengæld blev der fundet en anden parameter som indirekte giver det ønskede<br />

resultat. Denne parameter er antallet <strong>af</strong> expand-shrink-pixels (10.2.3 Expand <strong>og</strong> Shrink s. 46).<br />

Parameteren er ikke direkte udtryk for kimbladsstruktur, men angiver i stedet for hvor kr<strong>af</strong>tige<br />

indhak, der er i objektet. Hvis der ingen indhak er, kan det med stor sikkerhed vurderes, at der ikke<br />

er n<strong>og</strong>en kimblade, <strong>og</strong> i dette tilfælde vil expand-shrink-pixels-parameteren give 0 eller små værdier.<br />

Hvis den derimod er stor, kan det både være et udtryk for at objektet er krumt, eller at det har<br />

kimblade.<br />

Den sidste parameter er symmetri i kimet som, fundet i kapitel 12 Symmetry s. 54. Ved symmetri<br />

forstås, at det er symmetrisk omkring længdeaksen. Et godt kim, har som regel <strong>og</strong>så en høj grad <strong>af</strong><br />

symmetri.<br />

Side 60 <strong>af</strong> 131


13 Quality 13.2 Teori<br />

De 4 parametre er samlet:<br />

• Areal<br />

• Excentricitet<br />

• Expand-shrink-pixels<br />

• Symmetri<br />

Ved at kombinere disse parametre, skal det være muligt at udvælge alle de gode kim.<br />

13.2.2 Manuel inspektion<br />

For at fastslå hvor godt det, <strong>ved</strong> hjælp <strong>af</strong> parametrene, kan lade sig gøre at separere <strong>og</strong> udvælge de<br />

godkendte kim fra de ikke-godkendte, er der <strong>brug</strong> for en prøve <strong>af</strong> kim. Disse kim er blevet manuelt<br />

inspiceret med henblik på at vide hvor mange <strong>og</strong> hvilke kim, der objektivt er godkendte <strong>og</strong> ikkegodkendte<br />

i en tilfældig distribution. På den måde kan man sammenligne med pr<strong>og</strong>rammets<br />

godkendelse <strong>af</strong> kim. I alt er der inspiceret 11 billeder med et samlet antal kim på 313. Af de 313 var<br />

de 205 <strong>af</strong> dem ikke-godkendte, mens de resterende 108 var godkendte (billederne kan findes på<br />

DVD’en i ”13. Quality\Test\Manuelt godkendte”).<br />

For at visualisere hvordan godkendte <strong>og</strong> ikke-godkendte kim ligger i forhold til hinanden, er de<br />

blevet plottet i et 3-dimensionelt plot (figur 13.1). De 3 akser repræsenterer 3 <strong>af</strong> de 4 parametre. Det<br />

er <strong>ved</strong> forsøg blevet fastslået, at de 3 parametre der giver den bedste separation, er areal, symmetri<br />

<strong>og</strong> expand-shrink-pixels. Det anbefales, at <strong>af</strong>vikle det MatLab-script der ligger på DVD’en under<br />

”13. Quality\MatLab”, da dette giver mulighed for at rotere plottet <strong>og</strong> se det i original størrelse.<br />

Figur 13.1<br />

3-dimensionelt plot som viser hvor de godkendte (blå firkanter) <strong>og</strong> ikke-godkendte kim (røde cirkler) placerer sig<br />

Side 61 <strong>af</strong> 131


13 Quality 13.2 Teori<br />

På figur 13.1 er de røde cirkler de ikke-godkendte kim, <strong>og</strong> de blå firkanter er de godkendte. Det ses at<br />

de godkendte kim fortrinsvis samler sig i venstre hjørne <strong>af</strong> plottet. Opgaven er nu at indhegne alle de<br />

blå firkanter uden at udvælge n<strong>og</strong>en <strong>af</strong> de røde cirkler.<br />

13.2.3 Bestemmelse <strong>af</strong> grænser<br />

Til at indhegne de blå firkanter, kan der vælges flere geometriske figurer. Den mest simple figur er<br />

en 3-dimensionel rektangulær boks, hvor længderne på siderne <strong>af</strong>gøres <strong>af</strong> en minimums- <strong>og</strong><br />

maksimums-værdier for de respektive parametre.<br />

Figur 13.2<br />

3-dimensionelt plot der viser en rektangulær boks, hvor alle de godkendte kim ligger indenfor grænserne<br />

På figur 13.2 er en boks blevet plottet med grænser, som lige netop gør, at alle de blå firkanter ligger<br />

indenfor boksen. Ud over de grænser, som bestemmes <strong>af</strong> de 3 parametre der ses i plottet, er <strong>og</strong>så<br />

excentriciteten medtaget, denne er d<strong>og</strong> bare ikke visuelt synlig i 3d-plottet.<br />

Resultatet bliver, at de 108 godkendte kim ligger indenfor boksen, men desværre bliver <strong>og</strong>så 54 ikkegodkendte<br />

udvalgt.<br />

Da det ikke kan lade sig gøre kun at udvælge alle godkendte <strong>og</strong> ingen ikke-godkendte kim, kan det<br />

være interessant at forsøge at omgrænse dem med en anden form end boksen. F.eks. en 3dimensionel<br />

ellipse (ellipsoide). En ellipsoide har runde former <strong>og</strong> giver dermed en blødere overgang<br />

Side 62 <strong>af</strong> 131


13 Quality 13.2 Teori<br />

imellem grænserne (figur 13.3). Ellipsoiden er ikke så simpel som boksen, <strong>og</strong> derfor opstilles følgende<br />

teori for at beskrive dens funktionalitet:<br />

Figur 13.3<br />

Ellipsoide i 3-dimensionelt enhedskoordinatsystem<br />

3-dimensionelle koordinater ( xyz , , ) , der opfylder følgende ligning, vil alle ligge på ellipsoidens<br />

overflade:<br />

⎛x −x ⎞ ⎛y −y ⎞ ⎛z −z<br />

⎞<br />

⎜ ⎟ + ⎜ ⎟ + ⎜ ⎟ =<br />

⎝ a ⎠ ⎝ b ⎠ ⎝ c ⎠<br />

2 2 2<br />

0 0 0 1<br />

, hvor<br />

x 0 er centerpunktet for ellipsoiden i x-planet<br />

a er semiaksen i x-planet<br />

y 0 er centerpunktet for ellipsoiden i y-planet<br />

b er semiaksen i y-planet<br />

z 0 er centerpunktet for ellipsoiden i z-planet<br />

c er semiaksen i z-planet<br />

Derfor gælder det, at de koordinater der opfylder<br />

følgende ulighed:<br />

⎛x −x ⎞ ⎛y −y ⎞ ⎛z −z<br />

⎞<br />

⎜ ⎟ ⎜ ⎟ ⎜ ⎟<br />

⎝ a ⎠ ⎝ b ⎠ ⎝ c ⎠<br />

2 2 2<br />

0 + 0 + 0 ≤1<br />

, ligger inden for ellipsoiden.<br />

(13.1)<br />

Figur 13.4<br />

Semiakse <strong>og</strong> centerpunkt for ellipsoide i x, z-planet<br />

(13.2)<br />

På figur 13.4 ses ellipsoiden fra siden, <strong>og</strong> det ses hvilken<br />

betydning a har for ellipsoidens form. Det samme er gjort<br />

på figur 13.5, hvor ellipsoiden ses fra enden for at vise b <strong>og</strong><br />

c .<br />

Figur 13.5<br />

Semiakser <strong>og</strong> centerpunkter for ellipsoiden i z,<br />

y-planet<br />

Side 63 <strong>af</strong> 131


13 Quality 13.2 Teori<br />

Figur 13.6<br />

3-dimensionelt plot der viser en ellipsoide hvor alle de godkendte kim ligger inden for grænserne<br />

Med ellipsoiden, hvor den lige præcis omgrænser alle de godkendte, opnås et lidt bedre resultat end<br />

med boksen (figur 13.6). Udover alle de 108 godkendte kim er der nu kun udvalgt 46 ikke-godkendte.<br />

Det er altså ikke lykkedes at finde en form eller figur, der kan separere alle de godkendte kim fra de<br />

ikke-godkendte. Selvom kimene samler sig i venstre side <strong>af</strong> det 3-dimensionelle plot, er der d<strong>og</strong><br />

stadig n<strong>og</strong>le ikke-godkendte i denne gruppe. Her kan der enten være tale om, at der skal findes en<br />

parameter mere, eller at der skal forsøges med andre geometriske former. Måske skulle der findes<br />

andre metoder end dem, som her er valgt. Emnet er utroligt stort <strong>og</strong> kompliceret, <strong>og</strong> derfor har det<br />

ikke været muligt, at videreudvikle yderligere på parametrene <strong>og</strong> lave flere <strong>og</strong> større test, grundet den<br />

begrænsede tid i projektet.<br />

Gruppen har i stedet for valgt en anden fremgangsmetode. I stedet for at forsøge at udvælge alle<br />

godkendte <strong>og</strong> ingen ikke-godkendte kim, vil det derimod blive forsøgt at udvælge så mange<br />

godkendte uden at udvælge ikke-godkendte kim, ud fra den tankegang at kimene er relativt billige på<br />

det trin hvor dette projekt skal håndtere dem, <strong>og</strong> at det er vigtigere at undgå at få ikke-godkendte<br />

kim med.<br />

Anvendes denne fremgangsmetode først med boksen opnår man, med de bedst tilpassede grænser,<br />

at udvælge 54 godkendte uden at udvælge ikke-godkendte kim. Med ellipsoiden opnås at udvælge 51<br />

godkendte <strong>og</strong> 0 ikke-godkendte.<br />

Side 64 <strong>af</strong> 131


13 Quality 13.3 Test<br />

13.2.4 Variable grænser<br />

I det forrige <strong>af</strong>snit er de to ekstremer beskrevet. Enten blev alle godkendte <strong>og</strong> n<strong>og</strong>le ikke-godkendte<br />

kim udvalgt, eller <strong>og</strong>så udvælges ingen ikke-godkendte <strong>og</strong> n<strong>og</strong>le godkendte kim. Imidlertid kan man<br />

godt forestille sig, at en <strong>brug</strong>er <strong>af</strong> pr<strong>og</strong>rammet kunne være interesseret i, at kunne vælge grænser, der<br />

ligger imellem disse to yderpunkter. Ydermere kunne det <strong>og</strong>så ske, at kimenes størrelse ændrede sig.<br />

Der er altså et behov for at have justerbare grænser. Det skal derfor i en implementering <strong>af</strong><br />

kvalitetsvurderingen, være muligt at hente grænserne ind fra en ini-fil. Dermed bliver pr<strong>og</strong>rammet<br />

mere fleksibelt, <strong>og</strong> giver mulighed for at opfylde flere behov.<br />

Da de 2 geometriske figurer kun er blevet undersøgt i ekstrempunkterne, <strong>og</strong> deres resultater imellem<br />

disse ikke kendes, er det valgt, at det i implementeringen skal være muligt, for en <strong>brug</strong>er at vælge<br />

hvilken <strong>af</strong> de to udvælgelsesmodeller (boks eller ellipsoide) der ønskes anvendt.<br />

13.3 Test<br />

Test<strong>af</strong>snittet er delt i to dele. Den første del har til formål, at <strong>af</strong>dække hvorvidt koden der er udviklet<br />

til klassen, er implementeret korrekt. Den anden del har til formål, at vise hvor godt teorien, med at<br />

anvende boks <strong>og</strong> ellipsoide, virker.<br />

13.3.1 Første del<br />

13.3.1.1 Fremgangsmetode første del<br />

Algoritmen anvendes på alle billederne med de 313 kim (findes på DVD’en under ”13.<br />

Quality\Test\Første del”), som er vist i det 3-dimensionelle plot. Ved at benytte de fundne grænser<br />

for henholdsvis ellipsoiden <strong>og</strong> boksen, skulle der opnås de samme resultater som blev fundet med<br />

MatLab-scriptet i <strong>af</strong>snit 13.2.3 Bestemmelse <strong>af</strong> grænser s. 62:<br />

13.3.1.2 Testresultater første del<br />

Resultatet er vist i tabel 13.1:<br />

Type Grænser Godkendte Ikke<br />

godkendte<br />

Ellipsoide<br />

Boks<br />

Tabel 13.1<br />

Resultat <strong>af</strong> første test<br />

Smalle 51 0<br />

Brede 108 46<br />

Smalle 54 0<br />

Brede 108 54<br />

Side 65 <strong>af</strong> 131


13 Quality 13.3 Test<br />

13.3.2 Anden del<br />

Denne test skal vise, at anvendelsen <strong>af</strong><br />

justerbare grænser <strong>og</strong> de 2 udvælgelsesmodeller<br />

<strong>og</strong>så virker i praksis. Der<br />

testes på billedet vist i figur 13.7. På<br />

dette billede er de kim, der er manuelt<br />

godkendt markeret med hvide cirkler.<br />

Algoritmen skal ideelt udvælge disse<br />

kim. For bedre at kunne konkludere<br />

n<strong>og</strong>et ud fra resultaterne <strong>af</strong> testen,<br />

burde der anvendes mere end ét billede<br />

til testen, men det var desværre ikke<br />

muligt at fremsk<strong>af</strong>fe kimprøver sidst i<br />

projektets forløb. Det er ikke muligt at<br />

anvende billederne fra første del <strong>af</strong><br />

testen, da disse netop er dem der har<br />

dannet grundlag for grænseværdierne,<br />

der skal testes i anden del.<br />

13.3.2.1 Fremgangsmetode<br />

Testen <strong>af</strong> Quality-klassen foretages <strong>ved</strong><br />

at anvende udvælgelsesmodellerne på<br />

figur 13.7, d<strong>og</strong> uden de hvide cirkelmarkeringer.<br />

Overordnet vil der blive testet<br />

med begge udvælgelsesmodeller, boks<br />

<strong>og</strong> ellipsoide. I alt foretages fire test. To<br />

for hver <strong>af</strong> udvælgelsesmodellerne. En<br />

test med de smalle grænser, hvor der<br />

kun udvælges godkendte kim <strong>og</strong> en med<br />

brede grænser, hvor der <strong>og</strong>så udvælges<br />

ikke-godkendte kim.<br />

13.3.2.2 Testresultater ellipsoide<br />

Figur 13.8 viser resultatet <strong>ved</strong> <strong>brug</strong> <strong>af</strong><br />

ellipsoiden som udvælgelsesmodel <strong>og</strong><br />

med smalle grænser.<br />

Det ses, at der i bunden <strong>af</strong> billedet, er<br />

fundet et kim ud <strong>af</strong> de fire godkendte.<br />

Resultatet <strong>af</strong> den samme test, men<br />

denne gang med de brede grænser, kan<br />

ses på figur 13.9. Med de brede grænser<br />

udvælges alle fire godkendte, samt fem<br />

ikke-godkendte. Ved nærmere inspektion<br />

viser det sig, at det kun er en <strong>af</strong> de<br />

fem, som slet ikke kan <strong>brug</strong>es til n<strong>og</strong>et.<br />

De andre ligger lige på grænsen, <strong>og</strong> er 2.<br />

Figur 13.7<br />

Billede der blev anvendt til testen: De hvide markeringer angiver de kim der<br />

vurderes at være godkendte<br />

Figur 13.8<br />

Resultatet med ellipsoide <strong>brug</strong>t som udvælgelsesmodel <strong>og</strong> smalle grænser<br />

Figur 13.9<br />

Resultat med ellipsoide <strong>brug</strong>t som udvælgelsesmodel <strong>og</strong> brede grænser<br />

Side 66 <strong>af</strong> 131


13 Quality 13.3 Test<br />

klasses kim (3.4.2 Anden klasse – lette misdannelser s. 12).<br />

13.3.2.3 Testresulater rektangulær boks<br />

Med udvælgelsesmodellen, der baserer<br />

sig på boksen <strong>og</strong> med smalle grænser,<br />

fås det resultat, som ses på figur 13.10.<br />

Denne gang udvælges der et godkendt<br />

<strong>og</strong> et ikke godkendt kim. Det bemærkes<br />

<strong>og</strong>så, at der ikke blev udvalgt de<br />

samme godkendte kim, som da<br />

ellipsoiden blev anvendt.<br />

Med brede grænser opnås resultat som<br />

er vist på figur 13.11. Det ses her, at<br />

resultatet næsten er det samme, som<br />

da ellipsoiden med brede grænser blev<br />

anvendt. Denne gang udvælges der<br />

d<strong>og</strong> et mindre ikke godkendt kim.<br />

N<strong>og</strong>et, som umiddelbart kan undre, er<br />

at det ikke-godkendte kim, som blev<br />

udvalgt med smalle grænser, ikke<br />

udvælges når de brede grænser anvendes.<br />

Men dette skyldes, at når de smalle<br />

grænser anvendes, er der tilpasset<br />

en boks, som kun omkranser godkendte<br />

kim, <strong>og</strong> så er det gjort så stort,<br />

at det lige netop ikke udvælger n<strong>og</strong>le<br />

ikke-godkendte kim. Med brede grænser,<br />

er der tilpasset en ny boks, som<br />

omkranser alle godkendte, men som<br />

er tilpasset, så der udvælges så få ikkegodkendte<br />

som muligt. Det er med<br />

andre ord ikke de smalle grænser, som<br />

er blevet udvidet, men et helt andet<br />

rektangel.<br />

Samlet ses resultatet <strong>af</strong> testen i tabel<br />

13.2:<br />

Figur 13.10<br />

Resultat med rektangulær boks som udvælgelsesmodel <strong>og</strong> smalle grænser<br />

Figur 13.11<br />

Resultat med rektangulær boks som udvælgelsesmodel <strong>og</strong> brede grænser<br />

Type Grænser Godkendte Ikke<br />

godkendte<br />

Ellipsoide<br />

Boks<br />

Tabel 13.2<br />

Samlet resultat <strong>af</strong> testen<br />

Smalle 1 0<br />

Brede 4 5<br />

Smalle 1 1<br />

Brede 4 4<br />

Side 67 <strong>af</strong> 131


13 Quality 13.4 Sammenfatning<br />

13.4 Sammenfatning<br />

Overordnet kan det konkluderes, at det ikke har været muligt, at skabe en metode der kan udvælge<br />

alle godkendte <strong>og</strong> ingen ikke-godkendte kim i et givent billede.<br />

Ved gennemgangen i teori<strong>af</strong>snittet blev ellipsoiden foreslået, som et alternativ til boks-modellen som<br />

udvælgelsesmodel. Det viste sig at <strong>ved</strong> anvendelse <strong>af</strong> begge modeller på 313 prøvekim, at det ikke<br />

entydigt kunne <strong>af</strong>gøres hvilken <strong>af</strong> de to modeller der gav de bedste resultater.<br />

I den første test i test<strong>af</strong>snittet blev det undersøgt, hvorvidt den boksen <strong>og</strong> ellipsoiden blev<br />

implementeret korrekt, så de udførte deres opgave korrekt. Testen viste, at dette var tilfældet da<br />

C++ implementeringen gav det samme resultat, som fundet <strong>ved</strong> den manuelle inspektion<br />

(visualiseret igennem MatLab-scriptet). Dermed kan det konkluderes, at koden virker korrekt.<br />

I den anden test i test<strong>af</strong>snittet blev det testet hvorvidt boksen, var bedre end ellipsoidemodellen.<br />

Men <strong>ved</strong> test på et enkelt billede, viste det sig at være svært at <strong>af</strong>gøre, hvilken <strong>af</strong> modellerne der<br />

klarede sig bedst. Det står klart, at der skal anvendes mere end 1 billede, hvis en tendens skal kunne<br />

identificeres. Dette var d<strong>og</strong> ikke muligt, da der ikke kunne ansk<strong>af</strong>fes flere prøver tidsnok fra<br />

Københavns Universitet, men det er gruppens opfattelse, at de to udvælgelsesmodeller ikke<br />

nødvendigvis er de bedste løsningsmodeller, <strong>og</strong> at situationen er mere kompliceret end først antaget.<br />

Først <strong>og</strong> fremmest vil det være nødvendigt med større <strong>og</strong> mere omfattende undersøgelser, at<br />

<strong>af</strong>dække hvilken udvælgelsesmodel der er bedst. Det vil være nødvendigt at undersøge, om der<br />

findes bedre alternativer til boks- <strong>og</strong> ellipsoidemodellen, hvilket er meget muligt. Det er gruppens<br />

holdning at undersøgelsen med de 313 kim, ikke er omfattende nok til, at man i første omgang kan<br />

<strong>af</strong>gøre om boksmodellen er bedre eller dårligere end ellipsoidemodellen. Årsagen til at gruppen ikke<br />

har foretaget sig yderligere test er, at det er en meget tidskrævende proces, <strong>og</strong> det er i hele taget<br />

gruppens holdning at kvalitetsvurderingen <strong>af</strong> kimene er et <strong>af</strong>gangsprojekt i sig selv, <strong>og</strong> kræver<br />

omfattende statistisk analysearbejde.<br />

Et andet resultat <strong>af</strong> en mere omfattende analyse vil <strong>og</strong>så være at identificere flere <strong>og</strong>/eller andre<br />

parametre at arbejde med. Gruppen udarbejdede 4 parametre i samarbejde med Jens Iver Find (KU),<br />

men det er igen gruppens holdning, at yderligere analysearbejde skal <strong>af</strong>dække flere parametre, da det<br />

netop ikke er muligt, at opfylde ho<strong>ved</strong>kravet om at kunne udvælge alene alle godkendte kim. Flere<br />

parametre vil sandsynligvis gøre det muligt, at kunne få bedre resultater <strong>ved</strong> udvælgelsen.<br />

Side 68 <strong>af</strong> 131


14 Implementering 14.1 Indledning<br />

14 Implementering<br />

14.1 Indledning<br />

Når et projekt skal implementeres, er der flere ting der bør overvejes. Det gælder for det første om,<br />

at vælge det miljø hvori det ønskes at arbejde, hvilke fordele <strong>og</strong> ulemper der kan være. N<strong>og</strong>et andet<br />

er den struktur, der vælges for pr<strong>og</strong>rammet, samt på hvilket stadie det færdige produkt skal være.<br />

Skal det være en prototype eller et færdigt pr<strong>og</strong>ram? Derudover skal der <strong>og</strong>så være et user interface,<br />

således at en <strong>brug</strong>er vil være i stand til at benytte pr<strong>og</strong>rammet.<br />

14.2 Valg <strong>af</strong> implementeringsmiljø<br />

Implementeringen <strong>af</strong> teorien i projektet sket i C++. Valget <strong>af</strong> C++, var en kombination <strong>af</strong> flere<br />

faktorer. For det første var gruppen i forvejen kendt med spr<strong>og</strong>et, hvilket ville nedsætte den<br />

overhead, der altid er <strong>ved</strong> at lære et nyt pr<strong>og</strong>rammeringsspr<strong>og</strong>. Et andet aspekt var hastigheden i<br />

<strong>af</strong>viklingen. Sammenlignet med spr<strong>og</strong> som MatLab <strong>og</strong> Java er hastigheden i C++ større. Til gengæld<br />

har MatLab mange standardfunktioner til at behandle billeder indbygget. Et sidste argument for at<br />

<strong>brug</strong>e C++ er at det er et objektorienteret pr<strong>og</strong>rammeringsspr<strong>og</strong>.<br />

Gruppen valgte, at implementere projektet <strong>ved</strong> at <strong>brug</strong>e Visual C++ 2005 Express, en integreret<br />

IDE <strong>og</strong> kompiler fra Microsoft. Express-udgaven er gratis at <strong>brug</strong>e, <strong>og</strong> dette var ho<strong>ved</strong>grunden til at<br />

den blev valgt.<br />

14.3 Pr<strong>og</strong>ramstruktur<br />

Pr<strong>og</strong>rammet er udviklet på konceptbasis. Dvs. at pr<strong>og</strong>rammet skal sandsynliggøre, at det i praksis<br />

kan lade sig gøre, at detektere <strong>og</strong> klassificere kim. Dette indebærer, at der ikke er gjort så meget ud <strong>af</strong><br />

user interfacet samt hastighedsoptimering. Det er <strong>og</strong>så valgt, at man manuelt skal aktivere<br />

pr<strong>og</strong>rammet, hver gang det ønskes <strong>af</strong>viklet. Dette gør det nemt at arbejde med, så længe der udvikles<br />

på det.<br />

Selve pr<strong>og</strong>ramstrukturen er opbygget omkring en enkelt fil, ”<strong>vision</strong>.cpp”, der sekventielt <strong>af</strong>vikler<br />

pr<strong>og</strong>rammet svarende til blokdiagrammet i <strong>af</strong>snit 2.1.1 Pr<strong>og</strong>ram s. 8. Undervejs i pr<strong>og</strong>ram<strong>af</strong>viklingen,<br />

genereres der forskellige data, som alle gemmes i undermappen ”Data”.<br />

14.3.1 Vision.cpp<br />

I de foregående kapitler er de forskellige klasser, som pr<strong>og</strong>rammet gør <strong>brug</strong> <strong>af</strong>, beskrevet. Alle disse<br />

klasser instantieres fortrinsvis i filen ”<strong>vision</strong>.cpp”, som er pr<strong>og</strong>rammets ho<strong>ved</strong>fil. I den følgende<br />

tekst vil en, for overskuelighedens skyld, lidt forenklet version <strong>af</strong> denne fil blive beskrevet.<br />

Som det første oprettes der en instans <strong>af</strong> klassen Color. Denne instans <strong>brug</strong>es til at læse filen<br />

”kim.bmp” ind fra harddisken. Filen ”kim.bmp” skal ligge i samme mappe som pr<strong>og</strong>rammet:<br />

Color color;<br />

color.execute("kim.bmp");<br />

Side 69 <strong>af</strong> 131


14 Implementering 14.3 Pr<strong>og</strong>ramstruktur<br />

Herefter oprettes der en instans <strong>af</strong> klassen GrayScale, hvor det color-objekt, der indeholder filen<br />

”kim.bmp”, der blev loadet fra disken, overføres til. Dette gøres for at konvertere farvebilledet til<br />

gråtoner:<br />

GrayScale grayScale;<br />

grayScale.execute(color);<br />

Klassen Binary <strong>brug</strong>es bl.a. til at bestemme hvilken thresholdværdi, der skal <strong>brug</strong>es for at skelne<br />

forgrund fra baggrund. Til dette formål oprettes der en instans <strong>af</strong> denne. Binary-klassens execute()funktion<br />

tager gråtonebilledet grayScale som input:<br />

Binary binary;<br />

binary.execute(grayScale);<br />

Når thresholdværdien er udregnet, kan gråtonebilledet laves om til et binært billede, som kun består<br />

<strong>af</strong> baggrundspixels, som er sorte, <strong>og</strong> forgrundspixels, der er hvide. Der oprettes derfor en ny instans<br />

<strong>af</strong> klassen GrayScale kaldet binaryImage:<br />

GrayScale binaryImage;<br />

binary.makeBinary(binaryImage);<br />

For at bestemme hvilke hvide pixels der repræsenterer et kim, er det nødvendigt at finde ud <strong>af</strong> hvilke<br />

der rører <strong>ved</strong> hinanden. Til dette <strong>brug</strong>es klassen BlobDetection, som instantieres som<br />

blobDetection. Denne instans tager det binære billede binayImage som argument. De to<br />

efterfølgende funktioner setMaxArea() <strong>og</strong> setMinArea() sorterer grupperinger <strong>af</strong> forgrundspixels<br />

fra, som ikke er relevante at arbejde med. Grupper over 100.000 pixel er for store <strong>og</strong> grupper under<br />

250 pixel er for små:<br />

BlobDetection blobDetection;<br />

blobDetection.execute(binaryImage);<br />

blobDetection.setMaxArea(100000);<br />

blobDetection.setMinArea(250);<br />

For at kunne gemme informationer om hvert enkelt kim, er der oprettet en struktur til dette formål i<br />

klassen Seed. Der oprettes en pointer pSeed <strong>af</strong> klassen Seed. Herefter oprettes der en liste med alle<br />

de kim, som blev fundet i BlobDetection, som denne pointer sættes til at pege på. Til sidst gemmes<br />

antallet <strong>af</strong> kim i variablen numberOfSeeds:<br />

Seed *pSeed;<br />

int numberOfSeeds = blobDetection.makeSeeds(&pSeed);<br />

Efter alle kimene er fundet, skal deres x,y-koordinater, samt deres orientering θ i planet findes. Dette<br />

gøres <strong>ved</strong> at <strong>brug</strong>e klassen EllipseApproximation. Objektet ellipseApproximaion er en instans <strong>af</strong><br />

denne klasse. EllipseApproximations constructor skal have 2 parametre, den ene er pointeren til<br />

listen med kim, pSeed, den anden er antallet <strong>af</strong> kim i listen, numberOfSeeds, for kunne beregne x, y<br />

<strong>og</strong> θ på alle kimene:<br />

EllipseApproximation ellipseApproximation(pSeed, numberOfSeeds);<br />

ellipseApproximation.execute();<br />

Fra dette punkt i pr<strong>og</strong>rammet implementeres kvalitetssorteringen. Som det første findes toppen på<br />

alle kimene. Til dette formål anvendes TopDetection. TopDetection-klassen implementerer<br />

Arealforskel-algoritmen. Instansen <strong>af</strong> klassen kaldes topDetection. Igen tages de 2 parametre pSeed<br />

<strong>og</strong> numberOfSeeds som input:<br />

TopDetection topDetection(pSeed, numberOfSeeds);<br />

topDetection.execute();<br />

Side 70 <strong>af</strong> 131


14 Implementering 14.3 Pr<strong>og</strong>ramstruktur<br />

Når alle kimene har været igennem TopDetection, tages Symmetry-klassen i <strong>brug</strong>. Klassen <strong>brug</strong>es til<br />

at fastlægge kvalitetsparameteren, symmetri, for hvert <strong>af</strong> kimene. For at <strong>af</strong>vikle klassen sendes de to<br />

parametre pSeed <strong>og</strong> numberOfSeeds til constructoren:<br />

Symmetry symmetry(pSeed, numberOfSeeds);<br />

symmetry.execute();<br />

Nu er tiden inde til at beregne kvaliteten <strong>af</strong> kimene ud fra kvalitetsparametrene. Igen beregnes<br />

kvaliteten for hvert enkelt kim. Det første der sker, er at der oprettes en instans <strong>af</strong> klassen Quality,<br />

med de to parametre pSeed <strong>og</strong> numberOfSeeds som input. I Quality indlæses kvalitetsparametrenes<br />

grænser fra ”settings.ini”-filen. Det er ud fra disse parametre, at det beregnes hvilke kim der bliver<br />

godkendt.<br />

Quality quality(pSeed, numberOfSeeds);<br />

quality.execute();<br />

Når de godkendte kim er fundet, udskrives deres x,y-koordinater samt θ til tekstfilen<br />

”robotData.txt”.<br />

quality.saveRobotData("Data/robotData.txt");<br />

For at visualisere resultaterne <strong>af</strong> algoritmerne, genereres der en række billeder. Hertil anvendes<br />

klassen Draw (Appendiks 18.9.10 Draw s. 121). Det første billede der oprettes, tager udgangspunkt i<br />

originalbilledet ”kim.bmp”. Der tegnes på billedet med funktionen drawEllipse(). Dette billede<br />

viser alle de fundne kim <strong>og</strong> deres approkismerede ellipser. Billedet gemmes i ”Data”-mappen som<br />

”ellipse.bmp”.<br />

Draw draw;<br />

draw.load("kim.bmp");<br />

draw.drawEllipse(pSeed, numberOfSeeds, true);<br />

draw.save("Data/ellipse.bmp");<br />

Herefter tegnes der et nyt billede, som <strong>og</strong>så er baseret på det originale ”kim.bmp”. På dette billede er<br />

kun de godkendte kim med, samt en markering for hvert enkelt kim hvor toppen er fundet.<br />

Procesgangen er som følger: Først slettes alle tidligere data fra objektet draw med clear()<br />

funktionen. Herefter loades det originale billede ind. Derefter tegnes de approksimerede ellipser på<br />

de godkendte kim. Derefter indtegnes topmarkeringen med funktionen drawCenterTop(). Til sidst<br />

gemmes billedet i filen med navnet ”topBottomAppro<strong>ved</strong>.bmp”:<br />

draw.clear();<br />

draw.load("kim.bmp");<br />

draw.drawEllipse(pSeed, numberOfSeeds, false);<br />

draw.drawCenterTop(pSeed,numberOfSeeds, false);<br />

draw.save("Data/topBottomAppro<strong>ved</strong>.bmp");<br />

Billedet ”topBottomAppro<strong>ved</strong>.bmp” viser resultatet <strong>af</strong> den samlede algoritme.<br />

Side 71 <strong>af</strong> 131


14 Implementering 14.4 User interface<br />

14.4 User interface<br />

Som beskrevet i 2.1.1 Pr<strong>og</strong>ram s. 8 skal pr<strong>og</strong>rammet<br />

kun vise, om principperne virker efter hensigten.<br />

Derfor er det valgt kun at implementere et simpelt<br />

user interface. Der opbygges en konsolbaseret<br />

applikation, med et lille menusystem, der giver<br />

mulighed for at <strong>af</strong>vikle pr<strong>og</strong>rammet, indstille<br />

grænserne for kvalitetsparametrene <strong>og</strong> vise enkelte<br />

resultater i form <strong>af</strong> billeder (figur 14.1).<br />

Figur 14.1<br />

Menusystem<br />

Ho<strong>ved</strong>menu<br />

Kør<br />

Opsætning<br />

Fundne kim<br />

Godkendte kim<br />

Afslut<br />

Afvikler algoritme<br />

Åbner settings.ini<br />

I notepad<br />

Åbner paint <strong>og</strong><br />

viser alle funde<br />

kim<br />

Åbner paint <strong>og</strong><br />

viser alle de<br />

godkendte kim<br />

Side 72 <strong>af</strong> 131


15 Sammenfatning 15.1 Samlet test<br />

15 Sammenfatning<br />

15.1 Samlet test<br />

Det ønskes at teste det samlede pr<strong>og</strong>ram. I de enkelte kapitler testes funktionaliteten <strong>af</strong> de enkelte<br />

klasser, men her er det meningen at vise at sammenspillet mellem disse <strong>og</strong>så virker efter hensigten.<br />

15.1.1 Fremgangsmetode<br />

Testen er opdelt i tre dele. Den første del skal verificere at det er muligt at detektere kimene. Anden<br />

del skal vise at klassifikationen er implementeret efter hensigten. Sidste del <strong>af</strong> testen skal vise at user<br />

interfacet virker som forventet.<br />

15.1.2 Test 1 – detektering <strong>af</strong> kim<br />

I denne test skal det vises, om det er muligt at detektere alle kim. Derudover skal kimenes x, ykoordinater<br />

<strong>og</strong> θ findes. Dette gøres <strong>ved</strong> at <strong>af</strong>vikle pr<strong>og</strong>rammet på et billede. Efter algoritmen har<br />

detekteret kimene gemmes et billede, hvor de 3 parametre er tydelige at se.<br />

15.1.2.1 Testresultater<br />

Testresultaterne kan ses på billedet i<br />

figur 15.1.<br />

Kimenes placering <strong>og</strong> længdeakses<br />

orientering i planet skal findes. Ved at<br />

kigge nærmere på et tilfældigt udvalgt<br />

kim kan det ses, at der hvor ellipsens<br />

lille- <strong>og</strong> storakse krydser findes kimets<br />

midtpunkt. Dette punkt er kimets<br />

placering i x, y-planet. Derudover kan<br />

det <strong>og</strong>så ses, at kimets længdeakse er<br />

identisk med ellipsens storakse, hvilket<br />

er kimets orientering. Ydermere ses<br />

det, at kim der ligger i kanten <strong>af</strong><br />

billedet ikke bliver medtaget.<br />

Grupper at kim, dvs. flere kim der<br />

rører <strong>ved</strong> hinanden, bliver <strong>og</strong>så<br />

detekteret.<br />

15.1.3 Test 2 – <strong>klassificering</strong><br />

Figur 15.1<br />

Billedet viser resultatet <strong>af</strong> algoritmen hvor alle kim er fundet <strong>og</strong> har fået<br />

tilpasset en ellipse.<br />

Det skal verificeres, at teorien i 13 Quality s. 60 virker i samspil med de resterende klasser. Dette<br />

gøres <strong>ved</strong> at <strong>af</strong>vikle pr<strong>og</strong>rammet. Resultaterne gemmes herefter i en tekstfil samt et billede for at<br />

Side 73 <strong>af</strong> 131


15 Sammenfatning 15.1 Samlet test<br />

visualisere dem. Desuden ønskes det i denne test, at vise hvordan TopDetection-klassen virker i<br />

samspil med de andre klasser. I testen anvendes det brede sæt grænser, for den rektangulære<br />

udvælgelsesmodel (13.2.3 Bestemmelse <strong>af</strong> grænser s. 62).<br />

15.1.3.1 Testresultater<br />

Af figur 15.2 fremgår resultaterne.<br />

Det ses for det første, at der denne<br />

gang kun er blevet udvalgt n<strong>og</strong>le få<br />

kim i forhold til tidligere. Hvilke kim<br />

det er <strong>og</strong> hvorfor det netop er disse,<br />

der er blevet udvalgt kan læses i 13<br />

Quality s. 60.<br />

For hvert <strong>af</strong> de kim, som ses i figur<br />

15.2, er det forsøgt at finde hvor<br />

toppen ligger. Dette er vist lidt<br />

tydeligere i figur 15.3, hvor man kan se,<br />

at der på kimet er en lille lyserød<br />

markering. Denne indikerer, at toppen<br />

er beregnet til at ligge i den ende. Ved<br />

at gennemgå figur 15.2, ses det at<br />

toppen findes rigtigt på de 7 <strong>af</strong> 8 kim.<br />

På det ottende er det svært, at definere<br />

hvad der er top, da det her drejer sig<br />

om et meget deformt kim. Det ottende<br />

kim er det, som ses forstørret i øverste<br />

højre hjørne på figur 15.3.<br />

Dataene på de kim som godkendes i<br />

<strong>klassificering</strong>en gemmes alle i en<br />

tekstfil, ”robotData.txt”, som vises i<br />

figur 15.4. Her kan x- <strong>og</strong> y-koordinater,<br />

samt den vinkel, som kimets top<br />

danner i forhold til det vandrette plan,<br />

<strong>af</strong>læses.<br />

Figur 15.2<br />

Resultat med rektangel som udvælgelsesmodel <strong>og</strong> brede grænser.<br />

Figur 15.3<br />

Placeringen <strong>af</strong> den lyserøde prik <strong>af</strong>gør hvor toppen på kimet er fundet.<br />

Side 74 <strong>af</strong> 131


15 Sammenfatning 15.1 Samlet test<br />

Resultaterne i denne tekstfil er blevet sammenholdt med figur 15.3, hvor det i et billedebehandlingspr<strong>og</strong>ram<br />

er verificeret, at de stemmer.<br />

15.1.4 Test 3 – User interface<br />

User interfacet er opbygget efter den struktur, der er vist i 14.4 User interface s. 72. Testen gennemgår<br />

de enkelte dele i menustrukturen <strong>og</strong> viser hvordan de forskellige skærmbilleder ser ud.<br />

15.1.4.1 Testresultater<br />

Figur 15.5<br />

Pr<strong>og</strong>rammets ho<strong>ved</strong>menu<br />

Figur 15.4<br />

Tekstfil der viser dataene for de godkendte kim<br />

Side 75 <strong>af</strong> 131


15 Sammenfatning 15.1 Samlet test<br />

På figur 15.5 ses menupunkterne. Det første menupunkt er ”Kør”. Dette punkt <strong>af</strong>vikler algoritmerne,<br />

<strong>og</strong> viser skærmbilledet figur 15.6. Her ses det, at pr<strong>og</strong>ram<strong>af</strong>viklingen tager 481 millisekunder for lige<br />

præcis det billede, som er anvendt i denne test. Afviklingstiden <strong>af</strong>hænger <strong>af</strong> billedet <strong>og</strong> <strong>computer</strong>en.<br />

Figur 15.6<br />

Pr<strong>og</strong>rammet udprinter de tider som det tager at <strong>af</strong>vikle de forskellige algoritmer<br />

Det andet punkt i menuen er ”Opsætning”. Vælges dette punkt åbnes der en fil (figur 15.7), hvori<br />

parametrene for kvalitetsvurderingen kan sættes.<br />

Figur 15.7<br />

Settings.ini filen hvor man kan indstille kvalitetsparametrene<br />

Det tredje punkt ”Fundne kim” åbner et billede, hvor alle kimene er blevet fundet, <strong>og</strong> har fået<br />

approksimeret en ellipse. Et eksempel på dette billede er figur 15.1<br />

Det fjerde punkt ”Godkendte kim”, åbner et billede, hvor det kun er de kim der opfylder<br />

kvalitetsparametrene, der er indtegnet. Her er der tale om et billede magen til det i figur 15.2<br />

Side 76 <strong>af</strong> 131


15 Sammenfatning 15.2 Diskussion<br />

Det sidste punkt <strong>af</strong>slutter pr<strong>og</strong>rammet.<br />

15.2 Diskussion<br />

Arbejdet med biol<strong>og</strong>isk materiale har vist sig at være udfordrende. Der arbejdes i en verden med<br />

grænsetilfælde, hvor det kan være svært at <strong>af</strong>gøre hvad der er sandt <strong>og</strong> falskt, f.eks. hvornår er et kim<br />

for krumt, for bredt osv. Miljøet hvori kimene har befundet sig, har <strong>og</strong>så været en udfordring.<br />

Kimene klistrer til hinanden <strong>og</strong> belysningsforholdene varierer, da en fast testopstilling endnu ikke<br />

forefindes.<br />

At tage et billede med kameraet har givet anledning til en del overvejelser. For det første har det<br />

været vigtigt at fastlægge opløsningen på kimene. Hvor store skal de være på billedet, således at der<br />

lige netop kommer detaljer nok med. Her skal man d<strong>og</strong> <strong>og</strong>så passe på, at man ikke går i den anden<br />

grøft <strong>og</strong> får flere detaljer med end nødvendigt, for på den måde begrænses pladsen i selve billedet,<br />

<strong>og</strong> dermed udvælges færre kim. Valget <strong>af</strong> 10 pixels som et minimum i bredden på et kim virker<br />

fornuftigt <strong>og</strong> resulterer i et synsfelt for kameraet på 128 mm x 96 mm. At implementeringen <strong>af</strong> Fire-i<br />

biblioteket måtte udelades, var ikke hensigten fra starten, men set i lyset <strong>af</strong> de opståede problemer <strong>og</strong><br />

tiden i projektet, var dette en fornuftig beslutning.<br />

De opnåede resultater med Color- <strong>og</strong> GrayScale-klasserne har været tilfredsstillende. I forbindelse<br />

med GrayScale-klassen, foretages der ikke en egentlig gråtone-konvertering, da det blev vurderet, at<br />

der ikke var behov for en sådan. Den grønne kanal er tilstrækkelig i dette tilfælde.<br />

For at skille forgrund fra baggrund er Ridler <strong>og</strong> Calvards iterative thresholding-teknik blevet anvendt<br />

med succes. Selv efter få iterationer findes dalen imellem de to toppe i hist<strong>og</strong>rammet ligegyldigt hvor<br />

udgangspunktet tages.<br />

Identifikation <strong>af</strong> blobs gør, at man kan nøjes med kun at analysere små fragmenter <strong>af</strong> billedet, som<br />

er interessante at arbejde med. På denne måde har man identificeret <strong>og</strong> adskilt grupperinger <strong>af</strong> pixels<br />

fra hinanden. Dette er implementeret i BlobDetection-klassen, <strong>og</strong> resultaterne er helt som forventet.<br />

EllipseApproximation-klassen giver kimenes orientering i planet i form <strong>af</strong> en vinkel med det<br />

vandrette plan, samt længderne på akserne. Kombineret med beregningen <strong>af</strong> kimenes<br />

massemidtpunkter, som angiver kimenes placering, opnås det ønskede resultat om detektering <strong>af</strong><br />

kim. Metoden må derfor anses for at virke som forventet.<br />

Undersøgelsen <strong>og</strong> valg <strong>af</strong> TopDetection-algoritme resulterede i ”Arealforskel”. Metoden viste sig<br />

ikke at være så robust som ønsket. Ifølge testen findes toppen rigtigt på ca. 92 % <strong>af</strong> alle godkendte<br />

kim. Forestiller man sig, at der i en <strong>af</strong> udvælgelsesmodellerne anvendes brede grænser, udvælges der<br />

<strong>og</strong>så en del ikke-godkendte kim, hvilket vil resultere i, at toppen ikke findes rigtigt på flere <strong>af</strong><br />

kimene, <strong>og</strong> derfor vil resultatet på ca. 92 % ikke gælde i den situation. En anden betragtning, som er<br />

opstået under arbejdet er, at en topdetektering senere i beplantningsprocessen ville være nemmere,<br />

da kimene udvikler en kr<strong>af</strong>tig farveforskel mellem top <strong>og</strong> bund, som de modnes. Den nuværende<br />

udviklede TopDetection-algoritme vurderes ikke at være dækkende nok.<br />

Kvalitetsparameteren symmetri blev implementeret i Symmetry-klassen. Klassen tester symmetrien i<br />

kimene omkring deres længdeakse <strong>og</strong> giver et resultat mellem 0 – 100 %, som er forholdet imellem<br />

antallet <strong>af</strong> pixel, der ikke er symmetriske <strong>og</strong> kimets areal. Det vurderes, at klassen virker som ønsket.<br />

Kvalitetsvurderingen i Qualiy-klassen udfylder ikke dets formål. Det er ikke alene alle godkendte<br />

kim, der bliver udvalgt. Der er ikke fundet kvalitetsparametre nok, eller <strong>og</strong>så har det ikke været de<br />

rigtige, der er blevet anvendt. Det kunne <strong>og</strong>så være udvælgelsesmetoden, med netop at anvende<br />

Side 77 <strong>af</strong> 131


15 Sammenfatning 15.3 Konklusion<br />

kvalitetsparametre, der ikke er den optimale. Der kan <strong>og</strong>så stilles spørgsmålstegn <strong>ved</strong> n<strong>og</strong>le <strong>af</strong> de<br />

kim, som algoritmen godkender, men som ikke er blevet godkendt <strong>ved</strong> manuel inspektion eller<br />

omvendt. De kim, som gruppen har godkendt, er forsøgt godkendt objektivt ud fra kravene for 1.<br />

klasses kim givet <strong>af</strong> Jens Iver Find. Dette kan d<strong>og</strong> være yderst svært, da der kan være tale om<br />

grænsetilfælde, hvor den objektive vurdering bliver mere subjektiv.<br />

Generelt kan det siges, at alle gennemførte test har været simple. Resultaterne er som regel visuelt<br />

vurderede <strong>og</strong> ikke kvantitativt analyserede. Dette er grundet, at algoritmerne er <strong>computer</strong>baserede,<br />

<strong>og</strong> derfor kan der regnes med de store datamængder i billederne. Et menneske kan ikke duplikere<br />

denne regnekr<strong>af</strong>t, <strong>og</strong> netop derfor er vurderingerne <strong>af</strong> testene baseret på en simpel visuel inspektion.<br />

Skulle dataene analyseres korrekt, ville det være nødvendigt at <strong>af</strong>læse dem i <strong>computer</strong>ens<br />

hukommelse. Dette ville d<strong>og</strong> have været et stort arbejde. Af den årsag blev det besluttet, at vurdere<br />

testresultaterne <strong>ved</strong> at gemme dataene i en fil (som et billede) <strong>ved</strong> at <strong>brug</strong>e Draw-klassen. Det<br />

vurderes, at Draw-klassen ikke påvirker resultaterne i en nævneværdig grad, <strong>og</strong> derfor kan det<br />

retfærdiggøres, at anvende denne i verificering <strong>af</strong> testresultater.<br />

15.3 Konklusion<br />

Overordnet kan det konkluderes, at det har været muligt at fremstille et system, der med succes kan<br />

identificere alle kim i et givent billede, men der kun med begrænset succes, kan kvalitetssortere disse.<br />

Det følgende er gennemgang <strong>af</strong> de vigtige emner i rapportens to ho<strong>ved</strong>dele. Konklusionen bygger på<br />

kravspecifikationen (1.3 Kravspecifikation s. 6), <strong>og</strong> der henvises direkte til punkter i denne.<br />

15.3.1 Del I: <strong>Detektering</strong> <strong>af</strong> <strong>kimplanter</strong><br />

I første del <strong>af</strong> rapporten, blev det vist, at Color-klassen kan indlæse en BMP-fil <strong>og</strong> gøre denne<br />

tilgængelig for alle klasser, der har <strong>brug</strong> for den. På baggrund <strong>af</strong> testen i kapitlet omkring Colorklassen,<br />

kan det konkluderes, at systemet lever op til kravspecifikationens punkt 1.<br />

Det blev <strong>og</strong>så vist, at det er muligt at identificere enkelte <strong>og</strong> fritliggende kim, samt finde deres<br />

placering (koordinater) <strong>og</strong> længdeaksens orientering. Ved test kan det fastslås, at systemet godt kan<br />

håndtere kimplante-grupperinger, men at disse bliver identificeret som ét stort kim. Dette vurderes<br />

d<strong>og</strong> ikke som værende et problem, da kvalitetssorteringen vil sørge for, at den falske detektering vil<br />

blive sorteret fra pga. størrelsen <strong>af</strong> arealet. Dermed konkluderes det, at systemet lever op til punkt 2.<br />

15.3.2 Del II: Klassificering <strong>af</strong> <strong>kimplanter</strong><br />

I anden del <strong>af</strong> rapporten blev der udviklet forskellige metoder til udvælgelse <strong>af</strong> godkendte kim. I den<br />

forbindelse blev der <strong>af</strong>dækket flere parametre, der kan anvendes i udvælgelsesprocessen. Ydermere<br />

blev der udviklet 2 udvælgelsesmodeller, til at vurdere kimene med ud fra udvælgelsesmodellerne:<br />

boks <strong>og</strong> ellipsoide. Det er gruppens vurdering, at den analyse der ligger til bunds for bestemmelsen<br />

<strong>af</strong> parametrene <strong>og</strong> udvælgelsesmodellerne ikke er omfattende nok, <strong>og</strong> at der <strong>ved</strong> en mere omfattende<br />

analyse kan findes flere parametre <strong>og</strong> udvælgelsesmodeller. Dette er nødvendigt, da systemet ikke<br />

entydigt kan udvælge alene alle første klasses godkendte kim. Dermed kan det konkluderes, at<br />

systemet ikke lever op til punkt 3.a <strong>og</strong> 3.b.<br />

Side 78 <strong>af</strong> 131


15 Sammenfatning 15.4 Videreudvikling<br />

Der blev d<strong>og</strong> med succes implementeret en metode til, at udvælge kim, hvis parametre falder inden<br />

for <strong>brug</strong>erspecificerede grænser. Systemet kan yderligere udskrive x, y <strong>og</strong> θ på de udvalgte kim til en<br />

fil, <strong>og</strong> dermed lever systemet op til punkt 3.c <strong>og</strong> 3.d.<br />

I sammenfatningen er der lavet en samlet test <strong>af</strong> systemet. Denne test har til formål, at vise at hele<br />

systemet virker, som det skal, når alle klasserne arbejder sammen. Det ses fra testen, at <strong>ved</strong><br />

anvendelse <strong>af</strong> billeder fra test <strong>af</strong> Quality-klassen, opnås samme resultat. Der<strong>ved</strong> konkluderes det, at<br />

klasserne arbejder sammen korrekt. Der er udviklet et konsolbaseret interface, <strong>og</strong> testen viser, at det<br />

er muligt for <strong>brug</strong>eren, at angive hvilke grænser kvalitetssorteringen skal anvende. Ydermere ses det,<br />

at det er muligt at se resultatet fra detekteringen <strong>af</strong> alle kim <strong>og</strong> resultatet <strong>af</strong> kvalitetssorteringen, <strong>ved</strong><br />

at interfacet automatisk kan hente disse billeder frem <strong>og</strong> vise dem. Dermed lever systemet op til<br />

punkt 4.<br />

Samlet vurderer gruppen at ”Del I: <strong>Detektering</strong> <strong>af</strong> <strong>kimplanter</strong>” fungerer som ønsket, <strong>og</strong> at der ikke<br />

er yderligere at foretage sig i denne del. D<strong>og</strong> vurderes det, at ”Del II: Klassificering <strong>af</strong> <strong>kimplanter</strong>”<br />

har to vigtige udfordringer (punkt 3.a <strong>og</strong> 3.b), der skal løses før systemet er fuldt funktionelt.<br />

15.4 Videreudvikling<br />

Dette <strong>af</strong>snit har til formål, at give gruppens bud på hvilke emner der kan være interessante at<br />

videreudvikle. Generelt kan det siges, at der ikke er fundet mange alternativer til hver algoritme, der<br />

er implementeret på nær i TopDetection. Dette skyldes delvist, at størstedelen <strong>af</strong> algoritmerne er<br />

meget simple, <strong>og</strong> der derfor ikke er mange alternativer, men <strong>og</strong>så at gruppen fra starten, i samarbejde<br />

med vejleder, har fundet frem til algoritmer, der blev vurderet til at løse opgaven. Herefter var det<br />

meningen, at en implementering skulle <strong>af</strong>gøre hvorvidt, der var problemer med den implementerede<br />

algoritme, <strong>og</strong> hvis ikke, kunne det konkluderes, at algoritmen fungerede som ønsket, <strong>og</strong> der ville ikke<br />

blive udviklet alternativer. En tilbundsgående analyse <strong>af</strong> alle alternative algoritmer, inden der blev<br />

implementeret, blev vurderet til at være en for stor opgave for gruppen, set i lyset <strong>af</strong> projektets<br />

begrænsede tid.<br />

15.4.1 Kamera<br />

Det er gruppens holdning, at <strong>ved</strong> videreudvikling på projektet, vil det være fordelagtigt at<br />

implementere kameraet direkte i kodeprojektet, som det <strong>og</strong>så var planen fra starten. Dvs. at den<br />

kode der er udviklet fra gruppens side vil interface direkte med kode, der kommunikerer med<br />

kameraet. På den måde er al funktionalitet samlet i ét pr<strong>og</strong>ram.<br />

Det er tidligere beskrevet, at den optimale opløsning giver et synsfelt på ca. 128 mm x 96 mm.<br />

Gruppen vurderer, at det er TopDetection, der er toneangivende i den henseende. Derfor vil det<br />

være sandsynligt, at man vil kunne få et større synsfelt, hvis TopDetection udelades eller ændres.<br />

Det skal herefter undersøges nærmere, hvad den mindste opløsning skal være, da det ikke vides med<br />

sikkerhed. De fleste <strong>af</strong> algoritmerne kan arbejde med selv meget små objekter, men usikkerheden<br />

bliver større, som objekterne bliver mindre. I tilfælde <strong>af</strong> at synsfeltet er mindre end bredden på det<br />

transportbånd eller bord, der skal passere kimene forbi kameraet, må der laves en løsning således<br />

båndet eller bordet kan rykkes under kameraet, eller kameraet kan rykkes over båndet/bordet, eller<br />

evt. lave flere parallelle kameraopstillinger.<br />

Side 79 <strong>af</strong> 131


15 Sammenfatning 15.4 Videreudvikling<br />

15.4.2 EllipseApproksimation<br />

I slutningen <strong>af</strong> projektet blev gruppen klar over at der fandtes et værktøj, der muligvis kan håndtere<br />

mange <strong>af</strong> de problemstillinger der løses i projeket. Fourier-deskriptorer (Image processing [7]) kan<br />

muligvis delvist erstatte EllipseApproksimation, <strong>ved</strong> at det, sammen med hjælpefunktioner, kan være<br />

med til at bestemme længdeaksen, <strong>og</strong> vinklen objektet er roteret med. Det vurderes, at der stadig vil<br />

være behov for massemidtpunktsbestemmelsen.<br />

15.4.3 TopDetection<br />

Det er gruppens holdning, at det bedste resultat opnås, hvis bestemmelsen <strong>af</strong> toppen gøres på et<br />

senere tidspunkt i beplantningsprocessen. Dette skyldes, at kimene får en markant farveforskel<br />

mellem top <strong>og</strong> bund, som de modnes. Denne forskel er nem at detektere <strong>og</strong> vil give en markant<br />

større sikkerhed end at bestemme top på dette tidligere stadie i beplantningsprocessen, som er<br />

tilfældet nu.<br />

I tilfælde <strong>af</strong> der stadig ønskes at arbejde videre med at finde top <strong>og</strong> bund på dette trin i processen,<br />

anbefaler gruppen, at der arbejdes videre med ”Afstand 2”-algoritmen fra TopDetection-kapitlet.<br />

Denne algoritme virker lovende <strong>og</strong> vil muligvis kunne give et bedre resultat end den nuværende<br />

implementerede algoritme.<br />

Som et led i bestemmelsen <strong>af</strong> toppen bestemmes expand-shrink-pixel-parameteren. Denne<br />

parameter vil stadig være interessant i <strong>klassificering</strong>en <strong>af</strong> kimene, selvom toppen ikke skal findes.<br />

Dvs. ExpandShrink-klassen med fordel kan forblive en del <strong>af</strong> pr<strong>og</strong>rammet, selvom TopDetectionklassen<br />

evt. fjernes.<br />

Som alternativ til ”Afstand 2”-algoritmen, er det <strong>og</strong>så blevet foreslået, at finde toppen <strong>af</strong> kimet, <strong>ved</strong><br />

at finde det sted hvor kimet er bredest, vinkelret på længdeaksen. Dette er en meget simpel<br />

algoritme, men er en teori, der er opstået, efter gruppen har kigget mange billeder igennem, <strong>og</strong> lagt<br />

mærke til at kimene generelt er bredest i toppen.<br />

15.4.4 Quality<br />

Gruppen vurderer, at Fourier-deskriptorer kan anvendes i stedet for de tidligere udviklede parametre<br />

<strong>og</strong> udvælgelsesmodeller. Det er d<strong>og</strong> uvist, om Fourier-deskriptorer vil kunne løse opgaven bedre<br />

end de nuværende parametre <strong>og</strong> udvælgelsesmodeller, men det er et emne der med fordel kan<br />

undersøges nærmere. Nearest Neighbour er navnet på en anden udvælgelsesmodel. Denne model<br />

anvender de tidligere fundne kvalitetsparametre, men er altså et alternativ til boksen <strong>og</strong> ellipsoiden.<br />

Det kan <strong>og</strong>så her anbefales at undersøge denne nærmere, med henblik på at vurdere om den kan<br />

erstatte andre modeller. Samlet set er der mange andre modeller <strong>og</strong> systemer, der kan erstatte det,<br />

der er udviklet i projektet, <strong>og</strong> nærmere analyser kan <strong>af</strong>dække, om der er flere interessante modeller at<br />

anvende, som ikke er nævnt her. Gruppen <strong>af</strong>viser ikke, at der kan laves en holdbar løsning, ud fra<br />

det der allerede er lavet, men vil samtidigt heller ikke <strong>af</strong>vise, at der findes bedre modeller <strong>og</strong><br />

systemer. Det vil et mere detaljeret analysearbejde <strong>af</strong>dække. Ydermere er det gruppens holdning, at<br />

det skal undersøges, om der kan findes flere kvalitetsparametre, end dem der allerede er <strong>af</strong>dækket.<br />

Hvis det ønskes at vurdere krumheden <strong>af</strong> et objekt, kan expand-shrink-pixels til dels anvendes.<br />

Succesen <strong>af</strong> denne <strong>af</strong>hænger d<strong>og</strong> <strong>af</strong> hvor <strong>af</strong>langt indhakket i objektet er. En mere pålidelig algoritme<br />

kunne være en, hvor man først finder alle midterpunkterne i objektet. Dvs. i hele objektets længde<br />

vurderes det for hver horisontale linie, hvor midten på objektet er i den linie. Herefter fittes en ret<br />

Side 80 <strong>af</strong> 131


15 Sammenfatning 15.4 Videreudvikling<br />

linie til punkterne. Til sidst gås der igennem for alle punkter, <strong>og</strong> <strong>af</strong>standen fra midterpunktet til den<br />

fittede linie er så et mål for, hvor krumt objektet er.<br />

15.4.5 Implementering<br />

Ved implementering i fremtiden vil det være interessant, at lave en form for ekstern trigning <strong>af</strong><br />

pr<strong>og</strong>rammet. På den måde vil pr<strong>og</strong>rammet blive eksekveret når kim passerer under det, <strong>og</strong> tage et<br />

billede <strong>og</strong> analysere det. Ydermere skal pr<strong>og</strong>rammet interfaces med en robot. På nuværende<br />

tidspunkt bliver koordinaterne for godkendte kim gemt i ”robotData.txt”, men en optimal<br />

implementering ville muligvis indebære en overførsel <strong>af</strong> data direkte til robotten <strong>ved</strong> anvendelse <strong>af</strong><br />

en protokol.<br />

Der kan <strong>og</strong>så udvikles et gr<strong>af</strong>isk <strong>brug</strong>erinterface (GUI), der på en mere hensigtsmæssig måde giver<br />

mulighed for at angive grænserne, <strong>og</strong> få vist hvilke kim der udvælges. GUI’et kan vise billederne som<br />

pr<strong>og</strong>rammet analyserer <strong>og</strong> resultatet, uden at der skal åbnes eksterne pr<strong>og</strong>rammer op.<br />

I forbindelse med en reel implementering skal det <strong>og</strong>så vurderes, hvorvidt en ændring i overfladen <strong>af</strong><br />

transportbåndet har effekt for, hvorvidt pr<strong>og</strong>rammet fortsat virker som ønsket. Gruppen vurderer,<br />

at det vil være en hensigtsmæssig løsning at anvende et finmasket net hertil, men at det skal<br />

undersøges nærmere, om det vil give anledninger til ændringer i pr<strong>og</strong>rammet. I tilfælde <strong>af</strong> valg <strong>af</strong><br />

andre løsninger, skal det vurderes konsekvenserne her<strong>af</strong>.<br />

Side 81 <strong>af</strong> 131


16 Litteraturliste 15.4 Videreudvikling<br />

16 Litteraturliste<br />

[1] Ingeniørhøjskolen Odense Teknikum Elektroretningen December 2000 AIPA: E- <strong>og</strong> I-PRO 1<br />

Kompendium, Re<strong>vision</strong> 3, 990927/AIPA.<br />

[2] Find, Jens Iver: Høj-tech træer præsentation-1.ppt.<br />

[3] Davies, E.R: Machine Vision, 3rd edition 2005, Morgan Kaufmann. ISBN: 0-12-206093-8.<br />

[4] Horn, Bertholde Klaus Paul: Robot Vision, 3rd printing 1987, MIT Press. ISBN: 0-07-030349-5.<br />

[5] Trussell, H. J.: Comments on ”Picture Thresholding Using an Iterative Selection Method”, IEEE<br />

Transactions on systems, man, and Cybernetics, Vol. Smc-9, no. 5. May 1979.<br />

[6] Ridler, T. W. <strong>og</strong> Calvard, S.: Picture Thresholding Using an Iterative Selection Method, IEEE<br />

Transactions on systems, man, and Cybernetics, Vol. Smc-8, no. 8. August 1978.<br />

[7] Image processing, March issue 1999.<br />

Side 82 <strong>af</strong> 131


17 Ordliste 15.4 Videreudvikling<br />

17 Ordliste<br />

Ord Beskrivelse<br />

Array En gruppe <strong>af</strong> hom<strong>og</strong>ene elementer <strong>af</strong> en specifik datatype<br />

Blob En del <strong>af</strong> et binært billede hvor alle pixels er sammenhængende<br />

BMP-header Den første del <strong>af</strong> en BMP-fil, der består <strong>af</strong> to under-headers. Disse indeholder<br />

yderligere information om BMP-filen<br />

Boundingbox Det mindste rektangel der lige præcis omgrænser en blob<br />

Fire-i API En softwarepakke fra firmaet Unibrain, der via FireWire kan kommunikere med<br />

et kamera<br />

FireWire Er en PC seriel bus interface-standard<br />

MatLab Et numerisk beregningsmiljø <strong>og</strong> et pr<strong>og</strong>rammeringsspr<strong>og</strong> fra firmaet The<br />

Math­Works<br />

Pixel Sammensat <strong>af</strong> ”picture element” hvor picture er forkortet pix. En pixel er et<br />

enkelt punkt i et gr<strong>af</strong>isk billede<br />

RGB-værdier Et tal mellem 0 <strong>og</strong> 255, som anvendes i de 3 farvekanaler, rød, grøn <strong>og</strong> blå<br />

SDU Syddansk Universitet<br />

Threshold Tærskelværdi der l<strong>og</strong>isk adskiller to tilfælde. Anvendes i projektet som en værdi<br />

der adskiller forgrund fra baggrund<br />

WDM Windows Driver Model<br />

Side 83 <strong>af</strong> 131


18 Appendiks 18.1 Klasseoversigt<br />

18 Appendiks<br />

18.1 Klasseoversigt<br />

-int height<br />

-int width<br />

-unsigned char**ppRedArray<br />

-unsigned char**ppGreenArray<br />

-unsigned char**ppBlueArray<br />

Color<br />

+Color(void)<br />

+Color(const Color &colorInput)<br />

+~Color()<br />

-void makeVirtualImage(void)<br />

+void execute(int width, int height)<br />

+int execute(char *path)<br />

+void clearImage(void)<br />

+int getWidth(void)<br />

+int getHeight(void)<br />

+int setValue(int x, int y, unsigned char redColor, unsigned char greenColor, unsigned char blueColor)<br />

+int getValue(int x, int y, unsigned char &redColor, unsigned char &greenColor, unsigned char &blueColor)<br />

+unsigned char **getRedPointer(void)<br />

+unsigned char **getGreenPointer(void)<br />

+unsigned char **getBluePointer(void)<br />

+void save(char *filename)<br />

GrayScale<br />

-int width;<br />

-int height;<br />

-unsigned char **ppArray;<br />

+GrayScale(void)<br />

+GrayScale(const GrayScale& grayScaleInput)<br />

+~GrayScale()<br />

-void makeVirtualImage(void)<br />

+void operator= (const GrayScale& grayScaleInput)<br />

+void execute(int width, int height)<br />

+void execute(Color& color)<br />

+void execute(GrayScale *grayScaleInput)<br />

+int execute(char *path)<br />

+int setValue(int x, int y, unsigned char grayColor)<br />

+int getValue(int x, int y, unsigned char &grayColor)<br />

+void clearImage(void)<br />

+int getWidth(void)<br />

+int getHeight(void)<br />

+unsigned char **getPointer(void)<br />

+void save(char *filename)<br />

Binary<br />

-int height<br />

-int width<br />

-int hist<strong>og</strong>ram[HISTOGRAM_SIZE]<br />

-int threshold<br />

-GrayScale *pGrayScale<br />

-unsigned char **ppGrayArray<br />

+Binary(void)<br />

-void makeHist<strong>og</strong>ram(void)<br />

-void evaluateThreshold(void)<br />

+void execute(GrayScale &grayScaleInput)<br />

+void makeBinary(GrayScale binaryImage)<br />

+void drawHist<strong>og</strong>ram(void)<br />

Side 84 <strong>af</strong> 131


18 Appendiks 18.1 Klasseoversigt<br />

Side 85 <strong>af</strong> 131


18 Appendiks 18.1 Klasseoversigt<br />

-unsigned char **ppBlob<br />

-Seed *pSeed<br />

-int numberOfSeeds<br />

-Color color<br />

-unsigned char **ppRedMap<br />

-unsigned char **ppGreenMap<br />

-unsigned char **ppBlueMap<br />

Symmetry<br />

+Symmetry(Seed *pSeedInput, int blobCount)<br />

+void execute(void)<br />

+int getPixelDeviation(int seedCount)<br />

+Coordinate rotateCoordinate(Coordinate coordinate, float angle)<br />

Draw<br />

Utilities<br />

+Utilities()<br />

+~Utilities()<br />

-Coordinates calculateCM(unsigned char **ppBlob, int ySize, int xSize, int numberOfPixels)<br />

+float average(int numberOfElements, float *arrayOfElements)<br />

+Coordinates calculateCenterOfMass(GrayScale &grayScale, int noOfPixels)<br />

+Coordinates calculateCenterOfMass(unsigned char **ppBlob, int ySize, int xSize, int numberOfPixels)<br />

+Draw(void)<br />

+Draw(int width, int height)<br />

+~Draw()<br />

+void clear(void)<br />

+void load(char *path)<br />

+void drawBlobs(Seed *pSeed, int numberOfSeeds, bool all)<br />

+void drawBounds(Seed *pSeed, int numberOfSeeds, bool all)<br />

+void drawEllipse(Seed *pSeed, int numberOfSeeds, bool all)<br />

+void drawCenterTop(Seed *pSeed, int numberOfSeeds, bool all)<br />

+void save(char *path)<br />

-Seed *pSeed<br />

-int numberOfSeeds<br />

-int expandShrinkLow<br />

-int expandShrinkHigh<br />

-int symmetryLow<br />

-int symmetryHigh<br />

-int areaLow<br />

-int areaHigh<br />

-float eccentricityLow<br />

-float eccentricityHigh<br />

-int selection<br />

Quality<br />

+Quality(Seed *pSeedInput, int blobCount)<br />

-void evaluateSeeds(void)<br />

-void getParametersFromFile(void)<br />

+void execute(void)<br />

+void saveSeedData(char *path)<br />

+void saveRobotData(char *path)<br />

Side 86 <strong>af</strong> 131


18 Appendiks 18.2 Projektoplæg<br />

18.2 Projektoplæg<br />

Titel: <strong>Detektering</strong> <strong>og</strong> <strong>klassificering</strong> <strong>af</strong> <strong>kimplanter</strong><br />

Baggrund:<br />

På danske forskningsinstitutioner er der udviklet meget effektive bioteknol<strong>og</strong>iske metoder til at<br />

klone planter, i første omgang kloning <strong>af</strong> nordmannsgran til dansk juletræsproduktion.<br />

Kloning kan sikre en stabil produktion <strong>af</strong> planter <strong>af</strong> høj, ensartet kvalitet <strong>og</strong> øge den gennemsnitlige<br />

salgspris pr. produceret træ. Men det er meget arbejdskrævende <strong>og</strong> dermed dyrt at håndtere klonede<br />

planter manuelt inden de når producenterne. Med <strong>computer</strong> <strong>vision</strong> vil robotter kunne gøre en del <strong>af</strong><br />

arbejdet med at finde, isolere <strong>og</strong> udplante spirende <strong>kimplanter</strong> fra sterile vækstmedier til fx en potte.<br />

Afgangsprojekt:<br />

I projektet skal der udvikles 2D <strong>computer</strong> <strong>vision</strong> metoder til at finde <strong>og</strong> kvalitetsvurdere spirende<br />

<strong>kimplanter</strong> der er spredt ud på en plan flade.<br />

18.3 Procesbeskrivelse<br />

Formålet med dette <strong>af</strong>snit er at beskrive, hvordan projektet forløb overordnet set. Det står klart, at<br />

forløbet stort set har været, som det blev planlagt i begyndelsen (2.2 Planlægning s.10). Milepælene har<br />

med rimelighed været overholdt, kun med få dages difference. Derudover har der været 2<br />

demonstrationsdage, hvor gruppen har fremlagt resultaterne for projektstyringsgruppen fra HiTec<br />

Elitetræer, samt andre interesserede.<br />

Det er gruppens opfattelse, at der har været et godt <strong>og</strong> dynamisk samarbejde, der har været præget <strong>af</strong><br />

intensiv fordybelse i emnerne. Ydermere har gruppemedlemmerne arbejdet sammen i større eller<br />

mindre omfang om næsten alle emnerne. Dette samarbejde på kryds <strong>og</strong> tværs kan være hårdt <strong>og</strong><br />

tidskrævende, men på den måde har det været muligt at skabe et hom<strong>og</strong>ent produkt.<br />

Det har vist sig at modellen med, at slå problemløsnings- <strong>og</strong> analysefasen sammen var en god måde<br />

at strukturere arbejdet på, i det mere forskningsprægede projekt. N<strong>og</strong>le tidligere semestres<br />

projektarbejde har vist, at 6-fasemodellen er en god model at anvende i projektarbejde, men i dette<br />

tilfælde blev det fra starten vurderet, at 6-fasemodellen ikke ville slå an. Sammenlægningen <strong>af</strong> de 2<br />

første faser blev en succes, i det mange problemstillinger opstod undervejs i udviklingen <strong>af</strong><br />

algoritmerne. De fleste <strong>af</strong> disse problemer var meget svære at identificere på forhånd.<br />

Samarbejde på tværs <strong>af</strong> professioner, med bl.a. biol<strong>og</strong>er, har været en lærerig proces på flere planer.<br />

For det første har det været interessant at lære omkring kloning <strong>af</strong> kim. For det andet har det være<br />

lærerigt, at formidle sin viden indenfor sit område til andre udenforstående, som f.eks. biol<strong>og</strong>er.<br />

Denne kommunikation på tværs <strong>af</strong> professioner har været givende.<br />

Side 87 <strong>af</strong> 131


18 Appendiks 18.4 Tidsplan<br />

18.4 Tidsplan<br />

Side 88 <strong>af</strong> 131


18 Appendiks 18.5 Orientering i planet<br />

18.5 Orientering i planet<br />

Det ønskes at finde den linie der angiver, hvor inertimoment<br />

(I) er mindst. Hertil anvendes teori fra Horn [4:48-53]. Det<br />

ønskes altså at bestemme minimum <strong>af</strong> flg. formel:<br />

2<br />

I = ∫∫ r b(, x y) dxdy (18.1)<br />

, hvor r er den korteste <strong>af</strong>stand fra et punkt (x,y) i objektet,<br />

til et punkt (x 0,y 0) på linien der ønskes fundet (figur 18.1).<br />

Det ønskes at finde en løsning for I, der kan udtrykkes i<br />

C++-kode. Først findes en ligning, for linien der ønskes<br />

fundet. Denne indsættes i ligningen for I. I bliver til sidst<br />

minimeret for at finde aksen med det mindste inertimoment.<br />

En linie i planet kan angives <strong>ved</strong> flg. parameterfremstilling: (, )<br />

x sin θ−ycos θ+ρ= 0<br />

bxy<br />

(, )<br />

(18.2)<br />

Her er θ vinklen, linien med mindst inertimoment danner med x-aksen, <strong>og</strong> ρ er den korteste <strong>af</strong>stand<br />

fra linien til origo (figur 18.2):<br />

( −ρsin θ, ρcos θ)<br />

−ρ<br />

sin θ<br />

Figur 18.2<br />

Vigtige punkter på figur<br />

θ<br />

y<br />

ρ<br />

ρ<br />

cosθ<br />

(x,y)<br />

r<br />

b(x,y)<br />

(x0,y0)<br />

Ved at anvende punkterne, hvor linien skærer x-<br />

<strong>og</strong> y-aksen, fås flg. parameterligninger:<br />

x0= −ρ sin θ + scos<br />

θ<br />

y = +ρcos θ + ssinθ<br />

(18.3)<br />

0<br />

, hvor s er <strong>af</strong>standen langs linien fra det tætteste<br />

punkt til origo.<br />

Afstanden r er den korteste <strong>og</strong> vinkelrette <strong>af</strong>stand<br />

mellem et punkt (x,y) i objektet, til et<br />

punkt (x 0,y 0) på linien. Med Pythagoras gælder<br />

flg. relation:<br />

( ) ( )<br />

2<br />

2 2<br />

r x x0 y y0<br />

= − + − (18.4)<br />

Indsættes ligning (18.3) i ligning (18.4) fås:<br />

( ) 2 ( sin cos ) 2 ( cos sin )<br />

2 2 2 2 2<br />

r = x + y +ρ + ρ x θ−y θ − s x θ+ y θ + s (18.5)<br />

Differentieres ligning (18.5) <strong>og</strong> sættes lig 0 fås et udtryk for s:<br />

x<br />

s = x cos θ+ ysinθ<br />

(18.6)<br />

y<br />

(x,y)<br />

r<br />

(x0,y0)<br />

b(x,y)<br />

Figur 18.1<br />

xy er et tilfældigt punkt i objektet<br />

x<br />

Side 89 <strong>af</strong> 131


18 Appendiks 18.5 Orientering i planet<br />

Dette udtryk indsættes i parameterligningerne (18.3), <strong>og</strong> der isoleres så forskellene findes:<br />

0<br />

( )<br />

( )<br />

x − x0= sin θ x sin θ−ycos θ+ ρ<br />

y − y = −cos θ x sin θ−ycos θ+ρ (18.7)<br />

Forskellene kan indsættes i udtrykket for ligning (18.4):<br />

( sin ( sin cos ) ) cos ( sin cos )<br />

( sin cos )<br />

( )<br />

2<br />

2 2<br />

r = θ x θ−y θ+ρ + − θ x θ−y θ+ρ<br />

...<br />

2<br />

r x y<br />

= θ− θ+ρ<br />

2<br />

(18.8)<br />

Det ses, at ligningen for (18.8) er lig ligningen for linien, der angiver det mindste inertimoment (hvor<br />

r = 0 ) (18.2). Ligning (18.8) indsættes nu i formlen for inertimomentet (18.1):<br />

( ) 2<br />

∫∫ sin cos ( , )<br />

(18.9)<br />

I = x θ−yθ+ ρ b x y dx dy<br />

Vi ønsker at finde minimum <strong>af</strong> ovenstående funktion, så derfor differentieres der med hensyn til<br />

ρ <strong>og</strong> ligningen sættes lig nul:<br />

( )<br />

Axsin θ−ycos θ+ρ = 0<br />

(18.10)<br />

, hvor ( xy , ) er massemidtpunktet i objektet, <strong>og</strong> A er arealet. Fra formlen ses det at aksen passerer<br />

igennem massemidtpunktet. Derfor kan der med fordel indføres nye koordinater, der gør at<br />

massemidtpunktet bliver centrum i koordinatsystemet:<br />

x′ = x − x , y′ = y − y<br />

Det betyder at følgende gælder:<br />

(18.11)<br />

x sin θ−ycos θ+ρ= x′ sin θ−y′ cos θ (18.12)<br />

Ved indsættelse i (18.9) <strong>og</strong> udregning <strong>af</strong> integrale fås:<br />

I A B C<br />

2 2<br />

= sin θ− sin θcosθ+ cos θ (18.13)<br />

Hvor A, B <strong>og</strong> C er defineret som:<br />

∫∫<br />

∫∫<br />

∫∫<br />

2<br />

( ) ( , )<br />

A = x′ b x y dx′ dy′<br />

2<br />

( ) ( )<br />

B = 2 x′′ y b x, y dx′ dy′<br />

2<br />

( ) ( , )<br />

C = y′ b x y dx′ dy′<br />

Ligningen for inertimomentet kan vha. substitutioner <strong>og</strong>så udtrykkes som:<br />

(18.14)<br />

1 1 1<br />

I = ( A+ C) − ( A−C) cos2θ− Bsin<br />

2θ<br />

(18.15)<br />

2 2 2<br />

Side 90 <strong>af</strong> 131


18 Appendiks 18.6 Bestemmelse <strong>af</strong> ellipseparametre<br />

Hvis dette udtryk differentieres <strong>og</strong> sættes lig nul, fås den løsning der giver det mindste inertimoment:<br />

B<br />

tan 2θ=<br />

A−C Ved anvendelse <strong>af</strong><br />

sin 2θ=±<br />

cos2θ=±<br />

2<br />

tan 2<br />

2<br />

sin 2θ<br />

θ= fås to løsninger for ligningen:<br />

2<br />

cos 2θ<br />

B<br />

( )<br />

2<br />

B + A−C A−C ( )<br />

+ −<br />

2<br />

B A C<br />

2<br />

2<br />

(18.16)<br />

(18.17)<br />

Herefter kan sin 2θ <strong>og</strong> cos2θ indsættes i formlen for I. Af de to løsninger, vil den negative hos<br />

både sin 2θ <strong>og</strong> cos2θ give det mindste inertimoment I min, <strong>og</strong> den positive vil give det største inertimoment<br />

I max.<br />

Ønskes vinklen til den principale storakse, θ major , der angiver det mindste inertimoment, kan θ major<br />

isoleres i den positive løsning for sin 2θ :<br />

θ =<br />

major<br />

1 arcsin<br />

2<br />

( ) 2<br />

⎛<br />

B<br />

⎞<br />

⎜ ⎟<br />

⎜ 2<br />

B + A−C ⎟<br />

⎝ ⎠<br />

18.6 Bestemmelse <strong>af</strong> ellipseparametre<br />

Det gælder at:<br />

max<br />

(18.18)<br />

2<br />

Imin b<br />

= (18.19)<br />

2<br />

I a<br />

Længderne b <strong>og</strong> a kan herefter bestemmes ud fra 2 relationer:<br />

e =<br />

2<br />

b<br />

1 − 2<br />

a<br />

(18.20)<br />

A = abπ<br />

(18.21)<br />

, hvor e er excentriciteten <strong>og</strong> A er arealet <strong>af</strong> ellipsen. Først udregnes længden a <strong>og</strong> dernæst <strong>brug</strong>es a<br />

til at udregne b. (18.20) kan omregnes til:<br />

2<br />

b<br />

e = 1 − ⇒ 2<br />

a<br />

2<br />

b 2 b 2 2<br />

e e b a e<br />

2<br />

= + 1 ⇔ = + 1 ⇔ = + 1<br />

a a<br />

A isoleres ligning (18.21):<br />

(18.22)<br />

Side 91 <strong>af</strong> 131


18 Appendiks 18.6 Bestemmelse <strong>af</strong> ellipseparametre<br />

A<br />

a =<br />

π b<br />

Indsættes udtrykket for b fra ligning (18.22):<br />

a<br />

a<br />

2<br />

a<br />

A<br />

1<br />

A<br />

1<br />

A<br />

=<br />

2<br />

π a e +<br />

=<br />

2<br />

π e +<br />

=<br />

2<br />

π e +<br />

Det gælder fra ligning (18.22) at<br />

a<br />

A<br />

=<br />

2<br />

π +<br />

=<br />

=<br />

e<br />

A<br />

2<br />

b<br />

π 2<br />

a<br />

A<br />

I<br />

π<br />

I<br />

min<br />

max<br />

1<br />

1<br />

b<br />

a<br />

2<br />

2<br />

2<br />

= e + 1 :<br />

Dernæst kan b ifølge ligning (18.21) findes som:<br />

(18.23)<br />

(18.24)<br />

(18.25)<br />

A<br />

b = (18.26)<br />

π a<br />

Hermed er der udledt udtryk for bestemmelse <strong>af</strong> længderne <strong>af</strong> stor- (a ) <strong>og</strong> lille-akse (b ) samt excentriciteten<br />

(e ).<br />

Side 92 <strong>af</strong> 131


18 Appendiks 18.7 Valg <strong>af</strong> TopDetection-algoritme<br />

18.7 Valg <strong>af</strong> TopDetection-algoritme<br />

18.7.1 Brainstorm<br />

For at finde metoder til at detektere top eller bund er der blevet brainstormet på emnet. Det skal<br />

bemærkes, at gruppen på tidspunktet, da brainstormen blev gennemført, endnu ikke havde set et<br />

rigtigt kim, <strong>og</strong> kun kendte deres udseende fra andenhåndsbeskrivelser. Brainstormen er lavet på<br />

baggrund <strong>af</strong> disse forudsætninger, som antages opfyldt:<br />

1. Kimenes centerkoordinater kendes, samt akseorienteringer, som er et resultat <strong>af</strong> ellipse<br />

approksimationen<br />

2. Kimene er i den ene ende runde <strong>og</strong> forholdsvis glatte. Det er herfra, at rodnettet senere<br />

udvikler sig. I toppen derimod, kan der allerede på dette stadie, anes en svag begyndelse til<br />

kimbladene, som gør at planten er lidt flosset <strong>og</strong> har n<strong>og</strong>le rundinger<br />

<strong>og</strong> hak<br />

Brainstormen resulterede i et antal metoder <strong>og</strong> teknikker, som kan anvendes<br />

til formålet:<br />

18.7.1.1 Cirkel<br />

Metoden går ud på, at man fra den approksimerede ellipses storakse finder<br />

frem til skæringspunkterne med kanten <strong>af</strong> objektet. Fra centrum <strong>og</strong> i 2/3 <strong>af</strong><br />

<strong>af</strong>standen til skæringspunkterne, tegner man en cirkel. Herefter kontrolleres<br />

det, om der er sorte baggrundspixels med i cirklerne. Hvis ikke øges radius,<br />

<strong>og</strong> operationen foretages igen. Efterhånden som cirklerne udvides, vil der i<br />

toppen, begynde at komme baggrundspixels med, mens cirklen i bunden<br />

stadig kun får hvide pixels (figur 18.3). På denne måde kan det <strong>af</strong>gøres, hvad<br />

der er top <strong>og</strong> bund. Det kræver d<strong>og</strong>, at centeraksen ligger præcist, som vist<br />

på figur 18.3, altså at den går lige igennem top <strong>og</strong> bund. Det vil nok ikke<br />

realistisk, at kimet vil være symmetrisk omkring centeraksen. Derfor vil<br />

cirklerne muligvis ikke ligge indenfor kimet (figur 18.4).<br />

Ulemper<br />

• Figuren skal være symmetrisk omkring ellipsens længdeakse.<br />

18.7.1.2 Afstand 1<br />

Den første <strong>af</strong>standsmetode går ud på, at man fra centrum måler <strong>af</strong>stande<br />

ud til kanten i begge ender (figur 18.5). Der holdes så øje med hvordan<br />

<strong>af</strong>standene fordeler sig. Starter de med at være korte, for derefter at vokse<br />

indtil de falder igen, kan man gå ud fra, at det er bunden man har fundet.<br />

Sker der pludselig et fald i stedet for en stigning, må det være enden med<br />

de karakteristiske ”bølgedale” eller hak som er fundet. Metoden er en<br />

følsom overfor urenheder i kanten, som kan resultere i et fald hvor man<br />

forventer en stigning. Der kan anvendes en threshold-teknik, som sorterer<br />

disse ikke ønskværdige ændringer fra.<br />

Figur 18.3<br />

Cirkel-metoden<br />

Figur 18.4<br />

Illustrerer problemet med<br />

en skæv centerakse<br />

Figur 18.5<br />

Afstand 1-metoden<br />

Side 93 <strong>af</strong> 131


18 Appendiks 18.7 Valg <strong>af</strong> TopDetection-algoritme<br />

Fordele<br />

• Metoden indebærer kun beregning <strong>af</strong> <strong>af</strong>stande, <strong>og</strong> på denne måde er algoritmen meget simpel<br />

Ulemper<br />

• Metoden er ikke så robust, da det ikke er sikkert at kanterne er<br />

”rene”. Dette kan d<strong>og</strong> omgås <strong>ved</strong> at <strong>brug</strong>e en thresholdværdi, der<br />

<strong>af</strong>gør hvor kr<strong>af</strong>tig en stigning skal være før den accepteres<br />

18.7.1.3 Afstand 2<br />

Den anden <strong>af</strong>standsmetode er at plotte alle <strong>af</strong>standene fra hver ende imod<br />

den vinkel, som <strong>af</strong>standsvektoren danner med centeraksen (figur 18.6).<br />

Til dette plot tilpasses en parabel. Den parabel, som er stejlest,<br />

repræsenterer den ende hvor den er mest rund, altså bunden, hvilket er illustreret på figur 18.7. I<br />

stedet for at <strong>brug</strong>e centerpunktet til at beregne <strong>af</strong>standene fra, kunne man i stedet <strong>brug</strong>e ellipsens to<br />

brændpunkter. Ved at gøre dette opnås der større<br />

variation mellem der hvor der er lang <strong>af</strong>stand, <strong>og</strong> hvor<br />

der er kort. Dette vil give et tydeligere resultat.<br />

Fordele<br />

• Den tilpassede parabel bliver vægtet med vinklen,<br />

hvilket giver større variation<br />

Ulemper<br />

• Hvis bunden, hvor der ingen flosser er, er meget<br />

flad, så bliver krumningen på den tilnærmede<br />

parabel <strong>og</strong>så lille, <strong>og</strong> derfor kan det være svært at<br />

skelne mellem top <strong>og</strong> bund<br />

18.7.1.4 dy/dx 1<br />

Differentialkvotienten findes rundt langs kanten, <strong>og</strong> der<br />

hvor den er størst, er toppen (figur 18.8).<br />

Fordele<br />

• Metoden <strong>af</strong>hænger ikke <strong>af</strong> figurens centerkoordinater<br />

Ulemper<br />

• Det er langt fra sikkert det er i toppen at der er den største hældning<br />

• Det er svært at differentiere, da kanterne på figuren aldrig er ”rene”,<br />

hvilket kan medføre kr<strong>af</strong>tig stigning/fald i differentialkvotienten<br />

18.7.1.5 dy/dx 2<br />

Her kigges <strong>og</strong>så på differentialkvotienten, men her er det ikke størrelsen på<br />

hældningen, men fortegnet der er interessant. I den ende hvor fortegnet skifter flest gange findes<br />

toppen.<br />

Afstans<br />

Afstans<br />

Vinkel θ<br />

Vinkel θ<br />

Figur 18.6<br />

Afstand 2-metoden<br />

Figur 18.7<br />

Tilpasning <strong>af</strong> parabel i Afstand 2-metoden<br />

Figur 18.8<br />

Illustration <strong>af</strong> metoderne<br />

dy/dx1 <strong>og</strong> 2<br />

θ<br />

Side 94 <strong>af</strong> 131


18 Appendiks 18.7 Valg <strong>af</strong> TopDetection-algoritme<br />

Fordele<br />

• Den er simpel fordi den ikke <strong>af</strong>hængig <strong>af</strong> figurens centerkoordinater eller akse orienteringer<br />

Ulemper<br />

• Det er svært at differentiere, da kanterne på figuren aldrig er ”rene”, hvilket kan medføre<br />

lokale fortegnsændringer<br />

18.7.1.6 Spejling<br />

Objektet spejles omkring lilleaksen i ellipsen, <strong>og</strong> der foretages en<br />

sammenligning <strong>af</strong> de to halvdele. Der hvor der er mest forskel, findes den<br />

reelle top. Denne metode er d<strong>og</strong> ret svær at realisere, da den lille akse ikke<br />

<strong>af</strong>standsmæssigt ligger lige langt fra top <strong>og</strong> bund, men i stedet <strong>af</strong>hænger <strong>af</strong><br />

figurens massemidtpunkt (figur 18.9). Lilleaksen vil derfor flytte sig<br />

<strong>af</strong>hængigt <strong>af</strong> kimets form. Dette gør det svært at opstille et kriterium, som<br />

kan <strong>brug</strong>es som sammenligningsgrundlag, for at bestemme hvilken ende<br />

der er top <strong>og</strong> bund.<br />

Ulempe<br />

• Det er svært at <strong>af</strong>gøre gyldigheden <strong>af</strong> kriteriet i metoden<br />

18.7.1.7 Arealforskel<br />

Først udvides objektet med et antal pixels, hvorefter det skrumpes<br />

tilsvarende tilbage igen. Dette udjævner alle indhak, hvilket gør at<br />

”bølgedalen” i toppen vil blive gjort mere flad (figur 18.10). Nu<br />

foretages der en sammenligning <strong>af</strong> det oprindelige <strong>og</strong> det skrumpede<br />

objekt. I toppen vil der nu være delarealer, hvor de to objekter <strong>af</strong>viger<br />

fra hinanden, mens bunden stadig er intakt. Det er derfor nu muligt<br />

at identificere toppen som værende der, hvor den største arealforskel<br />

er. Der kan være et problem hvis indhakkene i ”bølgedalen” ikke er<br />

skarpe nok. Dette medfører, at der ikke vil være n<strong>og</strong>en forskel<br />

imellem de to objekter, <strong>og</strong> dermed bliver toppen ikke mulig at<br />

detektere.<br />

Fordele<br />

• Denne metode er u<strong>af</strong>hængig <strong>af</strong> centerkoordinater <strong>og</strong><br />

aksernes orientering<br />

Ulemper<br />

• Det er ikke sikkert, at det bliver n<strong>og</strong>en nævneværdig forskel<br />

at detektere, <strong>og</strong> det kan derfor blive svært at finde toppen<br />

18.7.1.8 Color<br />

Denne metode bygger på, at der ud fra farve, kan kendes forskel på<br />

de to ender. Ved at tage et gennemsnit <strong>af</strong> farverne i hver ende, <strong>og</strong><br />

sammenligne resultaterne kan toppen findes (figur 18.11).<br />

Fordele<br />

Figur 18.9<br />

Spejling omkring lilleaksen<br />

Figur 18.10<br />

Arealforskel-algoritmen<br />

Figur 18.11<br />

De 2 streger indikerer i hvilke<br />

områder gennemsnittet skal beregnes<br />

Side 95 <strong>af</strong> 131


18 Appendiks 18.7 Valg <strong>af</strong> TopDetection-algoritme<br />

• Det er enkelt at foretage en farve sammenligning, <strong>og</strong> igen er metoden u<strong>af</strong>hængig <strong>af</strong><br />

centerkoordinater <strong>og</strong> aksernes orientering<br />

Ulemper<br />

• Det er ikke sikkert, at der er n<strong>og</strong>en farveforskel at detektere<br />

18.7.1.9 Thinning<br />

Thinning vil sige, at der fjernes lag <strong>af</strong> fra ydersiden. Når man er nået ind til den<br />

sidste pixel inden figuren bliver delt, fjernes der ikke yderligere pixels. Dette<br />

resulterer i en y-form, som den vist på figur 18.12. I den ende, hvor y’et opstår,<br />

er toppen. Problemet her er, at der kan opstå grene, som dem i y’et, hvis<br />

figuren har udposninger, eller er uren i kanten. Det er derfor først nødvendigt,<br />

at rense kanten inden thinning-algoritmen kan tages i <strong>brug</strong>. Dette <strong>af</strong>hjælper<br />

d<strong>og</strong> stadig ikke problemet med udposninger.<br />

Fordele<br />

• Algoritmen giver et tydeligt resultat<br />

Ulemper<br />

• Algoritmen er følsom overfor ”urenheder” langs kanten, dvs. at der kan opstå grene udover<br />

de to som er i y’et<br />

• Udposninger på figuren kan have stor indflydelse<br />

18.7.1.10 Diameter<br />

Denne metode bygger på, at man tager et tilfældigt punkt i objektet. Fra dette<br />

punkt beregner man nu <strong>af</strong>standen til det punkt, i objektet, der ligger længst væk.<br />

Fra dette nye punkt beregner man så igen <strong>af</strong>standen til det punkt der ligger<br />

længst væk. På denne måde får man hurtigt beregnet den største diameter<br />

figuren kan have. Ved at beregne <strong>af</strong>standene fra diameteren til centeraksen i de<br />

to ender, kan toppen findes. Toppen er der, hvor der er længst <strong>af</strong>stand ind til<br />

storaksen (figur 18.13). Hvis kimet har en anden form, end den der er vist på<br />

figuren, kan diameteren komme til at ligge et andet sted. Det er derfor ikke et<br />

holdbart kriterium, at <strong>brug</strong>e <strong>af</strong>standen mellem diameteren <strong>og</strong> længdeaksen,<br />

som det ses på figur 18.14.<br />

Fordele<br />

• Algoritmen for <strong>af</strong>standsberegning er nem at udføre<br />

Ulemper<br />

• Algoritmen er baseret på længdeaksen i ellipsen <strong>og</strong> hvis denne ligger<br />

lidt skævt, er det ikke sikkert at kriteriet, om at det er <strong>af</strong>standen mellem<br />

længde aksen <strong>og</strong> diameteren, er <strong>brug</strong>bart<br />

18.7.1.11 Linie til alle punkter<br />

Figur 18.12<br />

Thinning, som danner<br />

et ”y” i toppen<br />

Figur 18.13<br />

Diameter<br />

Figur 18.14<br />

Problemet med parallelle<br />

akser<br />

Side 96 <strong>af</strong> 131


18 Appendiks 18.7 Valg <strong>af</strong> TopDetection-algoritme<br />

Denne metode bygger på, at man fra hver eneste pixel i kanten <strong>af</strong> objektet<br />

tegner en streg til hver enkel <strong>af</strong> alle andre pixels i kanten. På denne måde opstår<br />

der et nyt objekt, som har fået udfyldt kimbladsstrukturen i toppen (figur 18.15).<br />

Dette nye objekt <strong>og</strong> det oprindelige kan så sammenlignes. I den ende hvor der<br />

er mindst lighed findes toppen. Det kan d<strong>og</strong> give problemer, hvis kimet er<br />

krumt, hvilket kan ses på figur 18.16.<br />

På denne måde kommer stregerne som tegnes mellem punkterne til at ligge<br />

udenfor objektet.<br />

Fordele<br />

• Metoden er u<strong>af</strong>hængig <strong>af</strong> centerkoordinater <strong>og</strong> aksernes orientering<br />

Ulemper<br />

• Metoden er følsom overfor krumhed i kimet<br />

18.7.1.12 Ellipse<br />

Denne metode gør <strong>brug</strong> <strong>af</strong>, at der allerede er en approksimeret en ellipse.<br />

Denne kan anvendes til sammenligning med objektet. I den ende hvor der er<br />

mindst lighed mellem de to figurer, findes toppen (figur 18.17).<br />

Fordele<br />

• Der findes allerede teknikker til at approksimere en ellipse<br />

Ulemper<br />

• Metoden kræver at kimet er symmetrisk omkring længdeaksen i<br />

ellipsen<br />

18.7.2 Rating <strong>af</strong> idéer<br />

For at fastslå hvilken <strong>af</strong> idéerne fra brainstormingen der skal anvendes, benyttes en metode (AIPA<br />

[1:47-48]) hvor man sammenligner alle idéerne parvis. Metoden bygger på ét intuitivt valg <strong>af</strong> hvilken<br />

<strong>af</strong> de to idéer, der vinder sammenligningen. I tabel 18.1 er sammenligningen foretaget.<br />

Tabel 18.1<br />

Ratingskema hvor ideerne er sammenlignet parvis<br />

Figur 18.15<br />

Linie til alle punkter<br />

Figur 18.16<br />

Viser problemet med en<br />

buet figur<br />

Figur 18.17<br />

Ellipse<br />

Side 97 <strong>af</strong> 131


18 Appendiks 18.7 Valg <strong>af</strong> TopDetection-algoritme<br />

18.7.2.1 Valg <strong>af</strong> idé<br />

Herefter tælles der sammen hvor mange gange en idé har vundet en sammenligning. Den eller de<br />

som har vundet flest, går så videre til en nærmere undersøgelse. Det er valgt, at nr. 1, 2 <strong>og</strong> 3 er idéer,<br />

som gruppen ønsker at arbejde videre med.<br />

1. Diameter<br />

2. Thinning<br />

3. a) Arealforskel<br />

b) Afstand 2<br />

c) Linie til alle punkter<br />

Disse idéer ønskes nærmere undersøgt <strong>og</strong> det er heriblandt, at den metode som der ønskes at<br />

arbejde videre med skal findes.<br />

18.7.2.2 Førsteplads<br />

”Diameter”-metoden vandt ratingen, <strong>og</strong> det var derfor umiddelbart denne metode, der skulle <strong>brug</strong>es<br />

til at finde top <strong>og</strong> bund. Som nævnt i Appendiks 18.7.1.10 Diameter s. 96, er dens svaghed at kriteriet,<br />

om at <strong>brug</strong>e <strong>af</strong>standen mellem diameteren <strong>og</strong> storaksen i ellipsen, til at bestemme top <strong>og</strong> bund, ikke<br />

vil være holdbart i alle tilfælde. Ved nærmere undersøgelser viser det sig, det ikke nødvendigvis er i<br />

toppen, der er den længste <strong>af</strong>stand mellem de to linier. Hvis kimet er en asymmetrisk, kan det lade<br />

sig gøre at den største <strong>af</strong>stand opstår i bunden. Gruppen har vurderet at dette er for uholdbart, <strong>og</strong><br />

har derfor fravalgt metoden.<br />

18.7.2.3 Andenplads<br />

”Thinning” blev nr. 2 i ratingen efter Diameter-metoden. Metoden er, som beskrevet i Appendiks<br />

18.7.1.9 Thinning s. 96, følsom overfor urenheder i kanten samt udposninger i figuren. Ved nærmere<br />

undersøgelser viser det sig at det ikke sikkert, at y’et vil være lige. Det kan være krumt, <strong>af</strong>hængigt <strong>af</strong><br />

kanten på objektet. Der blev derfor ikke fundet n<strong>og</strong>et kriterium, der kan opstilles til at bestemme<br />

toppen. Derfor valgte gruppen <strong>og</strong>så at fravælge denne idé.<br />

18.7.2.4 Tredjeplads<br />

”Arealforskel” blev rated som nr. 3, sammen med ”Afstand 2” <strong>og</strong> ”Linie til alle punkter”. Her blev<br />

”Arealforskel” valgt, da det var den algoritme, som syntes at have flest fordele. Den blev vurderet<br />

som værende robust, <strong>og</strong> kræver kun at kimet har kimbladsstruktur. Dette gør det muligt, at udviske<br />

de skarpe kanter, <strong>og</strong> på denne måde få en nævneværdig forskel mellem det originale kim-objekt, <strong>og</strong><br />

det hvor algoritmen er blevet anvendt.<br />

Side 98 <strong>af</strong> 131


18 Appendiks 18.8 Kodestandard<br />

18.8 Kodestandard<br />

18.8.1 Indledning<br />

For at koden skal fremstå ensartet, er der fastlagt en kodestandard. Denne skal <strong>og</strong>så hjælpe til med at<br />

gøre koden mere læsevenlig.<br />

18.8.2 Navngivning<br />

Variabelnavne, klassenavne m.m. skrives altid på engelsk <strong>og</strong> skal værende sigende.<br />

18.8.2.1 Klasser<br />

Alle klasser navngives med det første b<strong>og</strong>stav stort. Indgår der flere ord i navnet, startes det nye ord<br />

igen med stort. Derudover har .h filer <strong>og</strong> .cpp filer altid det samme navn.<br />

Eksempel:<br />

class EllipseApproximation<br />

EllipseApproximation.cpp<br />

EllipseApproximation.h<br />

18.8.2.2 Variable<br />

I variabelnavne skrives det første b<strong>og</strong>stav altid med småt. Kommer der et nyt ord i navnet skrives<br />

dette med stort.<br />

Eksempel:<br />

int numberOfBlobs<br />

18.8.2.3 Definements<br />

Definements skrives altid med store b<strong>og</strong>staver <strong>og</strong> indgår der flere ord, adskilles disse <strong>af</strong> en<br />

underscore ”_”.<br />

Eksempel:<br />

#define HISTOGRAM_SIZE 256<br />

18.8.2.4 Pointere<br />

Pointere navngives med et ”p” foran navnet. ”p”’et er med småt <strong>og</strong> det efterfølgende ord er med<br />

stort. Er det en dobblet pointer tilføjes der et ”p” mere.<br />

Side 99 <strong>af</strong> 131


18 Appendiks 18.8 Kodestandard<br />

Eksempel:<br />

Seed *pSeed<br />

int **ppSubBlob<br />

18.8.3 Udseende<br />

18.8.3.1 Pointere<br />

Når pointeren oprettes benyttes ”*”-operatoren, som altid står sammen med navnet <strong>og</strong> ikke typen.<br />

Eksempel:<br />

int *pBlobList<br />

18.8.3.2 Referencer<br />

Oprettes der referencer med ”&”-operatoren, står denne altid sammen med navnet på referencen <strong>og</strong><br />

ikke typen<br />

Eksempel:<br />

void execute(GrayScale &binaryImage)<br />

18.8.3.3 Funktioner<br />

Der er ingen mellemrum mellem parentesen, <strong>og</strong> det første <strong>og</strong> sidste der står inde i den.<br />

Eksempel:<br />

void rootUnion(int a, int b)<br />

18.8.3.4 Indrykning<br />

Koden inddeles i niveauer. Et niveau er det der står mellem de to tegn ”{” <strong>og</strong> ”}” <strong>og</strong> der skal være<br />

én tabulator indrykning.<br />

Eksempel:<br />

int BlobDetection::rootFind(int a)<br />

{<br />

if (pSubBlobList[a] == a)<br />

{<br />

return a;<br />

}<br />

else<br />

{<br />

return rootFind(pSubBlobList[a]);<br />

}<br />

}<br />

Side 100 <strong>af</strong> 131


18 Appendiks 18.8 Kodestandard<br />

18.8.4 Pr<strong>og</strong>rammeringsregler<br />

Hvis en klasse består <strong>af</strong> flere funktioner, der <strong>af</strong>vikles i rækkefølge, oprettes der en execute()funktion<br />

hvorfra disse funktioner <strong>af</strong>vikles.<br />

Eksempel:<br />

void BlobDetection::execute(GrayScale &binaryImage)<br />

{<br />

pBinaryImage = &binaryImage;<br />

height = pBinaryImage->getHeight();<br />

width = pBinaryImage->getWidth();<br />

}<br />

findSubBlobs();<br />

joinSubBlobs();<br />

makeBlobs();<br />

Side 101 <strong>af</strong> 131


18 Appendiks 18.9 Implementering<br />

18.9 Implementering<br />

18.9.1 Color<br />

Da der er behov for at arbejde med billeder i forskellige størrelser, er bredden <strong>og</strong> højden variable.<br />

Selve billedet gemmes i tre dobbeltarrays. Disse tre dobbeltarrays indeholder hver sin farve (rød,<br />

grøn <strong>og</strong> blå). Det første index er y-koordinatet mens det andet index er x-koordinatet. På grund <strong>af</strong><br />

den variable højde <strong>og</strong> bredde er de tre dobbeltarrays allokeret dynamisk.<br />

18.9.1.1 Color()<br />

Ved hjælp <strong>af</strong> overloading er der lavet to forskellige versioner <strong>af</strong> constructoren Color(). Den ene er<br />

en simpel constructor, som sørger for at højden, bredden bliver initialiseret til 0. Da der er behov for<br />

at kunne kopiere et billede er den anden er en copy-constructor, der sørger for at kopiere et billede<br />

fra det ene color-objekt til et andet. Dette gøres <strong>ved</strong> at kopiere variablerne, allokere plads til de tre<br />

dobbelt arrays <strong>og</strong> kopiere værdierne fra de tre arrays til det nye objekt.<br />

18.9.1.2 execute()<br />

Ved hjælp <strong>af</strong> overloading er der lavet to forskellige versioner <strong>af</strong> execute(). Den ene version <strong>af</strong><br />

execute() tager den ønskede bredde <strong>og</strong> højde som parameter. Funktionen opretter de tre dobbeltarrays<br />

<strong>og</strong> sørger for at nulstille disse så billedet er sort som udgangspunkt.<br />

void Color::execute(int setWidth, int setHeight)<br />

{<br />

width = setWidth;<br />

height = setHeight;<br />

}<br />

makeVirtualImage();<br />

clearImage();<br />

Den anden version <strong>af</strong> execute() tager et filnavn som parameter. Filen skal være et ikke<br />

komprimeret BMP-billede. Hele filen bliver kopieret over i en buffer, så der kun skal læses fra<br />

harddisken én gang. Ud fra oplysninger fra headeren findes billedets højde samt bredde <strong>og</strong> de<br />

dynamiske arrays bliver allokeret.<br />

Far<strong>ved</strong>ybden læses ind fra headeren. Hvis far<strong>ved</strong>ybden er 8 bit oprettes der en palette. Indlæsning <strong>af</strong><br />

billeddata starter fra den adresse som offset-værdien peger på. Hvis billedets far<strong>ved</strong>ybde er 8 bit slås<br />

billeddataene op i paletten for at finde farven. Hvis billedet er 24 bit læses billededataene direkte ind<br />

i de 3 farvearrays.<br />

18.9.1.3 save()<br />

Funktionen sørger for at billedet bliver gemt til disken. For at undgå flere skrivninger til harddisken<br />

oprettes der en buffer, hvor alle dataene skrives i. Billedet bliver gemt i 24-bit, så der er ikke n<strong>og</strong>en<br />

palette med. Billedets højde, bredde, far<strong>ved</strong>ybde mv. bliver skrevet til headeren. Efterfølgende bliver<br />

de enkelte pixels farve skrevet i datadelen <strong>af</strong> bufferen. Når alle pixels er skrevet til bufferen kopieres<br />

denne til harddisken hvor filen oprettes.<br />

Side 102 <strong>af</strong> 131


18 Appendiks 18.9 Implementering<br />

18.9.1.4 getWidth(), getHeight()<br />

Da width <strong>og</strong> height er erklæret som ”private” <strong>brug</strong>es getWidth() <strong>og</strong> getHeight() til at hente<br />

henholdsvis bredden <strong>og</strong> højden <strong>af</strong> det aktuelle billede.<br />

18.9.1.5 getRedPointer(), getGreenPointer(), getBluePointer()<br />

Funktionerne returnerer en pointer til det aktuelle dobbeltarray. Funktionerne <strong>brug</strong>es, hvis man har<br />

behov for at tilgå billededataene direkte. Dette er det hurtigste, hvis man har mange skrivninger eller<br />

læsninger til givent billede. D<strong>og</strong> skal man selv holde styr på, at man skriver indenfor billedet.<br />

18.9.1.6 getValue(), setValue()<br />

getValue() <strong>brug</strong>es til at få oplyst farven i en given pixel. setValue() <strong>brug</strong>es til at sætte farven i en<br />

given pixel. Når man benytter disse mutator- <strong>og</strong> accessor-funktioner sørger klassen for, at man ikke<br />

læser/skriver uden for billedet.<br />

18.9.1.7 clearImage()<br />

Funktionen <strong>brug</strong>es til at nulstille alle pixels i billedet. Funktionen <strong>brug</strong>es bl.a. efter at man har<br />

allokeret ny hukommelse, så de data der skulle ligge på de givne pladser bliver nulstillet.<br />

18.9.1.8 makeVirtualImage()<br />

Funktionen allokerer hukommelse til dobbeltarrays med de tre farver i.<br />

18.9.1.9 ~Color()<br />

Destuctoren sørger for at slette de tre dynamisk erklærede dobbeltarrays.<br />

18.9.2 Binary<br />

I funktionen execute() i klassen <strong>af</strong>vikles 2 funktioner, makeHist<strong>og</strong>ram() <strong>og</strong> evaluateThreshold().<br />

18.9.2.1 makeHist<strong>og</strong>ram()<br />

Det første trin i processen er at skabe et hist<strong>og</strong>ram. Dette gøres <strong>ved</strong> at traversere igennem billedet i<br />

dets 2 dimensioner, <strong>og</strong> tælle op hvor mange gange hver pixelintensitet forekommer. ppGrayArray er<br />

en dobbeltpointer, der peger på arrayet der indeholder billedet:<br />

void Binary::makeHist<strong>og</strong>ram(void)<br />

{<br />

for(int i=0; i


18 Appendiks 18.9 Implementering<br />

}<br />

}<br />

Herefter er hist<strong>og</strong>rammet til rådighed i klassen i arrayet hist<strong>og</strong>ram.<br />

18.9.2.2 evaluateThreshold()<br />

Næste trin er at udføre Ridler <strong>og</strong> Calvards iterative thresholding-teknik. Indledende deklareres <strong>og</strong><br />

initialiseres alle variable:<br />

void Binary::evaluateThreshold(void)<br />

{<br />

int i = 0;<br />

float backGroundMean = 0, foreGroundMean = 0;<br />

int oldThreshold = 0, newThreshold = 127;<br />

int backGroundItems = 0, foreGroundItems = 0;<br />

int backGroundSum = 0, foreGroundSum = 0;<br />

…<br />

newThreshold er den variabel der indeholder k T . Dvs. For første iteration skal T0 sættes. Den sættes<br />

altid til midt i hist<strong>og</strong>rammet (127), da det er det bedste simple bud. Algoritmen er næsten ufølsom<br />

overfor hvilken værdi T 0 antager, <strong>og</strong> derfor er der ikke n<strong>og</strong>en grund til at anvende mere<br />

sofistikerede metoder til at bestemme T 0 .<br />

Herefter begynder iterationen, der vil køre indtil en <strong>af</strong> to betingelser er falske: Enten er k T lig T k + 1<br />

(dvs. der er altså ikke n<strong>og</strong>en ændring i thresholdværdien længere), eller <strong>og</strong>så har iterationsloopet kørt<br />

10 gange. Der er sat en øvre grænse på 10, da 6-7 iterationer som regel er nok:<br />

…<br />

bool breakLoop = false;<br />

for(int k=0; !breakLoop; k++)<br />

{<br />

backGroundSum =0;<br />

backGroundItems =0;<br />

foreGroundSum =0;<br />

foreGroundItems =0;<br />

for(i=0; i0)<br />

{<br />

foreGroundMean = float(foreGroundSum)/foreGroundItems;<br />

}<br />

else<br />

{<br />

foreGroundMean = 0;<br />

}<br />

Side 104 <strong>af</strong> 131


18 Appendiks 18.9 Implementering<br />

}<br />

oldThreshold = newThreshold;<br />

newThreshold = int((backGroundMean+foreGroundMean)/2+0.5);<br />

if(oldThreshold==newThreshold || k>=10)<br />

{<br />

breakLoop=true;<br />

}<br />

}<br />

threshold = newThreshold;<br />

Den nye thresholdværdi er nu tilgængelig for klassen i variablen threshold.<br />

Sidste trin i processen er selve thresholdingen <strong>af</strong> billedet. Dette foregår <strong>ved</strong>, at der først dannes et<br />

nyt billede, der skal indeholde det nye thresholdede binære billede. Herefter traverseres billedet på<br />

samme måde som <strong>ved</strong> genereringen <strong>af</strong> hist<strong>og</strong>rammet, <strong>og</strong> det undersøges hvorvidt den aktuelle pixels<br />

pixelintensitet er over eller under den fastsatte thresholdværdi. Hvis værdien er under eller lig sættes<br />

0 ind i det binære billede, <strong>og</strong> hvis værdien er over sættes 255 ind:<br />

void Binary::makeBinary(GrayScale &binaryImage)<br />

{<br />

binaryImage.execute(width, height);<br />

unsigned char **ppBinaryArray = binaryImage.getPointer();<br />

}<br />

int x,y;<br />

for(y=0; y


18 Appendiks 18.9 Implementering<br />

18.9.3.3 Sikkerhedsproblematik<br />

Alle variabler i Seed-klassen er erklæret som ”public”, så andre klasser kan rette i værdierne. Dette er<br />

ikke god pr<strong>og</strong>rammeringsskik, men det vurderes ikke at være et væsentligt problem, da gruppen godt<br />

kan administrere tilgangen til klassen.<br />

Seed-klassen indeholder ingen funktioner, men følgende variabler:<br />

class Seed<br />

{<br />

private:<br />

};<br />

public:<br />

// BlobDetection<br />

int seedNumber;<br />

int area;<br />

int boundsXMin;<br />

int boundsXMax;<br />

int boundsYMin;<br />

int boundsYMax;<br />

GrayScale grayScale;<br />

// EllipseApproximation<br />

float centerOfMassX;<br />

float centerOfMassY;<br />

float eccentricity;<br />

float majorAxis;<br />

float minorAxis;<br />

float thetaMajorAxis;<br />

float thetaMinorAxis;<br />

// Symetry<br />

float symmetry;<br />

// TopDetection<br />

int centerTopX;<br />

int centerTopY;<br />

bool topDetection;<br />

int expandShrinkPixels;<br />

float thetaCenterTop;<br />

float thetaTop;<br />

// Quality<br />

bool appro<strong>ved</strong>;<br />

18.9.3.4 Sammenfatning<br />

Der er med succes lavet en klasse, hvor de forskellige oplysninger omkring<br />

de enkelte kim kan gemmes, så andre klasser kan tilgå relevante<br />

oplysninger på kimene. Ydermere bør der <strong>ved</strong> en senere realisering laves<br />

accessor- <strong>og</strong> mutator-funktioner, for at sikre korrekt tilgang til variablerne.<br />

18.9.4 BlobDetection<br />

Funktionen execute() analyserer det binære billede. Efterfølgende kan de<br />

relevante objekter, trækkes ud med funktionen makeSeeds().<br />

18.9.4.1 execute()<br />

Funktionen sørger for at funktionerne; findSubBlobs(), joinSubBlobs()<br />

Figur 18.18<br />

Flowchart for execute<br />

Side 106 <strong>af</strong> 131


18 Appendiks 18.9 Implementering<br />

<strong>og</strong> makeBlobs() bliver eksekveret i nævnte rækkefølge (figur 18.18).<br />

18.9.4.2 findSubBlobs()<br />

Denne funktion sørger for at knytte de enkelte pixels i billedet til de forskellige subblobs. Hvis det<br />

opdages, at 2 subblobs rører <strong>ved</strong> hinanden, bliver disse knyttet sammen med funktionen<br />

rootUnion().<br />

18.9.4.3 Træstrukturen<br />

Træstrukturen realiseres med arrayet pSubBlobList, samt funktionerne rootFind() <strong>og</strong> rootUnion().<br />

For hver subblob er der en plads i arrayet, som <strong>brug</strong>es til sammenknytning. Værdien i arrayet<br />

<strong>af</strong>spejler hvilken subblob, subblobben er knyttet til. Hvis værdien svarer til subblobens eget<br />

nummer, er subblobben en rod i sig selv.<br />

18.9.4.4 rootFind()<br />

Funktionen <strong>brug</strong>es til at finde roden til en subblob. Dette gøres <strong>ved</strong> at slå subblobbens nummer op i<br />

pSubBlobList, hvorfra det kan indlæses hvilken subblob, den er knyttet til. D<strong>og</strong> kan det forekomme,<br />

at roden er knyttet til en tredje subblob. Derfor kalder funktionen sig selv med det nye<br />

subblobnummer som parameter. Funktionen stopper med at kalde sig selv, når den har fundet<br />

roden.<br />

int BlobDetection::rootFind(int a)<br />

{<br />

if (pSubBlobList[a] == a)<br />

{<br />

return a;<br />

}<br />

else<br />

{<br />

return rootFind(pSubBlobList[a]);<br />

}<br />

}<br />

18.9.4.5 rootUnion()<br />

Funktionen <strong>brug</strong>es til at sætte to forskellige subblobs sammen. Da de begge kan være knyttet til<br />

andre subblobs, er det nødvendigt først at finde deres rod med rootFind(). Når rødderne er fundet,<br />

knyttes rødderne sammen, <strong>ved</strong> at lade den med det største nummer pege på den med det mindste<br />

<strong>ved</strong> at rette i pSubBlobList.<br />

void BlobDetection::rootUnion(int a, int b)<br />

{<br />

int rootA;<br />

int rootB;<br />

rootA = rootFind(a);<br />

rootB = rootFind(b);<br />

if(rootA < rootB)<br />

{<br />

pSubBlobList[rootB] = rootA;<br />

}<br />

else if(rootA > rootB)<br />

{<br />

pSubBlobList[rootA] = rootB;<br />

}<br />

Side 107 <strong>af</strong> 131


18 Appendiks 18.9 Implementering<br />

}<br />

18.9.4.6 joinSubBlobs()<br />

Denne funktions laver en liste, der sammenkæder de enkelte subblobs, med de blobs som de er<br />

knyttet til. Listen realiseres i arrayet pBlobList, hvor indexet er subblobnummeret <strong>og</strong> værdierne er<br />

blobnummeret.<br />

void BlobDetection::joinSubBlobs(void)<br />

{<br />

pBlobList = new int[numberOfSubBlobs];<br />

}<br />

for(int i=0; i 0<br />

&& pBlob[i].boundsYMax < height-1<br />

numberOfSeeds++;<br />

}<br />

}<br />

return numberOfSeeds;<br />

Side 108 <strong>af</strong> 131


18 Appendiks 18.9 Implementering<br />

18.9.4.10 makeSeeds()<br />

Funktionen genererer et array <strong>af</strong> seed-objekter, <strong>og</strong> kopierer værdierne fra blobsne over i disse.<br />

18.9.5 EllipseApproximation<br />

Formålet med <strong>af</strong>snittet er at beskrive virkemåden <strong>af</strong> den C++-kode, der realiserer teorien i <strong>af</strong>snit 9.2<br />

Teori s. 34. Klassen er overordnet bygget op med en funktion execute(), der sørger for en korrekt<br />

<strong>af</strong>vikling <strong>af</strong> funktionerne i klassen. execute() kan overordnet beskrives med følgende flowchart<br />

(figur 18.19):<br />

18.9.5.1 execute()<br />

Funktionen består overordnet <strong>af</strong> en for-løkke,<br />

der gennemløber alle kimene, der er fundet<br />

med BlobDetection. numberOfSeeds er det<br />

totale antal <strong>af</strong> kim (objekter) <strong>og</strong> seedCounter er<br />

en tæller, der inkrementeres for hvert objekt<br />

der arbejdes på. I execute() eksekveres 3<br />

funktioner:<br />

1. Find alle koordinater hvor der er hvide<br />

pixels<br />

2. Udregn massemidtpunktet for alle<br />

hvide pixels<br />

3. Bestem den principale stor- <strong>og</strong> lilleakse<br />

samt vinklerne hertil<br />

18.9.5.2 getCoordinates()<br />

Denne funktion har til formål at finde alle<br />

steder i billedet, hvor der er hvidt. Billedet<br />

traverseres i både x- <strong>og</strong> y-dimensionen, <strong>og</strong> for<br />

hver pixel der er hvid, <strong>af</strong>sættes x- <strong>og</strong> ykoordinatet<br />

i hvert sit array. På den måde<br />

opnås en samling <strong>af</strong> koordinater, hvor der<br />

findes hvide pixels:<br />

void EllipseApproximation::getCoordinates()<br />

{<br />

int i=0;<br />

for(int y=0; y


18 Appendiks 18.9 Implementering<br />

18.9.5.3 Utilities.calculateCenterOfMass()<br />

Denne funktion er beskrevet i Appendiks 18.9.11.2 calculateCenterOfMass() s. 123.<br />

18.9.5.4 calculateAxes()<br />

Funktionen har overordnet til formål at udregne stor- <strong>og</strong> lilleaksen i ellipsen, samt disses vinkler med<br />

den horisontale x-akse. Det gøres <strong>ved</strong> at implementere teorien beskrevet i <strong>af</strong>snit 9.2.2 Orientering i<br />

planet s. 35. Indledende skal massemidtpunktet bringes til centrum i koordinatsystemet <strong>ved</strong> at<br />

fratrække alle x- <strong>og</strong> y-koordinater massemidtpunktets x- <strong>og</strong> y-koordinater (ligning (18.11)):<br />

void EllipseApproximation::calculateAxes(Coordinates CM)<br />

{<br />

for(int i=0; i


18 Appendiks 18.9 Implementering<br />

Til sidst i funktionen udregnes excentriciteten axisRatio <strong>og</strong> længderne på stor- <strong>og</strong> lilleakserne. Disse<br />

længder skal <strong>brug</strong>es i en senere klasse til at tegne ellipsen med:<br />

…<br />

float axisRatio = 0;<br />

if(momentOfInertiaMax>0)<br />

{<br />

axisRatio = momentOfInertiaMin/momentOfInertiaMax;<br />

}<br />

if(axisRatio>0)<br />

{<br />

majorAxis = float(sqrt(numberOfPixels/(M_PI*sqrt(axisRatio))));<br />

minorAxis = float(numberOfPixels/(M_PI*majorAxis));<br />

}<br />

else<br />

{<br />

majorAxis = 0;<br />

minorAxis = 0;<br />

}<br />

float eccentricity = sqrt(1-axisRatio);<br />

…<br />

Til sidst i funktionen opdateres det aktuelle seed med de nyudregnede oplysninger:<br />

}<br />

…<br />

pSeed[seedCounter].thetaMajorAxis = thetaMajorAxis;<br />

pSeed[seedCounter].thetaMinorAxis = thetaMinorAxis;<br />

pSeed[seedCounter].majorAxis = majorAxis;<br />

pSeed[seedCounter].minorAxis = minorAxis;<br />

pSeed[seedCounter].eccentricity = eccentricity;<br />

18.9.6 ExpandShrink<br />

Klassen ExpandShrink indeholder de to funktioner expand() <strong>og</strong> shrink(). Der er ikke n<strong>og</strong>en<br />

execute()-funktion, da de to algoritmer ikke nødvendigvis skal <strong>af</strong>vikles sekventielt.<br />

18.9.6.1 expand()<br />

Parametrene, som sendes til denne funktion, er pointerne til to GrayScale-billeder, samt antallet <strong>af</strong><br />

gange det ønskes at expande. Det første GrayScale-billede er det billede, som operationen skal<br />

udføres på, source. Det andet er det, som der skal skrives til, altså resultatet destination. Det første<br />

som udføres er, at dimensionerne på destination-billedet beregnes <strong>og</strong> oprettes. Herefter farves<br />

destination-billedets pixels sorte:<br />

void ExpandShrink::expand(GrayScale &source, GrayScale &destination, int magnification)<br />

{<br />

int width, height;<br />

height = source.getHeight();<br />

width = source.getWidth();<br />

destination.execute(width+2*magnification, height+2*magnification);<br />

unsigned char **ppSpurceGrayScalePointer = source.getPointer();<br />

unsigned char **ppDestGrayScalePointer = destination.getPointer();<br />

for(int y = 0; y < height+magnification*2; y++)<br />

{<br />

for(int x = 0; x < width+magnification*2; x++)<br />

{<br />

ppDestGrayScalePointer[y][x] = 0;<br />

}<br />

}<br />

Side 111 <strong>af</strong> 131


18 Appendiks 18.9 Implementering<br />

…<br />

Nu traverseres der igennem source-billedet. Et eksempel på et source-<br />

billede på 10 x 10 pixel er vist på figur 18.20. Den hvide pixel ligger på<br />

position (1,1).<br />

Expandes der én gang så bliver det nye destination-billede 12 x 12 pixel, <strong>og</strong><br />

den hvide pixel kommer til at ligge i (2,2). Nu skal alle dens naboer farves<br />

hvide. Starter man i destination-billedet, der hvor man finder en hvid pixel<br />

i source-billedet, altså i (1,1) <strong>og</strong> farver to gange antallet <strong>af</strong> gange, der skal<br />

expandes i den positive x-retning. I dette tilfælde vil det sige, at der farves fra<br />

(1,1) til (1,3). Dette resulterer i, at man får farvet den nederste række pixels<br />

(figur 18.21), i den firkant man ønsker tegnet:<br />

Gentages dette igen, to gange <strong>af</strong> antallet <strong>af</strong> gange det ønskes at expande, i den positive y-retning,<br />

dvs. igen fra 1 til 3, opnås det ønskede resultat, at alle nabopixelene rundt om 2,2, bliver farvet hvide<br />

(figur 18.22):<br />

Dette princip er implementeret i expand()-funktionen:<br />

…<br />

Figur 18.21<br />

Udvidet billede hvor den<br />

nederste række i firkanten er<br />

genereret<br />

Figur 18.22<br />

Det færdigt udvidede billede,<br />

med 1 gang expand<br />

for(int y = 0; y < height; y++)<br />

{<br />

for(int x = 0; x < width; x++)<br />

{<br />

if(ppSpurceGrayScalePointer[y][x] != 0)<br />

{<br />

for(int m = y ; m < y + 2*magnification+1; m++)<br />

{<br />

for(int n = x; n < x + 2*magnification+1; n++)<br />

{<br />

ppDestGrayScalePointer[m][n] = 255;<br />

}<br />

}<br />

Figur 18.20<br />

En figur bestående <strong>af</strong> 1<br />

pixel<br />

Side 112 <strong>af</strong> 131


18 Appendiks 18.9 Implementering<br />

}<br />

}<br />

}<br />

}<br />

18.9.6.2 shrink()<br />

Inputtene til denne funktion er de samme som til expand()-funktionen. De to GrayScale-billeder,<br />

med henholdsvis source <strong>og</strong> destination, samt det antal gange det ønskes at formindske billedet.<br />

Igen beregnes der først dimensioner på destination-billedet. Da det er muligt, at de nye<br />

dimensioner bliver negative kontrolleres det, at dette ikke sker. Herefter farves destinationbilledets<br />

pixels hvide:<br />

void ExpandShrink::shrink(GrayScale &source, GrayScale &destination, int magnification)<br />

{<br />

int width, height;<br />

height = source.getHeight();<br />

width = source.getWidth();<br />

if(width-2*magnification


18 Appendiks 18.9 Implementering<br />

18.9.7 TopDetection<br />

TopDetection-klassen er opbygget således, at den har en funktion<br />

execute(), som er ho<strong>ved</strong>funktionen, der eksekverer alle<br />

underfunktioner, som er nødvendige for at udføre klassens<br />

formål.<br />

18.9.7.1 execute()<br />

execute()-funktionen består <strong>af</strong> en stor for-løkke hvori der<br />

udføres en række operationer på hvert enkelt kim (figur 18.23).<br />

I tilfælde <strong>af</strong> det ønskes at fjerne urenheder i kanten, kan kimet<br />

shrinkes <strong>og</strong> expandes et antal gange. Herefter expandes <strong>og</strong><br />

shrinkes kimet 4 gange (<strong>af</strong>snit 11.3 Test s. 51 for nærmere<br />

information).<br />

Nu findes forskellen mellem billedet, hvor kanten er blevet<br />

renset, <strong>og</strong> det som er blevet expandet <strong>og</strong> shrinket 4 gange i<br />

funktionen subtract(). I denne funktion udregnes <strong>og</strong>så topmassemidtpunktet.<br />

Til sidst beregnes vinklen mellem det<br />

vandrette plan, som går igennem massemidtpunktet fra<br />

ellipseapproksimationen, <strong>og</strong> den linie som dette punkt danner<br />

med det nye massemidtpunkt beregnet i subtract(). Dette<br />

sker i funktionen findTop(). I denne funktion kontrolleres<br />

det <strong>og</strong>så hvilken ende <strong>af</strong> kimet, der er toppen:<br />

void TopDetection::execute(void)<br />

{<br />

for(int count = 0; count < numberOfSeeds; count++)<br />

{<br />

ExpandShrink expandShrink;<br />

}<br />

GrayScale expanded, shrinked, subtracted, forExpand, forShrink;<br />

expandShrink.shrink(pSeed[count].grayScale, forShrink, 0);<br />

expandShrink.expand(forShrink, forExpand, 0);<br />

expandShrink.expand(forExpand, expanded, 4);<br />

expandShrink.shrink(expanded, shrinked, 4);<br />

subtract(forExpand, shrinked, subtracted, count);<br />

}<br />

findTop();<br />

18.9.7.2 Subtract()<br />

Start<br />

execute()<br />

Count


18 Appendiks 18.9 Implementering<br />

…<br />

for(int y = 0; y < height; y++)<br />

{<br />

for(int x = 0; x < width; x++)<br />

{<br />

if(ppTempSource1GrayScalePointer[y][x]!=<br />

ppTempSource2GrayScalePointer[y][x])<br />

{<br />

ppTempDestGrayScalePointer[y][x] = 255;<br />

numberOfWhitePixels++;<br />

}<br />

}<br />

}<br />

…<br />

Derefter beregnes massemidtpunktet for de små arealer som er opstået. Til dette formål anvendes<br />

Utilities-klassens calculateCenterOfMass(). Bagefter tilføjes koordinater for punktet i seedobjektet:<br />

…<br />

CenterOfMass centerOfMassCoordinates;<br />

Utilities utilities;<br />

centerOfMassCoordinates = utilities.calculateCenterOfMass(destination, numberOfWhitePixels);<br />

pSeed[count].centerTopX = int(centerOfMassCoordinates.xCoordinate) + pSeed[count].boundsXMin;<br />

pSeed[count].centerTopY = int(centerOfMassCoordinates.yCoordinate) + pSeed[count].boundsYMin;<br />

pSeed[count].TopBottomDetection = true;<br />

…<br />

18.9.7.3 findTop()<br />

I denne funktion implementeres beregningen <strong>af</strong> vinklen mellem den linie, der går igennem de to<br />

massemidtpunkter <strong>og</strong> det vandrette plan. De to massemidtpunkter er fra henholdsvis<br />

ellipseapproksimationen <strong>og</strong> subtract()-funktionen. Som det første beregnes sidelængderne i<br />

trekanten a, b <strong>og</strong> c. Derefter beregnes vinklen. Herefter følger de to tjek der <strong>af</strong>gør om topmassemidtpunktet<br />

ligger på henholdsvis den ene eller den anden side <strong>af</strong> lilleaksen. Til sidst tilføjes<br />

det i hvilken ende toppen er beregnet til at ligge, i seed-objektet:<br />

…<br />

b = float(pSeed[count].centerTopX - pSeed[count].centerOfMassX);<br />

a = float(pSeed[count].centerTopY - pSeed[count].centerOfMassY);<br />

c = sqrt(pow(a,2)+pow(b,2));<br />

angle = acos(b/c);<br />

if(a pSeed[count].thetaMinorAxis && pSeed[count].thetaCenterTop <<br />

pSeed[count].thetaMinorAxis + M_PI)<br />

{<br />

pSeed[count].thetaTop += float(M_PI);<br />

}<br />

}<br />

else<br />

{<br />

if(pSeed[count].thetaCenterTop > pSeed[count].thetaMinorAxis || pSeed[count].thetaCenterTop <<br />

pSeed[count].thetaMinorAxis - M_PI)<br />

{<br />

pSeed[count].thetaTop += float(M_PI);<br />

}<br />

}<br />

…<br />

Side 115 <strong>af</strong> 131


18 Appendiks 18.9 Implementering<br />

18.9.8 Symmetry<br />

I dette <strong>af</strong>snit gennemgås implementeringen <strong>af</strong> en løsning på teorien beskrevet i 12 Symmetry s. 54.<br />

Klassen er bygget op efter standarden med en execute() funktion, der sørger for at funktionerne i<br />

klassen bliver <strong>af</strong>viklet i rigtig sekvens.<br />

18.9.8.1 execute()<br />

execute() indeholder en for-løkke, der gennemløber alle kimene (seedCounter). Hver gang <strong>af</strong>vikles<br />

funktionen getPixelDeviation(), som har til formål at udregne den procentvise symmetri-værdi:<br />

void Symmetry::execute(void)<br />

{<br />

int seedCounter;<br />

for(seedCounter=0; seedCounter


18 Appendiks 18.9 Implementering<br />

Når denne er udregnet roteres koordinatet tilbage (e), <strong>og</strong> origo flyttes tilbage fra massemidtpunktet:<br />

…<br />

e = rotateCoordinate(d, thetaMajorAxis);<br />

e.xCoordinate += CM.xCoordinate;<br />

e.yCoordinate += CM.yCoordinate;<br />

x2 = int(e.xCoordinate+0.5);<br />

y2 = int(e.yCoordinate+0.5);<br />

…<br />

Koordinatsættet (x2,y2) er nu punktet, som evt. kan være symmetripartner med (x1,y1). Herefter<br />

undersøges det om (x2,y2) ligger inden for boundingboxen, <strong>og</strong> hvis dette er tilfældet skal det<br />

undersøges om (x2,y2) er hvid pixel, <strong>og</strong> hvis ikke inkrementeres pixelsDeviation. Hvis den ligger<br />

uden for boundingboxen kan den ikke være symmetrisk med andre pixels så derfor inkrementeres<br />

der <strong>og</strong>så i det tilfælde:<br />

…<br />

}<br />

}<br />

…<br />

grayScale.setValue(x1,y1,255);<br />

if((x2>=0 && x2=0 && y2


18 Appendiks 18.9 Implementering<br />

række nøgleord initialiseres. I filen står der efter hvert <strong>af</strong> disse nøgleord et kolon <strong>og</strong> derefter den<br />

tilhørende værdi:<br />

void Quality::getParametersFromFile(void)<br />

{<br />

string line, sub;<br />

int i = 0;<br />

size_t offset1, offset2;<br />

char *search0 = "#";<br />

char *search1 = "areaLow";<br />

char *search2 = "areaHigh";<br />

char *search3 = "symmetryLow";<br />

char *search4 = "symmetryHigh";<br />

char *search5 = "eccentricityLow";<br />

char *search6 = "eccentricityHigh";<br />

char *search7 = "expandShrinkLow";<br />

char *search8 = "expandShrinkHigh";<br />

char *search9 = "selectionModel";<br />

char *colon = ":";<br />

…<br />

Herefter hentes ”settings.ini” <strong>og</strong> det kontrolleres om den er åben. Hvis den er det, <strong>af</strong>vikles nu et<br />

while-loop, der kører så længe enden i filen ikke er nået. I loopet læses filen ind linie for linie. Det<br />

første der kontrolleres er om linien indeholder et # (search0) tegn. Er dette tilfældet, springes linien<br />

over, da dette betyder udkommentering, ellers kontrolleres det om et <strong>af</strong> de andre nøgleord er<br />

indeholdt i linien. Findes et <strong>af</strong> dem, overføres værdien til den respektive variabel i pr<strong>og</strong>rammet:<br />

…<br />

ifstream infile("settings.ini");<br />

if(infile.is_open())<br />

{<br />

while(infile.good())<br />

{<br />

getline(infile,line);<br />

if(line.find(search0, 0) == string::npos)<br />

{<br />

if (offset1 = line.find(search1, 0) != string::npos)<br />

{<br />

offset2 = line.find(colon, offset1);<br />

sub = line.substr((long)offset2+1);<br />

std::istringstream strin(sub);<br />

strin >> areaLow;<br />

}<br />

…<br />

På denne måde fortsættes der for alle variablerne, der skal indlæses. Herefter kontrolleres det om alle<br />

variable er blevet hentet ind fra filen, <strong>og</strong> der udskrives en fejlmeddelelse, hvis en <strong>af</strong> dem ikke er. Som<br />

eksempel angives areaLow, men proceduren er ens for alle variablerne:<br />

…<br />

}<br />

}<br />

if(areaLow == PARAMETER_NOT_SPECIFIED)<br />

{<br />

cout


18 Appendiks 18.9 Implementering<br />

18.9.9.3 evaluateSeeds()<br />

Funktionen har til formål at implementere ønsket,<br />

om at kunne udvælge kim <strong>ved</strong> både at <strong>brug</strong>e<br />

boks- <strong>og</strong> ellipsoide-modellen. Fremgangsmetoden<br />

er som følger (figur 18.24):<br />

1. Først undersøges det om der ønskes<br />

anvendt boks- eller ellipsoide-model<br />

2. Hvis der anvendes ellipsoide-model<br />

udregnes x0, y0, z0, a, b <strong>og</strong> c<br />

3. Herefter gennemløber for-løkken alle<br />

kimene i seeds-objektet<br />

4. Det undersøges om det aktuelle kim<br />

falder inden for grænserne for den valgte<br />

model<br />

Koden i C++ er som følger:<br />

void Quality::evaluateSeeds(void)<br />

{<br />

float x0, y0, z0;<br />

float aSquared, bSquared, cSquared;<br />

…<br />

På 1. <strong>og</strong> 2. trin i fremgangsmetoden ovenover undersøges det, om der er valgt ellipsoide-modellen,<br />

<strong>og</strong> i så fald regnes x0, y0, z0, a, b <strong>og</strong> c ud:<br />

…<br />

if (selection!=0)<br />

{<br />

float temp;<br />

temp = (float(expandShrinkHigh)-float(expandShrinkLow))/2;<br />

x0 = expandShrinkHigh-temp;<br />

aSquared = float(pow(double(temp),2));<br />

}<br />

…<br />

temp = (float(symmetryHigh)-float(symmetryLow))/2;<br />

y0 = float(symmetryHigh)-temp;<br />

bSquared = float(pow(double(temp),2));<br />

temp = (float(areaHigh)-float(areaLow))/2;<br />

z0 = float(areaHigh)-temp;<br />

cSquared = float(pow(double(temp),2));<br />

På 3. trin gennemløbes for-løkken, <strong>og</strong> dataene hentes på kimet:<br />

…<br />

for(int i=0; i


18 Appendiks 18.9 Implementering<br />

float x = float(pSeed[i].expandShrinkPixels);<br />

float y = float(pSeed[i].symmetry);<br />

float z = float(pSeed[i].area);<br />

float eccentricity = float(pSeed[i].eccentricity);<br />

bool condition = false;<br />

…<br />

Udregning <strong>af</strong> boks:<br />

…<br />

if(selection==0)<br />

{<br />

condition = (x>=expandShrinkLow && x=symmetryLow &&<br />

y=areaLow && z=eccentricityLow &&<br />

eccentricity


18 Appendiks 18.9 Implementering<br />

18.9.10 Draw<br />

For visuelt at kunne se resultaterne <strong>af</strong> de forskellige algoritmer, er denne klasse lavet. Klassen giver<br />

mulighed for at tegne resultaterne <strong>af</strong> de forskellige algoritmer på det originale inputbillede eller på en<br />

simpel sort baggrund.<br />

Klassen giver mulighed for at tegne 5 forskellige elementer på billedet:<br />

1. De enkelte blobs i tydeligt forskellige farver<br />

2. De enkelte blobs i rød farve, hvor blobbens nummer står i den blå farvekanal<br />

3. Boundingboxene omkring de enkelte objekter<br />

4. Approksimerede ellipser med stor- <strong>og</strong> lilleaksen<br />

5. Pink pixel til markering <strong>af</strong> top på kim<br />

Ved tegning <strong>af</strong> de forskellige elementer kan det vælges, om der skal tegnes for alle de objekter som<br />

BlobDetection har fundet, eller for alle objekter som Quality-klassen har godkendt.<br />

18.9.10.1 drawBlobs()<br />

Denne funktion har til formål, at give en måde hvorpå man tydeligt kan indikere, hvilke pixels der<br />

hører til hvilken blob, i det samlede billede.<br />

18.9.10.2 drawBlobNumbers()<br />

Disse blobs tegnes ligeledes i det samlede billede, men denne gang gemmes blobbens id-nummer i<br />

den blå farvekanal. Alle blobsne får derfor tildelt en farve på følgende måde:<br />

Blob 0: (255, 0, 0)<br />

Blob 1: (255, 0, 1)<br />

Blob 2: (255, 0, 2)<br />

osv…<br />

På denne måde er det nemt i et billede, at se hvilken blob der har hvilket id-nummer, uden at skulle<br />

lave en decideret skrive-funktionalitet i koden, der kunne skrive tal i billedet.<br />

18.9.10.3 drawBounds()<br />

Boundingboxene tegnes i det samlede billede, <strong>og</strong> viser grænserne for hver enkelt blob.<br />

18.9.10.4 drawEllipse()<br />

EllipseApproximation-klassen udregner parametrene til den ellipse, der passer bedst til de enkelte<br />

objekter. Klassen skal derfor kunne tegne disse ellipser, samt deres stor- <strong>og</strong> lilleakser. Når<br />

pr<strong>og</strong>rammet er kompileret til ”Debug”-mode oprettes der billeder <strong>af</strong> de enkelte kim med ellipser <strong>og</strong><br />

akser.<br />

Side 121 <strong>af</strong> 131


18 Appendiks 18.9 Implementering<br />

18.9.10.5 Stor- <strong>og</strong> lilleakserne<br />

Ud fra aksernes vinkel θ, med det vandrette plan, <strong>og</strong> objektets centerkoordinat, udregnes koordinaterne<br />

for de pixels, der skal tændes ud, fra følgende parameterfremstilling:<br />

x() t = xCM + tcos<br />

θ<br />

y() t = y + tsin<br />

θ<br />

CM<br />

Hvor xCM <strong>og</strong> yCM er koordinatsættet for ellipsens massemidtpunkt.<br />

18.9.10.6 Ellipse<br />

(18.27)<br />

En ellipse, der ligger vandret i planet, kan tegnes ud fra følgende parameterfremstilling:<br />

x = acos<br />

φ<br />

y = bsin<br />

φ<br />

, hvor<br />

a > b<br />

a er længden <strong>af</strong> storaksen<br />

b er længden <strong>af</strong> lilleaksen<br />

φ∈[ 0;2 π]<br />

x samt y er koordinatsættet for de enkelte punkter rundt i ellipsen<br />

(18.28)<br />

Da ellipsen, der ønskes tegnet, sjældent ligger vandret, er det nødvendigt at rotere denne. Et hvert<br />

objekt, i et koordinatsystem, kan drejes omkring origo med følgende ligning:<br />

x = x cos( −θ ) + ysin(<br />

−θ)<br />

2<br />

y = ycos( −θ) −x sin( −θ)<br />

2<br />

, hvor<br />

x <strong>og</strong> y er koordinatsættet for det punkt der ønskes drejet<br />

θ er vinkel figuren ønskes drejet<br />

x 2 <strong>og</strong> y 2 er koordinatsættet for det drejede punkt<br />

18.9.10.7 drawCenterTop()<br />

(18.29)<br />

Denne funktionalitet angiver det sted, hvor TopDetection-klassen har fundet toppen <strong>af</strong> et kim, med<br />

en pink pixel.<br />

18.9.11 Utilities<br />

18.9.11.1 average()<br />

Funktionen udregner gennemsnittet <strong>af</strong> et array <strong>af</strong> tal.<br />

Side 122 <strong>af</strong> 131


18 Appendiks 18.9 Implementering<br />

18.9.11.2 calculateCenterOfMass()<br />

Der lavet to udgaver <strong>af</strong> denne funktion. Dette er gjort, for at massemidtpunktsudregningen kan<br />

<strong>brug</strong>es flere steder selvom det, det ene sted er et dobbeltarray <strong>af</strong> koordinater, <strong>og</strong> det andet sted er et<br />

grayScale-objekt der arbejdes med:<br />

Coordinates Utilities::calculateCenterOfMass(unsigned char **ppBlob, int ySize, int xSize, int<br />

numberOfPixels)<br />

{<br />

Coordinates CM;<br />

CM = calculateCM(ppBlob, ySize, xSize, numberOfPixels);<br />

return CM;<br />

}<br />

Coordinates Utilities::calculateCenterOfMass(GrayScale &grayScale, int numberOfPixels)<br />

{<br />

Coordinates CM;<br />

unsigned char **ppBlob = grayScale.getPointer();<br />

int xSize = grayScale.getWidth();<br />

int ySize = grayScale.getHeight();<br />

}<br />

CM = calculateCM(ppBlob, ySize, xSize, numberOfPixels);<br />

return CM;<br />

18.9.11.3 calculateCM()<br />

calculateCM() er funktionen, der foretager den reelle massemidtpunktsudregning. Funktionen<br />

består <strong>af</strong> to for-løkker der traverserer alle x- <strong>og</strong> y-koordinater igennem <strong>og</strong> summerer deres værdier<br />

op. Når begge løkker er færdige, deles der med antallet <strong>af</strong> pixels for at få den gennemsnitlige x- <strong>og</strong> yværdi.<br />

Disse to værdier er koordinatsættet for massemidtpunktet:<br />

Coordinates Utilities::calculateCM(unsigned char **ppBlob, int ySize, int xSize, int<br />

numberOfPixels)<br />

{<br />

int i=0;<br />

float centerOfMassX = 0, centerOfMassY=0;<br />

}<br />

for(int y=0; y


18 Appendiks 18.10 Test <strong>af</strong> Binary<br />

18.10 Test <strong>af</strong> Binary<br />

Her følger testdataene fra testen <strong>af</strong> Binary-klassen (7.3 Test s. 26):<br />

Billede Forgrund Baggrund Threshold Genereret hist<strong>og</strong>ram<br />

blandet1 173,413 19,4556 96<br />

159,905 17,4753 89<br />

157,364 17,1948 87<br />

156,585 17,1149 87<br />

blandet2 191,585 18,3187 105<br />

182,818 17,3078 100<br />

180,957 17,1288 99<br />

180,61 17,0968 99<br />

blandet3 198,586 19,5937 109<br />

191,694 18,735 105<br />

190,213 18,5756 104<br />

189,832 18,536 104<br />

Side 124 <strong>af</strong> 131


18 Appendiks 18.10 Test <strong>af</strong> Binary<br />

Billede Forgrund Baggrund Threshold Genereret hist<strong>og</strong>ram<br />

blandet4 154,718 19,3838 87<br />

132,542 15,1839 74<br />

127,305 14,4492 71<br />

126,114 14,305 70<br />

125,718 14,259 70<br />

blandet5 162,178 18,49 90<br />

141,364 15,2627 78<br />

135,859 14,5938 75<br />

1134,595 14,4575 75<br />

blandet6 149,828 19,6955 85<br />

123,195 15,2926 69<br />

115,14 14,1802 65<br />

113,224 13,953 64<br />

112,79 13,9039 63<br />

112,295 13,8492 63<br />

blandet7 152,184 18,7445 85<br />

122,392 15,1006 69<br />

112,882 13,9813 63<br />

109,742 13,6578 62<br />

109,243 13,6095 61<br />

108,754 13,5631 61<br />

Side 125 <strong>af</strong> 131


18 Appendiks 18.10 Test <strong>af</strong> Binary<br />

Billede Forgrund Baggrund Threshold Genereret hist<strong>og</strong>ram<br />

blandet8 173,457 18,0378 96<br />

155,735 15,9664 86<br />

150,170 15,4146 83<br />

148,575 15,2481 82<br />

148,11 15,2264 82<br />

godkendte1 151,721 17,6763 85<br />

132,626 15,3232 74<br />

128,426 14,9924 72<br />

127,694 14,9417 71<br />

127,287 14,9144 71<br />

godkendte2 174,647 16,8111 96<br />

161,644 15,644 89<br />

158,728 15,4239 87<br />

157,925 15,3717 87<br />

godkendte3 158,687 17,2375 88<br />

141,795 15,3152 79<br />

138,376 15,0511 77<br />

137,541 14,9928 76<br />

137,206 14,9701 76<br />

Tabel 18.2<br />

Side 126 <strong>af</strong> 131


18 Appendiks 18.11 Test <strong>af</strong> TopDetection<br />

18.11 Test <strong>af</strong> TopDetection<br />

Testen <strong>af</strong> TopDetection-algoritmen blev foretaget på 3 billeder. Testresultaterne fra disse bliver<br />

præsenteret i dette Appendiks. For nærmere information omkring hvordan testresultaterne skal<br />

fortolkes henvises der til 10.3 Test s. 47 i ho<strong>ved</strong>rapporten.<br />

18.11.1 Billede 1<br />

Figur 18.25<br />

Kombination<br />

Arealer Antal<br />

Udglatning<br />

Antal<br />

Expand-<br />

Shrink<br />

Antal<br />

rigtigt<br />

fundne<br />

Antal<br />

forkert<br />

fundne<br />

Antal<br />

udefinerede<br />

1 Alle arealer 0 1 17 2 9 60,7<br />

2 Alle arealer 0 2 21 3 4 75,0<br />

3 Alle arealer 0 3 23 3 2 82,1<br />

4 Alle arealer 0 4 23 3 2 82,1<br />

5 Alle arealer 0 5 23 3 2 82,1<br />

6 Alle arealer 1 1 15 2 11 53,6<br />

7 Alle arealer 1 2 20 3 5 71,4<br />

8 Alle arealer 1 3 23 2 3 82,1<br />

9 Alle arealer 1 4 22 3 3 78,6<br />

10 Alle arealer 1 5 22 3 3 78,6<br />

11 Alle arealer 2 1 9 0 19 32,1<br />

12 Alle arealer 2 2 12 2 14 42,9<br />

%<br />

Side 127 <strong>af</strong> 131


18 Appendiks 18.11 Test <strong>af</strong> TopDetection<br />

13 Alle arealer 2 3 13 4 11 46,4<br />

14 Alle arealer 2 4 14 4 10 50,0<br />

15 Alle arealer 2 5 14 4 10 50,0<br />

16 Største areal 0 1 16 3 9 57,1<br />

17 Største areal 0 2 20 4 4 71,4<br />

18 Største areal 0 3 22 4 2 78,6<br />

19 Største areal 0 4 22 4 2 78,6<br />

20 Største areal 0 5 23 3 2 82,1<br />

21 Største areal 1 1 15 2 11 53,6<br />

22 Største areal 1 2 19 4 5 67,9<br />

23 Største areal 1 3 21 4 3 75,0<br />

24 Største areal 1 4 21 4 3 75,0<br />

25 Største areal 1 5 22 3 3 78,6<br />

26 Største areal 2 1 9 0 19 32,1<br />

27 Største areal 2 2 13 1 14 46,4<br />

28 Største areal 2 3 13 4 11 46,4<br />

29 Største areal 2 4 13 5 10 46,4<br />

30 Største areal 2 5 13 5 10 46,4<br />

Tabel 18.3<br />

18.11.2 Billede 2<br />

Figur 18.26<br />

Side 128 <strong>af</strong> 131


18 Appendiks 18.11 Test <strong>af</strong> TopDetection<br />

Kombination<br />

Arealer Antal<br />

Udglatning<br />

Antal<br />

Expand-<br />

Shrink<br />

Antal<br />

rigtigt<br />

fundne<br />

Antal<br />

forkert<br />

fundne<br />

Antal<br />

udefinerede<br />

1 Alle arealer 0 1 20 2 3 76,9<br />

2 Alle arealer 0 2 24 0 1 92,3<br />

3 Alle arealer 0 3 23 1 1 88,5<br />

4 Alle arealer 0 4 23 1 1 88,5<br />

5 Alle arealer 0 5 22 2 1 84,6<br />

6 Alle arealer 1 1 18 2 5 69,2<br />

7 Alle arealer 1 2 21 2 2 80,8<br />

8 Alle arealer 1 3 19 4 2 73,1<br />

9 Alle arealer 1 4 20 3 2 76,9<br />

10 Alle arealer 1 5 20 3 2 76,9<br />

11 Alle arealer 2 1 10 1 14 38,5<br />

12 Alle arealer 2 2 10 3 12 38,5<br />

13 Alle arealer 2 3 11 3 11 42,3<br />

14 Alle arealer 2 4 11 3 11 42,3<br />

15 Alle arealer 2 5 11 4 10 42,3<br />

16 Største areal 0 1 17 5 3 65,4<br />

17 Største areal 0 2 24 0 1 92,3<br />

18 Største areal 0 3 21 3 1 80,8<br />

19 Største areal 0 4 22 2 1 84,6<br />

20 Største areal 0 5 22 2 1 84,6<br />

21 Største areal 1 1 15 5 5 57,7<br />

22 Største areal 1 2 19 4 2 73,1<br />

23 Største areal 1 3 17 6 2 65,4<br />

24 Største areal 1 4 19 4 2 73,1<br />

25 Største areal 1 5 19 4 2 73,1<br />

26 Største areal 2 1 9 2 14 34,6<br />

27 Største areal 2 2 10 3 12 38,5<br />

28 Største areal 2 3 11 3 11 42,3<br />

29 Største areal 2 4 11 3 11 42,3<br />

30 Største areal 2 5 11 4 10 42,3<br />

Tabel 18.4<br />

%<br />

Side 129 <strong>af</strong> 131


18 Appendiks 18.11 Test <strong>af</strong> TopDetection<br />

18.11.3 Billede 3<br />

Figur 18.27<br />

Kombination<br />

Arealer Antal<br />

Udglatning<br />

Antal<br />

Expand-<br />

Shrink<br />

Antal<br />

rigtigt<br />

fundne<br />

Antal<br />

forkert<br />

fundne<br />

Antal<br />

udefinerede<br />

1 Alle arealer 0 1 20 4 4 71,4<br />

2 Alle arealer 0 2 23 3 2 82,1<br />

3 Alle arealer 0 3 23 3 2 82,1<br />

4 Alle arealer 0 4 23 3 2 82,1<br />

5 Alle arealer 0 5 23 3 2 82,1<br />

6 Alle arealer 1 1 19 1 8 67,9<br />

7 Alle arealer 1 2 23 1 4 82,1<br />

8 Alle arealer 1 3 23 1 4 82,1<br />

9 Alle arealer 1 4 23 1 4 82,1<br />

10 Alle arealer 1 5 23 1 4 82,1<br />

11 Alle arealer 2 1 8 3 17 28,6<br />

12 Alle arealer 2 2 12 2 14 42,9<br />

13 Alle arealer 2 3 12 2 14 42,9<br />

14 Alle arealer 2 4 13 2 13 46,4<br />

15 Alle arealer 2 5 12 3 13 42,9<br />

16 Største areal 0 1 20 4 4 71,4<br />

17 Største areal 0 2 23 3 2 82,1<br />

18 Største areal 0 3 23 3 2 82,1<br />

19 Største areal 0 4 23 3 2 82,1<br />

20 Største areal 0 5 23 3 2 82,1<br />

21 Største areal 1 1 19 1 8 67,9<br />

22 Største areal 1 2 22 2 4 78,6<br />

%<br />

Side 130 <strong>af</strong> 131


18 Appendiks 18.11 Test <strong>af</strong> TopDetection<br />

23 Største areal 1 3 22 2 4 78,6<br />

24 Største areal 1 4 22 2 4 78,6<br />

25 Største areal 1 5 21 3 4 75,0<br />

26 Største areal 2 1 9 2 17 32,1<br />

27 Største areal 2 2 11 3 14 39,3<br />

28 Største areal 2 3 11 3 14 39,3<br />

29 Største areal 2 4 12 3 13 42,9<br />

30 Største areal 2 5 11 4 13 39,3<br />

Tabel 18.5<br />

Side 131 <strong>af</strong> 131

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!