opencv+c++实现Kmeans聚类算法分割

1,937 阅读1分钟

#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; 

 }

效果: