Au Brésil un formulaire standard rempli (à la main) pour chaque nouveau-né dans un hôpital. Ce formulaire est appelé "DNV" (après le portugais pour "Born Alive Declaration"). Il y a aussi un formulaire appelé "DO" (après le portugais pour "Decease Declaration"). Dans mon état, les hôpitaux envoient près d'un million de ces formulaires à l'agence où je travaille, où nous calculons une base de données appelée «Statistiques vitales». J'étudie s'il est possible d'automatiser le travail. Puisque les solutions commerciales de RIC coûtent beaucoup d'argent, personne ne croit que cela peut se faire à l'interne, c'est donc un projet de base.Comment localiser un champ de formulaire spécifique dans cette image
Le sommet de la forme est comme ceci:
Je suis mes mains dans 100K fichiers PDF envoyés par plusieurs hôpitaux et a pu les classer dans l'un des deux types (DNV ou DO) au moyen d'un algorithme naïf: d'abord je localise le rectangle noir qui contient le type du document (en utilisant cv2.findContours
et un peu d'heuristique) et j'applique un OCR (pytesseract.image_to_string
). J'ai trouvé 20k "déclaration de décès" (DO) et 80k "déclaration vivante née". En utilisant un algorithme similaire, j'ai été en mesure d'OCR le numéro à la droite du rectangle noir et de lier des images de forme 55k avec l'enregistrement correspondant dans une base de données remplie par des dactylos professionnels basés sur ces documents.
Maintenant, je veux trouver le champ de date (en rouge) afin d'essayer un peu d'apprentissage automatique pour reconnaître les chiffres - le champ est en surbrillance:
D'abord j'ai essayé un « template matching » algorithme en utilisant ceci comme modèle:
Ceci fonctionne bien mais seulement si le modèle et l'image de forme sont dans la même échelle et angle. La méthode cv2.matchTemplate
est très sensible à l'échelle. J'ai essayé des algorithmes de correspondance de caractéristiques en utilisant SURF, mais j'ai du mal à le faire fonctionner (ça me donne l'impression d'être exagéré).
Comme il est facile de localiser le rectangle noir dans la gauche, je pense quelques options afin de localiser les chiffres:
normalisant l'échelle et de l'angle sur la base du rectangle noir et essayer
cv2.matchTemplate
. En essayant de localiser le contour, simplifiez-le en utilisantcv2.approxPolyDP
et devinez l'emplacement des chiffres.
Ma question est: des conseils sur la façon d'attaquer le problème? Quel autre algorithme puis-je utiliser pour localiser ce champ de formulaire si l'entrée n'est pas normalisée en termes de résolution/angle?
[mise à jour # 1]
(x, y, w, h) la position et la taille du rectangle noir dans la gauche, je peux restreindre la recherche avec une confiance raisonnable.
Essayer des échantillons aléatoires, cette formule me donne:
img.crop((x+w, y+h/3, x+h*3.05, y+2*h/3))
[mise à jour # 2]
Je viens d'apprendre au sujet erode
et dilate
, maintenant ils sont mes nouveaux meilleurs amis.
horizontal = edges.copy()
vertical = edges.copy()
kv = np.ones((25, 1), np.uint8)
kh = np.ones((1, 30), np.uint8)
horizontal = cv2.dilate(cv2.erode(horizontal, kh, iterations=2), kh, iterations=2)
vertical = cv2.dilate(cv2.erode(vertical, kv, iterations=2), kv, iterations=2)
grid = horizontal | vertical
plt.imshow(edges, 'gray')
plt.imshow(grid, 'gray')
BTW Je n'ai pas la moindre idée de la vision par ordinateur. Revenons à google ...