Opencv k-平均聚类算法进行减色处理第一步

$$k-$$平均聚类算法进行减色处理第一步—-按颜色距离分类.

imori.jpg利用 k-平均聚类算法进行减色处理。

在问题六中涉及到了减色处理,但是在问题六中事先确定了要减少的颜色。这里,k-平均聚类算法用于动态确定要减少的颜色。

算法如下:

  1. 从图像中随机选取K\text{RGB}分量(这我们称作类别)。

  2. 将图像中的像素分别分到颜色距离最短的那个类别的索引中去,色彩距离按照下面的方法计算:
    \text{dis}=\sqrt{(R-R’)^2+(G-G’)^2+(B-B’)^2}

  3. 计算各个索引下像素的颜色的平均值,这个平均值成为新的类别;

  4. 如果原来的类别和新的类别完全一样的话,算法结束。如果不一样的话,重复步骤2和步骤3;
  5. 将原图像的各个像素分配到色彩距离最小的那个类别中去。

完成步骤1和步骤2。

  • 类别数K=5
  • 使用reshape((HW, 3))来改变图像大小之后图像将更容易处理;
  • 步骤1中,对于np.random.seed(0),使用np.random.choice(np.arrange(图像的HW), 5, replace=False)
  • 现在先不考虑步骤3到步骤5的循环。

python实现:

import cv2
import numpy as np
import matplotlib.pyplot as plt
from glob import glob


# K-means step1
def k_means_step1(img, Class=5):
    #  get shape
    H, W, C = img.shape

    # initiate random seed
    np.random.seed(0)

    # reshape
    img = np.reshape(img, (H * W, -1))

    # select one index randomly
    i = np.random.choice(np.arange(H * W), Class, replace=False)
    Cs = img[i].copy()

    print(Cs)

    clss = np.zeros((H * W), dtype=int)

    # each pixel
    for i in range(H * W):
        # get distance from base pixel
        dis = np.sqrt(np.sum((Cs - img[i]) ** 2, axis=1))
        # get argmin distance
        clss[i] = np.argmin(dis)

    # show
    out = np.reshape(clss, (H, W)) * 50
    out = out.astype(np.uint8)

    return out


# read image
img = cv2.imread("imori.jpg").astype(np.float32)

# K-means step2
out = k_means_step1(img)

cv2.imwrite("out.jpg", out)
cv2.imshow("result", out)
cv2.waitKey(0)

# 最初选择的颜色
[[140. 121. 148.]
 [135. 109. 122.]
 [211. 189. 213.]
 [135.  86.  84.]
 [118.  99.  96.]]
输入 (imori.jpg) 输出

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程