Opencv k-平均聚类算法第一步

k-平均聚类算法(k -means Clustering)第一步:生成质心

前面所讲到的图像识别任务是需要预期输出的简单监督学习(supervised-training)中的一种简单情况。在这里我们通过不需要预期输出的无监督学习(unsupervised-training)来进行图像分类。

最简单的方法是 k-平均聚类算法(k -means Clustering)。

k-平均聚类算法在类别数已知时使用。在质心不断明确的过程中完成特征量的分类任务。

k-平均聚类算法如下:

  1. 为每个数据随机分配类;
  2. 计算每个类的重心;
  3. 计算每个数据与重心之间的距离,将该数据分到重心距离最近的那一类;
  4. 重复步骤2和步骤3直到没有数据的类别再改变为止。

在这里,以减色化和直方图作为特征量来执行以下的算法:

  1. 对图像进行减色化处理,然后计算直方图,将其用作特征量;
  2. 对每张图像随机分配类别0或类别1(在这里,类别数为2,以np.random.seed (1)作为随机种子生成器。当np.random.random小于th时,分配类别0;当np.random.random大于等于th时,分配类别1,在这里th=0.5);
  3. 分别计算类别0和类别1的特征量的质心(质心存储在gs = np.zeros((Class, 12), dtype=np.float32)中);
  4. 对于每个图像,计算特征量与质心之间的距离(在此取欧氏距离),并将图像指定为质心更接近的类别。
  5. 重复步骤3和步骤4直到没有数据的类别再改变为止。

在这里,实现步骤1至步骤3吧(步骤4和步骤5的循环不用实现)!将图像test@@@.jpg进行聚类。

python实现:

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

# Dicrease color
def dic_color(img):
    img //= 63
    img = img * 64 + 32
    return img


# Database
def get_DB():
    # get training image path
    train = glob("dataset/test_*")
    train.sort()

    # prepare database
    db = np.zeros((len(train), 13), dtype=np.int32)
    pdb = []

    # each train
    for i, path in enumerate(train):
        # read image
        img = dic_color(cv2.imread(path))
        # histogram
        for j in range(4):
            db[i, j] = len(np.where(img[..., 0] == (64 * j + 32))[0])
            db[i, j+4] = len(np.where(img[..., 1] == (64 * j + 32))[0])
            db[i, j+8] = len(np.where(img[..., 2] == (64 * j + 32))[0])

        # get class
        if 'akahara' in path:
            cls = 0
        elif 'madara' in path:
            cls = 1

        # store class label
        db[i, -1] = cls

        # add image path
        pdb.append(path)

    return db, pdb

# k-Means step1
def k_means_step1(db, pdb, Class=2):
    # copy database
    feats = db.copy()

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

    # assign random class 
    for i in range(len(feats)):
        if np.random.random() < 0.5:
            feats[i, -1] = 0
        else:
            feats[i, -1] = 1

    # prepare gravity
    gs = np.zeros((Class, 12), dtype=np.float32)

    # get gravity
    for i in range(Class):
        gs[i] = np.mean(feats[np.where(feats[..., -1] == i)[0], :12], axis=0)
    print("assigned label")
    print(feats)
    print("Grabity")
    print(gs)


db, pdb = get_DB()
k_means_step1(db, pdb)

答案:

assigned label
[[ 1493  7892  4900  2099  1828  9127  4534   895  1554  6750  5406  2674 0]
[  242 10338  3628  2176   587 12212  2247  1338   434 10822  4506   622 1]
[ 6421  5478   719  3766  5482  4294  2537  4071  5609  4823  2051  3901 0]
[ 3343  8134  4756   151  3787  7588  3935  1074  3595  8444  4069   276 0]]
Grabity
[[ 3752.3333  7168.      3458.3333  2005.3334  3699.      7003.
3668.6667  2013.3334  3586.      6672.3335  3842.      2283.6667]
[  242.     10338.      3628.      2176.       587.     12212.
2247.      1338.       434.     10822.      4506.       622.    ]]

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程