热点推荐

查看: 1752|回复: 4
收起左侧

[资料] Halcon阈值化算子dual_threshold和var_threshold的理解

[复制链接]
  • TA的每日心情
    萌萌
    2019-2-25 12:21
  • 签到天数: 29 天

    连续签到: 1 天

    [LV.4]偶尔看看III

    10

    主题

    30

    帖子

    494

    积分

    Rank: 2Rank: 2

    积分
    494
    发表于 2018-1-24 15:55:40 | 显示全部楼层 |阅读模式

    51Halcon诚邀您的加入,专注于机器视觉开发与应用技术,我们一直都在努力!

    您需要 登录 才可以下载或查看,没有帐号?会员注册

    x
    Halcon中阈值二值化的算子众多,通常用得最多的有threshold、binary_threshold、dyn_threshold等。
    threshold是最简单的阈值分割算子,理解最为简单;binary_threshold是自动阈值算子,它可以自动选出暗(dark)的区域,或者自动选出亮(light)的区域,理解起来也没有难度。

    动态阈值算子dyn_threshold理解起来稍微复杂一点,使用dyn_threshold算子的步骤基本是这样的:
    ① 将原图进行滤波平滑处理。
    ② 用原图和平滑后的图逐个像素做比较,它可以根据参数分割出原图比平滑后的图灰度高(或者低)若干个灰度值的区域。
    举例如下:
    1002191-20170209225518541-258147306.jpg
    处理程序是这样的:
    1. read_image (Image, 'C:/Users/happy xia/Desktop/dynPic.png')
    2. mean_image (Image, ImageMean, 9, 9)
    3. dyn_threshold (Image, ImageMean, RegionDynThresh, 10, 'dark')
    复制代码
    程序分析:本例中,将图片模糊后,点阵字的黑色扩散了,随之就是字的黑色不如原图那么黑了,那么通过给定的限值“10”和“dark”,就可以将原图比模糊后的图暗10个灰阶以上的区域(即黑色文字部分)选出来了。

    以上所说的三个算子并不是本文的重点,但却是理解下面的两个阈值分割算子的准备知识。
    1、dual_threshold
    先看程序和效果图再分析。
    1002191-20170209231616822-1772002850.png
    1. read_image (Image, 'C:/Users/happy xia/Desktop/2.png')
    2. dual_threshold (Image, RegionCrossings, 174, 200, 180)
    复制代码
    1002191-20170209232425010-1259922116.png
    dual_threshold(Image : RegionCrossings : MinSize, MinGray, Threshold : )
    该算子签名中:Threshold 表示用于分割的阈值数值,MinSize表示分割出来的区域的最小面积(即数像素的数目个数),MinGray表示分割出来的区域对应的原图中图像像素的最高灰度不能低于MinGray设定值。
    注意图中蓝色矩形小色块的面积是175个像素,因此当MinSize = 174时,它可以被分割出来。
    OK,我知道这么说比较拗口。下面我边改变参数边观察效果图,并做简要分析:
    1. read_image (Image, 'C:/Users/happy xia/Desktop/2.png')
    2. dual_threshold (Image, RegionCrossings, 176, 200, 180)
    复制代码
    效果图如下:
    1002191-20170209232940807-840114550.png
    由于最小面积设置为176,那么面积为175像素的矩形小色块就没有被分割出来。
    再来改变MinGray参数:
    1. read_image (Image, 'C:/Users/happy xia/Desktop/2.png')
    2. dual_threshold (Image, RegionCrossings, 176, 216, 180)
    复制代码
    1002191-20170209232940807-840114550.png
    此时观察到,最右边那个齿轮本来分割出来的区域没有了!
    通过取色器观察可知,这块区域最亮的灰度大概比211高一点点。
    1002191-20170209233757479-590819841.png
    我们把这个值略微调低再看看:
    1. read_image (Image, 'C:/Users/happy xia/Desktop/2.png')
    2. dual_threshold (Image, RegionCrossings, 176, 210, 180)
    复制代码
    1002191-20170209232940807-840114550.png
    最右边那个齿轮右下角那一块又被分割出来了!

    相信通过这样参数的反复调节,大家已经彻底明白了dual_threshold算子的意义和用法。

    我们看这个算子的名称——dual是“双”的意思,也就是双阈值。如果我们让参数列表中的MinGray = Threshold,那就是单阈值了。
    1. read_image (Image, 'C:/Users/happy xia/Desktop/2.png')
    2. dual_threshold (Image, RegionCrossings, 176, 180, 180)
    复制代码
    这个算子是很高效的。如果要完成上面这个程序这样的功能,用threshold算子的话,代码要这样写:
    1. read_image (Image, 'C:/Users/happy xia/Desktop/2.png')
    2. threshold (Image, Region, 180, 255)
    3. connection (Region, ConnectedRegions)
    4. select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 176, 9999999)
    复制代码
    也就是说dual_threshold一条算子顶这三条算子。
    dual_threshold算子的缺陷:它只能分割出灰度值高的亮区域,不能分割出灰度值低的暗区域。
    下面介绍var_threshold算子。

    2、var_threshold

    先看var_threshold算子的签名:
    var_threshold(Image : Region : MaskWidth, MaskHeight, StdDevScale, AbsThreshold, LightDark : )
    MaskWidth、 MaskHeight是用于滤波平滑的掩膜单元;StdDevScale是标准差乘数因子(简称标准差因子);AbsThreshold是设定的绝对阈值;LightDark有4个值可选,'light'、'dark'、'equal'、'not_equal'

    需要强调的是var_threshold算子和dyn_threshold算子极为类似。不同的是var_threshold集成度更高,并且加入了“标准差×标准差因子”这一变量。
    举例:
    1002191-20170210151411354-1816148769.png
    1. read_image (Image, 'C:/1.png')
    2. var_threshold (Image, Region, 4, 4, 0.2, 12, 'dark')
    复制代码
    1002191-20170210151528182-1667239949.jpg
    在该程序中,先用4×4的掩膜在图像上逐像素游走,用原图中的当前像素和对应掩膜中16个像素的灰度均值对比,找出暗(dark)的区域。当原图像素灰度比对应的掩膜灰度均值低(0.2,12)个灰阶时,该区域被分割出来。本程序中StdDevScale = 0.2, AbsThreshold = 12,问题的关键就是理解如何通过StdDevScaleAbsThreshold来确定用于分割的阈值。

    发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

    如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题前面加上【已解决】

    回报帮助你解决问题的坛友,右下角【免费评分】赠与对方视觉币和热心值,伸手党遭人唾弃,做一个热心并受欢迎的人!

    面向企业销售智能软件带相机和镜头,仅需3500,来电咨询 15019223858  18520862540
  • TA的每日心情
    萌萌
    2019-2-25 12:21
  • 签到天数: 29 天

    连续签到: 1 天

    [LV.4]偶尔看看III

    10

    主题

    30

    帖子

    494

    积分

    Rank: 2Rank: 2

    积分
    494
     楼主| 发表于 2018-1-24 15:56:03 | 显示全部楼层
    var_threshold的帮助文档中是这么写的:
    1002191-20170210152521104-1973867637.jpg
    说明:
    1、d(x,y)指的是遍历每个像素时,掩膜覆盖的那些像素块(本例中是4×4 = 16个像素)灰度的标准差;StdDevScale 是标准差因子。
    2、当标准差因子StdDevScale ≥ 0 时,v(x,y) 取(StdDevScale ×标准差)和AbsThreshold 中较大的那个。
    3、当标准差因子StdDevScale < 0 时,v(x,y) 取(StdDevScale ×标准差)和AbsThreshold 中较小的那个。实测发现,这里的比较大小是带符号比较,由于标准差是非负数,当StdDevScale < 0 时,(StdDevScale ×标准差)≤ 0恒成立。所以此时的取值就是(StdDevScale ×标准差)。

    文档是这么说的:
    If StdDevScale*dev(x,y) is below AbsThreshold for positive values of StdDevScale or above for negative values StdDevScale, AbsThreshold is taken instead.
    大致意思是:
    当StdDevScale为正时,如果StdDevScale*dev(x,y) 低于 AbsThreshold,则采用AbsThreshold。
    当StdDevScale为负时,如果StdDevScale*dev(x,y) 高于 AbsThreshold,则采用AbsThreshold。

    我找了一块黑白过渡处4×4的像素块,求得它的灰度标准差为51.16(或49.53):
    1002191-20170210154155869-673346347.png
    1002191-20170210154300385-404091463.png
    帮助文档中StdDevScale 的推荐值范围是-1~1,一般通过上面的例子可知,一般的明显的黑白过度处的标准差在50左右,乘以StdDevScale即-50 ~ 50 ,50的灰度差异,对于分割来说一般是够了的。
    文档还说:推荐的值是0.2,如果参数StdDevScale太大,可能分割不出任何东西;如果参数StdDevScale太小(例如-2),可能会把整个图像区域全部输出,也就说达不到有效分割的目的。(……with 0.2 as a suggested value. If the parameter is too high or too low, an empty or full region may be returned.)

    最后再看看是怎么分割像素的:
    1002191-20170210161338885-896535788.png
    其中g(x,y)指的是原始图像当前像素的灰度值;m(x,y)指的是遍历像素时,掩膜覆盖的像素的平均灰度值(mean)。
    LightDark = ‘dark’为例,当满足m(x,y) - g(x,y) ≥ v(x,y)时(即原始图像对应像素灰度比掩膜像素灰度均值低v(x,y)个灰度值以上),相应的灰度值低的暗像素被分割出来。

    最后看几个例子体会一下:(对比之前的例子var_threshold (Image, Region, 4, 4, 0.2, 12, 'dark')的效果)
    ① 将AbsThreshold 由12改成30,此时分割出的区域变小。
    1. read_image (Image, 'C:/1.png')
    2. var_threshold (Image, Region, 4, 4, 0.2, 30, 'dark')
    复制代码
    1002191-20170210162704697-1048977266.jpg
    AbsThreshold 保持12不变,将StdDevScale由0.2改成0.7,此时分割出的区域变小。
    1002191-20170210163008588-1599035080.jpg
    ③ 将参数改为var_threshold (Image, Region, 4, 4, -0.01, 12, 'dark'),此时分割出的区域大大增加,由前面的分析可知,此时参数AbsThreshold = 12无效,事实上,此时将AbsThreshold 改为1、50甚至200都对最终结果没有任何影响。
    1002191-20170210163505651-1275175898.jpg
    通过本人的分析,我认为StdDevScale取负值意义不大,因为它会分割出大量的不需要的区域,故一般推荐使用该算子时,StdDevScale取正值。

    需要强调的是:在黑白过渡处,一般掩膜覆盖的像素的标准差较大,而在其他平缓的地方,标准差较小;因此最终采用的分割阈值随着掩膜在不断遍历像素的过程中,在(StdDevScale×标准差)和AbsThreshold 之间不断切换。

    var_threshold和dyn_threshold的区别和联系:

    dyn_threshold是将原图和滤波平滑后的图对比,var_threshold是将原图和对应像素掩膜覆盖的像素的平均灰度值对比。

    在算子var_threshold中,如果参数StdDevScale = 0,那么就可以用动态阈值的方式非常近似地模拟。以下两种算法的效果极为类似:
    1. read_image (Image, 'C:/1.png')
    2. var_threshold (Image, Region, 4, 4, 0, 12, 'dark')
    复制代码
    1. read_image (Image, 'C:/1.png')
    2. mean_image (Image, ImageMean, 4, 4)
    3. dyn_threshold (Image, ImageMean, RegionDynThresh, 12, 'dark')
    复制代码
    两种方法的效果图:
    1002191-20170210165031776-383419088.jpg
    那么当StdDevScale > 0 时,var_threshold对比dyn_threshold还存在什么优点呢?我认为是在黑白过渡处能减少分割出不需要的区域的概率。(因为黑白过渡处标准差大,当然前提是StdDevScale 不能设置得太小)


    转载自:http://www.cnblogs.com/xh6300/p/6384542.html

    发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

    如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题前面加上【已解决】

    回报帮助你解决问题的坛友,右下角【免费评分】赠与对方视觉币和热心值,伸手党遭人唾弃,做一个热心并受欢迎的人!

  • TA的每日心情
    害羞
    2018-9-3 09:08
  • 签到天数: 29 天

    连续签到: 1 天

    [LV.4]偶尔看看III

    0

    主题

    21

    帖子

    109

    积分

    Rank: 1

    积分
    109
    发表于 2018-1-27 14:27:15 | 显示全部楼层
    赞一个……

    发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

    如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题前面加上【已解决】

    回报帮助你解决问题的坛友,右下角【免费评分】赠与对方视觉币和热心值,伸手党遭人唾弃,做一个热心并受欢迎的人!

    该用户从未签到

    0

    主题

    3

    帖子

    111

    积分

    Rank: 1

    积分
    111
    发表于 2018-3-6 10:52:20 | 显示全部楼层
    很好。收藏了

    发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

    如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题前面加上【已解决】

    回报帮助你解决问题的坛友,右下角【免费评分】赠与对方视觉币和热心值,伸手党遭人唾弃,做一个热心并受欢迎的人!

  • TA的每日心情
    点赞
    2019-1-9 08:05
  • 签到天数: 211 天

    连续签到: 2 天

    [LV.7]常住居民III

    3

    主题

    47

    帖子

    436

    积分

    Rank: 2Rank: 2

    积分
    436

    优质会员

    发表于 2018-3-28 15:26:30 | 显示全部楼层
    收藏了  多谢~~~~~~~

    发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

    如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题前面加上【已解决】

    回报帮助你解决问题的坛友,右下角【免费评分】赠与对方视觉币和热心值,伸手党遭人唾弃,做一个热心并受欢迎的人!

    您需要登录后才可以回帖 会员登录 | 会员注册

    本版积分规则

    经营性网站备案信息 经营性网站
    备案信息

    中国互联网举报中心 中国互联网
    举报中心

    中国文明网传播文明 中国文明网
    传播文明

    诚信网站

    深圳市市场监督管理局企业主体身份公示 工商网监
    电子标识