从前也练习使用过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: 测试初始中心是否最优

上代码:

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

 
 
 
from: http://blog.csdn.net/yangtrees/article/details/7971405

学习OpenCV——Kmean(C++)的更多相关文章

  1. 学习opencv之路(一)

    先看一下<学习opencv> 找几个demo 学会相机标定 我做的是单目相机的标定.

  2. [纯小白学习OpenCV系列]官方例程00:世界观与方法论

    2015-11-11 ----------------------------------------------------------------------------------- 其实,写博 ...

  3. 《学习OpenCV》中求给定点位置公式

    假设有10个三维的点,使用数组存放它们有四种常见的形式: ①一个二维数组,数组的类型是CV32FC1,有n行,3列(n×3) ②类似①,也可以用一个3行n列(3×n)的二维数组 ③④用一个n行1列(n ...

  4. 对人脑处理视觉的描述(摘《学习OpenCV(中文版)》)

    人脑将视觉信号划分入很多个通道,将各种不同的信息输入你的大脑.你的大脑有一个关注系统,会根据任务识别出图像的重要部分,并做重点分析,而其他部分则分析得较少 .在人类视觉流中存在大量的反馈,但是目前我们 ...

  5. 《学习OpenCV》练习题第五章第二题abc

    代码: #include <stdio.h> #include <opencv/highgui.h> #include <opencv/cv.h> #include ...

  6. 《学习OpenCV》练习题第五章第一题ab

    这道题是载入一幅带有有趣纹理的图像并用不同的模板(窗口,核)大小做高斯模糊(高斯平滑),然后比较用5*5大小的窗口平滑图像两次和用11*11大小的窗口平滑图像一次是否接近相同. 先说下我的做法,a部分 ...

  7. 《学习OpenCV》练习题第四章第八题ab

    这道题是利用OpenCV例子程序里自带的人脸检测程序,做点图像的复制操作以及alpha融合. 说明:人脸检测的程序我参照了网上现有的例子程序,没有用我用的OpenCV版本(2.4.5)的facedet ...

  8. 《学习OpenCV》练习题第四章第三题b

    #include <highgui.h> #include <cv.h> #include "opencv_libs.h" /* *<学习OpenCV ...

  9. 《学习OpenCV》练习题第四章第三题a

    #include <highgui.h> #include <cv.h> #include "opencv_libs.h" #pragma comment ...

随机推荐

  1. PHPStorm下XDebug配置

    PHPStorm下XDebug配置 分类: PHP2013-08-11 22:15 19697人阅读 评论(0) 收藏 举报   目录(?)[+]   1安装Xdebug 用yum安装可能会失败,用p ...

  2. /etc/hosts.conf

    一 作用       指定如何解析主机域名.可设置网络安全. 二 参数说明      默认情况,/etc/hosts.conf 文件有如下内容——      order hosts,bind     ...

  3. Asp.net 服务器Application,Session,Cookie,ViewState和Cache区别

    2.8 Context 的使用Context 对象包含与当前页面相关的信息,提供对整个上下文的访问,包括请求.响应.以及上文中的Session 和Application 等信息.可以使用此对象在网页之 ...

  4. 2.PHP内核探索:一次请求的开始与结束

    PHP开始执行以后会经过两个主要的阶段: 处理请求之前的开始阶段 请求之后的结束阶段 开始阶段有两个过程: 第一个过程是模块初始化阶段(MINIT), 在整个SAPI生命周期内(例如Apache启动以 ...

  5. Law of total probability

    https://en.wikipedia.org/wiki/Law_of_total_probability the total probability of an outcome which can ...

  6. WCF中自定义消息编码器:压缩编码器的使用

    通过抓包知道WCF在提交.返回数据的时候大多使用XML进行数据交互,如果返回DataTable那么这些数据将变得很大,通过查询找到一个对数据压缩的方法: http://msdn.microsoft.c ...

  7. Lazarus中Base64的操作

    在字符串处理中,我们经常需要对文件编码然后再进行传输,通常会使用base64编码,在FreePascal中默认集成了这个单元,我们来介绍如何使用: 首先需要在引用单元的时候使用: use base64 ...

  8. 原生js实现跑马灯抽奖效果

    目前好多的微信活动都有一些抽奖活动,其中就有跑马灯. <!DOCTYPE html> <html> <head> <title>跑马灯效果</ti ...

  9. 关于cocoa框架,你所要知道的一切(苹果官方文档,cocoa框架核心竞争力,必须收藏!)

    https://developer.apple.com/library/ios/documentation/General/Conceptual/DevPedia-CocoaCore/Accessib ...

  10. Android 环境快速搭建-详细步骤-win7-64bit

    电脑装了win7 64位的系统,重新来搭建了安卓环境,发现有一种非常便捷,快速的方法就可以搭建起来了~ 步骤一:下载java sdk 进入http://www.oracle.com/us/sun/in ...