目录
一、说明
halcon中取区域边缘的算子很多,但是哪个效果更好,本文对edges_image和edges_sub_pix介绍,并对它们的执行效果进行对比.
二、算子介绍
2.1 info_edges算子
1)描述
info_edges 返回对 edges_image 中使用的任何滤波器的宽度的估计。为此,对滤波器的相应连续脉冲响应进行采样,直到第一个滤波器系数小于最大系数的 5%。这等同于工具寻优。
Alpha 是滤波器参数(见edges_image)。支持七个边缘运算符(参数过滤器):
“deriche1”、“lanser1”、“deriche2”、“lanser2”、“shen”、“mshen”和“canny”。
参数 Mode ('edge'/'smooth') 用于确定是否要对相应的边缘或平滑算子进行采样。Canny 算子(使用高斯进行平滑)使用常规过滤器掩码实现,而所有其他过滤器是递归实现的。因此,对于 Canny 滤波器,除了滤波器宽度外,一维脉冲响应的系数在 Coeffs 中返回。
2)算子形式
info_edges( : : Filter, Mode, Alpha : Size, Coeffs)
3)例子:以下返回不同的size和Coeffs。
info_edges('deriche1','edge',0.5,Size,Coeffs)
info_edges('deriche2','edge',0.5,Size,Coeffs)
info_edges('lanser1','edge',0.5,Size,Coeffs)
info_edges('lanser2','edge',0.5,Size,Coeffs)
info_edges('shen','edge',0.5,Size,Coeffs)
info_edges('mshen','edge',0.5,Size,Coeffs)
info_edges('canny','edge',0.5,Size,Coeffs)
2.2 edges_image
1)算子综合描述
edges_image 使用递归实现的滤波器(根据 Deriche、Lanser 和 Shen)或 Canny 提出的传统实现的“高斯导数”滤波器(使用滤波器掩码)检测阶梯边缘。此外,可以使用 Sobel 滤波器的非常快速的变体。
对于除 'sobel_fast' 之外的所有过滤器,边缘方向在 ImaDir 中返回。deriche2' 也可用于 int4-images,并返回带符号的过滤器响应而不是其绝对值。通过应用 edges_image 计算图像的二阶导数(使用参数 'lanser2') 到有符号的一阶导数。边缘方向以 2 度的步长存储,即,在数学上正意义上的 x 度的边缘方向和相对于水平轴的边缘方向在边缘方向上存储为 x / 2图像。此外,还考虑了强度变化的方向。用图像梯度表示。
2)算子格式
edges_image(Image : ImaAmp, ImaDir : Filter, Alpha, NMS, Low, High : )
3)参数意义
- Image : 输入图像
- ImaAmp: 输出图像的边缘振幅(梯度幅值)以ImaAmp返回。
- ImaDir : 输出方向
- Filter: 可以使用以下边缘运算符,滤波器选择:
'deriche1', 'lanser1', 'deriche1_int4', 'deriche2', 'lanser2', 'deriche2_int4', 'shen', 'mshen', 'canny', and 'sobel_fast'
- Alpha:过滤器参数:较小的值会导致强平滑,因此细节较少(与“canny”相反)。此值小则线条少,大则线条多。
- NMS, 是否采用非击大值抑制
- Low:下门限值
- High:上门限值
4)参数详细信息
- ImaAmp: 输出图像的边缘振幅(梯度幅值)以ImaAmp返回。
对于除“sobel_fast”之外的所有过滤器,边缘方向以ImaDir返回。对于“sobel_fast”,不会计算边缘方向以加速过滤器。因此,ImaDir是一个空图像对象。边缘操作符“deriche1”分别为“deriche2”也可用于int4图像,并返回带符号的过滤器响应,而不是其绝对值。通过分别选择'deriche1_int4'和'deriche2_int4'作为过滤器,字节图像也可以获得此行为。这可用于计算图像的二阶导数,方法是将边缘_image(带参数“lanser2”)应用于带符号的一阶导数。边缘方向以2度步长存储,即,在数学上正意义上且相对于水平轴的x度边缘方向在边缘方向图像中存储为x/2。此外,还考虑了强度变化的方向。让我们来表示图像的梯度。然后,以下边缘方向返回为r/2‘
- Alpha:图像处理过滤器的大小尺度
除了 'sobel_fast' (其中过滤器宽度为 3x3 且忽略 Alpha)之外的所有过滤器,“过滤器宽度”(即平滑量)可以任意选择,并且可以通过调用 info_edges 来估算具体值参数 Alpha。对于 Deriche、Lanser 和 Shen 过滤器,它随着 Alpha 的增加而减小,而对于 Canny 过滤器,它是 Canny 算子所基于的高斯的标准偏差。“宽”过滤器表现出更大的不变性噪声,但也降低了检测小细节的能力。非递归滤波器,例如 Canny 滤波器,是使用滤波器掩码实现的,因此增加滤波器宽度会增加执行时间。因此,使用 Deriche 可以实现任意滤波器宽度, Lanser 和 Shen 过滤器不会增加算子的运行时间。对于较大的过滤器宽度自然会增加。作为边界处理,递归算子假设图像在图像之外为零,而 Canny 算子在图像边界处重复灰度值。可通过以下选择获得可比较的过滤器宽度Α:
Alpha('lanser1') = Alpha('deriche1'),
Alpha('deriche2') = Alpha('deriche1') / 2,
Alpha('lanser2') = Alpha('deriche2'),
Alpha('shen') = Alpha('deriche1') / 2,
Alpha('mshen') = Alpha('shen'),
Alpha('canny') = 1.77 / Alpha('deriche1').
最初提出的递归滤波器('deriche1'、'deriche2'、'shen')返回对角边缘幅度的有偏估记。'mshen'),同时保持相同的执行速度。
对于相对较小的过滤器宽度(11 x 11),即对于 Alpha('lanser2' = 0.5),所有过滤器都会产生相似的结果。只有“更宽”的过滤器开始出现差异:Shen 过滤器开始产生质量较差的结果。但是,它们是已实施的运算符中最快的——紧随其后的是 Deriche 运算符。
- NMS,非极大值抑制的处理方法
edge_image 可选择应用非最大抑制(NMS = 'nms'/'inms'/'hvnms';如果不需要,则为 'none')和滞后阈值操作(低、高;如果不需要,至少有一个负值)到生成的边缘图像。从概念上讲,这对应于以下调用:
nonmax_suppression_dir(...,NMS,...) under hysteresis_threshold(...,Low,High,999,...).
对于'sobel_fast',除了'none'之外,对NMS的所有值都进行同样的非极大值抑制。edge_image 可以在 OpenCL 设备上针对过滤器类型“canny”和“sobel_fast”执行。
- Low:下门限值 和 High:上门限值
2.3 edges_sub_pix
1)算子综合描述
使用 Deriche、Lanser、Shen 或 Canny 过滤器提取亚像素精确边缘。
edges_sub_pix 使用递归实现的滤波器(根据 Deriche、Lanser 和 Shen)或 Canny 提出的传统实现的“高斯导数”滤波器(使用滤波器掩码)检测阶梯边缘。
'deriche1', 'lanser1', 'deriche2', 'lanser2', 'shen', 'mshen', 'canny', 'sobel', and 'sobel_fast'
提取的边缘在 Edges 中作为亚像素精确 XLD 轮廓返回。对于除 'sobel_fast' 之外的所有边缘算子,为每个边缘点定义以下属性(参见 get_contour_attrib_xld)
- 'edge_direction' 边缘方向
- 'angle' 法线向量到轮廓的方向(当轮廓从起点到终点遍历时,法线向量指向轮廓的右侧;角度是相对于图像的行轴给出的) .)
- “respones”边缘幅度(梯度幅度)
除了‘sobel’和‘sobel_fast’之外的所有边缘算子可以任意选择“滤波器宽度”(即平滑量),可以通过调用info_edges来估计参数Alpha、Lanser和Lanser的具体值沉过滤器),“过滤器宽度”随着 Alpha 的增加而减小。唯一的例外是 Canny 过滤器,其增加的 Alpha 也会导致“过滤器宽度”的增加。实现非递归过滤器,例如 Canny 过滤器使用过滤器掩码,因此增加过滤器宽度会增加执行时间。因此,使用 Deriche、Lanser 和 Shen 过滤器可以实现任意过滤器宽度,而不会增加算子的运行时间。与 Canny 算子相比,在速度上自然具有优势增加作为边界处理,递归算子假设图像在图像之外为零,而 Canny 算子在图像边界处重复灰度值。可通过以下 Alpha 选择获得可比较的滤波器宽度:
Alpha('lanser1') = Alpha('deriche1'),
Alpha('deriche2') = Alpha('deriche1') / 2,
Alpha('lanser2') = Alpha('deriche2'),
Alpha('shen') = Alpha('deriche1') / 2,
Alpha('mshen') = Alpha('shen'),
Alpha('canny') = 1.77 / Alpha('deriche1').
最初提出的递归滤波器('deriche1'、'deriche2'、'shen')返回对角边缘幅度的有偏估计。'mshen'),同时保持相同的执行速度。
对于相对较小的过滤器宽度(11 x 11),即对于 Alpha('lanser2' = 0.5),所有过滤器都会产生相似的结果。只有“更宽”的过滤器开始出现差异:Shen 过滤器开始产生质量较差的结果。但是,它们是支持任意掩码大小的已实现算子中最快的,紧随其后的是 Deriche 算子。使用固定掩码大小 (3 x 3) 的两个 Sobel 过滤器比其他过滤器快。二,过滤器“sobel_fast”明显快于“sobel”。
edge_sub_pix 使用类似于迟滞阈值操作的算法将边缘点链接到边缘,这也用于lines_gauss. 幅度大于High 的点立即被认为属于边缘,而幅度小于Low 的点是如果所有其他点连接到已接受的边缘点,则所有其他点都被接受为边缘(另请参见lines_gauss 和 hysteresis_threshold)。
因为边缘提取器通常无法提取某些连接点,所以可以通过将'_junctions'附加到上述Filter的值来选择一种尝试通过不同方式提取这些缺失连接点的模式。在lines_gauss中可用的连接点。
边缘算子“sobel_fast”与所有其他边缘算子具有相同的语义。然而,在内部,它基于各个处理步骤(滞后阈值、边缘点链接和子像素边缘位置的提取)的显着简化变体。因此,在某些情况下,“sobel_fast”可能会返回稍微不太准确的边缘位置,并且可能会选择不同的边缘部分。
edge_sub_pix 可以在 OpenCL 设备上针对过滤器类型“canny”和“sobel_fast”执行。这将需要最多 width*height*29 字节的固定内存。由于分配内存是一项昂贵的操作,因此设置固定内存是有意义的内存缓存到至少这个大小(使用 set_compute_device_param 参数 'pinned_mem_cache_capacity',或完全禁用固定内存(使用 set_compute_device_param 参数 'alloc_pinned'),在这种情况下使用普通内存缓存。CPU 实现。
2)算子形式
edges_sub_pix( Image : Edges : Filter, Alpha, Low, High : )
3)参数说明
这些参数与上文edges_image相同,请参考。
三、edges_image的代码
以下是采用edges_image的边界提取示例代码。
read_image (Image, 'D:/images/taps/gtape')
edges_image (Image, ImaAmp, ImaDir, 'lanser2', 0.5, 'nms', 12, 22)
threshold (ImaAmp, Edges, 1, 255)
skeleton (Edges, Skeleton)
gen_contours_skeleton_xld (Skeleton, Contours, 1, 'filter')
dev_display (Image)
dev_set_colored (6)
dev_display (Contours)
四、 edges_sub_pix函数
以下是采用edges_sub_pix的边界提取示例代码。
read_image (Image, 'D:/images/taps/gtape')
*
* Init window
get_image_size (Image, Width, Height)
dev_open_window (0, 0, Width, Height, 'black', WindowHandle1)
*
* Segment a region containing the edges
fast_threshold (Image, Region, 0, 140, 7)
boundary (Region, RegionBorder, 'inner')
* clip_region_rel (RegionBorder, RegionClipped, 5, 5, 5, 5)
dilation_circle (RegionBorder, RegionDilation, 2.5)
reduce_domain (Image, RegionDilation, ImageReduced)
*
* In the subdomain of the image containing the edges,
* extract subpixel precise edges.
set_color(WindowHandle1, 'green')
*'deriche1', 'lanser1', 'deriche2', 'lanser2', 'shen', 'mshen', 'canny', 'sobel', and 'sobel_fast'
edges_sub_pix (ImageReduced, Edges, 'lanser2', 2, 20, 60)
五、结果分析
用edges_image的结果:
edges_sub_pix的结果:
可以看出,上图红线只是包络边缘,所以判定只能是像素级别;下图edges_sub_pix的边缘横跨黑白之间,达到亚像素测量。结论edges_sub_pix做测量时要优于edges_image。
六、小结:
如果您对两个算子的参数不得要领,那是因为有些知识点不够,相关理论将在此文解释,请大家参考。