Ich habe ein Diagramm mit mehreren Bildern, die alle Beschriftungen als alphanumerische Zeichen anstelle der Textbeschriftung selbst enthalten. Ich möchte, dass mein YOLO-Modell alle darin enthaltenen Zahlen und alphanumerischen Zeichen identifiziert.
Wie kann ich mein YOLO-Modell trainieren, um dasselbe zu tun? Den Datensatz finden Sie hier. https://drive.google.com/open?id=1iEkGcreFaBIJqUdAADDXJbUrSj99bvoi
Zum Beispiel: siehe die Begrenzungsrahmen. Ich möchte, dass YOLO erkennt, wo immer der Text vorhanden ist. Derzeit ist es jedoch nicht erforderlich, den darin enthaltenen Text zu identifizieren.
Dasselbe muss auch für diese Art von Bildern getan werden
Die Bilder können hier heruntergeladen werden
Dies ist, was ich versucht habe, opencv zu verwenden, aber es funktioniert nicht für alle Bilder im Datensatz.
import cv2
import numpy as np
import pytesseract
pytesseract.pytesseract.tesseract_cmd = r"C:\Users\HPO2KOR\AppData\Local\Tesseract-OCR\tesseract.exe"
image = cv2.imread(r'C:\Users\HPO2KOR\Desktop\Work\venv\Patent\PARTICULATE DETECTOR\PD4.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
clean = thresh.copy()
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (15,1))
detect_horizontal = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, horizontal_kernel, iterations=2)
cnts = cv2.findContours(detect_horizontal, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
cv2.drawContours(clean, [c], -1, 0, 3)
vertical_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1,30))
detect_vertical = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, vertical_kernel, iterations=2)
cnts = cv2.findContours(detect_vertical, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
cv2.drawContours(clean, [c], -1, 0, 3)
cnts = cv2.findContours(clean, 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 < 100:
cv2.drawContours(clean, [c], -1, 0, 3)
elif area > 1000:
cv2.drawContours(clean, [c], -1, 0, -1)
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.02 * peri, True)
x,y,w,h = cv2.boundingRect(c)
if len(approx) == 4:
cv2.rectangle(clean, (x, y), (x + w, y + h), 0, -1)
open_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (2,2))
opening = cv2.morphologyEx(clean, cv2.MORPH_OPEN, open_kernel, iterations=2)
close_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,2))
close = cv2.morphologyEx(opening, cv2.MORPH_CLOSE, close_kernel, iterations=4)
cnts = cv2.findContours(close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
x,y,w,h = cv2.boundingRect(c)
area = cv2.contourArea(c)
if area > 500:
ROI = image[y:y+h, x:x+w]
ROI = cv2.GaussianBlur(ROI, (3,3), 0)
data = pytesseract.image_to_string(ROI, lang='eng',config='--psm 6')
if data.isalnum():
cv2.rectangle(image, (x, y), (x + w, y + h), (36,255,12), 2)
print(data)
cv2.imwrite('image.png', image)
cv2.imwrite('clean.png', clean)
cv2.imwrite('close.png', close)
cv2.imwrite('opening.png', opening)
cv2.waitKey()
Gibt es ein Modell oder eine OpenCV-Technik oder ein vorab trainiertes Modell, das dasselbe für mich tun kann? Ich brauche nur die Begrenzungsrahmen um alle alphanumerischen Zeichen in den Bildern. Danach muss ich identifizieren, was darin vorhanden ist. Der zweite Teil ist derzeit jedoch nicht wichtig.
quelle
Antworten:
Ein möglicher Ansatz ist die Verwendung des Deep-Learning-Textdetektors EAST (Efficient and Accurate Scene Text), der auf dem 2017 erschienenen Artikel EAST: A Efficient and Accurate Scene Text Detector von Zhou et al. Basiert . Das Modell wurde ursprünglich für die Erkennung von Text in natürlichen Szenenbildern trainiert, kann jedoch möglicherweise auf Diagrammbilder angewendet werden. EAST ist ziemlich robust und kann unscharfen oder reflektierenden Text erkennen. Hier ist eine modifizierte Version von Adrian Rosebrocks Implementierung von EAST. Anstatt den Textdetektor direkt auf das Bild anzuwenden, können wir versuchen, möglichst viele Nicht-Textobjekte auf dem Bild zu entfernen, bevor die Texterkennung durchgeführt wird. Die Idee ist, horizontale Linien, vertikale Linien und Nicht-Text-Konturen (Kurven, Diagonalen, Kreisformen) zu entfernen, bevor die Erkennung angewendet wird. Hier sind die Ergebnisse mit einigen Ihrer Bilder:
Geben Sie
->
Nicht-Text-Konturen in Grün einErgebnis
Andere Bilder
Das vorgeübte
frozen_east_text_detection.pb
für die Texterkennung erforderliche Modell finden Sie hier . Obwohl das Modell den größten Teil des Textes erfasst, sind die Ergebnisse nicht 100% genau und weisen gelegentlich falsch positive Ergebnisse auf, wahrscheinlich aufgrund der Art und Weise, wie es auf natürlichen Szenenbildern trainiert wurde. Um genauere Ergebnisse zu erhalten, müssten Sie wahrscheinlich Ihr eigenes benutzerdefiniertes Modell trainieren. Wenn Sie jedoch eine anständige Out-of-the-Box-Lösung wünschen, sollte dies funktionieren. Weitere Informationen zum EAST-Textdetektor finden Sie im Blogbeitrag zu OpenCV Text Detection (EAST Text Detector) von Adrian .Code
quelle
Der Einfachheit halber möchte ich das Paket keras_ocr hinzufügen . Es kann einfach mit pip installiert werden und basiert auf dem CRAFT-Textdetektor, der etwas neuer als der EAST-Detektor ist, wenn ich mich nicht irre.
Neben der Erkennung werden bereits einige OCR-Vorgänge ausgeführt! Die Ergebnisse sind wie folgt: Sehen Sie dies als Alternative, die möglicherweise einfacher zu implementieren ist, als die akzeptierte Antwort.
quelle
Was Sie beschreiben, scheint OCR ( Optical Character Recognition ) zu sein. Eine OCR-Engine, die ich kenne, ist Tesseract , obwohl es auch diese von IBM und anderen gibt.
Da YOLO ursprünglich für eine ganz andere Aufgabe geschult wurde, muss es für die Lokalisierung von Text wahrscheinlich von Grund auf neu trainiert werden. Man könnte versuchen, vorhandene Pakete (angepasst an Ihre spezifische Einstellung) für die Grundwahrheit zu verwenden (obwohl es sich zu beachten lohnt, dass das Modell im Allgemeinen höchstens so gut ist wie die Grundwahrheit). Oder generieren Sie möglicherweise einfacher synthetische Daten für das Training (dh fügen Sie Text an Positionen hinzu, die Sie zu vorhandenen Zeichnungen auswählen, und trainieren Sie dann, um ihn zu lokalisieren).
Wenn alle Ihre Zielbilder ähnlich wie oben strukturiert sind, können Sie alternativ versuchen, mithilfe der klassischen CV-Heuristik wie oben eine Grundwahrheit zu erstellen, um Symbole zu trennen / zu segmentieren, gefolgt von einer Klassifizierung mithilfe eines auf MNIST trainierten CNN oder ähnlichem, um dies zu bestimmen wenn ein bestimmter Blob ein Symbol enthält.
Für den Fall, dass Sie sich für YOLO entscheiden - es gibt bereits Implementierungen in Python, z. B. hatte ich einige Erfahrungen mit dieser -, sollte es ziemlich einfach sein, ein Training mit Ihrer eigenen Grundwahrheit einzurichten.
Wenn die Verwendung von YOLO oder CNN kein Ziel an sich ist, sondern nur die Lösung, kann jede der oben genannten "Grundwahrheiten" direkt als Lösung verwendet werden und nicht zum Trainieren eines Modells.
Hoffe ich habe deine Frage richtig verstanden
quelle