기계 학습 초보 자: OpenCV K 평균치 코드 노트

5265 단어 ComputerVision
K 평균치 집합 알고리즘 은 Opencv 의 cxcore 에서 데이터 의 자연 분 류 를 찾 을 수 있 습 니 다.가장 자주 사용 되 는 집합 기술 중 하 나 는 '유형' 센터 를 신속하게 찾 아 데 이 터 를 집합 할 수 있다.
 
 
 
    우 리 는 그림 에서 K 평균치 알고리즘 의 집합 과정 을 이해 할 수 있다.
    (a) 클 러 스 터 센터 (원) 를 무 작위 로 배치 하고 데이터 샘플 (작은 사각형) 을 가장 가 까 운 중심 (즉 연결선) 에 모 습 니 다.
    (b) 데이터 센터 를 분류 중심 으로 이동 합 니 다.
    (c) 데이터 점 은 최근 인접 규칙 에 따라 분류 중심 에 다시 모 였 습 니 다 (예 를 들 어 b 에서 가장 오른쪽 원 의 견본 은 c 에서 아래 원 에 모 였 습 니 다)
    (d) 분류 센터 가 있 는 분류 센터 로 다시 이동
    수렴 할 때 까지 계속 운행 하면 우 리 는 견본 점 (작은 사각형) 을 세 가지 (원) 로 모 았 다.
 
    OpenCV Sample 의 kmeans 코드 는 무 작위 로 5 가지 유형 을 초과 하지 않 고 1000 개의 점 을 생 성 합 니 다.
#include "cv.h"
#include "highgui.h"
#include 

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
", 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; }

 
    가장 바깥쪽 for 순환 전에 우 리 는 5 가지 색상 color 를 정의 했다.tab, 카 테 고리 의 지난번 MAXCLUSTERS。
순환 중 랜 덤 으로 cluster 생 성count 개 클래스 및 sample샘플 점 을 카운트 합 니 다.
이 동시에 points 를 만들어 서 견본 점 을 저장 하고 clusters 는 모든 견본 점 의 유형 을 저장 합 니 다.CvMat* points = cvCreateMat( sample_count, 1, CV_32FC2 );CvMat* clusters = cvCreateMat( sample_count, 1, CV_32SC1 ); 
    그 중에서 cvCreateMat 의 첫 번 째 매개 변 수 는 행렬 의 줄 수 이 고 두 번 째 는 열 수 입 니 다.CV_32FC2 는 행렬 의 요 소 는 32 비트 부동 소수점 이원 그룹, 즉 우리 의 Point 임 을 나타 낸다.
    데이터 가 생 성 된 for 순환 에서 point 는 모든 견본 의 정 보 를 저장 합 니 다. 우 리 는 견본 을 분류 하고 무 작위 로 할당 해 야 합 니 다.
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));
    cvGetRows 는 이번 교체 의 현재 분류 k 에 따라 points 의 대응 하 는 서브 매트릭스 point 를 얻 습 니 다.chunk。각 분류 줄 수 는 samplecount/cluster_count。
    이 어 cvRandArr 를 사용 하여 이 서브 매트릭스 에 정상 분포 무 작위 할당 을 사용 합 니 다.
 
    다음 for 순환 에서 데이터 견본 의 순 서 를 어 지 럽 혔 습 니 다.
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 );
 
    우 리 는 pt1, pt2 는 points 에서 무 작위 로 선택 한 견본 점 이 고 교환 한 것 을 볼 수 있다.
    그리고 cvKmeans 2 () 를 사용 하여 집합 을 진행 하 였 으 며, 집합 센터 의 최대 이동 이 1 보다 작 음 을 알 고 있 습 니 다.마지막 으로 for 순환 으로 결 과 를 그립 니 다.
 
    프로그램 을 실행 하고 집합 결 과 를 봅 시다!
 
 
  ----------------------------------
저자: 작은 근 (진 흔)
본 고 는 오리지널 문장 에 속 합 니 다. 인용 을 전재 하려 면 원문의 작가 와 링크 를 밝 혀 주 십시오. 감사합니다.

좋은 웹페이지 즐겨찾기