【阿旭機器學習實戰】系列文章主要介紹機器學習的各種算法模型及其實戰案例,歡迎點贊,關注共同學習交流。
本文使用無監督學習算法K-means聚類算法通過對圖片顏色點進行聚類的方式,達到降低圖片存儲空間的目的
。
對于KMeans聚類算法原理的介紹,請參考之前的博文
《【阿旭機器學習實戰】【16】KMeans算法介紹及實戰:利用KMeans進行足球隊分類》
目錄
前言
在如今的互聯網時代,網絡上充滿了海量的數據,當然也包括很多圖片。因此圖像壓縮技術對于壓縮圖像和減少存儲空間變得至關重要。
本文我們將使用無監督學習算法K-means聚類算法通過對圖片顏色點進行聚類的方式,達到降低圖片存儲空間的目的
。
圖像由稱為像素的幾個強度值組成。在彩色圖像中, 每個像素為3個字節, 每個像素包含RGB(紅-藍-綠)值, 該值具有紅色強度值, 然后是藍色, 然后是綠色強度值。
具體方法如下:
使用K均值聚類算法將圖片相似的顏色歸為不同的” k”個聚類(例如k = 64),每個簇質心(RGB值)代表其各自簇的RGB顏色空間中的顏色矢量。
根據Kmeans算法找出圖片上每個像素點對應的簇質心(RGB值)的標號值。
圖片存儲時,我們只需存儲每個像素的標簽編號, 并保留每個聚類中心的顏色向量的記錄,根據編號及這個聚類中心顏色向量就可以告訴該像素所屬的集群,即RGB值。
由上述存儲方式可以看出,圖片單個像素點的存儲由RGB的3個字節,變為了只需存儲一個標簽編號的數字。存儲空間只需原來的30%左右。
1. 加載圖片及特征處理
from sklearn import datasets
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
# 加載圖片
china = datasets.load_sample_image("china.jpg")
plt.imshow(china)
在這里插入圖片描述
china.dtype
dtype('uint8')
china.shape
(427, 640, 3)
# 除以255,將像素點的值變為0-1之間
china = china/255
h,w,d = china.shape
# 把像素點展開
img_array = china.reshape((h*w,d))
img_array.shape
(273280, 3)
# 把像素點隨機打亂
from sklearn.utils import shuffle
img_array_shuffle = shuffle(img_array,random_state=0)
plt.imshow(img_array_shuffle.reshape((h,w,d)))
在這里插入圖片描述
2. 進行KMeans聚類建模
from sklearn.cluster import KMeans
# 用64個聚類來劃分這些像素點
km = KMeans(n_clusters=64,random_state=0)
# 僅用前1000個像素點進行模型訓練
km.fit(img_array_shuffle[:1000])
KMeans(algorithm='auto', copy_x=True, init='k-means++', max_iter=300,
n_clusters=64, n_init=10, n_jobs=1, precompute_distances='auto',
random_state=0, tol=0.0001, verbose=0)
# 表示這1000個樣本對應的聚類標簽,展示前100個標簽編號
km.labels_[:100]
array([22, 36, 8, 56, 38, 42, 22, 31, 7, 2, 55, 31, 62, 21, 52, 43, 31,
18, 2, 4, 31, 56, 21, 2, 15, 5, 6, 49, 57, 13, 5, 21, 21, 3,
21, 47, 21, 2, 47, 32, 5, 42, 5, 33, 45, 56, 5, 57, 2, 38, 47,
6, 50, 50, 27, 62, 56, 57, 30, 28, 6, 5, 26, 24, 58, 44, 8, 21,
58, 60, 10, 56, 31, 10, 41, 5, 62, 41, 22, 6, 38, 25, 57, 36, 28,
21, 49, 2, 21, 48, 14, 15, 57, 22, 47, 63, 47, 2, 41, 34])
# # 用聚類中心點的顏色來代表這個聚類的顏色,展示前10個聚類中心
km.cluster_centers_[:10]
array([[0.62570806, 0.60261438, 0.53028322],
[0.15546218, 0.1557423 , 0.12829132],
[0.82063983, 0.89896801, 0.98462332],
[0.42039216, 0.43843137, 0.2227451 ],
[0.69527105, 0.74994233, 0.76516724],
[0.92174422, 0.9556336 , 0.99514194],
[0.07058824, 0.0754637 , 0.0508744 ],
[0.28205128, 0.26395173, 0.19638009],
[0.46509804, 0.43372549, 0.36901961],
[0.71328976, 0.41960784, 0.31851852]])
3. 使用算法對原始圖片進行聚類
# 用km模型去對原圖進行聚類
labels = km.predict(img_array)
創建一個函數用于重新合成圖片
def recreate_img(centers,labels,h,w):
# 行數的作用是將每個像素點的值,用對應編號的聚類中心代替
# 按照h和w創建一個空白圖片
img = np.zeros((h,w,3))
# 通過for循環,遍歷img中每一個點,并且從labels中取出下標對應的聚類重新給img賦值
label_index = 0
for i in range(h):
for j in range(w):
img[i][j] = centers[labels[label_index]]
label_index += 1
return img
img_re = recreate_img(km.cluster_centers_, labels, h, w)
4. 展示原始圖片與使用64個聚類中心聚類后的圖片
plt.figure(figsize=(12,6))
axes1 = plt.subplot(121)
axes1.imshow(china)
axes1.set_title("Instaces")
axes2 = plt.subplot(122)
axes2.imshow(img_re)
axes2.set_title("64 colors,K-Means")
Text(0.5,1,'64 colors,K-Means')
在這里插入圖片描述
5. 圖片存儲方式
- 存儲上面的圖片每個像素點對應的
聚類編號:labels,
形狀為:(273280,) - 存儲每個聚類編號對應
聚類中心RGB值:km.cluster_centers_
。形狀為:(64, 3)
依據以上labels與km.cluster_centers_,我們即可還原出聚類之后的圖片。相對于原始數據存儲量降低了60%以上。
如果內容對你有幫助,感謝點贊+關注哦!
更多干貨內容持續更新中…