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 相关文章推荐
pygame 精灵的行走及二段跳的实现方法(必看篇)
Jul 10 Python
Python函数式编程
Jul 20 Python
Python使用flask框架操作sqlite3的两种方式
Jan 31 Python
Python编程深度学习绘图库之matplotlib
Dec 28 Python
Python中如何使用if语句处理列表实例代码
Feb 24 Python
Python实现带下标索引的遍历操作示例
May 30 Python
python爬虫增加访问量的方法
Aug 22 Python
Django框架 查询Extra功能实现解析
Sep 04 Python
Django REST framework 单元测试实例解析
Nov 07 Python
Pycharm Git 设置方法
Sep 15 Python
conda安装tensorflow和conda常用命令小结
Feb 20 Python
python批量创建变量并赋值操作
Jun 03 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 身份验证方面的函数
2009/10/11 PHP
Mysql中分页查询的两个解决方法比较
2013/05/02 PHP
thinkPHP5.0框架配置格式、加载解析与读取方法
2017/03/17 PHP
Gambit vs ForZe BO3 第二场 2.13
2021/03/10 DOTA
JS模拟Dialog弹出浮动框效果代码
2015/10/16 Javascript
jQuery mobile在页面加载时添加加载中效果 document.ready 和window.onload执行顺序比较
2016/07/14 Javascript
AngularJS国际化详解及示例代码
2016/08/18 Javascript
详解Vue.js动态绑定class
2016/12/20 Javascript
JavaScript实现大图轮播效果
2017/01/11 Javascript
JS 组件系列之Bootstrap Table的冻结列功能彻底解决高度问题
2017/06/30 Javascript
nodejs微信扫码支付功能实现
2018/02/17 NodeJs
vue源码学习之Object.defineProperty 对数组监听
2018/05/30 Javascript
微信小程序动态设置图片大小的方法
2019/11/21 Javascript
基于JavaScript实现简单抽奖功能代码实例
2020/10/20 Javascript
html+vue.js 实现漂亮分页功能可兼容IE
2020/11/07 Javascript
[52:10]LGD vs Optic Supermajor小组赛D组胜者组决赛 BO3 第二场 6.3
2018/06/04 DOTA
pygame学习笔记(4):声音控制
2015/04/15 Python
python实现解数独程序代码
2017/04/12 Python
Python编程使用NLTK进行自然语言处理详解
2017/11/16 Python
python类的方法属性与方法属性的动态绑定代码详解
2017/12/27 Python
利用python实现微信头像加红色数字功能
2018/03/26 Python
Python使用matplotlib绘制Logistic曲线操作示例
2019/11/28 Python
pycharm激活码有效到2020年11月底
2020/09/18 Python
使用python创建生成动态链接库dll的方法
2020/05/09 Python
Python列表的深复制和浅复制示例详解
2021/02/12 Python
python实现发送邮件
2021/03/02 Python
Bluebella法国官网:英国性感内衣品牌
2019/05/03 全球购物
抄作业检讨书
2014/02/17 职场文书
人事任命书范文
2014/06/04 职场文书
走进敬老院活动总结
2014/07/10 职场文书
父亲节寄语大全
2015/02/27 职场文书
九不准学习心得体会
2016/01/23 职场文书
2016年“9.22”世界无车日活动小结
2016/04/05 职场文书
2019年恭贺升学祝福语集锦
2019/08/15 职场文书
XX部保密工作制度范本
2019/08/27 职场文书
Python使用永中文档转换服务
2022/05/06 Python