目标
了解参数
输入参数
- 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_CENTERS 和 cv.KMEANS_RANDOM_CENTERS。
输出参数
- compactness:它是到其相应中心的每个点的平方距离之和。
- labels:这是标签数组(与前一篇文章中的“code”相同),其中每个元素标记为“0”、“1”......
- centers:这是簇中心的数组。
现在,我们将通过三个示例了解如何应用 K 均值算法。
1. 仅具有一个特征的数据
考虑一下,你有一组仅具有一个特征的数据,即一维数据。例如,我们可以解决 T 恤问题,其中仅使用人的身高来确定 T 恤的尺码。
因此,我们首先创建数据并在 Matplotlib 中绘制它
import numpy as np
import cv2 as cv
从 matplotlib 导入 pyplot 为 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,就停止算法并返回答案。
标准 = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 10, 1.0)
标志 = cv.KMEANS_RANDOM_CENTERS
double kmeans(InputArray data, int K, InputOutputArray bestLabels, TermCriteria criteria, int attempts, int flags, OutputArray centers=noArray())
找出聚类的中心,并在该中心周围对输入样本进行分组。
这向我们提供了紧密度、标签和中心。在这种情况下,我获得的中心为 60 和 207。标签的大小将与测试数据相同,其中每个数据将标记为“0”、“1”、“2”等,具体取决于其质心。现在,我们根据标签将数据拆分为不同的聚类。
A = z[标签==0]
B = z[标签==1]
现在,我们以红色绘制 A,以蓝色绘制 B,并以黄色绘制其质心。
plt.hist(A,256,[0,256],color = 'r')
plt.hist(B,256,[0,256],color = 'b')
plt.hist(中心,32,[0,256],color = 'y')
plt.show()
以下为我们获得的输出
图像
2. 具有多个特征的数据
在上一个示例中,我们只针对 t 恤问题采用身高。在这里,我们将采用身高和体重,即两个特征。
请记住,在以前的情况下,我们将我们的数据变为单列向量。每个特征按列排列,而每一行都对应一个输入测试样本。
例如,在此情况下,我们设置了一个大小为 50x2 的测试数据,即 50 人的身高和体重。第一列对应于所有 50 人的身高,第二列对应于他们的体重。第一行包含两个元素,其中第一个元素是第一位的身高,第二个元素是他的体重。类似地,其余的行对应于其他人的身高和体重。查看下图
图像
现在我直接转到代码
import numpy as np
import cv2 as cv
从 matplotlib 导入 pyplot 为 plt
X = np.random.randint(25,50,(25,2))
Y = np.random.randint(60,85,(25,2))
Z = np.vstack((X,Y))
Z = np.float32(Z)
标准 = (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)
A = Z[label.ravel()==0]
B = Z[label.ravel()==1]
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()
以下是我们获得的输出
图像
3. 颜色量化
颜色量化是减少图像中颜色数量的过程。这样做的一个原因是为了减少内存。有时,某些设备可能有限制,只能产生有限数量的颜色。在这些情况下,也会执行颜色量化。这里我们使用 k 均值聚类进行颜色量化。
这里无需解释任何新内容。有 3 个特征,例如 R、G、B。因此,我们需要将图像重新调整为 Mx3 大小的数组(M 是图像中的像素数量)。在聚类后,我们将质心值(它也是 R、G、B)应用于所有像素,从而使生成的图像具有指定数量的颜色。我们还需要将其重新调整回原始图像的形状。以下是代码
import numpy as np
import cv2 as cv
Z = img.reshape((-1,3))
Z = np.float32(Z)
标准 = (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)
center = np.uint8(center)
res = center[label.flatten()]
res2 = res.reshape((img.shape))
void imshow(const String &winname, InputArray mat)
在指定窗口中显示图像。
int waitKey(int delay=0)
等待按下的键。
void destroyAllWindows()
销毁所有 HighGUI 窗口。
CV_EXPORTS_W Mat imread(const String &filename, int flags=IMREAD_COLOR)
从文件中加载图像。
请参阅 K=8 以下的结果
图像
其他资源
练习