python基于K-means聚類算法的圖像分割
1 K-means算法
實(shí)際上,無論是從算法思想,還是具體實(shí)現(xiàn)上,K-means算法是一種很簡(jiǎn)單的算法。它屬于無監(jiān)督分類,通過按照一定的方式度量樣本之間的相似度,通過迭代更新聚類中心,當(dāng)聚類中心不再移動(dòng)或移動(dòng)差值小于閾值時(shí),則就樣本分為不同的類別。
1.1 算法思路
- 隨機(jī)選取聚類中心
- 根據(jù)當(dāng)前聚類中心,利用選定的度量方式,分類所有樣本點(diǎn)
- 計(jì)算當(dāng)前每一類的樣本點(diǎn)的均值,作為下一次迭代的聚類中心
- 計(jì)算下一次迭代的聚類中心與當(dāng)前聚類中心的差距
- 如4中的差距小于給定迭代閾值時(shí),迭代結(jié)束。反之,至2繼續(xù)下一次迭代
1.2 度量方式
根據(jù)聚類中心,將所有樣本點(diǎn)分為最相似的類別。這需要一個(gè)有效的盤踞,平方差是最常用的度量方式,如下

2 應(yīng)用于圖像分割
我們知道:無論是灰度圖還是RGB彩色圖,實(shí)際上都是存有灰度值的矩陣,所以,圖像的數(shù)據(jù)格式?jīng)Q定了在圖像分割方向上,使用K-means聚類算法是十分容易也十分具體的。
2.1 Code
導(dǎo)入必要的包
import numpy as np import random
損失函數(shù)
def loss_function(present_center, pre_center): ''' 損失函數(shù),計(jì)算上一次與當(dāng)前聚類中的差異(像素差的平方和) :param present_center: 當(dāng)前聚類中心 :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):
'''
分類器(通過當(dāng)前的聚類中心,給輸入圖像分類)
:param intput_signal: 輸入圖像
:param center: 聚類中心
:return: 標(biāo)簽矩陣
'''
input_row, input_col= intput_signal.shape # 輸入圖像的尺寸
pixls_labels = np.zeros((input_row, input_col)) # 儲(chǔ)存所有像素標(biāo)簽
pixl_distance_t = [] # 單個(gè)元素與所有聚類中心的距離,臨時(shí)用
for i in range(input_row):
for j in range(input_col):
# 計(jì)算每個(gè)像素與所有聚類中心的差平方
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,為下一個(gè)像素點(diǎn)做準(zhǔn)備
pixl_distance_t = []
return pixls_labels
基于k-means算法的圖像分割
def k_means(input_signal, center_num, threshold):
'''
基于k-means算法的圖像分割(適用于灰度圖)
:param input_signal: 輸入圖像
:param center_num: 聚類中心數(shù)目
:param threshold: 迭代閾值
:return:
'''
input_signal_cp = np.copy(input_signal) # 輸入信號(hào)的副本
input_row, input_col = input_signal_cp.shape # 輸入圖像的尺寸
pixls_labels = np.zeros((input_row, input_col)) # 儲(chǔ)存所有像素標(biāo)簽
# 隨機(jī)初始聚類中心行標(biāo)與列標(biāo)
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]
# 當(dāng)前的聚類中心
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 # 用于記錄迭代次數(shù)
while True:
pre_centet = present_center.copy() # 儲(chǔ)存前一次的聚類中心
# 計(jì)算當(dāng)前聚類中心
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])
# 根據(jù)當(dāng)前聚類中心分類
pixls_labels = classifer(input_signal_cp, present_center)
# 計(jì)算上一次聚類中心與當(dāng)前聚類中心的差異
loss = loss_function(present_center, pre_centet)
num = num + 1
print("Step:"+ str(num) + " Loss:" + str(loss))
# 當(dāng)損失小于迭代閾值時(shí),結(jié)束迭代
if loss <= threshold:
break
return pixls_labels
3 分類效果

聚類中心個(gè)數(shù)=3,迭代閾值為=1

聚類中心個(gè)數(shù)=3,迭代閾值為=1
4 GitHub
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Python使用樹狀圖實(shí)現(xiàn)可視化聚類詳解
- Python基于紋理背景和聚類算法實(shí)現(xiàn)圖像分割詳解
- python 層次聚類算法圖文示例
- Python K-means實(shí)現(xiàn)簡(jiǎn)單圖像聚類的示例代碼
- Python使用OpenCV和K-Means聚類對(duì)畢業(yè)照進(jìn)行圖像分割
- Python實(shí)現(xiàn)K-means聚類算法并可視化生成動(dòng)圖步驟詳解
- 在Python中使用K-Means聚類和PCA主成分分析進(jìn)行圖像壓縮
- python聚類算法解決方案(rest接口/mpp數(shù)據(jù)庫(kù)/json數(shù)據(jù)/下載圖片及數(shù)據(jù))
- 使用python實(shí)現(xiàn)3D聚類圖示例代碼
相關(guān)文章
Python調(diào)用工具包實(shí)現(xiàn)發(fā)送郵件服務(wù)
這篇文章主要為大家詳細(xì)介紹了Python圖畫調(diào)用工具包實(shí)現(xiàn)發(fā)送郵件服務(wù)的功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-05-05
詳解python的argpare和click模塊小結(jié)
這篇文章主要介紹了詳解python的argpare和click模塊小結(jié),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-03-03
Python線程池ThreadPoolExecutor使用方式
這篇文章主要介紹了Python線程池ThreadPoolExecutor使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-02-02
python面向?qū)ο髮?shí)現(xiàn)名片管理系統(tǒng)文件版
這篇文章主要為大家詳細(xì)介紹了python面向?qū)ο髮?shí)現(xiàn)名片管理系統(tǒng)文件版,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-04-04
Django實(shí)現(xiàn)帶進(jìn)度條的倒計(jì)時(shí)功能詳解
這篇文章主要為大家詳細(xì)介紹了如何利用Django實(shí)現(xiàn)簡(jiǎn)單的帶進(jìn)度條的倒計(jì)時(shí)功能,可以在頁(yè)面加載后自動(dòng)開始計(jì)時(shí),下次計(jì)時(shí)需要手動(dòng)刷新頁(yè)面,需要的可以參考一下2023-04-04
Python面向?qū)ο笾畠?nèi)置函數(shù)相關(guān)知識(shí)總結(jié)
本次要總結(jié)的的內(nèi)置函數(shù)共8個(gè),他們都跟面向?qū)ο蟮闹R(shí)相關(guān),文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下2021-06-06
使用python的pandas讀取excel文件中的數(shù)據(jù)詳情
這篇文章主要介紹了使用python的pandas讀取excel文件中的數(shù)據(jù)詳情,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-09-09
在python 中實(shí)現(xiàn)運(yùn)行多條shell命令
今天小編就為大家分享一篇在python 中實(shí)現(xiàn)運(yùn)行多條shell命令,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-01-01

