image-compression/compressionRGB.py
2023-12-09 12:36:06 +00:00

72 lines
2.1 KiB
Python

# -*- coding: utf-8 -*-
import matplotlib.pyplot as plt
import numpy as np
#import image
imCol = plt.imread("mini.jpg", format=None)
imRecons = np.zeros((len(imCol[:,0]), len(imCol[0,:]), 3))
erreur = np.ones((len(imCol[:,0]), len(imCol[0,:]), 3))
iterationsGlobales = 10
iterations = 10
imRecons[:,:,:] = imCol[:,:,:]
# Compress all channels one by one
for channel in range(len(imCol[0,0,:])): # for each color channel of original image
FF= [[]]*len(imCol[:,:,channel]) # all channels should have the same dimsneions but eh
GG= [[]]*len(imCol[0,:,channel])
for x in range(iterationsGlobales):
F=np.ones((len(imRecons[:,0,channel]), 1))
G=np.ones((len(imRecons[0,:,channel]), 1))
for y in range(iterations):
F = np.dot(imRecons[:,:,channel], G) / np.dot(np.transpose(G), G)
G = np.dot(np.transpose(imRecons[:,:,channel]), F) / np.dot(np.transpose(F), F)
FF = np.append(FF, F, 1)
GG = np.append(GG, G, 1)
imRecons[:,:,channel] = imRecons[:,:,channel] - np.dot(F,np.transpose(G))
erreur[:,:,channel] = imRecons[:,:,channel] - np.dot(FF,np.transpose(GG))
imRecons[:,:,channel] = np.dot(FF,np.transpose(GG))
#why does imRecons not fall into the 255 range ?
# why does plt need it to be between 0 and 1 where imCol is fine being 0 to 255 ? because it's not an int ?
print(np.max(imRecons))
imRecons = imRecons/np.max(imRecons)
#erreur = erreur/255
#compression rate
tauxComp = round(100-((len(imCol[:,0])+len(imCol[0,:]))*iterationsGlobales)/((len(imCol[:,0])*len(imCol[0,:])))*100,0)
print(tauxComp, "% de compression")
# plot
plt.figure(dpi=300)
plt.subplot(1, 3, 1)
plt.axis('off')
plt.title("Original", loc='center', pad=None)
plt.imshow(imCol, interpolation = "nearest")
plt.subplot(1, 3, 2)
plt.axis('off')
plt.title("Error", fontdict=None, loc='center', pad=None)
plt.imshow(erreur, interpolation = "nearest")
plt.subplot(1, 3, 3)
plt.axis('off')
plt.title("Compressed "+ str(tauxComp) +"%", fontdict=None, loc='center', pad=None)
plt.imshow(imRecons, interpolation = "nearest")
plt.show()