otsu自动确定图像分割时前景与背景的划分阈值,基于最大类间的原理进行图像分割。
#include<iostream>
#include"FTImage.h"
using namespace std;
#define WIDTH 640
#define HEIGHT 480
void otsu(FTImage& src,FTImage& dst)
{
long Level[256]={0};
float p[256];
int w=src.GetWidth();
int h=src.GetHeight();
for(int i=0;i<h;i++)
for(int j=0;j<w;j++)
{
Level[src.pixels[i*w+j]]++;
}
for(int i=0;i<256;i++)
{
p[i]=(float)((1.0*Level[i])/w*h);
}
float sum1,sum2,a1,a2,u1,u2,variance=0;
int thresh;
for(int m=1;m<256;m++)
{
sum1=0;
sum2=0;
for(int l=0;l<m;l++)
{
sum1+=p[l];
sum2+=l*p[l];
}
a1=sum1;
u1=sum2/sum1;
sum1=0;
sum2=0;
for(int l=m;l<256;l++)
{
sum1+=p[l];
sum2+=l*p[l];
}
a2=sum1;
u2=sum2/sum1;
float res=a1*a2*(u1-u2)*(u1-u2);
if(res>variance)
{
variance=res;
thresh=(int)(m-1);
}
}
for(int i=0;i<h;i++)
for(int j=0;j<w;j++)
{
if(src.pixels[i*w+j]>thresh)
{
dst.pixels[i*w+j]=255;
}
else
{
dst.pixels[i*w+j]=0;
}
}
}
int main(int argc,char* argv[])
{
FTImage Img;
Img.FTLoadImageGray("lena.bmp",WIDTH,HEIGHT);
FTImage rImg;
rImg.FTCreateImage(WIDTH,HEIGHT,1);
otsu(Img,rImg);
rImg.FTSaveImage("otsu.bmp");
}