使用OpenCV的kmeans实现图像分割
一、概述
案例:使用kmeans算法实现图像分割
1 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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.显示图像分割后的结果
二、代码样例
//输入图像 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);
三、示例图片
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
2015-04-10 fragment The specified child already has a parent. You must call removeView()