HCM硬性K均值聚类算法 C++实现 【字幕检测、车牌识别】

新博客地址:http://gorthon.sinaapp.com/

最初写的乱七八糟的代码,当初没有用STL,哎。

/***********************************************************************
						                                 HCM聚类算法:
feature[]为样本点向量//个数 = dimension * numfeature = 256*6
dimension是每个样本的维数//6
numpattern是样本的个数//256
K是要分类的数目//2(字幕/非字幕2类)
maxcycle是最大循环次数//1000
result[]为输出的划分矩阵,个数 = numfeature * K = 256*2 
***********************************************************************/
double* hcm(double feature[], int dimension, int numfeature, int K, int maxcycle, double result[])
{
    double *center = new double[K*dimension];//输出的样本的聚类中心向量,大小K*dimension=2*6
    int i, j;
	//选取初始迭代点作为初始的聚类中心。
   for(j=0;j<K;j++)
   {
	   int selnum=j*int(numfeature/K);//128j,将pattern均分为K份
	   for(i=0;i<dimension;i++)
		   center[j*dimension+i]=feature[selnum*dimension+i];
   }
   /***********************************************************************
   center[0] = feature[0]   center[1] = feature[1]   center[2] = feature[2] 
   center[3] = feature[3]   center[4] = feature[4]  center[5] = feature[5] 
   center[6] = feature[128*6]                  center[7] = feature[128*6+1] 
   center[8] = feature[128*6+2]                  center[9] = feature[128*6+3] 
   center[10] = feature[128*6+4]                 center[11] = feature[128*6+5] 
   ***********************************************************************/

   //开始主循环
   int cycle = 0;//循环次数
   int changed = 1;//中心是否变化了
   double min_dis = 0.001;//距离的最小值

   double *x = new double[dimension];//x[6]
   double *c0 = new double[dimension];//c0[6],字幕类中心
   double *c1 = new double[dimension];//c1[6],非字幕类中心
   double *temp = new double[numfeature];//temp[256]记录每一块属于哪一类(分为0类和1类)

   while(cycle < maxcycle && changed == 1)
   {
	   cycle++;
	   int N0 = 0, N1 = 0;//记录0,1类的块数
	   for (i=0; i<numfeature; i++)//第 i 子块
	   {
		   for (j=0; j<dimension; j++)
		   {
			   x[j] = feature[i*dimension+j];//第 0 块的6个值给x
			   c0[j] = center[j];//将center分为c0及c1两个中心
			   c1[j] = center[j+dimension];//c0 : 初始为第0块; c1 : 初始为第128块
		   }
		   double d1 = distance(x, c0, dimension);//第 0 块与中心c0的距离
		   double d2 = distance(x, c1, dimension);//第 0 块与中心c1的距离
			if(d1<d2)
			{
				temp[i] = 0;
				N0++;
			}
			else 
			{
				temp[i] = 1;
				N1++;
			}
	   }//end for i
	   //计算新的聚类中心:
	   double *c02 = new double[dimension];//c02[6]新的聚类中心
	   double *c12 = new double[dimension];//c12[6]

	   for (i = 0; i<dimension; i++)
		   c02[i] = c12[i] = 0;

	   for (i=0; i<numfeature; i++)//第 i 子块
		   if(temp[i] == 0)
			   for (j=0; j<dimension; j++)
				   c02[j] += feature[i*dimension+j];
		   else
			   for (j=0; j<dimension; j++)
				   c12[j] += feature[i*dimension+j];

		if(N0 == 0)N0 = 1;
		if(N1 == 0)N1 = 1;
		for (i = 0; i<dimension; i++)
		{
			c02[i] /= N0;
			c12[i] /= N1;
		}

		for (i = 0; i<dimension; i++)//比较中心是否变化
			if (fabs(c02[i] - c0[i]) > 0.1||fabs(c12[i] - c1[i]) > 0.1)
				changed = 1;
			else
				changed = 0;

		if (changed == 1)//变化了就计算新的聚类中心
			for (i = 0; i<dimension; i++)
			{
				center[i] = c02[i];
				center[i+dimension] = c12[i];
			}
   }//end while
   for(i = 0; i<numfeature; i++)//将结果整理并放入result向量中
   {
	   result[i] = temp[i];
	   result[i+numfeature] = temp[i];
   }
   return center;
}

效果图:


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值