利用K-means進行影象壓縮
阿新 • • 發佈:2019-01-01
前面幾篇文章 淺談支援向量機 神經網路——手寫數字識別 中涉及的演算法都屬於監督學習的範疇,今天小編給大家介紹一種屬於無監督學習範疇的演算法——K-means。
K-means是一種應用很廣泛的聚類演算法。聚類,通俗的講就是“人以群分物以類聚”。
K-means是怎麼實現聚類的呢?下面我們以一個簡單的樣例來闡述它的工作原理。
觀察上面的圖,我們一般會認為這些資料點集中分佈在三個區域,即這些資料點可以聚成三個族。K-means的工作過程是:首先隨機挑選三個點作為中心點,然後計算所有的資料點離哪個中心點最近,再根據離中心點近的點更新中心點,迴圈多次直到中心點不怎麼變化即可。
利用K-means聚類上面的資料,中心點更新過程如下。
好了,現在大致瞭解了K-means的作用和工作原理,下面就進入我們這次的主題——影象壓縮。
上圖是128*128的png影象,儲存格式是RGB,所以這副影象佔用的位數是128×128×24=393216。我們怎樣利用K-means演算法實現這副影象的壓縮呢?
我的想法是:這副影象存在許多很大一塊區域的顏色相近,既然相近,我們就用一種顏色替代一大塊區域中的各色。我們可以人為的用8、16、24、32種顏色表示整幅影象的顏色,也即說明聚類的個數為8、16、24、32。
具體的Python程式碼如下。
import matplotlib.pyplot as plt # plt 用於顯示圖片 import matplotlib.image as mpimg # mpimg 用於讀取圖片 from sklearn.cluster import KMeans import numpy as np pixel = mpimg.imread('bird_small.png') pixel = pixel.reshape((128*128 , 3)) kmeans = KMeans(n_clusters=16, random_state=0).fit(pixel) newPixel = [] for i in kmeans.labels_: newPixel.append(list(kmeans.cluster_centers_[i,:])) newPixel = np.array(newPixel) newPixel = newPixel.reshape((128,128,3)) plt.imshow(newPixel) plt.show()
如果用了16個類,則壓縮之後的影象佔用的位數為128×128×4 = 65536,壓縮比為16.7%。但這種壓縮是有失真壓縮,影象質量會下降,使用8、16、24、32壓縮後效果圖如下。
可以看到,影象的質量較原圖是有所下降的,有點類似在原圖上進行平滑處理,並且分類數越多,圖片質量越接近原圖,這個應該不難理解。
好了,以上就是本次的全部內容。