图像分割: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;
}
聚类:将抽象对象的集合分成由多个相似的对象组成的多个子类的过程,常用聚类方法有:分裂法,层次法,基于密度的方法,基于网格的方法,基于模型的方法,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;
}
相关文章推荐
- HTTP请求之两种方式
- [深入理解Java虚拟机]第八章 字节码执行引擎-方法调用
- Android核心分析
- 重新拾起刷题- 明明的随机数
- python学习记录之_1025
- 20151024_003_C#基础知识(File / FileStream / StreamReader/StreamWriter)
- MFC 简单实现 DES 算法
- zufe 1926: sailspark的奇怪癖好 (set的使用,好题 STL)
- android之存储篇_SQLite数据库_让你彻底学会SQLite的使用
- Web_PHP_数组排序、查找算法;
- Codeforces Round #327 (Div. 2)B. Rebranding
- php将图片以二进制保存到mysql数据库并显示
- zf-关于更换页面,的各种问题。
- 活动的最佳实践(知晓当前是在哪一个活动,随时随地退出程序,启动活动的最佳写法)
- requestWindowFeature()的应用
- Codeforces Round #327 (Div. 2)A. Wizards' Duel
- atomic && nonatomic那些事儿
- ios开发中button控件的属性及常见问题
- javascript基本使用 11 ------垃圾收集和块级作用域
- 遥望布达拉——DAY2 雅安-新沟