基于K-means聚類算法的圖像分割

1 K-means算法

實(shí)際上,無論是從算法思想棘伴,還是具體實(shí)現(xiàn)上寞埠,K-means算法是一種很簡(jiǎn)單的算法。它屬于無監(jiān)督分類焊夸,通過按照一定的方式度量樣本之間的相似度仁连,通過迭代更新聚類中心,當(dāng)聚類中心不再移動(dòng)或移動(dòng)差值小于閾值時(shí)阱穗,則就樣本分為不同的類別饭冬。

1.1 算法思路

  1. 隨機(jī)選取聚類中心
  2. 根據(jù)當(dāng)前聚類中心,利用選定的度量方式揪阶,分類所有樣本點(diǎn)
  3. 計(jì)算當(dāng)前每一類的樣本點(diǎn)的均值伍伤,作為下一次迭代的聚類中心
  4. 計(jì)算下一次迭代的聚類中心與當(dāng)前聚類中心的差距
  5. 如4中的差距小于給定迭代閾值時(shí),迭代結(jié)束遣钳。反之扰魂,至2繼續(xù)下一次迭代

1.2 度量方式

根據(jù)聚類中心,將所有樣本點(diǎn)分為最相似的類別蕴茴。這需要一個(gè)有效的盤踞劝评,平方差是最常用的度量方式,如下

c^{(i)} :=\min _{j}\left\|x^{(i)}-\mu_{j}\right\|^{2}

  • x^{(i)}為樣本點(diǎn)倦淀,i = 1,\dots, n蒋畜,共n個(gè)樣本點(diǎn)
  • c^{(i)}x^{(i)}最相似的類別,即x^{(i)}被分類至該類
  • \mu_{j}為聚類中心撞叽,j= 1,\dots, k姻成,共k個(gè)類別

2 應(yīng)用于圖像分割

我們知道:無論是灰度圖還是RGB彩色圖插龄,實(shí)際上都是存有0-255灰度值的矩陣,所以科展,圖像的數(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

click me

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末哨查,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子剧辐,更是在濱河造成了極大的恐慌寒亥,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,376評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件浙于,死亡現(xiàn)場(chǎng)離奇詭異护盈,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)羞酗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門腐宋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人檀轨,你說我怎么就攤上這事胸竞。” “怎么了参萄?”我有些...
    開封第一講書人閱讀 156,966評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵卫枝,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我讹挎,道長(zhǎng)校赤,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,432評(píng)論 1 283
  • 正文 為了忘掉前任筒溃,我火速辦了婚禮马篮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘怜奖。我一直安慰自己浑测,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,519評(píng)論 6 385
  • 文/花漫 我一把揭開白布歪玲。 她就那樣靜靜地躺著迁央,像睡著了一般掷匠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上岖圈,一...
    開封第一講書人閱讀 49,792評(píng)論 1 290
  • 那天讹语,我揣著相機(jī)與錄音,去河邊找鬼幅狮。 笑死募强,一個(gè)胖子當(dāng)著我的面吹牛株灸,可吹牛的內(nèi)容都是我干的崇摄。 我是一名探鬼主播,決...
    沈念sama閱讀 38,933評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼慌烧,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼逐抑!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起屹蚊,我...
    開封第一講書人閱讀 37,701評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤厕氨,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后汹粤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體命斧,經(jīng)...
    沈念sama閱讀 44,143評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,488評(píng)論 2 327
  • 正文 我和宋清朗相戀三年嘱兼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了国葬。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,626評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡芹壕,死狀恐怖汇四,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情踢涌,我是刑警寧澤通孽,帶...
    沈念sama閱讀 34,292評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站睁壁,受9級(jí)特大地震影響背苦,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜潘明,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,896評(píng)論 3 313
  • 文/蒙蒙 一行剂、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧钉疫,春花似錦硼讽、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽壤躲。三九已至,卻和暖如春备燃,著一層夾襖步出監(jiān)牢的瞬間碉克,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來泰國(guó)打工并齐, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留漏麦,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,324評(píng)論 2 360
  • 正文 我出身青樓况褪,卻偏偏與公主長(zhǎng)得像撕贞,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子测垛,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,494評(píng)論 2 348