[OCR]Captcha Erkennung verbessern

10/05/2014 14:21 D3luxe.#1
Hey Leute,

ich muss für einen Account Creator CAPTCHAs knacken.

Ein Captcha sieht im Original so aus: [Only registered and activated users can see links. Click Here To Register...]
Nachdem BG & Striche entfernt wurden: [Only registered and activated users can see links. Click Here To Register...]

Danach lasse ich (im Moment noch) Tesseract 3 drüber laufen.
Tesseract erkennt ein Captcha im Schnitt aber erst nach 6.72 Versuchen richtig, was einer Erkennungsrate von 15% entspricht.

Jetzt zu meiner Frage: Macht es Sinn, die Erkennungsrate noch weiter zu erhöhen? Wenn ja, wie?

Hier wird zum Beispiel erklärt, wie sich das Ganze mit einem neuronalen Netzwerk lösen lässt: [Only registered and activated users can see links. Click Here To Register...]
Was in meinem Fall aber das Problem aufwirft, dass die Buchstaben teilweise rotiert sind oder sich überlappen und somit evt. nicht richtig erkannt werden.
Würde sich die Arbeit trotzdem lohnen?

Hier lassen sich unendlich viele Captchas bekommen: [Only registered and activated users can see links. Click Here To Register...]
10/05/2014 14:48 Shadow992#2
Quote:
Originally Posted by D3luxe. View Post
Hey Leute,

ich muss für einen Account Creator CAPTCHAs knacken.

Ein Captcha sieht im Original so aus: [Only registered and activated users can see links. Click Here To Register...]
Nachdem BG & Striche entfernt wurden: [Only registered and activated users can see links. Click Here To Register...]

Danach lasse ich (im Moment noch) Tesseract 3 drüber laufen.
Tesseract erkennt ein Captcha im Schnitt aber erst nach 6.72 Versuchen richtig, was einer Erkennungsrate von 15% entspricht.

Jetzt zu meiner Frage: Macht es Sinn, die Erkennungsrate noch weiter zu erhöhen? Wenn ja, wie?

Hier wird zum Beispiel erklärt, wie sich das Ganze mit einem neuronalen Netzwerk lösen lässt: [Only registered and activated users can see links. Click Here To Register...]
Was in meinem Fall aber das Problem aufwirft, dass die Buchstaben teilweise rotiert sind oder sich überlappen und somit evt. nicht richtig erkannt werden.
Würde sich die Arbeit trotzdem lohnen?

Hier lassen sich unendlich viele Captchas bekommen: [Only registered and activated users can see links. Click Here To Register...]
Derartig geringe Rotation stört Neuronale Netze normalerweise nicht. Ich würde diaber trotzdem mehr preprocessing empfehlen:

1. "Verdünner" die Linien, schneid unnötiges "Geschnörksel" wie z.B. beim C den Strich ab. Mach bei der 7 unten den "Punkt" weg.
2. Verbinde die Buchstaben wieder zu einem ganzen Buchstaben, das dürfte relativ leicht sein und das Ergebnis sollte sich enorm verbessern.
3. Versuche die Rotation rückgängig zu machen, das ist auch nicht überaus schwer, zwar nicht trivial, aber machbar.

Wenn das alles nicht hilft, kannst du immernoch ein eigenes Neuronales Netz ansetzen. Wenn du davon aber wenig Ahnung hast, wird selbst das Trainieren solcher Netze kniffelig, würde mich also an deiner Stelle an der Vorverarbeitung halten. Wenn das Ergebnis, dann trotzdem ausbleibt, kannste immer noch ein eigenes Netz machen, in welchem du dann deine Vorvearbeitung mit einfließen lassen kannst.
10/05/2014 19:02 D3luxe.#3
Quote:
Originally Posted by Shadow992 View Post
1. "Verdünner" die Linien, schneid unnötiges "Geschnörksel" wie z.B. beim C den Strich ab. Mach bei der 7 unten den "Punkt" weg.
2. Verbinde die Buchstaben wieder zu einem ganzen Buchstaben, das dürfte relativ leicht sein und das Ergebnis sollte sich enorm verbessern.
3. Versuche die Rotation rückgängig zu machen, das ist auch nicht überaus schwer, zwar nicht trivial, aber machbar.
Danke erstmal für die Antwort :)

Ich fürchte, dass es ziemlich schwierig wird, die Serifen [= Geschnörksel] einfach so abzuschneiden. Wie willst du festlegen, was eine Serife und was z.B. ein dünner Strich vom U oder Z etc. ist.

Was ich aber tatsächlich mal probieren muss, ist die Buchstaben wieder zusammen zu flicken.
Habe mir das so gedacht, dass ich ne Liste mache mit allen Pixeln, die vorher mal ein Strich waren und dann einen Radius von x Pixeln auf die Farbe schwarz überprüfe.

Und wie man Grafiken in C# rotiert, habe ich mir tatsächlich mal angesehen, die Frage ist dann nur, wie man feststellen kann, dass der Buchstabe gerade ist...
10/05/2014 19:20 Shadow992#4
Quote:
Originally Posted by D3luxe. View Post
Danke erstmal für die Antwort :)

Ich fürchte, dass es ziemlich schwierig wird, die Serifen [= Geschnörksel] einfach so abzuschneiden. Wie willst du festlegen, was eine Serife und was z.B. ein dünner Strich vom U oder Z etc. ist.

Was ich aber tatsächlich mal probieren muss, ist die Buchstaben wieder zusammen zu flicken.
Habe mir das so gedacht, dass ich ne Liste mache mit allen Pixeln, die vorher mal ein Strich waren und dann einen Radius von x Pixeln auf die Farbe schwarz überprüfe.

Und wie man Grafiken in C# rotiert, habe ich mir tatsächlich mal angesehen, die Frage ist dann nur, wie man feststellen kann, dass der Buchstabe gerade ist...
Ist eine einfache Möglichkeit, jo.

@Rotieren
Naja ich würde da ohne groß Nachzudenken den Ansatz nehmen, den man auch hat, wenn man die Aufgabe per Hand lösen soll, wie machst du es denn da?

Ganz einfach du nimmst ein Lineal und drehst den ausgeschnittenen Buchstaben solange bis kein Punkt mehr über das Lineal hinaus schaut, aber möglichst viele Punkte das Lineal berühren. Dabei darf man natürlich nicht mehr als 45° o.ä. drehen.

Damit ist der Buchstabe zwar nicht immer perfekt ausgerichtet (z.B. wäre das C ein schlechter Kandidat) aber Buchstaben wie "E", "F", usw. werden damit einwandfrei ausgerichtet.

Wenn man zusätzlich noch hinzu nimmt, dass ein Buchstabe nie breiter als X-Pixel sein darf (wird ja durch die Schriftart bestimmt), dann richtet man seine Buchstaben auch nie falsch aus.

@Verdünnern/Abschneiden
Nach ein paar Überlegungen erscheint mir das Prozedere sogar relativ leicht. Du musst einfach nur den Buchstaben in einen "Graphen" übertragen. Dabei sollte man mit folgendem Algorithmus sehr weit kommen:

Man fängt oben links an zu suchen, dann geht man Reihe für Reihe durch. Sobald man einen schwarzen Pixel gefunden hat, beginnt man mit dem eigentlichen Algorithmus.

Man zerlegt den Buchstaben jetzt in Linien mit gleich großen Längen. Die Länge könnte z.B. 5 Pixel betragen. Das heißt nach jedem 5. Pixel beginnt ein neuer Punkt/Knoten im Graphen.

Man läuft also sozusagen den Buchstaben ab und legt alle 5 Pixel eine Marke ab. Diese Marken werden dann am Ende verbunden und voila man hat einen Buchstaben mit einer Breite von 1px (oder mehr je nachdem wie breit man die Linien eben macht).

Anschließend kann man Linien zwischen denen nur ein sehr kleiner Winkel herrscht zu einer großen Linie zusammenfassen.

Damit könnte man dann sogar direkt ein selbst programmiertes Neuronales Netz trainieren. Würde auf jeden Fall auch sehr gute Ergebnisse liefern.

Edit:
Wenn du das Rotieren sogar mit 2 gedachten Linealen machst, kann man sogar so Buchstaben wie "C" ausrichten.
10/05/2014 21:09 D3luxe.#5
Habe mir mal schnell ein kleines Testprogramm geschrieben, das automatisch immer wieder Captchas runterlädt und versucht, sie mit Tesseract zu knacken.

Die Lösung mit dem Radius funktioniert halbwegs, nachdem ich durch ein bisschen ausprobieren die richtigen Werte (für Radius, Durchläufe und benötigte Treffer) raus hatte, werden schon einige Buchstaben wieder zusammen geflickt.

Das hilft tatsächlich bei ca. 1 von 7 Captchas, um an den richtigen Code zu kommen (ich lasse Tess. vor und nach dem flicken drüber laufen).

So wird aus [Only registered and activated users can see links. Click Here To Register...]

Die Buchstabenteile sind also noch nicht komplett miteinander verbunden, aber es ist schon mal ein Anfang.
Das Problem ist im Moment, dass sobald man versucht, noch mehr wiederherzustellen, auch schnell zu viel dazu gegeben wird und man Striche quer über die Buchstaben hat.

Ich werde bei Gelegenheit mal das Testprojekt hochladen, wer Zeit & Lust hat zu helfen, kann das gerne tun.

@shadow: Ich verstehe den Ansatz, aber noch nicht genau, wie du dir die Umsetzung vorstellst :/
Buchstaben zu Graph / bzw. den Buchstaben auf eine 'Linienbreite' reduzieren...?

Das Netz scheint mir immer noch eine Nummer zu groß, ich stelle mir die Umsetzung sehr schwierig vor...

Edit:
Quote:
Wenn du das Rotieren sogar mit 2 gedachten Linealen machst, kann man sogar so Buchstaben wie "C" ausrichten.
Genial!
10/06/2014 13:19 Shadow992#6
Quote:
Originally Posted by D3luxe. View Post
Habe mir mal schnell ein kleines Testprogramm geschrieben, das automatisch immer wieder Captchas runterlädt und versucht, sie mit Tesseract zu knacken.

Die Lösung mit dem Radius funktioniert halbwegs, nachdem ich durch ein bisschen ausprobieren die richtigen Werte (für Radius, Durchläufe und benötigte Treffer) raus hatte, werden schon einige Buchstaben wieder zusammen geflickt.

Das hilft tatsächlich bei ca. 1 von 7 Captchas, um an den richtigen Code zu kommen (ich lasse Tess. vor und nach dem flicken drüber laufen).

So wird aus [Only registered and activated users can see links. Click Here To Register...]

Die Buchstabenteile sind also noch nicht komplett miteinander verbunden, aber es ist schon mal ein Anfang.
Das Problem ist im Moment, dass sobald man versucht, noch mehr wiederherzustellen, auch schnell zu viel dazu gegeben wird und man Striche quer über die Buchstaben hat.

Ich werde bei Gelegenheit mal das Testprojekt hochladen, wer Zeit & Lust hat zu helfen, kann das gerne tun.

@shadow: Ich verstehe den Ansatz, aber noch nicht genau, wie du dir die Umsetzung vorstellst :/
Buchstaben zu Graph / bzw. den Buchstaben auf eine 'Linienbreite' reduzieren...?

Das Netz scheint mir immer noch eine Nummer zu groß, ich stelle mir die Umsetzung sehr schwierig vor...

Edit:

Genial!
@Buchstaben reparieren
Gib jedem Buchstaben seinen eigenen "Bereich". Die Bereiche kannst du in etwa so feststellen:
Wenn sich die Buchstaben nie überlappen (also zumindest nicht viel), dann ist das ganze sehr einfach:
Geh das Bild durch und mach immer einen Bereich, wenn eine Spalte (also eine Pixel-Spalte) keinen einzigen schwarzen Pixel enthält. Sobald der Radius für das Zusammenfügen darüber hinaus "färben" will, dann lässt du es einfach nicht zu. Die Methode geht auch in abgewandelter Form, wenn sich die Buchstaben nur leicht überlappen. Der Bereich beginnt/hört auf, wo höchstens eine bestimmte Pixel-Zahl X in der Spalte vorkommt.

Sollten sich die Buchstaben sehr stark überlappen, musst du zusätzlich auch die Farbe der Buchstaben für die Bereichsaufteilung mit einbeziehen.

@Verdünnern
Du fängst an erst einmal einen schwarzen Pixel zu finden. Gehen wir davon aus, dass dieser Pixel beim "C" der höchste Punkt ist also ganz oben an der Rundung. Jetzt versuchen wir möglichst mittig durchs "C" durchzulaufen, wir gehen also zuerst 1px nach rechts, schauen ob hier ein weißer Pixel ist, wenn dort ein weißer Pixel ist, gehen wir wieder zurück. Jetzt gehen wir einen Pixel nach links, ist dieser Pixel ebenfalls weiß, gehen wir 1px nach oben, auch dieser Pixel ist beim "C" weiß. Also schauen wir uns einen Pixel unten drunter an. Dieser Pixel ist schwarz, also gehen wir weiter Pixel runter, bis sie weiß werden. Anschließend setzen wir genau in der Mitte von diesen Pixel (also bei der Hälfte der schwarzen Pixel) eine Marke hin. Jetzt machen wir von unserem gefundenen Pixel aus weiter, schauen wieder alle Pixel an und gehen in die Richtung wo wir schwarze Pixel finden, wobei wir wieder die Mitte suchen und dort einen Marker hinsetzen.

@Verdünner die Zweite
Gibt sogar noch eine viel einfachere Methode, man unterteilt das Bild einfach in X 2x2, 3x3 oder 4x4 Pixel und sagt dann: "Wenn mehr als die Hälfte der Pixel schwarz ist in unseren neuen 2x2,3x3 ... Pixeln, dann wird an dieser Stelle in einem neuem Bild ein Pixel hingesetzt."

Ist zwar nicht ganz so effektiv wie Methode 1 aber viel leichter umzusetzen und vorallem schneller.

Edit:
Du kannst dir auch einmal Erosion, Dilatation und die Kombination von beidem in der Bildverarbeitung ansehen für das Füllen von Löchern. ;)

Edit2:
Für das Verdünnern, kannst du dir auch einmal die "Skelettierung / Medial axis" in der Bildverarbeitung ansehen.
Siehe auch: http://de.wikipedia.org/wiki/Skelett...erarbeitung%29
10/08/2014 19:37 VisionEP1#7
Ich habe auch schon Captcha Solver Programmiert auf beide Arten.
Für die LoL Seite reicht folgendes Prinzip:

1. Hintergrund und Störlinien entfernen
(einfach tabelle mit farbhäufung)
2. trennen in einzelne chars
3. mit beispieldaten pixelweise vergleichen.

Für mein Allgemeines Captcha Solving Netz hab ich nen feed forward 3 Schichtig mit Rprop genommen, und ein zweites Netz,welches mir den Auschnitt liefert.

Allgemein:
Mach viel vorher das spart den trainingsaufwand