1、算子帮助文档
edges_sub_pix
使用递归实现的滤波器(根据Deriche、Lanser和Shen的方法)或Canny提出的常规实现的“高斯导数”滤波器(使用滤波器掩模)来检测阶梯边缘。因此,以下边缘算子可用于滤波器:
'deriche1', 'lanser1', 'deriche2', 'lanser2', 'shen', 'mshen', 'canny', 'sobel' 和 'sobel_fast'。
提取的边缘作为亚像素精确的XLD轮廓在Edges中返回。对于除'sobel_fast'之外的所有边缘算子,为每个边缘点定义了以下属性(有关更多详细信息,请参阅get_contour_attrib_xld):
'edge_direction':
给出边缘的方向(而非XLD轮廓的方向),根据图像在水平和垂直方向上的梯度计算得出。角度[弧度]是相对于图像的列轴给出的。
'angle':
轮廓法向量的方向,以弧度表示(法向量指向轮廓的右侧,当从起点到终点遍历轮廓时;角度是相对于图像的行轴给出的)。
'response':
边缘幅度(梯度大小)。
对于除'sobel'和'sobel_fast'之外的所有边缘算子,可以任意选择“滤波器宽度”(即平滑量),并且可以通过调用info_edges来估计Alpha参数的具体值。对于所有滤波器(Deriche、Lanser和Shen滤波器),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')返回的对角边缘幅度估计存在偏差。在相应的修改版运算符('lanser1', 'lanser2' 和 'mshen')中,这种偏差被消除,同时保持了相同的执行速度。
对于相对较小的滤波器宽度(11 x 11),即Alpha('lanser2' = 0.5)时,所有滤波器都会产生相似的结果。只有当滤波器“更宽”时,差异才开始出现:Shen滤波器开始产生质量较低的结果。然而,它们是支持任意掩模大小的实现运算符中最快的,紧随其后的是Deriche运算符。使用固定掩模大小(3 x 3)的两个Sobel滤波器比其他滤波器更快。其中,'sobel_fast'滤波器比'sobel'快得多。
edges_sub_pix
通过使用类似于滞后阈值操作的算法将边缘点连接成边缘,该算法也在lines_gauss中使用。幅度大于High的点立即被接受为属于边缘,而幅度小于Low的点则被拒绝。所有其他点如果与已接受的边缘点相连,则被视为边缘(另请参见lines_gauss和hysteresis_threshold)。
由于边缘提取器通常无法提取某些连接点,因此可以通过在上述Filter值后附加'_junctions'来选择一种通过不同方式提取这些缺失连接点的模式。这种模式类似于lines_gauss中可用的完成连接点的模式。
'sobel_fast'边缘算子与其他所有边缘算子具有相同的语义。然而,在内部,它基于各个处理步骤的显著简化变体(滞后阈值化、边缘点连接和亚像素边缘位置的提取)。因此,'sobel_fast'在某些情况下可能会返回略微不太准确的边缘位置,并且可能会选择不同的边缘部分。
edges_sub_pix
可以在OpenCL设备上为'canny'和'sobel_fast'滤波器类型执行。这将需要多达widthheight29字节的固定内存。由于分配内存是一个昂贵的操作,因此将固定内存缓存设置为至少此大小是有意义的(使用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 : )
各参数的含义如下:
- Image:输入的单通道灰度图像。
- Edges:输出的XLD轮廓。
- Filter:选择的滤波算子,用于边缘检测。默认是Canny,可选的有Canny、Deriche、Deriche Int4、Deriche2、Deriche2 Int4、Lanser1、Lanser2、MShen、Shen、Sobel_fast等。不同的滤波器对噪声的敏感度和计算效率有所不同。
- Alpha:平滑的程度。其值越小,表示平滑的程度越大。默认是0,可以取0.1到1.1之间的值。平滑有助于减少噪声对边缘检测的影响,但过多的平滑可能导致边缘细节的丢失。
- Low:滞后阈值的低阈值。低阈值越低,图像的细节会越丰富。低于此阈值的像素被认为不是边缘。
- High:滞后阈值的高阈值。高于此阈值的像素被认为是强边缘,这些边缘通常是连续的。在高阈值和低阈值之间的像素被认为是弱边缘,它们的边缘状态取决于其相邻像素。
3、使用技巧
选择合适的滤波器:
根据图像的特点和噪声情况选择合适的滤波器。例如,如果图像质量较好且噪声较小,可以选择速度较快的'sobel_fast'滤波器。但如果对边缘的精度要求较高,则建议选择'canny'或'lanser2'等更复杂的滤波器。
调整平滑参数:
通过调整Alpha
参数来控制平滑的程度。平滑可以减少噪声对边缘检测的影响,但过度的平滑也可能导致边缘细节的丢失。因此,需要根据实际情况进行权衡。
设置合理的滞后阈值:
低阈值Low
和高阈值High
的设置对边缘检测的结果有很大影响。低阈值越低,图像中的细节会越丰富;而高阈值则用于区分边缘与背景。在实际应用中,可以通过尝试不同的阈值组合来找到最佳的设置。
预处理和后处理:
在进行边缘检测之前,可以对图像进行预处理,如高斯滤波或二值化等,以减少噪声或突出边缘特征。在边缘检测之后,还可以进行后处理操作,如轮廓分割、合并或拟合等,以得到更精确的边缘轮廓。
利用图像掩膜:
如果只对图像的特定区域感兴趣,可以使用图像掩膜来限制边缘检测的范围。这不仅可以提高边缘检测的准确性,还可以缩短算法的执行时间。
4、参数设置参考
其中的固定值按需修改,使用尽量多测试
High := 6 + 20 * (1 - Sensitivity)
Low := 3 + 10 * (1 - Sensitivity)
if(BrightLineSensitivity >= 0.75)
Alpha := 1.1
elseif(Sensitivity >= 0.4 and Sensitivity < 0.75)
Alpha := 0.5
else
Alpha := 0.2
endif
edges_sub_pix (ImageScaled, Edges, 'canny', Alpha, Low, High)