实验目的
- 目标︰利用K-means聚类算法对图像像素点颜色进行聚类实现简单的图像分割
- 输出∶同一聚类中的点使用相同颜色标记,不同聚类颜色不同
函数详解
获取图片的函数
def loadData(filePath):data = []img = image.open(f)m,n = img.sizefor i in range(m):for j in range(n):x,y,z = img.getpixel((i,j))data.append([x/256.0,y/256.0,z/256.0])return np.mat(data),m,n
- image是PIL的Image类,调用open方法打开对应路径的文件,生成为image的对象
- getpixel((x,y)):图片读进来是一个二维矩阵,每一个点是三个值(R,G,B)
- image对象的size属性:返回的是一个元组,像素构成的矩阵的长宽,(width,height)
具体的图像处理
label = KMeans(n_clusters=4).fit_predict(imgData)label = label.reshape([row,col])
pic_new = image.new("L",(row,col))
for i in range(row):for j in range(col):pic_new.putpixel((i,j),int(256/(label[i][j]+1)))
pic_new.save("result-bull-4.jpg","JPEG")
- KMeans(n_clusters=4).fit_predict(imgData):
- fit_predict():计算每一个簇的中心并预测每一个点的是属于哪个簇的,返回的与输入数组相同大小的labels数组,标记了每一个数据所属的簇
- label = label.reshape([row,col]):将由标记组成的数组进行的变形和转换,形成和原图一样大小的数组
- pic_new = image.new(“L”,(row,col)):根据给定的大小和模式,创建的一个新的图片
* PIL.Image.new(mode,size,color):size是对应的一个二维的元组,指定图片的大小
* mode:这里是指定对应每一个像素点是8个位,0到255之间
- pic_new.putpixel((i,j),int(256/(label[i][j]+1))):将生成的新的像素点放到新生成的矩阵中
- PIL.Image.eval(image, *args):后续为一个整数
- int(256/(label[i][j]+1))):将的之转变为的对应的不同的灰度值的图片,防止除数为零,就标记上在加+
最终实现的代码
import numpy as np
import PIL.Image as image
from sklearn.cluster import KMeansdef loadData(filePath):data = []img = image.open(filePath)m,n = img.sizefor i in range(m):for j in range(n):x,y,z = img.getpixel((i,j))data.append([x/256.0,y/256.0,z/256.0])return np.mat(data),m,nimgData,row,col = loadData('bull.jpg')
label = KMeans(n_clusters=4).fit_predict(imgData)label = label.reshape([row,col])
pic_new = image.new("L",(row,col))
for i in range(row):for j in range(col):pic_new.putpixel((i,j),int(256/(label[i][j]+1)))
pic_new.save("result-bull-4.jpg","JPEG")