pca图像压缩python_基于PCA的图像降维及图像重构

1 PCA简述

PCA(Principal Component Analysis)主成分分析算法,在进行图像识别以及高维度数据降维处理中有很强的应用性,算法主要通过计算选择特征值较大的特征向量来对原始数据进行线性变换,不仅可以去除无用的噪声,还能减少计算量。

2算法过程

2.1对所有的样本进行中心化;

数据集的每个样本的不同特征减去所有样本对应特征的均值,处理过的不同特征上的数据均值为0。这样处理的好处是可以减少特征之间的差异性,可以使得不同的特征具有相同的尺度,让不同特征对参数的影响程度一致。

2.2计算样本的协方差矩阵(每列代表一个特征,每行代表一个样本)

2.2.1 计算样本矩阵每一列的均值

2.2.2 样本矩阵的每个样本减去对应列的均值

2.2.3 通过以下公式得到协方差矩阵 (m为样本总数)

2.3对协方差矩阵进行特征值分解,得到特征值和特征向量;

2.4取出最大的k个特征值对应的特征向量,组成投影矩阵W;

2.5对样本集中的每一个样本,都乘以投影矩阵W进行转化,得到降维的数据;

3Python代码实例

#encoding:GBK

"""

Created on 2019/09/23 16:19:11

@author: Sirius_xuan

"""

'''

基于PCA的图像降维及重构

'''

import numpy as np

import cv2 as cv

#数据中心化

def Z_centered(dataMat):

rows,cols=dataMat.shape

meanVal = np.mean(dataMat, axis=0) # 按列求均值,即求各个特征的均值

meanVal = np.tile(meanVal,(rows,1))

newdata = dataMat-meanVal

return newdata, meanVal

#协方差矩阵

def Cov(dataMat):

meanVal = np.mean(data,0) #压缩行,返回1*cols矩阵,对各列求均值

meanVal = np.tile(meanVal, (rows,1)) #返回rows行的均值矩阵

Z = dataMat - meanVal

Zcov = (1/(rows-1))*Z.T * Z

return Zcov

#最小化降维造成的损失,确定k

def Percentage2n(eigVals, percentage):

sortArray = np.sort(eigVals) # 升序

sortArray = sortArray[-1::-1] # 逆转,即降序

arraySum = sum(sortArray)

tmpSum = 0

num = 0

for i in sortArray:

tmpSum += i

num += 1

if tmpSum >= arraySum * percentage:

return num

#得到最大的k个特征值和特征向量

def EigDV(covMat, p):

D, V = np.linalg.eig(covMat) # 得到特征值和特征向量

k = Percentage2n(D, p) # 确定k值

print("保留99%信息,降维后的特征个数:"+str(k)+"\n")

eigenvalue = np.argsort(D)

K_eigenValue = eigenvalue[-1:-(k+1):-1]

K_eigenVector = V[:,K_eigenValue]

return K_eigenValue, K_eigenVector

#得到降维后的数据

def getlowDataMat(DataMat, K_eigenVector):

return DataMat * K_eigenVector

#重构数据

def Reconstruction(lowDataMat, K_eigenVector, meanVal):

reconDataMat = lowDataMat * K_eigenVector.T + meanVal

return reconDataMat

#PCA算法

def PCA(data, p):

dataMat = np.float32(np.mat(data))

#数据中心化

dataMat, meanVal = Z_centered(dataMat)

#计算协方差矩阵

#covMat = Cov(dataMat)

covMat = np.cov(dataMat, rowvar=0)

#得到最大的k个特征值和特征向量

D, V = EigDV(covMat, p)

#得到降维后的数据

lowDataMat = getlowDataMat(dataMat, V)

#重构数据

reconDataMat = Reconstruction(lowDataMat, V, meanVal)

return reconDataMat

def main():

imagePath = 'D:/desktop/banana.jpg'

image = cv.imread(imagePath)

image=cv.cvtColor(image,cv.COLOR_BGR2GRAY)

rows,cols=image.shape

print("降维前的特征个数:"+str(cols)+"\n")

print(image)

print('----------------------------------------')

reconImage = PCA(image, 0.99)

reconImage = reconImage.astype(np.uint8)

print(reconImage)

cv.imshow('test',reconImage)

cv.waitKey(0)

cv.destroyAllWindows()

if __name__=='__main__':

main()

4 结果

重构前

重构后

5 总结

不难发现,在保留99%信息的情况下,维度由1000降到了44,这大大减小了图像分类时的计算量,重构前和重构后的特征依然明显,读者也可自行调整percentage参数,体验PCA的效果。

PS:喜欢的读者,欢迎随时评论,觉得受益的话,给博主点个赞吧!!

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值