170.图像分割之K均值聚类
2025-11-07 本文已影响0人
大龙10
- 区域分割之聚类方法
一、图像分割之K均值聚类
-
基于 k 均值聚类的区域分割
聚类方法的思想是将样本集合按照其特征的相似性划分为若干类别,使同一类别样本的特征具有较高的相似性,不同类别样本的特征具有较大的差异性。 -
基于聚类的区域分割,就是基于图像的灰度、颜色、纹理、形状等特征,用聚类算法把图像分成若干类别或区域,使每个点到聚类中心的均值最小。
-
k 均值(k-means)是一种无监督聚类算法。基于 k 均值聚类算法的区域分割,算法步骤为:
(1)首先从图像中选取 k 个点作为初始的聚类中心;
(2)对所有的像素点,计算像素到每个聚类中心的距离,将像素分类到距离最小的一个聚类中;
(3)根据分类结果计算出新的聚类中心;
(4)如此反复迭代直到聚类中心收敛到稳定值。
二、函数
- OpenCV 提供了函数 cv.kmeans 来实现 k-means 聚类算法。函数 cv.kmeans 不仅可以基于灰度、颜色对图像进行区域分割,也可以基于样本的其它特征如纹理、形状进行聚类。
cv.kmeans(data, K, bestLabels, criteria, attempts, flags[, centers]) → compactness, labels, centersdst
- 函数kmeans 实现 k-means 算法寻找聚类中心,并按聚类对输入样本进行分组。
参数说明:
- data:用于聚类的数据,N 维数组,类型为 CV_32F、CV_32FC2
- K:设定的聚类数量
- bestLabels:整数数组,分类标签,每个样本的所属聚类的序号
- criteria:元组 (type, max_iter, epsilon),算法结束标准,最大迭代次数或聚类中心位置精度
- cv2.TERM_CRITERIA_EPS:如果达到指定的精度 epsilon,则停止算法迭代
- cv2.TERM_CRITERIA_MAX_ITER:在指定的迭代次数max_iter之后停止算法
- cv2.TERM_CRITERIA_EPS + - cv.TERM_CRITERIA_MAX_ITER:当满足上述任何条件时停止迭代
- attempts:标志,指定使用不同聚类中心初值执行算法的次数
flags:像素邻域的尺寸,用于计算邻域的阈值,通常取 3,5,7- cv2. KMEANS_RANDOM_CENTERS:随机产生聚类中心的初值
- cv2. KMEANS_PP_CENTERS:Kmeans++ 中心初始化方法
- cv2. KMEANS_USE_INITIAL_LABELS:第一次计算时使用用户指定的聚类初值,之后的计算则使用随机的或半随机的聚类中心初值
- centers:聚类中心数组,每个聚类中心为一行,可选项
- labels:整数数组,分类标签,每个样本的所属聚类的序号
- centersdst:聚类中心数组
三、例程
- 11.27:图像分割之 k 均值聚类
import cv2
import numpy as np
from matplotlib import pyplot as plt
# 11.27 图像分割之 k 均值聚类
img = cv2.imread(r"E:/OpenCV/barbara.bmp", flags=1) # 读取彩色图像(BGR)
dataPixel = np.float32(img.reshape((-1, 3)))
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 200, 0.1) # 终止条件
flags = cv2.KMEANS_RANDOM_CENTERS # 起始的中心选择
K = 3 # 设置聚类数
_, labels, center = cv2.kmeans(dataPixel, K, None, criteria, 10, flags)
centerUint = np.uint8(center)
classify = centerUint[labels.flatten()] # 将像素标记为聚类中心颜色
imgKmean3 = classify.reshape((img.shape)) # 恢复为二维图像
K = 4 # 设置聚类数
_, labels, center = cv2.kmeans(dataPixel, K, None, criteria, 10, flags)
centerUint = np.uint8(center)
classify = centerUint[labels.flatten()] # 将像素标记为聚类中心颜色
imgKmean4 = classify.reshape((img.shape)) # 恢复为二维图像
K = 5 # 设置聚类数
_, labels, center = cv2.kmeans(dataPixel, K, None, criteria, 10, flags)
centerUint = np.uint8(center)
classify = centerUint[labels.flatten()] # 将像素标记为聚类中心颜色
imgKmean5 = classify.reshape((img.shape)) # 恢复为二维图像
plt.figure(figsize=(9, 7))
plt.subplot(221), plt.axis('off'), plt.title("Origin")
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) # 显示 img1(RGB)
plt.subplot(222), plt.axis('off'), plt.title("K-mean (k=3)")
plt.imshow(cv2.cvtColor(imgKmean3, cv2.COLOR_BGR2RGB))
plt.subplot(223), plt.axis('off'), plt.title("K-mean (k=4)")
plt.imshow(cv2.cvtColor(imgKmean4, cv2.COLOR_BGR2RGB))
plt.subplot(224), plt.axis('off'), plt.title("K-mean (k=5)")
plt.imshow(cv2.cvtColor(imgKmean5, cv2.COLOR_BGR2RGB))
plt.tight_layout()
plt.show()
四、资料
youcans_的博客:
https://blog.csdn.net/youcans/article/details/124550523
```