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像素值而求定的位置。