Ich habe versucht, Bilder für OCR zu löschen: (die Linien)
Ich muss diese Zeilen entfernen, um das Bild manchmal weiter zu verarbeiten, und ich komme mir ziemlich nahe, aber die meiste Zeit nimmt der Schwellenwert zu viel vom Text weg:
copy = img.copy()
blur = cv2.GaussianBlur(copy, (9,9), 0)
thresh = cv2.adaptiveThreshold(blur,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV,11,30)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9,9))
dilate = cv2.dilate(thresh, kernel, iterations=2)
cnts = cv2.findContours(dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
area = cv2.contourArea(c)
if area > 300:
x,y,w,h = cv2.boundingRect(c)
cv2.rectangle(copy, (x, y), (x + w, y + h), (36,255,12), 3)
Bearbeiten: Außerdem funktioniert die Verwendung konstanter Zahlen nicht, falls sich die Schriftart ändert. Gibt es eine generische Möglichkeit, dies zu tun?
Antworten:
Hier ist eine Idee. Wir unterteilen dieses Problem in mehrere Schritte:
Bestimmen Sie die durchschnittliche rechteckige Konturfläche. Wir schwellen dann Konturen und filtern anhand des begrenzenden Rechteckbereichs der Kontur. Der Grund, warum wir dies tun, ist die Beobachtung, dass jedes typische Zeichen nur so groß ist, während großes Rauschen einen größeren rechteckigen Bereich überspannt. Wir bestimmen dann die durchschnittliche Fläche.
Entfernen Sie große Ausreißerkonturen. Wir durchlaufen die Konturen erneut und entfernen die großen Konturen, wenn sie
5x
größer als die durchschnittliche Konturfläche sind, indem wir die Kontur ausfüllen. Anstatt einen festen Schwellenwertbereich zu verwenden, verwenden wir diesen dynamischen Schwellenwert für mehr Robustheit.Erweitern Sie mit einem vertikalen Kernel, um Zeichen zu verbinden . Die Idee ist, die Beobachtung zu nutzen, dass Zeichen in Spalten ausgerichtet sind. Durch die Erweiterung mit einem vertikalen Kernel verbinden wir den Text miteinander, sodass in dieser kombinierten Kontur kein Rauschen enthalten ist.
Entfernen Sie kleine Geräusche . Nachdem der zu behaltende Text verbunden ist, finden wir Konturen und entfernen alle Konturen, die kleiner als
4x
die durchschnittliche Konturfläche sind.Bitweise - und um das Bild zu rekonstruieren . Da wir nur gewünschte Konturen haben, um auf unserer Maske zu bleiben, arbeiten wir bitweise - und um den Text zu erhalten und unser Ergebnis zu erhalten.
Hier ist eine Visualisierung des Prozesses:
Wir Otsus Schwelle , um ein Binärbild zu erhalten, finden dann Konturen , um die durchschnittliche rechteckige Konturfläche zu bestimmen. Von hier aus entfernen wir die großen grün hervorgehobenen Ausreißerkonturen durch Füllen von Konturen
Als nächstes konstruieren wir einen vertikalen Kernel und erweitern ihn , um die Charaktere zu verbinden. Dieser Schritt verbindet den gesamten gewünschten Text, um das Rauschen beizubehalten, und isoliert es in einzelne Blobs.
Jetzt finden wir Konturen und filtern mithilfe des Konturbereichs , um das kleine Rauschen zu entfernen
Hier sind alle entfernten Rauschpartikel grün hervorgehoben
Ergebnis
Code
Hinweis: Die herkömmliche Bildverarbeitung beschränkt sich auf Schwellenwerte, morphologische Operationen und Konturfilterung (Konturnäherung, Fläche, Seitenverhältnis oder Blob-Erkennung). Da die Eingabebilder je nach Größe des Zeichentextes variieren können, ist es ziemlich schwierig, eine singuläre Lösung zu finden. Vielleicht möchten Sie Ihren eigenen Klassifikator mit maschinellem / tiefem Lernen für eine dynamische Lösung trainieren.
quelle