Singular Value Decomposition applied to Images + Streamlit App

Guillermo Velazquez
MCD-UNISON
Published in
5 min readMar 18, 2024

Introduction

Singular Value Decomposition (SVD) plays a pivotal role in linear algebra and finds numerous applications, notably in lossy image compression. With the ever-increasing demand for storage space for images, various compression techniques have been explored. Many of these techniques yield changes that are imperceptible to the human eye while achieving significant reductions in storage requirements.

SVD

Singular Value Decomposition (SVD) is a process that breaks down a matrix A into three matrices. This computation enables us to preserve essential singular values crucial for the image’s quality, while discarding less critical values, optimizing image retention and quality.

Images as matrices

It’s important to recognize that computers represent images as matrices of numbers. For grayscale images, this representation is typically in the form M x N. However, for colored images, it is more common to encounter matrices of the form M x N x C, where C represents the number of channels. Channels are commonly utilized in constructing colored images, such as RGB or BGR. In certain applications, like satellite imagery, more than three channels may be used to store additional information, such as color and infrared data.

By applying Singular Value Decomposition (SVD) to an image, we aim to generate a reduced version with minimal information loss.

Red, green and blue channels of image. Source.

Truncated SVD

Scikit Learn provides a convenient high-level class for applying Truncated Singular Value Decomposition (SVD) to our data. By specifying the desired number of components, we can easily generate new data representations. It’s crucial to note that choosing fewer components results in a loss of information.

Let’s illustrate this by applying image decomposition to a face image generated by a GAN, with a dimension of 1024 x 1024.

import numpy as np
import matplotlib.pyplot as plt

plt.figure(figsize=(6,6))
face = plt.imread("face.jpg")
plt.imshow(face )
plt.title("Original colored image")
plt.show()
Colored image of a face

To simplify the process, let’s work with a grayscale version of our image. One common method to convert colored images to grayscale is by applying the mean function to its three RGB channels.

# We get the mean of the last dimension (channels)
gray_face = np.mean(face, axis=-1)
plt.figure(figsize=(6,6))
plt.imshow(gray_face, cmap="gray")
plt.title("Grayscale image")
plt.show()
Grayscale image of a face

Now, let’s instantiate our TruncatedSVDobject to handle the decomposition logic seamlessly.

k = 100 # We define k (number of components)
svd = TruncatedSVD(n_components=k)
svd.fit(gray_face)
U, S, V = svd.transform(gray_face), svd.singular_values_, svd.components_

Using the .fit() and .transform() methods

Calling the .fit() method on our TruncatedSVD object instructs it to learn the structure of our image for reduction. Subsequently, employing the .transform() method adjusts the parameters based on the provided data. The TruncatedSVD class simplifies this process, providing us with the three matrices from the theoretical SVD.

  • U: Contains important features of our columns.
  • Σ: Holds the singular values.
  • V: Contains important features of our rows.

Image reconstruction

To reconstruct our image, we simply multiply the matrices U and V. In other words, we combine the features from our columns and rows to recreate the original image.

reconstructed_face = U @ V

plt.figure(figsize=(12,6))
plt.subplot(1, 2, 1)
plt.imshow(gray_face, cmap="gray")
plt.title("Original image")

plt.subplot(1, 2, 2)
plt.title(f"Reconstructed image with $k={k}$")
plt.imshow(reconstructed_face, cmap="gray")
plt.show()
Original and reconstructed image

We can see that using only 100 components, we get a great reconstruction of our image.

Explained Variance

Using just 100 components, we achieve a remarkably accurate reconstruction of our image.

plt.figure(figsize=(10,6))
cumulative = np.cumsum(svd.explained_variance_ratio_)
plt.title("Explained variance")
plt.plot(np.arange(k), cumulative)
plt.xlabel("Number of components")
plt.ylabel("Cumulative explained variance")
plt.show()

This plot illustrates that with 100 components, we capture 98% of the original image variance. As anticipated, increasing the number of components should allow us to explain even more variance.

Space Utilization Comparison

Let’s calculate the space used by the original and reconstructed image:

  1. Original Image:
    Dimensions: 1024 x 1024 = 1,048,576 pixel values
  2. Reconstructed Image:
    - U: 1024 x 100 = 102,400
    - V: 100 x 1024 = 102,400
    - Total: 102,400 x 2 = 204,800 pixel values

So, the reconstructed image utilizes only 19.53% of the original size.

Streamlit App: A User-Friendly SVD Tool

Leveraging the power of ChatGPT and drawing inspiration from Siddhant Sadangi’s repository, I’ve developed a user-friendly Streamlit application (App Repo 💻).

This app empowers users to effortlessly perform Singular Value Decomposition (SVD) on an image of their preference.

Feel free to explore the app, upload your images, and witness firsthand the transformative effects of Singular Value Decomposition. Happy decomposing!

App demo

Conclusion: Unlocking Image Insights with SVD

In summary, our exploration of Singular Value Decomposition (SVD) has illuminated its profound impact on image processing, specifically in the realm of compression. Unveiling the principles of SVD, we’ve seen how this fundamental linear algebra concept can be a game-changer in balancing data reduction and image quality.

From breaking down images into matrices to applying Truncated SVD for reconstruction, our journey has demonstrated the tangible effects of component selection on image fidelity. The creation of a Streamlit app integrates theory with practice, providing a user-friendly interface for dynamic experimentation.

As we wrap up this exploration, we invite you to continue delving into the fascinating intersection of linear algebra and image analysis. Whether you’re a seasoned practitioner or a curious enthusiast, the world of Singular Value Decomposition beckons for further exploration. May your coding endeavors be both rewarding and enlightening!

Happy coding!

--

--