首页 > 其他 > 详细

cvKMeans2函数用法概述

时间:2014-04-17 16:14:52      阅读:659      评论:0      收藏:0      [点我收藏+]

     一般情况下,我们通过C++/Matlab/Python等语言进行实现K-means算法,结合近期我刚刚学的C++,先从C++实现谈起,C++里面我们一般采用的是OpenCV库中写好的K-means函数,即cvKmeans2,首先来看函数原型:

     从OpenCV manual看到的是:
     int cvKMeans2(const CvArr* samples, int nclusters,
        CvArr* labels, CvTermCriteria termcrit,
        int attempts=1, CvRNG* rng=0,int flags=0,
        CvArr* centers=0,double* compactness=0);


    由于除去已经确定的参数,我们自己需要输入的为:
void cvKMeans2( 
    const CvArr* samples, //输入样本的浮点矩阵,每个样本一行。 
    int cluster_count,  //所给定的聚类数目 
     * labels,    //输出整数向量:每个样本对应的类别标识 ,注意:该变量的行数必须与samples的行数是一致的
     CvTermCriteria termcrit //指定聚类的最大迭代次数和/或精度(两次迭代引起的聚类中心的移动距离)
 ); 

 

一个例程如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
1 #ifdef _CH_
 2 #pragma package <opencv>
 3 #endif
 4
 5 #define CV_NO_BACKWARD_COMPATIBILITY
 6
 7 #ifndef _EiC
 8 #include "cv.h"
 9 #include "highgui.h"
10 #include <stdio.h>
11 #endif
12
13 int main( int argc, char** argv )
14 {
15     #define MAX_CLUSTERS 5    //设置类别的颜色,个数(《=5)
16     CvScalar color_tab[MAX_CLUSTERS];
17     IplImage* img = cvCreateImage( cvSize( 500, 500 ), 8, 3 );
18     CvRNG rng = cvRNG(-1);
19     CvPoint ipt;
20
21     color_tab[0] = CV_RGB(255,0,0);
22     color_tab[1] = CV_RGB(0,255,0);
23     color_tab[2] = CV_RGB(100,100,255);
24     color_tab[3] = CV_RGB(255,0,255);
25     color_tab[4] = CV_RGB(255,255,0);
26
27     cvNamedWindow( "clusters", 1 );
28
29     for(;;)
30     {
31         char key;
32         int k, cluster_count = cvRandInt(&rng)%MAX_CLUSTERS + 1;
33         int i, sample_count = cvRandInt(&rng)%1000 + 1;
34        <span style="color: rgb(255, 0, 0);"> <strong>CvMat* points = cvCreateMat( sample_count, 1, CV_32FC2 );//这里实际上的列数可以是很多列,并不一定仅仅是局限于这种两列(因为这里每列是一个二元数组)                             <br></strong></span>35         CvMat* clusters = cvCreateMat( sample_count, 1, CV_32SC1 );
36         cluster_count = MIN(cluster_count, sample_count);
37
38         /** generate random sample from multigaussian distribution */
39         for( k = 0; k < cluster_count; k++ )
40         {
41             CvPoint center;
42             CvMat point_chunk;
43             center.x = cvRandInt(&rng)%img->width;
44             center.y = cvRandInt(&rng)%img->height;
45             cvGetRows( points, &point_chunk, k*sample_count/cluster_count,
46                        k == cluster_count - 1 ? sample_count :
47                        (k+1)*sample_count/cluster_count, 1 );
48
49             cvRandArr( &rng, &point_chunk, CV_RAND_NORMAL,
50                        cvScalar(center.x,center.y,0,0),
51                        cvScalar(img->width*0.1,img->height*0.1,0,0));
52         }
53
54         /** shuffle samples */
55         for( i = 0; i < sample_count/2; i++ )
56         {
57             CvPoint2D32f* pt1 = (CvPoint2D32f*)points->data.fl + cvRandInt(&rng)%sample_count;
58             CvPoint2D32f* pt2 = (CvPoint2D32f*)points->data.fl + cvRandInt(&rng)%sample_count;
59             CvPoint2D32f temp;
60             CV_SWAP( *pt1, *pt2, temp );
61         }
62
63         printf( "iterations=%d\n",<strong><span style="color: rgb(255, 0, 0);"> cvKMeans2( points, cluster_count, clusters,
64                 cvTermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, 1.0 ),
65                 5, 0, 0, 0, 0 )</span></strong>);//<span style="color: rgb(255, 0, 0);"><strong>作者备注:cvKMeans2返回值为迭代次数?用户手册里面的意思应该是返回体现各个类别与类中心的差别的 compactness量度吧</strong></span>                                           <br>66
67         cvZero( img );
68
69         for( i = 0; i < sample_count; i++ )
70         {
71             int cluster_idx = clusters->data.i[i];
72             ipt.x = (int)points->data.fl[i*2];
73             ipt.y = (int)points->data.fl[i*2+1];
74             cvCircle( img, ipt, 2, color_tab[cluster_idx], CV_FILLED, CV_AA, 0 );
75         }
76
77         cvReleaseMat( &points );
78         cvReleaseMat( &clusters );
79
80         cvShowImage( "clusters", img );
81
82         key = (char) cvWaitKey(0);
83         if( key == 27 || key == ‘q‘ || key == ‘Q‘ ) // ‘ESC‘
84             break;
85     }
86
87     cvDestroyWindow( "clusters" );
88     return 0;
89 }
90
91 #ifdef _EiC
92 main(1,"kmeans.c");
93 #endif

 

另外,关于KMeans与SIFT算子的一个结合应用,有一个很好的帖子就是参考[2]中的内容。

此处为了说明其对KMeans使用的理解,将其第四部分step2内容备份于此。

 

Step2——Kmeans应用

  Step1里面的feature只是“预备单词”,在成为单词之前还要通过Step2生成“单词表”和Step3将“文档”中的“预备单词”找到“单词表”中最相近的“单词”替换之(并不是真正操作上的替换,只是当成“单词表”中的“单词”统计出来而已)。

  在Step2中,关键操作如下:

    

 其中关键函数当然是import_features(...)和cvKMeans2(...),前者是sift源码里的方法,用来导入feature文件使之成为内存数据结构,后者是Opencv里的kmeans算法之一(cvKMeans2(...)内部调用了kmeans(...))。

 

Reference

[1]聚类算法——K-means(下) http://www.cnblogs.com/moondark/archive/2012/03/08/2385870.html

[2]基于SIFT+Kmeans+LDA的图片分类器的实现 http://www.cnblogs.com/freedomshe/archive/2012/04/24/2468747.html

 

cvKMeans2函数用法概述,布布扣,bubuko.com

cvKMeans2函数用法概述

原文:http://www.cnblogs.com/jiayouwyhit/p/3670357.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!