利用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实现的图像自动色彩量化结果图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值