Python:K-means的图像分割

作者: 大龙10 | 来源:发表于2023-12-04 06:30 被阅读0次

一、十大经典算法

  • 1、K-means K均值(无监督算法,聚类算法,随机算法)
  • 2、KNN(K Nearest Neighbor) K近邻(有监督算法,分类算法)
  • 3、逻辑回归(分类算法)
  • 4、决策树(有监督算法,概率算法)
  • 5、随机森林(集成算法中最简单的,模型融合算法)
  • 6、朴素贝叶斯
  • 7、EM算法
  • 8、Adaboost(集成算法之一)
  • 9、SVM
  • 10、马尔可夫

二、“ K”和“means”

  • K:有k个质心(簇)。
  • means:质心是一个簇所有点的均值。
  • K-means属于硬聚类。
    硬聚类指数据只能属于一个簇,
    与软聚类:数据可以不同程度的属于多个类相反。

三、算法步骤

  • S1:选取初始质心:
    从样本点中随机抽取K个点作为质心。
  • S2:所有样本点归类:
    计算所有样本点到K个质心的距离,将其划分到与其距离最近的簇中心所在簇。
  • S3:重新确定质心:
    新质心 = 簇内所有点的均值。
  • S4:循环更新:
    重复步骤S2,S3,直到质心不再变化。

四、流程图

五、程序

import cv2
import numpy as np
img = cv2.imread('d:\\OpenCVpic\\Happyfish.jpg')
row = img.shape[0]
col = img.shape[1]
cv2.imshow("img",img)
 
def knn(data, iter, k):
    data = data.reshape(-1, 3)  # 使二维空间,变成一维空间,避免后面计算距离时使用双层循环, 这样每一行代表不同空间的像素
    data = np.column_stack((data, np.ones(row*col)))   # 加一列
    # 1.随机产生选择k个像素作为初始簇心
    cluster_center = data[np.random.choice(row*col, k)]  
    # 2.分类
    distance = [[] for i in range(k)]
    for i in range(iter):
        print("迭代次数:", i)
        # 2.1距离计算
        for j in range(k):
            distance[j] = np.sqrt(np.sum((data - cluster_center[j])**2, axis=1))
        # 2.2归类
        data[:, 3] = np.argmin(distance, axis=0)
        # 3.计算新簇心
        for j in range(k):
            cluster_center[j] = np.mean(data[data[:, 3] == j], axis=0)
    return data[:, 3]
 
 if __name__ == "__main__":
    image_show = knn(img, 100, 2)
    image_show = image_show.reshape(row, col)
    cv2.imshow("result",image_show)
    cv2.waitKey()
    cv2.destroyAllWindows()
运行结果

六、代码解释

1、 reshape(-1,3)

  • reshape:
    在不改变元素值的情况下,改变一个数组的形状(行数和列数)。
  • 参数值-1
    表示可以“根据需要填充元素”,reshape(-1,3)意味着行数为3,列数根据需要填充。
  • img = img.reshape(-1,3)
    使二维空间,变成一维空间(降维),避免后面计算距离时使用双层循环, 这样每一行代表不同空间的像素。

2、imread

  • 把图片的信息提取到数组中(将图片转化为数组)。
  • 假设图片分辨率=mn,宽
    如果是灰度图,返回(n, m)形状2维数组。
    如果是RGB图像,返回(n, m, 3)形状的三维数组。
  • 例子
    img = cv2.imread('d:\OpenCVpic\Happyfish.jpg')
    row = img.shape[0]
    col = img.shape[1]
    print( row,col,img[10,30])
    数据输出
    可以看出img[10,30] 坐标点处的RGB值=[ 209,207,243]

3、数组形状

  • (1)三维:
    从图片提取的数组是三维,可以由imshow()正常显示。
  • (2)二维:
    图像分割的结果是二维数组,数组每个元素对应一个像素点的种类。
    如果图像有3种簇,那么二维数组的取值是[0, 1, 2],代表归属不同的种类。

4、随机产生簇心

  • 1)二维数组索引
    一般情况下,对于二维数组,用1个或者1对数字分别索引数组某行或者某个元素。
    也可以用向量进行索引,得到的是指定行构成的数组。
    例子:
import numpy as np
x = np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]])
print( x[0] ) #[1, 2]
print( x[0,0,] ) # 1
print( x[[0, 1, 2]] ) #[[1, 2], [3, 4], [5, 6]]
    1. 随机产生k个簇心
      先从[0, row * col-1]中随机产生长度为k的向量,再在data中索引该向量,得到k个随机点
      distance = np.sqrt(np.sum((x - y) * * 2, axis=1))
      作为簇心。

5、同列不同行的数组可以进行加减法。

计算图片RGB数组和一个簇心距离,二者形状分别为:[n, 3]和[1, 3]。

import numpy as np
x = np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]])
y = np.array([1, 2])
print(x-y)

输出是: [ [0,0],[2,2],[4,4],[6,6],[8,8] ]

6、归类

  • 将三维数组另起一列,放像素点的归类信息。属于第k个簇,归类信息就存储为k。
    最终K-means返回的结果:每个像素点对应的信息只有它属于哪个类,取值范围为[0, k-1]。
data[:, 3] = np.argmin(distance, axis=0)

np.argmin:返回一行/列中最小元素的索引。

7、计算新簇心

簇心 = 簇内所有点的平均值,簇心并不一定是实际存在的像素点的RGB取值。

for j in range(k): # k为簇的个数
    cluster.center[j] = np.mean(data[data[:, 3] == j], axis=0)

其中,data[data[:, 3] == j]:返回全部有指定元素的行。

七、资料

1、「Mr.Q」的博客:机器学习十大经典算法之K-means 
https://blog.csdn.net/jizhidexiaoming/article/details/89214614
2、「毕业回老家」的博客:基于K-means的图像分割
https://blog.csdn.net/marujie123/article/details/125721608
3、「毕业回老家」的博客:基于模糊C均值聚类(FCM)的图像分割原理
https://blog.csdn.net/marujie123/article/details/125722953

相关文章

  • Apriori、ID3、Naive_Bayes等(数据挖掘)

    Apriori算法 线性回归 UCI分类KNN 决策树 Naive_Bayes K-Means图像分割 Aprio...

  • 利用K-Means进行图像分割

    使用K—Means进行图像分割 一、需要用到的库: sklearn.cluster中的kmeans、PIL中的im...

  • 图像分割

    图像分割 什么是图像分割? 图像分割就是预测图像中每一个像素所属的类别或者物体。图像分割有两个子问题,一个是只预测...

  • OpenCV+Python图像分割

    分水岭算法 用于分割多个相邻的物体。 原理 灰度图像根据灰度值可以把像素之间的关系看成山峰和山谷的关系,高亮度(灰...

  • OpenCV Python 图像 阈值分割

    src 源图像 参考资料:https://study.163.com/course/courseLearn.htm...

  • 基于K-means聚类算法的图像分割

    1 K-means算法 实际上,无论是从算法思想,还是具体实现上,K-means算法是一种很简单的算法。它属于无监...

  • 图像分割算法总结

    图像处理的很多任务都离不开图像分割。因为图像分割在cv中实在太重要(有用)了,就先把图像分割的常用算法做个总...

  • 我所了解的图像分割

    图像分割是我大二2019年做的东西,这篇文章用来总结。 一、什么是图像分割 分语义【像素级别图像】,实例【分割物体...

  • 基于caffe的FCN图像分割(一)

    前言 在计算视觉领域,除了图像分类,目标检测,目标跟踪之外,图像分割也是研究的热点之一。 图像分割的常用医学图像,...

  • 图像分割笔记(冈萨雷斯-数字图像处理)

    第10章 图像分割 ​分割将一幅图像细分为其组成区域或对象。(针对不同问题有不同的细分需求) ​单色图像分割算法通...

网友评论

    本文标题:Python:K-means的图像分割

    本文链接:https://www.haomeiwen.com/subject/mcmcgdtx.html