我们已经在上一篇文章中研究过 PCA 。在本文中,我们将研究图像数据的主成分分析。PCA 是一种著名的无监督降维技术,每当维数诅咒困扰着我们时,它就能拯救我们。
处理图像数据与通常的数据集略有不同。典型的彩色图像由微小的像素(简称“图像元素”)组成,许多像素以阵列形式聚集在一起形成数字图像。
典型的数字图像是由强度范围为 0 到 255 的红、蓝和绿像素阵列堆叠而成。
灰度图像不包含颜色,仅包含灰色阴影。灰度图像中的像素强度从黑色(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 个主成分时得到的结果。
如果我们增加主成分的数量,输出图像将会变得清晰。
使用前 50 个主成分:
现在,使用 100 个主成分:
有了前 100 个主成分,我们的输出就变得更加清晰。
现在让我们使用前 200 个主成分应用 PCA。
瞧!凭借 200 个主成分,我们能够创建出与原始图像一样的清晰图像。
要考虑的组件数量完全是任意的。从一些较小的值开始,然后逐渐增加它,直到达到所需的输出。请随意尝试代码。
结论
在本文中,我们探索了 PCA 作为降维技术的应用,并将其应用于图像数据。我们还了解了 PCA 如何在图像压缩中发挥作用。
快乐学习!