计算机视觉:基于Numpy的图像处理技术(二):图像主成分分析🏳️🌈
文章目录
- 计算机视觉:基于Numpy的图像处理技术(二):图像主成分分析:rainbow_flag:
- 图像主成分分析:m:
- 1、概念:orange_book:
- 2、原理:page_facing_up:
- 3、步骤:paw_prints:
- 1、数据中心化:减去每一维数据的均值
- 2、求特征协方差矩阵
- 3、计算协方差矩阵对应最大特征值的特征向量
- 4、根据阈值*t*,计算方差贡献率,确定要返回特征向量个数K
- 4、代码实现:snake:
演示图片如图,又是机甲“小花”
图像主成分分析Ⓜ️
1、概念📙
主成分分析(PCA)是一个有用的降维方法。可以在使用尽可能少数维度下,尽可能多地保持数据的信息。我们知道小花是一副图像,具有很高的维数。在许多计算机视觉应用里,都会使用降维操作。
Numpy类库中的 flatten()
方法可将图像转换成一维向量。
x
⃗
=
{
x
1
,
x
2
,
…
,
x
n
}
\vec x = {\lbrace x_{1},x_{2},\dots,x_n\rbrace}
x={x1,x2,…,xn}
2、原理📄
主成分分析希望能够通过旋转坐标系将数据在新的坐标系下表示,如果新的坐标系下某些轴包含的信息太少,则可以将其省略,从而达到降维的目的。
3、步骤🐾
有一组数据:可以理解为一副图像的灰度图,由多个行向量组成的矩阵。确定主成分个数的阈值t,一般选择80%左右,后续做判断使用。
z
⃗
=
{
z
⃗
1
,
z
⃗
2
,
…
,
z
⃗
n
}
\vec z = {\lbrace \vec z_{1},\vec z_{2},\dots,\vec z_n\rbrace}
z={z1,z2,…,zn}
1、数据中心化:减去每一维数据的均值
均值为:
μ ⃗ = 1 n ∑ i = 1 n z ⃗ i \vec \mu= \frac{1}{n} \sum_{i=1}^{n} \vec z_{i} μ=n1i=1∑nzi
将其中心化后表示为:
x
⃗
=
{
x
⃗
1
,
x
⃗
2
,
…
,
x
⃗
n
}
=
{
z
⃗
1
−
μ
⃗
,
z
⃗
2
−
μ
⃗
,
…
,
z
⃗
n
−
μ
⃗
}
\vec x = {\lbrace \vec x_{1},\vec x_{2},\dots,\vec x_n\rbrace} ={\lbrace \vec z_{1}-\vec \mu,\vec z_{2}-\vec \mu,\dots,\vec z_n- \vec \mu\rbrace}
x={x1,x2,…,xn}={z1−μ,z2−μ,…,zn−μ}
2、求特征协方差矩阵
M ( c o v ) = x ⃗ x ⃗ T M(cov) =\vec x \vec x^T M(cov)=xxT
3、计算协方差矩阵对应最大特征值的特征向量
将特征值从大到小排列,得到n个特征值
λ
1
,
λ
2
,
…
,
λ
n
\lambda_1,\lambda_2, \dots,\lambda_n
λ1,λ2,…,λn
其对应的特征向量:
A
=
a
⃗
1
,
a
⃗
2
,
…
,
a
⃗
n
A = \vec a_1,\vec a_2, \dots,\vec a_n
A=a1,a2,…,an
4、根据阈值t,计算方差贡献率,确定要返回特征向量个数K
K = a r g m a x ∑ i = 1 k λ i ∑ j = 1 n λ j ≥ t K=arg max \frac{\sum_{i=1}^k \lambda_i}{\sum_{j=1}^{n} \lambda_j} \ge t K=argmax∑j=1nλj∑i=1kλi≥t
R ⃗ = A T z ⃗ \vec R = A^T\vec z R=ATz
4、代码实现🐍
对小花图像进行PCA,求出其特征向量、投影矩阵、方差和均值
from PIL import Image
import numpy as np
def pca(X):
"""主成分分析
输入:矩阵X,存储训练数据,每一行为一条数据
返回:投影矩阵(按维度重要性排序的)方差和均值
"""
# 获取维数
num_data ,dim = X.shape
# print(num_data,dim)
# 数据中心化(减去每一维的均值)
mean_X = X.mean(axis = 0)
X = X -mean_X
if dim > num_data:
# 使用紧致技巧
# 协方差矩阵
# M = np.dot(X,X.T)
M = np.cov(X,rowvar=True)
# 特征值和特征向量
e,EV = np.linalg.eigh(M)
# print(E,EV)
# 紧致技巧
tmp = np.dot(X.T,EV).T
V = tmp[::-1]
#求平方根需要求其绝对值
S = np.sqrt(np.abs(e))[::-1]
for i in range(V.shape[1]):
V[:,i] /= S
print("投影矩阵",V)
print('特征向量',EV)
return V, S, mean_X
else:
# 使用SVD方法
U,S,V = np.linalg.svd(X)
# 返回前num_data维的数据
V = V[:num_data]
# 返回投影矩阵,方差和均值
print("投影矩阵",V)
return V,S,mean_X
hua = np.array(Image.open('hua.jpg').convert('L'))
pca(hua)
小花这里没有使用SVD方法,因为她的长是大于宽的,所以采用了PCA降维,输出的投影矩阵特征向量如下:
投影矩阵 [[ 8.03605309e-02 8.39756720e-02 9.83425336e-02 ... -9.76770092e-02
-1.07195860e-01 -6.24628102e-02]
[ 3.86431783e-01 3.65459420e-01 3.48954567e-01 ... 1.78539067e-01
1.60010909e-01 9.88472061e-02]
[ 4.35651716e-01 4.36100201e-01 3.93508064e-01 ... 1.17824688e-01
1.39685140e-01 1.07992053e-01]
...
[ 2.01307349e+00 8.67143722e-01 -1.67130144e-01 ... 1.31632783e-01
-1.57440711e+00 -1.57331512e+00]
[-7.05993726e-01 7.58672673e-01 -2.56566104e+00 ... -1.32999335e+00
-4.83894676e-01 -5.13382909e-01]
[ 6.00337969e-06 1.40041622e-05 7.53382818e-06 ... -1.04562028e-05
-1.44956931e-05 -1.41024684e-05]]
特征向量 [[ 0.05538488 -0.00144137 -0.03434008 ... -0.05946286 0.00335706
-0.00604234]
[ 0.05538488 -0.01475328 0.04735503 ... -0.05991643 0.00076363
-0.00695584]
[ 0.05538488 0.01067808 -0.01482254 ... -0.05387841 0.00558545
-0.00799025]
...
[ 0.05538488 0.006086 -0.01555427 ... -0.04001481 -0.04895945
0.02703765]
[ 0.05538488 -0.01572941 0.01562869 ... -0.04218723 -0.04845806
0.02248818]
[ 0.05538488 0.00939665 -0.00982804 ... -0.04250774 -0.04824829
0.01907884]]