在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。

目录
相关文章
|
23天前
|
JSON 算法 API
深度分析小红书城API接口,用Python脚本实现
小红书作为以UGC内容为核心的生活方式平台,其非官方API主要通过移动端抓包解析获得,涵盖内容推荐、搜索、笔记详情、用户信息和互动操作等功能。本文分析了其接口体系、认证机制及请求规范,并提供基于Python的调用框架,涉及签名生成、登录态管理与数据解析。需注意非官方接口存在稳定性与合规风险,使用时应遵守平台协议及法律法规。
|
22天前
|
数据采集 存储 JSON
地区电影市场分析:用Python爬虫抓取猫眼/灯塔专业版各地区票房
地区电影市场分析:用Python爬虫抓取猫眼/灯塔专业版各地区票房
|
23天前
|
JSON API 开发者
深度分析阿里妈妈API接口,用Python脚本实现
阿里妈妈是阿里巴巴旗下营销平台,提供淘宝联盟、直通车等服务,支持推广位管理、商品查询等API功能。本文详解其API调用方法,重点实现商品推广信息(佣金、优惠券)获取,并提供Python实现方案。
|
21天前
|
数据采集 数据可视化 API
驱动业务决策:基于Python的App用户行为分析与可视化方案
驱动业务决策:基于Python的App用户行为分析与可视化方案
|
22天前
|
API 数据安全/隐私保护 开发者
深度分析苏宁API接口,用Python脚本实现
深度分析苏宁API接口,用Python脚本实现
|
23天前
|
JSON API 数据安全/隐私保护
深度分析虾皮城API接口,用Python脚本实现
虾皮开放平台提供丰富的API接口,支持商品管理、订单处理及促销信息查询等功能。本文详解API认证机制与调用方法,基于Python实现商品价格及到手价获取方案,适用于电商数据分析与运营。
|
23天前
|
数据采集 机器学习/深度学习 数据可视化
Python量化交易:结合爬虫与TA-Lib技术指标分析
Python量化交易:结合爬虫与TA-Lib技术指标分析
|
自然语言处理 算法 Python
|
自然语言处理 算法 索引
|
3月前
|
Python
Python编程基石:整型、浮点、字符串与布尔值完全解读
本文介绍了Python中的四种基本数据类型:整型(int)、浮点型(float)、字符串(str)和布尔型(bool)。整型表示无大小限制的整数,支持各类运算;浮点型遵循IEEE 754标准,需注意精度问题;字符串是不可变序列,支持多种操作与方法;布尔型仅有True和False两个值,可与其他类型转换。掌握这些类型及其转换规则是Python编程的基础。
207 33

推荐镜像

更多