09基于聚类的“图像分割”实例编写
图像分割
图像分割:利用图像的灰度、颜色、纹理、形状等特征,把图像分成若干个互不重叠的区域,并使这些特征在同一区域内呈现相似性,在不同的区域之间存在明显的差异性。然后就可以将分割的图像中具有独特性质的区域提取出来用于不同的研究。
图像分割技术已在实际生活中得到广泛的应用。例如:在机车检验领域,可以应用到轮毂裂纹图像的分割,及时发现裂纹,保证行车安全;在生物医学工程方面,对肝脏CT图像进行分割,为临床治疗和病理学研究提供帮助。
图像分割常用方法
阈值分割:对图像灰度值进行度量,设置不同类别的阈值,达到分割的目的。
边缘分割:对图像边缘进行检测,即检测图像中灰度值发生跳变的地方,则为一片区域的边缘。
直方图法:对图像的颜色建立直方图,而直方图的波峰波谷能够表示一块区域的颜色值的范围,来达到分割的目的。
特定理论:基于聚类分析、小波变换等理论完成图像分割。
实例描述
目标:利用K-means聚类算法对图像像素点颜色进行聚类实现简单的图像分割。
输出:同一聚类中的点使用相同颜色标记,不同聚类颜色不同。
技术路线:sklearn.cluster.KMeans
实例数据:本实例中的数据可以是任意大小的图片,为了使效果更佳直观,可以采用区分度比较明显的图片。
实验过程
PIL包:因为本实验涉及图像的加载和创建,因此需要使用到PIL包。
实现步骤:
1、建立工程并导人sklearn包
2、加载图片并进行预处理
3、加载Kmeans聚类算法
-
km = KMeans (n clusters=3 )
-
其中n_clusters属性指定了聚类中心的个数为3
4、对像素点进行聚类并输出
- 依据聚类中心,对属于同一聚类的点使用同样的颜色进行标记。
具体代码
# 1、建立工程并导人sklearn包
import numpy as np
# 加载PIL包,用于加载创建图片
import PIL.Image as image
# 加载KMeans算法
from sklearn.cluster import KMeans
# 2、加载图片并进行预处理
# 加载训练数据
def loadData(filePath):
# 以二进制形式打开文件
f = open(filePath, 'rb')
data = []
img = image.open(f) # 以列表形式返回图片像素值
m, n = img.size # 获得图片的大小
for i in range(m): # 将每个像素点RGB颜色处理到0-1
for j in range(n): # 范围内并存放进data
x, y, z = img.getpixel((i, j))
data.append([x / 256.0, y / 256.0, z / 256.0])
f.close()
return np.mat(data), m, n # 以矩阵形式返回data,以及图片大小
imgData, row, col = loadData('1.jpg') # 加载数据
# 3、加载Kmeans聚类算法
# 聚成4类
km = KMeans(n_clusters=4)
# 4、对像素点进行聚类并输出
# 用fit_predict()函数聚类获得每个像素所属的类别
label = km.fit_predict(imgData)
label = label.reshape([row, col])
# 创建一张新的灰度图片保存聚类后的结果
pic_new = image.new("L", (row, col))
# 根据所属类别向图片中添加灰度值
for i in range(row):
for j in range(col):
pic_new.putpixel((i,j), int(256/(label[i][j]+1)))
# 以JPEG格式保存图像
pic_new.save("result-4.jpg", "JPEG")
实验分析
通过设置不同的k值,能够得到不同的聚类结果。同时,k值的不确定也是Kmeans算法的一个缺点。往往为了达到好的实验结果,需要进行多次尝试才能够选取最优的k值。而像层次聚类的算法,就无需指定k值,只要给定限制条件,就能自动地得到类别数k。
原始图片:
-
聚成2类,km = KMeans(n_clusters=2)
-
聚成3类,km = KMeans(n_clusters=3)
-
聚成4类,km = KMeans(n_clusters=4)
最后的思考
-
因为本实验涉及图像的加载和创建,因此需要使用到PIL包,需要提前导入
-
刚开始写完代码,运行后会出现一个报错
D:\pywork\venv\lib\site-packages\sklearn\utils\validation.py:585: FutureWarning: np.matrix usage is deprecated in 1.0 and will raise a TypeError in 1.2. Please convert to a numpy array with np.asarray. For more information see: https://numpy.org/doc/stable/reference/generated/numpy.matrix.html warnings.warn(
找了一下百度:matrix的用法在1.0中被弃用,并将在1.2中引发TypeError。请使用np.asarray转换为numpy数组
查了一上午,解决办法可以把numpy的版本降下来,在吃饭前发现,这个好像是个warning,不用管,其实结果以及跑出来了,气死
-
图片自己找,我放在了同文件夹下的,这样路径简单
-
聚成的类自己定,定的n_clusters的数,会有不同的结果
自己导入PIL包
-
第一种:可以直接在pycharm里面,找到settings里的Python Interpreter,点+号自己加,名字是Pillow
-
第二种
- 在https://www.lfd.uci.edu/~gohlke/pythonlibs/#numpy 网站上找到自己python对应的版本的pillow,我下载的是Pillow-8.3.2-cp39-cp39-win_amd64.whl,
- 我放在python中的Scripts文件夹里
- 运行pip install Pillow-8.3.2-cp39-cp39-win_amd64.whl,进行安装
- 具体差不多的下载方法,可以对照02SKlearn库的安装