Tesseract vs tables. Reconnaissance des documents

Malgré la numérisation de tout et de tout le monde, à un moment où l'humanité est sur le point de créer une neurointerface, où l'IA est devenue monnaie courante, la tâche classique consistant à obtenir des données à partir d'un scan / image est toujours d'actualité.





Bonne journée. Je m'appelle Aleksey. Je travaille comme programmeur dans une entreprise de vente de matériel. J'avais mes propres bonnes pratiques pour reconnaître et charger des données dans un programme comptable, et ce n'étaient que les managers qui saisissaient manuellement des dizaines de pages de documents pdf qui ne pouvaient pas être facilement transférées vers EDF. Je les ai invités à essayer ma solution.





Au départ, ABBYY Cloud était utilisé pour la reconnaissance, mais ce n'est pas gratuit et le mode d'essai n'est pas assez long. J'ai décidé d'écrire mon API en python, où toute la puissance de la tesseracta gratuite est utilisée. Le problème est que tesseract est une reconnaissance de texte, et il ne définit pas de tableau, il s'avère être de peu d'utilité. Juste la veille, j'ai lu l'article https://vc.ru/ml/139816-povyshenie-kachestva-raspoznavaniya-skanov-dokumentov-s-tablicami-s-pomoshchyu-vychisleniya-koordinat-yacheek, où toutes les cellules du tableau sont obtenues en utilisant openCV, chaque cellule passe par tesseract et ainsi les données correctes peuvent être obtenues. J'ai décidé d'essayer cette méthode. Le message portera sur ce qui s'est passé.





Pour le test, j'ai pris de la base de démonstration 1c TORG-12. Ce formulaire a une structure assez complexe, beaucoup de tableaux, beaucoup de texte, beaucoup de données. Juste ce dont vous avez besoin.





pdf , gostscript . ImageMagick, - . cmd , gostscript .





, openCV , QR-. pyzbar.





, . , . , , . - .





clahe = cv2.createCLAHE(clipLimit=50, tileGridSize=(50, 50))
lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)  
l, a, b = cv2.split(lab) 
l2 = clahe.apply(l)  
lab = cv2.merge((l2, a, b))  
img2 = cv2.cvtColor(lab, cv2.COLOR_LAB2BGR) 

gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 75, 255, cv2.THRESH_BINARY_INV )

kernel = np.ones((2, 2), np.uint8)
obr_img = cv2.erode(thresh, kernel, iterations=1)

obr_img = cv2.GaussianBlur(obr_img, (3,3), 0)
      
      



, . , . 5 , delta.





contours, hierarchy = cv2.findContours(obr_img, cv2.RETR_TREE, cv2.CHAIN_APPROX_TC89_L1)
coordinates = []
ogr = round(max(img.shape[0], img.shape[1]) * 0.005)
delta = round(ogr/2 +0.5)
ind = 1;
for i in range(0, len(contours)):
	l, t, w, h = cv2.boundingRect(contours[i])
	if (h > ogr and w > ogr):
    # 
    # 
    # 
    #
    #
    #
    #
    #
  	coordinates.append((0, ind, 0, l, t, w, h, ''))
    ind = ind + 1
      
      



, . sqlite3 coordinates. . , hierarchy, , . .





, . - . , .





, , - . , , . . , , . , , , , , , .





2 :













. , . , . . , , , , . - . . , , . . . . / 2*. . , - , . .





. . 4 . , , "". "" , , . - , 4 , .









. . tesseract , 3 , . , "-". "-", "---00", . .





text1 = pytesseract.image_to_string(image[t1:t2,l1:l2], lang=lang, config='--psm 6')
text2 = pytesseract.image_to_string(image[t1:t2,l1:l2], lang=lang, config='')
text3 = pytesseract.image_to_string(image[t1+round(delta/2):t2-round(delta/2),l1+round(delta/2):l2-round(delta/2)], lang=lang, config='--psm 7')
text1 = text1.replace("\n", " ")
text2 = text2.replace("\n", " ")
text3 = text3.replace("\n", " ")
text1 = re.sub(' *[^ \(\)--\d\w\/\\\.\-,:; ]+ *', ' ', text1)
text2 = re.sub(' *[^ \(\)--\d\w\/\\\.\-,:; ]+ *', ' ', text2)
text3 = re.sub(' *[^ \(\)--\d\w\/\\\.\-,:; ]+ *', ' ', text3)

while text1.find('  ')!=-1:
    text1 = text1.replace('  ',' ')
while text2.find('  ') != -1:
    text2 = text2.replace('  ', ' ')
while text3.find('  ') != -1:
    text3 = text3.replace('  ', ' ')
      
      



. , . , . , -, , , . , , . , , , . , , ? , 2 , . . , , , . , ; ; , . .





. . 4 . "". , , . .





, , . , . API JSON, 1 . , . . . 1 pdf 20 , . , Tesserocr Pytesseract, .





https://github.com/Trim891/API. PyCharm "", GitHub, *.py requirements.txt. , , , , , ; " , ", , , - ; , , 2 . .





PS Il y a beaucoup de commentaires dans les fichiers, beaucoup de choses inutiles et, en général, le code de merde est un gâchis créatif. Tout était pour un usage interne, il n'y avait pas le temps de s'habiller =)








All Articles