SVD para compresión de imágenes en Python
Clase 12 de 12 • Curso Avanzado de Álgebra Lineal y Machine Learning: PCA y SVD
Contenido del curso
Eigen-Análisis
Reducción de Dimensionalidad con PCA
Descomposición en Valores Singulares (SVD)
Aplicar la descomposición en valores singulares (SVD) para comprimir imágenes en Python es una técnica poderosa y práctica. Con NumPy, Matplotlib y scikit-image, se transforma una imagen en matriz, se conservan solo los valores singulares más importantes y se reconstruye con pocos componentes. ¿El resultado? archivos más ligeros, modelos más rápidos y menos ruido sin perder la estructura visual esencial.
¿Cómo funciona la compresión de imágenes con SVD?
La clave es tratar la imagen como una matriz y descomponerla en tres matrices: U, Σ (sigma) y V transpuesta. Los valores singulares en Σ están ordenados por importancia. Al quedarnos con los primeros k, capturamos las formas y contrastes principales; los últimos suelen representar ruido o detalles finos.
- Una imagen se procesa como matriz de píxeles en escala de grises.
- Se aplica SVD: imagen ≈ U × Σ × Vᵀ.
- Se eligen los k valores singulares más altos.
- Se reconstruye con U_k, Σ_k y Vᵀ_k.
- Se logra compresión y reducción de ruido con mínima pérdida visual.
En el ejemplo, se usa una imagen de tamaño 300 × 200 (300 filas por 200 columnas). Tras SVD, se observan formas y dimensiones típicas: U de 300 × 300, Σ con 200 valores singulares y Vᵀ de 200 × 200. Además, se trabaja en escala de grises mediante rgb2gray, ya que la SVD se aplica a una matriz y no directamente a tres canales de color.
¿Cómo implementarlo en Python paso a paso?
Se demostró el flujo completo en Google Colab: cargar una imagen, redimensionarla, descomponerla con SVD, reconstruir con distintos k y graficar resultados. Con pocos componentes (k pequeños) la imagen luce borrosa; con k intermedios ya es reconocible; con k más altos se ve casi idéntica a la original.
¿Qué imports y preparación necesita Python?
import numpy as np
import matplotlib.pyplot as plt
from skimage import data
from skimage.transform import resize
from skimage.color import rgb2gray
# Cargar y preparar imagen (escala de grises + resize)
imagen_original = rgb2gray(data.rocket())
imagen = resize(imagen_original, (300, 200))
# Descomposición SVD
U, S, VT = np.linalg.svd(imagen)
print(U.shape) # (300, 300)
print(S.shape) # (200,)
print(VT.shape) # (200, 200)
rgb2gray: conversión a escala de grises.resize: ajuste a 300 × 200 para eficiencia.np.linalg.svd: descomposición en U, S, VT.- shape y print para validar dimensiones.
¿Cómo reconstruir la imagen con k valores singulares?
# Reconstrucción con k componentes
def reconstruir_con_k(k):
U_k = U[:, :k]
S_k = np.diag(S[:k])
VT_k = VT[:k, :]
return U_k @ S_k @ VT_k
K_valores = [5, 20, 50]
imagenes_reconstruidas = [reconstruir_con_k(k) for k in K_valores]
# Visualización
fig, axes = plt.subplots(1, 4, figsize=(20, 5))
axes[0].imshow(imagen, cmap='gray')
axes[0].set_title('original')
for i, k in enumerate(K_valores):
axes[i + 1].imshow(imagenes_reconstruidas[i], cmap='gray')
axes[i + 1].set_title(f'reconstrucción con k={k}')
plt.show()
- List comprehension para múltiples k.
- Subplots en una fila y cuatro columnas.
cmap='gray'para escala de grises.- Títulos claros por cada reconstrucción.
Observaciones clave:
- Con k = 5: imagen borrosa, estructura general poco clara.
- Con k = 20: la forma del cohete ya es distinguible.
- Con k = 50: alta similitud con la original.
¿Qué beneficios obtiene el machine learning con SVD?
Más allá de la compresión visual, SVD aporta ventajas directas a flujos de ML: menos datos, más velocidad y mejor generalización al reducir el ruido.
- Eficiencia en almacenamiento y velocidad. Una imagen de 300 × 200 usa 60000 números; con k = 50 guardas una fracción, logrando una compresión de casi 6×. En grandes colecciones, ahorra gigabytes y acelera cargas.
- Aceleración del entrenamiento. En lugar de 60000 píxeles, usar 50 valores singulares por imagen reduce el espacio de características y acelera el entrenamiento.
- Eliminación de ruido (denoising). Al descartar componentes con valores singulares pequeños, filtras grano e imperfecciones del sensor, favoreciendo modelos que aprenden la estructura fundamental y no el ruido.
¿Te animas a practicar? Ejecútalo y prueba con distintos k: ¿cuál es el k mínimo con el que aún reconoces claramente la imagen? Publica tu respuesta y una captura en los comentarios.