Alles sehr interessant für mich als "Grafik-Neuling" was man mit so wenig code hinbekommen kann...
Bild
verarbeitung heißt das Stichwort, nicht Grafik...
Ich machs mal etwas detailierter. Vielleicht interessiert es ja den ein oder anderen.
Fangen wir mal von vorn an.
Wir brauchen einen Kanal, d.h. einfach nur ein Graustufen-Bild weil die nachfolgenden Schritte es so brauchen. Ich habe einfach den roten Kanal genommen. Das ist natürlich schlecht weil so z.B. keine rote Schrift auf weißem Grund oder blaue Schrift auf schwarzem Grund gefunden werden kann. Besser wäre der Mittelwert über alle Kanäle gewesen. Oder etwas richtig ausgefuchstes... Den Aufwand hab ich mir erspart.
Nun kommt der wichtigste Schritt der ganzen Verarbeitung. Die grundsätzlich Frage ist ja: wie kann ich Text erkennen? Man könnte versuchen die Schriftzeichen direkt auswändig zu lernen und diese dann im Bild suchen. Das wird nicht gut funktionieren (jedenfalls nicht ohne großen Aufwand), da man sehr viele Zeichen für sehr viele Schriftarten lernen muss. Außerdem werden von PC zu PC unterschiedliche Kantenglättungen (insb. verschiedene Stufen Win7 Cleartype) das Ergebnis stören. Also braucht man was generisches. Dazu muss man sich fragen was die Regionen mit Schrift von dem Rest des Bildes? Ein entscheidendes Kriterium ist das Schrift (egal welche Sprache) aus Linien besteht. Der Ansatz ist also: Finde Regionen im Bild wo besonders viele Linien sind. Da ist vmtl. Text.
Linien finden geschieht im nächsten Schritt. Linien direkt im Bild zu finden ist sehr schwer. Deswegen benutze ich folgenden Trick: Ich versuche alle Linien verschwinden zu lassen und bilde das Differenzbild zum Original. Verschwinden lassen funktioniert mit dem Medianfilter.
Median:
Differenzbild:
Man sieht deutlich das die Regionen mit vielen Linien im Bild hervorgehoben sind.
Nun müssen die Regionen nur noch gefunden werden. Zuerst wird ein Schwellenwert t gesetzt. D.h. alle Pixel im Bild größer t werden 1 der Rest 0. Dadurch werden sehr kontrastarme Linien heraus gefiltert und es ist einfacher Regionen voneinander abzugrenzen.
Binarisierung:
Nun müssen die Regionen im Bild, die einzeln stehen aber zusammenwachsen sollen (Buchstaben), vereint werden. Das geschieht durch die Dilation. Such mal im Netz danach. Im Grunde wachsen die Vordergrund-Regionen im Bild. Allerdings nur horizontal da der Filterkern eine horizontale Linie ist.
Dilation:
Nun kommt das Labeling. Momentan sind zwar einige Regionen im Bild hervorgehoben, jedoch noch nicht einzeln identifiziert. Das Bild sieht also in etwa so aus:
Wir brauchen aber so was:
D.h. zusammenhängende Regionen im Bild sollen eine eindeutige ID bekommen damit man sie einzeln ansprechen kann.
Das Verfahren nennt sich Connected Component Labeling (eine Farbe = ein Segment):
Mit der Funktion
find_objects werden die Regionen im Bild dann als slices zurückgegeben. Diese Segmente filtere ich dann nochmals und schmeiß die Regionen raus die garantiert keinen Text enthalten. Z.B. riesige Regionen oder Regionen die eine Höhe kleiner 16 haben (Text auf Screenshots ist meist größer).
Der Rest ist nur noch einzeichnen der Regionen ins Bild.
Und so kann man ganz einfach Text in einem Screenshot finden
MFG HerrHagen