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

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

重复试验

在本节中,我们将在𝑘= 2到𝑘= 20之间重复此步骤:

  1. 执行k-means以获取每个像素的聚类中心和聚类标签
  2. 将每个像素替换为其聚类中心。
  3. 保存指标值以进行进一步优化:WCSS,BCSS,解释方差和图像大小
  4. 用越来越多的颜色绘制压缩图像
range_k_clusters = (2, 21)
kmeans_result = []
for k in range(*range_k_clusters):
     # CLUSTERING
     kmeans = KMeans(n_clusters = k,
                     n_jobs = -1,
                     random_state = 123).fit(X)
     # REPLACE PIXELS WITH ITS CENTROID
     new_pixels = replaceWithCentroid(kmeans)
     # EVALUATE
     WCSS = kmeans.inertia_
     BCSS = calculateBCSS(X, kmeans)
     exp_var = 100*BCSS/(WCSS + BCSS)
     metric = {
         "No. of Colors": k,
         "Centroids": list(map(get_colour_name, np.uint8(kmeans.cluster_centers_))),
         "Pixels": new_pixels,
         "WCSS": WCSS,
         "BCSS": BCSS,
         "Explained Variance": exp_var,
         "Image Size (KB)": imageByteSize(new_pixels)
    }
     kmeans_result.append(metric)
kmeans_result = pd.DataFrame(kmeans_result).set_index("No. of Colors")
kmeans_result

image.png

聚类指标:最佳的颜色种类数

在本节中,我们将尝试搜索最佳的颜色数(聚类中心)k,以便在保持较高的解释方差百分比的同时将内存大小减小到尽可能小。

image.png

如何确定最佳颜色数k?以下是算法:

  1. 用直线连接曲线的第一个和最后一个点
  2. 计算每个点到该线的垂直距离
  3. 将距离最长的点视为拐点

image.png

下一个问题,如何在步骤2中计算垂直距离?很简单,我们可以使用从点(x0,y0)到线ax + by + c = 0的距离公式,如下所示:

image.png

def locateOptimalElbow(x, y):
     # START AND FINAL POINTS
     p1 = (x[0], y[0])
     p2 = (x[-1], y[-1])
     # EQUATION OF LINE: y = mx + c
     m = (p2[1] - p1[1]) / (p2[0] - p1[0])
     c = (p2[1] - (m * p2[0]))
     # DISTANCE FROM EACH POINTS TO LINE mx - y + c = 0
     a, b = m, -1
     dist = np.array([abs(a*x0+b*y0+c)/math.sqrt(a**2+b**2) for x0, y0 in zip(x,y)])
     return np.argmax(dist) + x[0]

但是,如果图形不是增加或减少的曲线函数,该怎么办?我们可以使用有限差分法使用二阶导数来定位梯度中变化最剧烈的地方。

什么是有限差分法?这是一种数值方法,可以近似离散值的导数。共有三种类型:

forward差异:

image.png

backward差异:

image.png

中心差异:

image.png

其中:

f’(x)是函数f(x)的一阶导数h是步长,在这种情况下,h = 1(颜色数的步长)O(h)是一级误差项O(h²)是二次误差项

由于中心差异具有较高的度数误差项,因此预期它会比其他两个差异产生更好的结果。我们仅对第一个点使用前向差异,对最后一个点使用后向差异。

def calculateDerivative(data):
     derivative = []
     for i in range(len(data)):
         if i == 0:
             # FORWARD DIFFERENCE
             d = data[i+1] - data[i]
         elif i == len(data) - 1:
             # BACKWARD DIFFERENCE
             d = data[i] - data[i-1]
         else:
             # CENTER DIFFERENCE
             d = (data[i+1] - data[i-1])/2
         derivative.append(d)
     return np.array(derivative)
def locateDrasticChange(x, y):
     # CALCULATE GRADIENT BY FIRST DERIVATIVE
     first_derivative = calculateDerivative(np.array(y))
     # CALCULATE CHANGE OF GRADIENT BY SECOND DERIVATIVE
     second_derivative = calculateDerivative(first_derivative)
return np.argmax(np.abs(second_derivative)) + x[0]

让我们搜索每个指标的最佳k值:

optimal_k = []
for col in kmeans_result.columns[2:]:
     optimal_k_dict = {}
     optimal_k_dict["Metric"] = col
     if col == "Image Size (KB)":
         optimal_k_dict["Method"] = "Derivative"
         optimal_k_dict["Optimal k"] = locateDrasticChange(kmeans_result.index, kmeans_result[col].values)
     else:
         optimal_k_dict["Method"] = "Elbow"
         optimal_k_dict["Optimal k"] = locateOptimalElbow(kmeans_result.index, kmeans_result[col].values)
     optimal_k.append(optimal_k_dict)
optimal_k = pd.DataFrame(optimal_k)
optimal_k

image.png

我们选择最大的最优k作为所有最优k的代表,即k = 12。

目录
相关文章
|
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 揭示时间序列数据中的隐藏模式
|
1天前
|
数据采集 机器学习/深度学习 人工智能
Python编程入门:从基础到实战
【10月更文挑战第36天】本文将带你走进Python的世界,从基础语法出发,逐步深入到实际项目应用。我们将一起探索Python的简洁与强大,通过实例学习如何运用Python解决问题。无论你是编程新手还是希望扩展技能的老手,这篇文章都将为你提供有价值的指导和灵感。让我们一起开启Python编程之旅,用代码书写想法,创造可能。
|
3天前
|
Python
不容错过!Python中图的精妙表示与高效遍历策略,提升你的编程艺术感
本文介绍了Python中图的表示方法及遍历策略。图可通过邻接表或邻接矩阵表示,前者节省空间适合稀疏图,后者便于检查连接但占用更多空间。文章详细展示了邻接表和邻接矩阵的实现,并讲解了深度优先搜索(DFS)和广度优先搜索(BFS)的遍历方法,帮助读者掌握图的基本操作和应用技巧。
17 4
|
3天前
|
设计模式 程序员 数据处理
编程之旅:探索Python中的装饰器
【10月更文挑战第34天】在编程的海洋中,Python这艘航船以其简洁优雅著称。其中,装饰器作为一项高级特性,如同船上的风帆,让代码更加灵活和强大。本文将带你领略装饰器的奥秘,从基础概念到实际应用,一起感受编程之美。
下一篇
无影云桌面