Halcon阈值化算子dual_threshold和var_threshold的理解

Halcon阈值化算⼦dual_threshold和var_threshold的理解Halcon中阈值⼆值化的算⼦众多,通常⽤得最多的有threshold、binary_threshold、dyn_threshold等。
threshold是最简单的阈值分割算⼦,理解最为简单;binary_threshold是⾃动阈值算⼦,它可以⾃动选出暗(dark)的区域,或者⾃动选出亮(light)的区域,理解起来也没有难度。
动态阈值算⼦dyn_threshold理解起来稍微复杂⼀点,使⽤dyn_threshold算⼦的步骤基本是这样的:
①将原图进⾏滤波平滑处理。
②⽤原图和平滑后的图逐个像素做⽐较,它可以根据参数分割出原图⽐平滑后的图灰度⾼(或者低)若⼲个灰度值的区域。
举例如下:
处理程序是这样的:
1 read_image (Image, 'C:/Users/happy xia/Desktop/dynPic.png')
2mean_image (Image, ImageMean, 9, 9)
3 dyn_threshold (Image, ImageMean, RegionDynThresh, 10, 'dark')
程序分析:本例中,将图⽚模糊后,点阵字的⿊⾊扩散了,随之就是字的⿊⾊不如原图那么⿊了,那么通过给定的限值“10”和“dark”,就可以将原图⽐模糊后的图暗10个灰阶以上的区域(即⿊⾊⽂字部分)选出来了。
以上所说的三个算⼦并不是本⽂的重点,但却是理解下⾯的两个阈值分割算⼦的准备知识。一小时的故事
1、dual_threshold
先看程序和效果图再分析。
1 read_image (Image, 'C:/Users/happy xia/Desktop/2.png')
2 dual_threshold (Image, RegionCrossings, 174, 200, 180)
dual_threshold(Image : RegionCrossings : MinSize, MinGray, Threshold : )
该算⼦签名中:Threshold 表⽰⽤于分割的阈值数值,MinSize表⽰分割出来的区域的最⼩⾯积(即数像素的数⽬个数),MinGray表⽰分割出来的区域对应的原图中图像像素的最⾼灰度不能低于MinGray设定值。
注意图中蓝⾊矩形⼩⾊块的⾯积是175个像素,因此当MinSize = 174时,它可以被分割出来。
OK,我知道这么说⽐较拗⼝。下⾯我边改变参数边观察效果图,并做简要分析:
82RCC.
1 read_image (Image, 'C:/Users/happy xia/Desktop/2.png')
2 dual_threshold (Image, RegionCrossings, 176, 200, 180)
效果图如下:
由于最⼩⾯积设置为176,那么⾯积为175像素的矩形⼩⾊块就没有被分割出来。
再来改变MinGray参数:
1 read_image (Image, 'C:/Users/happy xia/Desktop/2.png')
2 dual_threshold (Image, RegionCrossings, 176, 216, 180)
此时观察到,最右边那个齿轮本来分割出来的区域没有了!
通过取⾊器观察可知,这块区域最亮的灰度⼤概⽐211⾼⼀点点。
我们把这个值略微调低再看看:
1 read_image (Image, 'C:/Users/happy xia/Desktop/2.png')
2 dual_threshold (Image, RegionCrossings, 176, 210, 180)
最右边那个齿轮右下⾓那⼀块⼜被分割出来了!
相信通过这样参数的反复调节,⼤家已经彻底明⽩了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集成度更⾼,
并且加⼊了“标准差×标准差因⼦”这⼀变量。
举例:
1 read_image (Image, 'C:/1.png')
2 var_threshold (Image, Region, 4, 4, 0.2, 12, 'dark')
在该程序中,先⽤4×4的掩膜在图像上逐像素游⾛,⽤原图中的当前像素和对应掩膜中16个像素的灰度均值对⽐,出暗(dark)的区域。当原图像素灰度⽐对应的掩膜灰度均值低(0.2,12)个灰阶时,该区域被分割出来。本程序中StdDevScale = 0.2, AbsThreshold = 12,问题的关键就是理解如何通过StdDevScale和AbsThreshold来确定⽤于分割的阈值。八十年代香港电影
逸珑8133var_threshold的帮助⽂档中是这么写的:
说明:
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):
帮助⽂档中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.)
最后再看看是怎么分割像素的:
其中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')2012年浙江高考作文
2 var_threshold (Image, Region, 4, 4, 0.2, 30, 'dark')
② AbsThreshold 保持12不变,将StdDevScale由0.2改成0.7,此时分割出的区域变⼩。
③将参数改为var_threshold (Image, Region, 4, 4, -0.01, 12, 'dark'),此时分割出的区域⼤⼤增加,由前⾯的分析可知,此时参数AbsThreshold = 12⽆效,事实上,此时将AbsThreshold 改为1、50甚⾄200都对最终结果没有任何影响。
通过本⼈的分析,我认为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')
两种⽅法的效果图:
那么当StdDevScale > 0 时,var_threshold对⽐dyn_threshold还存在什么优点呢?我认为是在⿊⽩过渡处能减少分割出不需要的区域的概率。(因为⿊⽩过渡处标准差⼤,当然前提是StdDevScale 不能设置得太⼩)
(⽹上关于这两个算⼦的系统介绍很少,我的理解难免有不⾜之处,欢迎⼤家回复讨论)

本文发布于:2024-09-21 14:50:17,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/414208.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:分割   像素   灰度   区域   掩膜
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议