¿Te resulta más fácil leer con fondo crema, un tono de color, más contraste o un texto más grande? Elige tus colores y tu texto una sola vez, para todas las páginas.

Lección gratuita

Filtros y desenfoque: cómo quitar ruido

Después de esta lección: Puedo suavizar el ruido de una imagen con un filtro.

Lección de 60 min3 comandosLaboratorio de visión por computador: píxeles, umbrales y recuento de objetos en JupyterLab

Un filtro suaviza el ruido de una imagen

Un filtro de imagen cambia cada píxel usando los píxeles de su alrededor. El desenfoque es el filtro más usado para quitar ruido. Sin él, una foto escaneada con motas da umbrales y bordes falsos.

Hoy calculas a mano un filtro de 3 por 3 y ves cuánto baja el ruido en una página escaneada.

Al final de esta lección

Nota

Puedo suavizar el ruido de una imagen con un filtro.

Palabras clave

PalabraQué significaEjemplo
Ruidopíxeles con valores erróneos, como motas
Filtrouna regla que cambia cada píxel según sus vecinos
Núcleola cuadrícula de pesos del filtro (kernel en inglés)3 × 3
Convolucióndeslizar el núcleo y sumar productos en cada punto
Desenfoqueun filtro que promedia los vecinos
Medianael valor del medio de una lista ordenada

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Un píxel suelto se corrige con sus vecinos

Una página escaneada tiene motas: puntos negros o blancos que no están en el papel. Eso es ruido.

Un vecino sabe cómo debería ser un píxel. Si sustituyes cada píxel por la media de su trozo de 3 por 3, una mota se reparte entre nueve puntos y casi desaparece. Eso es un desenfoque.

Ejemplo resuelto: una mota entre nueve píxeles

PasoCálculoResultado
El trozo de 3 × 3Ocho píxeles de 10 y una mota de 90Mota en el centro
Suma de los nueve8 × 10 + 90170
Media entera170 // 918
Píxel nuevoEl centro pasa de 90 a 18La mota casi no se nota

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Un núcleo dice cuánto pesa cada vecino

Un núcleo es una cuadrícula pequeña de pesos. Se coloca sobre un trozo de la imagen, se multiplica cada píxel por su peso y se suman los productos. Eso es una convolución.

Un núcleo de nueve unos suma el trozo entero. Dividido entre 9 da la media. Otros pesos dan otros filtros.

Un núcleo sobre un trozo

Código: python
# Un filtro 3 por 3 en UNA posición: multiplica cada vecino por su peso y suma.
patch = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
]
kernel = [
    [1, 1, 1],
    [1, 1, 1],
    [1, 1, 1],
]
total = 0
for row in range(3):
    for column in range(3):
        total = total + patch[row][column] * kernel[row][column]
print("suma de productos:", total)
print("desenfoque:", total // 9)
# Cambia el núcleo: un 9 en el centro y ceros en los demás. ¿Qué devuelve el filtro?

Ejemplo resuelto: tres núcleos sobre el mismo trozo

NúcleoQué pesos tieneResultado sobre 1 a 9
Nueve unosTodos 145, y 5 al dividir entre 9
Solo el centroUn 1 en el centro y ceros5, la imagen no cambia
En cruzUnos arriba, abajo, izquierda y derecha20

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

La suma del núcleo de unos

Comando
docker exec jupyter python3 -c "print(1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9, 45 // 9)"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Un error muy común

Advertencia

Mucha gente cree que basta con escribir cada resultado en la misma imagen. Pero el píxel siguiente necesita los valores viejos de sus vecinos. Escribe el resultado en una imagen nueva y deja la original sin tocar. Además, la nueva sale 2 filas y 2 columnas más pequeña, porque en el borde el núcleo no cabe.

La mediana ignora las motas

La media se deja arrastrar por una mota. La mediana no: se ordenan los nueve valores y se toma el del medio.

Con ocho píxeles de 10 y una mota de 255, la media entera da 32 y la mediana da 10. Por eso el filtro de mediana limpia bien las motas de tinta y de papel.

La media y la mediana de una mota

Comando
docker exec jupyter python3 -c "v = [10, 10, 10, 10, 255, 10, 10, 10, 10]; print(sum(v) // 9, sorted(v)[4])"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Qué cuenta el script del desenfoque

El script blur.py desenfoca scan.png con un desenfoque gaussiano, que da más peso a los vecinos cercanos. Mide cuánto varían los píxeles de un trozo vacío de la página.

Imprime en inglés: before es antes y after es después. La dispersión baja de 25,3 a 4,9 niveles de gris.

Desenfoca la página escaneada

Comando
docker exec jupyter python3 steps/blur.py

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Para ir más lejos: más desenfoque

En el código de arriba, cambia el trozo para que tenga una mota de 90 en el centro y ocho píxeles de 10. Comprueba que el desenfoque da 18.

Después abre scan_blurred.png en JupyterLab y compárala con scan.png. ¿Qué pasa con las letras?

Sobre este laboratorio y su código: Laboratorio de visión por computador: píxeles, umbrales y recuento de objetos en JupyterLab

¿Enseñas a una clase? Asigna este módulo a tus alumnos con guía del profesor, tareas con corrección automática y un laboratorio para cada alumno.