opencv::KMeans方法概述

 

KMeans方法概述
    1. 无监督学习方法 
    2. 分类问题,输入分类数目,初始化中心位置 
    3. 硬分类方法,以距离度量 
    4. 迭代分类为聚类

 

  

 

//----------    
//迭代算法的终止准则
//----------
TermCriteria(
  int type,    
     //type=TermCriteria::MAX_ITER/TermCriteria::COUNT  迭代到最大迭代次数终止
      //type= TermCriteria::EPS   迭代到阈值终止
      //type= TermCriteria::MAX_ITER+ TermCriteria::EPS 上述两者都作为迭代终止条件
  int maxCount,    //迭代的最大次数
  double epsilon    // 阈值(中心位移值)
);

 

//----------
//按照给定的类别数目对样本集合进行聚类 
//----------
void cvKMeans2( 
  const CvArr* samples,   //输入样本的浮点矩阵,每个样本一行。
  int cluster_count,     //所给定的聚类数目
  CvArr* labels,       //输出整数向量:每个样本对应的类别标识 
  CvTermCriteria termcrit  //指定聚类的最大迭代次数和/或精度(两次迭代引起的聚类中心的移动距离) 
)

 

 

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main(int argc, char** argv) {
    Mat img(500, 500, CV_8UC3);
    RNG rng(12345);

    //scalar是将图像设置成单一灰度和颜色
    Scalar colorTab[] = {
        Scalar(0, 0, 255),
        Scalar(0, 255, 0),
        Scalar(255, 0, 0),
        Scalar(0, 255, 255),
        Scalar(255, 0, 255)
    };

    //分类个数
    int numCluster = rng.uniform(2, 5);
    printf("number of clusters : %d\n", numCluster);

    //取10-100个随机样本
    int sampleCount = rng.uniform(2, 1000);
    //每一列至少两个数
    Mat points(sampleCount, 1, CV_32FC2);
    Mat labels;
    Mat centers;
    
    // 生成随机数
    for (int k = 0; k < numCluster; k++) {
        Point center;
        center.x = rng.uniform(0, img.cols);
        center.y = rng.uniform(0, img.rows);
        //行,给随机点
        Mat pointChunk = points.rowRange(k*sampleCount/numCluster, k == numCluster - 1 ? sampleCount : (k + 1)*sampleCount / numCluster);

        //用随机数填充矩阵
        rng.fill(pointChunk, RNG::NORMAL, Scalar(center.x, center.y), Scalar(img.cols*0.05, img.rows*0.05));
    }
    //算法打乱元素排列顺序
    randShuffle(points, 1, &rng);
    
    // 使用KMeans
    kmeans(points, numCluster, labels, TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 10, 0.1/*最小值*/), 3/*次数*/, KMEANS_PP_CENTERS, centers);

    // 用不同颜色显示分类
    //初始化图片颜色。
    img = Scalar::all(255);
    for (int i = 0; i < sampleCount; i++) {
        int index = labels.at<int>(i);
        //获取ponint点
        Point p = points.at<Point2f>(i);
        //填充
        circle(img, p, 2, colorTab[index], -1, 8);
    }
    
    // 每个聚类的中心来绘制圆
    for (int i = 0; i < centers.rows; i++) {
        int x = centers.at<float>(i, 0);
        int y = centers.at<float>(i, 1);
        printf("c.x= %d, c.y=%d", x, y);
        circle(img, Point(x, y), 40, colorTab[i], 1, LINE_AA);
    }
    
    imshow("KMeans-Data-Demo", img);
    waitKey(0);
    return 0;
}

 


 

posted @ 2019-10-25 11:06  osbreak  阅读(724)  评论(0编辑  收藏  举报