Image Compression

The goal of this notebook is to explore image compression using various forms of matrix decomposition.

In [1]:
import numpy as np
from numpy import random
import math
from matplotlib import pyplot as plt
from scipy import misc
import scipy
from tqdm import tqdm, trange
from time import perf_counter
In [2]:
%cd ..
from rputil import *
%cd -

Here is the sample image we will be using for all our experiments in this notebook:

In [3]:
face = misc.face()
data = face[:,:,0] / 255
In [4]:
(768, 1024)


First we use a canned PCA routine as a baseline for image compression:

In [5]:
from sklearn.decomposition import PCA
pca = PCA(0.95)
approx = pca.inverse_transform(pca.fit_transform(data))

The resulting image is almost indistinguishable from the original.

Next, we illustrate some of the image compression methods we have implemented:

In [6]:
def plot_approx_array(rank):
    fig, ax = plt.subplots(1,5, figsize=(15,2.5))

    # Original Data
    ax[0].set_xlabel('Original data')

    # Singular Value Decomposition
    start = perf_counter()
    ax[1].imshow(svd_rank_k(data, rank))
    ax[1].set_xlabel('Singular Value Decomposition')
    print(f'SVD: {perf_counter() - start}')

    # Randomized SVD
    start = perf_counter()
    ax[2].imshow(random_svd_rank_k(data, rank))
    ax[2].set_xlabel('Randomized SVD')
    print(f'RSVD: {perf_counter() - start}')

    # Interpolative Decomposition
    start = perf_counter()
    ax[3].imshow(id_rank_k(data, rank))
    ax[3].set_xlabel('Interpolative Decomposition')
    print(f'ID: {perf_counter() - start}')

    # Randomized ID
    start = perf_counter()
    ax[4].imshow(random_id_rank_k(data, rank))
    ax[4].set_xlabel('Randomized ID')
    print(f'RID: {perf_counter() - start}')

    plt.suptitle(f'Rank-{rank} Approximations')
In [7]:
SVD: 0.2247085999999996
RSVD: 0.023911800000000483
ID: 0.12913830000000015
RID: 0.030367000000000033
In [8]:
SVD: 0.2632754999999998
RSVD: 0.04349679999999978
ID: 0.12046409999999952
RID: 0.03117350000000041