python基于K-means聚类算法的图像分割
作者:iwuqing 发布时间:2021-03-30 02:29:05
标签:python,K-means,图像分割
1 K-means算法
实际上,无论是从算法思想,还是具体实现上,K-means算法是一种很简单的算法。它属于无监督分类,通过按照一定的方式度量样本之间的相似度,通过迭代更新聚类中心,当聚类中心不再移动或移动差值小于阈值时,则就样本分为不同的类别。
1.1 算法思路
随机选取聚类中心
根据当前聚类中心,利用选定的度量方式,分类所有样本点
计算当前每一类的样本点的均值,作为下一次迭代的聚类中心
计算下一次迭代的聚类中心与当前聚类中心的差距
如4中的差距小于给定迭代阈值时,迭代结束。反之,至2继续下一次迭代
1.2 度量方式
根据聚类中心,将所有样本点分为最相似的类别。这需要一个有效的盘踞,平方差是最常用的度量方式,如下
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 分类效果
聚类中心个数=3,迭代阈值为=1
聚类中心个数=3,迭代阈值为=1
4 GitHub
click me
来源:https://www.jianshu.com/p/11d7cde4944d
0
投稿
猜你喜欢
- 一、实现代码1.sql-- phpMyAdmin SQL Dump-- version 4.5.1-- http://www.phpmyad
- 我们都知道python的版本不同,在使用的时候就有所区别。鉴于我们推荐小伙伴们选择python3版本,所以这方面的区别了解的不是很多。就拿_
- 为了保证程序的健壮性与容错性,即在遇到错误时候程序不会崩溃,我们需要对异常进行处理,1.if进行处理,在错误发生之前进行预防如果错误发生的条
- 很早就在这里看到过解决方案,与嗷嗷讨论后发现这个方案还是很可靠的。当然,唯一的缺点就是每一个属性都要去Hack,但我在很多实践中,只用‘修正
- 在此之前,我一直都在研究JavaScript相关的反调试技巧。但是当我在网上搜索相关资料时,我发现网上并没有多少关于这方面的文章,而且就算有
- 上一篇的DOCTYPE声明好以后,接下来的代码是:<html xmlns="xhtml" ta
- 文章主要描述的是SQL Server数据库和Oracle数据库行转列的一种比较典型操作方法,对于有些业务来说,数据在表中的存储与其最终的Gr
- Python与Perl,C和Java语言等有许多相似之处。不过,也有语言之间有一些明确的区别。本章的目的是让你迅速学习Pytho
- #pd.to_datetime函数#读取数据import pandas as pddata = pd.read_csv('polic
- Player.playState0 Undefined Windows Media Player is in an undefined st
- 前言本项目是使用了谷歌开源的框架mediapipe,里面有非常多的模型提供给我们使用,例如面部检测,身体检测,手部检测等。原理首先先进行手部
- 决策树也是有监督机器学习方法。 电影《无耻混蛋》里有一
- 1、看机器配置,指三大件:cpu、内存、硬盘2、看mysql配置参数3、查系mysql行状态,可以用mysqlreport工具来查看4、查看
- bootstrap自带的响应式导航栏是向下滑动的,有时满足不了个性化的需求,需要做一个类似于android drawerLayout 侧滑的
- 最初开发的 Matplotlib,仅支持绘制 2d 图形,后来随着版本的不断更新, Matplotlib 在二维绘图的基础上,构建了一部分较
- 最近在学习PHP,以下是看PHP100视频教程,做的学习笔记,在这里存放以便今后使用。apache--PHP--DB(mysql)一、apa
- Tkinter是python的GUI模块,内含各种窗口控件,利用其中messagbox可以制作各种信息弹出窗口。以下是制作信息提示框的代码:
- 目标在本章中,将了解:如何生成OpenCV-Python bindings如何将新的OpenCV模块扩展到PythonOpenCV-Pyth
- 登录SYS创建临时表空间/*创建临时表空间 */create temporary tablespace 表空间名 t
- 一 描述561. 数组拆分 I - 力扣(LeetCode) (leetcode-cn.com)给定长度为 2n 的整数