#include "opencv2/opencv.hpp"
#include <iostream>
#include <string>
using namespace cv;
using namespace std;
//这是Kmeans算法的一个缺点,在聚类之前需要指定类别个数
const int nClusters = 20;
int _tmain(int argc, _TCHAR* argv[])
{
Mat src; //相当于IplImage
// src = imread("fruit.jpg"); //只是另一张图
src = imread("zombie.jpg"); //cvLoadImage
imshow("original", src); //cvShowImage
blur(src, src, Size(11,11));
imshow("blurred", src);
//p是特征矩阵,每行表示一个特征,每个特征对应src中每个像素点的(x,y,r,g,b共5维)
Mat p = Mat::zeros(src.cols*src.rows, 5, CV_32F); //初始化全0矩阵
Mat bestLabels, centers, clustered;
vector<Mat> bgr;
cv::split(src, bgr); //分隔出src的三个通道
for(int i=0; i<src.cols*src.rows; i++)
{
p.at<float>(i,0) = (i/src.cols) / src.rows; // p.at<uchar>(y,x) 相当于 p->Imagedata[y *p->widthstep + x], p是8位uchar
p.at<float>(i,1) = (i%src.cols) / src.cols; // p.at<float>(y,x) 相当于 p->Imagedata[y *p->widthstep + x], p是32位float
p.at<float>(i,2) = bgr[0].data[i] / 255.0;
p.at<float>(i,3) = bgr[1].data[i] / 255.0;
p.at<float>(i,4) = bgr[2].data[i] / 255.0;
}
//计算时间
double t = (double)cvGetTickCount();
//kmeans聚类,每个样本的标签保存在bestLabels中
cv::kmeans(p, nClusters, bestLabels,
TermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, 1.0),
3, KMEANS_PP_CENTERS, centers);
t = (double)cvGetTickCount() - t;
float timecost = t/(cvGetTickFrequency()*1000);
//给每个类别赋颜色,其值等于每个类第一个元素的值
Vec3b colors[nClusters];
bool colormask[nClusters]; memset(colormask, 0, nClusters*sizeof(bool));
int count = 0;
for(int i=0; i<src.cols*src.rows; i++)
{
int clusterindex = bestLabels.at<int>(i,0);
for (int j=0; j<nClusters; j++)
{
if(j == clusterindex && colormask[j] == 0)
{
int y = i/src.cols;
int x = i%src.cols;
colors[j] = src.at<Vec3b>(y,x);
colormask[j] = 1;
count++;
break;
}
}
if(nClusters == count)break;
}
//显示聚类结果
clustered = Mat(src.rows, src.cols, CV_8UC3);
for(int i=0; i<src.cols*src.rows; i++) {
int y = i/src.cols;
int x = i%src.cols;
int clusterindex = bestLabels.at<int>(i,0);
clustered.at<Vec3b>(y, x) = colors[clusterindex];
}
imshow("clustered", clustered);
cout<< "time cost = %gms\n"<<timecost ;
//保存图像
stringstream s1,s2;
s1<<timecost;
s2<<nClusters;
string name = "n=" + s2.str() + "_timecost=" + s1.str() + ".png";
imwrite(name, clustered);
waitKey();
return 0;
}
Kmeans聚类
最新推荐文章于 2023-06-14 17:19:54 发布