利用SVD分解压缩图像

from PIL import Image
import numpy as np

# 利用SVD分解处理并返回压缩后的数据
def svd_approx(data, per): # data是数据矩阵,per代表处理的奇异值个数占比
if per > 1 or per < 0:
print("percentage error!")
return
U, s, VT = np.linalg.svd(data)
Sigma = np.zeros(np.shape(data))
Sigma[:len(s), :len(s)] = np.diag(s)
k = int(per * len(s))
D = U[:, :k] @ Sigma[:k, :k] @ VT[:k, :]
D[D < 0] = 0
D[D > 255] = 255
return np.rint(D).astype("uint8") # rint是根据四舍五入取整


# 导入图像,进行SVD压缩,输出图像
def rebuild_img(filename, per):
img = Image.open(filename)
data = np.array(img)
R, G, B = data[:, :, 0], data[:, :, 1], data[:, :, 2]
color = [R, G, B]
new_color = []
for color in [R, G, B]:
new_color.append(svd_approx(color, per))
I = np.stack(new_color, 2)
svae_name = str(round(per * 100, 0)) + ".jpg"
Image.fromarray(I).save(svae_name)
img = Image.open(svae_name)
img.show()

filename = "test.jpeg" #这里设置图像的文件名
for per in np.linspace(0.01, 1, 10): #这里选择保留特征值的占比
rebuild_img(filename, per)

    所属分类:Python     发表于2022-02-04