因为python的特征值分解存在复数矩阵的情况,而后续步骤不能很好的兼容复数,于是采用了范围更广的奇异值分解(SVD)进行图像处理。并且在后续测试中选取了不同的特征值进行保留(并不一定是最大的特征值)。
numpy 处理矩阵
学习:https://blog.csdn.net/a373595475/article/details/79580734
PIL 图像处理
imageio 图像处理
import numpy as np
from PIL import Image
import imageio
#获取图像并转换为三维数组
img=Image.open('妹子.jpg')
a=np.asarray(img)
下图是a矩阵的shape
可见是一个512 x 512 x 3的三维矩阵,第三个维度代表了每个像素点的RGB值,我们不妨将其考虑为R,G,B三个512 x 512的二维矩阵,分别进行奇异值分解,再对其进行整合,得到一个新的三维矩阵。
#定义重构函数
def rebuildimg(u,sigma,v,p,q):
m=len(u)
n=len(v)
a=np.zeros((m,n))
k=0
while k<=p*q:
uk=u[:,k].reshape(m,1)
vk=v[k].reshape(1,n)
a+=sigma[k]*np.dot(uk,vk)
k+=q
a[a<0]=0
a[a>255]=255
return np.rint(a).astype("int32")
#输入
i=input("你所希望保留的特征值数量:")
j=input("你所希望选取的特征值的间隔:")
#我的代码里面是从第一个特征值开始处理的,当然,这个可以根据需要进行修改
i=int(i)
j=int(j)
#化i,j为整形
np.linalg.svd()可以直接对矩阵进行奇异值分解,我们不妨使用。它会返回三个值。
#对R,G,B三个矩阵依次进行处理
u,sigma,v=np.linalg.svd(a[:,:,0])
R=rebuildimg(u,sigma,v,i,j)
u,sigma,v=np.linalg.svd(a[:,:,1])
G=rebuildimg(u,sigma,v,i,j)
u,sigma,v=np.linalg.svd(a[:,:,2])
B=rebuildimg(u,sigma,v,i,j)
#整合得到处理后的三维矩阵
I=np.stack((R,G,B),2)
#将矩阵变成图像保存
imageio.imsave("大妹子.jpg",I)
输入:i=10 , j=1
输出:
输入:i=30 , j=1
输出:
输入:i=50 , j=1
输出:
输入:i=100 , j=1
输出:
输入:i=200 , j=1
输出:
输入:i=50 , j=2
输出:
输入:i=50 , j=3
输出:
输入:i=50 , j=5
输出:
输入:i=50 , j=7
输出:
输入:i=50 , j=9
输出:
奇异值分解相较于特征值分解而言,它还能够对非正方形的图片进行处理,比如下图:
输入:i=50 , j=1
输出:
输入:i=50 , j=6
输出:
https://blog.csdn.net/weixin_44873868/article/details/104583909
https://blog.csdn.net/a373595475/article/details/79580734