Optimizing Image Compression with Wavelet Transform and Singular Value Decomposition: A Step-by-Step Guide

Sreya GhoshSreya Ghosh
3 min read

Hi!! How have you all been? I will start first. It was a hella ride from working to penning down what I have been reading. It was fun, not gonna lie, but I feel I hadn't been able to write much about my projects!

I had discussed Image compression and using wavelet methods earlier in my medium blogs, but today, I would love to take a different take and would like to show you how Singular Value Decomposition (SVD) just levels up the game!

Let's understand the basic notions first. You can check out Image Compression using Wavelet for some detailed clarity on how to compress an image. The wavelet transform is a widely used technique for multiresolution analysis of images, enabling efficient extraction of different frequency subbands. In this blog, I will discuss how SVD allows you to compress and why it is recommended.

Image compression plays a crucial role in the digital storage and transmission of images over the Internet. Different methods are used for encoding and compressing image data, to find a balance between compression efficiency and image fidelity.

SVD allows for more flexibility in selecting the desired level of compression by choosing the number of singular values to retain. This flexibility allows for a trade-off between compression ratio and image quality, making SVD a suitable choice for applications where preserving image fidelity is important. Additionally, SVD provides a low-rank approximation, which means that it can effectively capture and represent the most important features of the image with a reduced number of singular values. This leads to efficient compression without significant loss of information or image quality. Using SVD for image compression involves finding the optimal approximation of the image in terms of the singular values and vectors. This optimal approximation results in high-quality compression, as it retains the most important information and eliminates redundant or less important details.

Singular Value Decomposition (SVD) decomposes the image into its constituent parts: singular values and singular vectors. These singular values correspond to the energy contained in each component, with lower singular values representing less critical information.

As it is evident that SVD and DWT are powerful tools, can they combine to get a better result? Let's find it out.

import cv2
import numpy as np
import pywt
from google.colab.patches import cv2_imshow
import matplotlib.pyplot as plt

Installed necessary packages.

img = cv2.imread("/content/IMG-20231030-WA0198.jpg")

gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

The code first reads an image, converts it to grayscale, and performs a 2D wavelet decomposition using the Haar wavelet.

coeffs = pywt.wavedec2(gray_img, 'haar', level=2)

The horizontal detail subband coefficients are then extracted and their magnitude is plotted . The code then applies singular value decomposition to each subband and compresses the coefficients using a desired compression ratio.

plt.imshow(magnitude, cmap='gray')
plt.title('Magnitude of Horizontal Detail Subband')
plt.colorbar()
plt.show()

The compressed coefficients are then used to reconstruct the compressed image using the inverse wavelet transform. This approach allows for selective compression of different frequency subbands, balancing image quality and compression ratio .

compressed_coeffs = []
for i in range(1, len(coeffs)):
    cH, cV, cD = coeffs[i]
    U_h, S_h, Vt_h = np.linalg.svd(cH)
    U_v, S_v, Vt_v = np.linalg.svd(cV)
    U_d, S_d, Vt_d = np.linalg.svd(cD)
    print("Singular values for horizontal subband:", S_h)
    print("Singular values for vertical subband:", S_v)
    print("Singular values for diagonal subband:", S_d)
    threshold = np.max(np.abs(cH)) * compression_ratio
    compressed_coeff = [pywt.threshold(cH, threshold, mode='soft'),
                        pywt.threshold(cV, threshold, mode='soft'),
                        pywt.threshold(cD, threshold, mode='soft')]
    compressed_coeffs.append(tuple(compressed_coeff))
num_singular_values_retained = int(compression_ratio * len(S_h))
print("Number of singular values:",num_singular_values_retained)

The hybrid method can be beneficial in applications where high-quality reconstruction of specific regions of interest is required while achieving significant overall compression. As demonstrated in the code, the integration of wavelet transform and SVD enables the preservation of essential image information while achieving high compression rates.

You can check out my GitHub for the elaborate code and the results. Do recommend me changes or better paths I might implement-would love to collaborate! What projects are you currently working on? Do let me know in the comment section!

0
Subscribe to my newsletter

Read articles from Sreya Ghosh directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Sreya Ghosh
Sreya Ghosh