2 Infrastruktur

2.1 Überblick

In der Abbildung 1 sehen Sie die Komponenten der Software CSI-Authentiware, welche in den folgenden Kapiteln näher erläutert werden.


PIC

Abbildung 1: Überblick der Komponenten von CSI-Authentiware

Die Komponenten sind im Einzelnen: Die Datenbasis, in der die Templates gespeichert werden. Der Cluster, er holt sich diese Templates wenn eine Anfrage vom Enrollment Terminal kommt und bearbeitet diese. Dabei nimmt er entweder ein Template in die Datenbasis auf oder vergleicht ein Template mit den anderen Templates aus der Datenbasis. Dann gibt es noch das Enrollment Terminal, hier werden die Fingerabdrücke abgenommen bzw. die Iriden aufgenommen. Aus diesen Bildern werden dann Templates generiert und eine Anfrage wird an den Cluster geschickt.

Diese Komponenten müssen jeweils einmal für die Fingerabdruckerkennung, und für die Iriserkennung implementiert werden.

2.2 FPGA Entwicklungs-Tools

In diesem Kapitel werden die Entwicklungssprachen aufgezeigt, die zum Entwerfen der FPGA-Konfigurationen von uns genutzt werden. Anhand von Vor- und Nachteilen werden wir unsere Entscheidung für die jeweilige Sprache erläutern. Die Entwicklungssprachen VHDL, Matlab-Simulink und HANDEL-C sind die Sprachen, die für uns in Frage kommen, um FPGA-Konfigurationen zu entwickeln.

Die erste Entwicklungssprache ist VHDL, eine Hardwarebeschreibungssprache. Das zweite ist Matlab Simulink, eine Software, die es ermöglicht, aus zuvor erstellten Modellen VHDL Code zu erzeugen. Und zu guter letzt HANDEL-C, welche eine modifizierte C-Implementierung zur Spezifikation von Hardware ist.

Wir haben entschieden, dass wir uns nicht auf eine der oben genannten Entwicklungssprachen festlegen werden. Dies ermöglicht eine höhere Flexibilität bei der Implementierung von Algorithmen. Zudem hat es den Vorteil, dass man schon vorgefertigte Programmstücke der jeweiligen Programmiersprache wiederverwenden kann, womit sich der Aufwand der Implementierung enorm verringern lässt. Denn man muss berücksichtigen, dass nicht alle Algorithmen in den jeweiligen Sprachen vorhanden sind. Zudem erhöht sich der Arbeitsaufwand, wenn man sich auf eine Sprache festsetzt und somit vielleicht schwierige Algorithmen in der festgelegten Sprache implementieren müsste. Genau genommen versuchen wir, die Stärken der jeweiligen Sprache auszuschöpfen, denn es ist nicht immer die schnellste Möglichkeit, alles direkt in VHDL zu programmieren. Es kann erheblich leichter sein, Designs in Matlab oder HANDEL-C zu implementieren, was die Rechtfertigung unserer Entscheidung verstärkt. Es gibt drei mögliche Szenarien, die im Folgenden vorgestellt werden, um zu verdeutlichen welches die Vorteile unserer Entscheidung sind. Der erste Fall könnte sich so darstellen, dass wir ein Modul in VHDL vorliegen haben. Somit könnten wir dieses einfach übernehmen. Die andere Möglichkeit ist, dass ein Modul in Simulink schon vorhanden ist und es mit dem System-Generator in VHDL Code umgesetzt wird. Die letzte Möglichkeit ist, dass ein Modul in einer Programmiersprache wie C vorliegt. Dieser Code ließe sich dann mit Handel-C übersetzen beziehungsweise in eine Hardwarebeschreibungssprache portieren.

2.3 Datenbasis

Ein größeres Problem im Cluster-Umfeld ist das Verteilen der Template-Datenbank. So ist es zwar sehr wahrscheinlich, das ein FPGA allein schon mehrere tausend Vergleiche pro Sekunde durchführen kann, wenn aber der Nachschub versagt, bringt der hohe Durchsatz eines FPGAs nichts. Da das Einführen einer SQL-Datenbank im Clusterumfeld wenig sinnvoll und auch nicht erwünscht ist, werden wir eine eigene Lösung implementieren, um für die nach der Entwicklungsphase folgenden Leistungstests die Wartezeit bei der Initialisierung zu minimieren.

Die Datenbasis wird, wie auf sehr vielen Parallelrechnern üblich, auf einem dedizierten Speichersystem abgelegt. Im Fall des Arminius-Clusters im PC2, auf dem wir teilweise die Berechnungen durchführen werden, handelt es sich um einen Storage-Cluster mit einem verteilten Dateisystem. Dieser ist über 4 Gigabit-Leitungen an den Rechencluster angebunden, die das Speichersystem bis zur oberen Grenze aus zulasten vermag. Rücksprachen mit dem zuständigen Techniker ergaben, dass durchaus Datenraten von bis zu 400 MB/s erreicht werden können, was sehr nahe am theoretischen Maximum von 500 MB/s (4 1000Mbits 8 ) liegt. Um aber auf diese Leistung zu kommen, müssen noch ein paar Dinge beachtet werden.


PIC

Abbildung 2: Jeder Headnode holt sich die entsprechenden Daten über das Ethernet und verteilt diese über das Infiniband weiter an die Slavenodes.

Die Datenbasis darf nicht in vielen kleinen Dateien, z.B. jedes Template in einer Datei, abgelegt werden. Eine solche Vorgehensweise würde dazu führen, dass das Betriebssystem für jedes Template einen Trap ausführen muss, was bei einer Datenbank von mehreren zig Millionen Einträgen einen enormen Overhead zur Folge hätte. Die gesamte Datenbasis in eine große Datei abzulegen, hätte zur Folge das konkurrierend auf diese zugegriffen würde und immer nur ein Plattensystem unter Last stünde. Um diese beiden Probleme zu umschiffen, haben wir uns entschlossen das die Datenbasis in n Dateien abgelegt wird, wobei n die Anzahl der vom Storage zum Cluster verfügbaren Datenleitungen ist.

Um konkurrierende Zugriffe zu minimieren, werden die so genannten Headnodes im Rechencluster, von denen ebenfalls n Stück existieren, die ihnen jeweils zugeordneten Datei über das Netzwerk in ihren Hauptspeicher laden. Dort werden die Templates in einer Queue abgelegt. Auf diesem Abschnitt sollte die maximale Performance erreicht werden.

Im Cluster selbst sind jedem der n Headnotes gleich viele Slavenodes zugeordnet, die Ihre Daten auch von den Headnodes beziehen. Für die Übertragung wird hier aber nicht mehr das Ethernet, sondern das weitaus schnellere Infiniband eingesetzt. So können noch weitere Verzögerungen ausgeschlossen werden, weil der Headnode prompt seine Daten weitergeben kann, sobald seine Queue zu sich füllen beginnt. Auf einem Slave wird dann der entsprechende Teil der Datenbasis jeweils im Hauptspeicher abgelegt.

2.3.1 Format

Wie im vorigen Abschnitt beschrieben verwenden wir einige wenige große Dateien die jeweils zu einer Datenbank zusammengefasst werden. Dieser Abschnitt definiert wie diese Dateien aufgebaut sind.

Da wir zig Millionen Templates in der Datenbank haben werden, kommt es hier besonders auf ein effizientes Format an um Plattenspeicherplatz und Netzwerkbandbreite zu sparen. Aus diesem Grund haben wir uns für selbstdefinierte Bitlängen der Datentypen entschieden und gegen C/++ Standardtypen. Dadurch verhindern wir einen Overhead von vielen Bits wenn wir anstatt z.B: 16 nur 9 benötigen. Weiterhin haben wir für jedes Template eine feste Bitlänge vorgegeben. In den Unterabschnitten zu den Algorithmen findet sich jeweils das genaue Format zu den Templates (siehe 3.4 und 4.3).

Jedes Template, egal ob Fingerabdruck oder Iris, hat eine eindeutige 32 bit ID. Da die ID einmalig ist, wird somit eine Datenbankgröße von maximal 4.294.967.296 Einträgen ermöglicht. Bei Bedarf kann die ID global, also für Iris und Fingerabdruck durchgängig, vergeben werden oder jeweils für eine Art von biometrischem Merkmal erneut definiert werden.

Die Datendateien sind Flatfiles, in der die einzelnen Templates einfach hintereinander weg gespeichert werden. Durch die fixe Bitlänge eines Templates ist so eine effiziente direkte Adressierung möglich aber auch ein performantes, kontinuierliches Lesen.

2.4 Enrollment Terminal

2.4.1 Komponenten

PIC

Abbildung 3: Übersicht Komponenten der Enrollment-Software

Das Enrollment-Terminal sorgt dafür, dass wir neue Fingerabdrücke bzw. Iriden in die Datenbasis übernehmen können. Weiter werden wir über diese Benutzerschnittstelle das gesamte System steuern, was dann in einem konkreten Anwendungsfall so aussieht, dass ein Fingerabdruck am Terminal erfasst, die Merkmale extrahiert und dann zur Auswertung an den Cluster übermittelt werden. Dort nimmt der Cluster-Dienst die Daten entgegen. Es soll aber auch die Möglichkeit gegeben werden, neue Fingerabdrücke bzw. Iriden in die Datenbasis zu integrieren.

Das Enrollment-Terminal wird aus Gründen der Kompatibilität unter Windows laufen. Sowohl die Kamera für die Iriserkennung, als auch der Fingerabdruckscanner laufen, mit Zusicherung der jeweiligen Herstellern, auf der Betriebssystemplattform von Microsoft. Wie wir in unserem Projekt auf die Scanner zugreifen wollen, ist in den jeweiligen Abschnitten zu den Geräten erläutert. Da die Art und Weise wie die Sensoren angebunden werden können maßgeblich die Struktur der Software in diesem Teil des Gesamtsystem bestimmt, haben wir uns dazu entschlossen, dass Anbindung der Sensoren, GUI sowie Feature-Extraction in einer Software vereinigt werden. Wir werden alle drei Teilmodule hier besprechen und noch weiter auf die Anbindung zum Cluster, auf dem nachher das Matching durchgeführt werden soll, eingehen.

2.4.2 System

Als Terminal dient uns ein herkömmlicher PC, an den die beiden Sensoren jeweils per USB angeschlossen werden. Sowohl der Bird 3 wie auch die IG-H100 verfügen über solche Anschlüsse. An den PC werden, keine großen Anforderungen gestellt, ein PC mit >1Ghz, 1GB Ram und USB 2.0 Anschlüssen sollten unseren Zwecken genügen. Auf diesem System wird Windows XP Professional installiert.

Optional wäre ein kleinerer Touchscreen für das System eine sinnvolle Erweiterung, um den Enrollment-Prozess zu erleichtern. So müsste in der Testphase nicht immer umständlich zur Maus gegriffen werden, um das Userinterface zu bedienen.

2.4.3 Kommunikation zwischen Terminalsoftware und Cluster

Es existieren momentan zwei Möglichkeiten, zwischen Terminal und Cluster zu kommunizieren. Zum einen kann der Dienst des Clusters eine Verbindung zum Terminal-PC aufbauen. Diese Herangehensweise ist etwas unbequem, weil die Clustersoftware die Verbindung selbständig aufrechterhalten muss und auf Änderungen in der Netztopologie nicht flexibel reagiert werden kann. So müssten wir das Terminal während einer Testphase immer an der Selben und vor allem an einer öffentlich zugänglichen IP betreiben.


PIC

Abbildung 4: Ein Portforwarding über SSH bietet sich in dem Umfeld an.

Zum anderen wäre es aber möglich, die Kommunikation zum Cluster über SSH zu tunneln. Mit Boardmitteln ist dies unter Windows zwar nicht machbar, aber dank Cyqwin kann man diese Funktionalität gut nachrüsten. Erste Tests von uns haben ergeben, dass sich mit dem unter Linux/Unix üblichen Befehl:

ssh <nutzername>@<host> -L <portlocal>:<remotehost>:<remoteport>

auch unter Windows ein Port auf einem Rechner hinter einem SSH-Frontend forwarden lässt. Über diesen Tunnel wird die Kommunikation zwischen Enrollment-Software und Cluster-Dienst über eine klassische IP-Socket Verbindung realisiert.

2.4.4 GUI

Die Benutzerschnittstelle bietet mehrere Optionen und Sichten, deren spätere Funktionalität in diesem Abschnitt besprochen werden soll. Jede Sicht wird hierbei durch einen Screenshot verdeutlicht, wobei es sich bei diesen um Skizzen und nicht schon um das fertige Produkt handelt.

Grundsicht In der Grundsicht der Terminalsoftware, bietet die GUI ein Sichtfenster, das den momentanen Status des Sensors aufzeigen soll. Für die Aufnahme von Iriden ist diese Funktion nützlicher als für das Erfassen von Fingerabdrücken, da beim Iriserkennungssystem das Auge passend vor der Kamera positioniert werden muss. Aber auch für eine kurze Sichtprüfung ist das Sichtfenster gut geeignet. In der Grundsicht wird in dem Fenster noch nichts angezeigt, dennoch soll es immer sichtbar sein.


PIC

Abbildung 5: Grundsicht

In der Grundsicht stehen lediglich zwei Optionen zur Auswahl. Hier wird abgefragt, ob der Nutzer eine Iris oder einen Fingerabdruck mit der Datenbasis abgleichen möchte. Zu jedem Zeitpunkt kann mit cancel das System im in die Grundsicht zurückversetzt werden, alle bis dorthin erhobenen Daten werden dann verworfen.

Erhebungssicht In der Erhebungssicht tritt das Sichtfenster in Aktion. Hat der User die Iris-Erkennung ausgewählt, so wird dort ein Live-Bild angezeigt. Beim Fingerabdruck soll bei jedem erneuten Auflegen der Fingerbeere, der aktualisierte Fingerabdruck angezeigt werden. Der User hat hier die Möglichkeit das Erhebungsmaterial zu begutachten, dann steht Ihm hier zur Interaktion die Wahl zur Bestätigung, zum Abbruch oder zur erneuten Erhebung frei.


PIC

Abbildung 6: Grundsicht, bei der in Scanner bereits ausgewählt wurde.

Auswertungssicht Hier kann dann letztendlich ausgewählt werden, ob das Template mit der Datenbasis abgeglichen, oder in selbige gespeichert werden soll. Wir können so leicht neue Fingerabdrücke bzw. Iriden in die Datenbasis aufnehmen.


PIC

Abbildung 7: Auswertungssicht

In beiden Fällen gibt die GUI eine Identnummer aus. Wir werden in unserem System keine personenbezogenen Daten speichern, aber für eine Überprüfung ist eine Identifikation notwendig. Eine Identnummer bietet hier eine einfache Möglichkeit, den Datensatz für jeden Teilnehmer anonym identifizierbar zu machen. Sollte Save ausgewählt worden sein, so wird eine Identnummer vom System vergeben und an den Nutzer zurück geliefert.


PIC

Abbildung 8: Rückgabe

Menü Im Menü des Hauptfensters können drei Funktionen ausgewählt werden. Quit, beendet die Terminal-Software. Die Auswahl Host führt weiter zu einem Dialog, in dem man den Host auswählen kann, auf dem hinter dem Frontend der Cluster-Control-Deamon läuft. Mit der Option Scanner Setup wird ein Dialog geöffnet, in dem spezifische Parameter an den Sensoren geändert werden können (Kontrast, Auflösung etc.).


PIC

Abbildung 9: Hauptmenü

2.4.5 GUI-Controller

Das Hauptmodul des Enrollment-Terminals, der GUI-Controller, steuert alle Abläufe auf dem Terminal. Stellt die GUI eine Anfrage, gibt dieser einen Auftrag an das Scan-Modul weiter. Das dort ermittelte Bild wird an die GUI weitergegeben und gespeichert. Gibt der User über die GUI bescheid, dass die Erhebung in Ordnung ist, gibt der Controller dieses an das Feature-Extraction-Modul weiter. Sind alle diese Vorgänge erfolgreich abgeschlossen, so übergibt der GUI-Controller das ermittelte Template über eine Socket-Verbindung an den Cluster-Controller.


Listing 1:InterfacedesGUI-Controllers
 
1char *scanfunct(char *c  ); 
2int match( ); 
3int rollout( ); 
4int extractfeature( );

2.4.6 Scanner Modul

Das Scanner Modul kommuniziert mit dem Fingerabdrucksensor und der Iriskamera. Soll ein neues Template eines Benutzers generiert werden, ruft der Gui-Controller die entsprechenden Funktionen des Scanner Moduls auf, das dann den Sensor steuert. Soll ein Template eines Fingerabdruckes generiert werden heißt die Funktion scan_fingerprint. Wird ein Template einer Iris generiert, wird die Funktion scan_iris auf dem Scanner Modul aufgerufen. Der Sensor nimmt dann das JPEG-Bild auf und überreicht es dem Scanner Modul. Das Scanner Modul übergibt dieses Bild dann schließlich dem Gui-Controller, der dieses dann weiter verarbeitet.


Listing 2:InterfacedesScannermoduls
 
1char *scanfunct(char *c  );

2.4.7 Feature-Extraction Modul

Das Feature-Extraction Modul kapselt sämtliche Arbeitsschritte, die für das eigentliche Extrahieren notwendig sind.

Als Eingabe bekommt das Modul lediglich das rohe Bild, welches der Fingerprint- bzw. der Iris-Sensor liefert, sowie einige Parameter, welche die gewünschten Extraktionsfilter festlegen. Der Ablauf sowie die einzelnen Filteralgorithmen werden ab 3.1 genauer beschrieben.

Als Ausgabe wird ein Objekt erstellt, welches die Kapazität besitzt - alle Daten, die alle implementierten Extraktionsalgorithmen produzieren könnten, aufzunehmen. Diese Schnittstelle wird bewusst sehr universell gehalten, damit sie den Anforderungen von zwei unterschiedlichen Systemem gerecht wird (Verschmelzung von Fingerprint- und Iris-Feature Extraction) und eine gewisse Flexibilität hinsichtlich nachträglicher Änderungen aufweist.

Die Schnittstelle besteht in dem Funktionsaufruf ExtractFeature, dessen Rückgabewert hier noch weiter aufgeführt wird:


Listing 3:InterfacedesFeature-ExtractionModuls
 
1 
2extractiondata ExtractFeature (char[] pictureA, 
3char *filter, char *params); 
4 
5struct tempminutie { 
6        int x; 
7        int y; 
8        char mintype; 
9        int angle; 
10} 
11 
12struct extractiondata { 
13        char *usedFilter; 
14 
15        //Minutien 
16        tempminutie[] minutieA; 
17 
18        //Gabor 
19        char *gaborgreyvalueA; 
20 
21        //Clustering 
22        short averagedistancevector; 
23        short orientationvector; 
24 
25        //Iriscode 
26        char[] irismaskA; 
27        char[] iriscodeA; 
28 
29        //Raw-Image 
30        char[] pictureA; 
31 
32}

Der Aufruf ExtractFeature beinhaltet alle ausführbaren Funktionen der Feature-Extraction Komponente. Dem Aufruf wird zudem das Bild vom Fingerabdruck bzw. der Iris übergeben, die Filterauswahl als String sowie diverse Parameter für den Filter. Als Rückgabewert wird ein Extractiondata-Objekt erzeugt, welches die ermittelten Features enthält. Dabei beinhaltet das Grundgerüst dieses Objektes die Möglichkeit, die Daten aller Filter gleichzeitig zu speichern.

Wir achten an dieser Stelle nicht auf Speichereffizienz, da es nur für das Enrollment dient und die Daten nur über das Ethernet zur Datenbank schaufeln muss. Somit gibt es hier nur einen Datentyp, der alles speichern kann.

2.5 Cluster

2.5.1 Komponenten

Der Cluster-Control-Daemon ist das Softwaremodul, welches auf jedem Cluster-Knoten implementiert wird (Abbildung 10). Er ist für die Abarbeitung der Anfragen zuständig und führt das Template-Matching wie auch die Feature-Extraction (beim Rollout) aus.


PIC

Abbildung 10: Komponenten des Cluster-Control-Daemons

2.5.2 Cluster-Control-Deamon

Diese Komponente (gleichnamig zum Softwaremodul) bildet die Hauptkomponente, welche eine Schnittstelle für die Enrollment-Komponente zur Verfügung stellt und die anderen Komponenten steuert.
Jede Instanz eines Clusternodes wird durch eine eindeutige ID der MPI-Schnittstelle identifiziert. Darüber lassen sich drei Betriebsmodi implementieren:

  1. Mastermode ID 0: Hält Verbindung zum Enrollment; Initiiert die Datenbankverteilung.
  2. Headnode ID 0-4: Kontrolliert jeweils m = n5 Clientnodes; Liest bei Initialisierung Datenbank ein; Spaltet Datenbank in m Datensätze auf; Sendet Datensätze 1m 1 an die Clientnodes und speichert Datensatz m für sich im Hauptspeicher.
  3. Clientnode ID 0-n: Erhält seinen Datensatz vom Headnode und speichert diesen temporär im Hauptspeicher (ausser Node-ID’s:0-4); Übergibt sequenziell Templates aus Datensatz an Template-Matching oder beim Rollout an Feature-Extraction.

Generell gilt hier das Prinzip der Vererbung: Masternode ist Headnode ist Clientnode.


Listing 4:Schnittstelleinterface_ccd
 
1 
2void init(); 
3 
4unsigned int identify(extractiondata td); 
5 
6unsigned int rollout(extractiondata td, char* image); 
7 
8int renew(int db_type); 
9 
10struct extractiondata { 
11        char *usedFilter; 
12 
13        //Minutien 
14        tempminutie[] minutieA; 
15 
16        //Gabor 
17        char *gaborgreyvalueA; 
18 
19        //Clustering 
20        short averagedistancevector; 
21        short orientationvector; 
22 
23        //Iriscode 
24        char[] irismaskA; 
25        char[] iriscodeA; 
26 
27        //Raw-Image 
28        char[] pictureA; 
29 
30}

2.5.3 Template-Matching

Die Aufgabe dieser Komponente besteht grundätzlich darin, ein gegebenes Template mit einem anderen Template zu vergleichen und das Ergebnis zurückzugeben. Diese Komponente wird sowohl in Software als auch in Hardware (FPGA) implementiert, um Performanceunterschiede angeben zu können.


Listing 5:Schnittstelleinterface_tm
 
1 
2void set_template(templatedata td); 
3 
4unsigned int run_match(char *templatedb); 
5 
6struct templatedata { 
7        //Iriserkennung oder Fingerprint und welcher Filter 
8        char *usedFilter; 
9 
10        //Minutien 
11        tempminutie[] minutieA; 
12 
13        //Gabor 
14        char *gaborgreyvalueA; 
15 
16        //Clustering 
17        short averagedistancevector; 
18        short orientationvector; 
19 
20        //Iriscode 
21        char[] irismaskA; 
22        char[] iriscodeA; 
23}

2.5.4 Feature-Extraction

Beim Rollout wird im Austausch zum Template-Matching diese Komponente verwendet. Wie Template-Matching wird diese ebenfalls in Hardware und Software implementiert, um die Performance vergleichen zu können. Die Aufgabe der Feature-Extraction ist die der Enrollment-Komponente (siehe 2.4.7).


Listing 6:Schnittstelleinterface_fe
 
1 
2extractiondata ExtractFeature (char[] pictureA, 
3char *filter, char *params); 
4 
5struct extractiondata { 
6        char *usedFilter; 
7 
8        //Minutien 
9        tempminutie[] minutieA; 
10 
11        //Gabor 
12        char *gaborgreyvalueA; 
13 
14        //Clustering 
15        short averagedistancevector; 
16        short orientationvector; 
17 
18        //Iriscode 
19        char[] irismaskA; 
20        char[] iriscodeA; 
21 
22        //Raw-Image 
23        char[] pictureA; 
24 
25}

2.5.5 Database

Der Database-Controller kümmert sich um die Datensätze. Kontrolliert bei Initiierung die Datensatzbeschaffung und gegebenfalls das Datensatzsplitting. Überwacht die Datenspeicherung, lagert Datensätze in Hauptspeicher aus und greift bei Initiierung gegebenenfalls auf Datenbank zu. Hält die Datensätze, falls vorhanden, für Zugriffe bereit.


Listing 7:Schnittstelleinterface_db_control
 
1 
2long int add_rawdata(FILE *fp, char *rawdata); 
3 
4int add_template(FILE *fp, unsigned int ID, char *template); 
5 
6char* read_template(unsigned int ID); 
7 
8int store_temp_database(FILE *fp); 
9 
10char* read_raw(FILE *fp, long int &timer);

2.5.6 MPI-Controller

Initiiert und kontrolliert die MPI-Schnittstelle. Überwacht und leitet Mitteilungen gegebenenfalls an den Cluster-Control-Daemon zurück. Schickt und empfängt Datensätze.


Listing 8:interface_mpi
 
1 
2void push_over_dma(int MPI_ID, FILE *fp); 
3 
4void push_result(int MPI_ID_CCD, unsigned int ID, 
5        float result); 
6 
7void push_template(extractiondata *data); 
8 
9struct extractiondata { 
10        char *usedFilter; 
11 
12        //Minutien 
13        tempminutie[] minutieA; 
14 
15        //Gabor 
16        char *gaborgreyvalueA; 
17 
18        //Clustering 
19        short averagedistancevector; 
20        short orientationvector; 
21 
22        //Iriscode 
23        char[] irismaskA; 
24        char[] iriscodeA; 
25 
26        //Raw-Image 
27        char[] pictureA; 
28 
29}