您好,欢迎访问三七文档
分享到一键分享QQ空间新浪微博百度云收藏人人网腾讯微博百度相册开心网腾讯朋友百度贴吧豆瓣网搜狐微博百度新首页QQ好友和讯微博更多...百度分享登录|注册窗体顶端toolbar窗体底端收藏成功确定收藏失败,请重新收藏确定窗体顶端标题灰度图像阈值化标题不能为空网址文档提问题写博客传资源创建项目创建代码片设置昵称编辑自我介绍,让更多人了解你帐号设置退出社区博客论坛下载Share极客头条服务CODE英雄会活动CSTO俱乐部CTO俱乐部高校俱乐部奋斗斌斌的专栏解决项目中的琐碎细节问题b.zhao_npu@hotmail.com目录视图摘要视图订阅有奖征资源,博文分享有内涵人气博主的资源共享:老罗的Android之旅微软Azure•英雄会编程大赛题关注CSDN社区微信,福利多多社区问答:叶劲峰游戏引擎架构灰度图像阈值化分割常见方法总结及VC实现分类:图像处理OpenCV2011-11-1123:207427人阅读评论(14)收藏举报算法图形byte图像处理扩展目录(?)[+]Otsu法最大类间方差法一维交叉熵值法二维OTSU法参考文献在图像处理领域,二值图像运算量小,并且能够体现图像的关键特征,因此被广泛使用。将灰度图像变为二值图像的常用方法是选定阈值,然后将待处理图像的每个像素点进行单点处理,即将其灰度值与所设置的门限进行比对,从而得到二值化的黑白图。这样一种方式因为其直观性以及易于实现,已经在图像分割领域处于中心地位。本文主要对最近一段时间作者所学习的阈值化图像分割算法进行总结,全文描述了作者对每种算法的理解,并基于OpenCV和VC6.0对这些算法进行了实现。最终将源代码公开,希望大家一起进步。(本文的代码暂时没有考虑执行效率问题)首先给出待分割的图像如下:1、Otsu法(最大类间方差法)该算法是日本人Otsu提出的一种动态阈值分割算法。它的主要思想是按照灰度特性将图像划分为背景和目标2部分,划分依据为选取门限值,使得背景和目标之间的方差最大。(背景和目标之间的类间方差越大,说明这两部分的差别越大,当部分目标被错划分为背景或部分背景错划分为目标都会导致这两部分差别变小。因此,使用类间方差最大的分割意味着错分概率最小。)这是该方法的主要思路。其主要的实现原理为如下:1)建立图像灰度直方图(共有L个灰度级,每个出现概率为p)2)计算背景和目标的出现概率,计算方法如下:上式中假设t为所选定的阈值,A代表背景(灰度级为0~N),根据直方图中的元素可知,Pa为背景出现的概率,同理B为目标,Pb为目标出现的概率。3)计算A和B两个区域的类间方差如下:第一个表达式分别计算A和B区域的平均灰度值;第二个表达式计算灰度图像全局的灰度平均值;第三个表达式计算A、B两个区域的类间方差。4)以上几个步骤计算出了单个灰度值上的类间方差,因此最佳分割门限值应该是图像中能够使得A与B的类间灰度方差最大的灰度值。在程序中需要对每个出现的灰度值据此进行寻优。本人的VC实现代码如下。[cpp]viewplaincopyprint?/*******************************************************************************\函数名称:*OneDimentionOtsu()**\输入参数:*pGrayMat:二值图像数据*width:图形尺寸宽度*height:图形尺寸高度*nTlreshold:经过算法处理得到的二值化分割阈值*\返回值:*无*\函数说明:实现灰度图的二值化分割——最大类间方差法(Otsu算法,俗称大津算法)*****************************************************************************/voidCBinarizationDlg::OneDimentionOtsu(CvMat*pGrayMat,intwidth,intheight,BYTE&nThreshold){doublenHistogram[256];//灰度直方图doubledVariance[256];//类间方差intN=height*width;//总像素数for(inti=0;i256;i++){nHistogram[i]=0.0;dVariance[i]=0.0;}for(i=0;iheight;i++){for(intj=0;jwidth;j++){unsignedcharnData=(unsignedchar)cvmGet(pGrayMat,i,j);nHistogram[nData]++;//建立直方图}}doublePa=0.0;//背景出现概率doublePb=0.0;//目标出现概率doubleWa=0.0;//背景平均灰度值doubleWb=0.0;//目标平均灰度值doubleW0=0.0;//全局平均灰度值doubledData1=0.0,dData2=0.0;for(i=0;i256;i++)//计算全局平均灰度{nHistogram[i]/=N;W0+=i*nHistogram[i];}for(i=0;i256;i++)//对每个灰度值计算类间方差{Pa+=nHistogram[i];Pb=1-Pa;dData1+=i*nHistogram[i];dData2=W0-dData1;Wa=dData1/Pa;Wb=dData2/Pb;dVariance[i]=(Pa*Pb*pow((Wb-Wa),2));}//遍历每个方差,求取类间最大方差所对应的灰度值doubletemp=0.0;for(i=0;i256;i++){if(dVariance[i]temp){temp=dVariance[i];nThreshold=i;}}}/*******************************************************************************\函数名称:*OneDimentionOtsu()**\输入参数:*pGrayMat:二值图像数据*width:图形尺寸宽度*height:图形尺寸高度*nTlreshold:经过算法处理得到的二值化分割阈值*\返回值:*无*\函数说明:实现灰度图的二值化分割——最大类间方差法(Otsu算法,俗称大津算法)*****************************************************************************/voidCBinarizationDlg::OneDimentionOtsu(CvMat*pGrayMat,intwidth,intheight,BYTE&nThreshold){doublenHistogram[256];//灰度直方图doubledVariance[256];//类间方差intN=height*width;//总像素数for(inti=0;i256;i++){nHistogram[i]=0.0;dVariance[i]=0.0;}for(i=0;iheight;i++){for(intj=0;jwidth;j++){unsignedcharnData=(unsignedchar)cvmGet(pGrayMat,i,j);nHistogram[nData]++;//建立直方图}}doublePa=0.0;//背景出现概率doublePb=0.0;//目标出现概率doubleWa=0.0;//背景平均灰度值doubleWb=0.0;//目标平均灰度值doubleW0=0.0;//全局平均灰度值doubledData1=0.0,dData2=0.0;for(i=0;i256;i++)//计算全局平均灰度{nHistogram[i]/=N;W0+=i*nHistogram[i];}for(i=0;i256;i++)//对每个灰度值计算类间方差{Pa+=nHistogram[i];Pb=1-Pa;dData1+=i*nHistogram[i];dData2=W0-dData1;Wa=dData1/Pa;Wb=dData2/Pb;dVariance[i]=(Pa*Pb*pow((Wb-Wa),2));}//遍历每个方差,求取类间最大方差所对应的灰度值doubletemp=0.0;for(i=0;i256;i++){if(dVariance[i]temp){temp=dVariance[i];nThreshold=i;}}}阈值分割结果如下图,求解所得的阈值为116.2、一维交叉熵值法这种方法与类间最大方差很相似,是由Li和Lee应用了信息论中熵理论发展而来。首先简要介绍交叉熵的概念。对于两个分布P和Q,定义其信息交叉熵D如下:这代表的物理意义是两个分布之间信息理论距离,另外一种理解是,将分布P变为Q后所带来的信息变化。那么对于图像分割来说,如果要用分割图像来替换原来的图像,最优的分割依据应该就是使得两幅图像之间的交叉熵最小。以下对最小交叉熵法的过程进行简要总结。可以假设上文的P为源图像的灰度分布,Q为所得到的分割图像的灰度分布,其中:上式中H为统计直方图;N为图像总的像素点数;L为源图像总的灰度级数;P代表源图像,其每个元素代表每个灰度级上的灰度分布(平均灰度值);Q为分割后的二值图像,两个u分别代表两个分割后的区域的平均灰度值,其中t为分割图像所采用的阈值。根据以上定义,以每个灰度级上的灰度和为计算量,可以很容易根据交叉熵的公式,推导出P和Q之间的交叉熵定量表达式:根据上文所述思路,使得D最小的t即为最小交叉熵意义下的最优阈值。作者VC实现代码如下。[cpp]viewplaincopyprint?/*******************************************************************************\函数名称:*MiniCross()**\输入参数:*pGrayMat:二值图像数据*width:图形尺寸宽度*height:图形尺寸高度*nTlreshold:经过算法处理得到的二值化分割阈值*\返回值:*无*\函数说明:实现灰度图的二值化分割——最小交叉熵算法*****************************************************************************/voidCBinarizationDlg::MiniCross(CvMat*pGrayMat,intwidth,intheight,BYTE&nThreshold){doubledHistogram[256];//灰度直方图doubledEntropy[256];//每个像素的交叉熵intN=height*width;//总像素数for(inti=0;i256;i++){dHistogram[i]=0.0;dEntropy[i]=0.0;}for(i=0;iheight;i++){for(intj=0;jwidth;j++){unsignedcharnData=(unsignedchar)cvmGet(pGrayMat,i,j);dHistogram[nData]++;//建立直方图}}doublePa=0.0;//区域1平均灰度值doublePb=0.0;//区域2平均灰度值doubleP0=0.0;//全局平均灰度值doubleWa=0.0;//第一部分熵doubleWb=0.0;//第二部分的熵doubledData1=0.0,dData2=0.0;//中间值doubledData3=0.0,dData4=0.0;//中间值for(i=0;i256;i++)//计算全局平均灰度{dHistogram[i]/=N;P0+=i*dHistogram[i];}for(i=0;i256;i++){Wa
本文标题:灰度阈值分割算法
链接地址:https://www.777doc.com/doc-3217727 .html