Skip to content

Instantly share code, notes, and snippets.

@thekensta
Created September 21, 2015 12:07
Show Gist options
  • Save thekensta/0c2d54c69c6e7ee3a308 to your computer and use it in GitHub Desktop.
Save thekensta/0c2d54c69c6e7ee3a308 to your computer and use it in GitHub Desktop.
SVD Image Compression
# Ipython code using SVD to extract components of an image
%matplotlib inline
import matplotlib.pyplot as plt
import matplotlib.cm as cmap
import numpy as np
from scipy import ndimage
# Any image file here, this is colourso convert to greyscale
DOG_IMAGE_FILE = "dog2.jpg"
dog = ndimage.imread(DOG_IMAGE_FILE)
# Greyscale the image
# Simple mean - didn't use this one
# gdog = dog.mean(axis=2)
# Fix with NTSC transform
gdog = 0.299 * dog[:,:,0] + 0.587 * dog[:,:,1] + 0.114 * dog[:,:,2]
plt.imshow(gdog, cmap=cmap.gray)
# Decompose the image matrix
U, S, V = np.linalg.svd(gdog)
# Shape of the image I am using
print(U.shape, S.shape, V.shape)
# (768, 768) (768,) (1024, 1024)
# Plot the percentage of information in each component for info
plt.plot(S.cumsum() / S.sum())
plt.ylim(0, 1.1)
# Reconstruct the image at different detail levels
approx_dogs = []
detail_levels = [1, 2, 4, 5, 10, 30, 100, 500, 768]
for detail in detail_levels:
n = detail
sigmat = np.zeros((U.shape[0], V.shape[1]))
# Fill S matrix with N components
# ... is numpy function to do this? fill_diagonal works with scalar only
for i in range(n):
sigmat[i, i] = S[i]
approx_dogs.append(np.dot(U, np.dot(sigmat, V)))
# Show all the images in a grid
plt.figure(figsize=(12, 12))
for i in range(len(approx_dogs)):
plt.subplot(3, 3, i+1)
plt.imshow(approx_dogs[i], cmap=cmap.gray)
plt.title("Detail Level " + str(detail_levels[i]))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment