# java screenshots und erkennung des bildes



## Guest (16. Mai 2008)

hallo,

ich bin auf der suche nach einem programm, welches screenshots des desktops oder eines anderen programms macht und auf diesem screenshot sind zahlen zu sehen.

diese zahlen sollen in dem java programm, welches auch den screenshot machen kann aus dem bild erkannt werden und einer variable zugeordnet werden.

z.b.

java programm  ->  erstellt screenshot -> untersucht die auf dem bild befindlichen zahlen -> ordnet jeder rzahl einer variable zu  -> ich glaub den rest schaff ich allein ....

geht das , ich glaub ich habe schon im netz einen kleinen programmabschnitt gefunden der screenshots erstellt und diese in einer datei schreibt,

aber das bild automatisch auszuwerten und die zahlen zu erkenn ist schwieriger,



könnt ihr mir helfen ?


grüße,
gerhart


----------



## Illuvatar (16. Mai 2008)

Automatische Bildverarbeitung gehört zu den schwierigsten Themen die es überhaupt gibt  Dass das ganze schwierig ist, ist natürlich mit Grund dafür, dass alle Welt Captchas verwendet.

Wie auch immer, lösbar ist es natürlich schon. Kommt natürlich auch darauf an, wie gut die Zahlen lesbar sind, und ob es immer die gleichen Zahlen sind. Ich nehme zuerst mal den einfachsten Fall an: du kennst ein Gebiet in dem Screenshot, von dem du weißt, dass die Zahlen in dem Gebiet sind. Dieses Gebiet hat eine einfarbige Hintergrundfarbe. Die Zahlen sehen immer auf den Pixel genau gleich aus.
Dann wirst du anfangen, dass du dir den Bildbereich in ein Image holst. Das gehst du dann Pixel für Pixel durch, ob du ein Pixel findest (von oben nach unten, von links nach rechts -> richtige Reihenfolge), das nicht die Hintergrundfarbe hast. Du machst dir ein boolean[][] das so groß ist, wie die Ziffer maximal sein kann. Dann suchst du von dem gefunden Pixel aus alle anderen Pixel mit einer anderen Farbe als der Hintergrundfarbe. Wo du die findest, markierst du das in dem Array als true. Am Ende vergleichst du das boolean[][] mit 10 Referenzarrays für die einzelnen Ziffern. Wenn die Bedingungen so einfach sind wie anfangs gesagt, müsste eins davon passen. Danach: verwendete Pixel auf die Hintergrundfarbe setzen und die nächste Ziffer suchen.

Wenn die Ziffern z.B. immer anders aussehen, wird es schwerer. Die grobe Richtung wäre wohl, die gefundenen Bildstrukturen in Datenstrukturen wie "Linie" und "Knoten" zu bringen und das dann mit Referenzstrukturen zu vergleichen. Mehr dazu auch hier.


----------



## Guest (17. Mai 2008)

zum glück sind die zahlen immer gleich, aber im screenshot nicht pixelgenau an der selben stelle

nur muss das fenster, welches ich dann einen screenie von erstelle immer pixelgenau an der selben stelle erscheinen muss, sobald ein pixel abweichung vom array besteht, gehts nicht mehr oder?

vielleicht sollte man vorher im programm noch jedesmal ein refernzpunkt auswählen können, wo dieses kleine gebiet aus dem screenshot markiert wird.

könnte man nicht z.b. falls ein groß geschreibenes A erkannt werden soll, ein vorprogrammiertes A mit dem A aus dem screenie vergleichen, mit dem unterschied das das vorprogrammierte A nur aus 3 strichen besteht und dann mit den pixels im scrennie verglichen werden soll, dann könnte man doch evtl. kleinere verschiebungsfehler bei der bilderkennung kompensieren...


aber mal zum grundsätzlichen,

wie ist denn der java code um aus einem gescreenten bild die pixel auszulesen, und der code wie man die pixel mit anderen vorprogrammierten pixelarrays vergleicht?

ich kenn immerhin den code wie man einen screenie erstellt und in eine jpg-datei speichert...
mehr leider nich...

kennt den einer?   oder vielleicht einen vorschlag,  hab bisher auf dem gebiet noch nix programmiert


----------



## Lulumann6 (17. Mai 2008)

wofür brauchst du das eigentlich? vielleicht kann man eventuell auch anders an die sache rangehen...
für mich hört es sich so an als ob du ein bot für ein browsergame machen willst  :lol: (es hört sich vielleicht auch nur für mich so an, weil ich sowas selber schon probiert habe XD )


----------



## 0x7F800000 (17. Mai 2008)

Naja, kleine verschiebungsfehler sind nicht schlimm. Ich würde da wie folgt vorgehen:

-Wenn du am anfang irgendetwas wie ein JPEG-Bild eines Buchstaben hast, musst du zuerst Buchstaben/Ziffer vom Hintergrund trennen, weil selbst das allerschwarzweiseste JPEG aus hundert farben besteht. Du brauchst das alles erstmal binär, quasi schwarz weiß.

-Den zu identifizierenden schwarzen klumpen betrachten, den am weitesten links und den am weitesten oben gesetzten pixel raussuchen, und sich an diesen pixeln ausrichten => verschiebungsfehler wird dadurch minimal

-Auf 100% Korrelation sollte man sich bei irgendwelchen bildchen nicht verlassen => Nicht 1:1 mit referenz-arrays vergleichen, sondern lieber den "Abstand" zwischen dem bild und dem referenz-array ausrechnen, z.B. in dem du die anzahl der übereinstimmenden pixel zählst, das wäre wohl die naheliegendste Metrik... Danach einfach das zeichen wählen, bei dem die beste übereinstimmung der daten festgestellt wurde. 

-Referenz arrays in verschiedenen auflösungen, also sowas wie MIP-maps verwenden, dann spart man eine menge zeit, weil man die anzahl der in frage kommenden zeichen auch mit sehr kleinen auflösung stark reduzieren kann.

-Was das auslesen von pixeln angeht, tja, da hätte ich selbst mal ne frage: Warum steht in der Java-Insel nix mehr vom PixelGrabber/MemoryImageSource und dem ganzen kram? Bei BufferedImage kommt man da jedenfalls auch mit getRGB(x,y) an die Pixelfarbe, obwohl ich jetzt nicht genau weiß was da jetzt so viel toller oder so viel schlimmer dran sein soll...


@Lulumann6: Ich kenn mich zwar mit irgendwelchen browsergames überhaupt nicht aus, aber "browsergame" hört sich doch so an, als man das in einem "browser" spielen würde, und wo ein "browser" ist, dürfte der hypertext doch nicht allzuweit sein, und wenn man den hyper*text *hat, wozu soll man sich die sache mit *bild*auswertung antun? Obwohl, kA, wie gesagt, 0 plan von browsergames, hab noch nie eins gesehen, geschweige denn gespielt...


----------



## dajos7 (17. Mai 2008)

Hallo,

Du hast ja anscheinend schon nen Code gefunden, der Screenshots erstellt, ist ja auch nicht wirklich schwer  Dennoch poste ich hier mal den Abschnitt.

So nun zu dem komplexen Thema: Bildverarbeitung. Besonders Klassifizieren von Objekten steht am Ende der Bearbeitungskette einer Bildanalyse. Wie Illuvatar schon geschrieben hat, ist das ein recht anspruchsvolles Thema.
Wenn Du evtl einen screenshot der Zahlen geben könntest. 


Liess Dir das mal Durch:

Bildverarbeitung - Kassifikation besonders Kantenerkennung

Mustererkennung - hier ist der Ablauf einer Bildverarbeitung aufgezeigt

Musteranalyse

Such in Google mal nach "Bildverarbeitung skripte", das wird dir viele Universitätsdokumente des entsprechendem Fachbereichs anzeigen

zB 
Osnabrück - Vom Bild zum Objekt

Screenshot machen und als Datei ablegen:

```
try {
			Toolkit toolkit = Toolkit.getDefaultToolkit();
			Dimension screenSize = toolkit.getScreenSize();
			Rectangle rectangle = new Rectangle(0, 0, screenSize.width,
					screenSize.height);

			Robot robot = new Robot();
			BufferedImage image = robot.createScreenCapture(rectangle);

			File file = new File("C:\\screen.jpg");
			ImageIO.write(image, "jpg", file);
		} catch (Exception e) {
			System.err.println("Fehler : " + e);
		}
```

Um Pixel aus einem BufferedImage zu lesen kannste das hier amchen:


```
...
BufferedImage image =  robot.createScreenCapture(rectangle);

for (int y =0;y<image.getHeight();y++) {

  for (int x =0;x<image.getWidth();x++) {

     int rgb= image.getRGB(x,y);

  }

}
```

Es geht auch über das Raster (mit setPixel() ist es auch möglich hier sauberer auf die Pixel mit 255,255,255 werten zu manipulieren) ich empfinde setRGB und getRGB recht umständlich, wenns um die manipulation der Farbwerte geht:

```
...
BufferedImage image =  robot.createScreenCapture(rectangle);

WritableRaster raster = image.getRaster();
raster.getPixel(x, y, iArray);

for (int y =0;y<image.getHeight();y++) {

  for (int x =0;x<image.getWidth();x++) {

     int[] rgb = new int[3]
     raster.getPixel(x, y, rgb);

  }

}
```

*@0x7F800000*
Ich visualisiere mal das vorgehen, wie es auch schon angesprochen wurde:

1. Screenshot nehmen
2. Zahlen extrahieren (über evtl feste Positionen?)
3. Zahlen zuschneiden auf die Grenzen der Ziffern.
4. das dann abgleichen mit abgespeicherten festen Werten (hier könnte man auch versuchen nur die Ähnlichkeit bei einer bestimmten pixeltrefferzahl mit ner % klausel festzulegen

5. eine Grenze in % festlegen, wann eine Zahl als sicher erkannt eingestuft ist.

Wäre das ne gescheite Abarbeitungsliste?


----------



## dajos7 (17. Mai 2008)

So hab mal was gezaubert:


Optimal ist es absolut nicht, aber es geht mit meinen Dateien wunderbar. Zu mehr bin ich einfach zu faul. Aber damit kann man sicherlich schon was anfangen. Die Zahl im Screenshot kann liegen wo sie will, es muss aber immer drauf geachtet werden, dass nur weiss um sie rum ist. Das Programm schneidet die Zahl passend zu und vergleicht dann.
Ich habe die Prozentschwelle auf 90% gesetzt. Ist egal die Bilder erkennt er zu 100%. Programm missachtet auch unterschiedliche Größen von Template und angepasstem Ausschnitt aus dem Scrennshot.

Dateien dazu (Pfade bitte im Quelltext ändern):

Der Screenshot
screenshot.png

Die Templates
1.png
2.png
3.png
4.png
5.png
6.png


Das Progamm hat alle 6 Zahlen aus dem Screenshot zu 100% erkannt.


```
package de;

import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.io.File;

import javax.imageio.ImageIO;

public class MainApp {

	// Schwelle ist unterschiedlich, kommt auf die Farbkodierung
	// im Bild an muss man ermitteln, war ich zu faul zu
	private static int S_W_Schwelle = 14;

	public static void main(String[] args) {
		try {

			// 1. Nimm screenshot
			BufferedImage screenshot = ImageIO.read(new File(
					"C:\\screenshot.png"));

			// 2. Nimm die erste Zahl hier über feste Pos
			// Für die eins im screenshot.png x_left=0 width=30
			// Für die zwei im screenshot.png x_left=33 width = 33
			// Für die drei im screenshot.png x_left=71 width =32
//			 Für die vier im screenshot.png x=104 width =35
//			 Für die fünf im screenshot.png x=140 width =32
//			 Für die sechs im screenshot.png x=175 width =32

			screenshot = screenshot.getSubimage(71, 0, 32, screenshot
					.getHeight());

			// 3. Zuschneiden auf die Grenten der Zahl
			screenshot = cutToEdges(screenshot);

			// 4. Vergleichen und Prozent ausrechnen
			for (int i = 1; i <= 6; i++) {
				BufferedImage template = ImageIO.read(new File(
						"C:\\templates\\" + i + ".png"));

				System.out.println(i + " numer result #############");
				int percentage = compareWithPercentage(template, screenshot);
				System.out.println("% =" + percentage);
				if (percentage > 90) {
					System.out.println("Found number. Number is " + i);
					break;
				}
			}

		} catch (Exception e) {
			System.err.println("Fehler : " + e);
			e.printStackTrace();
		}

	}

	private static BufferedImage cutToEdges(BufferedImage img) {

		int bottom = 0;
		int top = img.getHeight();

		int right = 0;
		int left = img.getWidth();

		Raster raster = img.getRaster();

		// Grenzen ermitteln
		for (int y = 0; y < img.getHeight(); y++) {
			for (int x = 0; x < img.getWidth(); x++) {

				int[] rgb = new int[3];
				raster.getPixel(x, y, rgb);

				if (rgb[0] < S_W_Schwelle) {
					if (x < left) {
						left = x;
					}
					if (x > right) {
						right = x;
					}

					if (y < top) {
						top = y;
					}

					if (y > bottom) {
						bottom = y;
					}
				}
			}
		}

		// Unterbild extrahieren mit den neuen Grenzen
		img = img.getSubimage(left, top, right - left, bottom - top);

		return img;
	}

	private static int compareWithPercentage(BufferedImage template,
			BufferedImage screenshot) {

		int completepixel = template.getWidth() * template.getHeight();
		int matches = 0;
		Raster tempRaster = template.getRaster();
		Raster screenRaster = screenshot.getRaster();
		try {
			for (int y = 0; y < template.getHeight(); y++) {
				for (int x = 0; x < template.getWidth(); x++) {

					int[] temp_rgb = new int[3];
					int[] screen_rgb = new int[3];

					tempRaster.getPixel(x, y, temp_rgb);
					screenRaster.getPixel(x, y, screen_rgb);

					// Schwelle setzen
					if (temp_rgb[0] < S_W_Schwelle) {
						temp_rgb[0] = 0;
					} else {
						temp_rgb[0] = 15;
					}

					if (screen_rgb[0] < S_W_Schwelle) {
						screen_rgb[0] = 0;
					} else {
						screen_rgb[0] = 15;
					}

					// Hier stimmt was überein
					if (temp_rgb[0] == screen_rgb[0]) {
						matches++;
					}
				}
			}
		} catch (Exception e) {
			// Wenn hier fehler auftreten ignoriere sie erstmal
			// die 2-5% differenz in unterschiedlichen
			// Bildmaßen machen hier keinen Unterschied
		}

		// gibt die prozentuale Übereinstimmung zurück
		return (100 * matches / completepixel);
	}

}
```


----------



## dajos7 (17. Mai 2008)

Sollte man dann immer anders strukturierte Zahlen erkennen wollen, macht evtl. die Verwendung von Skelletierung Sinn.

Seite 175ff in diesem Standardwerk wird dir sicherlich helfen Seite 175ff

Quelle: DBV-Buch


----------



## dajos7 (17. Mai 2008)

So nochmal eine verbesserte Version. Nun erkennt die Software automatisch die Segmente der Zahlen und erkennt die komplette Zahl. Auch sind die Zahlen nun unterschiedlich verteilt.

es fehlt lediglich die null, die muss man eben noch ergänzen, das ganze kann man dann noch mit dem Alphabet ins Extreme treiben 

Für die Segemntierung im screenshot2.png schaut das Programm einfach ob die x Line in jedem y weisse Pixel enthät.


Dateien dazu (Pfade bitte im Quelltext ändern):

Der Screenshot
screenshot.png
Hier mit den zahlen verteilt im Bild
screenshot2.png

Die Templates
1.png
2.png
3.png
4.png
5.png
6.png
7.png
8.png
9.png





```
package de;

import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.io.File;
import java.util.ArrayList;

import javax.imageio.ImageIO;

public class MainApp {

   // Schwelle ist unterschiedlich, kommt auf die Farbkodierung
   // im Bild an muss man ermitteln, war ich zu faul zu
   private static int S_W_Schwelle = 14;

   private static int number =0;
   
 
   public static void main(String[] args) {
      try {

         // 1. Nimm screenshot
         BufferedImage screenshot = ImageIO.read(new File(
               "C:\\screenshot.png"));

         
         
         // 2. Berechne segmente der zahlen
         ArrayList<Integer> list = calcSegments(screenshot);

         
         BufferedImage screenshot_sub = new BufferedImage(screenshot.getWidth(),screenshot.getHeight(),screenshot.getType());
         for (int listindex =0; listindex< list.size()-1; listindex++) {
	        
        	// System.out.println(" pos: "+list.get(listindex) );
        	 
        	 screenshot_sub = screenshot.getSubimage(list.get(listindex), 0, (list.get(listindex+1) - list.get(listindex)), screenshot.getHeight());
	
	         // 3. Zuschneiden auf die Grenten der Zahl
        	 screenshot_sub = cutToEdges(screenshot_sub);
	
	         // 4. Vergleichen und Prozent ausrechnen
	         for (int i = 1; i <= 9; i++) {
	            BufferedImage template = ImageIO.read(new File(
	                  "C:\\templates\\" + i + ".png"));
	
	            
	            int percentage = compareWithPercentage(template, screenshot_sub);
	            
	            if (percentage > 90) {
	              // System.out.println("Found number. Number is " + i);
	               number = number + (int)( i*Math.pow(10,list.size()-1-listindex-1));
	              // System.out.println("--> "+number +" pow: "+(list.size()-1-listindex));
	               break;
	            }
	         }
         }
         System.out.println("number in screenshot is: "+number);

      } catch (Exception e) {
         System.err.println("Fehler : " + e);
         e.printStackTrace();
      }

   }

   private static BufferedImage cutToEdges(BufferedImage img) {

      int bottom = 0;
      int top = img.getHeight();

      int right = 0;
      int left = img.getWidth();

      Raster raster = img.getRaster();

      // Grenzen ermitteln
      for (int y = 0; y < img.getHeight(); y++) {
         for (int x = 0; x < img.getWidth(); x++) {

            int[] rgb = new int[3];
            raster.getPixel(x, y, rgb);

            if (rgb[0] < S_W_Schwelle) {
               if (x < left) {
                  left = x;
               }
               if (x > right) {
                  right = x;
               }

               if (y < top) {
                  top = y;
               }

               if (y > bottom) {
                  bottom = y;
               }
            }
         }
      }

      // Unterbild extrahieren mit den neuen Grenzen
      img = img.getSubimage(left, top, right - left, bottom - top);

      return img;
   }

   private static int compareWithPercentage(BufferedImage template,
         BufferedImage screenshot) {

      int completepixel = template.getWidth() * template.getHeight();
      int matches = 0;
      Raster tempRaster = template.getRaster();
      Raster screenRaster = screenshot.getRaster();
      try {
         for (int y = 0; y < template.getHeight(); y++) {
            for (int x = 0; x < template.getWidth(); x++) {

               int[] temp_rgb = new int[3];
               int[] screen_rgb = new int[3];

               tempRaster.getPixel(x, y, temp_rgb);
               screenRaster.getPixel(x, y, screen_rgb);

               // Schwelle setzen
               if (temp_rgb[0] < S_W_Schwelle) {
                  temp_rgb[0] = 0;
               } else {
                  temp_rgb[0] = 15;
               }

               if (screen_rgb[0] < S_W_Schwelle) {
                  screen_rgb[0] = 0;
               } else {
                  screen_rgb[0] = 15;
               }

               // Hier stimmt was überein
               if (temp_rgb[0] == screen_rgb[0]) {
                  matches++;
               }
            }
         }
      } catch (Exception e) {
         // Wenn hier fehler auftreten ignoriere sie erstmal
         // die 2-5% differenz in unterschiedlichen
         // Bildmaßen machen hier keinen Unterschied
      }

      // gibt die prozentuale Übereinstimmung zurück
      return (100 * matches / completepixel);
   }
   
   
   public static ArrayList<Integer> calcSegments(BufferedImage image) {
	   
	   ArrayList<Integer> list = new ArrayList<Integer>();
	   Raster raster = image.getRaster();
	   boolean segmentline= true;
	   int count =0;
	   int temp =0;
	   for (int x = 0; x < image.getWidth(); x++) {
		   segmentline = true;
		  
		   for (int y = 0; y < image.getHeight(); y++) {
          
			   int[] rgb = new int[3];
        	   raster.getPixel(x, y, rgb);
        	   if (rgb[0] < S_W_Schwelle) {
        		   segmentline = false;
        	   }
        	   
        	   
           }

		   if (segmentline)  {
			  
			   if (count == 1) {
				   list.add(x);
			   }
			   count++;
		   } else {
			   count =0;
		   }
		   
	   }
	  
	  return list; 
   }
   

}
```


----------



## Guest (18. Mai 2008)

beeindruckend, 

hast du diesen ganzen java-code selber ausgedacht und programmiert?

ich hab schon ein paar progs geschrieben, aber so was komplexes sehe ich selten,


aber zum thema,

naja es geht darum bei einem pokerprogramm die karten in variabeln zu packen, genauso wie die einsätze der mitspieler,


ja ich weiss, ich habe schon von einigen gehört, pokerprogramme sind scheisse , klappen nicht richtig , usw.

aber ich habe da eine eigene idee ...

es sollen z.b. solche ziffern und buchstaben erkannt werden : 






und falls eine neue karte kommt, könnte man ja damit das programm auch weiss, nun kommt was neues, so eine art stetige aktualisierung des vergleiches mit dem bildauschnitt erzeugen.

sobald man das erkannte in variablen packen kann und man ständig die aktuellen spielinfos bekommt , denke ich komme ich allein zurecht, technisch bzw. programmiertechnisch gesehen, ist glaube ich die bilderkennung und der datenerhalt der spielinfos am schwierigsten...[/img]


----------



## dajos7 (18. Mai 2008)

Sicherlich ist das selbst progammiert! Immerhin mach ich sowas hauptberuflich und hab mit komplexen Algorithmen jeden Tag zu tun, wobei das hier eher eine Anfängerübung ist und nichtmal sauber programmiert *shame on me*.

Bildverarbeitung hab ich studiert, zumindest mal 2 Semester lang 
Und meine Diplomarbeit hat sich auch mit dem Thema recht intensiv beschäftigt (including JAVA  )

Aber wie gesagt um effektiv Zahlen zu erkennen sollte man sich mit der Bildverarbeitung näher beschäftigen. Zahlen auch zu erkennen, wenn Sie zT gedreht oder verzerrt sind wird dan nicht mehr so einfach. Man kann das dann vlt sogar mit neuronalen netzen verbinden und die Software sogar neue Zahlen lernen lassen. Aber das geht dann echt schon in die extreme Programmierung. Das dauert mehrere Monate bis da dann was brauchbares rauskommt.

Das Programm oben nimmt eben nur die Vorlagen, die man erst selbst erstellen muss. Sollte man auf die grenzen der Ziffern zuschneiden und dann als template abspeichern. da das programm das dann immer zuschneidet ist die Deckungsgleichheit zu immer 80-99,9 % gegeben. Am besten man speichert die templates in 1bit (SW-Bild) Bildern ab. definier ne schwelle und arbeitet dann auch im progamm nur mit 1bit Farbe also nur Schwarz oder weiss. War mir halt einfach zu aufwendig.

 Viel Spass damit, mal sehen was die anderen noch so an Beispielen bringen 

PS
Anstatt einen Screenshot zu machen, kannste auch direkt das fenster als Bild nehmen, dazu solltest Du das handle des fensters nehmen, und evtl am Namen identifizieren? Hab das Früher mal mit Delphi umgesetzt, wie das nun in Java geht weiss ich gar nicht, und ob das überhaupt geht 

Müsste man halt auf die Win API zugreifen, das habe ich so aber noch nicht gemacht geht vlt auch nur nativ.

PS 2
Das Bild wird nicht angezeigt ?


----------



## Illuminatus0301 (18. Mai 2008)

Man könnte das ganze aber auch ganz anders angehen: man versucht die zahlen durch Kantendetektion zu erkennen! Als erstes muss man die Kanten finde, dazu sollte sich am besten ein Canny-Filter eignen (s. Wikipedia). Im entstandenen Bild kann man jetzt alle zusammenhängenden, weißen Pixel als eine Kante ansehen, diese müsste man dann ein eine passende Datenstruktur eilesen (zu kleine kann man, wenn der Hintergrund komplizierter wird, rauslassen), und dann muss man die gefundenen Kanten mit den Werten aus der Datenbank für die Zahlen vergleichen, der Vergleich-Algorithmus ist dabei sehr komplex und ich hätte weder einen parat (_Edit: ich hab das gefunden: Wikipedia, weiß aber nicht, wie effizient und genau das ist_) noch die Zeit das mal zu machen, aber dabei ist es einfach drehungen oder verformungen auch zu erkennen (ich will hier aber niemandem raten das auszuprobieren, weil das als Thema für eine Proffesur-Arbeit passen würde, und der großteil, mir sehr wahrscheinlich eingeschlossen, gnadenlos scheitern würde!).


----------



## dajos7 (18. Mai 2008)

> Man könnte das ganze aber auch ganz anders angehen: man versucht die zahlen durch Kantendetektion zu erkennen! Als erstes muss man die Kanten finde, dazu sollte sich am besten ein Canny-Filter eignen (s. Wikipedia). Im entstandenen Bild kann man jetzt alle zusammenhängenden, weißen Pixel als eine Kante ansehen, diese müsste man dann ein eine passende Datenstruktur eilesen (zu kleine kann man, wenn der Hintergrund komplizierter wird, rauslassen), und dann muss man die gefundenen Kanten mit den Werten aus der Datenbank für die Zahlen vergleichen, der Vergleich-Algorithmus ist dabei sehr komplex und ich hätte weder einen parat (Edit: ich hab das gefunden: Wikipedia, weiß aber nicht, wie effizient und genau das ist) noch die Zeit das mal zu machen, aber dabei ist es einfach drehungen oder verformungen auch zu erkennen (ich will hier aber niemandem raten das auszuprobieren, weil das als Thema für eine Proffesur-Arbeit passen würde, und der großteil, mir sehr wahrscheinlich eingeschlossen, gnadenlos scheitern würde!).



Ja, im Endeffekt muss man immer das gefundene auf Standard-erkennungsmerkmale zurückführen um es dann zu vergleichen. Bei biometrischen Daten verwendet man zB Vektoren, da lässt sich auch bei verzerrten und ge- und verdrehten Eingaben recht gut ein Vergleich anstellen. Aber das Thema ist wirklich wissenschaftlich in alle Richtungen ausreizbar, weil es eben sehr viele Bereiche überschneidet. 

Bei der Skelettierung macht man im Prinzip auch nichts anderes als Kanten erkennen, allerdings zieht man die Kanten quasi zu einem Mittelwert zwischen den äusseren Grenzen des Objekts zusammen und erhält eine Linie. Diese Line kann man mit Vektoren bestücken und dann ähnlich wie bei den biometrischen Daten (Fingerabdruck) einordnen und auch hier wieder mit wahrscheinlicher Übereinstimmung zuordnen. Zu 100% genau eine Zahl mit einem Progamm erkennen ist schwer. Unser Gehrin macht das glaube ich auch ähnlich. Es erkennt das komplexe Muster und vergleicht es mit bekannten Mustern (Neuronale Netze). Dabei lernt es das neue Muster, wenn es identifiziert wurde.

zB Fingerbilderkennung

Ich wette mit etwas längerer Betrachtung kannste das Hildebrandslied lesen


----------



## antiranker (17. Nov 2008)

hehe^^
lesen schon.. verstehen ... NOT


----------

