Eye-RIS programozás Összeállította: Fülöp Tamás Nagy para esetére:
[email protected] Ez az útmutató bemutatja, hogy hogyan kapcsolódhattok a távoli számítógéphez, amelyen az EyeRIS ADK-t elérhetitek.
Tartalomjegyzék Eye-RIS programozás...........................................................................................................................1 Csatlakozás a távoli számítógépre windows alól.............................................................................1 Csatlakozás a távoli számítógépre Linux alól..................................................................................2 Belépés a távoli számítógépre..........................................................................................................2 Eye-RIS ADK indítása.....................................................................................................................3 Új projekt létrehozása az ADK-ban.................................................................................................4 Eye-RIS rendszer programozása......................................................................................................5 Main.cpp (sorról-sorra)....................................................................................................................5 CFPPCode.fpp (sorról-sorra)...........................................................................................................5 Fordítás............................................................................................................................................6 Hogyan dolgozzunk?.......................................................................................................................6 Kód a 6-os feladatra.........................................................................................................................9 Main.cpp.....................................................................................................................................9 CFPPcode.fpp.............................................................................................................................9
Csatlakozás a távoli számítógépre windows alól Start->Kellékek->Távoli asztali kapcsolat
Hostnév:
fultavirt.itk.ppke.hu
Csatlakozás a távoli számítógépre Linux alól • •
Nyiss meg egy terminált A következő parancsot futtasd: ◦ rdesktop -g 1024x768 fultavirt.itk.ppke.hu Az 1024×768 helyett beírhatod a kívánt ablakméretet!
Belépés a távoli számítógépre Felhasználónév: eyeris#, ahol a # a csoport feladatának száma. Pl a 6-os feladat esetén a felhasználónév: eyeris6 lesz. A jelszó mindenkinél „d46”
Eye-RIS ADK indítása Kattints az asztalon látható ikonnal indítható Eye-RIS ADK 10.1 feliratú ikonra. A Workspace kijelölésénél a C:\AnaFocus\EyeRISADK\eclipse\eyeris# válasszátok (át kell írni a számot), ahol a # a felhasználónévhez hasonlóan a feladatotok számát jelölje. Ez nálam a 6-os feladat lesz:
Ezután elindul az Eclipsre épülő fejlesztőeszköz. Korábbi tanulmányaitokból ezt már ismerhetitek, mint azt az előadáson is kérdeztem, így a működésről, képernyő felépítéséről nem beszélek. Az egyedüli különbséget az Eye-RIS user interface jelenti, mely képes az eszközről beérkező képek megjelenítésére, valamint itt található az általa elérhető konzol. A rajta szereplő gombok az Eye-RIS képmemóriájából tudják a tartalmat előhívni.
Új projekt létrehozása az ADK-ban File->New->Eye-RIS Project
A megjelenő képernyőn kell beállítani a projekt bizonyos jellemzőit. FIGYELEM! Az alábbiakat pontosan állítsátok be: •
Project template: Image accuration
•
System vesrion: Eyeris13 vagy 12 legyen
A projekt templateből az Image accuration garantáltan elkészíti a számotokra szükséges linkeléseket, valamint a fordítót beállítását. Ha beállítottátok, akkor a Finish gombra lehet kattintani és elkezdeni a programozást.
Eye-RIS rendszer programozása A legtöbb segítséget a programozáshoz az alapjaiban jól áttekinthető és sok példával illusztrált kézikönyv jelenti, melyet korábban megkaptatok, de a távoli számítógépen is elérhető: Start->Programok->Anafocus->Eye-RIS ADK->Eye-RIS User Manual Az IPL dokumentum tartalomjegyzékét mindenképpen olvassátok át, mert sok segítséget ad, hogy milyen képfeldolgozási műveleteket érhettek el az Eye-RIS rendszeren. Az itt szereplő függvényeket vessétek össze azzal, amit a feladat leír. Minden függvényt példakóddal illusztrálnak. – Miután a projectet létrehoztátok, a projektfában bontsátok le a projektet. A programozáshoz két állományhoz kell nyúlnotok: •
Main.cpp
•
CFPPCode.fpp
Az eyeris#.elf a futtatható bináris, melyet a fordítás után a keretrendszer feltölt az eszközre.
Main.cpp (sorról-sorra) A fordító a main.cpp esetében mutatja hol a hiba. Képes akkor is lefordítani a kódot, ha a Q-Eye chipre írt kód hibás és létezik korábbról. #include "eyerisbl.h"
//ez mindenképpen kell
extern fpp_int g_sensedImage;
//a Q-Eye chippel közös memóriaterületre mutató változó. Ezen az oldalon nem lehet tudni, hogy kép, vagy rendes változó
int main() { int i;
//változót mindig így deklarálunk. Ha értéket is adsz meg hozzá, akkor a képmemóriára lesz mutató!!!
for (i=0;i<1000;i++)
//láthatjátok, még egy egyszerű ciklusnál sem lehet
{ Section_execute(ImageAcquire);
//ezzel hívjuk meg a Q-Eye chipen lévő függvényt
Image_display(g_sensedImage,WINDOW_0,GREY);
//ezzel rakjuk ki a képet, az első ablakba. A GREY jelöli, hogy szürkeskálás képről van szó és nem binárisról
} }
CFPPCode.fpp (sorról-sorra) Az fpp kód fordítása nem olyan barátságos, mint a c kódé, a hiba helyét pontosan nem adja meg, csak következtetni lehet, hogy melyik megírt függvényben lehet a hiba. Az egyes függvényeket
csak akkor fordítja le, ha ténylegesen használni is fogjátok, vagyis debugolni így lehet. Ha nem tudja lefordítani a kódot, akkor jelez és megkérdezi, hogy a kód régebbi verzióját akarjátok-e használni. – #include "ipl.hfpp"
//ezt szükséges beinklúdolni
int g_sensedImage = 0;
//a main.cpp-ben már hivatkozott változó képváltozó lesz, a 0. cellát fogjuk megadni helyként
void section ImageAcquire() { time expTime = 5;
//a Q-Eye chippen már lehet a deklarálás után értéket adni. Célszerű végignézni, hogy milyen változók vannak.
int gain = 2; Sense_acquire(LAM_0, expTime, gain);
//Ezzel készítünk felvételt, amelyet a LAM_0 analóg memóriaterületre helyezünk (a chippen, cellánként van). Figyeljetek arra, hogy az idő előrehaladtával a tartamlát elveszíti!
Move_downloadImage(LAM_0, g_sensedImage, GREY); //az analóg memóriából így lehet a digitális memóriába a képet lementeni. Meg kell adni, hogy szürkeárnyalatos-e. }
Fordítás Ezt követi a fordítás, ami az Eclipse rendszerekből (majdnem) teljesen jól ismert. Ctrl+B paranccsal lehetséges. Ha futtatni akarnánk a kódot, akkor „Eye-RIS applications”-ként kell és nem stand aloneként.
Hogyan dolgozzunk? Egy ki nem osztott feladaton, a 6-os feladaton mutatom be, hogy mi az amit szeretnénk kérni a bemutatóra. Kontraszt érték számítás – fókusz mérték A feladat célja: Az Eye‐RIS rendszer optikai bemenetén keresztül érzékelt képfolyamon számolja ki a kép kontrasztját (élképének abszolút értékkel vett átlagát), és ezt jelenítse meg a képernyőn. Egy megfelelő nagykontrasztú képet a kamera látóterébe helyezve manuálisan állítsa élesre a kamerát a kontrasztérték maximalizálásával. Megjegyzés: Célszerű a program futása folyamán külön ablakban kijelezni az eredeti képet, az élkép abszolút értékét. Az összes képi műveletet a szenzor‐processzor chipen kell implementálni! A képfolyam érzékelését a betöltött mintaprogram megoldja, persze a paraméterek állítása hasznos lehet. Szükség van tehát egy élképre, amit elő kellene állítani valahogy. Hajtsuk fel az IPL (Image Processing Library) dokumentációját és nézzük végig a függvényeket. Egy éldetekció tipikusan
szűréshez tartozik, így keressük itt! Láthatjuk, hogy több filter is van. Ha nem vagyunk biztosak milyet keressünk, akkor kis googlizás után (vagy más forrással, pl. itt: http://en.wikipedia.org/wiki/Edge_detection) nézzük meg, hogy mely éldetekciós módszerek léteznek, s melyek vannak megvalósítva a Q-Eye chippen. Első bökésre én most a Laplace filtert választom, s elolvasom a róla szóló fejezetet. Látható, hogy egy függvény túlterhelhető, így érdemes kiválasztani a legszimpatikusabbat a feladathoz. Alatta minden esetben le van írva, hogy hogyan paraméterezhető, s mi mit jelent. void Filter_laplace(lam source, lam destination, int mode); void Filter_laplace(lam source, lam destination, ldm destinationPositive, ldm destinationNegative, int mode); A source és a destination cellák használatkor NE legyenek ugyanazok, mert képesek érdekes dolgokat produkálni (szeretnék ismét utalni Kovács Ferenc Professzor Úr Analóg Áramkörökről szóló óráira még a Bsc-s időszakból).
Ezt követően kellene valahogyan megszámolni az élhez tartozó elemeket. Kézenfekvő megoldás az abszolút differencia alkalmazása, ám „nincsen” fix középérték és sokszor elcsúszhat, így csak nagy különbségképzésnél érdemes hozzányúlni, illetve, ha még akarunk vele tovább dolgozni. Én úgy oldottam most meg a feladatot, hogy kettőt thresholdolok a középérték környékén (ami most éppen nem 127, hanem csak 109, ez legközelebb megint picit más lesz, a megoldásaitokban ezzel számoljatok!) Veszem egyszer az élkép thresholdját 106 felett, valamint 110 felett (az élképet ha megnézitek, láthatjátok, hogy fehér és fekete részek egyaránt előfordulnak, függően a kontrasztviszonyoktól). Ezután fogom és veszem a két bináris kép AND kapcsolatát, így már ténylegesen csak az élek vannak, mint azt az ábrán láthatjátok.
Mostmár vannak fekete és fehér pontjaim, meg kellene számolni valamelyiket, legyen ez mondjuk a fehér, mert erre a tartalomjegyzékből találhatunk megoldást az IPL kézikönyv long Counting_whitePoints(ldm source);
fejezetnél. Ezt követően ezt az értéket vissza kellene adni az FPGA számára, úgyhogy emiatt át kell írni a függvény definíció void-ját, long-ra, majd visszatérni a fehérpontok számával. A main-ben be kell állítani még a megjelenítendő ablakok számát, meghívni a függvényt, fogadni a visszatérési értékét, majd kiiratni azt az UI-ra. Eredmény és a hozzá tartozó kód:
Kód a 6-os feladatra Main.cpp
#include "eyerisbl.h" extern fpp_int g_sensedImage; extern fpp_int g_filteredImage; extern fpp_int g_countImage; //ezek közös képváltozók lesznek int main() { setNumberOfWindows(3, 3); while (true) { int _count;
//beállítjuk hány ablakunk //legyen, hány oszlopban //nem szép...
//ebbe számoljuk bele majd a fv. Futás //eredményét _count=Section_execute(ImageAcquire); //fv. futtatása Image_display(g_sensedImage, WINDOW_0, GREY); Image_display(g_filteredImage, WINDOW_1, GREY); Image_display(g_countImage, WINDOW_2, BINARY); //így rakjuk ki a képet az ADKra, figyeljetek, hogy mi //bináris, mi GREYscale printMessage ( "m: %i \n", (178*144)_count); //kiiratás } } CFPPcode.fpp
#include "ipl.hfpp" int g_sensedImage = 0; int g_filteredImage = 1; int g_meanImage = 2; //meghatároztuk a képek helyét a közös memóriaterületen long section ImageAcquire() //visszatérési értékünk lesz! { time expTime = 5; //msben a képkészítési idő int gain = 2; //erősítés Sense_acquire(LAM_0, expTime, gain); //felvétel készítés Filter_laplace(LAM_0, LAM_1, MODE_4, false); //éldetektálás Thresh_global (LAM_1, LDM_0, 107); //threshold alul Thresh_global (LAM_1, LDM_1, 110); //threshold felül Logic_and(LDM_0, LDM_1, LDM_2); //a logikai és long wp; //változó a számoláshoz wp=Counting_whitePoints(LDM_2); //megszámoljuk //a digit membe töltjük ami kell Move_downloadImage(LAM_0, g_sensedImage, GREY); Move_downloadImage(LAM_1, g_filteredImage, GREY); Move_downloadImage(LDM_2, g_meanImage, BINARY); return wp;//függvény vége, visszatérési értéket adunk
}