Es posible que desee digitalizar un documento para ahorrar espacio físico o crear una copia de seguridad. De cualquier manera, escribir un programa que pueda convertir fotos de sus archivos en papel a un formato estándar es una tarea en la que Python sobresale.
Usando una combinación de bibliotecas apropiadas, puede crear una pequeña aplicación para digitalizar documentos. Su programa tomará una imagen de un documento físico como entrada, le aplicará varias técnicas de procesamiento de imágenes y generará una versión escaneada de la entrada.
Preparación de su entorno
Para seguir este artículo debe estar familiarizado con el fundamentos de python. También necesita tener una comprensión de cómo trabajar con la biblioteca NumPy Python.
Abra cualquier IDE de Python y cree dos archivos de Python. Nombra uno main.py y el otro transform.py. Luego ejecute el siguiente comando en la terminal para instalar las bibliotecas requeridas.
pip install OpenCV-Python imutils scikit-image NumPy
Utilizará OpenCV-Python para tomar la entrada de imagen y realizar algún procesamiento de imagen. Imutils para cambiar el tamaño de las imágenes de entrada y salida. scikit-image para aplicar un umbral en la imagen. NumPy te ayudará a trabajar con arreglos.
Espere a que finalice la instalación y que el IDE actualice los esqueletos del proyecto. Una vez completada la actualización de los esqueletos, está listo para comenzar a codificar. El código fuente completo está disponible en un repositorio GitHub.
Importación de las bibliotecas instaladas
Abra el archivo main.py e importe las bibliotecas que instaló en el entorno. Esto le permitirá llamar y utilizar sus funciones cuando sea necesario.
importar cv2
importar imutiles
de skimage.filters importar umbral_local
de transformar importar transformación_perspectiva
Ignore el error arrojado en perspectiva_transform. Desaparecerá cuando termine de trabajar en el archivo transform.py.
Tomar y cambiar el tamaño de la entrada
Tome una imagen clara del documento que desea escanear. Asegúrese de que las cuatro esquinas del documento y su contenido estén visibles. Copie la imagen en la misma carpeta en la que está almacenando los archivos del programa.
Pase la ruta de la imagen de entrada a OpenCV. Haga una copia de la imagen original, ya que la necesitará durante la transformación de perspectiva. Divide la altura de la imagen original por la altura a la que deseas cambiar su tamaño. Esto mantendrá la relación de aspecto. Finalmente, imprima la imagen redimensionada.
# Pasando la ruta de la imagen
original_img = cv2.imread('muestra.jpg')
copiar = original_img.copiar()# La altura redimensionada en cientos
relación = original_img.forma[0] / 500.0
img_resize = imutils.resize (original_img, altura=500)# Mostrar salida
cv2.imshow('Imagen redimensionada', img_resize)
# Esperando a que el usuario presione cualquier tecla
cv2.esperaClave(0)
La salida del código anterior es la siguiente:
Ahora ha cambiado el tamaño de la altura de la imagen original a 500 píxeles.
Convertir la imagen redimensionada a escala de grises
Convierta la imagen RGB redimensionada a escala de grises. La mayoría de las bibliotecas de procesamiento de imágenes solo funcionan con imágenes en escala de grises, ya que son más fáciles de procesar.
imagen_gris = cv2.cvtColor (img_resize, cv2.COLOR_BGR2GRAY)
cv2.imshow('Imagen en gris', imagen_gris)
cv2.esperaClave(0)
Observe la diferencia entre la imagen original y la gris.
La mesa de colores se ha convertido en blanco y negro.
Aplicar un detector de bordes
Aplique un filtro de desenfoque gaussiano en la imagen atenuada para eliminar el ruido. Luego llame a la función Canny de OpenCV para detectar los bordes presentes en la imagen.
imagen_borrosa = cv2.GaussianBlur (imagen_gris, (5, 5), 0)
edged_img = cv2.Canny (imagen_borrosa, 75, 200)
cv2.imshow('Bordes de la imagen', bordeado_img)
cv2.esperaClave(0)
Los bordes son visibles en la salida.
Los bordes con los que trabajará son los del documento.
Encontrar el contorno más grande
Detecta los contornos presentes en la imagen con bordes. Ordenarlos en orden descendente manteniendo solo los cinco contornos más grandes. Aproxime el contorno más grande con cuatro lados recorriendo los contornos ordenados.
cnts, _ = cv2.findContours (edged_img, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cnts = ordenado (cnts, key=cv2.contourArea, reverse=Verdadero)[:5]para C en centavos:
peri = cv2.arcLength (c, Verdadero)
aprox = cv2.approxPolyDP(c, 0.02 * peri, Verdadero)
si largo (aprox.) == 4:
doc = aprox.
romper
Es probable que el contorno con cuatro lados contenga el documento.
Rodeando las cuatro esquinas del contorno del documento
Encierre en un círculo las esquinas del contorno del documento detectado. Esto lo ayudará a determinar si su programa pudo detectar el documento en la imagen.
pag = []
para d en doc:
punto_tupla = tupla (d[0])
cv2.circle (img_resize, tuple_point, 3, (0, 0, 255), 4)
p.append (tuple_point)
cv2.imshow('Puntos de esquina redondeados', img_resize)
cv2.esperaClave(0)
Implemente círculos en la imagen RGB redimensionada.
Habiendo detectado el documento, ahora necesita extraer el documento de la imagen.
Uso de la perspectiva Warp para obtener la imagen deseada
La perspectiva warp es una técnica de visión artificial para transformar una imagen para corregir distorsiones. Transforma una imagen en un plano diferente permitiéndole ver la imagen desde un ángulo diferente.
warped_image = perspectiva_transformar (copiar, doc.reformar(4, 2) * relación)
imagen_distorsionada = cv2.cvtColor (imagen_distorsionada, cv2.COLOR_BGR2GRAY)
cv2.imshow("Imagen deformada", imutils.resize (warped_image, altura=650))
cv2.esperaClave(0)
Para obtener una imagen deformada, debe crear un módulo simple que realizará la transformación de perspectiva.
Módulo de Transformación
El módulo ordenará los puntos de las esquinas del documento. También transformará la imagen del documento en un plano diferente y cambiará el ángulo de la cámara a una toma desde arriba.
Abra el archivo transform.py que creó anteriormente. Importe bibliotecas OpenCV y NumPy.
importar entumecido como notario público
importar cv2
Este módulo contendrá dos funciones. Cree una función que ordenará las coordenadas de los puntos de las esquinas del documento. La primera coordenada será la de la esquina superior izquierda, la segunda será la de la esquina superior derecha, la tercera será la de la esquina inferior derecha, y la cuarta coordenada será la de la esquina inferior izquierda esquina.
definitivamentepuntos_de_pedido(puntos):
# inicializando la lista de coordenadas a ordenar
rect = np.ceros((4, 2), tipo de d = "flotador32")s = pts.sum (eje = 1)
# el punto superior izquierdo tendrá la suma más pequeña
rect[0] = ptos[np.argmin(s)]# el punto inferior derecho tendrá la suma más grande
rect[2] = pts[np.argmax(s)]calculando la diferencia entre los puntos, el
el punto superior derecho tendrá la diferencia más pequeña,
mientras que la parte inferior izquierda tendrá la mayor diferencia
diff = np.diff (pts, eje = 1)
rect[1] = pts[np.argmin (diferencia)]
rect[3] = pts[np.argmax (diferencia)]
# devuelve las coordenadas ordenadas
devolver rectificar
Cree una segunda función que calcule las coordenadas de las esquinas de la nueva imagen y obtenga una toma desde arriba. Luego calculará la matriz de transformación de perspectiva y devolverá la imagen deformada.
definitivamentetransformación_perspectiva(imagen, puntos):
# desempaquetar las coordenadas ordenadas individualmente
rect = puntos_de_pedido (pts)
(tl, tr, br, bl) = rectcalcular el ancho de la nueva imagen, que será el
distancia máxima entre abajo a la derecha y abajo a la izquierda
coordenadas x o la parte superior derecha y coordenadas x arriba a la izquierda
anchoA = np.sqrt(((br[0] - bl[0]) ** 2) + ((br[1] - bl[1]) ** 2))
anchoB = np.sqrt(((tr[0] - tl[0]) ** 2) + ((tr[1] - tl[1]) ** 2))
maxWidth = max (int (anchoA), int (anchoB))calcular la altura de la nueva imagen, que será la
distancia máxima entre la parte superior izquierda y coordenadas y abajo a la izquierda
alturaA = np.sqrt(((tr[0] - hermano[0]) ** 2) + ((tr[1] - hermano[1]) ** 2))
alturaB = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2))
maxHeight = max (int (alturaA), int (alturaB))construir el conjunto de puntos de destino para obtener un plano cenital
dst = np.matriz([
[0, 0],
[anchura máxima - 1, 0],
[anchura máxima - 1, Altura máxima - 1],
[0, Altura máxima - 1]], dtipo = "flotador32")# calcular la matriz de transformación de perspectiva
transform_matrix = cv2.getPerspectiveTransform (rect, dst)# Aplicar la matriz de transformación
warped = cv2.warpPerspective (imagen, transform_matrix, (maxWidth, maxHeight))
# devolver la imagen deformada
devolver deformado
Ahora ha creado el módulo de transformación. El error en la importación de outlook_transform ahora desaparecerá.
Observe que la imagen que se muestra tiene un plano cenital.
Aplicar umbral adaptativo y guardar la salida escaneada
En el archivo main.py, aplique el umbral gaussiano a la imagen deformada. Esto le dará a la imagen deformada un aspecto escaneado. Guarde la salida de la imagen escaneada en la carpeta que contiene los archivos del programa.
T = umbral_local (imagen_distorsionada, 11, desplazamiento=10, método="gaussiano")
deformado = (imagen_deformada > T).astype("uint8") * 255
cv2.imwrite('./'+'escanear'+'.png',deformado)
Guardar el escaneo en formato PNG mantiene la calidad del documento.
Visualización de la salida
Salida de la imagen del documento escaneado:
cv2.imshow("Imagen escaneada final", imutils.resize (deformado, altura=650))
cv2.esperaClave(0)
cv2.destroyAllWindows()
La siguiente imagen muestra el resultado del programa, una vista aérea del documento escaneado.
Cómo avanzar en visión artificial
La creación de un escáner de documentos cubre algunas áreas centrales de la visión por computadora, que es un campo amplio y complejo. Para avanzar en la visión por computadora, debe trabajar en proyectos interesantes pero desafiantes.
También debería leer más sobre cómo puede usar la visión artificial con las tecnologías actuales. Esto lo mantendrá informado y le dará nuevas ideas para proyectos en los que trabajar.