二值化阈值自动选取方法 1. 双峰法
双峰法的原理及其简单:它认为图像由前景和背景组成,在灰度直方图上,前后二景都形成高峰,在双峰之间的最低谷处就是图像的阈值所在。根据这一原理,我们给出了它的实现,部分代码如下(Pascal语言描述,以下同):
//intPeak、intPeak2、intValley:峰值和直方图值
//intIndx::相应的灰度值
intPeak,intIndx,intPeak2,intIndx2,intValley,intValleyIndx:integer;
//初始双峰值
intPeak:=0;
intPeak2:=0;
//取得第一峰值
for intLoop:=0 to 255 do
if intPeak<=intGrayLevel[intLoop] then
begin
intPeak:=intGrayLevel[intLoop];
intIndx:=intLoop;
end;
//取得第二峰值
for intLoop:=0 to 255 do
Begin
if (intPeak2<=intGrayLevel[intLoop]) and (intLoop<>intIndx) then
begin
intPeak2:=intGrayLevel[intLoop];
intIndx2:=intLoop;
end
end;
//取得双峰之间的谷值
intValley:=intSize;
if intIndx2 for intLoop:=intIndx2 to intIndx do if intValley>intGrayLevel[intLoop] then begin intValley:=intGrayLevel[intLoop]; intValleyIndx:=intLoop; end; 从分割的效果来看,当前后景的对比较为强烈时,分割效果较好;否则基本无效。 2. 迭代法 迭代法是基于逼近的思想,其步骤如下: 1. 求出图象的最大灰度值和最小灰度值,分别记为ZMAX和ZMIN,令初始阈值T0=(ZMAX+ZMIN)/2; 2. 根据阈值TK将图象分割为前景和背景,分别求出两者的平均灰度值ZO和ZB; 3. 求出新阈值TK+1=(ZO+ZB)/2; 4. 若TK=TK+1,则所得即为阈值;否则转2,迭代计算。 以下给出迭代求阈值的部分实现: //阈值初始为0 intThresholdVal:=0; intThresholdVal2:=0; //总灰度值 intTotalGrayLevel:=0; for intLoop:=0 to 255 do if intGrayLevel[intLoop]<>0 then intTotalGrayLevel:=intTotalGrayLevel+intLoop*intGrayLevel[intLoop]; //求出初始最大灰度值 for intLoop:=0 to 255 do if intGrayLevel[intLoop]>0 then begin intLGrayLevel:=intLoop; intThresholdVal:=intLoop; break; end; //求出初始最小灰度值和初始阈值 for intLoop:=255 downto 0 do if intGrayLevel[intLoop]>0 then begin intRGrayLevel:=intLoop; intThresholdVal:=(intThresholdVal+intLoop)div 2; break; end; //迭代求解 while intThresholdVal<>intThresholdVal2 do begin intThresholdVal2:=intThresholdVal; intCount:=0; intLGrayLevel:=0; for intLoop:=0 to intThresholdVal do if intGrayLevel[intLoop]<>0 then begin intCount:=intCount+intGrayLevel[intLoop]; intLGrayLevel:=intLGrayLevel+intLoop*intGrayLevel[intLoop]; end; intRGrayLevel:=intTotalGrayLevel-intLGrayLevel; intLGrayLevel:=intLGrayLevel div intCount; intRGrayLevel:=intRGrayLevel div (intSize-intCount); intThresholdVal:=(intLGrayLevel+intRGrayLevel)div 2; end; 迭代所得的阈值分割的图象效果良好。基于迭代的阈值能区分出图像的前景和背景的主要区域所在,但在图像的细微处(如图1中的浅色线条)还没有很好的区分度。 但令人惊讶的是,对某些特定图象,微小数据的变化却会引起分割效果的巨大改变,两者的数据只是稍有变化,但分割效果却反差极大,个中原因还有待进一步研究。 3. 大津法(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,根据方差的定义即得该式。因方差是灰度分布均匀性的一种度量,方差值越大,说明构成图像的两部分差别越大,当部分目标错分为背景或部分背景错分为目标都会导致两部分差别变小,因此使类间方差最大的分割意味着错分概率最小。 直接应用大津法计算量较大,因此我们在实现时采用了等价的公式g=w0*w1*(u0-u1)2。部分计算过程如下: //遍历所有灰度值求Max g。 for intCurrentLevel:=0 to intArrLen do begin if intSclGrayLevel[intCurrentLevel]=0 then continue else begin //计算当阈值为intCurrentLevel时的g intCount:=0; intSumPels:=0; for intLoop:=0 to intCurrentLevel do begin intCount:=intCount+intSclGrayLevel[intLoop]; intSumPels:=intSumPels+intSumPelsArr[intLoop];