python實現使用聚類算法進行圖片壓縮

python實現使用聚類算法進行圖片壓縮

現在我們獲得了一張圖片flower.jpg,我們希望使用聚類算法對圖像進行壓縮,其思想是:其核心思想是通過聚類將顏色表示數量減少。例如,傳統RGB,每個通道0~255(8 bits),則可以表示16777216 (24 bits)種顏色,通過聚類可以減少到16種顏色。

代碼:

import numpy as np
from scipy import misc 
from sklearn import cluster
import matplotlib.pyplot as plt

###STEP1###
#compress_image函數實現圖片壓縮功能,compress_image函數將每個像素作爲一個元素進行聚類,以此減少其顏色個數。
#參數img是圖片傳入的接口,因此我們需要知道變量img的數據結構,請自行查看。 
def compress_image(img, num_clusters):
    #思考,聚類算法對輸入的數據結構要求如何?
    #問題一:補全代碼,將img結構進行轉換即每個像素作爲一個元素,使之能符合聚類算法數據輸入的要求。
    X = img.reshape((-1, 1))    #將原來的img文件的數據結構轉化爲單列格式。不知道img原來的數據結構可能是一個矩陣,我們將每一個像素點都轉化爲單列的格式。

    #print(X.shape)
    # 創建KMeans聚類模型,並訓練。
    kmeans = cluster.KMeans(n_clusters=num_clusters, n_init=4, random_state=5)
    kmeans.fit(X)
    
    #問題二:補全代碼,分別獲取每個數據聚類後的label,以及每個label的質心。
    centroids = kmeans.cluster_centers_.squeeze()  #把img文件新生成的數組將其數組形狀中的維度刪除 也就是將shape中爲1的刪除。
    labels = kmeans.labels_                        #那到新數據的質心,目的要替換原來像素點的質心
    
    #問題三:使用質心的數值代替原數據的label值,那麼我們將獲得一個新的圖像。 
    # 提示,使用numpy的choose函數進行進行質心值的代替,reshape函數回覆原圖片的數據結構,並返回結果。
    input_image_compressed = np.choose(labels, centroids).reshape(img.shape) 
    #使用choose函數將質心替換原來的數據。

    return input_image_compressed 

###STEP2###
#plot_image函數打印圖片
def plot_image(img, title):
    vmin = img.min()
    vmax = img.max()
    plt.figure()
    plt.title(title)
    plt.imshow(img, cmap=plt.cm.gray, vmin=vmin, vmax=vmax)


###STEP3###
#讀入圖片,設置壓縮率,實現壓縮
if __name__=='__main__':
    #設置圖片的路徑和壓縮比例
    input_file = "E:/flower/flower.jpg"
    num_bits = 2
    if not 1 <= num_bits <= 8:
        raise TypeError('Number of bits should be between 1 and 8')
    num_clusters = np.power(2, num_bits)
    # 輸出壓縮的比例
    compression_rate = round(100 * (8.0 - num_bits) / 8.0, 2)
    print ("\nThe size of the image will be reduced by a factor of", 8.0/num_bits)
    print ("\nCompression rate = " + str(compression_rate) + "%")
    # 加載需要壓縮的圖片
    input_image = misc.imread(input_file, True).astype(np.uint8)
    # 原始圖像的輸出
    plot_image(input_image, 'Original image')
    # 壓縮後的圖像輸出 
    input_image_compressed = compress_image(input_image, num_clusters)
    plot_image(input_image_compressed, 'Compressed image; compression rate = ' 
            + str(compression_rate) + '%')

    plt.show()

結果:

在這裏插入圖片描述
感謝閱讀!希望能對你有幫助,有問題可以私信我。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章