使用OpenCV的kmeans实现图像分割
Opencv 实现 图像 分割 Kmeans 使用
2023-09-14 09:05:26 时间
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);
3、示例图片
本文福利,莬费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击莬费领取↓↓
相关文章
- OpenCV每日函数 图像过滤模块 (2) blur函数(归一化框滤波)
- OpenCV使用EigenFaceRecognizer来实现人脸识别
- OpenCV使用filter2D实现图像对比度提升
- opencv-python实现马赛克油画漫画风格的图片
- C++ opencv之实现多个视频拼接播放(亲测可用)
- OpenCV鼠标滑轮事件
- 《学习opencv》笔记——矩阵和图像处理——cvAnd、cvAndS、cvAvg and cvAvgSdv
- Opencv Mat运算(转)
- 在OpenCV里实现计算图像信息熵
- 在OpenCV里实现模板匹配
- 在OpenCV里实现直方图反向投影算法
- 在OpenCV里实现极坐标变换1
- 在OpenCV里实现极坐标变换5
- 在OpenCV里实现全局阈值分割2
- 在OpenCV里实现霍夫直线检测2
- 在OpenCV里实现视频格式转换
- Opencv项目实战:11 使用Opencv高亮显示文本检测
- 【OpenCV 例程200篇】77. OpenCV 实现快速傅里叶变换
- 【OpenCV 例程200篇】76. OpenCV 实现图像傅里叶变换
- 【OpenCV 例程200篇】75. Numpy 实现图像傅里叶变换
- Python-OpenCV图像处理-10-直方图的操作
- opencv-python处理图片的一些列操作
- Python - Opencv应用实例之头发自动分割、计数、特征统计智能分析系统
- Opencv从入门到精通(五):透视图、拼接图片、颜色检测
- OpenCV-Python实战(5) —— OpenCV 使用cv.setMouseCallback实现截图功能