• 学习OpenCV——Kmean(C++)


    从前也练习使用过OpenCV的Kmean算法,但是那版本低,而且也是基于C的开发。这两天由于造论文的需要把它重新翻出来在研究一下C++,发现有了些改进

    kmeans

    C++: doublekmeans(InputArraydata, int K, InputOutputArray bestLabels, TermCriteriacriteria, int attempts, int flags, OutputArraycenters=noArray() )
    data:输入样本,要分类的对象,浮点型,每行一个样本(我要对颜色分类则每行一个像素);
    K:    类型数目;
    bestLabels: 分类后的矩阵,每个样本对应一个类型label;
    TermCriteria criteria:结束条件(最大迭代数和理想精度)
    int attempts:根据最后一个参数确定选取的最理想初始聚类中心(选取attempt次初始中心,选择compactness最小的);
    int flags :

    Flag that can take the following values:

    • KMEANS_RANDOM_CENTERS Select random initial centers in each attempt.
    • KMEANS_PP_CENTERS Use kmeans++ center initialization by Arthur and Vassilvitskii [Arthur2007].
    • KMEANS_USE_INITIAL_LABELS During the first (and possibly the only) attempt, use the user-supplied labels instead of computing them from the initial centers. For the second and further attempts, use the random or semi-random centers. Use one of KMEANS_*_CENTERS flag to specify the exact method.

    centers:输出聚类中心,每行一个中心(第一列是聚类中心,但是还有其他列,这里不太明白,大家谁懂,求科普啊!~~)

    compactness: 测试初始中心是否最优

                              

    上代码:

    [cpp] view plain copy
     
     print?
    1.   
    [cpp] view plain copy
     
     print?
    1. #include <string>  
    2. #include <iostream>  
    3. #include <math.h>  
    4. #include <vector>  
    5. #include <map>  
    6.   
    7. #include "opencv/cv.h"  
    8. #include "opencv/highgui.h"  
    9. #include "opencv/cxcore.h"  
    10.   
    11. #define ClusterNum (6)  
    12.   
    13. using namespace cv;  
    14. using namespace std;  
    15.   
    16. string filename="D:/demo1.jpg";  
    17.   
    18. Mat clustering(Mat src)  
    19. {  
    20.     int row = src.rows;  
    21.     int col = src.cols;  
    22.     unsigned long int size = row*col;  
    23.   
    24.     Mat clusters(size, 1, CV_32SC1);    //clustering Mat, save class label at every location;  
    25.   
    26.     //convert src Mat to sample srcPoint.  
    27.     Mat srcPoint(size, 1, CV_32FC3);      
    28.   
    29.     Vec3f* srcPoint_p = (Vec3f*)srcPoint.data;//////////////////////////////////////////////  
    30.     Vec3f* src_p = (Vec3f*)src.data;  
    31.     unsigned long int i;  
    32.   
    33.     for(i = 0;i < size; i++)  
    34.     {  
    35.         *srcPoint_p = *src_p;  
    36.         srcPoint_p++;  
    37.         src_p++;  
    38.     }  
    39.     Mat center(ClusterNum,1,CV_32FC3);  
    40.     double compactness;//compactness to measure the clustering center dist sum by different flag  
    41.     compactness = kmeans(srcPoint, ClusterNum, clusters,  
    42.         cvTermCriteria (CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 10, 0.1),ClusterNum,  
    43.         KMEANS_PP_CENTERS , center);  
    44.   
    45.     cout<<"center row:"<<center.rows<<" col:"<<center.cols<<endl;  
    46.     for (int y = 0; y < center.rows; y++)   
    47.     {  
    48.         Vec3f* imgData = center.ptr<Vec3f>(y);  
    49.         for (int x = 0; x < center.cols; x++)  
    50.         {  
    51.             cout<<imgData[x].val[0]<<" "<<imgData[x].val[1]<<" "<<imgData[x].val[2]<<endl;  
    52.         }  
    53.         cout<<endl;  
    54.     }  
    55.   
    56.   
    57.     double minH,maxH;  
    58.     minMaxLoc(clusters, &minH, &maxH);          //remember must use "&"  
    59.     cout<<"H-channel min:"<<minH<<" max:"<<maxH<<endl;  
    60.   
    61.     int* clusters_p = (int*)clusters.data;  
    62.     //show label mat  
    63.     Mat label(src.size(), CV_32SC1);  
    64.     int* label_p = (int*)label.data;  
    65.     //assign the clusters to Mat label  
    66.     for(i = 0;i < size; i++)  
    67.     {  
    68.         *label_p = *clusters_p;  
    69.         label_p++;  
    70.         clusters_p++;  
    71.     }  
    72.   
    73.     Mat label_show;  
    74.     label.convertTo(label_show,CV_8UC1);  
    75.     normalize(label_show,label_show,255,0,CV_MINMAX);  
    76.     imshow("label",label_show);  
    77.   
    78.   
    79.   
    80.     map<int,int> count;       //map<id,num>  
    81.     map<int,Vec3f> avg;       //map<id,color>  
    82.   
    83.     //compute average color value of one label  
    84.     for (int y = 0; y < row; y++)   
    85.     {  
    86.         const Vec3f* imgData = src.ptr<Vec3f>(y);  
    87.         int* idx = label.ptr<int>(y);  
    88.         for (int x = 0; x < col; x++)  
    89.         {  
    90.   
    91.             avg[idx[x]] += imgData[x];  
    92.             count[idx[x]] ++;  
    93.         }  
    94.     }  
    95.     //output the average value (clustering center)  
    96.     //计算所得的聚类中心与kmean函数中center的第一列一致,  
    97.     //以后可以省去后面这些繁复的计算,直接利用center,  
    98.     //但是仍然不理解center的除第一列以外的其他列所代表的意思  
    99.     for (i = 0; i < ClusterNum; i++)  
    100.     {  
    101.         avg[i] /= count[i];  
    102.         if (avg[i].val[0]>0&&avg[i].val[1]>0&&avg[i].val[2]>0)  
    103.         {  
    104.             cout<<i<<": "<<avg[i].val[0]<<" "<<avg[i].val[1]<<" "<<avg[i].val[2]<<" count:"<<count[i]<<endl;  
    105.   
    106.         }  
    107.     }  
    108.     //show the clustering img;  
    109.     Mat showImg(src.size(),CV_32FC3);  
    110.     for (int y = 0; y < row; y++)   
    111.     {  
    112.         Vec3f* imgData = showImg.ptr<Vec3f>(y);  
    113.         int* idx = label.ptr<int>(y);  
    114.         for (int x = 0; x < col; x++)  
    115.         {  
    116.             int id = idx[x];  
    117.             imgData[x].val[0] = avg[id].val[0];  
    118.             imgData[x].val[1] = avg[id].val[1];  
    119.             imgData[x].val[2] = avg[id].val[2];  
    120.         }  
    121.     }  
    122.     normalize(showImg,showImg,1,0,CV_MINMAX);  
    123.     imshow("show",showImg);  
    124.     waitKey();  
    125.     return label;  
    126. }  
    127.   
    128. int main()  
    129. {  
    130.     Mat img=imread(filename,1);  
    131.     GaussianBlur(img,img,Size(3,3),0);  
    132.     img.convertTo(img,CV_32FC3);  
    133.     Mat pixId=clustering(img);  
    134. }  

     
     
     
    from: http://blog.csdn.net/yangtrees/article/details/7971405
  • 相关阅读:
    vijos1198:最佳课题选择
    vijos1071:新年趣事之打牌
    vijos1153:猫狗大战
    bzoj3594: [Scoi2014]方伯伯的玉米田
    bzoj2753: [SCOI2012]滑雪与时间胶囊
    bzoj1923: [Sdoi2010]外星千足虫
    bzoj2783: [JLOI2012]树
    bzoj4590: [Shoi2015]自动刷题机
    bzoj4580: [Usaco2016 Open]248
    bzoj4579: [Usaco2016 Open]Closing the Farm
  • 原文地址:https://www.cnblogs.com/GarfieldEr007/p/5401870.html
Copyright © 2020-2023  润新知