(五)OpenCV图像分割_03_GMM(高斯混合模型)数据分类_机器学习

这篇博客探讨了如何使用OpenCV进行图像分割,重点在于高斯混合模型(GMM)的数据分类。介绍了GMM的原理,包括高斯分布和概率密度分布,以及它与K-Means的区别——GMM采用软分类。文章还详细阐述了GMM的期望最大化(E-M)实现方法和停止条件,并讨论了模型的训练和预测过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. 数据聚类
    图像分类
  2. 高斯混合模型(GMM)
    高斯分布与概率密度分布(PDF)
    初始化
  3. 跟K-Means相比较,属于软分类(随机概率)
    实现方法:期望最大化(E-M)
    停止条件:收敛
  4. 样本数据训练与预言
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace std;
using namespace cv;
using namespace cv::ml;

int main(int argc, char** argv)
{
	Mat src(500, 500, CV_8UC3);
	RNG rng;//随机数产生器

	const int MAX_CLUSTERS = 5; //最大聚类数目
	
	Scalar color[] =
	{
		Scalar(0,0,255),
		Scalar(0,255,0),
		Scalar(255,0,0),
		Scalar(0,255,255),
		Scalar(255,0,255),
	};

	//分类
	int clusterCount = rng.uniform(2, MAX_CLUSTERS);
	cout << "number of clusters聚类数目 :" << clusterCount << endl;

	int sampleCount = rng.uniform(5, 1001);
	cout << "number of sampleCount采样点数目 :" << sampleCount << endl;

	Mat points(sampleCount, 2, CV_32FC1);//存放样本点//2维
	//Mat centers(clusterCount, 1, points.type());//用来存储聚类后的中心点

	Mat labels;//标注

	// 生成随机数
	for (int i = 0; i < clusterCount; i++)
	{
		Point center;//均匀随机产生初始化聚类中心
		center.x = rng.uniform(0, src.cols);
		center.y = rng.uniform(0, src.rows);
		Mat pointChunk = points.rowRange(i * sampleCount / clusterCount,
										i == clusterCount - 1 ? sampleCount : (i + 1)*sampleCount / clusterCount);
		rng.fill(pointChunk, RNG::NORMAL, Scalar(center.x, center.y), Scalar(src.cols*0.05, src.rows*0.05));
	}

	randShuffle(points, 1, &rng);//随机打乱points里面的样本点

	//GMM高斯混合模型
	Ptr<EM> em_model = EM::create(); //ml库中机器学习算法
	em_model->setClustersNumber(clusterCount);//聚成clusterCount类
	em_model->setCovarianceMatrixType(EM::COV_MAT_SPHERICAL);//设置协方差矩阵类型
	em_model->setTermCriteria(TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 100, 0.1));//指定要运行算法的最大迭代次数
	//训练分类器
	em_model->trainEM(points, //samples输入的样本,一个单通道的矩阵。从这个样本中,进行高斯混和模型估计。
					  noArray(), //可选项,输出一个矩阵,里面包含每个样本的似然对数值。
					  labels,//可选项,输出每个样本对应的标注。
					  noArray());//可选项,输出一个矩阵,里面包含每个隐性变量的后验概率

	//对每个坐标点进行分类,并根据类别用不同的颜色画出
	Mat sample(1, 2, CV_32FC1);
	for (int row = 0; row < src.rows; row++) 
	{
		for (int col = 0; col < src.cols; col++)
		{
			sample.at<float>(0) = (float)col;
			sample.at<float>(1) = (float)row;
			//predict2返回的是double值,用cvRound进行四舍五入得到整型
			//此处返回的是两个值Vec2d,取第二个值作为样本标注
			//https://blog.youkuaiyun.com/qq_30815237/article/details/86353405
			int response = cvRound(em_model->predict2(sample, noArray())[1]);
			Scalar c = color[response];//为不同类别设定颜色
			circle(src, Point(col, row), 1, c*0.75, -1);
		}
	}

	//画出样本点
	for (int i = 0; i < sampleCount; i++) 
	{
		Point p(cvRound(points.at<float>(i, 0)), points.at<float>(i, 1));
		circle(src, p, 1, color[labels.at<int>(i)], -1);
	}

	imshow("高斯混合模型EM", src);

	waitKey(0);
	return 0;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值