奇异值分解矩阵还原灰度图像结果报告

  • 一、由图片生成矩阵
  • 1.1原图与灰度图
  • 1.2图片转换矩阵
  • 二、奇异值分解还原图像
  • 2.1取最大特征值还原图像
  • 2.2取最小特征值还原图像


一、由图片生成矩阵

用特征值(奇异值)还原图片涉及到了矩阵的特征值特征向量的应用,奇异值分解矩阵,以及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()

Python将矩阵渲染成二维图_Image

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()

用这个矩阵还原的图片如下:

Python将矩阵渲染成二维图_Python将矩阵渲染成二维图_02


定义一个函数,能够取最大的任意几个奇异值还原图片

#定义函数取最大前几个奇异值还原图片
    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个奇异值得到的图片如下:

Python将矩阵渲染成二维图_奇异值分解_03

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个最小奇异值得到的图片

Python将矩阵渲染成二维图_特征值_04


400个最小奇异值得到的图片

Python将矩阵渲染成二维图_特征值_05