VC++ K-Means 图像二值化

K-MEANS算法的工作原理及流程
K-MEANS算法:
输入:聚类个数k,以及包含 n个数据对象的数据库。
输出:满足方差最小标准的k个聚类

处理流程

(1) 从 n个数据对象任意选择 k 个对象作为初始聚类中心;
(2) 根据每个聚类对象的均值(中心对象),计算每个对象与这些中心对象的距离;并根据最小距离重新对相应对象进行划分;
(3) 重新计算每个(有变化)聚类的均值(中心对象)
(4) 循环(2)到(3)直到每个聚类不再发生变化为止
k-means 算法接受输入量 k ;然后将n个数据对象划分为 k个聚类以便使得所获得的聚类满足:同一聚类中的对象相似度较高;而不同聚类中的对象相似度较小。聚类相似度是利用各聚类中对象的 均值所获得一个“中心对象”(引力中心)来进行计算的。
工作过程k-means 算法的工作过程
说明如下:首先从n个数据对象任意选择 k 个对象作为初始聚类中心;而对于所剩下其它对象,则根据它们与这些聚类中心的相似度(距离),分别将它们分配给与其最相似的(聚类中心所代表的)聚类;然 后再计算每个所获新聚类的聚类中心(该聚类中所有对象的均值);不断重复这一过程直到标准测度函数开始收敛为止。一般都采用均方差作为标准测度函数。k个聚类具有以下特点:各聚类本身尽可能的紧凑,而各聚类之间尽可能的分开。
K-MEANS 二值化,把图像分成两类,设置中心(随机选择中心点像素值, rand()%256
8位灰度图像   center1 =rand()%256, center2 =rand()%256
计算各像素点到中心聚类的距离,并根据最小距离重新对相应对象进行划分,重新计算每个(有变化)聚类的均值(中心对象),循环直到每个聚类不再发生变化为止。 VC++ K-Means 图像二值化_第1张图片
void CShowPicView::OnKmeans() 
{
	CShowPicDoc* pDoc = GetDocument();
	CDC* pDC=GetDC();
	srand((unsigned int)time(NULL));
	int center1=rand()%256,center2=rand()%256, distance1 = 0,distance2 =0;
	int temp_center1 =0,temp_center2=0;
	int i=0,j=0;
	bool convergence = 1;
	do{
		double center1_count = 0,center2_count = 0, count1 = 0, count2 = 0;
		for(j = 0; j < intHeight; j++)//将图像中各像素值及特征读取出来
		{
			for(i = 0; i < intWidth; i++)
			{
				distance1 = abs(center1-Data[j][i]);
				distance2 = abs(center2-Data[j][i]);
				if(distance1
     
       abs(center2-Data[j][i]) ? pDC->SetPixel(i+intWidth,j,RGB(255,255,255)) : pDC->SetPixel(i+intWidth,j,RGB(0,0,0));
	
	delete pDoc;
	ReleaseDC(pDC);
	pDoc = NULL;
	pDC  = NULL;
}
     
24位彩色度图像   center1 (R_center1, G_center1, B_center1),  center2 R_center2 G_center2 B_center2
计算各像素点到中心聚类的距离,并根据最小距离重新对相应对象进行划分,重新计算每个(有变化)聚类的均值(中心对象),循环直到每个聚类不再发生变化为止。
VC++ K-Means 图像二值化_第2张图片
void CShowPicView::OnKMeansImageSegmentation() 
{
	CShowPicDoc* pDoc = GetDocument();
	CDC* pDC=GetDC();
	srand((unsigned int)time(NULL));

	int R_center1=rand()%256,R_center2=rand()%256;
	int G_center1=rand()%256,G_center2=rand()%256;
	int B_center1=rand()%256,B_center2=rand()%256;	
	int R_temp_center1 =0,R_temp_center2=0;
	int G_temp_center1 =0,G_temp_center2=0;
	int B_temp_center1 =0,B_temp_center2=0;
	int i=0,j=0;
	double	distance1 = 0,distance2 =0;	
	bool convergence = 1;
	do{
		double R_center1_count = 0, R_center2_count = 0, R_count1 = 0, R_count2 = 0;
		double G_center1_count = 0, G_center2_count = 0, G_count1 = 0, G_count2 = 0;
		double B_center1_count = 0, B_center2_count = 0, B_count1 = 0, B_count2 = 0;
		//pDC->SetPixel(x,y,RGB(pDoc->pic[y][x][0],pDoc->pic[y][x][1],pDoc->pic[y][x][2]));
		for(j = 0; j < intHeight; j++)//将图像中各像素值及特征读取出来
		{
			for(i = 0; i < intWidth; i++)
			{
				distance1 = sqrt( pow((R_center1-pDoc->pic[j][i][0]),2)+pow((G_center1-pDoc->pic[j][i][1]),2)+pow((B_center1-pDoc->pic[j][i][2]),2) ); 
				distance2 = sqrt( pow((R_center2-pDoc->pic[j][i][0]),2)+pow((G_center2-pDoc->pic[j][i][1]),2)+pow((B_center2-pDoc->pic[j][i][2]),2) );
				if(distance1
    
     pic[j][i][0];   R_count1++;
					G_center1_count+=pDoc->pic[j][i][1];   G_count1++;
					B_center1_count+=pDoc->pic[j][i][2];   B_count1++;
				}
				else{
					R_center2_count+=pDoc->pic[j][i][0];   R_count2++;
					G_center2_count+=pDoc->pic[j][i][1];   G_count2++;
					B_center2_count+=pDoc->pic[j][i][2];   B_count2++;
				}
			}
		}
		R_temp_center1 = int(R_center1_count/R_count1);		R_temp_center2 = int(R_center2_count/R_count2);
		G_temp_center1 = int(G_center1_count/G_count1);		G_temp_center2 = int(G_center2_count/G_count2);
		B_temp_center1 = int(B_center1_count/B_count1);		B_temp_center2 = int(B_center2_count/B_count2);
		if(	  abs(R_temp_center1-R_center1)<0.1&&abs(R_temp_center2-R_center2)<0.1
			&&abs(G_temp_center1-G_center1)<0.1&&abs(G_temp_center2-G_center2)<0.1
			&&abs(B_temp_center1-B_center1)<0.1&&abs(B_temp_center2-B_center2)<0.1)
			convergence = 0;
		else
		{
			R_center1 = R_temp_center1;			R_center2 = R_temp_center2;
			G_center1 = G_temp_center1;			G_center2 = G_temp_center2;
			B_center1 = B_temp_center1;			B_center2 = B_temp_center2;
		}

	}while(convergence);

	for(j = 0; j < intHeight; j++)//将图像中各像素值及特征读取出来
		for(i = 0; i < intWidth; i++)
		{
			distance1 = sqrt( pow((R_center1-pDoc->pic[j][i][0]),2)+pow((G_center1-pDoc->pic[j][i][1]),2)+pow((B_center1-pDoc->pic[j][i][2]),2) ); 
			distance2 = sqrt( pow((R_center2-pDoc->pic[j][i][0]),2)+pow((G_center2-pDoc->pic[j][i][1]),2)+pow((B_center2-pDoc->pic[j][i][2]),2) );
			distance1 > distance2 ? pDC->SetPixel(i+intWidth,j,RGB(255,255,255)) : pDC->SetPixel(i+intWidth,j,RGB(0,0,0));
		}
	delete pDoc;
	ReleaseDC(pDC);
	pDoc = NULL;
	pDC  = NULL;
}

    
24位彩色度图像  ,分别对三通道的颜色R,G,B做单通道聚类,每通道二值化,结果会产生最多8个聚类结果。
 (R_center1,R_center2 ,(G_center1,G_center2   ,(B_center1 ,B_center2 VC++ K-Means 图像二值化_第3张图片
void CShowPicView::OnKMeansimagesegmentation() 
{
	CShowPicDoc* pDoc = GetDocument();
	CDC* pDC=GetDC();
	srand((unsigned int)time(NULL));
	int R_center1=rand()%256,R_center2=rand()%256;
	int G_center1=rand()%256,G_center2=rand()%256;
	int B_center1=rand()%256,B_center2=rand()%256;		
	int R_temp_center1 =0,R_temp_center2=0;
	int G_temp_center1 =0,G_temp_center2=0;
	int B_temp_center1 =0,B_temp_center2=0;
	int i=0,j=0;
	int	distance1 = 0,distance2 =0;	
	bool convergence = 1;
	do{
		double R_center1_count = 0, R_center2_count = 0, R_count1 = 0, R_count2 = 0;
		double G_center1_count = 0, G_center2_count = 0, G_count1 = 0, G_count2 = 0;
		double B_center1_count = 0, B_center2_count = 0, B_count1 = 0, B_count2 = 0;
		//pDC->SetPixel(x,y,RGB(pDoc->pic[y][x][0],pDoc->pic[y][x][1],pDoc->pic[y][x][2]));
		for(j = 0; j < intHeight; j++)//将图像中各像素值及特征读取出来
		{
			for(i = 0; i < intWidth; i++)
			{
				distance1 = abs(R_center1-pDoc->pic[j][i][0]); distance2 = abs(R_center2-pDoc->pic[j][i][0]);
				if(distance1
    
     pic[j][i][0];   R_count1++;
				}
				else{
					R_center2_count+=pDoc->pic[j][i][0];   R_count2++;
				}

				distance1 = abs(G_center1-pDoc->pic[j][i][1]); distance2 = abs(G_center2-pDoc->pic[j][i][1]);
				if(distance1
     
      pic[j][i][1];   G_count1++;
				}
				else{
					G_center2_count+=pDoc->pic[j][i][1];   G_count2++;
				}

				distance1 = abs(B_center1-pDoc->pic[j][i][2]); distance2 = abs(B_center2-pDoc->pic[j][i][2]);
				if(distance1
      
       pic[j][i][2];   B_count1++;
				}
				else{
					B_center2_count+=pDoc->pic[j][i][2];   B_count2++;
				}
			}
		}
		R_temp_center1 = int(R_center1_count/R_count1);		R_temp_center2 = int(R_center2_count/R_count2);
		G_temp_center1 = int(G_center1_count/G_count1);		G_temp_center2 = int(G_center2_count/G_count2);
		B_temp_center1 = int(B_center1_count/B_count1);		B_temp_center2 = int(B_center2_count/B_count2);
		if(	  abs(R_temp_center1-R_center1)<0.1&&abs(R_temp_center2-R_center2)<0.1
			&&abs(G_temp_center1-G_center1)<0.1&&abs(G_temp_center2-G_center2)<0.1
			&&abs(B_temp_center1-B_center1)<0.1&&abs(B_temp_center2-B_center2)<0.1)
			convergence = 0;
		else
		{
			R_center1 = R_temp_center1;			R_center2 = R_temp_center2;
			G_center1 = G_temp_center1;			G_center2 = G_temp_center2;
			B_center1 = B_temp_center1;			B_center2 = B_temp_center2;
		}

	}while(convergence);
	int temp1=0,temp2=0,temp3=0;
	for(j = 0; j < intHeight; j++)//将图像中各像素值及特征读取出来
		for(i = 0; i < intWidth; i++)
		{
			distance1 = abs(R_center1-pDoc->pic[j][i][0])+abs(G_center1-pDoc->pic[j][i][1])+abs(B_center1-pDoc->pic[j][i][2]); 
			distance2 = abs(R_center2-pDoc->pic[j][i][0])+abs(G_center2-pDoc->pic[j][i][1])+abs(B_center2-pDoc->pic[j][i][2]);
			distance1 > distance2 ? pDC->SetPixel(i+2*intWidth,j,RGB(255,255,255)) : pDC->SetPixel(i+2*intWidth,j,RGB(0,0,0));
			abs(R_center1-pDoc->pic[j][i][0])>abs(R_center2-pDoc->pic[j][i][0]) ? temp1=255 : temp1=0 ;
			abs(G_center1-pDoc->pic[j][i][1])>abs(G_center2-pDoc->pic[j][i][1]) ? temp2=255 : temp2=0 ;
			abs(B_center1-pDoc->pic[j][i][2])>abs(B_center2-pDoc->pic[j][i][2]) ? temp3=255 : temp3=0 ;
			pDC->SetPixel(i+intWidth,j,RGB(temp1,temp2,temp3));
		}

//	delete pDoc;
//	ReleaseDC(pDC);
//	pDoc = NULL;
//	pDC  = NULL;
}
      
     
    

https://github.com/wukai0909/Image-Processing-Segmentation/tree/master

你可能感兴趣的:(vc++,图像处理)