个性化阅读
专注于IT技术分析

使用K均值聚类的图像压缩

先决条件:K均值聚类

互联网上以图像形式充满了大量数据。人们每天在社交媒体网站(如Instagram, Facebook)和云存储平台(如Google Drive等)上上传数百万张图片。由于海量数据, 图像压缩技术对于压缩图像和减少存储空间变得至关重要。

在本文中, 我们将研究使用无监督学习算法K-means聚类算法进行的图像压缩。

图像由称为像素的几个强度值组成。在彩色图像中, 每个像素为3个字节, 每个像素包含RGB(红-蓝-绿)值, 该值具有红色强度值, 然后是蓝色, 然后是绿色强度值。

方法:

K均值聚类会将相似的颜色归为不同颜色(RGB值)的” k”个聚类(例如k = 64)。因此, 每个簇质心代表其各自簇的RGB颜色空间中的颜色矢量。现在, 这些” k”簇质心将替换它们各自簇中的所有颜色矢量。因此, 我们只需要存储每个像素的标签, 就可以告诉该像素所属的集群。此外, 我们保留每个聚类中心的颜色向量的记录。

所需的库–

-> Numpy库:sudo pip3 install numpy。
-> Matplotlib库:sudo pip3 install matplotlib。
-> scipy库:sudo pip3 install scipy

以下是Python实现:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as img
# from scipy.io import loadmat
from scipy import misc
  
def read_image():
      
     # loading the png image as a 3d matrix 
     img = misc.imread( 'bird_small.png' ) 
  
     # uncomment the below code to view the loaded image
     # plt.imshow(A) # plotting the image
     # plt.show() 
      
     # scaling it so that the values are small
     img = img /255 
  
     return img
  
def initialize_means(img, clusters):
      
     # reshaping it or flattening it into a 2d matrix
     points = np.reshape(img, (img.shape[ 0 ] * img.shape[ 1 ], img.shape[ 2 ])) 
     m, n = points.shape
  
     # clusters is the number of clusters
     # or the number of colors that we choose.
      
     # means is the array of assumed means or centroids. 
     means = np.zeros((clusters, n)) 
  
     # random initialization of means. 
     for i in range (clusters):
         rand1 = int (np.random.random( 1 ) * 10 )
         rand2 = int (np.random.random( 1 ) * 8 )
         means[i, 0 ] = points[rand1, 0 ]
         means[i, 1 ] = points[rand2, 1 ]
  
     return points, means
  
  
# Function to measure the euclidean
# distance (distance formula)
def distance(x1, y1, x2, y2):
      
     dist = np.square(x1 - x2) + np.square(y1 - y2)
     dist = np.sqrt(dist)
  
     return dist
  
  
def k_means(points, means, clusters):
  
     iterations = 10 # the number of iterations 
     m, n = points.shape
      
     # these are the index values that
     # correspond to the cluster to
     # which each pixel belongs to.
     index = np.zeros(m) 
  
     # k-means algorithm.
     while (iterations> 0 ):
  
         for j in range ( len (points)):
              
             # initialize minimum value to a large value
             minv = 1000
             temp = None
              
             for k in range (clusters):
                  
                 x1 = points[j, 0 ]
                 y1 = points[j, 1 ]
                 x2 = means[k, 0 ]
                 y2 = means[k, 1 ]
                  
                 if (distance(x1, y1, x2, y2) <minv):         
                     minv = distance(x1, y1, x2, y2)
                     temp = k
                     index[j] = k 
          
         for k in range (clusters):
              
             sumx = 0
             sumy = 0
             count = 0
              
             for j in range ( len (points)):
                  
                 if (index[j] = = k):
                     sumx + = points[j, 0 ]
                     sumy + = points[j, 1 ] 
                     count + = 1
              
             if (count = = 0 ):
                 count = 1    
              
             means[k, 0 ] = float (sumx /count)
             means[k, 1 ] = float (sumy /count)     
              
         iterations - = 1
  
     return means, index
  
  
def compress_image(means, index, img):
  
     # recovering the compressed image by
     # assigning each pixel to its corresponding centroid.
     centroid = np.array(means)
     recovered = centroid[index.astype( int ), :]
      
     # getting back the 3d matrix (row, col, rgb(3))
     recovered = np.reshape(recovered, (img.shape[ 0 ], img.shape[ 1 ], img.shape[ 2 ]))
  
     # plotting the compressed image.
     plt.imshow(recovered)
     plt.show()
  
     # saving the compressed image.
     misc.imsave( 'compressed_' + str (clusters) +
                         '_colors.png' , recovered)
  
  
# Driver Code
if __name__ = = '__main__' :
  
     img = read_image()
  
     clusters = 16
     clusters = int ( input ( 'Enter the number of colors in the compressed image. default = 16\n' ))
  
     points, means = initialize_means(img, clusters)
     means, index = k_means(points, means, clusters)
     compress_image(means, index, img)

输入图片:

使用K均值聚类的图像压缩1

输出:

使用K均值聚类的图像压缩2

赞(0) 打赏
未经允许不得转载:srcmini » 使用K均值聚类的图像压缩
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!

 

觉得文章有用就打赏一下文章作者

微信扫一扫打赏