opencv - py_ml - py_kmeans

news2024/12/29 10:41:14

文章目录

  • 1.理解 K-Means 聚类
    • 目标
    • 理论
      • T 恤尺码问题
      • 它是如何工作的?
    • 其他资源
  • 2.OpenCV 中的 K-Means 聚类
    • 目标
    • 理解参数
      • 输入参数
      • 输出参数

1.理解 K-Means 聚类

目标

在本章中,我们将理解 K-Means 聚类的概念、其工作原理等。

理论

我们将通过一个常用的例子来处理这个问题。

T 恤尺码问题

假设一家公司即将向市场推出一款新的 T 恤。显然,他们必须生产不同尺寸的款式以满足各种身材的人。因此,该公司制作了人们的身高和体重数据,并将它们绘制在图表上,如下所示:
在这里插入图片描述

公司无法生产所有尺寸的 T 恤。相反,他们将人们分为小号、中号和大号,并只生产适合所有人的这 3 种型号。将人们分成三组可以通过 k 均值聚类来完成,算法会为我们提供最佳的 3 种尺寸,这将满足所有人的需求。如果不能,公司可以将人们分成更多组,可能是五组,依此类推。查看下图:

在这里插入图片描述

它是如何工作的?

该算法是一个迭代过程。我们将借助图像逐步解释它。

考虑如下一组数据(您可以将其视为 T 恤问题)。我们需要将此数据聚类为两组。

在这里插入图片描述

步骤:1 - 算法随机选择两个质心, C 1 C1 C1 C 2 C2 C2(有时,任何两个数据都被视为质心)。

步骤:2 - 计算每个点到两个质心的距离。如果测试数据更接近 C 1 C1 C1,则该数据标记为“0”。如果它更接近 C 2 C2 C2,则标记为“1”(如果有更多质心,则标记为“2”、“3”等)。

在我们的例子中,我们将所有“0”标记为红色,将“1”标记为蓝色。因此,经过上述操作后,我们得到以下图像。

在这里插入图片描述

步骤:3 - 接下来,我们分别计算所有蓝点和红点的平均值,这将是我们的新质心。也就是说, C 1 C1 C1 C 2 C2 C2 移至新计算的质心。(请记住,显示的图像不是真实值,也不是真实比例,仅用于演示)。

再次使用新质心执行步骤 2,并将数据标记为“0”和“1”。

因此,我们得到以下结果:

在这里插入图片描述

现在,步骤 2步骤 3 迭代,直到两个质心都收敛到固定点。
(或者,根据我们提供的标准,例如最大迭代次数,或达到特定精度等,可能会停止。) 这些点使得测试数据和其对应质心之间的距离总和最小。或者简单地说,
C 1 ↔ R e d _ P o i n t s C1 \leftrightarrow Red\_Points C1Red_Points C 2 ↔ B l u e _ P o i n t s C2 \leftrightarrow Blue\_Points C2Blue_Points 之间的距离总和最小。

[ m i n i m i z e    [ J = ∑ A l l   R e d _ P o i n t s d i s t a n c e ( C 1 , R e d _ P o i n t ) + ∑ A l l   B l u e _ P o i n t s d i s t a n c e ( C 2 , B l u e _ P o i n t ) ] ] [minimize \;\bigg[J = \sum_{All\: Red\_Points}distance(C1,Red\_Point) + \sum_{All\: Blue\_Points}distance(C2,Blue\_Point)\bigg]] [minimize[J=AllRed_Pointsdistance(C1,Red_Point)+AllBlue_Pointsdistance(C2,Blue_Point)]]

最终结果几乎如下所示:
在这里插入图片描述
因此,这只是对 K-Means 聚类的直观理解。有关更多详细信息和数学解释,请阅读任何标准机器学习教科书或查看其他资源中的链接。它只是 K-Means 聚类的顶层。对该算法有很多修改,例如如何选择初始质心,如何加快迭代过程等。

其他资源

  • 机器学习课程,Andrew Ng 教授的视频讲座(部分图片取自此处)

2.OpenCV 中的 K-Means 聚类

目标

  • 学习使用 OpenCV 中的 cv.kmeans() 函数进行数据聚类

理解参数

输入参数

  • samples :它应该是 np.float32 数据类型,并且每个特征应该放在一个列中。
  • nclusters(K) :结束时所需的聚类数
  • criteria :它是迭代终止标准。当满足此标准时,算法迭代停止。实际上,它应该是 3 个参数的元组。它们是 `( type, max_iter, epsilon )`:
    • 终止标准类型。它有 3 个标志,如下所示:
      • cv.TERM_CRITERIA_EPS - 如果达到指定的准确度 epsilon,则停止算法迭代。
      • cv.TERM_CRITERIA_MAX_ITER - 在指定的迭代次数 max_iter 后停止算法。
      • cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER - 当满足上述任何条件时停止迭代。
    • max_iter - 指定最大迭代次数的整数。
    • epsilon - 所需准确度
  • attempts:标志,用于指定使用不同初始标签执行算法的次数。算法返回产生最佳紧凑度的标签。此紧凑度作为输出返回。
  • flags:此标志用于指定如何获取初始中心。通常,为此使用两个标志:cv.KMEANS_PP_CENTERScv.KMEANS_RANDOM_CENTERS

输出参数

  • 紧凑性:它是每个点到其相应中心的平方距离之和。

  • 标签:这是标签数组(与上一篇文章中的“代码”相同),其中每个元素标记为“0”、“1”…

  • 中心:这是聚类中心的数组。

现在我们将通过三个示例了解如何应用 K-Means 算法。

  1. 仅具有一个特征的数据

考虑一下,您有一组仅具有一个特征的数据,即一维数据。例如,我们可以以 T 恤问题为例,您仅使用人的身高来决定 T 恤的尺寸。

因此我们首先创建数据并在 Matplotlib 中绘制它

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt

x = np.random.randint(25,100,25)
y = np.random.randint(175,255,25)
z = np.hstack((x,y))
z = z.reshape((50,1))
z = np.float32(z)
plt.hist(z,256,[0,256]),plt.show()

因此,我们有“z”,它是一个大小为 50 的数组,值范围从 0 到 255。我已将“z”重塑为列向量。当存在多个特征时,它将更有用。然后我制作了 np.float32 类型的数据。

我们得到以下图像:

在这里插入图片描述

现在我们应用 KMeans 函数。在此之前,我们需要指定标准。我的标准是这样的:每当运行 10 次算法迭代,或达到 epsilon = 1.0 的精度时,就停止算法并返回答案。

# Define criteria = ( type, max_iter = 10 , epsilon = 1.0 )
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 10, 1.0)

# Set flags (Just to avoid line break in the code)
flags = cv.KMEANS_RANDOM_CENTERS

# Apply KMeans
compactness,labels,centers = cv.kmeans(z,2,None,criteria,10,flags)

这给了我们紧凑性、标签和中心。在本例中,我得到的中心是 60 和 207。标签的大小与测试数据的大小相同,其中每个数据将根据其质心标记为“0”、“1”、“2”等。现在我们根据数据的标签将其拆分为不同的集群。

A = z[labels==0]
B = z[labels==1]

现在我们用红色绘制 A,用蓝色绘制 B,用黄色绘制它们的质心。

# Now plot 'A' in red, 'B' in blue, 'centers' in yellow
plt.hist(A,256,[0,256],color = 'r')
plt.hist(B,256,[0,256],color = 'b')
plt.hist(centers,32,[0,256],color = 'y')
plt.show()

下面是我们得到的输出:

在这里插入图片描述

  1. 具有多个特征的数据

在前面的例子中,我们只取 T 恤问题的身高。在这里,我们将取身高和体重,即两个特征。

记住,在前面的例子中,我们将数据制成单列向量。每个特征排列在一列中,而每行对应一个输入测试样本。

例如,在本例中,我们设置了一个大小为 50x2 的测试数据,其中包含 50 个人的身高和体重。第一列对应所有 50 个人的身高,第二列对应他们的体重。第一行包含两个元素,其中第一个元素是第一个人的身高,第二个元素是他的体重。同样,其余行对应其他人的身高和体重。
查看下图:
在这里插入图片描述

现在我直接转到代码:

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt

X = np.random.randint(25,50,(25,2))
Y = np.random.randint(60,85,(25,2))
Z = np.vstack((X,Y))

# convert to np.float32
Z = np.float32(Z)

# define criteria and apply kmeans()
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 10, 1.0)
ret,label,center=cv.kmeans(Z,2,None,criteria,10,cv.KMEANS_RANDOM_CENTERS)

# Now separate the data, Note the flatten()
A = Z[label.ravel()==0]
B = Z[label.ravel()==1]

# Plot the data
plt.scatter(A[:,0],A[:,1])
plt.scatter(B[:,0],B[:,1],c = 'r')
plt.scatter(center[:,0],center[:,1],s = 80,c = 'y', marker = 's')
plt.xlabel('Height'),plt.ylabel('Weight')
plt.show()

以下是我们得到的输出:
在这里插入图片描述

  1. 颜色量化

颜色量化是减少图像中颜色数量的过程。这样做的原因之一是为了减少内存。有时,某些设备可能存在限制,因此只能产生有限数量的颜色。在这些情况下,也会执行颜色量化。这里我们使用 k-means 聚类进行颜色量化。

这里没有什么新东西需要解释。有 3 个特征,例如 R、G、B。因此,我们需要将图像重塑为 Mx3 大小的数组(M 是图像中的像素数)。聚类之后,我们将质心值(也是 R、G、B)应用于所有像素,这样生成的图像将具有指定数量的颜色。我们再次需要将其重塑回原始图像的形状。
以下是代码:

import numpy as np
import cv2 as cv

img = cv.imread('home.jpg')
Z = img.reshape((-1,3))

# convert to np.float32
Z = np.float32(Z)

# define criteria, number of clusters(K) and apply kmeans()
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 10, 1.0)
K = 8
ret,label,center=cv.kmeans(Z,K,None,criteria,10,cv.KMEANS_RANDOM_CENTERS)

# Now convert back into uint8, and make original image
center = np.uint8(center)
res = center[label.flatten()]
res2 = res.reshape((img.shape))

cv.imshow('res2',res2)
cv.waitKey(0)
cv.destroyAllWindows()

当 K=8 时,结果如下:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2223810.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

4.2-6 使用Hadoop WebUI

文章目录 1. 查看HDFS集群状态1.1 端口号说明1.2 用主机名访问1.3 主节点状态1.4 用IP地址访问1.5 查看数据节点 2. 操作HDFS文件系统2.1 查看HDFS文件系统2.2 在HDFS上创建目录2.3 上传文件到HDFS2.4 删除HDFS文件和目录 3. 查看YARN集群状态4. 实战总结 1. 查看HDFS集群状态 …

JVM 实战篇(一万字)

此笔记来至于 黑马程序员 内存调优 内存溢出和内存泄漏 内存泄漏(memory leak):在Java中如果不再使用一个对象,但是该对象依然在 GC ROOT 的引用链上,这个对象就不会被垃圾回收器回收,这种情况就称之为内…

matlab中,close和close all的区别、clc和clear的区别、

文章目录 1. clear vs. clear all2. clc vs. clear3. hold on vs. hold off4. subplot vs. subplot(221)5. axis tight vs. axis equal6. save vs. saveas总结 在 MATLAB 中,有许多命令和函数在功能上相似,但其用法和效果却有所不同。以下是一些常见的例…

基于SSM+小程序的垃圾分类管理系统(垃圾2)

👉文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1、项目介绍 基于SSM小程序的垃圾分类管理系统实现了管理员及用户。 1、管理员功能结构图,管理员功能有个人中心,管理员管理,基础数据管理、论坛管理、垃圾信息管理…

logback 如何将日志输出到文件

如何作 将日志输出到文件需要使用 RollingFileAppender&#xff0c;该 Appender 必须定义 rollingPolicy &#xff0c;另外 rollingPollicy 下必须定义 fileNamePattern 和 encoder <appender name"fileAppender" class"ch.qos.logback.core.rolling.Rollin…

Zabbix企业级分布式监控环境部署

“运筹帷幄之中&#xff0c;决胜千里之外”。在IT运维中&#xff0c;监控占据着重要的地位&#xff0c;按比例来算&#xff0c;说占30%一点也不为过。对IT运维工程师来说&#xff0c;构建一个真正可用的监控告警系统是一项艰巨的任务。在监控系统的开源软件中&#xff0c;可供选…

论文阅读:华为的LiMAC

《LIGHTWEIGHT NEURAL APP CONTROL》 用于app控制的轻量级神经网络 摘要 输入是一个文本目标和一系列过去的移动感知&#xff0c;比如截图和相应的UI树&#xff0c;来生成精确的动作。 针对智能手机固有的计算限制&#xff0c;我们在LiMAC中引入了一个小型Action Transforme…

【安全解决方案】深入解析:如何通过CDN获取用户真实IP地址

一、业务场景 某大型互联网以及电商公司为了防止客户端获取到真实的ip地址&#xff0c;以及达到保护后端业务服务器不被网站攻击&#xff0c;同时又可以让公安要求留存网站日志和排查违法行为&#xff0c;以及打击犯罪的时候&#xff0c;获取不到真实的ip地址&#xff0c;发现…

元数据 - ​媒体管理

媒体管理 Media Management元数据遵循 XMP&#xff08;可扩展元数据平台&#xff09;规范&#xff0c;特别是 xmpMM&#xff08;XMP Media Management&#xff09;命名空间。通过理解和利用这些元数据&#xff0c;可以更好地管理媒体文件的版本、历史记录、派生关系和管理信息&…

Flutter Image和Text图文组件实战案例

In this section, we’ll go through the process of building a user interface that showcases a product using the Text and Image widgets. We’ll follow Flutter’s best practices to ensure a clean and effective UI structure. 在本节中&#xff0c;我们将使用“Te…

ue5实现数字滚动增长

方法1 https://www.bilibili.com/video/BV1h14y197D1/?spm_id_from333.999.0.0 b站教程 重写loop节点 方法二 写在eventtick里

合并数组的两种常用方法比较

在 JavaScript 中&#xff0c;合并数组的两种常用方法是使用扩展运算符 (...) 和使用 push 方法。 使用扩展运算符 this.items [...this.items, ...data.items]; 优点&#xff1a; 易于理解&#xff1a;使用扩展运算符的语法非常直观&#xff0c;表达了“将两个数组合并成一个…

最新版本jdbcutils集成log4j做详细sql日志、自动释放连接...等

maven坐标 <!-- MySQL 8 --><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><version>8.0.33</version></dependency><!-- Druid连接池 --><dependency><groupId&…

记一次AWS服务器扩容

1、首先通过下列命令列出设备详情&#xff0c;可以看到红色框起来的部分有160G&#xff0c;需要把新增的20G扩容到根目录(139.9)上 lsblk查看文件系统 df -h2.执行sudo growpart /dev/xvda 1即可把20G的空间扩容到根目录上 扩容成功 但是可以看到并未生效 3.列出文件系统格…

菜叶子芯酸笔记2:服务器、互联技术和AI芯片参数解读

服务器相关知识 服务器是一种高性能计算机&#xff0c;作为网络的节点&#xff0c;存储、处理网络上80%的数据、信息&#xff0c;因此也被称为网络的灵魂。 服务器的分类 种类 描述 塔式服务器(tower server) 正面似PC机&#xff0c;但侧面长度长很多&#xff0c;无统一标准…

pair类型应用举例

在main.cpp里输入程序如下&#xff1a; #include <iostream> //使能cin(),cout(); #include <utility> //使能pair数据类型; #include <string> //使能string字符串; #include <stdlib.h> //使能exit(); //pair类型可以将两个相同的或不同类…

2024年10月-2025年5月 Oracle 19c OCM 考试安排

2024年10月-2025年5月 Oracle 19c OCM 考试安排&#xff1a; 北京考场&#xff1a; 上海考场&#xff1a; 更新时间&#xff1a;2024年10月25日 Oracle 19c OCM往期学员成绩展示&#xff1a; Oracle 19c OCM认证证书&#xff08;电子版&#xff09;

数理统计(第3章第1节:假设检验的基本概念)

目录 假设检验&#xff1a;对母体的分布或者母体分布中的未知参数提出某种假设&#xff0c;由子样推断是否接受该种假设 假设检验的基本概念&#xff08;概率性质的反证法&#xff09; 假设检验&#xff1a;对母体的分布或者母体分布中的未知参数提出某种假设&#xff0c;由子…

云计算欲上九天,AI大模型能否推波助澜?

大数据产业创新服务媒体 ——聚焦数据 改变商业 时代洪流滚滚朝前&#xff0c;千禧年的“世界末日”并未如期而至&#xff0c;但信息大爆炸了&#xff0c;有人开始探索那80%常规生活以外的“20%世界”。谁都未曾想到恰恰这20%成为了如今赛博世界的“种子”&#xff0c;数据不再…

考研读研生存指南,注意事项

本视频&#xff0c;涉及考研读研的方方面面&#xff0c;从考研初试→复试面试→研究生生活→导师相处→论文专利写作混毕业&#xff0c;应有尽有。有了他&#xff0c;你的研究生生涯稳了。 读研考研注意事项&#xff0c;研究生生存指南。_哔哩哔哩_bilibili 一、考研初试注意事…