基于VC的最大类间方差(Otsu)方法分割图像
该程序所用的算法: 大津阈值分割算法(OTSU处理图像)
算法描述:
void Otsu(void)
{
float TCandidate[256]={0},TC=0,T=0;
int i,j,k=0;
float w0=0,w1=0;
float u0=0,u1=0;
for(k=0;k<=255;k++)//get Best T
{
u0=0;u1=0;w0=0;w1=0;
for(i=0;i<N;i++)
{
for(j=0;j<M;j++)
{
if(image[i][j]<=k)
{
w0++;//front
u0+=image[i][j];
}
else
{
w1++;//background
u1+=image[i][j];
}
}
}
u0/=w0;
u1/=w1;
w0/=(M*N);
w1/=(M*N);
TCandidate[k]=w0*w1*pow(u0-u1,2);
}
for(i=0;i<256;i++)//find the best threshold value
{
if(TCandidate[i]>=TC)
{
TC=TCandidate[i];
T=i;
}
else
continue;
}
for(i=0;i<N;i++)
{
for(j=0;j<M;j++)
{
if(image[i][j]<=T)
imageT[i][j]=0;
else
imageT[i][j]=255;
}
}
for(i=1;i<N;i++)
for(j=1;j<M;j++)
image[i][j]=imageT[i][j];
}`
Otsu算法与固定阈值分割算法的对比:
固定阈值分割算法的C语言实现:
在这里我随意选定了一个灰度阈值:100。
void SThresholdSeg(void)
{
int t,i,j;
printf("Enter Threshold value:\n");
scanf("%d",&t);
for(i=0;i<N;i++)
{
for(j=0;j<M;j++)
{
if(image[i][j]<=t)
imageT[i][j]=0;
else
imageT[i][j]=255;
}
}
for(i=1;i<N;i++)
for(j=1;j<M;j++)
image[i][j]=imageT[i][j];
}
原图
采用固定阈值分割算法后输出的二值图像为:
而使用Otsu算法的图像为:
对比可以看出采用OTSU算法处理的图像在经过二值化后图像特征保存的更好。
调试过程中可以查看到该图像在类方差最大时的灰度值为146,即经过遍历后得出的最佳分割阈值为146。则以此灰度值为阈值分割出的二值图像保留了原图像最多的信息。
因此,该算法可以部署在一些算力不高的单片机、DSP以及一些对程序运行时间要求较高的场合。用于把信息量较大的图像转换为二值图像,同时最大程度保证图像特征不丢失。为系统的判决服务。