2017-07-03 2 views
1

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: enter image description here

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: enter image description here

D'abord j'ai essayé un « template matching » algorithme en utilisant ceci comme modèle: enter image description here

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 utilisant cv2.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.enter image description here

Essayer des échantillons aléatoires, cette formule me donne:

img.crop((x+w, y+h/3, x+h*3.05, y+2*h/3)) 

enter image description here enter image description here enter image description here

[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') 

enter image description here

plt.imshow(grid, 'gray') 

enter image description here

BTW Je n'ai pas la moindre idée de la vision par ordinateur. Revenons à google ...

Répondre

0

Essayez de trouver les coins des champs, l'angle de calage/échelle et de simplement transformer l'image en image normalisée.