Otsu算法(大律法或最大类间方差法)

合集下载

otsu算法——图像分割

otsu算法——图像分割
前景比例:
背景比例:
像素点总数:
前景和背景概率之和:
平均灰度值:
类间方差:
将公式(4)和(5)带入(6)可以得到等价公式:
核心代码:Histogram[data[i*srcimage.step + j]]++;//step指向每行的字节总量,date访问每个像素的值for (int i = 1; i < 255 ;i++)//从1开始遍历,寻找最合适的值{//每次遍历前需要初始化各变量w0 = 0; u0 = 0; w1 = 0; u1 = 0;for (int j = 0; j <= i; j++)//背景部分各值计算 { w0 += Histogram[j]; //背景部分像素点总数 u0 += j*Histogram[j]; //背景部分像素总灰度和 } u0 = u0 / w0; //背景像素平均灰度 w0 = w0 / number; //背景部分像素点所占比例}double varValueI = w1*w2*(u1 - u2)*(u1 - u2); //类间方差计算
算法过程:(1)设K(x,y)=f(x,y)/g(x,y)为像素点的 斜率,其中f(x,y)为点(x,y)的灰度值, g(x,y)为点(x,y)周围点的平均值。 (2)设阈值t1,t2将二维直方图分为A、B、 C三个区域。其中B区域代表前景和背 景像素点部分,而A、C代表边界点和 噪声点部分。
算法过程:(1)对于图像I(x,y),将前景与背景的分割阈值设为T。(2)将属于前景的像素点的个数占整个图像的比例设为w0,其平均灰度设为u0。(3)将属于背景的像素点的个数占整个图像的比例设为w1,其平均灰度设为u1。(4)图像的总平均灰度设为u,类间方差设为S。 假设图片的大小为M*N,图像中像素灰度值小于阈值T的像素个数记为N0,像素灰度大于阈值T的像素个数记为N1。则它们之间的关系如下。

大津法原理(otsu)

大津法原理(otsu)

最大类间方差法(大津法,OTSU)最大类间方差法是由日本学者大津(Nobuyuki Otsu)于1979年提出的,是一种自适应的阈值确定的方法,又叫大津法,简称OTSU 。

它是按图像的灰度特性,将图像分成背景和目标2部分。

背景和目标之间的类间方差越大,说明构成图像的2部分的差别越大,当部分目标错分为背景或部分背景错分为目标都会导致2部分差别变小。

因此,使类间方差最大的分割意味着错分概率最小。

对于图像I(x,y),前景(即目标)和背景的分割阈值记作T ,属于前景的像素点数占整幅图像的比例记为1ω,其平均灰度1μ;背景像素点数占整幅图像的比例为2ω,其平均灰度为2μ。

图像的总平均灰度记为μ,类间方差记为g 。

假设图像的背景较暗,并且图像的大小为M N ⨯,图像中像素的灰度值小于阈值T 的像素个数记作1N ,像素灰度大于阈值T 的像素个数记作2N ,则有:11N M N ω=⨯ (1.1)22N M N ω=⨯ (1.2)12N N M N +=⨯ (1.3)121ωω+= (1.4)1122μμωμω=⨯+⨯ (1.5) 221122()()g ωμμωμμ=⨯-+⨯-(1.6) 将式(1.5)代入式(1.6),得到等价公式:21212()g ωωμμ=⨯⨯- (1.7) 采用遍历的方法得到使类间方差最大的阈值T ,即为所求。

OpenCV 代码:int myOtsu(const IplImage *frame) //大津法求阈值{#define GrayScale 256 //frame 灰度级int width = frame->width;int height = frame->height;int pixelCount[GrayScale]={0};float pixelPro[GrayScale]={0};int i, j, pixelSum = width * height, threshold = 0;uchar* data = (uchar*)frame->imageData;//统计每个灰度级中像素的个数for(i = 0; i < height; i++){for(j = 0;j < width;j++){pixelCount[(int)data[i * width + j]]++;}}//计算每个灰度级的像素数目占整幅图像的比例for(i = 0; i < GrayScale; i++){pixelPro[i] = (float)pixelCount[i] / pixelSum;}//遍历灰度级[0,255],寻找合适的thresholdfloat w0, w1, u0tmp, u1tmp, u0, u1, deltaTmp, deltaMax = 0;for(i = 0; i < GrayScale; i++){w0 = w1 = u0tmp = u1tmp = u0 = u1 = deltaTmp = 0;for(j = 0; j < GrayScale; j++){if(j <= i) //背景部分{w0 += pixelPro[j];u0tmp += j * pixelPro[j];}else //前景部分{w1 += pixelPro[j];u1tmp += j * pixelPro[j];}}u0 = u0tmp / w0;u1 = u1tmp / w1;deltaTmp = (float)(w0 *w1* pow((u0 - u1), 2)) ;if(deltaTmp > deltaMax){deltaMax = deltaTmp;threshold = i;}}return threshold;}参考文献:Nobuyuki Otsu发表的原文"A Threshold Selection Method from Gray-Level Histograms," Systems, Man and Cybernetics, IEEE Transactions on , vol.9, no.1, pp.62-66, Jan. 1979。

Ots算法(大律法或最大类间方差法)

Ots算法(大律法或最大类间方差法)

Otsu算法(大律法或最大类间方差法)一、Otsu最大类间方差法原理利用阈值将原图像分成前景,背景两个图象。

前景:用n1,csum,m1来表示在当前阈值下的前景的点数,质量矩,平均灰度后景:用n2, sum-csum,m2来表示在当前阈值下的背景的点数,质量矩,平均灰度当取最佳阈值时,背景应该与前景差别最大,关键在于如何选择衡量差别的标准,而在otsu算法中这个衡量差别的标准就是最大类间方差(英文简称otsu,这也就是这个算法名字的来源),在本程序中类间方差用sb表示,最大类间方差用fmax 关于最大类间方差法(otsu)的性能:类间方差法对噪音和目标大小十分敏感,它仅对类间方差为单峰的图像产生较好的分割效果。

当目标与背景的大小比例悬殊时,类间方差准则函数可能呈现双峰或多峰,此时效果不好,但是类间方差法是用时最少的。

最大类间方差法(otsu)的公式推导:记t为前景与背景的分割阈值,前景点数占图像比例为w0,平均灰度为u0;背景点数占图像比例为w1,平均灰度为u1。

则图像的总平均灰度为:u=w0*u0+w1*u1。

前景和背景图象的方差:g=w0*(u0-u)*(u0-u)+w1*(u1-u)*(u1-u)=w0*w1*(u0-u1)*(u0-u1),此公式为方差公式。

可参照概率论课本上面的g的公式也就是下面程序中的sb的表达式。

当方差g最大时,可以认为此时前景和背景差异最大,此时的灰度t是最佳阈值sb = w1*w2*(u1-u0)*(u0-u1)算法实现1:unsafe public int GetThreshValue(Bitmap image){BitmapData bd = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.WriteOnly, image.PixelFormat);byte* pt = (byte*)bd.Scan0;int[] pixelNum = new int[256]; //图象直方图,共256个点byte color;byte* pline;int n, n1, n2;int total; //total为总和,累计值double m1, m2, sum, csum, fmax, sb; //sb为类间方差,fmax存储最大方差值int k, t, q;int threshValue = 1; // 阈值int step = 1;switch (image.PixelFormat){case PixelFormat.Format24bppRgb:step = 3;break;case PixelFormat.Format32bppArgb:step = 4;break;case PixelFormat.Format8bppIndexed:step = 1;break;}//生成直方图for (int i = 0; i < image.Height; i++){pline = pt + i * bd.Stride;for (int j = 0; j < image.Width; j++){color = *(pline + j * step); //返回各个点的颜色,以RGB表示pixelNum[color]++; //相应的直方图加1}}//直方图平滑化for (k = 0; k <= 255; k++){total = 0;for (t = -2; t <= 2; t++) //与附近2个灰度做平滑化,t值应取较小的值{q = k + t;if (q < 0) //越界处理q = 0;if (q > 255)q = 255;total = total + pixelNum[q]; //total为总和,累计值}//平滑化,左边2个+中间1个+右边2个灰度,共5个,所以总和除以5,后面加0.5是用修正值pixelNum[k] = (int)((float)total / 5.0 + 0.5);}//求阈值sum = csum = 0.0;n = 0;//计算总的图象的点数和质量矩,为后面的计算做准备for (k = 0; k <= 255; k++){//x*f(x)质量矩,也就是每个灰度的值乘以其点数(归一化后为概率),sum为其总和sum += (double)k * (double)pixelNum[k];n += pixelNum[k]; //n为图象总的点数,归一化后就是累积概率}fmax = -1.0; //类间方差sb不可能为负,所以fmax初始值为-1不影响计算的进行n1 = 0;for (k = 0; k < 255; k++) //对每个灰度(从0到255)计算一次分割后的类间方差sb{n1 += pixelNum[k]; //n1为在当前阈值遍前景图象的点数if (n1 == 0) { continue; } //没有分出前景后景n2 = n - n1; //n2为背景图象的点数//n2为0表示全部都是后景图象,与n1=0情况类似,之后的遍历不可能使前景点数增加,所以此时可以退出循环if (n2 == 0) { break; }csum += (double)k * pixelNum[k]; //前景的“灰度的值*其点数”的总和m1 = csum / n1; //m1为前景的平均灰度m2 = (sum - csum) / n2; //m2为背景的平均灰度sb = (double)n1 * (double)n2 * (m1 - m2) * (m1 - m2); //sb为类间方差if (sb > fmax) //如果算出的类间方差大于前一次算出的类间方差{fmax = sb; //fmax始终为最大类间方差(otsu)threshValue = k; //取最大类间方差时对应的灰度的k就是最佳阈值}}image.UnlockBits(bd);image.Dispose();return threshValue;}算法实现2:Otsu算法步骤如下:设图象包含L个灰度级(0,1…,L-1),灰度值为i的的象素点数为Ni ,图象总的象素点数为N=N0+N1+...+N(L-1)。

二维otsu法阈值选择

二维otsu法阈值选择

二维Otsu法是一种图像分割算法,能够自适应地选择图像的阈值。

该算法是在Otsu算法基础上,在二维图像上进行的扩展。

一维Otsu法(也称为最大类间方差法)的基本原理是将一幅灰度图像分成两部分,使得每部分的类间方差最大,从而得到最佳的阈值。

与一维Otsu法不同的是,二维Otsu法从图像的全局信息中选择最佳阈值,因此具有更高的鲁棒性和更好的适应性。

实现二维Otsu法的基本步骤如下:1. 对图像进行灰度处理,将彩色图像转换为灰度图像。

2. 计算图像的直方图,即各灰度级别的像素数目。

3. 计算图像的累积分布函数(CDF),即各灰度级别的像素的累计和。

4. 根据CDF计算各灰度级别的均值和方差。

5. 计算各灰度级别的类间方差,选择最大值对应的灰度级别为阈值,用于将图像分割为前景和背景。

需要注意的是,二维Otsu法的实现较为复杂,计算量较大,因此需要在具体应用中结合实际情况进行调优和优化。

在实现二维Otsu法时,需要注意以下几点:1. 对图像进行预处理,如平滑、滤波和缩放等,以提高算法效率和准确度。

2. 根据图像的特点和实际需求,选择合适的灰度级别数目和区间范围,并进行合适的采样和压缩。

3. 对于大尺寸、高分辨率和复杂场景的图像,可以采用分块处理或多层分割等技术来提高算法效率和准确度。

4. 在计算类间方差时,需要进行有效的数据处理和统计方法,以避免过拟合和低通滤波等问题。

5. 在图像分割后,需要进行后续处理,如形态学运算、噪声消除和轮廓提取等,以得到更精确和完整的分割结果。

总的来说,二维Otsu法是一种非常有效和实用的图像分割算法,可以广泛应用于图像处理、计算机视觉和模式识别等领域。

如果您需要更具体的技术细节和应用案例,建议咨询相关专业人士或参考相关文献。

OSTU最大类间方差

OSTU最大类间方差

OSTU最大类间方差法原理在最小二乘原理基础上推导出来的,适用于双峰的直方图。

利用阈值将原图像分成前景,背景两个部分。

当取最佳阈值时,背景应该与前景差别最大,即方差最大。

OSTU算法找的就是这个最大方差下的阈值。

最大类间方差法的公式推导:记t为前景与背景的分割阈值,前景是所有灰度级大于t的像素点,背景是所有灰度级小于或等于t的像素点。

前景点数占图像比例为w0,前景加权平均灰度为u0;背景点数占图像比例为w1,背景加权平均灰度为u1。

则整个图像的总平均灰度为:u=w0*u0+w1*u1。

前景和背景图象的方差:g(t)=w0*(u0-u)*(u0-u)+w1*(u1-u)*(u1-u)=w0*w1*(u0-u1)*(u0-u1)。

g(t)就是当分割阈值为t时的类间方差表达式。

OSTU算法使得g(t)取得全局最大值,当g(t)为最大时所对应的t称为最佳阈值。

循环求取最大方差即可。

MABLAB代码及详细注释:function ostuimg = imread('Lena.jpg');I_gray=rgb2gray(img);figure,imshow(I_gray);I_double=double(I_gray); %转化为双精度,因为大多数的函数和操作都是基于double的%figure,imshow(I_double);[wid,len]=size(I_gray); %wid为行数,len为列数colorlevel=256; %灰度级hist=zeros(colorlevel,1); %直方图,256×1的0矩阵%threshold=128; %初始阈值%计算直方图,统计灰度值的个数for i=1:widfor j=1:lenm=I_gray(i,j)+1; %因为灰度为0-255所以+1hist(m)=hist(m)+1;endend%直方图归一化hist=hist/(wid*len);%miuT为总的平均灰度,hist[m]代表像素值为m的点个数miuT=0;for m=1:colorlevelmiuT=miuT+(m-1)*hist(m);endxigmaB2=0; %用于保存每次计算的方差,与下次计算的方差比较大小for mindex=1:colorlevelthreshold=mindex-1;omega1=0; %前景点所占比例omega2=0; %背景点所占比例for m=1:threshold-1omega1=omega1+hist(m); %计算前景比例endomega2=1-omega1; %计算背景比例miu1=0; %前景平均灰度比例miu2=0; %背景平均灰度比例%计算前景与背景平均灰度for m=1:colorlevelif mmiu1=miu1+(m-1)*hist(m); %前景平均灰度elsemiu2=miu2+(m-1)*hist(m); %背景平均灰度endend% miu1=miu1/omega1;% miu2=miu2/omega2;%计算前景与背景图像的方差xigmaB21=omega1*(miu1-miuT)^2+omega2*(miu2-miuT)^2;xigma(mindex)=xigmaB21; %保留每次计算的方差%每次计算方差后,与上一次计算的方差比较。

【转】七种常见阈值分割代码(Otsu、最大熵、迭代法、自适应阀值、手动、迭代法、基本全局阈值法)

【转】七种常见阈值分割代码(Otsu、最大熵、迭代法、自适应阀值、手动、迭代法、基本全局阈值法)

【转】七种常见阈值分割代码(Otsu、最⼤熵、迭代法、⾃适应阀值、⼿动、迭代法、基本全局阈值法)⼀、⼯具:VC+OpenCV⼆、语⾔:C++三、原理otsu法(最⼤类间⽅差法,有时也称之为⼤津算法)使⽤的是聚类的思想,把图像的灰度数按灰度级分成2个部分,使得两个部分之间的灰度值差异最⼤,每个部分之间的灰度差异最⼩,通过⽅差的计算来寻找⼀个合适的灰度级别来划分。

所以可以在⼆值化的时候采⽤otsu 算法来⾃动选取阈值进⾏⼆值化。

otsu算法被认为是图像分割中阈值选取的最佳算法,计算简单,不受图像亮度和对⽐度的影响。

因此,使类间⽅差最⼤的分割意味着错分概率最⼩。

设t为设定的阈值。

wo:分开后前景像素点数占图像的⽐例uo:分开后前景像素点的平均灰度w1:分开后被景像素点数占图像的⽐例u1:分开后被景像素点的平均灰度u=w0*u0 + w1*u1 :图像总平均灰度从L个灰度级遍历t,使得t为某个值的时候,前景和背景的⽅差最⼤,则这个 t 值便是我们要求得的阈值。

其中,⽅差的计算公式如下:g=wo * (uo - u) * (uo - u) + w1 * (u1 - u) * (u1 - u)[ 此公式计算量较⼤,可以采⽤: g = wo * w1 * (uo - u1) * (uo - u1) ]由于otsu算法是对图像的灰度级进⾏聚类,so 在执⾏otsu算法之前,需要计算该图像的灰度直⽅图。

迭代法原理:迭代选择法是⾸先猜测⼀个初始阈值,然后再通过对图像的多趟计算对阈值进⾏改进的过程。

重复地对图像进⾏阈值操作,将图像分割为对象类和背景类,然后来利⽤每⼀个类中的灰阶级别对阈值进⾏改进。

图像阈值分割---迭代算法1 .处理流程:1.为全局阈值选择⼀个初始估计值T(图像的平均灰度)。

2.⽤T分割图像。

产⽣两组像素:G1有灰度值⼤于T的像素组成,G2有⼩于等于T像素组成。

3.计算G1和G2像素的平均灰度值m1和m2;4.计算⼀个新的阈值:T = (m1 + m2) / 2;5.重复步骤2和4,直到连续迭代中的T值间的差⼩于⼀个预定义参数为⽌。

大津法求阈值

大津法求阈值

大津法求阈值
大津法求阈值,又称为最大类间方差法或Otsu算法,是一种自动图像阈值分割的统计学方法,由日本图像处理专家Nobuyuki Otsu于1979年提出。

该方法根据灰度直方图计算出合适的阈值,以分隔不同灰度水平的图像。

它被认为是最优二值化的方法,也是目前最流行的图像分割算法之一。

首先,所谓的“大津法求阈值”,是指在图像分割中,采用Otsu的算法来寻找最佳的阈值,以将图像有效分割为前景和背景两部分。

它的主要思想是:通过计算灰度值的类间方差,确定一个最佳的阈值,以此来使得类间方差最大,从而得到最佳的分割效果。

大津法求阈值的具体步骤如下:
(1)将灰度图像像素点按其灰度值从低到高排序,形成灰度直方图;
(2)计算每个灰度级中像素点的累积概率;
(3)从灰度值最小的级开始,依次将每个灰度级作为阈值,计算背景和前景的类间方差;
(4)选取类间方差最大的阈值作为最佳阈值;
(5)将原图像中像素点的灰度值与最佳阈值比较,大于最佳阈值的像素点设为前景,小于最佳阈值的像素点设为背景。

大津法求阈值在图像分割中具有明显的优势:(1)它是一种无人参与的自动化算法,结果更加准确可靠;(2)它可以在不同的图像上获得较高的分割质量;(3)它可以实现快速的计算,不需要太多额外的计算;(4)它可以在不同的图像上获得较高的分割质量。

总而言之,大津法求阈值是一种非常有效的图像分割方法,可以快速有效地将图像分割为前景和背景两部分,从而提高图像处理的效率。

图像二值化阈值选取常用方法汇总

图像二值化阈值选取常用方法汇总

图像二值化阈值选取常用方法最近在公司搞车牌识别的项目,车牌定位后,发现对车牌区域二值化的好坏直接影响后面字符切分的过程,所以就想把常用阈值选取方法做一个总结。

图像二值化阈值选取常用方法:1.双峰法。

2.P 参数法。

3.最大类间方差法(Otsu 、大津法)。

4.最大熵阈值法。

5.迭代法(最佳阈值法)。

1.双峰法在一些简单的图像中,物体的灰度分布比较有规律,背景与目标在图像的直方图各自形成一个波峰,即区域与波峰一一对应,每两个波峰之间形成一个波谷。

那么,选择双峰之间的波谷所代表的灰度值T 作为阈值,即可实现两个区域的分割。

如图1所示。

2.P 参数法当目标与背景的直方图分布有一定重叠时,两个波峰之间的波谷很不明显。

若采用双峰法,效果很差。

如果预先知道目标占整个图像的比例P ,可以采用P 参数法。

P 参数法具体步骤如下:假设预先知道目标占整个图像的比例为P ,且目标偏暗,背景偏亮。

1)、计算图像的直方图分布P(t),t=0,1,.....255。

2)、计算阈值T ,使其满足0()*Tt p t Pm n =-∑最小。

P 参数法一般用于固定分辨率下,目标所占整个图像比例已知的情况。

3.最大类间方差法(Otsu)最大类间方差法是由Otsu 于1979年提出的,是基于整幅图像的统计特性实现阈值的自动选取的,是全局二值化最杰出的代表。

Otsu 算法的基本思想是用某一假定的灰度值t 将图像的灰度分成两组,当两组的类间方差最大时,此灰度值t 就是图像二值化的最佳阈值。

设图像有L 个灰度值,取值范围在0~L-1,在此范围内选取灰度值T ,将图像分成两组G0和G1,G0包含的像素的灰度值在0~T ,G1的灰度值在T+1~L-1,用N 表示图像像素总数,i n 表示灰度值为i 的像素的个数。

已知:每一个灰度值i 出现的概率为/i i p n N =;假设G0和G1两组像素的个数在整体图像中所占百分比为01ϖϖ、,两组平均灰度值为01μμ、,可得概率:00=T ii p ϖ=∑11011L i i T p ωω-=+==-∑平均灰度值:00T i i ipμ==∑111L ii T i p μ-=+=∑图像总的平均灰度值:0011μϖμϖμ=+类间方差:()()()22200110101()g t ωμμωμμωωμμ=-+-=-最佳阈值为:T=argmax(g(t))使得间类方差最大时所对应的t 值。

最大类间方差法阈值初值

最大类间方差法阈值初值

最大类间方差法阈值初值最大类间方差法(Otsu算法)是图像处理中常用的一种阈值分割方法,通过将图像分割成两个类别,使类别内部的方差最小,不同类别之间的方差最大,以此确定一个最佳阈值。

而确定最大类间方差阈值的初值,则是这个方法中比较重要的一环。

下面将围绕“最大类间方差法阈值初值”进行讲解,具体步骤如下:1. 计算灰度级概率分布函数首先,我们需要计算图像的灰度级概率分布函数 P(i),其定义为每个像素灰度级 i 在整幅图像中的出现概率。

可以用下式进行计算: P(i) = n(i) / N其中,n(i) 为灰度级为 i 的像素数目,N 为整幅图像像素数目。

2. 计算灰度平均值和全局灰度平均值灰度平均值μ(T) 是指图像像素灰度级的平均值,全局灰度平均值μ(Total) 是整幅图像所有像素灰度值的平均值。

可以用下式进行计算:μ(T) = Σ[i=0, T]i * P(i) / w(T)μ(Total) = Σ[i=0, L]i * P(i)其中,T 为阈值,L 为最大的灰度级数目。

3. 计算类内方差类内方差σ1²(T) 是指灰度值小于等于 T 的像素的方差,类内方差σ2²(T) 是指灰度值大于 T 的像素的方差。

可以用下式进行计算:σ1²(T) = Σ[i=0, T](i - μ1(T))² * P(i) / w1(T)σ2²(T) = Σ[i=T+1, L](i - μ2(T))² * P(i) / w2(T)其中,μ1(T) 和μ2(T) 是灰度值小于等于 T 和大于 T 的像素灰度级的平均值,w1(T) 和 w2(T) 则是灰度值小于等于 T 和大于T 的像素数量。

4. 计算类间方差类间方差σ(T)² 是指灰度值小于等于 T 和灰度值大于 T 的像素之间的方差,可以用下式进行计算:σ(T)² = w1(T) * w2(T) * (μ1(T) - μ2(T))²5. 确定最大类间方差阈值最大类间方差阈值即为使类间方差σ(T)² 最大的阈值 T,可以先将所有灰度级都作为初值进行计算,然后根据所求得的最大值确定最优阈值。

最大类间方差法

最大类间方差法

最大类间方差法(otsu)的原理:阈值将原图象分成前景,背景两个图象。

前景:用n1, csum, m1来表示在当前阈值下的前景的点数,质量矩,平均灰度后景:用n2, sum-csum, m2来表示在当前阈值下的背景的点数,质量矩,平均灰度当取最佳阈值时,背景应该与前景差别最大,关键在于如何选择衡量差别的标准而在otsu算法中这个衡量差别的标准就是最大类间方差(英文简称otsu,这也就是这个算法名字的来源)在本程序中类间方差用sb表示,最大类间方差用fmax关于最大类间方差法(otsu)的性能:类间方差法对噪音和目标大小十分敏感,它仅对类间方差为单峰的图像产生较好的分割效果。

当目标与背景的大小比例悬殊时,类间方差准则函数可能呈现双峰或多峰,此时效果不好,但是类间方差法是用时最少的。

最大最大类间方差法(otsu)的公式推导:记t为前景与背景的分割阈值,前景点数占图像比例为w0,平均灰度为u0;背景点数占图像比例为w1,平均灰度为u1。

则图像的总平均灰度为:u=w0*u0+w1*u1。

前景和背景图象的方差:g=w0*(u0-u)*(u0-u)+w1*(u1-u)*(u1-u)=w0*w1*(u0-u1)*(u0-u1),此公式为方差公式,可参照概率论课本上面的g的公式也就是下面程序中的sb的表达式当方差g最大时,可以认为此时前景和背景差异最大,也就是此时的灰度是最佳阈值unsafe public int GetThreshValue(Bitmap image){BitmapData bd = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.WriteOnly, image.PixelFormat);byte* pt = (byte*)bd.Scan0;int[] pixelNum = new int[256]; //图象直方图,共256个点byte color;byte* pline;int n, n1, n2;int total; //total为总和,累计值double m1, m2, sum, csum, fmax, sb; //sb为类间方差,fmax存储最大方差值int k, t, q;int threshValue = 1; // 阈值int step = 1;switch (image.PixelFormat){case PixelFormat.Format24bppRgb:step = 3;break;case PixelFormat.Format32bppArgb:step = 4;break;case PixelFormat.Format8bppIndexed:step = 1;break;}//生成直方图for (int i = 0; i < image.Height; i++){pline = pt + i * bd.Stride;for (int j = 0; j < image.Width; j++){color = *(pline + j * step); //返回各个点的颜色,以RGB表示pixelNum[color]++; //相应的直方图加1}}//直方图平滑化for (k = 0; k <= 255; k++){total = 0;for (t = -2; t <= 2; t++) //与附近2个灰度做平滑化,t值应取较小的值{q = k + t;if (q < 0) //越界处理q = 0;if (q > 255)q = 255;total = total + pixelNum[q]; //total为总和,累计值}pixelNum[k] = (int)((float)total / 5.0 + 0.5); //平滑化,左边2个+中间1个+右边2个灰度,共5个,所以总和除以5,后面加0.5是用修正值}//求阈值sum = csum = 0.0;n = 0;//计算总的图象的点数和质量矩,为后面的计算做准备for (k = 0; k <= 255; k++){sum += (double)k * (double)pixelNum[k]; //x*f(x)质量矩,也就是每个灰度的值乘以其点数(归一化后为概率),sum为其总和n += pixelNum[k]; //n为图象总的点数,归一化后就是累积概率}fmax = -1.0; //类间方差sb不可能为负,所以fmax初始值为-1不影响计算的进行n1 = 0;for (k = 0; k < 255; k++) //对每个灰度(从0到255)计算一次分割后的类间方差sb{n1 += pixelNum[k]; //n1为在当前阈值遍前景图象的点数if (n1 == 0) { continue; } //没有分出前景后景n2 = n - n1; //n2为背景图象的点数if (n2 == 0) { break; } //n2为0表示全部都是后景图象,与n1=0情况类似,之后的遍历不可能使前景点数增加,所以此时可以退出循环csum += (double)k * pixelNum[k]; //前景的“灰度的值*其点数”的总和m1 = csum / n1; //m1为前景的平均灰度m2 = (sum - csum) / n2; //m2为背景的平均灰度sb = (double)n1 * (double)n2 * (m1 - m2) * (m1 - m2); //sb为类间方差if (sb > fmax) //如果算出的类间方差大于前一次算出的类间方差{fmax = sb; //fmax始终为最大类间方差(otsu)threshValue = k; //取最大类间方差时对应的灰度的k就是最佳阈值}}image.UnlockBits(bd);image.Dispose();return threshV alue;}。

最大类间方差法(otsu)的原理

最大类间方差法(otsu)的原理

在网上很多地方都可以找到,但是我发觉似乎都是一样,而且一点注释都没有,如果光拿来用当然可以了,可是用一个算法不搞清楚里面的数学是件很遗憾的事情,我把OTSU的代码加上详细的注释,也算是对自己以后继续努力的一个鞭笞吧!最大类间方差法(otsu)的原理:阈值将原图象分成前景,背景两个图象。

前景:用n1, csum, m1来表示在当前阈值下的前景的点数,质量矩,平均灰度后景:用n2, sum-csum, m2来表示在当前阈值下的背景的点数,质量矩,平均灰度当取最佳阈值时,背景应该与前景差别最大,关键在于如何选择衡量差别的标准而在otsu算法中这个衡量差别的标准就是最大类间方差(英文简称otsu,这也就是这个算法名字的来源)在本程序中类间方差用sb表示,最大类间方差用fmax关于最大类间方差法(otsu)的性能:类间方差法对噪音和目标大小十分敏感,它仅对类间方差为单峰的图像产生较好的分割效果。

当目标与背景的大小比例悬殊时,类间方差准则函数可能呈现双峰或多峰,此时效果不好,但是类间方差法是用时最少的。

最大最大类间方差法(otsu)的公式推导:记t为前景与背景的分割阈值,前景点数占图像比例为w0,平均灰度为u0;背景点数占图像比例为w1,平均灰度为u1。

则图像的总平均灰度为:u=w0*u0+w1*u1。

前景和背景图象的方差:g=w0*(u0-u)*(u0-u)+w1*(u1-u)*(u1-u)=w0*w1*(u0-u1)*(u0-u1),此公式为方差公式,可参照概率论课本上面的g的公式也就是下面程序中的sb的表达式当方差g最大时,可以认为此时前景和背景差异最大,也就是此时的灰度是最佳阈值unsafe public int GetThreshValue(Bitmap image){BitmapData bd = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.WriteOnly, image.PixelFormat);byte* pt = (byte*)bd.Scan0;int[] pixelNum = new int[256]; //图象直方图,共256个点byte color;byte* pline;int n, n1, n2;int total; //total为总和,累计值double m1, m2, sum, csum, fmax, sb; //sb为类间方差,fmax存储最大方差值int k, t, q;int threshValue = 1; // 阈值int step = 1;switch (image.PixelFormat){case PixelFormat.Format24bppRgb:step = 3;break;case PixelFormat.Format32bppArgb:step = 4;break;case PixelFormat.Format8bppIndexed: step = 1;break;}//生成直方图for (int i = 0; i < image.Height; i++){pline = pt + i * bd.Stride;for (int j = 0; j < image.Width; j++){color = *(pline + j * step); //返回各个点的颜色,以RGB表示pixelNum[color]++; //相应的直方图加1}}//直方图平滑化for (k = 0; k <= 255; k++){total = 0;for (t = -2; t <= 2; t++)//与附近2个灰度做平滑化,t值应取较小的值{q = k + t;if (q < 0) //越界处理q = 0;if (q > 255)q = 255;total = total + pixelNum[q]; //total为总和,累计值}pixelNum[k] = (int)((float)total / 5.0 + 0.5); //平滑化,左边2个+中间1个+右边2个灰度,共5个,所以总和除以5,后面加0.5是用修正值}//求阈值sum = csum = 0.0;n = 0;//计算总的图象的点数和质量矩,为后面的计算做准备for (k = 0; k <= 255; k++){sum += (double)k * (double)pixelNum[k]; //x*f(x)质量矩,也就是每个灰度的值乘以其点数(归一化后为概率),sum为其总和n += pixelNum[k]; //n为图象总的点数,归一化后就是累积概率}fmax = -1.0; //类间方差sb不可能为负,所以fmax初始值为-1不影响计算的进行n1 = 0;for (k = 0; k < 255; k++) //对每个灰度(从0到255)计算一次分割后的类间方差sb{n1 += pixelNum[k]; //n1为在当前阈值遍历前景图象的点数if (n1 == 0) { continue; } //没有分出前景后景n2 = n - n1; //n2为背景图象的点数if (n2 == 0) { break; } //n2为0表示全部都是背景图象,与n1=0情况类似,之后的遍历不可能使前景点数增加,所以此时可以退出循环csum += (double)k * pixelNum[k]; //前景的“灰度的值*其点数”的总和m1 = csum / n1; //m1为前景的平均灰度m2 = (sum - csum) / n2; //m2为背景的平均灰度sb = (double)n1 * (double)n2 * (m1 - m2) * (m1 - m2); //sb为类间方差if (sb > fmax) //如果算出的类间方差大于前一次算出的类间方差{fmax = sb; //fmax始终为最大类间方差(otsu)threshValue = k; //取最大类间方差时对应的灰度的k就是最佳阈值}}image.UnlockBits(bd);image.Dispose();如有侵权请联系告知删除,感谢你们的配合!。

otsu算法的工作原理(一)

otsu算法的工作原理(一)

otsu算法的工作原理(一)介绍随着数字图像处理技术的发展,otsu算法越来越被广泛使用。

这篇文章将向您介绍otsu算法的工作原理。

目标学习otsu算法的基本原理,以及在实际图像处理中的应用。

otsu算法otsu算法是处理数字图像的一种算法,可以用来确定图像的二值化阈值。

otsu算法可以自动寻找最佳阈值,以便得到最佳的图像分割结果。

原理otsu算法基于图像灰度值的方差,通过最小化类内方差和最大化类间方差来寻找最佳阈值。

它将图像灰度级划分为两个类别,并根据这些类别的方差计算得到最佳阈值。

实现在实现otsu算法时,需要遵循以下步骤:1.计算图像的直方图,获取每个灰度级的像素数量。

2.对于每个可能的阈值,计算该阈值下像素的类别、类内方差和类间方差。

3.选取最大的类间方差所对应的阈值作为最佳阈值。

应用otsu算法在实际图像处理中被广泛应用。

它可以用来处理包括肿瘤检测、医学影像分析、指纹识别、纸张分割和文本识别等在内的多种图像处理任务。

总结otsu算法是一种寻找最佳阈值的算法。

它利用图像的灰度级和方差来确定最佳阈值,可以自动寻找最佳阈值,以便得到最佳的图像分割结果。

otsu算法在实际图像处理中应用广泛,可以处理多种图像处理任务。

应用举例除了上述提到的医学影像分析、指纹识别和文本识别等应用外,otsu算法还可以用于图像增强和图像分割。

图像增强图像增强是一种将图像转换为更易于分析的形式的技术。

图像增强可以改善图像的质量和可视化效果,同时可以凸显出图像中的重要特征。

otsu算法可以用作图像增强的一种技术,通过选择最佳阈值进行图像二值化,使得底部灰度值较低的像素被转换为黑色,从而提高了图像的对比度和清晰度。

图像分割图像分割是一种将图像分解成具有不同属性的区域的技术。

otsu 算法可以用作一种图像分割技术,通过选择最佳阈值将像素分为前景和背景两类,从而实现图像分割。

这可以用于将感兴趣的物体从背景中分离出来,或者在图像中定位特定的病变区域。

otsu算法的工作原理

otsu算法的工作原理

Otsu算法是一种自适应的二值化方法,其主要思想是将图像分成背景和前景两部分,使得背景和前景之间的类间方差最大,而背景和前景内部的类内方差最小。

具体实现步骤如下:
统计图像的灰度直方图,得到每个灰度级别的像素数量。

计算每个灰度级别的归一化概率和平均灰度值。

遍历所有灰度级别,计算每个灰度级别的类内方差和类间方差。

选择使类间方差最大的灰度级别作为阈值进行二值化。

将图像中小于阈值的像素设为0,大于等于阈值的像素设为255。

通过Otsu 算法,可以得到一个自适应的二值化阈值,能够有效地将背景和前景分离,提高图像的对比度和清晰度,常用于图像分割和边缘检测等领域。

otsu

otsu

C Otsu 自动阈值法分类:3S2007.1.14 19:39 作者:東風耐候| 评论:0 | 阅读:207Otsu(大津法)由大津于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。

C++程序设计如下://Otsu求阈值//输入为图像数据,有可能是数组,也有可能直接就是图像文件里出来的数据,考虑到每行的字节数,和行顺序不一致,所以特意加了一个参数Pitch,用来表示每行数据的字节数int Otsu(BYTE *Data,int Width,int Height,int Pitch){long His[256];double dHis[256];double Fangcha[256];int PXD=0;double Total=Width*Height;int i,j;//循环变量//获取直方图memset(Fangcha,0,256*sizeof(double));memset(His,0,256*sizeof(long) );for(i=0;i<Height;i++)for(j=0;j<Width;j++){His[ *(Data+i*Pitch+j) ] ++;}for(i=0;i<256;i++){dHis[i]=His[i]/Total;}//循环取阈值double w0,w1;//小于阈值的像素在图像中所占的百分比,和大于阈值的像素在图像中所占的百分比double g0,g1;//小于阈值像素的平均值,和大于阈值像素的平均值for(PXD=0;PXD<255;PXD++){g0=0;g1=0;w0=0;w1=0;for(i=0;i<=PXD;i++){g0 +=i*dHis[i];w0 +=dHis[i];}for(i=PXD+1;i<256;i++){g1 +=i*dHis[i];w1 +=dHis[i];}// double u=w0*g0 + w1*g1;//Fangcha[PXD]=w0*(g0-u)*(g0-u) + w1*(g1-u)*(g1-u); //使用等价公式Fangcha[PXD]=w0*w1*(g0-g1)*(g0-g1);}//for(PXD)//寻找最大方差值PXD=0;for(i=0;i<256;i++){if(Fangcha[PXD]<Fangcha[i]){PXD=i;}}return PXD;//返回Otsu阈值}2.另一种二值化ucMaxGrayValue = 0;ucMinGrayValue = 255;for (j = 0; j < pCurPage->pSrcImage->usHeight; j++){jOffset = j * pCurPage->pSrcImage->usRowBytes;for(i = 0; i < pCurPage->pSrcImage->usWidth; i++){bPixel = pCurPage->pSrcImage->lpImage[i+jOffset];plHistogram[bPixel]++;if (ucMinGrayValue > bPixel){ucMinGrayValue = bPixel;}if (ucMaxGrayValue < bPixel){ucMaxGrayValue = bPixel;}}}ucNewThreshold = (ucMinGrayValue + ucMaxGrayValue)/2;ucThreshold = 0;for(usIterationTimes = 0; (ucNewThreshold != ucThreshold) && (usIterationTimes < 100); usIterationTimes++){ucThreshold = ucNewThreshold;lP1 =0;lP2 =0;lS1 = 0;lS2 = 0;for (i = ucMinGrayValue; i < ucThreshold; i++){lP1 += plHistogram[i] * i;lS1 += plHistogram[i];}ucMean1GrayValue = (UCHAR)(lP1 / lS1);for (i = ucThreshold+1; i < ucMaxGrayValue; i++){lP2 += plHistogram[i] * i;lS2 += plHistogram[i];}ucMean2GrayValue = (UCHAR)(lP2 / lS2);ucNewThreshold = (ucMean1GrayValue + ucMean2GrayValue)/2;}2.otsuUCHAR ImageThresholdBlockOtsu(P_PALM_IMAGE pCurrentImage, int beginX, int beginY, int step){for (li = beginX; li < beginX + step && li < pCurrentImage->usWidth ; li++) {//for(lj = beginY;lj < beginY+step&&lj<2400;lj++)for(lj = beginY; lj < beginY + step && lj < pCurrentImage->usHeight; lj++){pucOnePoint = (PUCHAR)pCurrentImage->lpImage + lLineBytes * lj + li;ucpixel = (UCHAR)*pucOnePoint;ihist[ucpixel]++;}}// set up everythingsum = csum = 0.0;n = 0;for (k = 0; k <= 255; k++){sum += (DOUBLE) k * (DOUBLE) ihist[k]; /* x*f(x) 质量矩*/ n += ihist[k]; /* f(x) 质量*/}if (!n){// if n has no value, there is problems...return 0;}// do the otsu global thresholding methodfmax = -1.0;n1 = 0;for (k = 0; k < 255; k++){n1 += ihist[k];if (!n1){continue;}n2 = n - n1;if (n2 == 0){break;}csum += (double) k *ihist[k];m1 = csum / n1;m2 = (sum - csum) / n2;sb = (double) n1 *(double) n2 *(m1 - m2) * (m1 - m2);/* bbg: note: can be optimized. */if (sb > fmax){fmax = sb;thresholdValue = k;}}return thresholdValue;}OTSU 算法可以说是自适应计算单阈值(用来转换灰度图像为二值图像)的简单高效方法。

最大类间方差

最大类间方差

最大类间方差法(统计学术语)
最大类间方差法是由日本学者大津(Nobuyuki Otsu)于1979年提出的,是一种自适合于双峰情况的自动求取阈值的方法,又叫大津法,简称Otsu。

它是按图像的灰度特性,将图像分成背景和目标2部分。

背景和目标之间的类间方差越大,说明构成图像的2部分的差别越大,当部分目标错分为背景或部分背景错分为目标都会导致2部分差别变小。

因此,使类间方差最大的分割意味着错分概率最小。

在Matlab中, graythresh函数使用最大类间方差法获得图像的阈值。

otsu 法 -回复

otsu 法 -回复

otsu 法-回复什么是Otsu法,以及它在图像处理中的应用。

Otsu法是一种基于图像灰度级分割的方法,最早由日本学者大津展之于1979年提出。

它通过计算一个最优的阈值来将图像分成两个部分,从而达到对图像进行二值化的目的。

Otsu法的主要思想是使得分割后的两个部分的类内方差最小,同时使得类间方差最大。

那么首先,什么是类内方差和类间方差呢?类内方差表示的是同一个类内的像素之间的差异,而类间方差则是不同类之间的差异。

Otsu法的目标就是通过计算不同阈值下的类内方差和类间方差,找到一个阈值,使得类内方差最小同时类间方差最大。

具体来说,Otsu法的步骤如下:第一步,计算图像的直方图。

直方图是一个统计图,用于表示不同灰度级出现的频率。

通过统计图可以了解到图像中的颜色分布情况。

第二步,计算不同阈值下的类内方差和类间方差。

使用直方图信息,Otsu法可以计算每个可能的阈值下的类内方差和类间方差。

类内方差可以通过计算两个类别的权重加权总方差来求解,而类间方差则是通过整个图像的方差减去类内方差得到。

第三步,选择最佳阈值。

通过比较不同阈值下的类内方差和类间方差,可以找到使得类内方差最小并且类间方差最大的阈值,这个阈值就是最佳阈值。

第四步,图像二值化。

使用最佳阈值对图像进行二值化处理,将图像分为两个部分。

Otsu法在图像处理中有着广泛的应用。

首先,它可以用于图像分割。

通过将图像分为前景和背景,可以更容易地提取出图像中感兴趣的目标。

其次,Otsu法还可以用于图像增强。

通过对图像进行二值化处理,可以突出显示图像中的特定部分,使得图像更加清晰。

此外,Otsu法还可以用于字符识别、图像分类等领域。

总之,Otsu法是一种基于图像灰度级分割的方法,通过计算最优阈值来对图像进行二值化。

它利用类内方差和类间方差来衡量图像分割的好坏,具有简单高效的特点,并在图像处理中得到了广泛的应用。

otsu阈值处理

otsu阈值处理

otsu阈值处理Otsu阈值处理(又称最大类间方差法、最大类间差法)是一种可以自动计算出最适合于图像分割的阈值的方法,它是根据图像的直方图,在直方图的灰度分布上计算特定的阈值,以进行二值化处理,将其应用于图像分割中,可以自动分割出事先想要的目标物体,可以有效地进行图像处理。

一、Otsu阈值处理的原理Otsu阈值处理是根据图像的直方图,来计算适合进行图像分割的阈值,直方图可以表示出一幅图像中每个灰度值的像素数量,若把图像分成了两个灰度阶段,可以将直方图分成两部分,显然需要寻找一个阈值,使得两个灰度阶段之间的灰度差别最大,从而使分割得到的每个阶段内的灰度变化尽可能小。

Otsu阈值是指所求的最理想阈值,它是根据图像的直方图而计算而出。

二、Otsu阈值处理的算法Otsu阈值处理的核心算法步骤如下:(1)统计灰度分布情况:统计图像中像素点的灰度分布,得到存放像素点的数量信息的一个灰度直方图;(2)计算质量函数:计算灰度直方图中每一灰度的总质量函数,及其最大的类间质量函数;(3)计算最优阈值:根据类间质量函数的曲线,寻找出一个最大的类间质量函数,将图像分割成两部分,找出阈值;(4)图像分割:根据所求出的阈值,将图像分割成背景与目标两部分,就能从图像中提取出想要的目标物体。

三、Otsu阈值处理的应用Otsu阈值处理方法主要用于图像分割,它可以自动提取图像中有用的信息,对于一些不容易判断的图像,或者一些非线性的图像,Otsu阈值处理可以帮助我们有效的分割图像,提取出有用的信息。

另外,Otsu阈值处理还应用在图像的压缩,去噪,边缘检测,二值化等多种图像处理方面都有用武之地。

四、Otsu阈值处理的优缺点Otsu阈值处理的优点在于能有效地进行灰度图像处理,而且只需要给出一个灰度值,即可自动进行图像分割。

缺点在于它只能处理灰度图像,在处理彩色图像时,需要进行额外的颜色变换才能获得分割的效果。

总之,Otsu阈值处理是一种简单易懂的计算机视觉技术,它可以有效的进行图像分割,而且操作会比较简单,节省时间,在图像处理中具有很重要的作用。

otsu 法 -回复

otsu 法 -回复

otsu 法-回复Otsu法是一种用于图像分割的经典算法,其主要目的是将一幅图像分成前景和背景两个部分。

该算法是由日本学者Otsu于1979年提出的,被广泛应用于图像处理、计算机视觉和模式识别领域。

在开始讲述Otsu法的具体过程前,我们先来了解一下图像分割的基本概念和意义。

图像分割是指将一幅图像划分成多个子区域或像素集合的过程。

它是图像处理中的重要一步,通常用于提取目标或感兴趣的区域,进行图像增强、目标识别等后续处理。

图像分割有许多方法,其中Otsu法是一种基于图像灰度级的自适应分割方法。

接下来,我们将详细介绍Otsu法的步骤:步骤1:计算图像的灰度直方图首先,我们需要计算图像的灰度直方图。

灰度直方图是一个统计图,表示不同灰度级别的像素在图像中的分布情况。

通过计算灰度直方图,我们可以获得图像各个灰度级别的像素数量。

步骤2:计算图像的总像素数根据灰度直方图,我们可以计算图像的总像素数。

这可以通过将灰度直方图中的像素数量进行累加来实现。

步骤3:计算图像的每个灰度级别的像素占比在得出图像的总像素数后,我们可以计算图像的每个灰度级别的像素占比。

这可以通过将每个灰度级别的像素数量除以总像素数来实现。

步骤4:计算图像的类间方差类间方差是衡量图像分割的一个重要指标,用于判断图像的分割效果。

它的计算公式是类间方差= 类别1的像素占比* 类别2的像素占比* (类别1的平均灰度值- 类别2的平均灰度值)^2。

通过计算不同阈值下的类间方差,即可得到最佳的分割阈值。

步骤5:选择最佳的分割阈值根据计算得到的不同阈值下的类间方差,我们可以选择使类间方差最大的阈值作为最佳的分割阈值。

最大类间方差的阈值将图像分成前景和背景两个部分。

通过以上几个步骤,我们就可以完成Otsu法对图像的分割。

需要注意的是,Otsu法是一种基于图像灰度级的自适应分割方法,适用于灰度图像的分割。

对于彩色图像的分割,可以先将图像转换为灰度图像,再进行分割。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Otsu算法(大律法或最大类间方差法)一、Otsu最大类间方差法原理利用阈值将原图像分成前景,背景两个图象。

前景:用n1,csum,m1来表示在当前阈值下的前景的点数,质量矩,平均灰度后景:用n2, sum-csum,m2来表示在当前阈值下的背景的点数,质量矩,平均灰度当取最佳阈值时,背景应该与前景差别最大,关键在于如何选择衡量差别的标准,而在otsu算法中这个衡量差别的标准就是最大类间方差(英文简称otsu,这也就是这个算法名字的来源),在本程序中类间方差用sb表示,最大类间方差用fmax 关于最大类间方差法(otsu)的性能:类间方差法对噪音和目标大小十分敏感,它仅对类间方差为单峰的图像产生较好的分割效果。

当目标与背景的大小比例悬殊时,类间方差准则函数可能呈现双峰或多峰,此时效果不好,但是类间方差法是用时最少的。

最大类间方差法(otsu)的公式推导:记t为前景与背景的分割阈值,前景点数占图像比例为w0,平均灰度为u0;背景点数占图像比例为w1,平均灰度为u1。

则图像的总平均灰度为:u=w0*u0+w1*u1。

前景和背景图象的方差:g=w0*(u0-u)*(u0-u)+w1*(u1-u)*(u1-u)=w0*w1*(u0-u1)*(u0-u1),此公式为方差公式。

可参照概率论课本上面的g的公式也就是下面程序中的sb的表达式。

当方差g最大时,可以认为此时前景和背景差异最大,此时的灰度t是最佳阈值sb = w1*w2*(u1-u0)*(u0-u1)算法实现1:unsafe public int GetThreshValue(Bitmap image){BitmapData bd = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.WriteOnly, image.PixelFormat);byte* pt = (byte*)bd.Scan0;int[] pixelNum = new int[256]; //图象直方图,共256个点byte color;byte* pline;int n, n1, n2;int total; //total为总和,累计值double m1, m2, sum, csum, fmax, sb; //sb为类间方差,fmax存储最大方差值int k, t, q;int threshValue = 1; // 阈值int step = 1;switch (image.PixelFormat){case PixelFormat.Format24bppRgb:step = 3;break;case PixelFormat.Format32bppArgb:step = 4;break;case PixelFormat.Format8bppIndexed:step = 1;break;}//生成直方图for (int i = 0; i < image.Height; i++){pline = pt + i * bd.Stride;for (int j = 0; j < image.Width; j++){color = *(pline + j * step); //返回各个点的颜色,以RGB表示pixelNum[color]++; //相应的直方图加1}}//直方图平滑化for (k = 0; k <= 255; k++){total = 0;for (t = -2; t <= 2; t++) //与附近2个灰度做平滑化,t值应取较小的值{q = k + t;if (q < 0) //越界处理q = 0;if (q > 255)q = 255;total = total + pixelNum[q]; //total为总和,累计值}//平滑化,左边2个+中间1个+右边2个灰度,共5个,所以总和除以5,后面加0.5是用修正值pixelNum[k] = (int)((float)total / 5.0 + 0.5);}//求阈值sum = csum = 0.0;n = 0;//计算总的图象的点数和质量矩,为后面的计算做准备for (k = 0; k <= 255; k++){//x*f(x)质量矩,也就是每个灰度的值乘以其点数(归一化后为概率),sum为其总和sum += (double)k * (double)pixelNum[k];n += pixelNum[k]; //n为图象总的点数,归一化后就是累积概率}fmax = -1.0; //类间方差sb不可能为负,所以fmax初始值为-1不影响计算的进行n1 = 0;for (k = 0; k < 255; k++) //对每个灰度(从0到255)计算一次分割后的类间方差sb{n1 += pixelNum[k]; //n1为在当前阈值遍前景图象的点数if (n1 == 0) { continue; } //没有分出前景后景n2 = n - n1; //n2为背景图象的点数//n2为0表示全部都是后景图象,与n1=0情况类似,之后的遍历不可能使前景点数增加,所以此时可以退出循环if (n2 == 0) { break; }csum += (double)k * pixelNum[k]; //前景的“灰度的值*其点数”的总和m1 = csum / n1; //m1为前景的平均灰度m2 = (sum - csum) / n2; //m2为背景的平均灰度sb = (double)n1 * (double)n2 * (m1 - m2) * (m1 - m2); //sb为类间方差if (sb > fmax) //如果算出的类间方差大于前一次算出的类间方差{fmax = sb; //fmax始终为最大类间方差(otsu)threshValue = k; //取最大类间方差时对应的灰度的k就是最佳阈值}}image.UnlockBits(bd);image.Dispose();return threshValue;}算法实现2:Otsu算法步骤如下:设图象包含L个灰度级(0,1…,L-1),灰度值为i的的象素点数为Ni ,图象总的象素点数为N=N0+N1+...+N(L-1)。

灰度值为i的点的概率为:P(i) = N(i)/N.门限t将整幅图象分为暗区c1和亮区c2两类,则类间方差σ是t的函数:σ=a1*a2(u1-u2)^2 (2) 式中,aj 为类cj的面积与图象总面积之比,a1=sum(P(i)) i->t, a2 = 1-a1;uj为类cj的均值,u1 = sum(i*P(i))/a1 0->t, u2 = sum(i*P(i))/a2, t+1->L-1,该法选择最佳门限t^使类间方差最大,即:令Δu=u1-u2,σb = max{a1(t)*a2(t)Δu^2}代码实现:int otsu (IplImage *image, int rows, int cols, int x0, int y0, int dx, int dy, int vvv){unsigned char *np; // 图像指针int thresholdValue=1; // 阈值int ihist[256]; // 图像直方图,256个点int i, j, k; // various countersint n, n1, n2, gmin, gmax;double m1, m2, sum, csum, fmax, sb;// 对直方图置零memset(ihist, 0, sizeof(ihist));gmin=255; gmax=0;// 生成直方图/*for (i = y0 + 1; i < y0 + dy - 1; i++){np = &image[i*cols+x0+1];for (j = x0 + 1; j < x0 + dx - 1; j++){ihist[*np]++;if(*np > gmax) gmax=*np;if(*np < gmin) gmin=*np;np++; /* next pixel}}*/for(j=y0;j<dy;j++){for(i=0;i<dx;i++){unsigned char temp=CV_IMAGE_ELEM(image,uchar,j,i);ihist[temp]++;}}// set up everythingsum = csum = 0.0;n = 0;for (k = 0; k <= 255; k++){sum += (double) k * (double) ihist[k]; // x*f(x) 质量矩n += ihist[k]; //f(x) 质量}if (!n){// if n has no value, there is problemsfprintf (stderr, "NOT NORMAL thresholdValue = 160\n");return (160);}// do the otsu global thresholding methodfmax = -1.0;n1 = 0;for (k = 0; k < 255; k++){n1 += ihist[k];if (!n1) { continue; }n2 = n - n1;if (n2 == 0) { break; }csum += (double) k *ihist[k];m1 = csum / n1;m2 = (sum - csum) / n2;sb = (double) n1 *(double) n2 *(m1 - m2) * (m1 - m2);/**//* bbg: note: can be optimized. */if (sb > fmax) {fmax = sb;thresholdValue = k;}}// at this point we have our thresholding value,debug code to display thresholding valuesif ( vvv & 1 )fprintf(stderr,"# OTSU: thresholdValue = %d gmin=%d gmax=%d\n",thresholdValue, gmin, gmax);return(thresholdValue);}。

相关文档
最新文档