k-means用于图像的颜色聚类

#coding:utf-8
__author__ = 'jmh081701'
#本文件主要学习一种经典的聚类方法:k-means
#我们把这个算法用于一个RGB图像的聚类,看能出来的什么的效果
#k-means的原理:
'''
输入:x[1],x[2],x[3],...,x[n],其中每个x[i]都是m维的向量,给定聚类的数目k
1.随机生成k个代表元:z[1],z[2],...,z[k];每个z[i]都是第i类的中心元
2.repeat:
  更新 xi所述的类别ci,使得:|x[i]-z[ci]|最小
  更新 z[j],z[j]等于所在类别G[j]的所有样本的平均值
until:z不再改变
'''
import numpy as np
import math
import  random
from  PIL import  Image

cnt=0
def calculate_zi(Gi,X):
#给定Gi,里面包含着属于这个类别的元素,然后计算这些元素的中心点
#在本实例中,Gi里面包含的是下标
    global  cnt
    sumi=np.zeros(len(X[0]))
    for each in Gi:
        cnt+=1
        sumi+=X[each]
    sumi/=(len(Gi)+0.000000001)
    zi=sumi
    return zi

def find_ci(xi,Z):
    #寻找离xi最近的中心元素ci,使得Z[ci]与xi之间的向量差的內积最小
    global  cnt
    dis_= np.inf
    len_=len(Z)
    rst_index = None
    for i in range(len_):
        cnt+=1
        tmp_dist=np.dot(xi-Z[i],np.transpose(xi-Z[i]))
        if tmp_dist<dis_:
            rst_index=i
            dis_=tmp_dist
    return  rst_index

def k_mean(X,k):
    G=[] #G[i]={1,2,3...}表示属于第i类的样本在X中的索引,洗标
    Z=[] #Z[i] 第i类的中心点
    N=len(X)
    c=[] #c[i]=1,2,...,k;表示第i个样本属于第c[i]类
    tmpr=set()
    while len(Z)<k:
        r=random.randint(0,len(X)-1)
        if r not in tmpr:
            tmpr.add(r)
            Z.append(X[r])
            G.append(set())
    for i in range(N):
        c.append(0)
    #随机生成K个中心元素
    while True:
        group_flag=np.zeros(k)
        for i in range(N):
            new_ci = find_ci(X[i],Z)
            if c[i] != new_ci:
                #找到了更好的,把xi从原来的c[i]调到new_ci去,于是有两个组需要更新:new_ci,c[i]
                if i in G[c[i]]:
                    G[c[i]].remove(i)
                group_flag[c[i]]=1  #把i从原来所属的组中移出来

                G[new_ci].add(i)
                group_flag[new_ci]=1    #把i加入到新的所属组去

                c[i]=new_ci

        #上面已经更新好了各元素的所属
        if np.sum(group_flag)==0:
            #没有组被修改
            break
        for i in range(k):
            if group_flag[i]==0:
                #未修改,无须重新计算
                continue
            else:
                Z[i]=calculate_zi(list(G[i]),X)
    return Z,c,k


def test_rgb_img():
    filename=r"1.jpg"
    im = Image.open(filename)
    img = im.load()
    im.close()
    height = im.size[0]
    width= im.size[1]
    print(im.size)
    X=[]
    for i in range(0,height):
        for j in range(0,width):
            X.append(np.array(img[i,j]))
    Z,c,k=k_mean(X,8)
    #print(Z)
    new_im = Image.new("RGB",(height,width))
    for i in range(0,height):
        for j in range(0,width):
            index = i * width + j
            pix = list(Z[c[index]])
            for k in range(len(pix)):
                pix[k]=int(pix[k])
            new_im.putpixel((i,j),tuple(pix))
    new_im.show()
if __name__ == '__main__':
    test_rgb_img()
    print(cnt)

原图:
这里写图片描述
k=8的聚类结果:

这里写图片描述

k=4的聚类结果:
这里写图片描述

k=2:聚类结果

这里写图片描述

github地址:https://github.com/jmhIcoding/ml.git

  • 8
    点赞
  • 60
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
基于MATLAB GUI的K-means算法图像聚类是一种常用的图像处理技术,旨在将图像中的像素点按照相似性进行分组。以下是一个300字的中文回答: K-means算法是一种无监督的机器学习算法,常用于图像聚类任务。MATLAB是一种强大的数学计算软件,提供了图形用户界面(GUI)工具包,使得编写和运行K-means算法更加简单便捷。 要在MATLAB GUI中实现K-means图像聚类,可以按照以下步骤进行: 1. 数据准备:将要处理的图像加载到MATLAB环境中,并将其转换为数字矩阵形式表示。可以使用imread函数读取图像,并用rgb2gray函数将其转换为灰度图像。 2. 初始化:选择要聚类的像素点数量,即确定聚类中心的数量。在GUI中,可以设置一个滑动条或者编辑框来动态调整聚类中心的数量。 3. 初始化聚类中心:使用随机或者其他策略选择初始聚类中心。可以使用randperm函数从图像中随机选取K个像素点作为初始聚类中心。 4. 迭代计算:根据K-means算法的原理,对每个像素点计算其与每个聚类中心的距离,并将其分配到距离最近的聚类中心。然后,根据新的聚类结果重新计算聚类中心。 5. 结果展示:将聚类结果可视化展示出来。可以在GUI中添加一个图像显示框,将不同聚类的像素点用不同颜色标记,形成聚类分割的效果。 在MATLAB GUI中实现K-means图像聚类,可以方便地调整参数和观察结果,提供了更好的交互性和可视化效果。通过这种方式,我们可以更好地理解和分析图像数据,提取出图像中的特定模式和信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值