奇异值分解矩阵还原灰度图像结果报告
一、由图片生成矩阵
用特征值(奇异值)还原图片涉及到了矩阵的特征值特征向量的应用,奇异值分解矩阵,以及python中numpy与Image库的函数应用。
from PIL import Image
import numpy as np
1.1原图与灰度图
首先将一个彩色图片转换成黑白图片,即灰度图。再将灰度图解析成为一个矩阵,矩阵中的每一个元素代表图片的一个像素,元素值对应像素的灰度值。
def loadImage():
# 读取图片
im = Image.open("1.jpg")
# 显示图片
im.show()
#转换为黑白图片
im = im.convert("L")
#显示黑白图片
im.show()
1.2图片转换矩阵
将灰度图解析为一个像素数组,再转化成一个矩阵(方阵),矩阵中的每一个元素代表图片的一个像素,元素值对应像素的灰度值。
#获取像素信息
data = im.getdata()
#转换为矩阵
data = np.array(data)
#重塑为方阵
data =data.reshape(440, 440)
二、奇异值分解还原图像
为了避免特征值出现复数,用奇异值分解的方式求解奇异值,得到一个由奇异值组成的一维数组data_val,以及两个矩阵data_vec1和data_vec2,再将奇异值数组其转化为对角矩阵。
#取奇异值(data_val是一个奇异值的一维数组)
data_vec1, data_val, data_vec2 = np.linalg.svd(data)
#将奇异值换成对角矩阵
data_val_mat = np.diag(data_val)
2.1取最大特征值还原图像
取前五十个奇异值(也是最大的五十个奇异值)计算得到一个矩阵:
#选取最大的50个值
mat_50_max = data_vec1[:,:50]@data_val_mat[0:50, 0:50]@data_vec2[:50, :]
img_50_max = Image.fromarray(mat_50_max)
img_50_max.show()
用这个矩阵还原的图片如下:
定义一个函数,能够取最大的任意几个奇异值还原图片
#定义函数取最大前几个奇异值还原图片
def max (n):
data_val_any = np.diag(data_val[: n])
mat_new_any = data_vec1[:, 0:n]@data_val_any@data_vec2[0:n, :]
return Image.fromarray(mat_new_any).show()
max(20)
取最大20个奇异值得到的图片如下:
2.2取最小特征值还原图像
由于图片的特殊性,最小的50个奇异值得到的图片都是黑色,当取400个最小奇异值时,才显示出图片的雏形:
#定义取最小几个值的函数
def min(n):
mat_min = data_vec1[:, -n:]@data_val_mat[-n:, -n:]@data_vec2[-n:, :]
img_min = Image.fromarray(mat_min)
img_min.show()
min(50)
min(440)
50个最小奇异值得到的图片
400个最小奇异值得到的图片