He estado tratando de borrar imágenes para OCR: (las líneas)
Necesito eliminar estas líneas para a veces procesar aún más la imagen y me estoy acercando bastante, pero muchas veces el umbral quita demasiado del texto:
copy = img.copy()
blur = cv2.GaussianBlur(copy, (9,9), 0)
thresh = cv2.adaptiveThreshold(blur,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV,11,30)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9,9))
dilate = cv2.dilate(thresh, kernel, iterations=2)
cnts = cv2.findContours(dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
area = cv2.contourArea(c)
if area > 300:
x,y,w,h = cv2.boundingRect(c)
cv2.rectangle(copy, (x, y), (x + w, y + h), (36,255,12), 3)
Editar: Además, el uso de números constantes no funcionará en caso de que cambie la fuente. ¿Hay una forma genérica de hacer esto?
Respuestas:
Aquí hay una idea. Dividimos este problema en varios pasos:
Determinar el área de contorno rectangular promedio. Luego umbralamos los contornos y los filtramos usando área del rectángulo delimitador del contorno. La razón por la que hacemos esto es por la observación de que cualquier personaje típico solo será tan grande, mientras que el ruido grande abarcará un área rectangular más grande. Luego determinamos el área promedio.
Eliminar grandes contornos atípicos. Repetimos los contornos nuevamente y eliminamos los contornos grandes si están
5x
más grandes que el área de contorno promedio rellenando el contorno. En lugar de usar un área de umbral fijo, usamos este umbral dinámico para una mayor solidez.Dilatar con un núcleo vertical para conectar personajes . La idea es aprovechar la observación de que los personajes están alineados en columnas. Al dilatar con un núcleo vertical conectamos el texto para que el ruido no se incluya en este contorno combinado.
Eliminar pequeños ruidos . Ahora que el texto a guardar está conectado, encontramos contornos y eliminamos los contornos más pequeños que
4x
el área de contorno promedio.A nivel de bits y para reconstruir la imagen . Como solo hemos deseado contornos para mantener nuestra máscara, lo hacemos a nivel de bits y para preservar el texto y obtener nuestro resultado.
Aquí hay una visualización del proceso:
Tenemos el umbral de Otsu para obtener una imagen binaria y luego encontramos contornos para determinar el área de contorno rectangular promedio. Desde aquí eliminamos los grandes contornos atípicos resaltados en verde rellenando contornos
A continuación, construimos un núcleo vertical y lo dilatamos para conectar los caracteres. Este paso conecta todo el texto deseado para mantener y aísla el ruido en blobs individuales.
Ahora encontramos contornos y filtros usando el área de contorno para eliminar el pequeño ruido
Aquí están todas las partículas de ruido eliminadas resaltadas en verde
Resultado
Código
Nota: El procesamiento tradicional de imágenes se limita a los umbrales, las operaciones morfológicas y el filtrado de contornos (aproximación de contornos, área, relación de aspecto o detección de manchas). Dado que las imágenes de entrada pueden variar según el tamaño del texto de los caracteres, encontrar una solución singular es bastante difícil. Es posible que desee estudiar la capacitación de su propio clasificador con aprendizaje automático / profundo para una solución dinámica.
fuente