PCA-图像降维重构

1)去平均值:(即去中心化)。
2) 计算协方差矩阵。
3) 计算协方差矩阵的特征值与特征向量。
4) 对特征值从大到小排序,选择其中最大的K个。然后将其对应的k个特征向量分别作为行向量组成新的特征向量矩阵。
5) 利用新的特征向量矩阵重构原始图像。

import numpy as np
import cv2 as cv
from sklearn import decomposition

# 数据中心化
def centere_data(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(dataMat, 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)
    temp_Sum = 0
    num = 0
    for i in sortArray:
        temp_Sum += i
        num += 1
        if temp_Sum >= 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

# PCA算法
def PCA(data, p):
    dataMat = np.float32(np.mat(data))
    # 数据中心化
    dataMat, meanVal = centere_data(dataMat)
    # 计算协方差矩阵
    covMat = np.cov(dataMat, rowvar=0)
    # 选取最大的k个特征值和特征向量
    D, V = EigDV(covMat, p)
    # 得到降维后的数据
    lowDataMat = dataMat * V
    # 重构数据
    reconDataMat = lowDataMat *V.T+ meanVal
    return reconDataMat

if __name__ == '__main__':
    img = cv.imread('D:/testimage/dog.jpg',0)
    rows, cols = img.shape
    #pca = decomposition.PCA()
    print("降维前的特征个数:" + str(cols) + "\n")
    print(img)
    print('----------------------------------------')
    PCA_img = PCA(img, 0.99)
    PCA_img = PCA_img.astype(np.uint8)
    print(PCA_img)
    cv.imshow('test', PCA_img)
    cv.imwrite('D:/testimage/dog-pca.jpg',PCA_img)
    cv.waitKey(0)
    cv.destroyAllWindows()




原图:

原图
PCA:

在这里插入图片描述
降维前的特征个数:605;
降维后的特征个数:116。

参考:基于PCA的图像降维及图像重构

posted @ 2020-05-04 18:22  code_witness  阅读(332)  评论(0编辑  收藏  举报