zoukankan      html  css  js  c++  java
  • 用小例子讲解k-means算法流程及如何实现

    图像色彩量化

    请参考:图像色彩量化讲解及实现

    k-means算法

    请参考:k-means算法讲解及实现

    算法流程:

    1. 从图像中随机选取K个RGB分量(K是k-means的类别数)
    2. 将图像中的像素分配到颜色距离最短的那个类别的索引中去,色彩距离按照下面的方法计算:
      色彩距离计算公式
    3. 计算各个索引下像素的颜色的平均值,这个平均值成为新的类别
    4. 如果原来的类别和新的类别一致,算法结束;不一致,重复步骤2和步骤3
    5. 将原图中各个像素分配到色彩距离最小的那个类别中去

    算法实现(python):

    import cv2 as cv 
    import numpy as np
    import matplotlib.pyplot as plt
    from glob import glob
    
    def k_means(img, Class=5):
        # get shape
        H, W, C = img.shape
    
        # initiate random seed
        np.random.seed(0)
    
        # reshape image
        img = np.reshape(img, (H * W, -1))
    
        # get index randomly
        i = np.random.choice(np.arange(H * W), Class, replace=False)
        Cs = img[i].copy()
        print(Cs)
    
        while True:
            # prepare pixel class label
            clss = np.zeros((H * W), dtype=int)
            
            # each pixel
            for i in range(H * W):
                # get distance from index pixel
                dis = np.sqrt(np.sum((Cs - img[i])**2, axis=1))
                # get argmin distance
                clss[i] = np.argmin(dis)
    
            # selected pixel values
            Cs_tmp = np.zeros((Class, 3))
            
            # each class label
            for i in range(Class):
                Cs_tmp[i] = np.mean(img[clss == i], axis=0)
    
            # if not any change
            if (Cs == Cs_tmp).all():
                break
            else:
                Cs = Cs_tmp.copy()
    
        # prepare out image
        out = np.zeros((H * W, 3), dtype=np.float32)
    
        # assign selected pixel values  
        for i in range(Class):
            out[clss == i] = Cs[i]
    
        print(Cs)
            
        out = np.clip(out, 0, 255)
    
        # reshape out image
        out = np.reshape(out, (H, W, 3))
        out = out.astype(np.uint8)
    
        return out
    
    # read image
    img = cv.imread("../paojie.jpg").astype(np.float32)
    
    # K-means
    out = k_means(img,Class=3)
    
    cv.imwrite("out.jpg", out)
    cv.imshow("result", out)
    cv.waitKey(0)
    cv.destroyAllWindows()
    

    实验结果:

    随机选取的三个像素点的RGB分量

    随机选取的三个像素点的RGB分量

    k-means三个聚类中心的RGB分量

    k-means三个聚类中心的RGB分量

    原图:

    原图

    用三个不同颜色(就是不同类)表示的原图像。(本实验的输出结果)

    k-means实现的图像自动色彩量化结果图

  • 相关阅读:
    第二章 成员、变量和常量
    Roman To Integer
    Integer To Roman
    Container With Most Water
    搜狗2015前端工程师笔试题
    从网易与淘宝的font-size思考前端设计稿与工作流
    移动端web app自适应布局探索与总结
    CSS 常用代码
    利用 HTML 和 CSS 实现常见的布局
    CSS 尺寸单位
  • 原文地址:https://www.cnblogs.com/wojianxin/p/12580771.html
Copyright © 2011-2022 走看看