Opencv和pycharm实现k-means对图像的分割处理

该博客介绍了如何使用OpenCV和PyCharm通过K-Means算法对图像进行分割处理。文章详细阐述了K-Means算法的步骤,包括选择初始中心点、迭代更新直至收敛,并探讨了算法的优缺点。作者通过实例展示了不同聚类数(2、3、4、5、32)对图像分割的影响,并提供了相应的代码实现和运行结果。
摘要由CSDN通过智能技术生成

用Opencv和pycharm实现k-means对图像的分割处理

注:这个例子只适合学习用,图像处理用k-means就像2021年用大哥大
安装Opncv: https://blog.csdn.net/aspecialpig/article/details/105746760

k-means算法

1.确定聚K类,随机选择K个点为中心点(质心)
2.计算所有样本点各自到K个中心的距离(欧氏距离),根据远近聚类
3.聚类完成后,每个聚类求平均值更新中心,重复上一步迭代
4.直到满足收敛条件(一般是中心点不再改变或者改变很小)
关键:
1.K选择聚几次
2.初始点选择(当前簇中所有数据点的平均值)
3.迭代次数
优点:
1.简单易实现
2.聚类效果中上(靠K和中心点的选择)
3.空间复杂度N,时间复杂度NKI(N样本个数,K中心点个数,I迭代次数)
缺点:
1.对离群点,噪声点敏感(求平均值更新中心点)
2.难区别样本少而且紧密的点
3.大规模数据,收敛速度比较慢(所有数据的平均值)
4.结果不一定全局最优,只是局部最优(与K和初始点选取有关)

代码

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

#读取原始图像
img = cv2.imread('girl.png')
print(img.shape)#高度,宽度,通道数量(可以看成属性),3表示RGB

#图像二维像素转换为一维,每一维上每个像素(样本)有三个属性
#遇到的RGB图像的值是处于0-255之间的,为了更好的处理图像,通常会将图像值转变到0-1之间
#这个处理的过程就是图像的float类型转变为uint8类型过程。
#float类型取值范围 :-1 到1 或者 0到1
#uint8类型取值范围:0到255
data = img.reshape((-1,3))#属性3个,其他变成一维
print(data.shape)
print(data.dtype)#查看数据类型 是uint8
data = np.float32(data)#将图像uint8转换为float,

#迭代停止模式选择(type, max_iter, epsilon)
#cv2.TERM_CRITERIA_EPS :精确度(误差)满足epsilon,则停止。
#cv2.TERM_CRITERIA_MAX_ITER:迭代次数超过max_iter,则停止。
#两者结合,满足任意一个结束。
criteria = (cv2.TERM_CRITERIA_EPS +
            cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
#初始点选取
#v2.KMEANS_PP_CENTERS:使用kmeans++算法的中心初始化算法,即初始中心的选择使眼色相差最大.
#cv2.KMEANS_RANDOM_CENTERS:每次随机选择初始中心(Select random initial centers in each attempt.)
flags = cv2.KMEANS_RANDOM_CENTERS
#compactness:紧密度,返回每个点到相应重心的距离的平方和
#labels:结果标记,每个成员被标记为分组的序号,如 0,1,2,3,4...等
#centers:由聚类的中心组成的数组
#K-Means聚类 聚集成2类
compactness2, labels2, centers2 = cv2.kmeans(data, 2, None, criteria, 10, flags)#None处表示分类标签,10表示重复试验10次返回最好一次结果
#K-Means聚类 聚集成4类
compactness3, labels3, centers3 = cv2.kmeans(data, 3, None, criteria, 10, flags)
#K-Means聚类 聚集成8类
compactness4, labels4, centers4 = cv2.kmeans(data, 4, None, criteria, 10, flags)
#K-Means聚类 聚集成16类
compactness5, labels5, centers5 = cv2.kmeans(data, 5, None, criteria, 10, flags)
#K-Means聚类 聚集成64类
compactness32, labels32, centers32 = cv2.kmeans(data, 32, None, criteria, 10, flags)

#图像转换回uint8二维类型,为BGR图像,不是原图
centers2 = np.uint8(centers2)
res = centers2[labels2]
dst2 = res.reshape((img.shape))

centers3 = np.uint8(centers3)
res = centers3[labels3]
dst3 = res.reshape((img.shape))

centers4 = np.uint8(centers4)
res = centers4[labels4]
dst4 = res.reshape((img.shape))

centers5 = np.uint8(centers5)
res = centers5[labels5]
dst5 = res.reshape((img.shape))

centers32 = np.uint8(centers32)
res = centers32[labels32]
dst32 = res.reshape((img.shape))

#BGR图像转换为RGB显示
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)#cv2.COLOR_BGR2RGB 将BGR格式转换成RGB格式
dst2 = cv2.cvtColor(dst2, cv2.COLOR_BGR2RGB)
dst3 = cv2.cvtColor(dst3, cv2.COLOR_BGR2RGB)
dst4 = cv2.cvtColor(dst4, cv2.COLOR_BGR2RGB)
dst5 = cv2.cvtColor(dst5, cv2.COLOR_BGR2RGB)
dst32 = cv2.cvtColor(dst32, cv2.COLOR_BGR2RGB)

#用来正常显示中文标签
plt.rcParams['font.sans-serif']=['SimHei']
#显示图像
titles = [u'原始图像', u'聚类图像 K=2', u'聚类图像 K=3',
          u'聚类图像 K=4', u'聚类图像 K=5',  u'聚类图像 K=32']
images = [img, dst2, dst3, dst4, dst5, dst32]
for i in range(6):
   plt.subplot(2,3,i+1)#2行3列
   plt.imshow(images[i])
   plt.title(titles[i])
   plt.xticks([]),plt.yticks([])#X,Y轴标空
plt.show()

图片

girl.png

运行结果

在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值