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 元类使用说明
Dec 18 Python
Python SQLite3数据库操作类分享
Jun 10 Python
python采集博客中上传的QQ截图文件
Jul 18 Python
python根据文件大小打log日志
Oct 09 Python
Python下载指定页面上图片的方法
May 12 Python
Python3.5编程实现修改IIS WEB.CONFIG的方法示例
Aug 18 Python
python Flask实现restful api service
Dec 04 Python
对python中的xlsxwriter库简单分析
May 04 Python
tensorflow实现加载mnist数据集
Sep 08 Python
详解安装mitmproxy以及遇到的坑和简单用法
Jan 21 Python
Python代码块及缓存机制原理详解
Dec 13 Python
python基础详解之if循环语句
Apr 24 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
从零开始的异世界生活:第二季延期后,B站上架了第二部剧场版
2020/05/06 日漫
php 三维饼图的实现代码
2008/09/28 PHP
PHP原生函数一定好吗?
2014/12/08 PHP
php导出中文内容excel文件类实例
2015/07/06 PHP
thinkPHP5框架auth权限控制类与用法示例
2018/06/12 PHP
php + WebUploader实现图片批量上传功能
2019/05/06 PHP
jquery 指南/入门基础
2007/11/30 Javascript
javascript 正则替换 replace(regExp, function)用法
2010/05/22 Javascript
jQuery在vs2008及js文件中的无智能提示的解决方法
2010/12/30 Javascript
js为空或不是对象问题的快速解决方法
2013/12/11 Javascript
jquery实现炫酷的叠加层自动切换特效
2015/02/01 Javascript
jQuery插件Tooltipster实现漂亮的工具提示
2015/04/12 Javascript
JavaScript基于setTimeout实现计数的方法
2015/05/08 Javascript
js实现点击向下展开的下拉菜单效果代码
2015/09/01 Javascript
Bootstrap实现渐变顶部固定自适应导航栏
2020/08/27 Javascript
js实现4个方向滚动的球
2017/03/06 Javascript
关于axios返回空对象的问题解决
2017/04/04 Javascript
angularjs利用directive实现移动端自定义软键盘的示例
2017/09/20 Javascript
详解从零搭建 vue2 vue-router2 webpack3 工程
2017/11/22 Javascript
Angular6 正则表达式允许输入部分中文字符
2018/09/10 Javascript
vue 2.1.3 实时显示当前时间,每秒更新的方法
2018/09/16 Javascript
Jquery实现无缝向上循环滚动列表的特效
2019/02/13 jQuery
JavaScript JSON数据处理全集(小结)
2019/08/15 Javascript
将Django项目部署到CentOs服务器中
2018/10/18 Python
python3 反射的四种基本方法解析
2019/08/26 Python
Pycharm中出现ImportError:DLL load failed:找不到指定模块的解决方法
2019/09/17 Python
python线程信号量semaphore使用解析
2019/11/30 Python
python base64库给用户名或密码加密的流程
2020/01/02 Python
python 判断txt每行内容中是否包含子串并重新写入保存的实例
2020/03/12 Python
python 画条形图(柱状图)实例
2020/04/24 Python
Python爬虫之Selenium库的使用方法
2021/01/03 Python
HTML5超炫酷粒子效果的进度条的实现示例
2019/08/23 HTML / CSS
航海技术专业毕业生求职信
2014/04/06 职场文书
医学生自荐信范文
2015/03/05 职场文书
2016党员干部廉洁自律心得体会
2016/01/13 职场文书
详解如何用Python实现感知器算法
2021/06/18 Python