Python 中图像数据的主成分分析

我们已经在上一篇文章中研究过 PCA 。在本文中,我们将研究图像数据的主成分分析。PCA 是一种著名的无监督降维技术,每当维数诅咒困扰着我们时,它就能拯救我们。

处理图像数据与通常的数据集略有不同。典型的彩色图像由微小的像素(简称“图像元素”)组成,许多像素以阵列形式聚集在一起形成数字图像。

典型的数字图像是由强度范围为 0 到 255 的红、蓝和绿像素阵列堆叠而成。

RGB 阵列组合形成数字图像

灰度图像不包含颜色,仅包含灰色阴影。灰度图像中的像素强度从黑色(0 强度)到白色(255 全强度)变化,使其成为我们通常所说的黑白图像。

将 PCA 应用于 Digits 数据集

Digits数据集是手写数字的灰度图像数据集,具有1797张8×8图像。

#importing the dataset
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_digits
 
digits = load_digits()
data = digits.data
data.shape

sklearn.datasets模块可以通过从中导入load_digits 类来快速导入数字数据。数字数据的形状为(1797, 64)。8×8 像素被展平,为每个图像创建一个长度为 64 的向量。

让我们看看我们的数据是什么样的。

#taking a sample image to view
#Remember image is in the form of numpy array.
image_sample = data[0,:].reshape(8,8)
plt.imshow(image_sample)
数字数据集中的样本图像

1. 减小图像尺寸

现在,使用 PCA 将图像维度从 64 减少到仅 2,以便我们可以使用散点图可视化数据

sklearn为我们提供了一个非常简单的PCA实现。

#Import required modules
from sklearn.decomposition import PCA
 
pca = PCA(2) # we need 2 principal components.
converted_data = pca.fit_transform(digits.data)
 
converted_data.shape

数据从 (1797, 64) 减少到 (1797, 2)。

2. 可视化结果数据集

我们将使用sklearn.decomposition 提供PCA()类来实现主成分分析算法。

它接受整数作为输入参数,描述我们在转换后的数据集中想要的主成分的数量。

我们还可以传递小于 1 的浮点值而不是整数。即 PCA(0.90),这意味着算法将找到解释 90% 数据方差的主成分。

让我们想象一下结果。

plt.style.use('seaborn-whitegrid')
plt.figure(figsize = (10,6))
c_map = plt.cm.get_cmap('jet', 10)
plt.scatter(converted_data[:, 0], converted_data[:, 1], s = 15,
            cmap = c_map , c = digits.target)
plt.colorbar()
plt.xlabel('PC-1') , plt.ylabel('PC-2')
plt.show()
二维可视化数字数据

图像数据压缩的主成分分析

PCA 的另一个很酷的应用是图像压缩。让我们看看如何使用 python 来实现这一点。

# Importing required libraries
import cv2
import numpy as np
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA

1. 加载图片

我们将使用OpenCV(开源计算机视觉库)。OpenCV是一个开源计算机视觉和机器学习库。

# Loading the image
img = cv2.imread('my_doggo_sample.jpg') #you can use any image you want.
plt.imshow(img)
原始图像输出示例

2. 将图像分割为 R、G、B 阵列

众所周知,数字彩色图像是 R、G 和 B阵列相互堆叠的组合。在这里,我们必须从图像中分割每个通道并从每个通道中提取主成分。

# Splitting the image in R,G,B arrays.
 
blue,green,red = cv2.split(img)
#it will split the original image into Blue, Green and Red arrays.

这里需要注意的重要一点是,OpenCV 将分为蓝色、绿色和红色通道,而不是红色、蓝色和绿色。请务必注意此处的顺序。

3. 将主成分应用于各个数组

现在,将 PCA 应用于每个阵列。

#initialize PCA with first 20 principal components
pca = PCA(20)
 
#Applying to red channel and then applying inverse transform to transformed array.
red_transformed = pca.fit_transform(red)
red_inverted = pca.inverse_transform(red_transformed)
 
#Applying to Green channel and then applying inverse transform to transformed array.
green_transformed = pca.fit_transform(green)
green_inverted = pca.inverse_transform(green_transformed)
 
#Applying to Blue channel and then applying inverse transform to transformed array.
blue_transformed = pca.fit_transform(blue)
blue_inverted = pca.inverse_transform(blue_transformed)

在这里,我们应用 PCA 只保留前 20 个主成分,并将其分别应用于 RGB 数组。

4. 压缩图像

逆变换对于重新创建基础图像的原始尺寸是必要的。

在从降低的维度重建原始维度的过程中,由于我们仅保留选定的主成分(本例中为 20),因此会丢失一些信息。

img_compressed = (np.dstack((red_inverted, red_inverted, red_inverted))).astype(np.uint8)

使用dstack函数堆叠倒排数组。这里指定数组的数据类型很重要,因为大多数图像都是 8 位的。每个像素由一个 8 位字节表示。

#viewing the compressed image
plt.imshow(img_compressed)
具有前 20 个主成分的压缩图像

上面的输出是我们仅考虑 20 个主成分时得到的结果。

如果我们增加主成分的数量,输出图像将会变得清晰。

使用前 50 个主成分:

具有前 50 个主成分的压缩图像

现在,使用 100 个主成分:

具有前 100 个主成分的压缩图像

有了前 100 个主成分,我们的输出就变得更加清晰。
现在让我们使用前 200 个主成分应用 PCA。

具有前 200 个主成分的压缩图像

瞧!凭借 200 个主成分,我们能够创建出与原始图像一样的清晰图像。

要考虑的组件数量完全是任意的。从一些较小的值开始,然后逐渐增加它,直到达到所需的输出。请随意尝试代码。

结论

在本文中,我们探索了 PCA 作为降维技术的应用,并将其应用于图像数据。我们还了解了 PCA 如何在图像压缩中发挥作用。

快乐学习!