Halcon双阈值与方差阈值算子原理解析
在Halcon的阈值分割工具集中,除了常见的threshold、binary_threshold和dyn_threshold外,dual_threshold和var_threshold这两个算子具有独特的工作机制。理解它们需要先掌握基础阈值方法——其中threshold是最直接的全局分割,binary_threshold能自动识别亮暗区域,而dyn_threshold则通过图像滤波后的局部对比实现分割。后者的典型流程是:先对原图做均值滤波,再逐像素比较原图与滤波图的灰度差异,从而提取出比背景更亮或更暗的特定区域。
1. dual_threshold:双阈值高效分割
这个算子通过单个调用整合了阈值化、连通区域提取和尺寸过滤三个步骤。其签名如下:
dual_threshold(Image, RegionCrossings, MinSize, MinGray, Threshold)
参数说明:
- Threshold:用于分割的灰度阈值
- MinSize:保留区域的最小像素面积
- MinGray:分割区域内像素的最大灰度值下限
假设我们有一张包含齿轮和小色块的测试图,其中蓝色矩形块面积为175像素。当设置MinSize=174, MinGray=200, Threshold=180时,满足条件(面积≥174且区域内最大灰度≥200)的区域会被保留。如果调整MinSize为176,该矩形块因面积不足被过滤;若将MinGray提高到216且MinSize保持176,最右侧齿轮部分区域因最大灰度未达216而消失,调低到210后该区域重新出现。
当设置MinGray = Threshold时,算子退化为单阈值模式。例如dual_threshold(Image, RegionCrossings, 176, 180, 180)等价于以下三段代码的组合:
threshold(Image, Region, 180, 255)
connection(Region, ConnectedRegions)
select_shape(ConnectedRegions, SelectedRegions, 'area', 'and', 176, 9999999)
注意:该算子只能分割高灰度值的亮区域,无法处理暗区域。
2. var_threshold:自适应方差阈值
算子签名如下:
var_threshold(Image, Region, MaskWidth, MaskHeight, StdDevScale, AbsThreshold, LightDark)
核心机制与dyn_threshold类似,但集成了标准差分析。其中MaskWidth/Height定义滤波窗口大小,StdDevScale为标准差缩放因子,AbsThreshold为绝对阈值。可选模式LightDark包含'light', 'dark', 'equal', 'not_equal'。
阈值计算规则如下:
- 设d(x,y)为窗口内像素的标准差,v(x,y)为最终使用的阈值
- 若StdDevScale ≥ 0:取StdDevScale × d(x,y)与AbsThreshold中的较大值
- 若StdDevScale < 0:取两者中的较小值(此时乘积为负数,因此实际取绝对值较小者)
例如处理一张包含文字和背景的图片:
var_threshold(Image, Region, 4, 4, 0.2, 12, 'dark')
操作时,每个像素会被其4×4邻域的平均灰度m(x,y)比较。当m(x,y) - g(x,y) ≥ v(x,y)时(g(x,y)为原图灰度),该像素被划为暗区。在边缘处标准差较大时,阈值由0.2×标准差决定;在平坦区域则使用12作为固定阈值。如果增大AbsThreshold到30或提高StdDevScale到0.7,分割区域会缩小;若将StdDevScale设为负值如-0.01,则AbsThreshold失效,可能导致全图被选中,实用性较低。
与dyn_threshold的关系:当StdDevScale=0时,var_threshold可模拟dyn_threshold的行为。例如以下两组代码效果几乎相同:
var_threshold(Image, Region, 4, 4, 0, 12, 'dark')
mean_image(Image, ImageMean, 4, 4)
dyn_threshold(Image, ImageMean, RegionDynThresh, 12, 'dark')
当StdDevScale > 0时,var_threshold在边缘区域能更有效地抑制噪声,因为它会根据局部对比度动态调整阈值。