PCA降维再进行二维重构生成图像

本文介绍了一种使用PCA(主成分分析)进行图像特征降维和重构的方法,通过Python实现降维前后的特征数量变化,并展示了针对一组图片的处理过程。通过中心化、计算协方差矩阵和选择关键特征,实现了高维图像数据的压缩和重构。
摘要由CSDN通过智能技术生成

一张 图像降维再重构:

import numpy as np
import cv2 as cv

# 数据中心化
def Z_centerted(dataMat):
    rows, clos = dataMat.shape
    meanVal = np.mean(dataMat, axis=0)
    meanVal = np.tile(meanVal, (rows, 1))
    newdata = dataMat - meanVal
    return newdata, meanVal

# 求出最大特征值k的个数
def Percentage2n(eigen, p):
    sortArray = np.sort(eigen) # 升序
    sortArray = sortArray[-1::-1] # 降序
    arraysum = sum(sortArray)
    num = 0
    itemnum = 0
    for i in sortArray:
        itemnum += i
        num += 1
        if itemnum >= arraysum*p:
            return num

# 求出特征值和特征向量
def EigDV(dataMat, p):
    D, V = np.linalg.eig(dataMat) # 求出特征值和特征向量
    k = Percentage2n(D, p) # 求出k值
    print("保留99%的信息:"+str(k)+"\n")
    eigenvalue = np.argsort(D)
    K_eigenvalue = eigenvalue[-1:-(k+1):-1]
    K_eigenvactor = V[:, K_eigenvalue]
    return K_eigenvalue, K_eigenvactor

# 获得降维图片
def getlowDataMat(dataMat, K_eigenvactor):
    return dataMat * K_eigenvactor

# 重构数据
def Reconstruction(lowDataMat, K_eigenvactor, meanVal):
    reconDatMat = lowDataMat*K_eigenvactor.T + meanVal
    return reconDatMat

# 创建PCA
def PCA(data, p):
    dataMat = np.float32(np.mat(data))
    dataMat, manVal = Z_centerted(dataMat)
    # 计算协方差矩阵
    covMat = np.cov(dataMat, rowvar=0)
    D, V = EigDV(covMat, p)
    lowDataMat = getlowDataMat(dataMat, V)
    reconstruction = Reconstruction(lowDataMat, V, manVal)
    return reconstruction

def main():
    imagePath = r'All_Resize/c1/15.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.8)
    reconImage = reconImage.astype(np.uint8)
    print(reconImage.shape)


if __name__ == '__main__':
    main()

一个文件夹多个图像降维再重构

import numpy as np
import cv2 as cv

def Z_centered(dataMat):
     rows, clos = dataMat.shape
     meanVal = np.mean(dataMat, axis=0)
     meanVal = np.tile(meanVal, (rows, 1))
     newdata = dataMat - meanVal
     return newdata, meanVal

def Percentage2n(eigVals, percentage):
     sortarray = np.sort(eigVals) # 升序
     sortarray = sortarray[-1::-1] # 降序
     sumarray = sum(sortarray)
     num = 0
     tempsum = 0
     for i in sortarray:
          num += 1
          tempsum += i
          if tempsum >= sumarray*percentage:
               return num

def EigDv(dataMat, p):
     # 特征值越大,所携带的东西越多
     D, V = np.linalg.eig(dataMat) # 确定协方差和协方差矩阵
     k = Percentage2n(D, p)
     print("保留99%信息,降维后的特征个数:"+str(k)+"\n")
     eigenValue = np.argsort(D) # 升序
     K_eigenValue = eigenValue[-1:-(k+1):-1]
     K_eigenVactor = V[:, K_eigenValue]
     return K_eigenValue, K_eigenVactor

def getlowDataMat(dataMat, K_eigenVactor):
     return dataMat*K_eigenVactor

def Reconstruction(lowDataMat, K_eigenvactor, meanval):
     reconstruction = lowDataMat*K_eigenvactor.T + meanval
     return reconstruction

def PCA(data,p):
     dataMat = np.float32(np.mat(data))
     dataMat, meanval = Z_centered(dataMat)
     convdata = np.cov(dataMat, rowvar=0)
     K_eigenvalue, K_eigenvactor = EigDv(convdata, p)
     lowDataMat = getlowDataMat(dataMat, K_eigenvactor)
     reconstruction = Reconstruction(lowDataMat, K_eigenvactor, meanval)
     return reconstruction

def main():
     for i in range(30):
          imagePath = r'All_Resize/c10/'+str(i+1)+'.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.999)
          reconImage = reconImage.astype(np.uint8)
          reconImage = cv.applyColorMap(reconImage, cv.COLORMAP_WINTER)
          print(reconImage)
          cv.imwrite('color-decline-resize/c10/'+str(i+1)+'.jpg', reconImage)
          cv.waitKey(0)
          cv.destroyAllWindows()

if __name__ == '__main__':
     main()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI炮灰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值