1、概述
案例:使用kmeans算法实现图像分割
kmeans算法参数介绍:
kmeans( InputArray data, int K, InputOutputArray bestLabels,
TermCriteria criteria, int attempts,
int flags, OutputArray centers = noArray() )
data:输入数据,此输入数据必须是CV_32F类型的
k:要分成几个类别
bestLabels:分类的标签(分成k类,那么就有k种类型的标签)
criteria:表示kmeans分割的停止条件
attempts:判断某个样本属于某个类别的最少聚类次数。例如:3代表此列别如果聚类了3此就说明它属于这个类别
flags:中心初始化方法
有三个值可选:
1.KMEANS_RANDOM_CENTERS 表示随机初始化簇心
2.KMEANS_PP_CENTERS 表示用kmeans++算法来初始化簇心
3.KMEANS_USE_INITIAL_LABELS 表示第一次聚类时用用户给定的值初始化聚类,后面几次的聚类,则自动确定簇心。
centers:表示最终分割后每个聚类的中心点位置
使用kmeans实现图像像素分割的步骤:
1.载入输入图像
2.得到图像的宽、高、通道数
3.创建一个CV_32F的的Mat用于存放样本数据(由于kmeans方法的输入数据必须是CV_32F类型的,而直接载入的图像数据是CV_8U类型的所以要经过一层转换)
4.将输入图像的RGB数据转换为 CV_32F的数据
5.使用kmeans算法开始给样本数量分类
6.显示图像分割后的结果
2、代码样例
//输入图像
Mat src = imread(filePath);
if(src.empty()){
qDebug()<<"图片为空";
return;
}
imshow("src",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图片数据转换为样本数据,因为kmeans要求输入的样本数据为CV_32F类型的
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]);
points.at<float>(index,1) = static_cast<int>(bgr[1]);
points.at<float>(index,2) = static_cast<int>(bgr[2]);
}
}
//使用KMeans分类
TermCriteria criteria = TermCriteria(TermCriteria::EPS+TermCriteria::COUNT,10,0.1);
kmeans(points,clusterCount,labels,criteria,3,KMEANS_PP_CENTERS,centers);
//显示图像分割后的结果
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];
}
}
imshow("result",result);
QT开发交流君羊:714620761