别催~ 在加载了 . . .

Kmeans_2


Kmeans_2

Question

利用Kmeans算法,对目标图片进行减色处理。

理论基础

即将色彩丰富的一张图片根据像素点的相似程度,换成仅有16种颜色的图片。这种操作可以在保留图片基本特征的同时大大减少内存的占用,视觉上打折扣,但是在使用上方便很多。我们通过matlab将jpg,png格式的图片先转为mat格式的图片矩阵。再将图片矩阵转换为一个像素点一行的数据矩阵。接着进行常规的Kmeans操作,同文章Kmeans_1中所示,然后将聚类完毕的数据矩阵还原为图片矩阵,并进行显示。

完整程序

本代码这次没有用jupyter进行编写运行,而是选择了pycharm(因为jupyter不知道什么情况卡住了,算个624×624的图片半天没反应,电脑风扇都没动静,无奈只能换成pycharm运行)。

注意,pycharm中plt.imshow()操作并不能直接显示图片,要在其操作后加上plt.show()。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import numpy as np
import scipy.io as sio
import matplotlib.pyplot as plt

data=sio.loadmat('Kmeans_2.mat')
data.keys()

A=data['test']
A.shape

A=A/255
plt.imshow(A)
plt.show()

A=A.reshape(-1,3)
A.shape

def find_centroids(X,centros):
idx=[]
for i in range(len(X)):
dist = np.linalg.norm((X[i]-centros),axis=1)
id_i=np.argmin(dist)
idx.append(id_i)
return np.array(idx)



def compute_centros(X,idx,k):
centros=[]
for i in range(k):
centros_i=np.mean(X[idx==i],axis=0)
centros.append(centros_i)
return np.array(centros)


def run_kmeans(X,centros,iters):
k=len(centros)
centros_all=[]
centros_all.append(centros)
centros_i=centros
for i in range(iters):
idx=find_centroids(X,centros_i)
centros_i=compute_centros(X,idx,k)
centros_all.append(centros_i)
return idx,np.array(centros_all)

def init_centros(X,k):
index=np.random.choice(len(X),k)
return X[index]

k=16
idx,centros_all=run_kmeans(A,init_centros(A,k=16),iters=20)
centros=centros_all[-1]
im=np.zeros(A.shape)
for i in range(k):
im[idx==i]=centros[i]
im=im.reshape(642,642,3)
print(im)
plt.imshow(im)
plt.show()

结果展示

减色前:

png

减色后:

可以看出来图片的基本特征得以保留,并且减色后图片去除了人物眼睛等部位的复杂颜色,统一换为了主题色:紫色。

png

Site

代码(Python)和所用数据:https://github.com/codeYu233/Study/tree/main/Kmeans_2

Note

该题与数据集均来源于Coursera上斯坦福大学的吴恩达老师机器学习的习题作业,学习交流用,如有不妥,立马删除


文章作者: codeYu233
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 codeYu233 !
评论
  目录