Skip to content

Clase 11 — Filtros Gaussiano, Mediana, Escalado y Ecualización. Estructura del Examen

Resumen Ejecutivo

Sesión doble (1h 57m). Primera parte: cierre del Tema 8 (parte 1 y parte 2). Se completan los filtros de suavizado (filtro de la mediana y por qué elimina ruido sal-pimienta), se introduce el escalado de imágenes (pyrDown, pyrUp, cv2.resize) con el problema del aliasing por submuestreo y el teorema de Nyquist aplicado a imágenes 2D, los filtros de realce (bordes y contraste), y la ecualización de histograma (cv2.equalizeHist). Segunda parte: la profesora explica la estructura del examen, permisos y consejos.


Conceptos Clave

  • Filtro de la mediana (cv2.medianBlur): ordena los píxeles del vecindario y toma el valor central. Elimina ruido sal-pimienta sin afectar bordes. ⚠️ EXAMEN
  • Ruido sal-pimienta: píxeles blancos (255) o negros (0) aleatorios que el filtro de la media y el gaussiano no eliminan eficazmente.
  • Downsampling (cv2.pyrDown): reduce la imagen a la mitad aplicando primero un gaussiano y luego eliminando filas/columnas pares.
  • Upsampling (cv2.pyrUp): amplía la imagen al doble insertando filas/columnas de ceros en posiciones pares y aplicando un gaussiano.
  • Aliasing: efecto diente de sierra en los bordes al hacer downsampling sin suavizado previo. Causa: el muestreo viola el teorema de Nyquist. ⚠️ EXAMEN
  • Teorema de Nyquist en imágenes: para reducir una imagen sin aliasing hay que suavizarla antes (bajar la frecuencia de los bordes). ⚠️ EXAMEN
  • cv2.resize: función de escalado configurable con factores de escala e interpolación. Mejor calidad que pyrDown/pyrUp.
  • Filtro de realce de bordes: kernel que potencia los cambios bruscos de intensidad.
  • Ecualización de histograma (cv2.equalizeHist): redistribuye las intensidades para aumentar el contraste global y revelar detalles ocultos. ⚠️ EXAMEN
  • Examen: 2 problemas. OpenGL 7 puntos + OpenCV 3 puntos. Duración 90 minutos. Todo programación.

Desarrollo del Temario

1. Filtro de la mediana — por qué elimina ruido sal-pimienta

El filtro de la mediana no es convolucional: en lugar de producto escalar, ordena los valores del vecindario de menor a mayor y se queda con el valor central (la mediana estadística).

Por qué funciona contra el ruido sal-pimienta:

Dado un vecindario 3×3 con dos píxeles de ruido blanco (255) y el resto valores oscuros ~26:

Vecindario original:  [26, 18, 30, 0, 255, 26, 30, 255, 18]
Ordenado:             [0, 18, 18, 26, 26, 30, 30, 255, 255]
Mediana (posición 4): 26

Los valores extremos (0 y 255) quedan en los extremos de la lista ordenada y nunca son la mediana mientras el ruido sea minoritario. ⚠️ EXAMEN

img_mediana = cv2.medianBlur(img, 5)   # 5 = tamaño del kernel (impar)

Comparación de filtros contra ruido sal-pimienta:

Filtro Elimina ruido sal-pimienta Conserva bordes
Media (cv2.blur) No — promedia los 255, los difumina pero no los elimina Regular
Gaussiano No — idem, ponderado pero sigue difuminando Regular
Mediana (cv2.medianBlur) Sí — los extremos no son la mediana Mejor que la media

Cuanto mayor es el kernel de la mediana, más se reduce el ruido pero también más desenfoca. No hay regla fija para elegir el tamaño: hay que hacer pruebas con la imagen concreta.

2. Escalado de imágenes

2.1 Downsampling — reducción

Reducir una imagen descarta información. El método más básico elimina las filas y columnas pares.

Problema: aliasing (efecto diente de sierra). Las zonas de alta frecuencia (bordes) al ser submuestreadas producen artefactos visuales. La causa es violar el teorema de Nyquist: para muestrear correctamente una señal hay que hacerlo a al menos el doble de su frecuencia máxima. ⚠️ EXAMEN

Solución: suavizar la imagen antes de submuestrear (bajar las frecuencias altas = difuminar bordes).

cv2.pyrDown implementa esta solución automáticamente:

  1. Aplica un filtro gaussiano (reduce frecuencias altas).
  2. Elimina filas y columnas pares → imagen a la mitad.
img_reducida = cv2.pyrDown(img)          # mitad del tamaño
img_reducida2 = cv2.pyrDown(img_reducida) # cuarto del tamaño (aplicación sucesiva)

pyrDown siempre reduce exactamente a la mitad. No es configurable.

2.2 Upsampling — ampliación

Ampliar una imagen no crea información nueva, solo aumenta la densidad.

cv2.pyrUp es la función opuesta a pyrDown:

  1. Inserta filas y columnas de ceros (negros) en posiciones pares.
  2. Aplica el mismo filtro gaussiano para suavizar los saltos introducidos.
img_ampliada = cv2.pyrUp(img)   # doble del tamaño

También siempre amplía exactamente al doble.

Pérdida encadenada: aplicar pyrDown seguido de pyrUp produce una imagen notablemente más borrosa que la original, porque primero se ha descartado información y luego se han interpolado los huecos con gaussiano.

2.3 cv2.resize — escalado de calidad superior

resize no trabaja con el algoritmo rudimentario de filas/columnas pares. Utiliza interpolación para calcular los valores de los píxeles nuevos.

# Ampliar al doble con interpolación cúbica (recomendado para upsampling)
img_grande = cv2.resize(img, (0, 0),
                        fx=2, fy=2,
                        interpolation=cv2.INTER_CUBIC)

# Reducir a la mitad con interpolación por área (recomendado para downsampling)
img_peq = cv2.resize(img, (0, 0),
                     fx=0.5, fy=0.5,
                     interpolation=cv2.INTER_AREA)

Parámetros: - dsize=(0,0) o None: usa los factores de escala fx, fy en lugar de tamaño absoluto. - interpolation: método de interpolación.

Constante Uso recomendado
cv2.INTER_AREA Downsampling (reducción) — el manual de OpenCV lo recomienda
cv2.INTER_CUBIC Upsampling (ampliación) — interpolación cúbica por splines
cv2.INTER_LINEAR Uso general (opción por defecto)

resize produce resultados notablemente más nítidos que pyrDown/pyrUp porque en lugar de insertar ceros, interpola un valor entre los píxeles vecinos generando transiciones suaves. ⚠️ EXAMEN

3. Filtros de realce

Lo opuesto a los filtros de suavizado: potencian en lugar de atenuar.

3.1 Realce de bordes

Kernel que amplifica los cambios bruscos de intensidad. Aplicado a un retrato, resalta pelo, cejas, pecas y cualquier contorno. Útil como paso en un pipeline de "cartoonización" (resaltar contornos + colorear zonas planas).

kernel_realce = np.array([[-1, -1, -1],
                           [-1,  9, -1],
                           [-1, -1, -1]], dtype=np.float32)
img_realzada = cv2.filter2D(img, -1, kernel_realce)

3.2 Ecualización de histograma — realce de contraste ⚠️ EXAMEN

El objetivo es redistribuir las intensidades de la imagen para que cubran todo el rango [0, 255], aumentando el contraste global y revelando detalles que no se aprecian a simple vista.

Cómo funciona: el histograma ecualizado "estira" el histograma concentrado. No produce una distribución plana perfecta, pero sí reparte las ocurrencias por todo el rango.

Casos de uso: - Imágenes muy oscuras o muy claras donde los detalles son invisibles. - Imágenes científicas y médicas (no añade información clínica, solo redistribuye el contraste). - Preprocesado previo al análisis cuando el contraste es escaso.

# La función requiere imagen en escala de grises
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img_eq = cv2.equalizeHist(img_gray)

cv2.equalizeHist solo acepta imágenes en escala de grises (un canal). Si se quiere ecualizar solo una zona, se usa una máscara.

Ejemplos de la profesora: - Búho (imagen oscura): al ecualizar aparecen ramas y detalles de fondo prácticamente invisibles en la original. - Imagen muy clara: se pierde blanco y aparece contraste en zonas antes "quemadas". - Imagen negra (aparentemente vacía): al ecualizar aparece un objeto completo que no se podía intuir.

Con el uso de máscaras se puede ecualizar solo una zona de la imagen y no alterar el resto (por ejemplo, solo el fondo y no el sujeto principal).


Estructura del Examen ⚠️ EXAMEN

Formato

  • Duración: 90 minutos (cambio a partir de este PER de primavera 2026).
  • 2 problemas:
  • Problema 1 — OpenGL: 7 puntos. Representar una escena 3D con cubos unitarios monocolor. Se facilita el módulo .py de funciones de apoyo de la profesora. Se puede usar ese módulo o crear funciones propias. El elemento básico siempre debe ser un cubo unitario monocolor.
  • Problema 2 — OpenCV: 3 puntos. Enunciado corto con un ejercicio de procesamiento de imágenes.
  • Entrega: ficheros de código en un ZIP.

Materiales permitidos

  • Todo el contenido del aula Moodle (transparencias, cuadernos Jupyter, vídeos, actividades propias entregadas).
  • Esos mismos ficheros descargados en local (para no perder tiempo buscando en Moodle durante el examen).
  • El entorno de desarrollo propio (Anaconda, Visual Studio Code, JupyterLab, PyCharm, Spyder).
  • Hojas de papel en blanco para bocetos.

No permitido: plantillas o ficheros preparados expresamente para el examen que no sean material del aula o actividades propias entregadas. GitHub Copilot y extensiones similares, deshabilitadas.

Consejos de la profesora

  • Asegurar la parte de OpenGL (7 puntos): practicar construyendo escenas con cubos, medir tiempos. Con un buen resultado en OpenGL ya se tiene casi aprobada la asignatura.
  • La profesora colgará exámenes de otros años (solo la parte de OpenGL) para practicar.
  • Llevar portátil propio (imprescindible, el examen es de programación).
  • Anotar en papel el teléfono de incidencias técnicas del examen.
  • Avisar siempre en voz alta (cámara lateral) antes de cualquier acción durante el examen.
  • Acceder a Anaconda desde Anaconda Navigator (no desde terminal del sistema) para evitar problemas de permisos.

Preguntas de Autoevaluación

  1. ¿Qué hace el filtro de la mediana y en qué se diferencia de la convolución?
  2. ¿Por qué el filtro de la mediana elimina el ruido sal-pimienta pero el filtro de la media no?
  3. ¿Qué es el aliasing en imágenes y por qué se produce al hacer downsampling?
  4. ¿Qué dice el teorema de Nyquist y cómo se aplica al escalado de imágenes?
  5. ¿Qué pasos realiza internamente cv2.pyrDown? ¿Y cv2.pyrUp?
  6. ¿Por qué cv2.resize produce mejor calidad que pyrDown/pyrUp encadenados? ¿Qué interpolación recomienda el manual para upsampling? ¿Y para downsampling?
  7. ¿Para qué sirve la ecualización de histograma? ¿Qué función de OpenCV la implementa?
  8. ¿Qué tipo de imagen acepta cv2.equalizeHist? ¿Qué hacer si se quiere ecualizar solo una zona?
  9. ¿Cuál es la puntuación de cada parte del examen? ¿Cuánto dura?
  10. ¿Qué materiales están permitidos en el examen y cuáles no?