• 计算机视觉:基于Numpy的图像处理技术(二):图像主成分分析(PCA)


    计算机视觉:基于Numpy的图像处理技术(二):图像主成分分析🏳️‍🌈

    演示图片如图,又是机甲“小花”

    hua

    图像主成分分析Ⓜ️

    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 ={z 1,z 2,,z n}

    1、数据中心化:减去每一维数据的均值

    均值为:

    μ ⃗ = 1 n ∑ i = 1 n z ⃗ i \vec \mu= \frac{1}{n} \sum_{i=1}^{n} \vec z_{i} μ =n1i=1nz i

    将其中心化后表示为:
    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 ={x 1,x 2,,x n}={z 1μ ,z 2μ ,,z nμ }

    2、求特征协方差矩阵

    M ( c o v ) = x ⃗ x ⃗ T M(cov) =\vec x \vec x^T M(cov)=x x T

    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=a 1,a 2,,a n

    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=argmaxj=1nλji=1kλit

    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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    小花这里没有使用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]]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
  • 相关阅读:
    LHS RHS
    web开发理论测试题
    计算机毕业设计Java计算机office课程平台(源码+系统+mysql数据库+lw文档)
    Flutter之安卓端极光推送使用
    str.c_str() 补充C中没有string类型的问题
    刷题之路:1196 - 【入门】递归版拐角I题解
    Day28|Leetcode 93. 复原 IP 地址 Leetcode 78. 子集 Leetcode 90. 子集 II
    认识C#.
    C++ replace,replace_if和replace_copy函数用法详解(深入了解,一文学会)
    基于C/C++的UTF-8转GBK
  • 原文地址:https://blog.csdn.net/tianhai12/article/details/127968598