十五天掌握OpenCV——理解K值聚类

T恤大小问题

  1. 案例分析:服装厂要生产T恤,需要获得尺寸数据,所以收集一批身高体重信息并且绘在坐标系上。
  2. 为了便于生产,需要将数据分类。K值聚类可以把所有数据分为N组。
    1

工作原理

把图中数据分为两组。2
第一步:随机选取两重心点C1、C2.
第二步:计算每个点到两重心点距离。距离C1近标为0,距离C2近标为1.属于0的标为红色,属于1的标为蓝色。2
第三步:重新计算所有蓝色和红色点的重心,以两点更新重心点的位置。
重复第二步,更新点的标记。不断迭代,直到两重心点位置稳定。此时这些点到相应重心的距离之和最小。3
K值聚类改进方向:如何选取好的起始重心点,怎样加速迭代过程。

OpenCV中的K值聚类

解释函数参数—— cv2.kmeans()

输入参数:

  1. samples:np.float32类型数据,每个特征放在一列。
  2. nclusters(K):聚类的最终数目。
  3. criteria:终止迭代的条件。条件满足,迭代终止。含三成员(typw,max_iter,epsilon)的元组。
    ——type终止的三种类型:
    cv2.TERM_CRITERIA_EPS 只有精确度epsilon满足时停止迭代
    cv2.TERM_CRITERIA_MAX_ITER 当迭代次数超过阈值时停止迭代
    cv2.TERM_CRITERIA_EPS+cv2.TERM_CRITERIA_MAX_ITER 上面一个条件满足就停止迭代
    ——max_iter 最大迭代次数
    ——epsilon 精确度阈值
  4. attempts:使用不同的起始标记来执行算法次数。算法返回紧密度最好的标记,紧密度也作为输出被返回。
  5. flags:设置如何选择起始重心。cv2.KMEANS_PP_CENTERS 或 cv2.KMEANS_RANDOM_CENTERS
    输出参数:
  6. compactness:紧密度,返回每个点到相应重心的距离的平方和。
  7. labels:标志数组,将成员标记为0,1。
  8. centers:由聚类中心组成的数组。

仅有一个特征的数据

  1. 对一组只有一个特征的数据,先产生随机数据,使用Matplotlib绘制。
  2. 将长度为50、取值范围是0-255的向量Z进行重排,变成列向量。将数据类型转换为np.float32。得到下图:1
  3. 设置好终止条件:算法执行10次迭代或者精确度为1.0,使用KMeans函数。返回值:紧密度compactness、标志和中心。
  4. A组数据用红色表示,B组数据用蓝色表示,重心用黄色表示。结果下图:2

代码演示

#coding=utf-8
import numpy as np
import cv2
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)

criteria=(cv2.TERM_CRITERIA_EPS+cv2.TERM_CRITERIA_MAX_ITER,10,1.0)
flags=cv2.KMEANS_RANDOM_CENTERS
compactness,labels,centers=cv2.kmeans(z,2,None,criteria,10,flags)

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

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()

4

含有多个特征的数据

有n个特征就使用n列向量。每一行对应每一个元素。1

代码演示

#coding=utf-8
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))

Z=np.float32(Z)

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)

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()

2

颜色量化

  1. 减少图片中颜色数目的一个过程。为了减少内存消耗。
  2. K值聚类的方法来进行颜色量化。
  3. 3个特征:R、G、B,把图片数据变形成M(图片中像素点数目)×3的向量。
  4. 聚类完成后,用聚类中心值替换与其同组的像素值,保证结果图片只含有指定数目的颜色。

代码演示

#coding=utf-8
import cv2
import numpy as np

img=cv2.imread('./image2/mario.jpg')
Z=img.reshape((-1,3))

Z=np.float32(Z)#转换数据类型

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)

center=np.uint8(center)
res=center[label.flatten()]
res2=res.reshape((img.shape))

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

3

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值