【youcans 的 OpenCV 例程200篇】170.图像分割之K均值聚类

【OpenCV 例程200篇】 系列,持续更新中…
【OpenCV 例程200篇 总目录-202205更新】


【youcans 的 OpenCV 例程200篇】170.图像分割之K均值聚类


5. 区域分割之聚类方法

5.1 基于 k 均值聚类的区域分割

聚类方法的思想是将样本集合按照其特征的相似性划分为若干类别,使同一类别样本的特征具有较高的相似性,不同类别样本的特征具有较大的差异性。

基于聚类的区域分割,就是基于图像的灰度、颜色、纹理、形状等特征,用聚类算法把图像分成若干类别或区域,使每个点到聚类中心的均值最小。
a r g min ⁡ C ( ∑ i = 1 k ∑ z ∈ C i ∥ z − m i ∥ 2 ) arg \min_{C} \Big( \sum^k_{i=1} \sum_{z \in C_i} \lVert z - m_i \rVert ^2 \Big) argCmin(i=1kzCizmi2)
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

函数 cv.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 均值聚类

    # 11.27 图像分割之 k 均值聚类
    img = cv2.imread("../images/imgB6.jpg", 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@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/124550523)

Copyright 2022 youcans, XUPT
Crated:2022-4-30


欢迎关注 『youcans 的 OpenCV 例程 200 篇』 系列,持续更新中
欢迎关注 『youcans 的 OpenCV学习课』 系列,持续更新中

【youcans 的 OpenCV 例程200篇】168.图像分割之区域生长
【youcans 的 OpenCV 例程200篇】169.图像分割之区域分离
【youcans 的 OpenCV 例程200篇】170.图像分割之K均值聚类
更多内容,请见:
【OpenCV 例程200篇 总目录-202206更新】

你可能感兴趣的:(聚类,opencv,均值算法,图像处理,python)