Python圖像處理丨基於K-Means聚類的圖像區域分割

来源:https://www.cnblogs.com/huaweiyun/archive/2022/09/09/16673368.html
-Advertisement-
Play Games

摘要:本篇文章主要講解基於理論的圖像分割方法,通過K-Means聚類演算法實現圖像分割或顏色分層處理。 本文分享自華為雲社區《[Python圖像處理] 十九.圖像分割之基於K-Means聚類的區域分割》,作者: eastmount。 本篇文章主要講解基於理論的圖像分割方法,通過K-Means聚類演算法實 ...


摘要:本篇文章主要講解基於理論的圖像分割方法,通過K-Means聚類演算法實現圖像分割或顏色分層處理。

本文分享自華為雲社區《[Python圖像處理] 十九.圖像分割之基於K-Means聚類的區域分割》,作者: eastmount。

本篇文章主要講解基於理論的圖像分割方法,通過K-Means聚類演算法實現圖像分割或顏色分層處理。基礎性文章,希望對你有所幫助。

  • 一.K-Means原理
  • 二.K-Means聚類分割灰度圖像
  • 三.K-Means聚類對比分割彩色圖像

註意 :該部分知識均為楊秀璋查閱資料撰寫,未經授權禁止轉載,謝謝!!如果有問題隨時私聊我,只望您能從這個系列中學到知識,一起加油喔~

該系列在github所有源代碼:https://github.com/eastmountyxz/ImageProcessing-Python

一.K-Means聚類原理

第一部分知識主要參考自己的新書《Python網路數據爬取及分析從入門到精通(分析篇)》和之前的博客 [Python數據挖掘課程] 二.Kmeans聚類數據分析

K-Means聚類是最常用的聚類演算法,最初起源於信號處理,其目標是將數據點劃分為K個類簇,找到每個簇的中心並使其度量最小化。該演算法的最大優點是簡單、便於理解,運算速度較快,缺點是只能應用於連續型數據,並且要在聚類前指定聚集的類簇數。

下麵是K-Means聚類演算法的分析流程,步驟如下:

  • 第一步,確定K值,即將數據集聚集成K個類簇或小組。
  • 第二步,從數據集中隨機選擇K個數據點作為質心(Centroid)或數據中心。
  • 第三步,分別計算每個點到每個質心之間的距離,並將每個點劃分到離最近質心的小組,跟定了那個質心。
  • 第四步,當每個質心都聚集了一些點後,重新定義演算法選出新的質心。
  • 第五步,比較新的質心和老的質心,如果新質心和老質心之間的距離小於某一個閾值,則表示重新計算的質心位置變化不大,收斂穩定,則認為聚類已經達到了期望的結果,演算法終止。
  • 第六步,如果新的質心和老的質心變化很大,即距離大於閾值,則繼續迭代執行第三步到第五步,直到演算法終止。

下圖是對身高和體重進行聚類的演算法,將數據集的人群聚集成三類。

二.K-Means聚類分割灰度圖像

在圖像處理中,通過K-Means聚類演算法可以實現圖像分割、圖像聚類、圖像識別等操作,本小節主要用來進行圖像顏色分割。假設存在一張100×100像素的灰度圖像,它由10000個RGB灰度級組成,我們通過K-Means可以將這些像素點聚類成K個簇,然後使用每個簇內的質心點來替換簇內所有的像素點,這樣就能實現在不改變解析度的情況下量化壓縮圖像顏色,實現圖像顏色層級分割。

在OpenCV中,Kmeans()函數原型如下所示:

retval, bestLabels, centers = kmeans(data, K, bestLabels, criteria, attempts, flags[, centers])

  • data表示聚類數據,最好是np.flloat32類型的N維點集
  • K表示聚類類簇數
  • bestLabels表示輸出的整數數組,用於存儲每個樣本的聚類標簽索引
  • criteria表示演算法終止條件,即最大迭代次數或所需精度。在某些迭代中,一旦每個簇中心的移動小於criteria.epsilon,演算法就會停止
  • attempts表示重覆試驗kmeans演算法的次數,演算法返回產生最佳緊湊性的標簽
  • flags表示初始中心的選擇,兩種方法是cv2.KMEANS_PP_CENTERS ;和cv2.KMEANS_RANDOM_CENTERS
  • centers表示集群中心的輸出矩陣,每個集群中心為一行數據

下麵使用該方法對灰度圖像顏色進行分割處理,需要註意,在進行K-Means聚類操作之前,需要將RGB像素點轉換為一維的數組,再將各形式的顏色聚集在一起,形成最終的顏色分割。

# coding: utf-8
import cv2
import numpy as np
import matplotlib.pyplot as plt
#讀取原始圖像灰度顏色
img = cv2.imread('scenery.png', 0) 
print img.shape
#獲取圖像高度、寬度
rows, cols = img.shape[:]
#圖像二維像素轉換為一維
data = img.reshape((rows * cols, 1))
data = np.float32(data)
#定義中心 (type,max_iter,epsilon)
criteria = (cv2.TERM_CRITERIA_EPS +
            cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
#設置標簽
flags = cv2.KMEANS_RANDOM_CENTERS
#K-Means聚類 聚集成4類
compactness, labels, centers = cv2.kmeans(data, 4, None, criteria, 10, flags)
#生成最終圖像
dst = labels.reshape((img.shape[0], img.shape[1]))
#用來正常顯示中文標簽
plt.rcParams['font.sans-serif']=['SimHei']
#顯示圖像
titles = [u'原始圖像', u'聚類圖像'] 
images = [img, dst] 
for i in xrange(2): 
 plt.subplot(1,2,i+1), plt.imshow(images[i], 'gray'), 
 plt.title(titles[i]) 
 plt.xticks([]),plt.yticks([]) 
plt.show()

輸出結果如圖所示,左邊為灰度圖像,右邊為K-Means聚類後的圖像,它將灰度級聚集成四個層級,相似的顏色或區域聚集在一起。

三.K-Means聚類對比分割彩色圖像

下麵代碼是對彩色圖像進行顏色分割處理,它將彩色圖像聚集成2類、4類和64類。

# coding: utf-8
import cv2
import numpy as np
import matplotlib.pyplot as plt
#讀取原始圖像
img = cv2.imread('scenery.png') 
print img.shape
#圖像二維像素轉換為一維
data = img.reshape((-1,3))
data = np.float32(data)
#定義中心 (type,max_iter,epsilon)
criteria = (cv2.TERM_CRITERIA_EPS +
            cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
#設置標簽
flags = cv2.KMEANS_RANDOM_CENTERS
#K-Means聚類 聚集成2類
compactness, labels2, centers2 = cv2.kmeans(data, 2, None, criteria, 10, flags)
#K-Means聚類 聚集成4類
compactness, labels4, centers4 = cv2.kmeans(data, 4, None, criteria, 10, flags)
#K-Means聚類 聚集成8類
compactness, labels8, centers8 = cv2.kmeans(data, 8, None, criteria, 10, flags)
#K-Means聚類 聚集成16類
compactness, labels16, centers16 = cv2.kmeans(data, 16, None, criteria, 10, flags)
#K-Means聚類 聚集成64類
compactness, labels64, centers64 = cv2.kmeans(data, 64, None, criteria, 10, flags)
#圖像轉換回uint8二維類型
centers2 = np.uint8(centers2)
res = centers2[labels2.flatten()]
dst2 = res.reshape((img.shape))
centers4 = np.uint8(centers4)
res = centers4[labels4.flatten()]
dst4 = res.reshape((img.shape))
centers8 = np.uint8(centers8)
res = centers8[labels8.flatten()]
dst8 = res.reshape((img.shape))
centers16 = np.uint8(centers16)
res = centers16[labels16.flatten()]
dst16 = res.reshape((img.shape))
centers64 = np.uint8(centers64)
res = centers64[labels64.flatten()]
dst64 = res.reshape((img.shape))
#圖像轉換為RGB顯示
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
dst2 = cv2.cvtColor(dst2, cv2.COLOR_BGR2RGB)
dst4 = cv2.cvtColor(dst4, cv2.COLOR_BGR2RGB)
dst8 = cv2.cvtColor(dst8, cv2.COLOR_BGR2RGB)
dst16 = cv2.cvtColor(dst16, cv2.COLOR_BGR2RGB)
dst64 = cv2.cvtColor(dst64, cv2.COLOR_BGR2RGB)
#用來正常顯示中文標簽
plt.rcParams['font.sans-serif']=['SimHei']
#顯示圖像
titles = [u'原始圖像', u'聚類圖像 K=2', u'聚類圖像 K=4',
 u'聚類圖像 K=8', u'聚類圖像 K=16', u'聚類圖像 K=64'] 
images = [img, dst2, dst4, dst8, dst16, dst64] 
for i in xrange(6): 
 plt.subplot(2,3,i+1), plt.imshow(images[i], 'gray'), 
 plt.title(titles[i]) 
 plt.xticks([]),plt.yticks([]) 
plt.show()

輸出結果如下圖所示,當K=2顏色聚集成兩種,當K=64顏色聚集成64種。

 

點擊關註,第一時間瞭解華為雲新鮮技術~


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一個菜鳥的設計模式之旅,使用 Golang 實現。本節實現代理模式。小明很喜歡同班的雪怡,但是過於靦腆的他不敢當面說。打算通過手機(代理)跟雪怡表白! ...
  • 一個菜鳥的設計模式之旅,使用 Golang 實現。本節實現裝飾模式。小明和小王去吃沙縣小吃,各自喜歡不同的搭配,需要考慮每個人飲食喜好不同,隨時可能的變化。 ...
  • 2022-09-09 1、閉包的作用: 可以保存外部函數的變數 2、閉包的形成條件 (1)函數嵌套 (2)內部函數使用了外部函數的變數或者參數 (3)外部函數返回內部函數,這個使用了外部函數變數的內部函數稱為閉包 3、典例 1 # 函數嵌套 2 def func_out(): 3 # 外部函數 4 ...
  • 目錄 一.OpenGL 飽和度調節效果演示 1.IOS 飽和度演示效果 2.Windows OpenGL ES 飽和度演示效果 3.Windows OpenGL 飽和度演示效果 二.OpenGL 飽和度調節源碼下載 1.IOS Object-C 版本 2.Windows OpenGL ES 版本 3 ...
  • 一個菜鳥的設計模式之旅,使用 Golang 實現。本節實現解釋器模式。程式可按需載入用戶自定義的.work尾碼文件,將每行的命令解釋為具體行為。喵叫幾次、進程休眠幾秒、輸出範圍內隨機數、運行另外的work文件。 ...
  • #一、format的基本玩法 ##🚀🚀一、什麼是format format是字元串內嵌(字元串內嵌:字元串中再嵌套字元串,加入雙引號或單引號)的一個方法,用於格式化字元串。以大括弧{}來標明被替換的字元串 ##🚀🚀format玩法一:按順序輸出(按照{}的順序依次匹配括弧中的值) >>>s ...
  • IO流01 1.文件基礎知識 什麼是文件? 文件,我們並不陌生。文件是保存數據的地方。比如大家經常使用的word文檔,txt文件,excel文件等,都是文件。它既可以保存一張圖片,也可以保存聲音、視頻…… 文件流 文件在程式中是以流的形式來操作的: 流:數據在數據源(文件)和程式(記憶體)之間經歷的路 ...
  • 說明 意義 1.在Spring中,Bean的作用域可以通過scope屬性來指定。 2.指定作用域的目的是 存儲在此類單例bean的高速緩存中,並且對該命名bean的所有後續請求和引用都返回該高速緩存的對象。(本身的理念就是以空間換時間的思維,創建步驟繁雜,而且頻繁用到,我就存起來,下次用的時候就不用 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...