K均值用于图像分割

来源:互联网 发布:sql server 查询 一样 编辑:程序博客网 时间:2024/05/08 01:28

K均值聚类用于图像分割


       聚类:将抽象对象的集合分成由多个相似的对象组成的多个子类的过程,常用聚类方法有:分裂法,层次法,基于密度的方法,基于网格的方法,基于模型的方法,K均值法。其中K均值法是一种基于距离的分裂法。

K均值算法是非常常用的一种聚类算法,用于将给定的样本集分成指定数目的聚类。具体算法如下:

·      为每个聚类确定一个初始的聚类中心,这样k个聚类存在k个聚类中心

·      将样本集中的每一个样本按照最小距离原则 分配到k个聚类中的某一个

·      使用每个聚类中所有样本的均值作为新的聚类中心

·      如果聚类中心有变化则重复2、3步直到聚类中心不再变化为止

·      最后得到的k个聚类中心就是聚类的结果

K均值算法是一种贪心算法,因而不一定能得到最优化结果,不过它是必定收敛的。

BOOLCDibImage::KmeansDIB(LPSTRlpDIBBits, LONG lWidth, LONG lHeight)

{

LPSTRlpSrc;    // 指向源图像的指针 

LPSTRlpDst;     // 指向缓存图像的指针 

LPSTR lpNewDIBBits;   // 指向缓存DIB图像的指针

HLOCAL hNewDIBBits;

LONG lLineBytes;   // 图像每行的字节数

long i,j,k,order =0,temp=255;      // 循环变量

unsigned char pixel;   //像素值

lLineBytes = WIDTHBYTES(lWidth *8);

int N = 5;

long kNum[5];

int kAver[5];

int kOldAver[5];

int kSum[5];

int KTemp[5];

for( i =0;i < N; i++ )

{

   kAver[i] = kOldAver[i]= i * 255 / (N - 1);

}

for( i =0; i < N; i++ )

{

   kAver[i] =kOldAver[i];

   kNum[i] = 0;

   kSum[i] = 0;

}

hNewDIBBits= LocalAlloc( LHND,lLineBytes * lHeight );

if( hNewDIBBits ==NULL )

{

   return FALSE;

}

lpNewDIBBits = (char *)LocalLock(hNewDIBBits );

lpDst = (char *)lpNewDIBBits;

memset(lpDst, (BYTE)255, lLineBytes* lHeight);

for (j =0; j < lHeight;j++)

{

   for(i = 0; i <lWidth ;i++)

   {

    // 指向源图像倒数第j行,第i个象素的指针   

    lpSrc = (char*)lpDIBBits + lLineBytes * j +i;   

    //取得当前指针处的像素值,注意要转换为unsigned char型

    pixel =(unsigned char)*lpSrc;

    for( k = 0; k< N; k++)

    {

     KTemp[k] =abs( pixel - kAver[k] );

    }

    temp = 255;

    for( k = 0; k< N; k++ )

    {

     if(KTemp[k] < temp )

     {

      temp= KTemp[k];

     order = k;

     }

    }

    kNum[order]++;

    kSum[order] +=pixel;

   

    *lpSrc =(unsigned char)order;

   }

}

for( i = 0; i < N; i++)

{

   if( kNum[i] != 0 )

   {

    kOldAver[i] =kSum[i] / kNum[i];

   }

}

 

k = 0;

for( i = 0; i < N; i++)

{

   if( kAver[i] ==kOldAver[i] )

    k++;

   if(k = N)

   {

    break;

   }

}

/////////////////////////////////////////////////////

   

for (j = 0; j < lHeight;j++)

{

   for(i = 0; i <lWidth ;i++)

   {

     lpSrc = (char *)lpDIBBits + lLineBytes * j + i;

    lpDst = (char*)lpNewDIBBits + lLineBytes * j + i; 

    for( k = 0; k< N; k++ )

    {

     if( *lpSrc== k )

     {

     *lpDst = kAver[k];

     }

    }

  

   }

}

   memcpy(lpDIBBits,lpNewDIBBits,lHeight*lWidth);

 return TRUE;

 }

0 0
原创粉丝点击