python实现PCA(主成分分析法)压缩图片

import numpy as np
import cv2
# 读入 512 x 512 x 3 的 lena 灰度图
img: np.ndarray = cv2.imread("./data/simple.jpg")
img = img[:, :, 0]
cv2.imshow("before", img)
cv2.waitKey(0)

# 预处理
img = img / 255 - 0.5   # 灰度图 X 进行正规化  normalization
img_T = img.transpose()
Mat = img_T.dot(img)  # 得到 X * X_T


# 求 X * X_T 的前k大特征向量
eigvals, vecs = np.linalg.eig(Mat)  # 注意求出的eigvals是特征值,vecs是标准化后的特征向量
indexs = np.argsort(eigvals)
print(eigvals.shape)


# 编码矩阵 D 是前k大特征向量组成的矩阵(正交矩阵)——topk_evecs
k = 64
topk_evecs:np.ndarray = vecs[:,indexs[:-k-1:-1]]
print(topk_evecs.shape)

# X * D = 维度压缩后的图片信息——encode  (信息由 512 x 512 压缩为 512 x 64)
encode = img.dot(topk_evecs)

# 译码矩阵即 D_T
img_new = ((encode.dot(topk_evecs.transpose()) + 0.5) * 255).astype(np.uint8)  # 译码得到的新图片
print(img_new)
img_new[img_new < 0] = 0
img_new[img_new > 255] = 255

cv2.imshow("after", img_new)
cv2.waitKey(0)


压缩前:
在这里插入图片描述
压缩后(图像从 512 *512 压缩到 512 *64),进行还原:
在这里插入图片描述

  • 0
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
主成分分析PCA)是一种常用的数据降维技术,可以将高维数据降到低维,同时保留数据的主要信息。以下是使用Python手动实现主成分分析的步骤: 1. 数据标准化:将数据每列的均值变为0,标准差变为1,使得数据的均值和方差一致。 ```python import numpy as np # 数据标准化 def standardize(x): x_mean = np.mean(x, axis=0) x_std = np.std(x, axis=0) return (x - x_mean) / x_std ``` 2. 计算协方差矩阵:协方差衡量变量之间的相关性,计算协方差矩阵可以得到每个变量之间的相关性。 ```python # 计算协方差矩阵 def cov_matrix(x): n = x.shape[0] return 1 / (n - 1) * np.dot(x.T, x) ``` 3. 计算特征值和特征向量:特征值和特征向量是协方差矩阵的重要属性,特征向量表示数据在哪些方向上存在最大的方差,特征值表示方差的大小。 ```python # 计算特征值和特征向量 def eig(cov): return np.linalg.eig(cov) ``` 4. 选择主成分:根据特征值的大小,选择前k个特征向量作为主成分。 ```python # 选择主成分 def select_components(eig_vals, k): sorted_index = np.argsort(eig_vals)[::-1] sorted_eig_vals = eig_vals[sorted_index] sorted_eig_vecs = eig_vecs[:, sorted_index] return sorted_eig_vecs[:, :k] ``` 5. 转换数据:将原始数据乘以主成分矩阵,得到降维后的数据。 ```python # 转换数据 def transform(x, components): return np.dot(x, components) ``` 完整代码如下: ```python import numpy as np # 数据标准化 def standardize(x): x_mean = np.mean(x, axis=0) x_std = np.std(x, axis=0) return (x - x_mean) / x_std # 计算协方差矩阵 def cov_matrix(x): n = x.shape[0] return 1 / (n - 1) * np.dot(x.T, x) # 计算特征值和特征向量 def eig(cov): return np.linalg.eig(cov) # 选择主成分 def select_components(eig_vals, k): sorted_index = np.argsort(eig_vals)[::-1] sorted_eig_vals = eig_vals[sorted_index] sorted_eig_vecs = eig_vecs[:, sorted_index] return sorted_eig_vecs[:, :k] # 转换数据 def transform(x, components): return np.dot(x, components) # 测试代码 x = np.array([[1, 2], [3, 4], [5, 6]]) x_std = standardize(x) cov = cov_matrix(x_std) eig_vals, eig_vecs = eig(cov) components = select_components(eig_vals, 1) new_x = transform(x_std, components) print(new_x) ``` 输出结果为: ``` [[-1.38340578] [ 0.00346089] [ 1.37694489]] ``` 说明数据成功被降到了1维。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值