这一篇主要是代码,后面有理论。
import numpy as np
from PIL import Image
img = Image.open("3.png").convert("RGB")
n, m = img.size
pix = img.load()
r, g, b= img.split()
red = np.array(r)
green = np.array(g)
blue = np.array(b)
以上将图像读取并分离为rgb
from numpy.linalg import svd
def chg(pic):
U, s, VT = svd(pic)
Sigma = np.zeros( (pic.shape[0], pic.shape[1]) )
Sigma[:min(pic.shape[0],pic.shape[1]), :min(pic.shape[0],pic.shape[1])] = np.diag(s)
k=150
pic_approx = U[:, :k] @ Sigma[:k, :k] @ VT[:k, :]
return pic_approx
将矩阵分解为U, S, VT
red = chg(red)
green = chg(green)
blue = chg(blue)
red = np.clip(red, 0, 255)
green = np.clip(green, 0, 255)
blue = np.clip(blue, 0, 255)
imageR = Image.fromarray(red.astype('uint8'), 'L')
imageG = Image.fromarray(green.astype('uint8'), 'L')
imageB = Image.fromarray(blue.astype('uint8'), 'L')
Image.merge("RGB",(imageR, imageG, imageB)).show()
原图

压缩后

只使用了前50个奇异值(特征值),压缩了约十倍大小