勇哥的实验:halcon阈值分割算子细谈(五)var_threshold

阈值分割引言

C#
阈值分割有非常多的算法,大体上分为全局和局部算法。
全局算法包括全局固定阈值和基于图像直方图的阈值,局部算法包括局部动态阈值分割。
基于图像直方图阈值分割的方法也有很多,比如常规的高斯滤波双峰法,OTSU大津法。
但是这类所有的法都基于一个假设:图像是有前景和背景的,待分割目标处于背景中,即图像直方图是双峰的。
如果因为非均匀光照导致待分割目标不处于背景或前景中,即图像直方图无双峰,
那么基于图像直方图的所有法都是不甚理想的
只能在此基础上进行一定的变换,例如nbl算法等,这些都属于局部算法。

任何算法,都会基于假设空间的。没有假设空间,所有算法性能一致。包括经典算法和深度学习算法。

本系列的贴子勇哥通过实验来细品它们之间的差别,以求以后可以精准应用。


var threshold


(1) 参数说明:

           var threshold(Image : Region : MaskWidth, MaskHeight, StdDevScale, AbsThreshold, LightDark:)


           ①Image:输入图像;

           ②MaskWidth, MaskHeight:是用于滤波平滑的掩膜单元

           ③StdDevscale:是标准差乘数因子(简称标准差因子) ;

           ④AbsThreshold:是设定的绝对阈值;

           ⑤LightDark:有4个值可选:' light'、' dark'' equal'、' not equal'。


(2)应用举例:

           var threshold (Image, Region, 4, 4, 0.2, 12, 'dark' )

           在该程序中,先用4x4的掩膜在图像上逐像素游走,用原图中的当前像素和对应掩膜中16个像素的灰度均值对比,找出暗(dark)的区域。当原图像素灰度比对应的掩膜灰度均值低(0.2,12)个灰阶时,该区域被分割出来。

          本程序中StdDevScale = 0.2, AbsThreshold = 12,问题的关键就是理解如何通过StdDevscale和AbsThreshold来确定用于分割的阈值。


(3)关于参数StdDevScale (标准差因子)的说明:

          1、当标准差因子StdDevscale>=0时, v(x.y)取(StdDevscale x标准差)和AbsThreshold中较大的那个 ;

          2、当标准差因子StdDevScale<= 0时, v(xy)取(StdDevscale x标准差)和AbsThreshold中较小的那个。


          实测发现,这里的比较大小是带符号比较,由于标准差是非负数,当StdDevscale <0时,(StdDevscalex标准差) <=0恒成立,所以此时的取值就是(StdDevScale x标准差) 。

          帮助文档中StdDevscale的推荐值范围是-1-1,一般通过上面的例子可知,一般的明显的黑白过度处的在50左右,StdDevScale即-50 ~50 ,50的灰度差异,对于一般分割来说足够。

          标准差文档还说:推荐的值是0.2,如果参数StdDevScale太大,可能分割不出任何东西;如果参数StdDevScale太小(例如-2) ,可能会把整个图像区域全部输出,也就说达不到有效分割的目的。一般推荐使用该算子时,StdDevScale取正值。

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


(4) var_threshold和dyn_threshold的区别和联系:

         var_threshold算子和dyn_threshold算子极为类似,不同的是var threshold集成度更高,并且加入了"标准差x标准差因子"这一变量。

         dyn_threshold是将原图和滤波平滑后的图对比, var_threshold是将原图和对应像素掩膜覆盖的像素的平均,灰度值对比,在算子var_threshold中,如果参数StdDevScale=0,那么就可以用动态阈值的方式非常近似地模拟,以上两种算法的效果,极为类似。



官方文档的说明


名称

var_threshold —通过局部均值和标准差分析对图像阈值。

签名

描述

使用var_threshold,可以选择输入Image 的像素满足如下所述特征


  • 具有较高的局部标准偏差(对于正的 StdDevScale)或较低的局部标准偏差(对于负的 StdDevScale


因此,可以在不均匀,嘈杂或照明不均匀的背景上分割区域


输入参数提示

  • MaskWidth,MaskHeight

  • MaskWidth和 MaskHeight定义的过滤器蒙版的大小确定要分割的对象的最大大小。但是,如果选择的遮罩太大,则可能会合并非常靠近的对象。



    image.png
    (1)原始图像;目标是计算垂直线。
    (2)
    MaskWidth:= 12MaskHeight:= 12, StdDevScale:= 0.1,所有垂直线均正确分割。
    (3)如果选择的遮罩尺寸太小
    ,则无法正确选择所需区域。
    (4)如果遮罩大小太大(
    40),则可能会合并非常靠近的对象。


    如果MaskWidthMaskHeight是偶数,则使用下一个较大的奇数值。总而言之,值为3可以认为是最小明智值。



StdDevScale(标准差)


局部标准偏差用作图像中噪声的量度。可以通过StdDevScale对其进行缩放,以反映所需的灵敏度。较高的值表示仅选择与其周围环境有很大差异的像素。

对于参数StdDevScale,明智的选择是-1.0至1.0之间的值,建议值为0.2。如果参数太高或太低,则可能会返回空白区域或完整区域。


image.png

(1)如果StdDevScale太高(1.3),则操作员“挑剔”;仅选择与周围非常相似的像素。
(2)如果
StdDevScale太低(-0.3),则错误地选择了太多与其周围有些相似的像素。

AbsThreshold (绝对阈值)

在图像的均匀区域中,标准偏差较低;因此,单个灰度值的影响很大。为了降低操作员在均匀区域中的灵敏度,可以调整 AbsThreshold
因此,可以忽略均匀环境中较小的灰度值变化。请注意,对于 
StdDevScale的负值AbsThreshold也应选择为负。



LightDark(亮暗)


“亮”“暗”分别返回所有比其周围亮或暗的像素。“等于”返回所有未被选择的像素,即相对等于其周围的像素。'not_equal'返回'light''dark'的组合结果,即所有与其周围环境不同的像素。



计算


image.png

(1)初始图像。
(2)阈值图像(
StdDevScale:= 0.6MaskWidth:= 15MaskHeight:= 15AbsThreshold:= 10)。
以下图像直观地显示了沿着蓝色箭头的结果如何。


var_threshold从输入图像Image中选择 像素满足阈值条件的那些区域Region根据平均灰度值和每个像素(x,y)周围的MaskWidth x MaskHeight大小的局部蒙版中的标准偏差计算阈值 


  • g(x,y)是输入Image中位置(x,y)处的灰度值 


  • m(x,y)对应的平均灰度值,以及


  • d(x,y)围绕该像素的遮罩中的相应标准偏差。


image.png


然后,将可变阈值v(x,y)定义为


要么


解释:对于正的StdDevScale,将分析每个像素。确定用户定义的AbsThreshold或缩放的标准偏差是否更大。选择较大的值作为可变阈值v(x,y)。对于负的StdDevScale,选择相应的较小值。


image.png

image.png


Which pixels are chosen based on the variable threshold is defined by the parameter LightDark:

LightDark = 'light':


Interpretation: If the pixel is brighter by v(x,y) than its surrounding, it is selected.

LightDark = 'dark':


Interpretation: If the pixel is darker by v(x,y) than its surrounding, it is selected.

LightDark = 'equal':


解释:准确选择那些未被 “亮”“暗”选择的像素,即与周围相对相等的像素。

LightDark ='not_equal'


解释:选择“亮”“暗”的所有像素,即与周围像素相差v(x,y)的所有像素。

image.png

image.png


并行化

  • 多线程类型:可重入(与非排他运算符并行运行)。

  • 多线程作用域:全局(可以从任何线程调用)。

  • 在元组级别自动并行化。

  • 在域级别自动并行化。

参数

图片(input_object)  singlechannelimage(-array) 对象(字节/ int2 / int4 / uint2 /实数)

输入图像。

区域(output_object)  区域(数组) 对象

细分区域。

MaskWidth(input_control)  range.x → (整数)

掩模宽度,用于均值和偏差计算。

默认值: 15

建议值: 9,11,13,15

限制:MaskWidth> = 1

MaskHeight(input_control)  范围→ (整数)

掩膜高度,用于均值和偏差计算。

默认值: 15

建议值: 9,11,13,15

限制:MaskHeight> = 1

StdDevScale(input_control)  数字→ (实数/整数)

灰度值标准偏差的因数。

默认值: 0.2

建议值: -0.2,-0.1、0.1、0.2

AbsThreshold(input_control)  数字→ (实数/整数)

与平均值的最小灰度值差异。

默认值: 2

建议值: -2,-1、0、1、2

LightDark(input_control)  字符串→ (字符串)

阈值类型。

默认值: “暗”

值列表:'dark''equal''light''not_equal'

复杂度

假设A为输入区域的面积,则运行时间为O(A)。

结果

如果所有参数正确,则var_threshold返回2(H_MSG_TRUE)。可以通过使用set_system设置标志“ no_object_result”,“ empty_region_result”和“ store_empty_region”的值来确定有关输入图像和输出区域的行为。如有必要,将引发异常。

备择方案

dyn_threshold

threshold

参考文献

W.Niblack,“数字图像处理入门”,第115-116页,新泽西州恩格伍德·克里夫斯,普伦蒂斯·霍尔,1986年




未完待续…………


--------------------- 

作者:hackpig

来源:www.skcircle.com

版权声明:本文为博主原创文章,转载请附上博文链接!


本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

会员中心
搜索
«    2024年4月    »
1234567
891011121314
15161718192021
22232425262728
2930
网站分类
标签列表
最新留言
    热门文章 | 热评文章 | 随机文章
文章归档
友情链接
  • 订阅本站的 RSS 2.0 新闻聚合
  • 扫描加本站机器视觉QQ群,验证答案为:halcon勇哥的机器视觉
  • 点击查阅微信群二维码
  • 扫描加勇哥的非标自动化群,验证答案:C#/C++/VB勇哥的非标自动化群
  • 扫描加站长微信:站长微信:abc496103864
  • 扫描加站长QQ:
  • 扫描赞赏本站:
  • 留言板:

Powered By Z-BlogPHP 1.7.2

Copyright Your skcircle.com Rights Reserved.

鄂ICP备18008319号


站长QQ:496103864 微信:abc496103864