Friday, August 29, 2025

Machine Learning: Simple Image Compression using Singular Value Decomposition (SVD)


Singular Value Decomposition (SVD) is a matrix factorization technique commonly used in machine learning for dimensionality reduction, data compression, and feature extraction. It decomposes a matrix into three simpler matrices, revealing underlying patterns in the data. 


As seen from the above, the original picture on the left is compressed to the picture on the right. From the picture below, we can see that the file size of the image 'compressed_dog' is just 59kb, compare to 'dog' of 173kb.







Python Code by Grok

import numpy as np

from PIL import Image

import matplotlib.pyplot as plt


# Step 1: Load the color image from specified directory

image_path = "C:/Users/Ee Leen/dog.jpg"  # Image path

image = Image.open(image_path)  # Load color image

image_array = np.array(image)  # Shape: (height, width, 3)


# Step 2: Separate RGB channels

r = image_array[:, :, 0]  # Red channel

g = image_array[:, :, 1]  # Green channel

b = image_array[:, :, 2]  # Blue channel


# Step 3: Apply SVD to each channel

k = 20  # Changed from 50 to 20

Ur, sigmar, Vtr = np.linalg.svd(r, full_matrices=False)

Ug, sigmag, Vtg = np.linalg.svd(g, full_matrices=False)

Ub, sigmab, Vtb = np.linalg.svd(b, full_matrices=False)


# Step 4: Reduce dimensions for each channel

Ur_k = Ur[:, :k]

sigmar_k = np.diag(sigmar[:k])

Vtr_k = Vtr[:k, :]


Ug_k = Ug[:, :k]

sigmag_k = np.diag(sigmag[:k])

Vtg_k = Vtg[:k, :]


Ub_k = Ub[:, :k]

sigmab_k = np.diag(sigmab[:k])

Vtb_k = Vtb[:k, :]


# Step 5: Reconstruct each channel

r_compressed = np.dot(Ur_k, np.dot(sigmar_k, Vtr_k))

g_compressed = np.dot(Ug_k, np.dot(sigmag_k, Vtg_k))

b_compressed = np.dot(Ub_k, np.dot(sigmab_k, Vtb_k))


# Step 6: Combine channels into a single image

compressed_image = np.stack([r_compressed, g_compressed, b_compressed], axis=2)

compressed_image = np.clip(compressed_image, 0, 255).astype(np.uint8)


# Step 7: Display original and compressed images

plt.figure(figsize=(10, 5))

plt.subplot(1, 2, 1)

plt.title("Original Image")

plt.imshow(image_array)

plt.axis("off")


plt.subplot(1, 2, 2)

plt.title(f"Compressed Image (k={k})")

plt.imshow(compressed_image)

plt.axis("off")

plt.show()


# Step 8: Save compressed image

output_path = "C:/Users/Ee Leen/compressed_dog.jpg"  # Output path

Image.fromarray(compressed_image).save(output_path)






No comments:

Post a Comment