Parse String aus Image

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
da.dom
User
Beiträge: 114
Registriert: Dienstag 10. Juni 2008, 14:42

Hallo Zusammen,

gibt es eine Möglichkeit (lib / generelles Vorgehen) um aus einem Bild ein Text zu extrahieren? Es geht hier nicht um irgendwelche unkenntlichen gemachten Texte (Botschutz etc.) Geht um mehrer Klarschrift Passagen die aus einem Bild extrahiert werden sollen (Position der Texte ist immer gleich)

Danke schon mal für Ideen und Anregungen
Dom
Benutzeravatar
helduel
User
Beiträge: 300
Registriert: Montag 23. Juli 2007, 14:05
Wohnort: Laupheim

Moin,

kurzes googeln ergab: http://code.google.com/p/pytesser/

Kannst ja mal schauen, ob dir das hilft.

Gruß,
Manuel
da.dom
User
Beiträge: 114
Registriert: Dienstag 10. Juni 2008, 14:42

Hey, das sieht ja super aus, *kopfkratz* hab ich beim Google-Durchforsten scheinbar nicht gesehen/übersehen. Werd das ganze mal heute Abend Testen und sehen wie er mit Texten in Bildern klar kommt.

Dank Dir schon mal bis hierher
D
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Das Verfahren nennt sich uebrigens "OCR" (damit du ein Stichwort fuers Suchen hast).
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
lunar

helduel hat geschrieben:kurzes googeln ergab: http://code.google.com/p/pytesser/
Von diesem Modul möchte ich abraten. Es ist ziemlich mies programmiert. Allerdings ist es auch nicht unverzichtbar, im Gegenteil: Es tut nicht mehr als Tesseract in einem Unterprozess aufzurufen. Das kann man auch in einer Viertelstunde selbst implementieren ...
da.dom
User
Beiträge: 114
Registriert: Dienstag 10. Juni 2008, 14:42

Die Lib ist erstmal sehr übersichtlich, die Programmierleistung die dahinter steht will ich mal nicht bewerten (15minuten wird bei mir wohl nicht reichen um das nach zu programmieren ;) )

Leider ist das Tool nicht besonders effizient wenn es um "unsaubere" Textvorlagen geht. Mein Problem besteht darin das der Text auf einem Hintergrundbild liegt und die Lib scheint das nicht besonders gut zu finden.

(achtung ich drifte thematisch etwas ab)
Jetzt wollte ich das Bild so vorbereiten das die Lib es vielleicht sauberer Verarbeiten kann. PIL : Hab die Textpassagen ausgeschnitten. Jetzt würde ich gerne ein schwarz-weiss Bild daraus machen, indem ich eine Farbe definiere die weiss sein soll, alles andere soll schwarz werden (oder umgekert) die Textfarbe ist: 180,207,234

Ich hab die PIL Lib mir mal etwas genauer angesehen und die "convert" methode gefunden die scheinbar so was macht. Leider komme ich nicht ganz dahinter wie sie funktioniert
im.convert(mode, matrix) => image

Converts an "RGB" image to "L" or "RGB" using a conversion matrix. The matrix is a 4- or 16-tuple.
Leider verstehe ich die matrix nicht so ganz, wie ich die farbe definiere, die in welche Farbe umgewandelt werden soll....oder bin ich da generell auf dem Holzweg :) ?

Danke schon mal
Dom
da.dom
User
Beiträge: 114
Registriert: Dienstag 10. Juni 2008, 14:42

ok vielleicht bin ich mit der Idee ja auch auf dem Holzweg gewesen, hab es jetzt mal zu Fuss gemacht...: (Verbesserungsvorschläge, alterantiv Lösungen, elegantere Ideen sind natürlich trotzdem gern gesehen (toll das reimt sich :) )

Code: Alles auswählen

from pytesser import *

IMAGE='einBild.jpg'
MATCH_COLOR=(180,207,234)

def filterColor(pixel,color,rangeset=90):
    if pixel[0] in range(color[0]-rangeset,color[0]+rangeset):
        if pixel[0] in range(color[1]-rangeset,color[1]+rangeset):
            if pixel[0] in range(color[2]-rangeset,color[2]+rangeset):
                return True

    return False



image = Image.open(IMAGE)
pixel=image.load();
w,h = image.size
for x in range(w):
    for y in range(h):
        match=filterColor(pixel[x,y],MATCH_COLOR)
        if match:
            pixel[x,y]=(255,255,255)
        else:
            pixel[x,y]=(0,0,0)
image.show()
Werd heute Abend mal testen ob pytesser mit einem solch optimierten Bild besser klar kommt.

Grüße
D
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Sicher, dass du in filterColor (was besser filter_color heißen sollte) nicht pixel[0], pixel[1] und pixel[2] meinst und nicht dreimal pixel[0]?

Code: Alles auswählen

def filter_color(pixel, color, rangeset=90):
    return any(-rangeset <= pixel[i]-color[i] < rangeset for i in range(3))
oder nicht ganz äquivalent:

Code: Alles auswählen

def filter_color(pixel, color, rangeset=90):
    return any(abs(pixel[i]-color[i]) < rangeset for i in range(3))

Üblich wäre aber wohl eher gegen die Helligkeit des Pixels zu testen: also den arithmetischen Mittelwert der RGB-Kanäle bilden und Prüfen, ob dieser einen bestimmten Wert überschreitet.

Edit: und natürlich sind *-Importe böse!
Das Leben ist wie ein Tennisball.
da.dom
User
Beiträge: 114
Registriert: Dienstag 10. Juni 2008, 14:42

EyDu hat geschrieben:Sicher, dass du in filterColor nicht pixel[0], pixel[1] und pixel[2] meinst und nicht dreimal pixel[0]?
Na klar :) war mir auch aufgefallen

Code: Alles auswählen

def filter_color(pixel, color, rangeset=90):
    return any(-rangeset <= pixel[i]-color[i] < rangeset for i in range(3))
*schnauf* ich weiss ja das ich Anfänger bin in Python, aber manchmal zweifel ich selbst an meinen Grundlagen-Kenntnissen :( Kann mir das Statement mal jemand erklären was welches Zeichen da bewirkt? any erwartet ein Iterierbares Objekt, aber was macht den Ausdruck da zu einem eben solchen? das "-" und "<=" "<" sagt mit so auf anhieb in der Kombination nichts :(
EyDu hat geschrieben: Edit: und natürlich sind *-Importe böse!
Versuche mich mal daran zu halte, leider weiss ich nie was ich denn genau brauche :)

Danke (mal wieder) für die guten Hilfestellungen !!!
D
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

da.dom hat geschrieben:*schnauf* ich weiss ja das ich Anfänger bin in Python, aber manchmal zweifel ich selbst an meinen Grundlagen-Kenntnissen :( Kann mir das Statement mal jemand erklären was welches Zeichen da bewirkt?
Das ist ein any(...) und innendrin eine Generator Expression (stell dir da noch ein ()-Paar oder ein []-Paar drumrum vor), die den Bereich prüft.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

da.dom hat geschrieben:Versuche mich mal daran zu halte, leider weiss ich nie was ich denn genau brauche :)
Und genau deshalb solltest du die auch meiden, denn dann weisst du auch nie, was du gerade überschreibst ;)
BlackJack

Das `any()` sollte wohl eher ein `all()` sein, denn es sollen ja alle Komponenten ähnlich sein und nicht nur mindestens eine.

Mit den x/y-Kordinaten würde ich mich nicht weiter aufhalten, die sind ja nicht wichtig für die Umwandlung.

Code: Alles auswählen

from functools import partial
from PIL import Image


def color_test(color, pixel, threshold=90):
    return all(abs(a - b) < threshold for a, b in zip(color, pixel))


def main():
    image_filename = 'test.jpg'
    match_color = (180, 207, 234)
    source_image = Image.open(image_filename)
    target_image = Image.new('1', source_image.size)
    target_image.putdata(map(partial(color_test, match_color),
                             source_image.getdata()))
    target_image.save('test.pbm')


if __name__ == "__main__":
    main()
da.dom
User
Beiträge: 114
Registriert: Dienstag 10. Juni 2008, 14:42

Das wird ja fast kompliziert :) Schaue mir die geposteten Codes nachher noch mla genauer an, will ja was lernen :D Aber ich habe mal mein kleines TestBild durch die OCR Lib gejagt, mit meinem Coding, leider mit keinem zufriedenstellenden Ergebnis. Für meine Augen ist das Bild jetzt relativ gut ausgearbeitet, aber trotzdem liefert mir die LIB keine treffer. Hab das Bild mal angehängt, eigentlich sollte man so was doch parsen können, oder erwarte ich da zu viel?

Bild

Grüße
Dom
BlackJack

Wird es besser, wenn Du das Bild invertierst? Normaler wäre ja schwarzer Text auf weissem Untergrund.
da.dom
User
Beiträge: 114
Registriert: Dienstag 10. Juni 2008, 14:42

mh leider nein... er erkennt gar nichts. Die Beispielbilder die dabei sind, sind natürlich super klare Schriften. Kann man mit PIL noch was an der Bildschärfe vielleicht was machen ?

****

Hab das mit PIL mal gemacht, aber da gibt es nicht mehr viel dran zu drehen scheinbar. Das Bild ist, wie gesagt, ja meiner Meinung nach schon relativ deutlich :(

Jemand noch gute Ideen?
BlackJack

@da.dom: Also `gocr` erkennt das halbwegs wenn man's invertiert:

Code: Alles auswählen

bj@s8n:~$ pngtopnm xxsw.png | pnminvert | gocr -
6      1O
Die 0 (Null) ist als O (Oooh) erkannt worden, aber das ist ja auch wirklich nicht gut zu unterscheiden.
da.dom
User
Beiträge: 114
Registriert: Dienstag 10. Juni 2008, 14:42

Bin für jede funktionierende Alternative offen. Erklärst du mir auch wie ich das ganze in meinen Python Code einbinde? Stehe da gerade irgendwie auf dem Schlauch. Hab danach gegooglelt und das Archiv runter geladen....leider verstehe ich gerade nicht wie ich das ganze in Python anspreche :)
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

mit subprocess
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

derdon hat geschrieben:mit subprocess
Hint: Forensuche.
Hint: Dokumentation.
Hint: Wiki.

Damit sollte es einfach sein. Jetzt nocht ein brauchbares OCR aussuchen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten