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