FingerPrint.java
//
// Klasse FingerPrint
//
// Projekt FingerPrint
//
// Written by Christian Birzer, Peter Söllner Juni 1998
//
// Implementiert das Applet FingerPrint mit dem GUI und der
// Bedienerführung.
//
import java.applet.*;
import java.awt.*;
import java.awt.image.*;
import java.util.Date;
import KohonenNetz;
public class FingerPrint extends Applet
{
// UNTERSTÜTZUNG FÜR EINZELPLATZANWENDUNGEN:
// m_fStandAlone wird auf true gesetzt, falls das Applet eigenständig ausgeführt wird
//--------------------------------------------------------------------------
private boolean m_fStandAlone = false;
private Image SourceImg, DestImg, NetImg[];
private PictureCanvas pc2 = new PictureCanvas();
private PixelArray SourceData;
private PixelArray DestData;
private Button BuEdge, BuFind, BuThin, BuStart, BuLearn, BuSearch, BuForget,
BuAllV, BuNoneV, BuInvertV, BuDelV, BuAllI, BuNoneI, BuInvertI;
private Label MsgLabel, InputLabel, VectorLabel, FilterLabel, StepsLabel,
MinEpsLabel, MaxEpsLabel, MinSigLabel, MaxSigLabel;
private CheckboxGroup FilterGroup;
private Checkbox FilterCheck1, FilterCheck2, FilterCheck3, AutoLearn;
private TextField MinEpsText, MaxEpsText, MinSigText, MaxSigText;
private Choice StepsChoice;
private int w, h;
private LineFinder lf;
private List FingerPrintList, VectorList;
private NeuroVektor Vector;
private String PictureName;
private NetzTester Netz;
private TextArea DebugOut;
private int JavaBugWorkaround;
// UNTERSTÜTZUNG FÜR EINZELPLATZANWENDUNGEN
// Die Methode main() stellt den Einsprungpunkt des Applets dar, wenn es als eigenständige
// Anwendung ausgeführt wird. Diese wird ignoriert, falls das Applet innerhalb
// einer HTML-Seite ausgeführt wird.
//--------------------------------------------------------------------------
public static void main(String args[])
{
// Erstellen sie ein Fenster auf der obersten Ebene, das das Applet FingerPrint enthält
//----------------------------------------------------------------------
FingerPrintFrame frame = new FingerPrintFrame("FingerPrint");
// Rahmen (Frame) muss vor dem Dimensionieren angezeigt werden, damit insets() gültige Werte zurückgibt
//----------------------------------------------------------------------
frame.show();
frame.hide();
frame.resize(frame.insets().left + frame.insets().right + 830,
frame.insets().top + frame.insets().bottom + 1000);
// Der folgende Code startet die Ausführung des Applets innerhalb des Rahmenfensters.
// Hier wird auch GetParameters() aufgerufen, um die Parameterwerte der
// Befehlszeile abzurufen, und m_fStandAlone auf true gesetzt, um zu verhindern,
// dass init() diese Werte aus der HTML-Seite holt.
//----------------------------------------------------------------------
FingerPrint applet_FingerPrint = new FingerPrint();
frame.add("Center", applet_FingerPrint);
applet_FingerPrint.m_fStandAlone = true;
applet_FingerPrint.init();
applet_FingerPrint.start();
frame.show();
}
// FingerPrint Klassen-Konstruktor
//--------------------------------------------------------------------------
public FingerPrint()
{
// ZU ERLEDIGEN: Platzieren Sie hier Code für den Konstruktor
}
// APPLET-INFO-UNTERSTÜTZUNG:
// Die Methode getAppletInfo() gibt eine Zeichenfolge zurück, die Autor/Autorin,
// Copyright-Datum oder verschiedene andere Informationen des Applets beschreibt
//--------------------------------------------------------------------------
public String getAppletInfo()
{
return "Name: FingerPrint\r\n" +
"Autor/Autorin: Christian Birzer\r\n" +
"Erstellt mit Microsoft Visual J++ Version 1.1";
}
/*
** LoadImage
**
** Lädt das angegebene Bild in SourceImg. Es wird versucht, allen Speichermüll
** freizugeben. Funktioniert allerdings nicht. Nach 40 Aufrufen dieser Funktion
** sind 16MB weg :-((
*/
private void LoadImage(String name)
{
SourceImg = null;
Runtime.getRuntime().gc();
MediaTracker pictureTracker = new MediaTracker(this);
SourceImg = getImage(getDocumentBase(), name);
pictureTracker.addImage(SourceImg,0);
try {
pictureTracker.waitForAll();
} catch (InterruptedException e) {
getAppletContext().showStatus("Oops, could not load Image");
}
pictureTracker = null;
}
/*
** GetImageData
**
** Kopiert die Bilddaten aus dem SourceImg in den SourceData
** Pixel-Array.
*/
private void GetImageData()
{
PixelGrabber grabber = new PixelGrabber(SourceImg, 0, 0, w, h, SourceData.Pixels, 0, w);
try {
grabber.grabPixels();
} catch (InterruptedException e) {
getAppletContext().showStatus("Oops, could not grab Pixels");
}
if ((grabber.status() & ImageObserver.ABORT) != 0) {
getAppletContext().showStatus("image fetch aborted or errored");
}
}
/*
** SetImageData
**
** Erzeugt ein neues Bild aus den Bilddaten, die im Data-Array
** angegeben wurden (sollte eigentlich ein PixelArray sein...)
** Falls scaled true ist, wird das Bild um 50% in jeder Richtung
** verkleinert.
*/
private Image SetImageData(int Data[], boolean scaled)
{
Image Img;
int BufferData[] = new int[(w/2) * (h/2)];
int x, y;
if(scaled) {
for(x=0;x<w/2;x++) {
for(y=0;y<h/2;y++) {
BufferData[y*w/2+x] = Data[y*2*w+x*2];
}
}
Img = createImage(new MemoryImageSource(w/2, h/2, BufferData, 0, w/2));
} else {
Img = createImage(new MemoryImageSource(w, h, Data, 0, w));
}
return Img;
}
//Die Methode init() wird vom AWT aufgerufen, wenn ein Applet erstmals geladen oder
//neu geladen wird. Überschreiben Sie diese Methode, um jede Initialisierung auszuführen,
//die das Applet benötigt (z. B. die Initialisierung von Datenstrukturen, das Laden von Bildern oder
//Schriftarten, das Erstellen von Rahmenfenstern, das Festlegen des Layout-Managers oder das Hinzufügen von
//Komponenten der Benutzeroberfläche).
//--------------------------------------------------------------------------
public void init()
{
int i;
Panel PanelNorth, PanelWest, DummyPanel;
GridBagLayout WestLayout;
GridBagConstraints Constraint;
Graphics og;
//Wenn Sie eine mit Hilfe des Ressourcen-Assistenten generierte Steuerelement-Erstellungklasse verwenden,
//um die Steuerelemente in Ihrem Applet anzuordnen, können Sie dessen Methode
//CreateControls() von dieser Methode aus aufrufen. Entfernen Sie dazu den folgenden
//Aufruf von resize(), bevor Sie den Aufruf von CreateControls() einfügen.
//CreateControls() führt eine eigene Größenänderung durch.
//----------------------------------------------------------------------
resize(830,1000);
NetImg = new Image[3];
NetImg[0] = createImage(200,200);
NetImg[1] = createImage(200,200);
NetImg[2] = createImage(200,200);
// Netz-Ausgabe-Bilder löschen:
for(i=0;i<3;i++) {
og = NetImg[i].getGraphics();
og.setColor(Color.black);
og.fillRect(0,0,NetImg[i].getWidth(null)-1,NetImg[i].getHeight(null)-1);
}
LoadImage("Peter_0.gif");
pc2.SetImage(SourceImg);
Netz = new NetzTester(722);
/*
** GUI-Elemente erstellen:
*/
BuEdge = new Button("Kanten finden");
BuFind = new Button("Linien finden");
BuThin = new Button("Linien ausdünnen");
BuStart = new Button("Bildbearbeitung starten");
BuLearn = new Button("Lernen");
BuSearch = new Button("Suchen");
BuForget = new Button("Vergessen");
BuAllV = new Button("Alles");
BuNoneV = new Button("Nichts");
BuInvertV = new Button("Invertieren");
BuDelV = new Button("Alle löschen");
BuAllI = new Button("Alles");
BuNoneI = new Button("Nichts");
BuInvertI = new Button("Invertieren");
FingerPrintList = new List(8,true);
VectorList = new List(8,true);
MsgLabel = new Label("Bereit!");
InputLabel = new Label("Eingabebilder:");
VectorLabel = new Label("Vektoren:");
DebugOut = new TextArea(10,50);
FilterGroup = new CheckboxGroup();
FilterCheck1 = new Checkbox("Schwellwert", FilterGroup, true);
FilterCheck2 = new Checkbox("Sobel vertikal", FilterGroup, false);
FilterCheck3 = new Checkbox("Logarithmisch", FilterGroup, false);
FilterLabel = new Label("Kantendetektionsverfahren:");
StepsLabel = new Label("Anzahl Lernschritte:");
StepsChoice = new Choice();
MinEpsText = new TextField();
MaxEpsText = new TextField();
MinSigText = new TextField();
MaxSigText = new TextField();
MinEpsLabel = new Label("Min. Lernrate:");
MaxEpsLabel = new Label("Max. Lernrate:");
MinSigLabel = new Label("Min. Varianz:");
MaxSigLabel = new Label("Max. Varianz:");
AutoLearn = new Checkbox("Auto-Lernrate");
/*
** Listbox mit Abdrücken initialisieren:
*/
for(i=0;i<10;i++) {
FingerPrintList.addItem("Christian_"+i);
}
for(i=0;i<10;i++) {
FingerPrintList.addItem("Peter_"+i);
}
for(i=0;i<10;i++) {
FingerPrintList.addItem("Andrea_"+i);
}
for(i=0;i<10;i++) {
FingerPrintList.addItem("Liane_"+i);
}
/*
** Wieso die folgenden Zeilen nötig sind, weiß ich leider auch nicht.
** Jedenfalls erscheinen in der zweiten Listbox nie Scrollbars, wenn nicht
** die Listbox schon überfüllt ist, bevor sie das erste mal engezeigt wird.
** Nachdem die Listbox angezeigt wurde, können die Einträge gelöscht werden.
** Später erneut eingefügte Einträge erzeugen ggf. eine Scrollbar.
** Falls jemand weiß, wie man auch ohne diesen Hack an eine Scrollbar kommt,
** bitte Info an Christian.Birzer@t-online.de
*/
for(i=0;i<10;i++) {
VectorList.addItem("JavaBugWorkaround");
}
/*
** ComboBox mit Anzahl der Lernschritte füllen:
*/
StepsChoice.addItem("1");
StepsChoice.addItem("5");
StepsChoice.addItem("10");
StepsChoice.addItem("20");
StepsChoice.addItem("30");
StepsChoice.select(2);
/*
** GUI-Elemente in Panels hängen:
*/
PanelNorth = new Panel();
PanelNorth.add(BuEdge);
PanelNorth.add(BuFind);
PanelNorth.add(BuThin);
PanelWest = new Panel();
WestLayout = new GridBagLayout();
Constraint = new GridBagConstraints();
Constraint.fill = GridBagConstraints.NONE;
Constraint.gridwidth = GridBagConstraints.REMAINDER;
Constraint.weightx = 1.5;
Constraint.anchor = GridBagConstraints.NORTH;
Constraint.weightx = 1.0;
Constraint.insets = new Insets(1,4,1,4);
Constraint.fill = GridBagConstraints.HORIZONTAL;
WestLayout.addLayoutComponent("inputlabel", InputLabel);
WestLayout.setConstraints(InputLabel, Constraint);
// Input List:
Constraint.gridwidth=1;
Constraint.gridheight=3;
Constraint.weighty=0.0;//1.0;
WestLayout.addLayoutComponent("list", FingerPrintList);
WestLayout.setConstraints(FingerPrintList, Constraint);
// Input List Buttons:
Constraint.gridheight=1;
Constraint.gridwidth=GridBagConstraints.REMAINDER;
Constraint.weighty=0.0;
WestLayout.addLayoutComponent("bualli", BuAllI);
WestLayout.setConstraints(BuAllI, Constraint);
WestLayout.addLayoutComponent("bunonei", BuNoneI);
WestLayout.setConstraints(BuNoneI, Constraint);
WestLayout.addLayoutComponent("buinverti", BuInvertI);
WestLayout.setConstraints(BuInvertI, Constraint);
// Filter-Auswahl Group Label:
Constraint.gridwidth=1;
Constraint.gridheight=3;
WestLayout.addLayoutComponent("filterlabel", FilterLabel);
WestLayout.setConstraints(FilterLabel, Constraint);
// Filter-Auswahl Group:
Constraint.gridheight=1;
Constraint.gridwidth=GridBagConstraints.REMAINDER;
WestLayout.addLayoutComponent("filtergroup", FilterCheck1);
WestLayout.setConstraints(FilterCheck1, Constraint);
WestLayout.addLayoutComponent("filtergroup", FilterCheck2);
WestLayout.setConstraints(FilterCheck2, Constraint);
WestLayout.addLayoutComponent("filtergroup", FilterCheck3);
WestLayout.setConstraints(FilterCheck3, Constraint);
WestLayout.addLayoutComponent("bustart",BuStart);
WestLayout.setConstraints(BuStart, Constraint);
WestLayout.addLayoutComponent("label", MsgLabel);
WestLayout.setConstraints(MsgLabel, Constraint);
// Vektor Label:
WestLayout.addLayoutComponent("vectorlabel", VectorLabel);
WestLayout.setConstraints(VectorLabel, Constraint);
// Vektor List:
Constraint.gridwidth=1;
Constraint.gridheight=4;
Constraint.weighty=0.0;//1.0;
WestLayout.addLayoutComponent("vectorlist",VectorList);
WestLayout.setConstraints(VectorList, Constraint);
// Vektor List Buttons:
Constraint.gridheight=1;
Constraint.gridwidth=GridBagConstraints.REMAINDER;
Constraint.weighty=0.0;
WestLayout.addLayoutComponent("buallv", BuAllV);
WestLayout.setConstraints(BuAllV, Constraint);
WestLayout.addLayoutComponent("bunonev", BuNoneV);
WestLayout.setConstraints(BuNoneV, Constraint);
WestLayout.addLayoutComponent("buinvertv", BuInvertV);
WestLayout.setConstraints(BuInvertV, Constraint);
Constraint.insets = new Insets(10,4,1,4); // etwas Abstand...
WestLayout.addLayoutComponent("budelv", BuDelV);
WestLayout.setConstraints(BuDelV, Constraint);
Constraint.insets = new Insets(1,4,1,4);
// Lernschritte-Label:
Constraint.gridwidth=1;
WestLayout.addLayoutComponent("stepslabel", StepsLabel);
WestLayout.setConstraints(StepsLabel, Constraint);
// Lernschritte-Combo Box:
Constraint.gridwidth = GridBagConstraints.REMAINDER;
WestLayout.addLayoutComponent("stepschoice", StepsChoice);
WestLayout.setConstraints(StepsChoice, Constraint);
// Lernrate Labels und TextFields:
Constraint.gridwidth=1;
Constraint.weightx=1.0;
Constraint.insets = new Insets(1,4,1,4);
WestLayout.addLayoutComponent("minepslabel", MinEpsLabel);
WestLayout.setConstraints(MinEpsLabel, Constraint);
Constraint.insets = new Insets(0,0,0,0);
WestLayout.addLayoutComponent("minepstext", MinEpsText);
WestLayout.setConstraints(MinEpsText, Constraint);
WestLayout.addLayoutComponent("maxepslabel", MaxEpsLabel);
WestLayout.setConstraints(MaxEpsLabel, Constraint);
Constraint.gridwidth = GridBagConstraints.REMAINDER;
Constraint.insets = new Insets(1,4,1,4);
WestLayout.addLayoutComponent("maxepstext", MaxEpsText);
WestLayout.setConstraints(MaxEpsText, Constraint);
// Varianz Labels und TextFields:
Constraint.gridwidth=1;
Constraint.insets = new Insets(1,4,1,4);
WestLayout.addLayoutComponent("minsiglabel", MinSigLabel);
WestLayout.setConstraints(MinSigLabel, Constraint);
Constraint.insets = new Insets(0,0,0,0);
WestLayout.addLayoutComponent("minsigtext", MinSigText);
WestLayout.setConstraints(MinSigText, Constraint);
WestLayout.addLayoutComponent("maxsiglabel", MaxSigLabel);
WestLayout.setConstraints(MaxSigLabel, Constraint);
Constraint.insets = new Insets(1,4,1,4);
Constraint.gridwidth = GridBagConstraints.REMAINDER;
WestLayout.addLayoutComponent("maxsigtext", MaxSigText);
WestLayout.setConstraints(MaxSigText, Constraint);
Constraint.weightx=0.0;
Constraint.insets = new Insets(1,4,1,4);
// Auto-Lernrate
WestLayout.addLayoutComponent("autolearn", AutoLearn);
WestLayout.setConstraints(AutoLearn, Constraint);
// Netz Buttons:
WestLayout.addLayoutComponent("bulearn", BuLearn);
WestLayout.setConstraints(BuLearn, Constraint);
WestLayout.addLayoutComponent("busearch", BuSearch);
WestLayout.setConstraints(BuSearch, Constraint);
WestLayout.addLayoutComponent("buforget", BuForget);
WestLayout.setConstraints(BuForget, Constraint);
// Debug Ausgabe:
WestLayout.addLayoutComponent("debugout", DebugOut);
WestLayout.setConstraints(DebugOut, Constraint);
// Rest irgendwie auffüllen, damit der andere Mist oben ausgegeben wird...:
DummyPanel = new Panel();
Constraint.gridheight = GridBagConstraints.REMAINDER; //GridBagConstraints.REMAINDER;
Constraint.weighty = 1.0;
WestLayout.addLayoutComponent("dummypanel",DummyPanel);
WestLayout.setConstraints(DummyPanel, Constraint);
// GUI-Komponenten ins Panel einhängen:
PanelWest.setLayout(WestLayout);
PanelWest.add(InputLabel);
PanelWest.add(FingerPrintList);
PanelWest.add(BuAllI);
PanelWest.add(BuNoneI);
PanelWest.add(BuInvertI);
PanelWest.add(FilterLabel);
PanelWest.add(FilterCheck1);
PanelWest.add(FilterCheck2);
PanelWest.add(FilterCheck3);
PanelWest.add(BuStart);
PanelWest.add(MsgLabel);
PanelWest.add(VectorLabel);
PanelWest.add(VectorList);
PanelWest.add(BuAllV);
PanelWest.add(BuNoneV);
PanelWest.add(BuInvertV);
PanelWest.add(BuDelV);
PanelWest.add(StepsLabel);
PanelWest.add(StepsChoice);
PanelWest.add(MinEpsLabel);
PanelWest.add(MinEpsText);
PanelWest.add(MaxEpsLabel);
PanelWest.add(MaxEpsText);
PanelWest.add(MinSigLabel);
PanelWest.add(MinSigText);
PanelWest.add(MaxSigLabel);
PanelWest.add(MaxSigText);
PanelWest.add(AutoLearn);
PanelWest.add(BuLearn);
PanelWest.add(BuSearch);
PanelWest.add(BuForget);
PanelWest.add(DebugOut);
PanelWest.add(DummyPanel);
/*
** Panels und GUI-Elemente in Layoutmanager hängen:
*/
setLayout(new BorderLayout());
add("West", PanelWest);
add("East", pc2);
// add("North",PanelNorth); // Nur für Debug-Zwecke!
/*
** Bild-Daten ermitteln und Quell- und Zielbild anlegen:
*/
w = SourceImg.getWidth(null);
h = SourceImg.getHeight(null);
SourceData = new PixelArray(w,h);
DestData = new PixelArray(w,h);
pc2.resize(w,h);
DestData.Clear();
GetImageData();
/*
** Die Einträge in der VectorList, die nur zum Bug-Workaround nötig waren, wieder löschen.
** Ab jetzt kann er die Scrollbalken auch selbst darstellen!
*/
VectorList.clear();
// Schrift für Message-Label fett
MsgLabel.setFont(new Font(MsgLabel.getFont().getName(), Font.BOLD, MsgLabel.getFont().getSize()));
// Lernrate und Varianz setzen:
MinEpsText.setText(String.valueOf(Netz.Lernrate(true)));
MaxEpsText.setText(String.valueOf(Netz.Lernrate(false)));
MinSigText.setText(String.valueOf(Netz.Varianz(true)));
MaxSigText.setText(String.valueOf(Netz.Varianz(false)));
SourceImg = SetImageData(SourceData.Pixels, true);
DestImg = SetImageData(DestData.Pixels, false);
pc2.SetImage(DestImg);
}
// Hier zusätzlichen Bereinigungscode für das Applet platzieren. destroy() wird aufgerufen,
// wenn das Applet beendet und entladen wird
//-------------------------------------------------------------------------
public void destroy()
{
// ZU ERLEDIGEN: Platzieren Sie hier Bereinigungscode für das Applet
}
// FingerPrint Zeichnungsbehandlungsroutine
//--------------------------------------------------------------------------
public void paint(Graphics g)
{
g.drawString("Erstellt mit Microsoft Visual J++ Version 1.1", 10, 20);
}
// Die Methode start() wird aufgerufen, wenn die Seite, die das Applet enthält,
// erstmals auf dem Bildschirm erscheint. Die Startimplementierung des Applet-Assistenten
// dieser Methode startet die Ausführung des Threads des Applets.
//--------------------------------------------------------------------------
public void start()
{
// ZU ERLEDIGEN: Platzieren Sie hier zusätzlichen Code für den Start des Applets
}
// Die Methode stop() wird aufgerufen, wenn die Seite, die das Applet enthält,
// nicht mehr auf dem Bildschirm angezeigt wird. Die Startimplementierung des Applet-Assistenten
// dieser Methode beendet die Ausführung des Threads des Applets.
//--------------------------------------------------------------------------
public void stop()
{
}
/*
** getFilterMode
**
** Ermittelt den gewünschten Kantendetektions-Modus über die Auswahl der
** Checkbox. Liefert 1 für Schwellwert, 2 für Sobel, 3 für Logarithmisch
*/
private int getFilterMode()
{
if(FilterGroup.getCurrent() == FilterCheck1) {
return 1;
} else if(FilterGroup.getCurrent() == FilterCheck2) {
return 2;
} else {
return 3;
}
}
/*
** getFilterModeChar
**
** Ermittelt für den gewünschten Kantendetektions-Modus ein Zeichen
*/
private char getFilterModeChar()
{
if(FilterGroup.getCurrent() == FilterCheck1) {
return 'W'; // Schwellwert
} else if(FilterGroup.getCurrent() == FilterCheck2) {
return 'S'; // Sobel
} else {
return 'L'; // Log
}
}
/*
** OnBuStartPress
**
** Startet den Bildverarbeitungs-Prozess. Alle in der Listbox markierten
** Bilder werden der Reihe nach geladen, Kantendetektiert, Skelettiert und
** die Merkmale werden ermittelt und die erzeugten Vektoren ans Netz
** weitergegeben.
*/
private void OnBuStartPress()
{
int picindex, i, VecIndex, x, y, Who;
byte WEIGHT_3 = 10;
byte WEIGHT_2 = -2;
Filter f;
Node n;
String items[];
char FilterModeC;
/*
** Listeneintrag ermitteln und ggf. abbrechen:
*/
items = FingerPrintList.getSelectedItems();
if(items.length < 1) {
MsgLabel.setText("Kein Listeneintrag gewählt!");
return;
}
for(picindex = 0; picindex < items.length; picindex++) {
/*
** Eingabebild laden und anzeigen:
*/
MsgLabel.setText("Bild wird geladen (Bild "+(picindex+1)+"/"+items.length+")...");
PictureName = items[picindex];
LoadImage(PictureName+".gif");
GetImageData(); // Bild in SourceData holen
DestData.Clear(); // Ausgabebild löschen
// Daten in Bilder kopieren:
SourceImg = SetImageData(SourceData.Pixels, false);
DestImg = SetImageData(DestData.Pixels, false);
pc2.SetImage(SourceImg);
MsgLabel.setText("Kanten werden gesucht (Bild "+(picindex+1)+"/"+items.length+")...");
/*
** Kantendetektion:
*/
FilterModeC = getFilterModeChar();
f = new Filter(SourceData);
f.doFilter(getFilterMode());
DestData = f.getResult();
pc2.setPixels(DestData);
MsgLabel.setText("Merkmale werden gesucht (Bild "+(picindex+1)+"/"+items.length+")...");
/*
** Linien Finden:
*/
SourceData = DestData.Clone();
DestData.Clear();
lf = new LineFinder(SourceData.Pixels, DestData.Pixels, w, h);
lf.SetAppletContext(getAppletContext());
i = 0;
while(lf.Find()) {
lf.Thin();
lf.FindNodes();
lf.Copy();
i++;
if(i%10 == 0) {
MsgLabel.setText(""+i+" Linien bearbeitet (Bild "+(picindex+1)+"/"+items.length+")...");
}
}
MsgLabel.setText(""+i+" Linien bearbeitet (Bild "+(picindex+1)+"/"+items.length+")...");
/*
** Ausgabe:
*/
for(i=0;i<lf.Nodes.size();i++) {
n = (Node)lf.Nodes.elementAt(i);
if(n.level==3) {
DestData.drawCircle(n.x,n.y,7,0xff000000);
} else if(n.level==1) {
DestData.drawBox(n.x,n.y,7,0xff000000);
}
}
pc2.setPixels(DestData);
/*
** Merkmale Segmentieren:
*/
MsgLabel.setText("Merkmale werden segmentiert (Bild "+(picindex+1)+"/"+items.length+")...");
Vector = new NeuroVektor(722);
Vector.InitVektor((byte)0);
VecIndex = 0;
for(x=0;x<w-50;x+=25) {
for(y=0;y<h-80;y+=40) {
for(i=0;i<lf.Nodes.size();i++) {
n = (Node)lf.Nodes.elementAt(i);
if(n.x >= x && n.x < x+50 && n.y >= y && n.y < y+80) {
if(n.level == 3) {
Vector.Add(WEIGHT_3, VecIndex);
} else {
Vector.Add(WEIGHT_2, VecIndex+1);
}
}
}
VecIndex += 2;
MsgLabel.setText("Index " + VecIndex +"/722 (Bild "+(picindex+1)+"/"+items.length+")...");
}
}
/*
** Nachsehen, wer es war
*/
if(PictureName.startsWith("Christian_"))
Who = 0;
else if(PictureName.startsWith("Peter_"))
Who = 1;
else if(PictureName.startsWith("Liane_"))
Who = 3;
else if(PictureName.startsWith("Andrea_"))
Who = 4;
else
Who = 5;
Netz.Add(Vector, PictureName+FilterModeC, Who);
if(Vector == null) {
MsgLabel.setText("NULL");
return;
}
VectorList.addItem(PictureName+FilterModeC);
VectorList.makeVisible(VectorList.countItems()-1);
}
MsgLabel.setText("Bereit!");
Runtime.getRuntime().gc();
}
/*
** OnBuSearchPress
**
** Reagiert auf einen Click auf den Butten "Suchen" und startet die Erkennung
** der ausgewählten Muster. Eine Statistik wird dabei im Debug-Ausgabe-Fenster
** angezeigt.
*/
private void OnBuSearchPress()
{
String vector;
String items[], out, debout, search;
int v, i, found;
Date now;
// Wenn kein Vektor ausgewählt ist, sofort zurück:
items = VectorList.getSelectedItems();
if(items.length < 1) {
MsgLabel.setText("Kein Vektor ausgewählt!");
return;
}
found = 0; // Anzahl der richtig erkannten Muster
now = new Date(); // Aktuelle Zeit festhalten
DebugOut.appendText("\n===== Mustererkennung am " + now.toString() + " =====\n");
for(i=0;i<items.length;i++) {
MsgLabel.setText("Suche läuft (Muster " + (i+1) + "/" + items.length + ") ...");
// Vektor-Index suchen:
out = Netz.SucheMuster(items[i]);
search = //Netz.GetPerson(Netz.GetPersonenIndex(items[i])).name;
Netz.GetPerson(Netz.GetEingabe(items[i]).personenid).name;
if(Netz.Trefferquote() == 0.0) {
out = "nicht gefunden";
}
debout = "Gesucht: " + search +
", \tgefunden: " + out + ", \tTrefferquote: " + Netz.Trefferquote() +
"%, \tGeschlecht: ";
if(Netz.Geschlecht()<0)
debout += "weiblich";
else
debout += "männlich";
debout += "\n";
if(search.equals(out)) {
// Muster richtig erkannt!
found++;
}
MsgLabel.setText("Gefundenes Muster: " + out + " " + Netz.Trefferquote() + "%");
DebugOut.appendText(debout);
// Muster-Zentrum in Ausgabebild einzeichnen:
Netz.drawZentrum(NetImg[0], items[i], false);
pc2.Set3Image(NetImg[0], 1);
Netz.drawZentrum(NetImg[1], items[i], false);
pc2.Set3Image(NetImg[1], 2);
Netz.drawZentrum(NetImg[2], items[i], false);
pc2.Set3Image(NetImg[2], 3);
pc2.update3Image();
}
DebugOut.appendText("-----\nZusammenfassung: Richtig erkannte Muster: " + found +
" von " + items.length + " = " + (float)found*100.0/(float)items.length + "%\n");
}
/*
** OnBuLearnPress
**
** Startet den Lernvorgang. Alle in der Listbox markierten Vektoren
** werden im Netz zum Lernen markiert und gelernt. Anschließend
** wird die Netzstruktur grafisch ausgegeben.
*/
private void OnBuLearnPress()
{
int i, v, l, steps;
String items[];
int Who;
Graphics og;
Float mineps, maxeps, minsig, maxsig;
// Auswahl prüfen:
items = VectorList.getSelectedItems();
if(items.length < 1) {
MsgLabel.setText("Keine Vektoren ausgewählt!");
return;
}
// Varianz und Lernrate ermitteln:
try {
mineps = new Float(MinEpsText.getText());
} catch (NumberFormatException e) {
MsgLabel.setText("Keine Zahl bei minimaler Lernrate!");
return;
}
try {
maxeps = new Float(MaxEpsText.getText());
} catch (NumberFormatException e) {
MsgLabel.setText("Keine Zahl bei maximaler Lernrate!");
return;
}
try {
minsig = new Float(MinSigText.getText());
} catch (NumberFormatException e) {
MsgLabel.setText("Keine Zahl bei minimaler Varianz!");
return;
}
try {
maxsig = new Float(MaxSigText.getText());
} catch (NumberFormatException e) {
MsgLabel.setText("Keine Zahl bei maximaler Varianz!");
return;
}
// Netz-Parameter einstellen:
Netz.m_netz.Varianz((float)2.25);
Netz.LoescheMarkierungen();
Netz.Varianz(minsig.floatValue(), maxsig.floatValue());
Netz.Lernrate(mineps.floatValue(), maxeps.floatValue());
Netz.AutoLernrate(AutoLearn.getState());
// Vektoren zum Lernen markieren:
for(i=0;i<items.length;i++) {
Netz.MarkiereMuster(items[i], true);
}
// Anzahl der Lernschritte einstellen:
switch(StepsChoice.getSelectedIndex()) {
case 0: steps = 1;
break;
case 1: steps = 5;
break;
case 2: steps = 10;
break;
case 3: steps = 20;
break;
case 4: steps = 30;
break;
default:steps = 0;
}
Netz.Lernschritte(steps); // Anzahl Lernschritte setzen
l=0;
while (l < steps) {
l=Netz.Lernen(MsgLabel,l);
// Ausgabe des Netzes ***** alle 4 Lernschritte *****
MsgLabel.setText("Netzbilder werden berechnet...");
// Netz-Ausgabebilder löschen:
for(i=0;i<3;i++) {
og = NetImg[i].getGraphics();
og.setColor(Color.black);
og.fillRect(0,0,NetImg[i].getWidth(null)-1,NetImg[i].getHeight(null)-1);
}
Netz.drawZentren(NetImg[0]);
pc2.Set3Image(NetImg[0], 1);
Netz.drawMuster(NetImg[1]);
pc2.Set3Image(NetImg[1], 2);
Netz.drawAusgabeMap(NetImg[2]);
pc2.Set3Image(NetImg[2], 3);
pc2.update3Image();
}
MsgLabel.setText("Bereit!");
}
/*
** OnBuAllVPress
**
** Selektiert alle Einträge in der Vektoren-Liste.
*/
private void OnBuAllVPress()
{
int i;
for(i=0;i<VectorList.countItems();i++) {
VectorList.select(i);
}
}
/*
** OnBuNoneVPress
**
** Deselektiert alle Einträge in der Vektoren-Liste.
*/
private void OnBuNoneVPress()
{
int i;
for(i=0;i<VectorList.countItems();i++) {
VectorList.deselect(i);
}
}
/*
** OnBuInvertVPress
**
** Invertiert die Selektion in der Vektoren-Liste.
*/
private void OnBuInvertVPress()
{
int i;
for(i=0;i<VectorList.countItems();i++) {
if(VectorList.isSelected(i)) {
VectorList.deselect(i);
} else {
VectorList.select(i);
}
}
}
/*
** OnBuDelVPress
**
** Löscht alle berechneten Vektoren, indem eine neue
** Instanz der NetzTester-Klasse erzeugt wird.
*/
private void OnBuDelVPress()
{
VectorList.clear();
Netz = new NetzTester(722);
}
/*
** OnBuAllIPress
**
** Selektiert alle Einträge in der Eingabebild-Liste.
*/
private void OnBuAllIPress()
{
int i;
for(i=0;i<FingerPrintList.countItems();i++) {
FingerPrintList.select(i);
}
}
/*
** OnBuNoneIPress
**
** Deselektiert alle Einträge in der Eingabebild-Liste.
*/
private void OnBuNoneIPress()
{
int i;
for(i=0;i<FingerPrintList.countItems();i++) {
FingerPrintList.deselect(i);
}
}
/*
** OnBuInvertIPress
**
** Invertiert die Selektion in der Eingabebild-Liste.
*/
private void OnBuInvertIPress()
{
int i;
for(i=0;i<FingerPrintList.countItems();i++) {
if(FingerPrintList.isSelected(i)) {
FingerPrintList.deselect(i);
} else {
FingerPrintList.select(i);
}
}
}
/*
** OnBuForgetPress
**
** 'Vergisst' die gelernten Muster, löscht das Netz und die Ausgabebilder.
*/
private void OnBuForgetPress()
{
int i;
Graphics og;
Netz.LoescheNetz();
// Netz-Ausgabebilder löschen:
for(i=0;i<3;i++) {
og = NetImg[i].getGraphics();
og.setColor(Color.black);
og.fillRect(0,0,NetImg[i].getWidth(null)-1,NetImg[i].getHeight(null)-1);
}
}
/*
** handleEvent
**
** Message-Dispatch-Funktion. Reagiert auf Button-Clicks
** und ruft die entsprechende Behandlungsfunktion auf.
*/
public boolean handleEvent (Event evt)
{
int i;
if(evt.id == Event.ACTION_EVENT) {
/* if(evt.target == BuFind) {
OnBuFindPress();
} else if (evt.target == BuThin) {
OnBuThinPress();
} else if (evt.target == BuEdge) {
OnBuEdgePress();
} else*/ if (evt.target == BuStart) {
OnBuStartPress();
} else if (evt.target == BuLearn) {
OnBuLearnPress();
} else if (evt.target == BuSearch) {
OnBuSearchPress();
} else if (evt.target == BuForget) {
OnBuForgetPress();
} else if (evt.target == BuAllV) {
OnBuAllVPress();
} else if (evt.target == BuNoneV) {
OnBuNoneVPress();
} else if (evt.target == BuInvertV) {
OnBuInvertVPress();
} else if (evt.target == BuAllI) {
OnBuAllIPress();
} else if (evt.target == BuNoneI) {
OnBuNoneIPress();
} else if (evt.target == BuInvertI) {
OnBuInvertIPress();
} else if (evt.target == BuDelV) {
OnBuDelVPress();
}
}
return super.handleEvent(evt);
}
/* private void OnBuEdgePress()
{
String items[];
Filter f;
items = FingerPrintList.getSelectedItems();
if(items.length != 1) {
MsgLabel.setText("Kein oder mehrere Vektoren ausgewählt!");
return;
}
MsgLabel.setText("Bild wird geladen...");
LoadImage(items[0]+".gif");
GetImageData();
SourceImg = SetImageData(SourceData.Pixels,true);
MsgLabel.setText("Kanten werden gesucht...");
f = new Filter(SourceData);
f.doFilter(getFilterMode());
DestData = f.getResult();
pc2.setPixels(DestData);
MsgLabel.setText("Bereit!");
}
private void OnBuFindPress()
{
int i;
Node n;
SourceData = DestData.Clone();
// DestData löschen:
DestData.Clear();
MsgLabel.setText("Linien werden gesucht...");
lf = new LineFinder(SourceData.Pixels, DestData.Pixels, w, h);
lf.SetAppletContext(getAppletContext());
while(lf.Find()) {
lf.Thin();
lf.FindNodes();
lf.Copy();
}
for(i=0;i<lf.Nodes.size();i++) {
n = (Node)lf.Nodes.elementAt(i);
if(n.level==3) {
DestData.drawCircle(n.x,n.y,7,0xff000000);
} else if(n.level==1) {
DestData.drawBox(n.x,n.y,7,0xff000000);
}
}
pc2.setPixels(DestData);
MsgLabel.setText("Bereit!");
}
private void OnBuThinPress()
{
int i;
Node n;
SourceData = DestData.Clone();
lf = new LineFinder(SourceData.Pixels, DestData.Pixels, w, h);
lf.SetAppletContext(getAppletContext());
try {
while(lf.Find()) {
lf.Thin();
lf.FindNodes();
lf.Copy();
lf.DrawCenterLine();
}
for(i=0;i<lf.Nodes.size();i++) {
n = (Node)lf.Nodes.elementAt(i);
if(n.level==3) {
DestData.drawCircle(n.x,n.y,7,0xff000000);
} else if(n.level==1) {
DestData.drawBox(n.x,n.y,7,0xff000000);
}
}
} catch (ArrayIndexOutOfBoundsException e) {
getAppletContext().showStatus("ERROR: Exception ArrayIndexOutOfBounds in handleEvent()");
}
pc2.setPixels(DestData);
}
*/
}