The goal of this notebook is to explore image compression using various forms of matrix decomposition.
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
%cd ..
from rputil import *
%cd -
Here is the sample image we will be using for all our experiments in this notebook:
face = misc.face()
data = face[:,:,0] / 255
plt.imshow(data);
data.shape
First we use a canned PCA routine as a baseline for image compression:
from sklearn.decomposition import PCA
pca = PCA(0.95)
approx = pca.inverse_transform(pca.fit_transform(data))
plt.imshow(approx);
The resulting image is almost indistinguishable from the original.
Next, we illustrate some of the image compression methods we have implemented:
def plot_approx_array(rank):
fig, ax = plt.subplots(1,5, figsize=(15,2.5))
# Original Data
ax[0].imshow(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')
plot_approx_array(10)
plot_approx_array(100)