Reconstrucción de imágenes mediante descomposición de valores singulares (SVD) en Python

La descomposición de valores singulares, también conocida como SVD, es una de las muchas técnicas de descomposición de arrays que descompone una array en 3 subarrays, a saber, U, S, V, donde U es el vector propio izquierdo, S es una array diagonal de valores singulares y V se denomina vector propio derecho. Podemos reconstruir SVD de una imagen usando el método linalg.svd() del módulo NumPy.

Sintaxis: 

linalg.svd(array, arrays_completas=Verdadero, computar_uv=Verdadero, hermitian=Falso)

Parámetros:

  1. array : Una array real o compleja de tamaño > 2.
  2. full_arrays: si es verdadero, el tamaño de las arrays u y v es mxn, si es falso, entonces la forma de las arrays u y v es mxk, donde k es solo valores distintos de cero.
  3. compute_uv: toma un valor booleano para calcular las arrays u y v junto con la array s.
  4. hermitian: por defecto, se supone que la array es hermitiana si contiene valores reales, esto se usa internamente para calcular de manera eficiente los valores singulares.

Imagen utilizada:
 

Python3

# import module
import requests
import cv2
import numpy as np
import matplotlib.pyplot as plt
 
# assign and open image
url = 'https://media.geeksforgeeks.org/wp-content/cdn-uploads/20210401173418/Webp-compressed.jpg'
response = requests.get(url, stream=True)
 
with open('image.png', 'wb') as f:
    f.write(response.content)
 
img = cv2.imread('image.png')
 
# Converting the image into gray scale for faster
# computation.
gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
 
# Calculating the SVD
u, s, v = np.linalg.svd(gray_image, full_matrices=False)
 
# inspect shapes of the matrices
print(f'u.shape:{u.shape},s.shape:{s.shape},v.shape:{v.shape}')

Producción:

u.shape:(3648, 3648),s.shape:(3648,),v.shape:(3648, 5472)

Explicación:

La forma de salida anterior indica que hay 3648 vectores propios linealmente independientes en esta imagen.

Ahora veamos gráficamente la varianza de la imagen utilizada sobre un vector singular:

Python3

# import module
import seaborn as sns
 
var_explained = np.round(s**2/np.sum(s**2), decimals=6)
 
# Variance explained top Singular vectors
print(f'variance Explained by Top 20 singular values:\n{var_explained[0:20]}')
 
sns.barplot(x=list(range(1, 21)),
            y=var_explained[0:20], color="dodgerblue")
 
plt.title('Variance Explained Graph')
plt.xlabel('Singular Vector', fontsize=16)
plt.ylabel('Variance Explained', fontsize=16)
plt.tight_layout()
plt.show()

Producción:

Gráfico explicado de la varianza.

Explicación: El gráfico anterior de varianza explicada muestra claramente que alrededor del 99,77 % de la información se explica por el primer vector propio y sus propios valores propios correspondientes. Por lo tanto, es muy recomendable reconstruir la imagen con solo los primeros vectores propios. 

En el siguiente programa basado en la discusión anterior, reconstruimos la imagen usando SVD: 

Python3

# plot images with different number of components
comps = [3648, 1, 5, 10, 15, 20]
plt.figure(figsize=(12, 6))
 
for i in range(len(comps)):
    low_rank = u[:, :comps[i]] @ np.diag(s[:comps[i]]) @ v[:comps[i], :]
     
    if(i == 0):
        plt.subplot(2, 3, i+1),
        plt.imshow(low_rank, cmap='gray'),
        plt.title(f'Actual Image with n_components = {comps[i]}')
     
    else:
        plt.subplot(2, 3, i+1),
        plt.imshow(low_rank, cmap='gray'),
        plt.title(f'n_components = {comps[i]}')

 Producción:

Imagen reconstruida usando SVD.

Explicación: 

  1. Aunque el primer vector propio contiene el 99,77% de la información, la reconstrucción de una imagen únicamente a partir de él no ofrece una imagen clara.
  2. El uso de los 15 vectores principales para la reconstrucción de la imagen proporciona una aproximación bastante buena. También de 3648 vectores, que es una disminución masiva en el cálculo y también comprime la imagen.

Publicación traducida automáticamente

Artículo escrito por arun singh y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

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