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

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

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

``````import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as img
from scipy import misc

# 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__' :

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)``````

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

#### 微信扫一扫打赏 • 回顶