在Python中使用K-Means聚类和PCA主成分分析进行图像压缩(三)

简介: 在Python中使用K-Means聚类和PCA主成分分析进行图像压缩(三)

与原始图像进行比较

最后,让我们比较使用k = 12的压缩图像和原始图像的区别。

image.png

relative_size = ori_vs_kmeans.loc["Color-Reduced", "Image Size (KB)"]/ori_vs_kmeans.loc["Original", "Image Size (KB)"]
print("Reduction: {:.3f}% from original image size".format((1-relative_size)*100))
print("Explained Variance: {:.3f}%".format(ori_vs_kmeans.loc["Color-Reduced", "Explained Variance"]))


缩小比例:原始图像的79.012%解释方差:95.916%

通过使用k-means,我们可以将图像大小减少79.012%,而解释方差为95.916%,这真是太好了!接下来,我们执行PCA,看看它是否可以优于k-means。

主成分分析(PCA)

概念

PCA是用于降维的无监督学习技术之一。它从协方差矩阵计算出特征向量,然后将其称为主轴,并按称为解释方差百分比的特征值进行递减排序。然后将数据集居中并投影到形成主要成分(或分数)的主轴上。为了减少数据维度,我们仅保留一定数量的主成分n来解释原始数据集的方差,而忽略其余部分。

假设我们有一个X_ori数据集,其中包含m个观察值和n个特征。减去每行的平均值,我们得到居中的数据X。然后,PCA将为每个特征计算k个特征向量,从而产生形状为n×k的矩阵V。PCA投影或分数将以Z = XV给出,其中Z的尺寸为m×k。

降维时,我们在X_ori中选择n_select小于n。以下是我们使用所选PC重建矩阵X的方法:

image.png

其中:

Z_reduce的尺寸为m×n_selectV_reduce的维数为n×n_selectT是矩阵转置运算

最后,我们添加均值以得到原始图像的最终PCA,如下所示:

image.png


理念

我们将通过选择要使用的主分量n_select利用PCA来减小图像尺寸,以便它仅存储重要像素以保留原始图像的特征,从而使其在存储中更加有效。

我们的原始图像包含三个颜色通道:红色,绿色和蓝色。对于每个颜色通道,我们将像素视为具有(高度)观察值和(宽度)特征的2D矩阵。在lena.png中,我们有三个2D矩阵,其中包含220个观测值和220个特征。

RGB通道的主要组件

在每个颜色通道上执行PCA,从而得到PCA投影(或分数)和主成分(轴),它们都将是形状为220×220的矩阵形式。

res = []
cum_var = []
X_t = np.transpose(X)
for channel in range(3):
     # SEPARATE EACH RGB CHANNEL
     pixel = X_t[channel].reshape(*ori_pixels.shape[:2])
     # PCA
     pca = PCA(random_state = 123)
     pixel_pca = pca.fit_transform(pixel)
     pca_dict = {
         "Projection": pixel_pca,
         "Components": pca.components_,
         "Mean": pca.mean_
    }
     res.append(pca_dict)
     # EVALUATION
     cum_var.append(np.cumsum(pca.explained_variance_ratio_))


我们可以可视化每个颜色通道的主要成分,如下所示:

image.png

PC的可视化信息不足,随机性很大。我们应该引入一个称为解释方差的指标来评估PC性能。取值范围是0到100%,表示原始图像和压缩图像之间的相似度。

cum_var_df = pd.DataFrame(np.array(cum_var).T * 100,
                           index = range(1, pca.n_components_+1),
                           columns = ["Explained Variance by Red",
                                      "Explained Variance by Green",
                                      "Explained Variance by Blue"])
cum_var_df["Explained Variance"] = cum_var_df.mean(axis = 1)
cum_var_df


image.png

重复试验

在本节中,我们将重复以下步骤从n_select到n_select = 220:

  1. 区分PCA投影的前n_select列和组件的前n_select行
  2. 使用PCA建立公式和原始图像
  3. 对红色,绿色和蓝色每个颜色通道重复步骤1-2。
  4. 将三种颜色通道的PCA重构组合为一个3D矩阵
  5. 保存指标值(解释方差,图像大小和颜色数量)以进行进一步优化
  6. 用越来越多的主成分绘制压缩(重构)图像
pca_results = []
for n in range(1, pca.n_components_+1):
     # SELECT N-COMPONENTS FROM PC
     temp_res = []
     for channel in range(3):
         pca_channel = res[channel]
         pca_pixel = pca_channel["Projection"][:, :n]
         pca_comp = pca_channel["Components"][:n, :]
         pca_mean = pca_channel["Mean"]
         compressed_pixel = np.dot(pca_pixel, pca_comp) + pca_mean
         temp_res.append(compressed_pixel.T)
     compressed_image = np.transpose(temp_res)
     pca_dict = {
         "n": n,
         "Pixels": compressed_image,
         "Explained Variance": cum_var_df["Explained Variance"][n],
         "Image Size (KB)": imageByteSize(compressed_image),
         "No. of Colors": len(np.unique(np.uint8(compressed_image).reshape(-1, 3), axis = 0))
    }
     pca_results.append(pca_dict)
pca_results = pd.DataFrame(pca_results).set_index("n")
pca_results.head()

image.png

PCA指标:主成分的最佳数量

在本节中,我们将尝试搜索最佳数量的PC,以在达到预期的解释方差的同时,使内存占用尽可能最小。

image.png

我们想通过分析解释方差来获得最佳主成分数,这是思考过程:左图:我们需要19、33和73个主成分才能分别解释原始图像的方差的90%,95%和99%。中图:但是需要权衡取舍,解释方差越大,图像尺寸就越大。黑色虚线表示原始图像尺寸,我们要在此线下方选择n。因此,选择19或33个主成分。右图:如果将n从19增加到33,然后再增加到73,则图像中存在的颜色数量将减少。

从图中可以得出结论,应当33个主成分,因为它给我们提供了较小的图像大小和相当高的解释方差,并且比使用19个主要成分更接近原始图像。

与原始图像进行比较

最后,让对压缩图像和原始图像进行比较。

image.png

relative_size = ori_vs_pca.loc["PC-Reduced", "Image Size (KB)"]/ori_vs_kmeans.loc["Original", "Image Size (KB)"]
print("Reduction: {:.3f}% from original image size".format((1-relative_size)*100))
print("Explained Variance: {:.3f}%".format(ori_vs_pca.loc["PC-Reduced", "Explained Variance"]))


缩小比例:原始图像大小的6.825%解释方差:95.072%

通过使用PCA,我们只能将图像大小减小6.825%,并且压缩后的图像成功捕获了原始图像的95.072%的特征。接下来,我们比较k-means和PCA的结果。

k-means和PCA的比较

我们考虑几个指标,以比较使用k-means和PCA压缩图像的效果:

  1. 图片大小(以千字节为单位)
  2. 解释方差
  3. 图像中存在的颜色数
reduction_kmeans = (1-final_compare.loc["Color-Reduced", "Image Size (KB)"] / ori_img_size) * 100
reduction_pca = (1-final_compare.loc["PC-Reduced", "Image Size (KB)"] / ori_img_size) * 100
print("Image Size Reduction using K-Means: {:.3f}%".format(reduction_kmeans))
print("Image Size Reduction using PCA: {:.3f}%".format(reduction_pca))

使用k-means缩小图像大小:79.012%使用PCA缩小图像大小:6.825%

结论

我们使用无监督学习算法成功地实现了图像压缩,例如k-means聚类和使用主成分分析(PCA)进行降维。

在k-means中,通常通过可视化来主观地选择最佳聚类中心数k。在这里,我们提出两种选择方法,即:

  1. 使用最长垂直距离的方法
  2. 使用有限差分法和二阶导数

在PCA中,确定使用的PC数量首先要考虑解释方差,然后还要考虑图像大小减小的比例和减少颜色的数量,以分析它们与原始图像的相似性。

使用k-means,图像大小减小到79.012%,仅12种颜色就能解释原始图像的95.916%差异。使用PCA,图像大小减小仅为6.825%,并根据我们的目标解释了95,072%的差异。在经过PCA缩小的图像中,与原始图像相比,存在更多的颜色数量,表明存在噪音。从主观上可以看出,PCA压缩的图像更加粗糙。

与PCA相比,更建议使用k-means来缩小图像尺寸,但是如果我们要保持原始图像的整体色彩,请使用PCA。

另一个建议是尝试连续执行两种方法来进行图像缩小,即先用k-means再用PCA,或是先用PCA再用k-means。

目录
相关文章
|
2天前
|
数据采集 缓存 定位技术
网络延迟对Python爬虫速度的影响分析
网络延迟对Python爬虫速度的影响分析
|
4天前
|
数据采集 存储 JSON
Python爬虫开发中的分析与方案制定
Python爬虫开发中的分析与方案制定
|
11天前
|
数据可视化 开发者 Python
Python GUI开发:Tkinter与PyQt的实战应用与对比分析
【10月更文挑战第26天】本文介绍了Python中两种常用的GUI工具包——Tkinter和PyQt。Tkinter内置于Python标准库,适合初学者快速上手,提供基本的GUI组件和方法。PyQt基于Qt库,功能强大且灵活,适用于创建复杂的GUI应用程序。通过实战示例和对比分析,帮助开发者选择合适的工具包以满足项目需求。
48 7
|
10天前
|
存储 数据处理 Python
Python科学计算:NumPy与SciPy的高效数据处理与分析
【10月更文挑战第27天】在科学计算和数据分析领域,Python凭借简洁的语法和强大的库支持广受欢迎。NumPy和SciPy作为Python科学计算的两大基石,提供了高效的数据处理和分析工具。NumPy的核心功能是N维数组对象(ndarray),支持高效的大型数据集操作;SciPy则在此基础上提供了线性代数、信号处理、优化和统计分析等多种科学计算工具。结合使用NumPy和SciPy,可以显著提升数据处理和分析的效率,使Python成为科学计算和数据分析的首选语言。
20 3
|
11天前
|
存储 机器学习/深度学习 算法
Python科学计算:NumPy与SciPy的高效数据处理与分析
【10月更文挑战第26天】NumPy和SciPy是Python科学计算领域的两大核心库。NumPy提供高效的多维数组对象和丰富的数学函数,而SciPy则在此基础上提供了更多高级的科学计算功能,如数值积分、优化和统计等。两者结合使Python在科学计算中具有极高的效率和广泛的应用。
28 2
|
16天前
|
数据采集 机器学习/深度学习 搜索推荐
Python自动化:关键词密度分析与搜索引擎优化
Python自动化:关键词密度分析与搜索引擎优化
|
17天前
|
数据可视化 算法 JavaScript
基于图论的时间序列数据平稳性与连通性分析:利用图形、数学和 Python 揭示时间序列数据中的隐藏模式
本文探讨了如何利用图论分析时间序列数据的平稳性和连通性。通过将时间序列数据转换为图结构,计算片段间的相似性,并构建连通图,可以揭示数据中的隐藏模式。文章介绍了平稳性的概念,提出了基于图的平稳性度量,并展示了图分区在可视化平稳性中的应用。此外,还模拟了不同平稳性和非平稳性程度的信号,分析了图度量的变化,为时间序列数据分析提供了新视角。
40 0
基于图论的时间序列数据平稳性与连通性分析:利用图形、数学和 Python 揭示时间序列数据中的隐藏模式
|
自然语言处理 算法 Python
|
自然语言处理 算法 索引
|
1天前
|
数据采集 机器学习/深度学习 人工智能
Python编程入门:从基础到实战
【10月更文挑战第36天】本文将带你走进Python的世界,从基础语法出发,逐步深入到实际项目应用。我们将一起探索Python的简洁与强大,通过实例学习如何运用Python解决问题。无论你是编程新手还是希望扩展技能的老手,这篇文章都将为你提供有价值的指导和灵感。让我们一起开启Python编程之旅,用代码书写想法,创造可能。
下一篇
无影云桌面