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 过滤字符串的技巧,map与itertools.imap
Sep 06 Python
python生成验证码图片代码分享
Jan 28 Python
Python常用算法学习基础教程
Apr 13 Python
浅谈python import引入不同路径下的模块
Jul 11 Python
对python .txt文件读取及数据处理方法总结
Apr 23 Python
python调用Matplotlib绘制分布点并且添加标签
May 31 Python
分享8点超级有用的Python编程建议(推荐)
Oct 13 Python
python连接PostgreSQL过程解析
Feb 09 Python
pytorch使用tensorboardX进行loss可视化实例
Feb 24 Python
python实现快递价格查询系统
Mar 03 Python
Python 操作 PostgreSQL 数据库示例【连接、增删改查等】
Apr 21 Python
Python3批量创建Crowd用户并分配组
May 20 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
浅析ThinkPHP中的pathinfo模式和URL重写
2014/01/06 PHP
ThinkPHP 表单自动验证运用示例
2014/10/13 PHP
动态改变textbox的宽高的js
2006/10/26 Javascript
javascript dom代码应用 简单的相册[firefox only]
2010/06/12 Javascript
Javascript中正则表达式的全局匹配模式分析
2011/04/26 Javascript
jQuery EasyUI API 中文文档 - NumberSpinner数值微调器使用介绍
2011/10/21 Javascript
js登录弹出层特效
2014/03/07 Javascript
js实现文本框选中的方法
2015/05/26 Javascript
JavaScript中的Math.LOG2E属性使用详解
2015/06/14 Javascript
在JavaScript中使用JSON数据
2016/02/15 Javascript
jquery轮播的实现方式 附完整实例
2016/07/28 Javascript
jQuery动态添加与删除tr行实例代码
2016/10/18 Javascript
JS正则表达式学习之贪婪和非贪婪模式实例总结
2016/12/26 Javascript
如何在 Vue.js 中使用第三方js库
2017/04/25 Javascript
微信小程序实现移动端滑动分页效果(ajax)
2017/06/13 Javascript
浅谈JS对html标签的属性的干预以及对CSS样式表属性的干预
2017/06/25 Javascript
浅谈箭头函数写法在ReactJs中的使用
2017/08/22 Javascript
jquery.picsign图片标注组件实例详解
2018/02/02 jQuery
elementUI中Table表格问题的解决方法
2018/12/04 Javascript
layui实现多图片上传并限制上传的图片数量
2019/09/26 Javascript
如何使用three.js 制作一个三维的推箱子游戏
2020/07/29 Javascript
[03:07]DOTA2英雄基础教程 冰霜诅咒极寒幽魂
2013/12/06 DOTA
[01:14:05]《加油DOTA》第四期
2014/08/25 DOTA
Python获取任意xml节点值的方法
2015/05/05 Python
Python的条件语句与运算符优先级详解
2015/10/13 Python
python+Django+apache的配置方法详解
2016/06/01 Python
python按综合、销量排序抓取100页的淘宝商品列表信息
2018/02/24 Python
Python使用googletrans报错的解决方法
2018/09/25 Python
Python 读取 YUV(NV12) 视频文件实例
2019/12/09 Python
Tensorflow不支持AVX2指令集的解决方法
2020/02/03 Python
财务专业大学生职业生涯规划范文
2013/12/30 职场文书
初中毕业典礼演讲稿
2014/09/09 职场文书
营运督导岗位职责
2015/04/10 职场文书
军训决心书范文
2015/09/22 职场文书
少先大队干部竞选稿
2015/11/20 职场文书
python实现简单聊天功能
2021/07/07 Python