Cómo detectar texto en una imagen de rayos X con OpenCV

Adrian Krebs:

Quiero detectar texto en imágenes de rayos x. El objetivo es extraer los cuadros delimitadores orientadas como una matriz donde cada fila es un cuadro delimitador detectado y cada fila contiene las coordenadas de los cuatro bordes, es decir, [x1, x2, y1, y2]. Estoy usando Python 3 y OpenCV 4.2.0.

Aquí está una imagen de muestra:

introducir descripción de la imagen aquí

La cadena "palabra de prueba", "a" y "b" debe ser detectado.

He seguido este OpenCV tutorial sobre la creación de cajas rotados para contornos y esta respuesta stackoverflow sobre la detección de un área de texto en una imagen .

Las cajas de contorno resultante debe ser algo como esto:

introducir descripción de la imagen aquí

Yo era capaz de detectar el texto, pero el resultado incluido una gran cantidad de cajas sin texto.

Esto es lo que he intentado hasta ahora:

img = cv2.imread(file_name)

## Open the image, convert it into grayscale and blur it to get rid of the noise.
img2gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
ret, mask = cv2.threshold(img2gray, 180, 255, cv2.THRESH_BINARY)
image_final = cv2.bitwise_and(img2gray, img2gray, mask=mask)
ret, new_img = cv2.threshold(image_final, 180, 255, cv2.THRESH_BINARY)  # for black text , cv.THRESH_BINARY_INV


kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3))
dilated = cv2.dilate(new_img, kernel, iterations=6)

canny_output = cv2.Canny(dilated, 100, 100 * 2)
cv2.imshow('Canny', canny_output)

## Finds contours and saves them to the vectors contour and hierarchy.
contours, hierarchy = cv2.findContours(canny_output, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# Find the rotated rectangles and ellipses for each contour
minRect = [None] * len(contours)
for i, c in enumerate(contours):
    minRect[i] = cv2.minAreaRect(c)
# Draw contours + rotated rects + ellipses

drawing = np.zeros((canny_output.shape[0], canny_output.shape[1], 3), dtype=np.uint8)

for i, c in enumerate(contours):
    color = (255, 0, 255)
    # contour
    cv2.drawContours(drawing, contours, i, color)

    # rotated rectangle
    box = cv2.boxPoints(minRect[i])
    box = np.intp(box)  # np.intp: Integer used for indexing (same as C ssize_t; normally either int32 or int64)
    cv2.drawContours(img, [box], 0, color)

cv2.imshow('Result', img)
cv2.waitKey()

¿Es necesario para ejecutar los resultados a través de OCR para asegurarse de si se trata o no de texto? ¿Qué otros enfoques debería intentar?

PS: Estoy bastante nuevo en la visión por ordenador y que no están familiarizados con los conceptos más todavía.

nathancy:

He aquí un método sencillo:

  1. Obtener una imagen binaria. Cargar imagen, crear máscara en blanco, convertir a escala de grises , desenfoque gaussiano , entonces el umbral de Otsu

  2. Texto se funden en un solo contorno. Dado que queremos extraer el texto como una sola pieza, realizamos operaciones morfológicas a los contornos de texto individuales de conexión en un solo contorno.

  3. Extrae el texto. Nos encontramos con contornos y filtrar con contorno con cv2.contourAreay relación de aspecto mediante cv2.arcLength+ cv2.approxPolyDP. Si un contorno pasa el filtro, se encuentra la caja de contorno girado y dibujar esta en nuestra máscara.

  4. Texto aislado. Llevamos a cabo un cv2.bitwise_andoperación para extraer el texto.


He aquí una visualización del proceso. Usando esta imagen de entrada screenshotted (ya que su imagen de entrada proporcionado estaba conectado como una imagen):

Imagen de entrada ->de imagen binaria

Morph cerca ->texto Detectado

texto aislado

Los resultados con la otra imagen

Imagen de entrada ->de imagen binaria + morfo cerca

Texto detectado ->texto aislado

Código

import cv2
import numpy as np

# Load image, create mask, grayscale, Gaussian blur, Otsu's threshold
image = cv2.imread('1.png')
original = image.copy() 
blank = np.zeros(image.shape[:2], dtype=np.uint8)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (5,5), 0)
thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]

# Merge text into a single contour
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
close = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=3)

# Find contours
cnts = cv2.findContours(close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    # Filter using contour area and aspect ratio
    x,y,w,h = cv2.boundingRect(c)
    area = cv2.contourArea(c)
    ar = w / float(h)
    if (ar > 1.4 and ar < 4) or ar < .85 and area > 10 and area < 500:
        # Find rotated bounding box
        rect = cv2.minAreaRect(c)
        box = cv2.boxPoints(rect)
        box = np.int0(box)
        cv2.drawContours(image,[box],0,(36,255,12),2)
        cv2.drawContours(blank,[box],0,(255,255,255),-1)

# Bitwise operations to isolate text
extract = cv2.bitwise_and(thresh, blank)
extract = cv2.bitwise_and(original, original, mask=extract)

cv2.imshow('thresh', thresh)
cv2.imshow('image', image)
cv2.imshow('close', close)
cv2.imshow('extract', extract)
cv2.waitKey()

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=339538&siteId=1
Recomendado
Clasificación