zoukankan      html  css  js  c++  java
  • opencv笔记--Kmeans

        在图像分割中,使用 kmeans 算法可以实现图像区域基本分割。如果一幅图像被分为两类,kmeans 分割效果与  ostu 算法基本一致,具体如下图:

          

        

        kmeans 将图像灰度聚类为 k 类,ostu 将图像灰度分割为 2 类,当 k = 2 时,两种算法最终目的基本趋于一致。

        kmeans 算法基本思路如下:

        1)随机选取第一个聚类中心点,之后的聚类中心点选取有两种方法;

             a. 随机选取其他 k - 1 个聚类中心点;

             b. 根据已经选取的聚类中心点,计算所有点到已经选取的聚类中心点的距离,选择到所有已经选取的聚类中心点的最远点作为下一个聚类中心点;

        2)根据点到已经选取的聚类中心点的距离对其进行分类;

        3)重新求各个分类的聚类中心点,然后回到 2);

        4)当不再满足迭代条件时给出最终聚类结果,迭代条件包括:

              a. 聚类中心点在迭代过程中的偏移量;

              b. 迭代次数;

        对于聚类中心点的选择,一般情况下,方法 b 会得到更好的聚类,且迭代速度较快。

        opencv 提供的 kmean 函数为:

        double kmeans( InputArray data, int K, InputOutputArray bestLabels, TermCriteria criteria, int attempts,

                                  int flags, OutputArray centers=noArray() );

        参数如下:

        data: 待分类点矩阵,其类型必须为 CV_32F;

         K,bestLabels: 聚类数与待分类点所属分类;

         criteria:停止条件;

         attempts:使用不同的随机聚类中心点尝试聚类次数;

         flags:聚类中心点选择方案,包括完全随机选择,kmeans++选择方案(b),用户输入;

         centers:最终聚类中心点;

         以下给出 kmeans 算法使用代码:

         

     1 void UseKmeans(cv::Mat& src, cv::Mat& rst)
     2 {
     3     int width = src.cols;
     4     int height = src.rows;
     5     int dims = src.channels();
     6     int sampleCount = width * height;
     7 
     8     int clusterCount = 2;
     9     Mat points(sampleCount, dims, CV_32F, Scalar(10));
    10     cv::Mat pos(sampleCount, 2, CV_16S, Scalar(0, 0));
    11     Mat labels;
    12     Mat centers(clusterCount, 1, points.type());
    13 
    14     // invert to data points
    15     int index = 0;
    16     for (int row = 0; row < height; row++) {
    17         for (int col = 0; col < width; col++) {
    18             points.at<float>(index, 0) = static_cast<int>(src.ptr<uchar>(row)[col]);
    19             pos.at<short>(index, 0) = static_cast<short>(row);
    20             pos.at<short>(index, 1) = static_cast<int>(col);
    21             ++index;
    22         }
    23     }
    24 
    25     // k-mean algorithm
    26     TermCriteria criteria = TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 100, 1.0);
    27     kmeans(points, clusterCount, labels, criteria, 3, KMEANS_PP_CENTERS, centers);
    28 
    29     int bright_val = -1;
    30     for (int i = 0; i < centers.rows; ++i)
    31     {
    32         int val = centers.at<float>(i, 0);
    33         if (val > bright_val)
    34             bright_val = val;
    35     }
    36 
    37     int bright_label = -1;
    38     for (int idx = 0; idx < sampleCount; ++idx)
    39     {
    40         float *datapoint = points.ptr<float>(idx);
    41         int *datalabel = labels.ptr<int>(idx);
    42         if (datapoint[0] >= bright_val)
    43         {
    44             bright_label = datalabel[0];
    45             break;
    46         }
    47     }
    48 
    49     // save result
    50     rst.create(src.size(), CV_8UC1);
    51     rst.rowRange(0, rst.rows) = 0;
    52     for (int idx = 0; idx < sampleCount; ++idx)
    53     {
    54         int *datalabel = labels.ptr<int>(idx);
    55         if (datalabel[0] == bright_label)
    56         {
    57             int row = pos.at<short>(idx, 0);
    58             int col = pos.at<short>(idx, 1);
    59             rst.ptr<uchar>(row)[col] = 255;
    60         }
    61     }
    62 }

         

         

         

         

       

  • 相关阅读:
    二 ,Smarty模板技术/引擎——变量操作(1)
    一,Smarty模板技术/引擎——简介
    MVC模式学习--雇员管理系统项目开发
    mysqli扩展库---------预处理技术
    drupal7 上传文件中文乱码
    php根据IP获取IP所在城市
    php获取客户端IP
    drupal中安装CKEditor文本编辑器,并配置图片上传功能 之 方法一
    drupal7的node的内容的存储位置
    drupal7 安装百度编辑器Ueditor及后续使用
  • 原文地址:https://www.cnblogs.com/luofeiju/p/13890084.html
Copyright © 2011-2022 走看看