kmeans聚类图像的像素并可视化
程序员文章站
2024-02-13 19:50:58
...
kmeans聚类图像的像素并可视化
1. 题目要求
给定的图像,对其像素进行聚类并可视化。
2. 代码实现
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
import numpy as np
# from sklearn.cluster.KMeans import evaluate_clustering
import PIL.Image as image
import os
def loadData(filePath):
with open(filePath, 'rb') as f:
# f = open(filePath, 'rb') # deal with binary
data = []
img = image.open(f) # return to pixel(像素值)
m, n = img.size # the size of image
for i in range(m):
for j in range(n):
x, y, z = img.getpixel((i, j))
# deal with pixel to the range 0-1 and save to data
data.append([x / 256.0, y / 256.0, z / 256.0])
# f.close()
return np.mat(data), m, n
def main():
imgData, row, col = loadData(r"D:\work\python\Horse100\0075.jpg")
# setting clusers(聚类中心)
#print("imgData.shape=",imgData.shape)
img = image.open((r'D:\work\python\Horse100\0075.jpg'))
plt.figure("Image") # 图像窗口名称
plt.subplot(231)
plt.imshow(img)
plt.axis('off') # 关掉坐标轴为 off
plt.xticks([])
plt.yticks([])
plt.title("Picture")
for k in range(2, 7):
index = '23'+str(k)
plt.subplot(int(index))
label = KMeans(n_clusters=k).fit_predict(imgData)
#print("label.shape=",label.shape)
# get the label of each pixel
label = label.reshape([row, col])#
# create a new image to save the result of K-Means
pic_new = image.new("RGB", (row, col))
for i in range(row):
for j in range(col):
if label[i][j] == 0:
pic_new.putpixel((i, j), (0, 0, 255))
elif label[i][j] == 1:
pic_new.putpixel((i, j), (255, 0, 0))
elif label[i][j] == 2:
pic_new.putpixel((i, j), (0, 255, 0))
elif label[i][j] == 3:
pic_new.putpixel((i, j), (60, 0, 220))
elif label[i][j] == 4:
pic_new.putpixel((i, j), (249, 219, 87))
elif label[i][j] == 5:
pic_new.putpixel((i, j), (167, 255, 167))
elif label[i][j] == 6:
pic_new.putpixel((i, j), (216, 109, 216))
plt.title("K=%i"% k)
plt.imshow(pic_new)
plt.axis('off') # 关掉坐标轴为 off
plt.xticks([])
plt.yticks([])
# pic_new.save("./face_images/k6.jpg", "JPEG")
plt.axis('off') # 关掉坐标轴为 off
plt.xticks([])
plt.yticks([])
plt.show()
if __name__ == "__main__":
main()
ps:该代码来自某大佬,以下是我更改后的版本(迂回了一下),由于PIL的库函数函数前后配套,我只用了其中一个,要进行相应的转换。
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
import PIL.Image as image
#读取原始图像
paths ="D:\\work\\python\\Horse100\\0075.jpg"
X = plt.imread(paths)
X = np.array(X)
#print(X.shape)
shape = row ,col ,dim =X.shape
X_ = X.reshape(-1,3)#(将矩阵化为2维,才能使用聚类)
#print(X_.shape)
def kmeans(X, n):
kmeans = KMeans(n_clusters=n)
kmeans.fit(X)
Y = kmeans.predict(X)
return Y
plt.figure(1) # 图像窗口名称
plt.subplot(2,3,1)
plt.imshow(X)
plt.axis('off') # 关掉坐标轴为 off
plt.xticks([])
plt.yticks([])
plt.title("Picture")
for t in range(2, 7):
index = '23' + str(t)
plt.subplot(int(index))
label = kmeans(X_,t)
print("label.shape=",label.shape)
# get the label of each pixel
label = label.reshape(row,col)
# create a new image to save the result of K-Means
pic_new = image.new("RGB", (col, row))#定义的是图像大小为y*x*3的图像,这里列在前面行在后面
for i in range(col):
for j in range(row):
if label[j][i] == 0:
pic_new.putpixel((i, j), (0, 0, 255))#填写的是位置为(j,i)位置的像素,列和行也是反的
elif label[j][i] == 1:
pic_new.putpixel((i, j), (255, 0, 0))
elif label[j][i] == 2:
pic_new.putpixel((i, j), (0, 255, 0))
elif label[j][i] == 3:
pic_new.putpixel((i, j), (60, 0, 220))
elif label[j][i] == 4:
pic_new.putpixel((i, j), (249, 219, 87))
elif label[j][i] == 5:
pic_new.putpixel((i, j), (167, 255, 167))
elif label[j][i] == 6:
pic_new.putpixel((i, j), (216, 109, 216))
title = "k="+str(t)
plt.title(title)
plt.imshow(pic_new)
plt.axis('off') # 关掉坐标轴为 off
plt.xticks([])
plt.yticks([])
plt.show()
3. 输出图像