Skip to content

Instantly share code, notes, and snippets.

@Groot90
Created March 19, 2019 14:09
Show Gist options
  • Select an option

  • Save Groot90/09d07ba43939382d93e97d0dce43112b to your computer and use it in GitHub Desktop.

Select an option

Save Groot90/09d07ba43939382d93e97d0dce43112b to your computer and use it in GitHub Desktop.
Python, SVD for image compression example
'''
Objective:
Using SVD for image compression
'''
import numpy
from PIL import Image
# FUNCTION DEFINTIONS:
# open the image and return 3 matrices, each corresponding to one channel (R, G and B channels)
def openImage(imagePath):
imOrig = Image.open(imagePath)
im = numpy.array(imOrig)
aRed = im[:, :, 0]
aGreen = im[:, :, 1]
aBlue = im[:, :, 2]
return [aRed, aGreen, aBlue, imOrig]
# compress the matrix of a single channel
def compressSingleChannel(channelDataMatrix, singularValuesLimit):
uChannel, sChannel, vhChannel = numpy.linalg.svd(channelDataMatrix)
aChannelCompressed = numpy.zeros((channelDataMatrix.shape[0], channelDataMatrix.shape[1]))
k = singularValuesLimit
leftSide = numpy.matmul(uChannel[:, 0:k], numpy.diag(sChannel)[0:k, 0:k])
aChannelCompressedInner = numpy.matmul(leftSide, vhChannel[0:k, :])
aChannelCompressed = aChannelCompressedInner.astype('uint8')
return aChannelCompressed
# MAIN PROGRAM:
print ('*** Image Compression using SVD - a demo')
aRed, aGreen, aBlue, originalImage = openImage('lena.png')
# image width and height:
imageWidth = 512
imageHeight = 512
#number of singular values to use for reconstructing the compressed image
singularValuesLimit = 160
aRedCompressed = compressSingleChannel(aRed, singularValuesLimit)
aGreenCompressed = compressSingleChannel(aGreen, singularValuesLimit)
aBlueCompressed = compressSingleChannel(aBlue, singularValuesLimit)
imr=Image.fromarray(aRedCompressed,mode=None)
img=Image.fromarray(aGreenCompressed,mode=None)
imb=Image.fromarray(aBlueCompressed,mode=None)
newImage = Image.merge("RGB", (imr,img,imb))
originalImage.show()
newImage.show()
# CALCULATE AND DISPLAY THE COMPRESSION RATIO
mr = imageHeight
mc = imageWidth
originalSize = mr * mc * 3
compressedSize = singularValuesLimit * (1 + mr + mc) * 3
print('original size:')
print(originalSize)
print('compressed size:')
print(compressedSize)
print('Ratio compressed size / original size:')
ratio = compressedSize * 1.0 / originalSize
print(ratio)
print('Compressed image size is ' + str( round(ratio * 100 ,2)) + '% of the original image ' )
print('DONE - Compressed the image! Over and out!')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment