[OpenCV+VS2015]Kmeans颜色聚类算法(路牌检测程序)

[OpenCV+VS2015]Kmeans颜色聚类算法(路牌检测程序)

学到kmeans了,然后做个最简单的路牌颜色检测验证一下算法效果。不使用Opencv里的API了,自己编一个算法试试看效果。提供给大家一个思路

本人也是小白萌新,很多想法并不成熟,如果有错误,欢迎指正!

1 Kmeans算法介绍

传送门几篇很牛逼的Kmeans算法介绍:
一、【机器学习】K-Means算法的原理流程、代码实现及优缺点
二、k-means 的原理,优缺点以及改进
三、KMeans 算法(一)
简单来说呢,这是一种用于图像分割的算法。

K-Means聚类的步骤是
(1)设定需要聚类数目k,然后在数据点空间里随机选取k个点,称为簇心。
(2)遍历空间所有的数据点,计算每个点到这k个簇心的欧氏距离,找到距离该点最近的簇心,把这个点归到对应的簇中。最后所有的数据点都会被归类到 k个簇中。
(3)针对每一类簇,计算簇中所有数据的点的重心(平均距离中心),作为该簇新的簇心。最后每一类簇都会得到新的簇心。
(4)重复步骤(2)(3),直到达到某个终止条件,遍可以终止迭代。

需要注意的是,终止条件可以有很多,比如:迭代的次数、簇中心的变化率,所有点的最小均方差等,总之达到终止条件的时候,聚类应该基本完成。

在这里插入图片描述
最后多次迭代,这个中心点就不怎么动了,就停在这一类里了,然后两类自然而然就分离开了
在这里插入图片描述

2 算法代码

2.1 kmeans聚类代码

根据k的个数,在图片中选取k个聚类簇心的初始点。选取的方法很简单:我取了图片中间一行的像素点,将这一行像素点平均分成k份,从而均匀取得k个点作为初始点

将选取的聚类点的RGB三通道的值分别存储到对应的数组之中,接着执行之前所属的(2)(3)步骤:遍历图片所有像素点,计算每个像素点到这k个簇心的RGB距离,找到RGB距离最近的簇心,将这个点归到这一簇类中。之后重新计算新的簇心点,计算的方法就是把同一簇下的像素点R、G、B分量分别相加求和,然后除以这一簇类所有点的个数,得到平均值。

需要注意的是得到的新平均值RGB分量可能带有小数,需要对它int化。
这样经过多次迭代,我们就能将所有点进行聚类,颜色相近的点会被归到一类里。

void RGB_kmeans(Image &src, Image &dst )
{
   
	int i, j, s, it,t,pos;
	double diff;
    double mindiff = _mindiff;
	int Maxitr = _Maxitr;

	assert(!src.empty());
	for (i = 1; i < src.size(); i++) {
   
		assert(src[i].size() == src[0].size());
	}

	int rows = src.size();
	int cols = src[0].size();

	Mat cluster(src.size(), src[0].size(), CV_8UC1);
	dst.clear();

	double temp = src.size() / k;
	if (temp < 1||temp<0)
	{
     
		printf("the input 'k' error.please try again!");
	}

	int interval = (src.size() - src.size() % k) / k;
	int krow[k] = {
   0};
	int kcol[k] = {
   0};

	int kr[k];
	int kg[k];
	int kb[k];
	double fact_kr[k];
	double fact_kg[k];
	double fact_kb[k];
	int pre_kr[k];
	int pre_kg[k];
	int pre_kb[k]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值