您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 商业计划书 > 图像二值化阈值选取常用方法汇总
图像二值化阈值选取常用方法最近在公司搞车牌识别的项目,车牌定位后,发现对车牌区域二值化的好坏直接影响后面字符切分的过程,所以就想把常用阈值选取方法做一个总结。图像二值化阈值选取常用方法: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()*TtptPmn最小。P参数法一般用于固定分辨率下,目标所占整个图像比例已知的情况。3.最大类间方差法(Otsu)最大类间方差法是由Otsu于1979年提出的,是基于整幅图像的统计特性实现阈值的自动选取的,是全局二值化最杰出的代表。Otsu算法的基本思想是用某一假定的灰度值t将图像的灰度分成两组,当两组的类间方差最大时,此灰度值t就是图像二值化的最佳阈值。设图像有L个灰度值,取值范围在0~L-1,在此范围内选取灰度值T,将图像分成两组G0和G1,G0包含的像素的灰度值在0~T,G1的灰度值在T+1~L-1,用N表示图像像素总数,in表示灰度值为i的像素的个数。已知:每一个灰度值i出现的概率为/iipnN;假设G0和G1两组像素的个数在整体图像中所占百分比为01、,两组平均灰度值为01、,可得概率:00=Tiip11011LiiTp平均灰度值:00Tiiip111LiiTip图像总的平均灰度值:0011类间方差:22200110101()gt最佳阈值为:T=argmax(g(t))使得间类方差最大时所对应的t值。算法可这样理解:阈值T将整幅图像分成前景和背景两部分,当两类的类间方差最大时,此时前景和背景的差别最大,二值化效果最好。因为方差是灰度分布均匀性的一种度量,方差值越大,说明构成图像的两部分差别越大,当部分目标错分为背景或部分背景错分为目标都会导致两部分差别变小,因此使类间方差最大的分割阈值意味着错分概率最小。大律法得到了广泛的应用,但是当物体目标与背景灰度差不明显时,会出现无法忍受的大块黑色区域,甚至会丢失整幅图像的信息。以下为一段基于OpenCV的Otsu代码:BYTEGetPixel(IplImage*img,intx,inty){if(x0||x=img-width||y0||y=img-height)return0;returnimg-imageData[y*img-widthStep+x];}voidSetPixel(IplImage*img,intx,inty,BYTEval){if(x0||x=img-width||y0||y=img-height)return;img-imageData[y*img-widthStep+x]=val;}#ifndefEPSILON#defineEPSILON1e-6#endif/**Function:用Otsu(1979)阈值对图像二值化*Parameters:*[IN]img:要二值化的灰度图像*[OUT]out:二值化的输出图像,要求调用者分配好空间*Return:(None)*/voidOtsu(IplImage*img,IplImage*out){inthist[256],i,j,total,maxk;floatut,uk;/*ut表示整个图像的均值*/floatp[256],sigma,wk,maxs;/*得到灰度直方图*/memset(hist,0,sizeof(int)*256);total=img-width*img-height;for(i=0;iimg-height;i++){for(j=0;jimg-width;j++){hist[GetPixel(img,j,i)]++;}}/*计算大津阈值*/ut=0;for(i=0;i256;i++){p[i]=(float)hist[i]/total;ut+=i*hist[i];}ut/=total;wk=.0;uk=.0;maxs=.0;for(i=0;i256;i++){4、最大熵阈值法将信息论中的shannon熵概念用于图像分割,其依据是使得图像中目标与背景分布的信息量最大,即通过测量图像灰度直方图的熵,找出最佳阈值。根据shannon熵的概念,对于灰度范围为0,1,2,…,L-1的图像,其直方图的熵定义为(仅仅是定义):10,LiiiHipp为像素值为i的像素占整个图像的概率。设阈值t将图像划分为目标O和背景B两类,他们的概率分布分别为:uk+=i*p[i];wk+=p[i];if(wk=EPSILON||wk=1.0f-EPSILON){continue;}sigma=(ut*wk-uk);sigma=sigma*sigma/(wk*(1.0f-wk));if(sigmamaxs){maxs=sigma;maxk=i;}}/*得到了阈值,对原图像分割*/for(i=0;iimg-height;i++){for(j=0;jimg-width;j++){if(GetPixel(img,j,i)=maxk){SetPixel(out,j,i,0);}else{SetPixel(out,j,i,255);}}}}O区:,0,1,...,itpitp,其中0ttiippB区:,1,...,11itpitLp则目标O和背景B的熵函数分别为:0lnlntiitOtitttppHHtPPPP,其中0lnttiiiHpp11lnln1111LiitBtittttppHHHtPPPP,其中10lnLiiiHpp图像的总熵为:ln11ttOBttttHHHHtHtHtPPPP最佳阈值T为使得图像的总熵取得最大值:T=argmax(H(t))此方法不需要先验知识,而且对于非理想双峰直方图的图像也可以进行较好的分割。缺点是运算速度较慢不适合实时处理。仅仅考虑了像素点的灰度信息,没有考虑到像素点的空间信息,所以当图像的信噪比较低时分割效果不理想。以下为一段基于Opencv最大熵阈值算法例子:#includestdafx.h#includecv.h#includehighgui.h#pragmacomment(lib,highgui.lib)#pragmacomment(lib,cv.lib)#pragmacomment(lib,cvaux.lib)#pragmacomment(lib,cxcore.lib)intHistogramBins=256;floatHistogramRange1[2]={0,255};float*HistogramRange[1]={&HistogramRange1[0]};typedefenum{back,object}entropy_state;doublecaculateCurrentEntropy(CvHistogram*Histogram1,intcur_threshold,entropy_statestate){intstart,end;if(state==back){start=0;end=cur_threshold;}else{start=cur_threshold;end=256;}inttotal=0;for(inti=start;iend;i++){total+=(int)cvQueryHistValue_1D(Histogram1,i);}doublecur_entropy=0.0;for(inti=start;iend;i++){if((int)cvQueryHistValue_1D(Histogram1,i)==0){continue;}doublepercentage=cvQueryHistValue_1D(Histogram1,i)/total;cur_entropy+=-percentage*logf(percentage);}returncur_entropy;}voidMaxEntropy(IplImage*src,IplImage*dst){assert(src!=NULL);assert(src-depth==8&&dst-depth==8);assert(src-nChannels==1);CvHistogram*hist=cvCreateHist(1,&HistogramBins,CV_HIST_ARRAY,HistogramRange);cvCalcHist(&src,hist);doublemaxentropy=-1.0;intmax_index=-1;for(inti=0;iHistogramBins;i++){doublecur_entropy=caculateCurrentEntropy(hist,i,object)+caculateCurrentEntropy(hist,i,back);if(cur_entropymaxentropy){maxentropy=cur_entropy;max_index=i;}}cvThreshold(src,dst,(double)max_index,255,CV_THRESH_BINARY);5、迭代法(最佳阈值法)迭代法是基于逼近的思想,迭代阈值的获取步骤可以归纳如下:1)选择一个初始阈值T(j),通常可以选择整体图像的平均灰度值作为初始阈值。j为迭代次数,初始时j=0。2)用T(j)分割图像,将图像分为2个区域1jC和2jC。3)计算两区域的平均灰度值,其中1jN、2jN为第j次迭代时区域C1和C2的像素点个数,f(x,y)表示图像中(x,y)点的灰度值。11,11,jjjfxyCfxyN22,21,jjjfxyCfxyN4)再计算新的门限值,即1212jjTj5)令j=j+1,重复2~4),直到T(j+1)与T(j)的差小于规定值或j达到最大的迭代次数。以下为基于OpenCV的代码:cvReleaseHist(&hist);}intmain(intargc,_TCHAR*argv[]){IplImage*src;//声明IplImage指针//载入图像if(argc==2&&(src=cvLoadImage(argv[1],CV_LOAD_IMAGE_GRAYSCALE))!=0){cvNamedWindow(Image,1);//创建窗口IplImage*dst=cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);MaxEntropy(src,dst);cvShowImage(Image,dst);//显示图像cvWaitKey(0);//等待按键cvDestroyWindow(Image);//销毁窗口cvReleaseImage(&src);//释放图像cvReleaseImage(&dst);//释放图像return0;}return-1;}/*======================================================================*
本文标题:图像二值化阈值选取常用方法汇总
链接地址:https://www.777doc.com/doc-3141282 .html