Saltar al contenido

OpenCV – Eliminación de ruido en la imagen

Hola, hemos encontrado la respuesta a lo que estabas buscando, desplázate y la hallarás aquí.

Solución:

Probé algunos filtros/operaciones en OpenCV y parece funcionar bastante bien.

Paso 1: Dilatar la imagen –

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

Imagen dilatada

Como ven, el ruido desapareció pero los personajes son muy ligeros, por lo que erosioné la imagen.

Paso 2: Erosionar la imagen –

kernel = np.ones((5, 5), np.uint8)
cv2.erode(img, kernel, iterations = 1)

Imagen dilatada erosionada

Como puede ver, el ruido desapareció, sin embargo, algunos caracteres en las otras columnas están rotos. Recomendaría ejecutar estas operaciones solo en la columna ruidosa. Es posible que desee utilizar HoughLines para encontrar la última columna. Luego puede extraer solo esa columna, ejecutar dilatación + erosión y reemplazar esto con la columna correspondiente en la imagen original. Además, la dilatación + erosión es en realidad una operación llamada clausura. Esto se puede llamar directamente usando –

cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)

Como sugirió @Ermlg, medianBlur con un kernel de 3 también funciona maravillosamente.

cv2.medianBlur(img, 3)

Desenfoque medio

Paso alternativo

Como puede ver, todos estos filtros funcionan, pero es mejor si implementa estos filtros solo en la parte donde está el ruido. Para hacer eso, use lo siguiente:

edges = cv2.Canny(img, 50, 150, apertureSize = 3) // img is gray here
lines = cv2.HoughLinesP(edges, 1, np.pi / 180, 100, 1000, 50) // last two arguments are minimum line length and max gap between two lines respectively.
for line in lines: 
    for x1, y1, x2, y2 in line: 
        print x1, y1
// This gives the start coordinates for all the lines. You should take the x value which is between (0.75 * w, w) where w is the width of the entire image. This will give you essentially **(x1, y1) = (1896, 766)**

Luego, puede extraer esta parte solo como:

extract = img[y1:h, x1:w] // w, h are width and height of the image

Imagen extraída

Luego, implemente el filtro (mediana o de cierre) en esta imagen. Después de eliminar el ruido, debe colocar esta imagen filtrada en lugar de la parte borrosa de la imagen original. imagen[y1:h, x1:w] = mediana

Esto es sencillo en C++:

extract.copyTo(img, new Rect(x1, y1, w - x1, h - y1))

Resultado final con método alternativo

Resultado final
¡Espero eso ayude!

Mi solución se basa en el umbral para obtener la imagen resultante en 4 pasos.

  1. Leer imagen por OpenCV 3.2.0.
  2. Aplicar GaussianBlur() para suavizar la imagen, especialmente la región en color gris.
  3. Enmascare la imagen para cambiar el texto a blanco y el resto a negro.
  4. Invierta la imagen enmascarada en texto negro en blanco.

El código está en Python 2.7. Se puede cambiar a C++ fácilmente.

import numpy as np
import cv2
import matplotlib.pyplot as plt
%matplotlib inline 

# read Danish doc image 
img = cv2.imread('./imagesStackoverflow/danish_invoice.png')

# apply GaussianBlur to smooth image
blur = cv2.GaussianBlur(img,(5,3), 1) 

# threshhold gray region to white (255,255, 255) and sets the rest to black(0,0,0)
mask=cv2.inRange(blur,(0,0,0),(150,150,150))

# invert the image to have text black-in-white
res = 255 - mask

plt.figure(1)
plt.subplot(121), plt.imshow(img[:,:,::-1]), plt.title('original') 
plt.subplot(122), plt.imshow(blur, cmap='gray'), plt.title('blurred')
plt.figure(2)
plt.subplot(121), plt.imshow(mask, cmap='gray'), plt.title('masked')
plt.subplot(122), plt.imshow(res, cmap='gray'), plt.title('result')
plt.show()

Las siguientes son las imágenes trazadas por el código como referencia.

ingrese la descripción de la imagen aquí

Aquí está el imagen de resultado a 2197 x 3218 píxeles.

ingrese la descripción de la imagen aquí

Como sé, el filtro mediano es la mejor solución para reducir el ruido. Recomendaría usar un filtro mediano con una ventana de 3×3. Ver función cv::medianBlur().

Pero tenga cuidado cuando use cualquier filtración de ruido simultáneamente con OCR. Esto puede conducir a una disminución de la precisión del reconocimiento.

También recomendaría intentar usar un par de funciones (cv::erode() y cv::dilate()). Pero no estoy seguro de que sea la mejor solución que cv::medianBlur() con la ventana 3×3.

Acuérdate de que tienes concesión de añadir una evaluación certera si te ayudó.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *