使用PCA压缩图像(python实现)

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from scipy.io import loadmat
from skimage import io
from sklearn.decomposition import PCA
A=io.imread('butterfly.bmp')
A=A/255 #RGB的三个值[0,255],将它们范围设置为[0,1]
io.imshow(A)
plt.show()

​​​
png
​​​

A.shape
(243, 437, 3)
A[:,:,0].shape
(243, 437)
io.imshow(A[:,:,0])
plt.show()

​​​
png
​​​

fig,ax_array=plt.subplots(nrows=1,ncols=4,figsize=(32,32))
cmap_list=['Reds','Greens','Blues']
ax_array[0].imshow(A[:,:,:])
ax_array[0].set_xticks([])
ax_array[0].set_yticks([])
ax_array[0].set_title("Combined", size = 30,color='w')
for i in range(3):
    ax_array[i+1].imshow(A[:,:,i],cmap=cmap_list[i])
    ax_array[i+1].set_xticks([])
    ax_array[i+1].set_yticks([])
    ax_array[i+1].set_title(cmap_list[i][:-1], size = 30,color='w')
plt.tight_layout()
fig.suptitle("IMAGES OF EACH COLOR CHANNEL", size = 30, y = 0.6, fontweight = "bold",color='w')
plt.show()

​​​
png
​​​

R,G,B=A[:,:,0],A[:,:,1],A[:,:,2]
R.shape,G.shape,B.shape
((243, 437), (243, 437), (243, 437))

主成分分析

思路是利用矩阵的特征值分解,根据特征值的大小来确定数据中每个特征轴的权重。可以忽略特征值非常小的分量,从而实现数据降维或数据压缩。矩阵(图像)X,其维度为使用PCA压缩图像(python实现),可以理解为具有使用PCA压缩图像(python实现)特征和使用PCA压缩图像(python实现)样本的数据,主成分分析的目的是减少特征数量(每行对应一个特征,每列对应一个sample) ,并删除冗余特征。现在,我们需要对矩阵进行一些线性变换,使其维度变为使用PCA压缩图像(python实现)。如果我们找到一个变换矩阵并乘以X,并使用使用PCA压缩图像(python实现),就实现了矩阵的压缩。

根据线性代数的知识,很容易知道这个前向变换(实现压缩)矩阵的维数为使用PCA压缩图像(python实现),对压缩后的矩阵进行逆变换(实现解压)操作,有损可以得到压缩矩阵使用PCA压缩图像(python实现),逆变换矩阵的维数为使用PCA压缩图像(python实现)

在下面的代码中,矩阵为使用PCA压缩图像(python实现),每一列是一个特征,每一行是一个样本:

def pca_m(data,k):
    n_samples,n_features = data.shape#每列是一个特征,每一行是一个样本
    #求解一个特征的均值,即每一列的平均值,shape(n_samples,1)
    mean=(data.sum(axis=1)/n_samples).reshape(-1,1)
    # 去中心化,shape(n_samples,1)
    normal_data = data - mean
    # 得到协方差矩阵
    matrix_ = np.dot(np.transpose(normal_data),normal_data)
    eig_val,eig_vec = np.linalg.eig(matrix_)
    #得到最主要的k个特征
    eigIndex = np.argsort(eig_val)
    eigVecIndex = eigIndex[:-(k+1):-1]
    feature = eig_vec[:,eigVecIndex]
    
    new_data = np.dot(normal_data,feature)
    # 将降维后的数据映射回原空间
    rec_data = np.dot(new_data,np.transpose(feature))+ mean
    return rec_data

for k in range(5,150,10):
    R_new,G_new,B_new=pca_m(R,k),pca_m(G,k),pca_m(B,k)

    A_new=np.zeros(A.shape)
    A_new[:,:,0]=R_new
    A_new[:,:,1]=G_new
    A_new[:,:,2]=B_new

    fig,ax_array=plt.subplots(nrows=1,ncols=4,figsize=(32,32))
    cmap_list=['Reds','Greens','Blues']
    ax_array[0].imshow(A_new[:,:,:])
    ax_array[0].set_xticks([])
    ax_array[0].set_yticks([])
    ax_array[0].set_title("Combined", size = 30,color='g')
    for i in range(3):
        ax_array[i+1].imshow(A_new[:,:,i],cmap=cmap_list[i])
        ax_array[i+1].set_xticks([])
        ax_array[i+1].set_yticks([])
        ax_array[i+1].set_title(cmap_list[i][:-1], size = 30,color='g')
    plt.tight_layout()
    fig.suptitle("IMAGES OF EACH COLOR CHANNEL(K={})".format(k), size = 30, y = 0.6, fontweight = "bold",color='g')
    plt.show()
<ipython-input-224-33543b96ed01>:5: ComplexWarning: Casting complex values to real discards the imaginary part
  A_new[:,:,0]=R_new
<ipython-input-224-33543b96ed01>:6: ComplexWarning: Casting complex values to real discards the imaginary part
  A_new[:,:,1]=G_new
<ipython-input-224-33543b96ed01>:7: ComplexWarning: Casting complex values to real discards the imaginary part
  A_new[:,:,2]=B_new
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).

png

Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).

png

Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).

png

Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).

png

Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).

png

Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).

png

png

Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).

png

png

png

png

png

png

png

png

sklearn是机器学习最重要的库,里面包含了pca函数,尝试调用它:(pca函数不用自己写)

def pca(X,K):
    pca=PCA(n_components=K).fit(X)
    X_new=pca.transform(X)
    X_new = pca.inverse_transform(X_new)
    return X_new
for k in range(5,150,10):
    R_new,G_new,B_new=pca(R,k),pca(G,k),pca(B,k)

    A_new=np.zeros(A.shape)
    A_new[:,:,0]=R_new
    A_new[:,:,1]=G_new
    A_new[:,:,2]=B_new

    fig,ax_array=plt.subplots(nrows=1,ncols=4,figsize=(32,32))
    cmap_list=['Reds','Greens','Blues']
    ax_array[0].imshow(A_new[:,:,:])
    ax_array[0].set_xticks([])
    ax_array[0].set_yticks([])
    ax_array[0].set_title("Combined", size = 30,color='g')
    for i in range(3):
        ax_array[i+1].imshow(A_new[:,:,i],cmap=cmap_list[i])
        ax_array[i+1].set_xticks([])
        ax_array[i+1].set_yticks([])
        ax_array[i+1].set_title(cmap_list[i][:-1], size = 30,color='g')
    plt.tight_layout()
    fig.suptitle("IMAGES OF EACH COLOR CHANNEL(K={})".format(k), size = 30, y = 0.6, fontweight = "bold",color='g')
    plt.show()
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).

png

Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).

png

Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).

png

Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).

png

Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).

png

Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).

png

png

Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).

png

png

png

png

png

png

png

png

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
社会演员多的头像社会演员多普通用户
上一篇 2022年4月4日
下一篇 2022年4月4日

相关推荐