# -*- coding: utf-8 -*-
"""
Created on Mon Jan 10 16:51:39 2022
@author: Liu_Jun_Desktop
"""
import numpy as np
from PIL import Image
import xlrd
import openpyxl
import xlwt
import pandas as pd
import matplotlib.pyplot as plt
def load_image(filepath):#下载图像
im = Image.open(filepath)
return np.array(im)
def svd(A):#进行奇异值分解
return np.linalg.svd(A)
def rebuildsvd(U, S, V):#根据计算的奇异值重建图像
r = len(S)
return np.dot(U[:,:r] * S, V[:r,:])
def setZeros(U, S, V, k):#将三个矩阵的无关值置零
r = len(S)
for i in range(k, r):
U[:, i] = 0
S[i] = 0
V[i, :] = 0
return U, S, V
def total_variation(S, k):#总变化率求解
return np.sum(S[:k]) / np.sum(S)
def generate_sheet_names():#生成文件名
list = []
for j in range(3):
list.append(str(j)+"通道U矩阵")
list.append(str(j)+"通道S矩阵")
list.append(str(j)+"通道V矩阵")
return list
def img_process(img, k): # 图像处理
img2 = np.zeros_like(img)
tv = 1.0
sheetname=generate_sheet_names()
for c in range(img.shape[2]):
A = img[:,:,c]#三个通道分别进行依次计算
U, S, V = svd(A)
tv *= total_variation(S,k)
U, S, V = setZeros(U,S,V,k)
if c==0:
U_matrix0=pd.DataFrame(U)
S_diag1=pd.DataFrame(np.diag(S))
V_matri2=pd.DataFrame(V)
elif c==1:
U_matrix3=pd.DataFrame(U)
S_diag4=pd.DataFrame(np.diag(S))
V_matri5=pd.DataFrame(V)
else:
U_matrix6=pd.DataFrame(U)
S_diag7=pd.DataFrame(np.diag(S))
V_matri8=pd.DataFrame(V)
if k==4**2 and c==2:
with pd.ExcelWriter('奇异矩阵.xlsx') as writer:
U_matrix0.to_excel(writer, sheet_name=sheetname[0])
S_diag1.to_excel(writer, sheet_name=sheetname[1])
V_matri2.to_excel(writer, sheet_name=sheetname[2])
U_matrix3.to_excel(writer, sheet_name=sheetname[3])
S_diag4.to_excel(writer, sheet_name=sheetname[4])
V_matri5.to_excel(writer, sheet_name=sheetname[5])
U_matrix6.to_excel(writer, sheet_name=sheetname[6])
S_diag7.to_excel(writer, sheet_name=sheetname[7])
V_matri8.to_excel(writer, sheet_name=sheetname[8])
writer.save()
img2[:,:,c] = rebuildsvd(U, S, V)
return img2, tv
def compression_ratio(A, k):#图像压缩率计算
denominator = A.shape[0] * A.shape[1] * A.shape[2]
nominator = (A.shape[0] *np.sqrt(k) +np.sqrt(k)* A.shape[1] + k) * A.shape[2]
return 1 - (nominator/denominator)
if __name__=="__main__":#代码测试
filepath = 'lena_std.jpg'
lenna = load_image(filepath)
plt.imshow(lenna)
U,S,V=np.linalg.svd(lenna[:,:,0])
print("奇异值分解前的lenna,U,S,V维度:")
print(lenna.shape)
print(U.shape)
print(S.shape)
print(V.shape)
print('S的值如下:')
# S_diag=np.diag(S)
df=pd.DataFrame(S)
df.to_excel('原始奇异值矩阵.xlsx',sheet_name='未进行奇异值\
分解的0通道S对角矩阵0',index=False)
plt.figure(figsize=(20,10))
plt.subplot(141)
img, variance = img_process(lenna, 4)
ratio = compression_ratio(lenna, 4)
plt.imshow(img)
plt.title('{:.2%} / {:.2%}'.format(variance, ratio))
plt.subplot(142)
img, variance = img_process(lenna, 4 **2)
ratio = compression_ratio(lenna, 4 **2)
plt.imshow(img)
plt.title('{:.2%} / {:.2%}'.format(variance, ratio))
plt.subplot(143)
img, variance = img_process(lenna, 4 **3)
ratio = compression_ratio(lenna, 4 **3)
plt.imshow(img)
plt.title('{:.2%} / {:.2%}'.format(variance, ratio))
plt.subplot(144)
img, variance = img_process(lenna, 4**4)
ratio = compression_ratio(lenna,4**4)
plt.imshow(img)
plt.title('{:.2%} / {:.2%}'.format(variance, ratio))
svd图像压缩代码
最新推荐文章于 2024-05-16 11:19:15 发布