本章内容
1. 获取颜色特征集合
2. K均值聚类
3. 显示聚类结果
1. 获取颜色特征集合
2.k均值聚类
输出结果:
3. 绘制聚类结果:
输出结果:
源码
//#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;
}