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全局变量操作详解
Apr 14 Python
Python实现新浪博客备份的方法
Apr 27 Python
Python之reload流程实例代码解析
Jan 29 Python
Python管理Windows服务小脚本
Mar 12 Python
python3如何将docx转换成pdf文件
Mar 23 Python
Python 实现取矩阵的部分列,保存为一个新的矩阵方法
Nov 14 Python
Python中的集合介绍
Jan 28 Python
django的settings中设置中文支持的实现
Apr 28 Python
解决tensorboard多个events文件显示紊乱的问题
Feb 15 Python
Django ForeignKey与数据库的FOREIGN KEY约束详解
May 20 Python
PyQt QMainWindow的使用示例
Mar 24 Python
Python 使用 Frame tkraise() 方法在 Tkinter 应用程序中的Frame之间切换
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
php入门学习知识点七 PHP函数的基本应用
2011/07/14 PHP
ThinkPHP5.0框架验证码功能实现方法【基于第三方扩展包】
2019/03/11 PHP
PHP反射实际应用示例
2019/04/03 PHP
几个比较实用的JavaScript 测试及效验工具
2010/04/18 Javascript
javascript学习笔记(八) js内置对象
2012/06/19 Javascript
js设置组合快捷键/tabindex功能的方法
2013/11/21 Javascript
jQuery中prepend()方法用法实例
2014/12/25 Javascript
JS实现向表格中动态添加行的方法
2015/03/30 Javascript
javascript弹出拖动窗口
2015/08/11 Javascript
node.js Sequelize实现单实例字段或批量自增、自减
2016/12/08 Javascript
javascript帧动画(实例讲解)
2017/09/02 Javascript
使用JS中的Replace()方法遇到的问题小结
2017/10/20 Javascript
详解Koa中更方便简单发送响应的方式
2018/07/20 Javascript
vue将毫秒数转化为正常日期格式的实例
2018/09/16 Javascript
利用vue重构有赞商城的思路以及总结整理
2019/02/21 Javascript
vue两组件间值传递 $router.push实现方法
2019/05/15 Javascript
JS数组Object.keys()方法的使用示例
2019/06/05 Javascript
微信小程序图片左右摆动效果详解
2019/07/13 Javascript
vue $set 给数据赋值的实例
2019/11/09 Javascript
python编程-将Python程序转化为可执行程序[整理]
2007/04/09 Python
Python Tkinter简单布局实例教程
2014/09/03 Python
解决tensorflow测试模型时NotFoundError错误的问题
2018/07/26 Python
Python逐行读取文件中内容的简单方法
2019/02/26 Python
Django结合ajax进行页面实时更新的例子
2019/08/12 Python
Python中 CSV格式清洗与转换的实例代码
2019/08/29 Python
Python3 filecmp模块测试比较文件原理解析
2020/03/23 Python
html5清空画布方法(三种)
2017/10/16 HTML / CSS
文秘求职信范文
2014/04/10 职场文书
2014年重阳节活动策划方案书
2014/09/16 职场文书
家庭贫困证明
2014/09/23 职场文书
2015年大学辅导员工作总结
2015/05/12 职场文书
2015年英语教师工作总结
2015/05/20 职场文书
幼儿园托班开学寄语(2015秋季)
2015/05/27 职场文书
高一作文之暖冬
2019/11/09 职场文书
MySQL infobright的安装步骤
2021/04/07 MySQL
全新239军机修复记
2022/04/05 无线电