Created
September 21, 2015 12:07
-
-
Save thekensta/0c2d54c69c6e7ee3a308 to your computer and use it in GitHub Desktop.
SVD Image Compression
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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