OpenCV3.2图像分割 实例3:KMeans图像分割

发布时间 2023-08-18 09:00:17作者: 一杯清酒邀明月
 1 #include <opencv2/opencv.hpp>
 2 #include <iostream>
 3  
 4 using namespace cv;
 5 using namespace std;
 6  
 7 int main(int argc, char** argv) {
 8     Mat src = imread("toux.jpg");
 9     if (src.empty()) {
10         printf("could not load image...\n");
11         return -1;
12     }
13     namedWindow("input image", CV_WINDOW_AUTOSIZE);
14     imshow("input image", src);
15  
16     Scalar colorTab[] = {
17         Scalar(0, 0, 255),
18         Scalar(0, 255, 0),
19         Scalar(255, 0, 0),
20         Scalar(0, 255, 255),
21         Scalar(255, 0, 255)
22     };
23  
24     int width = src.cols;//图像的列
25     int height = src.rows;//图像的行
26     int dims = src.channels();//图像的通道数
27  
28     // 初始化定义
29     int sampleCount = width*height;//获取图像的像素点数
30     int clusterCount = 4;//要分类块数
31     Mat points(sampleCount, dims, CV_32F, Scalar(10));//定义样本数据
32     Mat labels;
33     Mat centers(clusterCount, 1, points.type());//定义中心点(浮点数)
34  
35     // RGB 数据转换到样本数据
36     int index = 0;
37     for (int row = 0; row < height; row++) {
38         for (int col = 0; col < width; col++) {
39             index = row*width + col;
40             Vec3b bgr = src.at<Vec3b>(row, col);
41             points.at<float>(index, 0) = static_cast<int>(bgr[0]);//通道0
42             points.at<float>(index, 1) = static_cast<int>(bgr[1]);//通道1
43             points.at<float>(index, 2) = static_cast<int>(bgr[2]);//通道2
44         }
45     }
46  
47     // 运行K-Means
48     TermCriteria criteria = TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 10, 0.1);
49     kmeans(points, clusterCount, labels, criteria, 3, KMEANS_PP_CENTERS, centers);//尝试3次
50  
51     // 显示图像分割结果
52     Mat result = Mat::zeros(src.size(), src.type());
53     for (int row = 0; row < height; row++) {
54         for (int col = 0; col < width; col++) {
55             index = row*width + col;
56             int label = labels.at<int>(index, 0);
57             result.at<Vec3b>(row, col)[0] = colorTab[label][0];
58             result.at<Vec3b>(row, col)[1] = colorTab[label][1];
59             result.at<Vec3b>(row, col)[2] = colorTab[label][2];
60         }
61     }
62  
63     for (int i = 0; i < centers.rows; i++) {
64         int x = centers.at<float>(i, 0);
65         int y = centers.at<float>(i, 1);
66         printf("center %d = c.x : %d, c.y : %d\n", i, x, y);
67     }
68     
69     imshow("KMeans Image Segmentation Demo", result);
70     waitKey(0);
71     return 0;
72 }

注:中心点是相对于图像RGB像素值而求定的位置。