web-dev-qa-db-fra.com

opencv - recadrage des lignes manuscrites (segmentation des lignes)

J'essaye de construire un système de reconnaissance d'écriture manuscrite en utilisant python et opencv. La reconnaissance des caractères n'est pas le problème mais la segmentation. J'ai réussi:

  • segmenté un mot en caractères uniques
  • segmenté un phrase unique en mots dans l'ordre requis.

Mais je n'ai pas pu segmenter différentes lignes dans le document. J'ai essayé de trier les contours (pour éviter la segmentation des lignes et utiliser uniquement la segmentation Word) mais cela n'a pas fonctionné. J'ai utilisé le code suivant pour segmenter les mots contenus dans un document manuscrit, mais il renvoie les mots dans le désordre (il renvoie les mots de manière triée de gauche à droite):

import cv2
import numpy as np
#import image
image = cv2.imread('input.jpg')
#cv2.imshow('orig',image)
#cv2.waitKey(0)

#grayscale
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
cv2.imshow('gray',gray)
cv2.waitKey(0)

#binary
ret,thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY_INV)
cv2.imshow('second',thresh)
cv2.waitKey(0)

#dilation
kernel = np.ones((5,5), np.uint8)
img_dilation = cv2.dilate(thresh, kernel, iterations=1)
cv2.imshow('dilated',img_dilation)
cv2.waitKey(0)

#find contours
im2,ctrs, hier = cv2.findContours(img_dilation.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

#sort contours
sorted_ctrs = sorted(ctrs, key=lambda ctr: cv2.boundingRect(ctr)[0])

for i, ctr in enumerate(sorted_ctrs):
    # Get bounding box
    x, y, w, h = cv2.boundingRect(ctr)

    # Getting ROI
    roi = image[y:y+h, x:x+w]

    # show ROI
    cv2.imshow('segment no:'+str(i),roi)
    cv2.rectangle(image,(x,y),( x + w, y + h ),(90,0,255),2)
    cv2.waitKey(0)

cv2.imshow('marked areas',image)
cv2.waitKey(0)

Veuillez noter que je suis en mesure de segmenter tous les mots ici mais ils apparaissent dans l'ordre. Y a-t-il un moyen de trier ces contours par ordre de haut en bas

OU

segmenter l'image en lignes distinctes afin que chaque ligne puisse être segmentée en mots en utilisant le code ci-dessus?

10
Sidharth Ramesh

J'ai obtenu la segmentation requise en modifiant le code ci-dessus sur la ligne:

kernel = np.ones((5,5), np.uint8)

Je l'ai changé en:

kernel = np.ones((5,100), np.uint8)

Maintenant, je reçois les sorties comme suit segmented lines of input text Cela fonctionne également avec des images de texte manuscrites avec des lignes qui ne sont pas parfaitement horizontales:

MODIFIER: Pour extraire des caractères individuels d'un mot, procédez comme suit:

  1. Redimensionnez le contour contenant le mot en utilisant le code comme suit.

    im = cv2.resize(image,None,fx=4, fy=4, interpolation = cv2.INTER_CUBIC)
    
  2. Appliquer le même processus de détection de contour que dans la segmentation de ligne, mais avec un noyau de taille (5,5), c'est-à-dire:

    kernel = np.ones((5,5), np.uint8)
    img_dilation = cv2.dilate(im_th, kernel, iterations=1)
    
11
Sidharth Ramesh