OpenCV52:OpenCV中的Kmeans聚类

目标

  • 了解如何在OpenCV中使用cv2.kmeans()函数进行数据聚类

理解参数

输入参数
  • sample:它应该是np.float32数据类型,并且每个特征都应该放在单个列中

  • nclusters(K):结束条件所需的簇数

  • criteria:这是迭代终止标准条件。满足此条件后,算法迭代将停止。实际上,它是3个参数的元组,分别是(type, max_iter, epsilon)

    • type 终止条件的类型,它具有3个标志,如下所示:

      • cv2.TERM_CRITERIA_EPS-如果达到指定的精度epsilon,则停止算法迭代

      • cv2.TERM_CRITERIA_MAX_ITER-在指定的迭代次数max_iter之后停止算法

      • cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER-当满足上述任何条件时停止迭代

    • max_iter-一个整数,指定最大迭代次数
    • epsilon-要求的精度
  • attempts:该标志用于指定使用不同的初始标签执行算法的次数。该算法返回产生最佳紧密度的标签。该紧凑性作为输出返回。

  • flags:此标志用于指定初始中心的获取方式。通常,为此使用两个标志:**cv2.KMEANS_PP_CENTERS**和cv2.KMEANS_RANDOM_CENTERS

输出参数
  • compactness:它是每个点到其相应中心的平方距离的总和。

  • labels:这是标签数组,其中每个元素可以标记为01

  • centers:这是群集中心的阵列。

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

单特征数据

假设有一组仅具有一个特征(即一维)的数据。例如,之前的T恤问题,只用身高这一特征来决定T恤的尺寸。因此,首先创建数据并将其绘制在Matplotlib中

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

x = np.random.randint(25, 100, 25)     # 25个25~100的数据
y = np.random.randint(175, 255, 25)    # 25个175~255的数据

z = np.hstack((x,y))   # 堆叠在一起
z = z.reshape((50,1))  # 向量变换
z = np.float32(z)      # 数据类型变换

plt.hist(z, 256, [0,256])  # 绘制直方图
plt.show()

因此,通过随机生成获得z数据,它是一个大小为(50, 1)的数组,值的范围是0到255,将z重塑为列向量后画出以下图像:

oc_1d_testdata.png

现在应用OpenCV的KMeans函数。在此之前,需要指定停止标准,本次设置的标准是迭代运行10次算法或达到 e p s i l o n = 1.0 epsilon=1.0 epsilon=1.0精度时,就停止算法并返回结果。

# define cirteria = (type, max_iter=10, epsilon=1.0)
certeria = (cv2.TERM_CRITERIA_EPS+cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)

# set flags 
flags = cv2.KMEANS_RANDOM_CENTERS

# apply KMeans
compactness, labels, centers = cv2.kmeans(z, 2, None, certeria, 10, flags)  # 分为2簇
print(compactness, centers, labels)

# centers 
# array([[ 57.879997],
#        [225.12    ]], dtype=float32)

# labels 每个点所属于的类别

# compactness 每个点距离属于的簇心的距离和

上述结果提供了紧凑性,标签和中心。在这种情况下,得到的中心分别为58和225。标签的大小将与测试数据的大小相同,其中每个数据的质心都将标记为01等。现在根据标签将数据分为不同的群集。

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

现在以红色绘制A,以蓝色绘制B,以黄色绘制其质心。

# now ploat 'A'用红色 'B'用蓝色,用黄色画出质心
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()

得到以下结果:

oc_1d_clustered.png

多特征数据

在前面的示例中,仅考虑了T恤问题的身高。多维数据时候需要考虑多个特征,这里将同时考虑身高和体重两个特征

在以前的情况下,将数据制作为单个列向量,每个特征排列在一列中,而每一行对应于一个输入测试样本

在多维情况下,设置了一个大小为50x2的测试数据,即50个人的身高和体重。第一列对应于全部50个人的身高,第二列对应于体重。第一行包含两个元素,其中第一个是第一人称的身高,第二个是其的体重。类似地,剩余的行对应于其他人的身高和体重。查看下面的图片:

oc_feature_representation.jpg

多维特征的实现代码

import cv2
import numpy as np
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))

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

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

# None seperate the data, note the flatten()
A = Z[label.ravel()==0]
B = Z[label.ravel()==1]

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

得到如下结果:

oc_2d_clustered.jpg

颜色量化

颜色量化(color quantization)是减少图像中颜色数量的过程,这样做的目的之一是减少内存。有时,某些设备可能会受到限制,因此只能产生有限数量的颜色。同样在那些情况下,执行颜色量化。在这里使用k均值聚类进行颜色量化

彩色图像每个像素点有3个值R,G,B,将其作为三个特征。因此,需要将图像重塑为Mx3大小的数组(M是图像中的像素数)。**在聚类之后,将质心值(也是R,G,B)应用于所有像素,以使生成的图像具有指定数量的颜色。**之后将向量转化为原始图像的形状。下面是代码:

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

img = cv2.imread('home.png')
Z = img.reshape((-1, 3))

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

# # define criteria, number of clusters(K) and apply kmeans()
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
K = 8

ret, label, center = cv2.kmeans(Z, K, None, criteria, 10, cv2.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))

plt.imshow(res2)
plt.show()

可以看的K=2, K=4, K=8的结果

oc_color_quantization.jpg

附加资源

  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
OpenCVkmeans聚类算法是一种用于将数据集分成K个簇的无监督学习算法。它的主要步骤如下: 首先,通过OpenCV的随机数生成器RNG,生成一些均匀分布的随机点,这些点的位置对应一副图像的像素位置。 然后,使用kmeans算法对这些随机点进行分类,并计算出每个类簇的心点。该算法将数据集的每个样本点分配到最近的心点,然后更新心点的位置,再重复这个过程直到满足终止标准为止。 在OpenCVkmeans算法的函数原型如下:kmeans(data, K, bestLabels, criteria, attempts, flags, centers)。其,data是用于聚类的数据,可以是具有浮点坐标的N维点数组;K是用来分割数据集的簇数;bestLabels是输入/输出整数数组,用于存储每个样本的聚类索引;criteria是算法终止标准,包括最大迭代次数和/或所需精度;attempts是用于指定执行算法的次数的标志;flags指定了算法的具体实现方法,可以选择使用随机的初始心还是使用Arthur和Vassilvitskii进行的心初始化,或者使用用户提供的标签来进行计算。 通过使用kmeans算法,我们可以将数据集分成具有相似特征的簇,从而实现数据的聚类分析。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [OpenCV使用kmeans算法的方法](https://blog.csdn.net/jpc20144055069/article/details/102763754)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

uncle_ll

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值