#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
Mat srcImage = imread("C:/Users/11815/Desktop/微信图片_20200912152639.jpg");
if (!srcImage.data)
{
printf("could not load image...\n");
return -1;
}
VideoCapture capture;
namedWindow("mouse_pictures.png", 0);
imshow("mouse_pictures.png", srcImage);
//五个颜色,聚类之后的颜色随机从这里面选择
Scalar colorTab[] = {
Scalar(0,0,255),
Scalar(0,255,0),
Scalar(255,0,0),
Scalar(0,255,255),
Scalar(255,0,255) };
int width = srcImage.cols;//图像的宽
int height = srcImage.rows;//图像的高
int channels = srcImage.channels();//图像的通道数
//初始化一些定义
int sampleCount = width * height;//所有的像素
int clusterCount = 3;//分类数
Mat points(sampleCount, channels, CV_32F, Scalar(10));//points用来保存所有的数据
Mat labels;//聚类后的标签
Mat center(clusterCount, 1, points.type());//聚类后的类别的中心
//将图像的RGB像素转到到样本数据
int index;
for (int i = 0; i < srcImage.rows; i++) {
for (int j = 0; j < srcImage.cols; j++) {
index = i * width + j;
Vec3b bgr = srcImage.at<Vec3b>(i, j);
//将图像中的每个通道的数据分别赋值给points的值
points.at<float>(index, 0) = static_cast<int>(bgr[0]);
points.at<float>(index, 1) = static_cast<int>(bgr[1]);
points.at<float>(index, 2) = static_cast<int>(bgr[2]);
}
}
//运行K-means算法
//MAX_ITER也可以称为COUNT最大迭代次数,EPS最高精度,10表示最大的迭代次数,0.1表示结果的精确度 TermCriteria criteria = TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 10, 0.1); kmeans(points, clusterCount, labels, criteria, 3, KMEANS_PP_CENTERS, center);
//显示图像分割结果
Mat result = Mat::zeros(srcImage.size(), srcImage.type());//创建一张结果图
for (int i = 0; i < srcImage.rows; i++)
{
for (int j = 0; j < srcImage.cols; j++)
{
index = i * width + j;
int label = labels.at<int>(index);//每一个像素属于哪个标签
result.at<Vec3b>(i, j)[0] = colorTab[label][0];//对结果图中的每一个通道进行赋值 result.at<Vec3b>(i, j)[1] = colorTab[label][1];
result.at<Vec3b>(i, j)[2] = colorTab[label][2];
}
}
namedWindow("Kmeans", 0);
imshow("Kmeans", result);
waitKey(0);
return 0;
}
效果: