用小例子講解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實現的圖像自動色彩量化結果圖


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM