本章内容


      1. 获取颜色特征集合
      2. K均值聚类
      3. 显示聚类结果

1. 获取颜色特征集合

opencv K均值聚类分析,标准像背景识别

2.k均值聚类

opencv K均值聚类分析,标准像背景识别

 

输出结果:

opencv K均值聚类分析,标准像背景识别

3. 绘制聚类结果:

opencv K均值聚类分析,标准像背景识别

输出结果:

opencv K均值聚类分析,标准像背景识别

源码

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

int main(int argc, char *argv[])
{
    /* 本章内容
     * K均值聚类
    */
    std::string fileName = "/home/wang/Image/toux.jpg";
    cv::Mat src = cv::imread(fileName);
    if(src.data == NULL){
        std::cout << "图片打开失败" << std::endl;
        return -1;
    }
    cv::imshow("src", src);
    int sampleNum = src.rows*src.cols;
    cv::Mat points(sampleNum,src.channels(),CV_32F,cv::Scalar(0));
    std::cout << "数据集维度:" << points.size() << std::endl;

    // rgb为特征
    for(int i=0;i<src.rows;i++){
        for(int j=0;j<src.cols;j++){
            cv::Vec3b bgr = src.at<cv::Vec3b>(i,j);
            int index =  i*src.cols + j;
            // Point(j,i) .
            points.at<float>(index,0) = bgr[0];
            points.at<float>(index,1) = bgr[1];
            points.at<float>(index,2) = bgr[2];
        }
    }

    cv::Mat labels;
    cv::Mat centers;

    /* k均值聚类
    api接口:CV_EXPORTS_W double kmeans( InputArray data, int K, InputOutputArray bestLabels,
                                TermCriteria criteria, int attempts,
                                int flags, OutputArray centers = noArray() );
    参数分析:
        data:聚类数据,N维点集, 矩阵输入,行为样本数目,列为特征。
        K: 分割的类数目
        bestLabels: 输入输出类型,点集合的索引,输入的值作为起始聚类值
        criteria: 迭代终止条件
        attempts: 尝试重新次数
        flags: 初始化中心模式,参考cv::KmeansFlags
        centers: 聚类的中心,Output matrix
        cv::KmeansFlags{
            KMEANS_RANDOM_CENTERS     = 0,
            KMEANS_PP_CENTERS         = 2,
            KMEANS_USE_INITIAL_LABELS = 1   }
  */
    int clusterNum = 4;
    cv::TermCriteria tc = cv::TermCriteria(cv::TermCriteria::EPS + cv::TermCriteria::COUNT,10,0.1);
    cv::kmeans(points,clusterNum,labels,tc,3,cv::KMEANS_RANDOM_CENTERS,centers);
    std::cout << "矩阵中心\n" << centers <<std::endl;
    std::cout << "labels.size()\n" << labels.size() <<std::endl;
    double minVal,maxVal;
    cv::minMaxIdx(labels,&minVal,&maxVal);
    std::cout << "minVal " << minVal << " maxVal " << maxVal << std::endl;
    std::cout << "labels.type()= "  << labels.type() << std::endl;
    // 显示图像分割结果
    // rgb为特征
//    cv::CV_8UC1;
    std::vector<cv::Vec3b> colorSet;
    cv::RNG rng(12345);
    for(int i=0; i < clusterNum; i++) colorSet.push_back(cv::Vec3b(rng.uniform(0,255),rng.uniform(0,255),rng.uniform(0,255)));
//    colorSet.push_back(cv::Vec3b(255,0,0));
//    colorSet.push_back(cv::Vec3b(0,255,0));
//    colorSet.push_back(cv::Vec3b(255,0,255));
//    colorSet.push_back(cv::Vec3b(0,255,255));
//    colorSet.push_back(cv::Vec3b(255,255,255));
    cv::Mat result = cv::Mat::zeros(src.rows,src.cols,CV_8UC3);
    // RGB 数据转换到样本数据
    // 显示图像分割结果
    for(int i=0;i<src.rows;i++){
        for(int j=0;j<src.cols;j++){
            int index = i*src.cols + j;
            int label = labels.at<int>(index);
            result.at<cv::Vec3b>(i, j) = colorSet[label];
      }
    }

    cv::imshow("cluster result", result);

    // 绘制中心

    cv::waitKey(0);
    return 1;
}

 

相关文章:

  • 2021-06-22
  • 2021-10-30
  • 2021-06-21
  • 2021-04-29
  • 2021-05-20
猜你喜欢
  • 2021-10-03
  • 2021-09-02
  • 2021-09-27
  • 2021-03-31
  • 2021-11-29
  • 2022-12-23
  • 2021-04-28
相关资源
相似解决方案