94 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			94 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#ifdef _CH_
 | 
						|
#pragma package <opencv>
 | 
						|
#endif
 | 
						|
 | 
						|
#define CV_NO_BACKWARD_COMPATIBILITY
 | 
						|
 | 
						|
#ifndef _EiC
 | 
						|
#include "cv.h"
 | 
						|
#include "highgui.h"
 | 
						|
#include <stdio.h>
 | 
						|
#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;
 | 
						|
        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 );
 | 
						|
        }
 | 
						|
 | 
						|
        printf( "iterations=%d\n", cvKMeans2( points, cluster_count, clusters,
 | 
						|
                cvTermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, 1.0 ),
 | 
						|
                5, 0, 0, 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];
 | 
						|
            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
 |