OpenCV图像分割资料分享:贾志刚的OpenCV图像分割实战视频教程全套资料(包含配套视频、配套PPT的PDF文件、源码和用到的图片素材等)
实例3:KMeans图像分割
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
Mat src = imread("toux.jpg");
if (src.empty()) {
printf("could not load image...\n");
return -1;
}
namedWindow("input image", CV_WINDOW_AUTOSIZE);
imshow("input image", src);
Scalar colorTab[] = {
Scalar(0, 0, 255),
Scalar(0, 255, 0),
Scalar(255, 0, 0),
Scalar(0, 255, 255),
Scalar(255, 0, 255)
};
int width = src.cols;//图像的列
int height = src.rows;//图像的行
int dims = src.channels();//图像的通道数
// 初始化定义
int sampleCount = width*height;//获取图像的像素点数
int clusterCount = 4;//要分类块数
Mat points(sampleCount, dims, CV_32F, Scalar(10));//定义样本数据
Mat labels;
Mat centers(clusterCount, 1, points.type());//定义中心点(浮点数)
// RGB 数据转换到样本数据
int index = 0;
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
index = row*width + col;
Vec3b bgr = src.at<Vec3b>(row, col);
points.at<float>(index, 0) = static_cast<int>(bgr[0]);//通道0
points.at<float>(index, 1) = static_cast<int>(bgr[1]);//通道1
points.at<float>(index, 2) = static_cast<int>(bgr[2]);//通道2
}
}
// 运行K-Means
TermCriteria criteria = TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 10, 0.1);
kmeans(points, clusterCount, labels, criteria, 3, KMEANS_PP_CENTERS, centers);//尝试3次
// 显示图像分割结果
Mat result = Mat::zeros(src.size(), src.type());
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
index = row*width + col;
int label = labels.at<int>(index, 0);
result.at<Vec3b>(row, col)[0] = colorTab[label][0];
result.at<Vec3b>(row, col)[1] = colorTab[label][1];
result.at<Vec3b>(row, col)[2] = colorTab[label][2];
}
}
for (int i = 0; i < centers.rows; i++) {
int x = centers.at<float>(i, 0);
int y = centers.at<float>(i, 1);
printf("center %d = c.x : %d, c.y : %d\n", i, x, y);
}
imshow("KMeans Image Segmentation Demo", result);
waitKey(0);
return 0;
}
注:中心点是相对于图像RGB像素值而求定的位置。