J'ai plusieurs diagrammes d'images, qui contiennent tous des étiquettes sous forme de caractères alphanumériques au lieu de simplement l'étiquette de texte elle-même. Je veux que mon modèle YOLO identifie tous les chiffres et caractères alphanumériques qu'il contient.
Comment puis-je entraîner mon modèle YOLO à faire de même. L'ensemble de données peut être trouvé ici. https://drive.google.com/open?id=1iEkGcreFaBIJqUdAADDXJbUrSj99bvoi
Par exemple: voir les boîtes englobantes. Je veux que YOLO détecte où le texte est présent. Cependant, il n'est actuellement pas nécessaire d'identifier le texte qu'il contient.
De même, la même chose doit être faite pour ce type d'images
Les images peuvent être téléchargées ici
C'est ce que j'ai essayé d'utiliser opencv mais cela ne fonctionne pas pour toutes les images du jeu de données.
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()
Y a-t-il un modèle ou une technique d'opencv ou un modèle pré-formé qui peut faire la même chose pour moi? J'ai juste besoin des cadres de délimitation autour de tous les caractères alphanumériques présents dans les images. Après cela, je dois identifier ce qui s'y trouve. Cependant la deuxième partie n'est pas importante actuellement.
la source
Réponses:
Une approche possible consiste à utiliser le détecteur de texte d'apprentissage en profondeur EAST (Efficient and Accurate Scene Text) basé sur l'article 2017 de Zhou et al., EAST: An Efficient and Accurate Scene Text Detector . Le modèle a été initialement formé pour détecter du texte dans des images de scènes naturelles, mais il peut être possible de l'appliquer sur des images de diagramme. EAST est assez robuste et est capable de détecter du texte flou ou réfléchissant. Voici une version modifiée de la mise en œuvre d'Adrian Rosebrock d'EAST. Au lieu d'appliquer le détecteur de texte directement sur l'image, nous pouvons essayer de supprimer autant d'objets non textuels sur l'image avant d'effectuer la détection de texte. L'idée est de supprimer les lignes horizontales, les lignes verticales et les contours non textuels (courbes, diagonales, formes circulaires) avant d'appliquer la détection. Voici les résultats avec certaines de vos images:
Saisie
->
des contours non textuels à supprimer en vertRésultat
Autres images
Le
frozen_east_text_detection.pb
modèle pré-formé nécessaire pour effectuer la détection de texte peut être trouvé ici . Bien que le modèle capture la plupart du texte, les résultats ne sont pas précis à 100% et présentent parfois des faux positifs, probablement en raison de la façon dont il a été formé sur les images de scènes naturelles. Pour obtenir des résultats plus précis, vous devrez probablement former votre propre modèle personnalisé. Mais si vous voulez une solution décente prête à l'emploi, cela devrait vous fonctionner. Consultez le billet de blog Adrian OpenCV Text Detection (détecteur de texte EAST) pour une explication plus complète du détecteur de texte EAST.Code
la source
Par souci de commodité, j'aimerais ajouter le package keras_ocr . Il peut facilement être installé avec pip et est basé sur le détecteur de texte CRAFT, qui est un peu plus récent que le détecteur EAST si je ne me trompe pas.
À côté de la détection, il fait déjà aussi de l'OCR! Les résultats sont les suivants, voir cela comme une alternative, peut-être plus facile à mettre en œuvre, que la réponse acceptée.
la source
Ce que vous décrivez semble être l'OCR (reconnaissance optique des caractères ). Un moteur OCR que je connais est tesseract , bien qu'il y ait aussi celui d'IBM et d'autres.
Comme YOLO a été initialement formé pour une tâche très différente, son utilisation pour localiser du texte nécessitera probablement de le recycler à partir de zéro. On pourrait essayer d'utiliser des packages existants (adaptés à votre environnement spécifique) pour la vérité terrain (bien qu'il soit bon de se rappeler que le modèle ne serait généralement au mieux aussi bon que la vérité terrain). Ou, peut-être plus facilement, générez des données synthétiques pour la formation (c.-à-d. Ajoutez du texte aux positions que vous choisissez aux dessins existants puis entraînez-vous à le localiser).
Alternativement, si toutes vos images cibles sont structurées de la même manière que ci-dessus, on pourrait essayer de créer une vérité fondamentale en utilisant l'heuristique CV classique comme vous l'avez fait ci-dessus pour séparer / segmenter les symboles, suivie d'une classification en utilisant un CNN formé sur MNIST ou similaire pour déterminer si un blob donné contient un symbole.
Dans le cas où vous optez pour YOLO - il existe des implémentations existantes en python, par exemple, j'ai eu une certaine expérience avec celui-ci - devrait être assez simple pour configurer la formation avec votre propre vérité de terrain.
Enfin, si l'utilisation de YOLO ou CNN n'est pas un objectif en soi mais plutôt seulement la solution, n'importe laquelle des «vérités fondamentales» ci-dessus pourrait être utilisée directement comme solution, et non pour former un modèle.
J'espère que j'ai bien compris votre question
la source