您的位置:首页 > 其它

图像分割:K均值用于图像分割

2015-10-26 00:21 253 查看
K均值用于图像分割

聚类:将抽象对象的集合分成由多个相似的对象组成的多个子类的过程,常用聚类方法有:分裂法,层次法,基于密度的方法,基于网格的方法,基于模型的方法,K均值法。其中K均值法是一种基于距离的分裂法。
K均值算法是非常常用的一种聚类算法,用于将给定的样本集分成指定数目的聚类。具体算法如下:
·      为每个聚类确定一个初始的聚类中心,这样k个聚类存在k个聚类中心
·      将样本集中的每一个样本按照最小距离原则 分配到k个聚类中的某一个
·      使用每个聚类中所有样本的均值作为新的聚类中心
·      如果聚类中心有变化则重复2、3步直到聚类中心不再变化为止
·      最后得到的k个聚类中心就是聚类的结果
K均值算法是一种贪心算法,因而不一定能得到最优化结果,不过它是必定收敛的。
BOOLCDibImage::KmeansDIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight)

{

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

LPSTR lpDst;     // 指向缓存图像的指针 

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;

 }

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: