نقاط پراکنده در صفحه دوبعدی به 5 خوشه تقسیم شده اند.
#ifdef _CH_
#pragma package
#endif
#define CV_NO_BACKWARD_COMPATIBILITY
#ifndef _EiC
#include "cv.h"
#include "highgui.h"
#include
#endif
#ifdef _DEBUG
#pragma comment (lib, "highguid.lib")
#pragma comment (lib, "cxcored.lib")
#else
#pragma comment (lib, "highgui.lib")
#pragma comment (lib, "cxcore.lib")
#endif
int main( int argc, char** argv )
{
#define MAX_CLUSTERS 5
CvScalar color_tab[MAX_CLUSTERS];
IplImage* img = cvCreateImage( cvSize( 500, 500 ), 8, 3 );
CvRNG rng = cvRNG(-1);
CvPoint ipt;
color_tab[0] = CV_RGB(255,0,0);
color_tab[1] = CV_RGB(0,255,0);
color_tab[2] = CV_RGB(100,100,255);
color_tab[3] = CV_RGB(255,0,255);
color_tab[4] = CV_RGB(255,255,0);
cvNamedWindow( "clusters", 1 );
for(;;)
{
char key;
int k, cluster_count = cvRandInt(&rng)%MAX_CLUSTERS + 1;
int i, sample_count = cvRandInt(&rng)%1000 + 1;
cv::Mat _points (sample_count, 2, CV_32FC1);
cv::Mat _clusters (sample_count, 1, CV_32SC1);
//cv::RNG& rng = cv::theRNG();
//rng.fill(_points, cv::RNG::NORMAL, param1, param2 );
for(int i = 0; i < sample_count; i++){
CvPoint center;
CvMat point_chunk;
center.x = cvRandInt(&rng)%img->width;
center.y = cvRandInt(&rng)%img->height;
}
CvMat* points = cvCreateMat( sample_count, 1, CV_32FC2 );
CvMat* clusters = cvCreateMat( sample_count, 1, CV_32SC1 );
cluster_count = MIN(cluster_count, sample_count);
/* generate random sample from multigaussian distribution */
for( k = 0; k < cluster_count; k++ )
{
CvPoint center;
CvMat point_chunk;
center.x = cvRandInt(&rng)%img->width;
center.y = cvRandInt(&rng)%img->height;
cvGetRows( points, &point_chunk, k*sample_count/cluster_count,
k == cluster_count - 1 ? sample_count :
(k+1)*sample_count/cluster_count, 1 );
cvRandArr( &rng, &point_chunk, CV_RAND_NORMAL,
cvScalar(center.x,center.y,0,0),
cvScalar(img->width*0.1,img->height*0.1,0,0));
}
/* shuffle samples */
for( i = 0; i < sample_count/2; i++ )
{
CvPoint2D32f* pt1 = (CvPoint2D32f*)points->data.fl + cvRandInt(&rng)%sample_count;
CvPoint2D32f* pt2 = (CvPoint2D32f*)points->data.fl + cvRandInt(&rng)%sample_count;
CvPoint2D32f temp;
CV_SWAP( *pt1, *pt2, temp );
}
for(int i = 0; i < sample_count; i++){
_points.at(i, 0) = points->data.fl[i*2];
_points.at(i, 1) = points->data.fl[i*2+1];
}
//old OpenCV Style
//cvKMeans2( points, cluster_count, clusters,
// cvTermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, 1.0 ),
// 5, 0, 0, 0, 0 );
//New OpenCV Style
cv::kmeans( _points, cluster_count, _clusters,
cvTermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, 1.0 ),
5, 0, 0);
cvZero( img );
for( i = 0; i < sample_count; i++ )
{
//int cluster_idx = clusters->data.i[i];
//ipt.x = (int)points->data.fl[i*2];
//ipt.y = (int)points->data.fl[i*2+1];
int cluster_idx = _clusters.at(i, 0);
ipt.x = (int)_points.at (i, 0);
ipt.y = (int)_points.at (i, 1);
cvCircle( img, ipt, 2, color_tab[cluster_idx], CV_FILLED, CV_AA, 0 );
}
cvReleaseMat( &points );
cvReleaseMat( &clusters );
cvShowImage( "clusters", img );
key = (char) cvWaitKey(0);
if( key == 27 || key == 'q' || key == 'Q' ) // 'ESC'
break;
}
cvDestroyWindow( "clusters" );
return 0;
}
#ifdef _EiC
main(1,"kmeans.c");
#endif