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 相关文章推荐
使用cx_freeze把python打包exe示例
Jan 24 Python
编写Python的web框架中的Model的教程
Apr 29 Python
Python3字符串学习教程
Aug 20 Python
pycharm debug功能实现跳到循环末尾的方法
Nov 29 Python
pytorch 转换矩阵的维数位置方法
Dec 08 Python
详解Python字典的操作
Mar 04 Python
详解Python 4.0 预计推出的新功能
Jul 26 Python
如何解决django-celery启动后迅速关闭
Oct 16 Python
python数字类型math库原理解析
Mar 02 Python
详解基于Jupyter notebooks采用sklearn库实现多元回归方程编程
Mar 25 Python
python两种获取剪贴板内容的方法
Nov 06 Python
去除python中的字符串空格的简单方法
Dec 22 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静态文件返回304技巧分享
2015/01/06 PHP
Laravel 5 学习笔记
2015/03/06 PHP
php将数组转换成csv格式文件输出的方法
2015/03/14 PHP
js自动生成的元素与页面原有元素发生堆叠的解决方法
2013/10/24 Javascript
jQuery中slideUp()方法用法分析
2014/12/24 Javascript
js用拖动滑块来控制图片大小的方法
2015/02/27 Javascript
js对字符串进行编码的方法总结(推荐)
2016/11/10 Javascript
ECMAScript6 新特性范例大全
2017/03/24 Javascript
使用node.js搭建服务器
2017/05/20 Javascript
AngularJS表单验证功能分析
2017/05/26 Javascript
layui select动态添加option的实例
2018/03/07 Javascript
微信小程序中添加客服按钮contact-button功能
2018/04/27 Javascript
Nodejs调用Dll模块的方法
2018/09/17 NodeJs
浅析JS中什么是自定义react数据验证组件
2018/10/19 Javascript
支付宝小程序自定义弹窗dialog插件的实现代码
2018/11/30 Javascript
详解可以用在VS Code中的正则表达式小技巧
2019/05/14 Javascript
JS数组扁平化(flat)方法总结详解
2019/06/24 Javascript
解决React在安装antd之后出现的Can't resolve './locale'问题(推荐)
2020/05/03 Javascript
VueX模块的具体使用(小白教程)
2020/06/05 Javascript
vue 在服务器端直接修改请求的接口地址
2020/12/19 Vue.js
Python操作json数据的一个简单例子
2014/04/17 Python
python实现上传样本到virustotal并查询扫描信息的方法
2014/10/05 Python
python中尾递归用法实例详解
2015/04/28 Python
Python轻量级ORM框架Peewee访问sqlite数据库的方法详解
2017/07/20 Python
Python入门之三角函数sin()函数实例详解
2017/11/08 Python
pycharm全局搜索的具体步骤
2020/07/28 Python
购买澳大利亚最好的服装和内衣在线:BONDS
2016/10/14 全球购物
世界上最好的威士忌和烈性酒购买网站:The Whisky Exchange
2016/11/20 全球购物
计算s=f(f(-1.4))的值
2014/05/06 面试题
个人简历自我评价八例
2013/10/31 职场文书
超市中秋节活动方案
2014/02/12 职场文书
供货协议书
2014/04/22 职场文书
初中教师个人工作总结
2015/02/10 职场文书
计算机专业自荐信
2015/03/05 职场文书
2015年学校德育工作总结
2015/04/22 职场文书
认识实习感想
2015/08/10 职场文书