关闭

用VLFeat库进行k-means聚类

750人阅读 评论(0) 收藏 举报
分类:

用VLFeat库进行k-means聚类

2012-08-28 22:55 by smyb000, 6360 阅读, 4 评论, 收藏编辑

摘要

本文将介绍如何使用VLFeat开源库来进行K-means聚类,关于K-means的介绍可以参考这里

什么是VLFeat

VLFeat官方主页的话来说,VLFeat 是一个实现了视觉领域诸多算法的开源库,其包括SIFTMSER,  k-meanshierarchical k-meansagglomerative information bottleneck, quick shift 等等。底层代码用C语言实现,并提供了MATLAB接口。支持WindowsMac OS X, 和 Linux。最新版本为 VLFeat 0.9.14

和OpenCV相比,VLFeat是一个轻量级的库,主要实现了在特征提取和聚类方面的高效算法, 可以用在图像检索和物体识别领域中。

Integer K-means (IKM) 介绍

接下来将介绍如何用VLFeat库来进行k-means聚类。

VLFeat 提供了k-means 聚类和分层k-means聚类的轻量级的实现。需要注意的是,IKmeans聚类数据的类型是unsigned char型。虽然这看上去有局限性,但对于图像的特征聚类,算法有很高的准确性,因为在高维空间中(例如SIFT特征,128维),UCHAR型已经足够。C语言的Integer K-means的接口文档请看这里

Integer K-means (IKM) 实现了整型数据的 K-means 聚类 (或者叫矢量量化)。在图像检索、识别领域,经常会用到Bag-of-words(BOW)模型,该模型对训练集图像提取特征并进行聚类,得到固定数量的代表性特征集(dictionary), 将测试集中提取出来的特征进行量化,用之前得到代表性特征集中的特征(word)来表示,这样每幅图像就可以表示成bag-of-words。该功能可以用VLFeat库轻松实现。

如何使用接口?

用VLFeat进行K-means 聚类,需要包含 ikmeans.h 头文件,其声明了如下接口:

数据结构

struct   VlIKMFilt  

量化器,k-means聚类的核心数据结构。聚类相关的任何函数都与此数据结构有关。

枚举类型

enum  VlIKMAlgorithms { VL_IKM_LLOYDVL_IKM_ELKAN }

VLFeat 实现了两种聚类算法,在进行训练时作为参数传入给vl_ikm_train 函数。

函数

VlIKMFilt  * vl_ikm_new (int method)

创建量化器,传入参数为VL_IKM_LLOYD或者 VL_IKM_ELKAN

 

void  vl_ikm_delete (VlIKMFilt *f)

删除量化器

 

void vl_ikm_init (VlIKMFilt *f, vl_ikm_acc const *centers, int M, int K)

指定聚类的center 对量化器初始化,M为数据的维数,K为聚类数

 

void vl_ikm_init_rand (VlIKMFilt *f, int M, int K)

随机生成center,并进行初始化,M为数据的维数,K为聚类数

 

void vl_ikm_init_rand_data (VlIKMFilt *f, vl_uint8 const *data, int M, int N, int K)

在数据中随机指定center,对量化器进行初始化,M为维数,N为数据数,K为聚类数

 

int vl_ikm_train (VlIKMFilt *f, vl_uint8 const *data, int N)

对输入数据进行训练, data为数据, N为数据数目。

 

void vl_ikm_push (VlIKMFilt *f, vl_uint *asgn, vl_uint8 const *data, int N)

将新数据量化到聚类中心,得到每个数据的标记。 asgn为数据的标记数组, data为输入数据, N为数据数目。

 

vl_uint vl_ikm_push_one (vl_ikm_acc const *centers, vl_uint8 const *data, int M, int K)

对一个数据进行量化

 

还有一些存取函数下文将省略,可以查询文档查看详情。

 

IKM使用步骤

step 1. 创建量化器

        用 vl_ikm_new() 函数创建一个IKM 量化器(聚类器)。

step 2. 初始化 IKM量化器

       用 vl_ikm_init() 或者其它接口(本文用vl_ikm_init_rand函数)。

step 3. 用 vl_ikm_train() 训练量化器。

step 4. 用vl_ikm_push() 函数或者 vl_ikm_push_one() 对新的特征进行量化(如只需要聚类,可以在这一步重复使用step 3. 的训练数据)。

 

开始聚类吧

准备工作就绪,开始聚类吧!

我们将随机产生值为[0,255)的2维数据点来进行k-means聚类,这样可以很直观方便地在图像中画出来看到聚类结果。

在这里用OpenCV的函数来显示二维数据点以及分类结果。

首先包含必须的头文件 ikmeans.h。

首先包含必须的头文件 ikmeans.h。

extern "C" {
#include "ikmeans.h"
}

用OpenCV建立矩阵来显示随机生成的数据以及聚类后的结果。

复制代码
int row = 255;
int col = 255;
Mat show = Mat::zeros(row, col, CV_8UC3);
Mat show2 = show.clone();
复制代码

创建随机训练数据,用200组2维数据进行训练。并在图像中绘制数据点。

复制代码
int data_num = 200;
int data_dim = 2;
vl_uint8 *data = new vl_uint8[data_num * data_dim];

for( int i=0; i<data_num; ++i)
{
    vl_uint8 x = data[i*data_dim] = rand()% col;
    vl_uint8 y = data[i*data_dim+1] = rand()% row;
    circle(show,Point(x,y),2,Scalar(255,255,255));
}
复制代码

如下图所示,生成了200个点的数据。

show

                                                                                 图1.随机生成的数据点

接下来的几行代码将创建量化器,训练,并得到量化结果,在这里,用训练数据作为新数据传给量化器,这样就可以得到训练数据的聚类结果,聚类数目为K=3。

复制代码
VlIKMFilt *kmeans = vl_ikm_new(VL_IKM_ELKAN);
vl_uint K = 3;
vl_ikm_init_rand(kmeans, data_dim, K);
vl_ikm_train(kmeans, data, data_num);
vl_uint * label = new vl_uint[data_num];
vl_ikm_push(kmeans, label, data, data_num);
复制代码

在上面的代码中,label数组存放的就是量化结果,量化的序号为0,1,2...,K-1。

最后,画图,显示结果。

复制代码
    for( int i=0;i<data_num; ++i)
    {
        vl_uint8 x = data[i*data_dim];
        vl_uint8 y = data[i*data_dim+1];
        switch(label[i])
        {
        case 0:
                circle(show2,Point(x,y),2,Scalar(255,0,0));
                break;
        case 1:
                circle(show2,Point(x,y),2,Scalar(0,255,0));
                break;
        case 2:
                circle(show2,Point(x,y),2,Scalar(0,0,255));
                break;
        }
    }
复制代码

结果如下图所示:

show2

                                                                                    图2.聚类(量化)结果

最后别忘了删除聚类器,以及清空数组。

vl_ikm_delete(kmeans);
delete []label;
label = NULL;
delete []data;
data = NULL;

整个程序的源代码如下:

复制代码
#include "stdafx.h"

extern "C" {

#include "ikmeans.h"
}

#include "global_header.h"


int main()
{
    /*initialize data point*/
    int row = 255;
    int col = 255;
    Mat show = Mat::zeros(row, col, CV_8UC3);
     Mat show2 = show.clone();

    int data_num = 200;
    int data_dim = 2;
    vl_uint8 *data = new vl_uint8[data_num * data_dim];

    for( int i=0; i<data_num; ++i)
    {
        vl_uint8 x = data[i*data_dim] = rand()% col;
        vl_uint8 y = data[i*data_dim+1] = rand()% row;
        circle(show,Point(x,y),2,Scalar(255,255,255));
    }

    VlIKMFilt *kmeans = vl_ikm_new(VL_IKM_ELKAN);
    vl_uint K = 3;
    vl_ikm_init_rand(kmeans, data_dim, K);
    vl_ikm_train(kmeans, data, data_num);

    vl_uint * label = new vl_uint[data_num];

    vl_ikm_push(kmeans, label, data, data_num);


    for( int i=0;i<data_num; ++i)
    {
        vl_uint8 x = data[i*data_dim];
        vl_uint8 y = data[i*data_dim+1];
        switch(label[i])
        {
        case 0:
                circle(show2,Point(x,y),2,Scalar(255,0,0));
                break;
        case 1:
                circle(show2,Point(x,y),2,Scalar(0,255,0));
                break;
        case 2:
                circle(show2,Point(x,y),2,Scalar(0,0,255));
                break;
        }
    }


    imwrite("show.jpg",show);
    imwrite("show2.jpg",show2);

    vl_ikm_delete(kmeans);
    
    delete []label;
    label = NULL;

    delete []data;
    data = NULL;


    return 0;
}
复制代码

0
0
查看评论

深度学习工具箱和Vlfeat库的配置及使用

这两个库都用在Matlab中,方便科研。 配置:MatlabR2013a+Win8.1+DeepLearnToolbox+Vlfeat-0.9.18   1.DeepLearnToolbox DeepLearnToolbox是Matlab的深度学习工具箱,包含了深度...
  • wm_1991
  • wm_1991
  • 2016-04-05 14:46
  • 981

用VLFeat库进行k-means聚类

摘要 本文将介绍如何使用VLFeat开源库来进行K-means聚类,关于K-means的介绍可以参考这里。 什么是VLFeat 用VLFeat官方主页的话来说,VLFeat 是一个实现了视觉领域诸多算法的开源库,其包括SIFT, MSER,  k-m...
  • lcj_cjfykx
  • lcj_cjfykx
  • 2013-07-04 02:04
  • 3137

用VLFeat库进行k-means聚类(C++ 实现)

摘要 本文习转载:原博文链接:http://www.cnblogs.com/smyb000/archive/2012/08/28/k-means_cluster_via_vlfeat.html 本文将介绍如何使用VLFeat开源库来进行K-means聚类,关于K-means的介绍可以参考这里。 ...
  • lilai619
  • lilai619
  • 2016-01-22 15:28
  • 1662

VLfeat--轻量级的--计算机视觉库的介绍

(一)VLFeat计算机视觉库的简介 1----VLFeat---是一个开源的计算机视觉库算法,和OpenCv相比来说,它是一个轻量级的计算机视觉库 2----VLFeat---这个开源BSD的计算机视觉库主要实现了 SIFT,MSER, k-means, hierarchical k...
  • maweifei
  • maweifei
  • 2016-08-31 16:31
  • 455

VLFeat教程k-means

VLFeat offers a hierarchical version of integer k-means, which recursively applies vl_ikmeans to compute finer and finer partitions. F...
  • GarfieldEr007
  • GarfieldEr007
  • 2015-12-17 12:41
  • 1207

用VLFeat库进行k-means聚类

用VLFeat库进行k-means聚类 2012-08-28 22:55 by smyb000, 6360 阅读, 4 评论, 收藏, 编辑 摘要 本文将介绍如何使用VLFeat开源库来进行K-means聚类,关于K-me...
  • maweifei
  • maweifei
  • 2016-08-31 16:32
  • 750

vlfeat-0.9.16 做kmeans聚类时遇到的bug

在使用vlfeat的kmeans聚类时,发现程序跑到聚类函数(vl_kmeans_cluster)那块马上挂了。报出了一个奇怪的错误: 多方查找,网上有说是windows 里面两个dll 的问题。需要把两个dll(windows /system32 下面的) 替换掉。我试了一下...
  • suifeng50
  • suifeng50
  • 2015-11-25 14:58
  • 578

vl_feat库中的k-means聚类

最近准备好好看一下vl_feat库。 首先简单介绍一下vl_feat库(http://www.vlfeat.org/index.html)。vl_feat库是用C语言开发的一个开源的计算机视觉的库,它比opencv要小,但是实现了一些比较常见的视觉方面的算法(包括HOG,SIFT, MS...
  • FacingTheSunCN
  • FacingTheSunCN
  • 2013-09-28 14:16
  • 4097

用kmeans对图片像素进行聚类

用kmeans对图片像素进行聚类对sklearn中kmeans的简单应用1,获得示例图像在scipy.misc 模块中有一个函数可以载入lena图像 from scipy import misc lena = misc.lena()plt.subplot() plt.imshow(lena,cmap...
  • zhaohansk
  • zhaohansk
  • 2015-12-27 21:19
  • 4007

TensorFlow实战— —K-Means聚类

TensorFlow是Google最近开源的人工智能库。这里写图片描述TensorFlow使用了data-flow graphs(DFG),如下图这里写图片描述从图中可以看出,DFG是表示计算表达式的一种树形结构图。每个节点代表一个运算,非叶子节点是运算符,叶子节点是直接的值(确定的值或者不确定的值...
  • u010417185
  • u010417185
  • 2016-07-11 10:13
  • 806
    个人资料
    • 访问:426103次
    • 积分:6249
    • 等级:
    • 排名:第4704名
    • 原创:195篇
    • 转载:157篇
    • 译文:3篇
    • 评论:59条
    最新评论