opencv – recortar líneas manuscritas (segmentación de líneas)

Estoy tratando de construir un sistema de reconocimiento de escritura a mano usando python y opencv. El reconocimiento de los caracteres no es el problema sino la segmentación. He tenido éxito:

  • segmentar una palabra en caracteres individuales
  • segmentó una sola oración en palabras en el orden requerido.

Pero no pude segmentar diferentes líneas en el documento. Intenté ordenar los contornos (para evitar la segmentación de líneas y usar solo la segmentación de palabras) pero no funcionó. He utilizado el siguiente código para segmentar palabras contenidas en un documento escrito a mano, pero devuelve las palabras fuera de orden (devuelve las palabras de manera ordenada de izquierda a derecha):

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) 

Tenga en cuenta que soy capaz de segmentar todas las palabras aquí, pero aparecen fuera de orden. Hay alguna manera de ordenar estos contornos en orden de arriba a abajo

O

segmentar la imagen en líneas separadas para que cada línea pueda segmentarse en palabras usando el código anterior?

    Obtuve la segmentación requerida haciendo un cambio en el código anterior en la línea:

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

    Lo cambié a

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

    Ahora me sale las salidas como sigue líneas segmentadas de texto de entrada Esto también funciona con imágenes de texto escritas a mano con líneas que no son perfectamente horizontales:

    EDITAR: para obtener caracteres individuales de una palabra, haga lo siguiente:

    1. Cambie el tamaño del contorno que contiene la palabra usando el código de la siguiente manera.

       im = cv2.resize(image,None,fx=4, fy=4, interpolation = cv2.INTER_CUBIC) 
    2. Aplique el mismo proceso de detección de contorno que en la segmentación de líneas, pero con un núcleo de tamaño (5,5), es decir:

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