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


Posted in Python onOctober 30, 2019

1 K-means算法

实际上,无论是从算法思想,还是具体实现上,K-means算法是一种很简单的算法。它属于无监督分类,通过按照一定的方式度量样本之间的相似度,通过迭代更新聚类中心,当聚类中心不再移动或移动差值小于阈值时,则就样本分为不同的类别。

1.1 算法思路

  1. 随机选取聚类中心
  2. 根据当前聚类中心,利用选定的度量方式,分类所有样本点
  3. 计算当前每一类的样本点的均值,作为下一次迭代的聚类中心
  4. 计算下一次迭代的聚类中心与当前聚类中心的差距
  5. 如4中的差距小于给定迭代阈值时,迭代结束。反之,至2继续下一次迭代

1.2 度量方式

根据聚类中心,将所有样本点分为最相似的类别。这需要一个有效的盘踞,平方差是最常用的度量方式,如下

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

2 应用于图像分割

我们知道:无论是灰度图还是RGB彩色图,实际上都是存有灰度值的矩阵,所以,图像的数据格式决定了在图像分割方向上,使用K-means聚类算法是十分容易也十分具体的。

2.1 Code

导入必要的包

import numpy as np
import random

损失函数

def loss_function(present_center, pre_center):
  '''
  损失函数,计算上一次与当前聚类中的差异(像素差的平方和)
  :param present_center: 当前聚类中心
  :param pre_center: 上一次聚类中心
  :return: 损失值
  '''
  present_center = np.array(present_center)
  pre_center = np.array(pre_center)
  return np.sum((present_center - pre_center)**2)

分类器

def classifer(intput_signal, center):
  '''
  分类器(通过当前的聚类中心,给输入图像分类)
  :param intput_signal: 输入图像
  :param center: 聚类中心
  :return: 标签矩阵
  '''
  input_row, input_col= intput_signal.shape # 输入图像的尺寸

  pixls_labels = np.zeros((input_row, input_col)) # 储存所有像素标签

  pixl_distance_t = [] # 单个元素与所有聚类中心的距离,临时用

  for i in range(input_row):
    for j in range(input_col):
      # 计算每个像素与所有聚类中心的差平方
      for k in range(len(center)):
        distance_t = np.sum(abs((intput_signal[i, j]).astype(int) - center[k].astype(int))**2)
        pixl_distance_t.append(distance_t)
      # 差异最小则为该类
      pixls_labels[i, j] = int(pixl_distance_t.index(min(pixl_distance_t)))
      # 清空该list,为下一个像素点做准备
      pixl_distance_t = []
  return pixls_labels

基于k-means算法的图像分割

def k_means(input_signal, center_num, threshold):
  '''
  基于k-means算法的图像分割(适用于灰度图)
  :param input_signal: 输入图像
  :param center_num: 聚类中心数目
  :param threshold: 迭代阈值
  :return:
  '''
  input_signal_cp = np.copy(input_signal) # 输入信号的副本
  input_row, input_col = input_signal_cp.shape # 输入图像的尺寸
  pixls_labels = np.zeros((input_row, input_col)) # 储存所有像素标签

  # 随机初始聚类中心行标与列标
  initial_center_row_num = [i for i in range(input_row)]
  random.shuffle(initial_center_row_num)
  initial_center_row_num = initial_center_row_num[:center_num]

  initial_center_col_num = [i for i in range(input_col)]
  random.shuffle(initial_center_col_num)
  initial_center_col_num = initial_center_col_num[:center_num]

  # 当前的聚类中心
  present_center = []
  for i in range(center_num):
    present_center.append(input_signal_cp[initial_center_row_num[i], initial_center_row_num[i]])
  pixls_labels = classifer(input_signal_cp, present_center)

  num = 0 # 用于记录迭代次数
  while True:
    pre_centet = present_center.copy() # 储存前一次的聚类中心
    # 计算当前聚类中心
    for n in range(center_num):
      temp = np.where(pixls_labels == n)
      present_center[n] = sum(input_signal_cp[temp].astype(int)) / len(input_signal_cp[temp])
    # 根据当前聚类中心分类
    pixls_labels = classifer(input_signal_cp, present_center)
    # 计算上一次聚类中心与当前聚类中心的差异
    loss = loss_function(present_center, pre_centet)
    num = num + 1
    print("Step:"+ str(num) + "  Loss:" + str(loss))
    # 当损失小于迭代阈值时,结束迭代
    if loss <= threshold:
      break
  return pixls_labels

3 分类效果

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

聚类中心个数=3,迭代阈值为=1

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

聚类中心个数=3,迭代阈值为=1

4 GitHub

click me

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python实现的批量下载RFC文档
Mar 10 Python
在Python中使用Mako模版库的简单教程
Apr 08 Python
python中使用正则表达式的后向搜索肯定模式(推荐)
Nov 11 Python
Python实现求解括号匹配问题的方法
Apr 17 Python
python 中字典嵌套列表的方法
Jul 03 Python
python matplotlib实现双Y轴的实例
Feb 12 Python
matplotlib实现区域颜色填充
Mar 18 Python
python 使用递归实现打印一个数字的每一位示例
Feb 27 Python
python实现门限回归方式
Feb 29 Python
Python3 io文本及原始流I/O工具用法详解
Mar 23 Python
django restframework serializer 增加自定义字段操作
Jul 15 Python
PyTorch 导数应用的使用教程
Aug 31 Python
Python列表原理与用法详解【创建、元素增加、删除、访问、计数、切片、遍历等】
Oct 30 #Python
Python文件路径名的操作方法
Oct 30 #Python
Python元组 tuple的概念与基本操作详解【定义、创建、访问、计数、推导式等】
Oct 30 #Python
解决python 上传图片限制格式问题
Oct 30 #Python
Python字典的概念及常见应用实例详解
Oct 30 #Python
Python集合基本概念与相关操作实例分析
Oct 30 #Python
python opencv将表格图片按照表格框线分割和识别
Oct 30 #Python
You might like
php使用fputcsv()函数csv文件读写数据的方法
2015/01/06 PHP
PHP5多态性与动态绑定介绍
2015/04/03 PHP
Yii框架实现邮箱激活的方法【数字签名】
2016/10/18 PHP
tp5(thinkPHP5)操作mongoDB数据库的方法
2018/01/20 PHP
PHP框架Laravel中使用UUID实现数据分表操作示例
2018/05/30 PHP
PHP常用日期加减计算方法实例小结
2018/07/31 PHP
tp5.1 实现setInc字段自动加1
2019/10/18 PHP
php+layui数据表格实现数据分页渲染代码
2019/10/26 PHP
IE浏览器兼容Firefox的JS脚本的代码
2008/10/23 Javascript
让复选框只能选择一项的方法
2013/10/08 Javascript
js实现上传图片及时预览
2016/05/07 Javascript
jQuery网页定位导航特效实现方法
2016/12/19 Javascript
ajax前台后台跨域请求处理方式
2018/02/08 Javascript
React Native使用fetch实现图片上传的示例代码
2018/03/07 Javascript
vue实现的下拉框功能示例
2019/01/29 Javascript
vue实现按需加载组件及异步组件功能
2019/05/27 Javascript
使用JavaScript计算前一天和后一天的思路详解
2019/12/20 Javascript
vue实现员工信息录入功能
2020/06/11 Javascript
初学python的操作难点总结(新手必看篇)
2017/08/03 Python
对TensorFlow中的variables_to_restore函数详解
2018/07/30 Python
python队列Queue的详解
2019/05/10 Python
Pycharm及python安装详细教程(图解)
2020/07/31 Python
Python基于pyjnius库实现访问java类
2020/07/31 Python
Python -m参数原理及使用方法解析
2020/08/21 Python
pytorch 把图片数据转化成tensor的操作
2021/03/04 Python
用html5的canvas画布绘制贝塞尔曲线完整代码
2013/08/14 HTML / CSS
贝玲妃英国官网:Benefit英国
2018/02/03 全球购物
介绍一下grep命令的使用
2012/06/28 面试题
幼儿园实习生辞职信
2014/01/20 职场文书
运动会稿件200字
2014/02/07 职场文书
四风问题个人对照检查剖析材料
2014/09/27 职场文书
学校机关党总支领导班子整改工作方案
2014/10/26 职场文书
男人帮观后感
2015/06/18 职场文书
python 闭包函数详细介绍
2022/04/19 Python
MySQL自定义函数及触发器
2022/08/05 MySQL
JDK8中String的intern()方法实例详细解读
2022/09/23 Java/Android