自动阈值迭代法及 Otsu 法实验报告
一、实验原理
大津法由大津于1979年提出,对图像Image,记t为前景与背景的分割阈
值,前景点数占图像比例为w0,平均灰度为u0;背景点数占图像比例为w1,平均
灰度为u1。图像的总平均灰度为:u=w0*u0+w1*u1。从最小灰度值到最大灰度值
遍历t,当t使得值g=w0*(u0-u)2+w1*(u1-u)2 最大时t即为分割的最佳阈值。对
大津法可作如下理解:该式实际上就是类间方差值,阈值t分割出的前景和背景
两部分构成了整幅图像,而前景取值u0,概率为 w0,背景取值u1,概率为w1,
总均值为u,根据方差的定义即得该式。因方差是灰度分布均匀性的一种度量,
方差值越大,说明构成图像的两部分差别越大, 当部分目标错分为背景或部分背
景错分为目标都会导致两部分差别变小,因此使类间方差最大的分割意味着错分
概率最小。
二、实验步骤
自动阈值(迭代法)步骤
(1)估计一个阈值 T(比如均值)
(2)用阈值 T 将灰度直方图分割成两个区域 R1、R2
(3)分别计算两个区域 R1、R2 内的灰度平均值 u1 和 u2
(4)选择新阈值 T=(u1+u2)/2
(5)重复上述工作 3~5 次,直到前后两次的阈值不变
自动阈值(Otsu 法)步骤
(1).计算直方图
(2).设置初值:wi(0)以及 ui(0)
(3).从 1 到最大值设置阈值 T。更新 wi (t)以及 ui (t)。计算σb(t) *
σb(t)。
(4).选取最大σb(t) * σb(t)对应的 T
三、实验程序
#include
#include
#include
#include
#include
int nWidth;
int nHeight;
int nColorBits;
int nColor;
int nLen;
int nByteWidth;
BYTE *lpBitmap;
BYTE *lpBits;
//图像宽度
//图像高度
//每个像素所占位数
//图像颜色数
//图像文件大小,以字节数计
//图像每行字节数
//指向图像首字节的指针
//指向图像实际数据的指针
void OpenFile(CString FileName);
void SaveFile(CString FileName);
void OtusTHreshold(void);
/*函数名称 OpenFile() 功能:读取一幅 BMP 图像*/
void OpenFile(CString FileName)
{
hFile=::CreateFile(FileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN
_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
//创建文件语句
HANDLE
if(hFile==0)
{
}
printf("不能打开文件,请重新选择!\n");
return;
//读取图像文件
DWORD WriteNum;
BITMAPFILEHEADER BFH;//文件头
ReadFile(hFile,&BFH,14,&WriteNum,NULL);//读取文件头,共 14 个字节
if((BFH.bfType!='MB')||(WriteNum!=sizeof(BITMAPFILEHEADER)))
{
printf("不是 BMP 位图文件或数据有误!\n");
return;
}
nLen=GetFileSize(hFile,NULL)-sizeof(BITMAPFILEHEADER);//获取文件的
长度
数据
lpBitmap=new BYTE[nLen];//存放图像,包括图像的信息头、调色板和像素
ReadFile(hFile,lpBitmap,nLen,&WriteNum,NULL);//读取图像数据
//设置全局变量的值
BITMAPINFOHEADER *BIH=((BITMAPINFOHEADER *)lpBitmap);//图像
文件的信息头
nWidth=BIH->biWidth;//图像的宽度
nHeight=BIH->biHeight;//图像的高度
nColorBits=BIH->biBitCount;//图像的颜色数
nByteWidth=(nWidth*nColorBits+31)/32*4;//图像的扫描宽度
nColor=(nColorBits>8)?0:(1<
/*图像分割 Otsu 法*/
void Otus(void)
{
int i,j;//循环变量
int nGrayHistogram[256];//灰度直方图数组,并初始化
memset(nGrayHistogram,0,sizeof(nGrayHistogram));//统计各个灰度级对应的
像素个数,并存放到灰度直方图数组中
int nPixel;
for(j=0;j
fVaria=w0*w1*(u0-u1)*(u0-u1);//计算两组间的方差
if(fVaria>fMaxVaria)//记录最大方差和最佳阈值
{
}
fMaxVaria=fVaria;
nBestT=nT;
}
//利用最佳阈值对源图像作分割处理
for(j=0;j
处理后图像: