//Einige sinnvolle Include-Dateien #include #include #include #include #include #include #include #include using namespace std; /* CONSTANTS */ //Achtung: Je nach Implementierung kann ein Aendern dieser Konstanten die Notwendigkeit //der Anpassung des Quelltexts zur Folge haben! //z. Teil sind diese Konstanten auch voneinander abhängig! const int WINDOW_SIZE = 125; //Kantenlänge des Ausschnitts aus Fingerabdruck (110 in [Baldi93]) const int CENTRAL_SIZE = 67; //Kantenlänge des Ausschnitts aus Referenzfinger (65 in [Baldi93]) const int FINAL_SIZE = 6; //Kantenlänge nach Anwendung des trainierbaren Filters (6 in [Baldi93]) const int FILTER_SIZE = 7; //Kantenlänge der Filter (7 in [Baldi93]) const int GAUSS_SIZE = 5; //Größe des Gauss-Filters (5 in [Baldi93] /* CONSTANTS, adjustable */ //diese Konstanten sind frei änderbar const double LEARN = 0.05; //Lernrate fuer MLP const int ITERATIONS = 10; //Anzahl der Iterationen bei einem Programmaufruf const int GAUSS[GAUSS_SIZE][GAUSS_SIZE] = { {1, 2, 3, 2, 1}, {2, 5, 6, 5, 2}, {3, 6, 8, 6, 3}, {2, 5, 6, 5, 2}, {1, 2, 3, 2, 1} }; //Matrix für die Gauss-Faltung /* TYPEDEFS */ typedef vector VS; //Vektor für Dateinamen typedef vector VuC; //Vektor, der eine Bildzeile speichert typedef vector VVuC; //Matrix, die ein Bild speichert typedef vector VD; //Vektor für eine Zeile der Gewichtsmatrix typedef vector VVD; //Matrix für die Gewichte typedef pair PII; //Tupel von Fingerabdruck-Indizes typedef vector VPII; //Vektor aus Fingerabdruck-Tupeln typedef vector VVPII; //Matrix aus Fingerabdruck-Tupeln /* ***** class Filter ******************************************************* */ class Filter { //Klasse, die ein vom neuronalen Netz adaptierbares Filter enthält }; typedef vector VFilter; /* ***** class Fingerprint ************************************************** */ class Fingerprint { //Klasse für einen Fingerabdruck public: VVuC window; Fingerprint(string file = ""); private: VVuC read_tiff(string); void filter_low_pass(VVuC&, int); void segmentation(VVuC&); void get_window(VVuC& v, int, int, int); }; typedef vector VFingerprint; //Liest eine TIFF Datei ein VVuC Fingerprint::read_tiff(string file) { //Einlesen eines im TIFF Format gespeicherten Fingerabdrucks //hierzu sollte am besten die libtiff verwendet werden //genaue Beschreibung findet man auf //http://www.libtiff.org/libtiff.html#FIO //oder genauer auf //http://www.libtiff.org/libtiff.html#TIFFRGBAImage } void Fingerprint::filter_low_pass(VVuC& v, int diff) { //Tiefpassfilter, wie in [Baldi93] auf Seite 406 beschrieben } void Fingerprint::segmentation(VVuC& v) { //Segmentierung: //Algorithmus, der die Bereiche des Bildes entfernt, die nicht zum //Fingerabdruck gehören } void Fingerprint::get_window(VVuC& v, int xpos, int ypos, int size) { //Schneidet ein Fenster aus dem Fingerabdruck aus, der an das neuronale //Netz übergeben werden kann, in [Baldi93] auf Seite 406 beschrieben } /* ***** functions for writing BMPs ****************************************** */ void fwrite_int(int n, FILE* file) { fwrite(&n, sizeof(int), 1, file); } void fwrite_short(short n, FILE* file) { fwrite(&n, sizeof(short), 1, file); } void write_bmp(VVuC v, string file) { /* make height and width divisible by 4 to meet BMP specs */ for (int i=0; i<(int)v.size(); i++) while (v[i].size() % 4) v[i].push_back(0); while (v.size() % 4) v.push_back(VuC(v[0].size(), 0)); FILE* outfile = fopen(file.c_str(), "w"); /* write BMP header */ fwrite("BM", sizeof(char), 2, outfile); fwrite_int(54 + 1024 + v.size()*v[0].size(), outfile); fwrite_int(0, outfile); fwrite_int(54 + 1024, outfile); fwrite_int(40, outfile); fwrite_int(v[0].size(), outfile); fwrite_int(v.size(), outfile); fwrite_short(1, outfile); fwrite_short(8, outfile); for (int i=0; i<6; i++) fwrite_int(0, outfile); /* write color table */ for (int i=0; i<256; i++) { fputc(i, outfile); fputc(i, outfile); fputc(i, outfile); fputc(0, outfile); } /* write actual image */ for (int i=v.size()-1; i>=0; i--) for (int j=0; j<(int)v[i].size(); j++) fputc(v[i][j], outfile); fclose(outfile); } void write_bmp(VVuC v, string file, int offset_y, int offset_x) { VVuC w(CENTRAL_SIZE); for (int i=0; i _T SQR(_T a) { return a * a; } inline double fermi(double x) { return 1.0 / (1.0 + exp(-x)); } inline double dfermi(double x) { return fermi(x) * (1 - fermi(x)); } /* *** BEGIN *** CONFIGURATION FILE *******************************************/ /* CONFIGURATION FILE FORMAT */ //So kann eine Konfigurationsdatei aussehen; es ist sinnvoll sich an dieses //Schema zu halten und eventuelle weitere Parameter unten anzuhängen /* theta filter[0].t filter[0].c[i][j]s filter[0].w[i][j]s ... filter[n-1].t filter[n-1].c[i][j]s filter[n-1].w[i][j]s */ /* read configuration file */ void read_config(char* file) { //liest die Konfigurationsdatei ein } /* write configuration file */ void write_config(char* file) { //Schreibt die neuen Werte der Gewichte in die Konfigurationsdatei! } /* **** END **** CONFIGURATION FILE *******************************************/ /* *** BEGIN *** ALIGNMENT ****************************************************/ //fi ist der Index des i-ten Fingerabdrucks //fj ist der Index des j-ten Fingerabdrucks PII get_alignment(int fi, int fj) { //Berechnet das Alignment für ein Fingerabdruckpaar fi, fj } void get_alignments() { //Prüft, ob bereits vorberechnete Alignments auf der Festplatte liegen //und liest diese gegebenenfalls ein //Ansonsten wird für jedes Fingerabdruckpaar get_alignment aufgerufen //und die Alignments werden auf der Festplattte gespeichert } void check_alignment() { //Gibt zwei Fingrabdrücke in einem Bild nebeneinander aus, damit man mit //dem Auge das Alignemnt testen kann, und gibt die Korrelation aus. } /* **** END **** ALIGNMENT ****************************************************/ /* *** BEGIN *** COMPRESS *****************************************************/ VVD compress(VVuC& v, int off_y, int off_x) { //Die Gauss'sche Faltung, wie in [Baldi93] auf Seite 407 beschrieben } /* **** END **** COMPRESS *****************************************************/ /* *** BEGIN *** APPLY FILTER *************************************************/ VVD apply_filter(VVD& c, Filter& f) { //Anwendung der durch das neuronale Netz gelernten Filter //wie in [Baldi93] auf Seite 410 beschrieben } /* **** END **** APPLY FILTER *************************************************/ /* *** BEGIN *** quad_diff ****************************************************/ VVD quad_diff(VVD& a, VVD& b) { //Berechnung der quadratischen Differenz der Filterausgaben } /* **** END **** quad_diff ****************************************************/ /* *** BEGIN *** MLP **********************************************************/ //fi ist der Index des i-ten Fingerabdrucks //fj ist der Index des j-ten Fingerabdrucks double train_MLP(int fi, int fj, double teacher) { //trainiert die Gewichte des MLPs für einzelnes Fingerabdruckpaar } double test_MLP(int fi, int fj) { //wendet das trainierte MLP an auf einzelnes Fingerabdruckpaar an //und erzeugt die Ausgabe } /* **** END **** MLP **********************************************************/ int main(int argc, char* argv[]) { //Einlesen der Konfigurationsdatei //read_config(argv[1]); //Vorverarbeitung, Teil I //Ermittlung der Alignments //get_alignments(); //Vorverarbeitung, Teil II //Training des neuronalen Netzes //Ausgabe der Ergebnisse //Evaluation des Netzes return 0; }