一、引言
在机器视觉领域,轮廓检测是一项关键技术,它能够提取物体的边缘信息,从而实现物体的定位、识别、测量等多种功能。Halcon 作为一款强大的机器视觉软件库,提供了丰富的轮廓检测算子。本文将详细介绍 Halcon 中轮廓检测的常用算子、原理及其应用场景。
二、Halcon 轮廓检测常用算子
(一)边缘提取算子
- edges_sub_pix()
- 功能:该算子用于亚像素精度的边缘提取。它可以处理灰度图像,通过计算图像的梯度来确定边缘的位置。
- 参数:
- 输入图像:通常是单通道的灰度图像。
- 滤波参数:用于在边缘提取前对图像进行平滑处理,以减少噪声对边缘检测的影响。
- 边缘类型参数:可以选择不同的边缘检测算法,如 'canny'、'lanser1' 等。
- 输出边缘轮廓:以亚像素精度表示的边缘点集合。
- 示例代码:
read_image(Image, 'test_image.jpg')
edges_sub_pix(Image, Edges, 'canny', 1, 20, 40)
- sobel_amp()
- 功能:计算图像的 Sobel 幅值,这是一种基于一阶导数的边缘检测方法。它通过计算水平和垂直方向的梯度幅值来突出边缘。
- 参数:
- 输入图像:单通道灰度图像。
- 输出幅值图像:每个像素点的梯度幅值,幅值越大,越有可能是边缘点。
- 示例代码:
read_image(Image, 'test_image.jpg')
sobel_amp(Image, Amplitude, 'sum_abs', 3)
(二)轮廓提取算子
- threshold()
- 功能:通过阈值分割将图像中的物体与背景分离,为后续的轮廓提取提供二值化图像。它根据像素灰度值与设定阈值的比较,将像素分为目标像素和背景像素。
- 参数:
- 输入图像:可以是灰度图像或彩色图像(通常先转换为灰度图像)。
- 阈值:可以是固定阈值,也可以是通过自动阈值计算方法得到的值。
- 输出二值化图像:目标像素为前景(通常为白色,值为 255),背景像素为黑色(值为 0)。
- 示例代码:
read_image(Image, 'test_image.jpg')
gray_image := rgb1_to_gray(Image)
threshold(gray_image, Region, 128, 255)
- boundary()
- 功能:从二值化区域中提取边界轮廓。它能够确定区域的外边界,并且可以选择提取内边界(如果区域是空心的)。
- 参数:
- 输入区域:通常是由阈值分割等操作得到的二值化区域。
- 输出轮廓:以链码形式表示的轮廓,链码记录了轮廓点之间的连接关系。
- 示例代码:
read_image(Image, 'test_image.jpg')
gray_image := rgb1_to_gray(Image)
threshold(gray_image, Region, 128, 255)
boundary(Region, Boundary)
(三)轮廓处理算子
- select_shape()
- 功能:根据形状特征选择轮廓。例如,可以根据轮廓的面积、周长、圆形度等特征筛选出符合特定要求的轮廓。
- 参数:
- 输入轮廓:可以是多个轮廓的集合。
- 形状特征参数:如 'area'(面积)、'perimeter'(周长)等,以及对应的特征值范围。
- 输出筛选后的轮廓:满足形状特征要求的轮廓子集。
- 示例代码:
read_image(Image, 'test_image.jpg')
gray_image := rgb1_to_gray(Image)
threshold(gray_image, Region, 128, 255)
boundary(Region, Boundary)
select_shape(Boundary, SelectedBoundary, ['area','>'], [100])
- smooth_contours_xld()
- 功能:对提取的轮廓(XLD 轮廓)进行平滑处理。这有助于去除轮廓上的小锯齿或噪声点,使轮廓更加平滑,便于后续的分析和处理。
- 参数:
- 输入轮廓:以 XLD(Extended Line Description)形式表示的轮廓。
- 平滑参数:如平滑方法(可以是 'gaussian' 等)和平滑强度。
- 输出平滑后的轮廓:经过平滑处理后的 XLD 轮廓。
- 示例代码:
read_image(Image, 'test_image.jpg')
gray_image := rgb1_to_gray(Image)
threshold(gray_image, Region, 128, 255)
boundary(Region, Boundary)
smooth_contours_xld(Boundary, SmoothedBoundary, 'gaussian', 3)
三、轮廓检测原理
(一)边缘提取原理
-
基于梯度的边缘检测
- 以 Sobel 算子为例,Sobel 算子是一种离散的差分算子,它通过计算图像在水平和垂直方向的一阶偏导数来近似梯度。对于图像中的一个像素点(x,y),Sobel 算子在水平方向Gx和垂直方向Gy的模板分别为:
- 图像中像素点(x,y)的梯度幅值G可以通过以下公式计算:。当梯度幅值超过一定阈值时,该像素点被认为是边缘点。这种基于梯度的方法能够有效地检测出图像中灰度变化剧烈的地方,即边缘。
- 而对于亚像素精度的边缘提取算子如 edges_sub_pix,它在基于梯度的基础上,通过拟合等方法进一步精确边缘位置,例如采用多项式拟合或其他曲线拟合技术,将边缘位置精确到亚像素级别。
-
Canny 边缘检测原理
- Canny 边缘检测是一种多阶段的边缘检测算法。首先,对图像进行高斯滤波,以减少噪声。高斯滤波的核函数为:,其中是高斯滤波器的标准差,它决定了滤波的程度。
- 然后,计算图像的梯度幅值和方向。与 Sobel 算子类似,通过差分模板计算梯度,但 Canny 算法在计算梯度方向时更加精确,它将梯度方向分为四个方向(水平、垂直、45 度、- 45 度)。
- 接着,进行非极大值抑制。在梯度方向上,只有梯度幅值为局部最大值的像素点才被保留,这样可以细化边缘,去除一些非边缘的梯度响应。
- 最后,通过双阈值检测和连接边缘。设置高阈值和低阈值,高于高阈值的像素点一定是边缘点,低于低阈值的像素点一定不是边缘点,介于两者之间的像素点如果与边缘点相连,则也被认为是边缘点。
(二)轮廓提取原理
- 阈值分割原理
- 阈值分割是基于图像中物体和背景的灰度差异。假设图像的灰度值范围是,通过选择一个阈值T,将图像分割为两部分。当像素灰度值时,该像素被划分为目标像素,否则为背景像素。阈值的选择方法有多种,包括手动设定、基于直方图的自动阈值选取(如双峰法,当图像直方图呈现明显的双峰分布时,阈值可以选择在两个峰之间的谷底)、自适应阈值法(根据图像局部区域的灰度特性动态调整阈值)等。
- 边界提取原理
- 从二值化区域中提取边界的原理比较直观。对于一个二值化区域,边界点是指那些周围既有目标像素又有背景像素的点。可以通过扫描图像中的像素点,判断其相邻像素的状态来确定边界点。例如,对于一个 8 - 邻域的像素点,如果它是目标像素,并且其 8 个相邻像素中有背景像素,那么它就是边界点。在 Halcon 中,边界提取算子通常会将这些边界点连接起来,形成轮廓,并且以链码等形式存储轮廓信息,链码记录了轮廓点之间的连接方向,便于后续的轮廓处理和分析。
四、应用场景
(一)工业检测
- 零件尺寸测量
- 在机械加工行业,需要对零件的尺寸进行精确测量。通过轮廓检测,可以提取零件的外轮廓,然后利用 Halcon 的几何测量算子计算轮廓的长度、宽度、直径等尺寸。例如,对于一个圆柱形零件,可以通过提取其圆形轮廓,测量圆的直径来判断零件是否符合规格。
- 首先使用边缘提取算子(如 edges_sub_pix)提取零件边缘,然后通过轮廓提取算子(如 boundary)得到零件的轮廓,再使用 select_shape 算子筛选出符合零件形状特征的轮廓,最后使用测量算子(如 distance_pp)计算轮廓上两点之间的距离,从而得到零件的尺寸。
- 表面缺陷检测
- 对于金属、塑料等材料的表面缺陷检测,轮廓检测也发挥着重要作用。例如,检测金属板材表面的划痕、裂纹等缺陷。通过提取板材的正常表面轮廓作为参考,然后检测与正常轮廓有差异的部分作为缺陷。
- 可以先使用阈值分割将板材区域从背景中分离出来,然后提取其边界轮廓。对于存在缺陷的板材,缺陷部分会导致轮廓的变化,如出现局部凹陷或凸起。通过比较实际轮廓与参考轮廓的差异,可以判断缺陷的存在和位置。可以使用轮廓处理算子(如 smooth_contours_xld)对提取的轮廓进行平滑处理,减少噪声对缺陷检测的影响。
(二)机器人视觉
- 目标抓取定位
- 在机器人视觉引导的抓取系统中,需要准确地定位目标物体的位置和姿态。轮廓检测可以帮助机器人识别目标物体的轮廓,从而确定其中心位置、方向等信息,以便机器人能够准确地抓取目标。
- 例如,对于一个形状不规则的工件,机器人视觉系统首先使用边缘提取和轮廓提取算子获取工件的轮廓。然后通过计算轮廓的重心(可以使用 Halcon 的 regionprops 算子来计算轮廓的重心等几何属性)来确定工件的中心位置。同时,通过分析轮廓的形状和方向,确定工件的姿态,为机器人的抓取动作提供准确的定位信息。
- 路径规划
- 机器人在执行任务过程中,有时需要沿着物体的轮廓进行运动,如在焊接、涂胶等任务中。通过轮廓检测,机器人可以获取物体的轮廓信息,从而规划出合理的运动路径。
- 以焊接任务为例,首先提取待焊接工件的轮廓,然后根据焊接工艺要求(如焊接速度、焊接起点和终点等),沿着轮廓生成焊接路径。可以使用轮廓的离散点信息,通过插值等方法生成连续的路径,并且可以根据实际情况对路径进行优化,如避开障碍物等。
(三)交通监控
- 车辆识别与跟踪
- 在智能交通系统中,轮廓检测可以用于车辆的识别和跟踪。通过提取车辆的轮廓,可以区分不同类型的车辆(如轿车、卡车等),并且可以在视频序列中跟踪车辆的运动。
- 首先对交通监控视频中的每一帧图像进行处理,使用边缘提取和轮廓提取算子获取车辆轮廓。根据车辆轮廓的大小、形状等特征可以初步识别车辆类型。在连续的视频帧中,通过匹配车辆轮廓的位置和形状变化来跟踪车辆的运动轨迹。可以使用卡尔曼滤波等方法对车辆的运动状态进行预测和更新,提高跟踪的准确性。
- 道路边界检测
- 道路边界检测对于自动驾驶和智能交通管理至关重要。通过轮廓检测,可以提取道路的边缘轮廓,为车辆的行驶提供安全保障。
- 对于车载视觉系统或路边监控设备获取的图像,利用边缘提取算子(如 edges_sub_pix)提取道路与周围环境的边缘,然后通过轮廓提取和处理算子(如 select_shape)筛选出符合道路边界特征的轮廓。可以根据道路的几何形状(如直线、曲线等)对提取的轮廓进行拟合,从而得到准确的道路边界信息,为车辆的路径规划和安全行驶提供支持。
五、结论
Halcon 轮廓检测算子为机器视觉应用提供了强大的工具。通过深入理解轮廓检测的常用算子及其原理,我们可以在工业检测、机器人视觉、交通监控等众多领域有效地应用这些技术。随着机器视觉技术的不断发展,轮廓检测技术也将不断完善,为更多的智能应用提供准确的边缘和轮廓信息,推动各个行业的自动化和智能化进程。在实际应用中,需要根据具体的场景和要求,合理选择和组合轮廓检测算子,以达到最佳的检测效果。
六、示例代码
以下是一个使用 Halcon 进行轮廓检测的综合示例代码,涵盖了从图像读取、边缘提取、轮廓提取到轮廓处理及简单应用的过程,示例场景模拟在一幅包含多个不同形状物体的图像中提取特定形状物体的轮廓并进行简单测量,你可以根据实际需求进行调整和扩展。
* 关闭窗口显示更新,加快处理速度(可根据实际情况选择是否添加)
dev_update_off ()
* 读取图像
read_image(Image, 'test_image.jpg')
* 将图像转换为灰度图(如果图像是彩色的,很多操作基于灰度更方便)
rgb1_to_gray(Image, GrayImage)
* 1. 边缘提取(使用edges_sub_pix算子进行亚像素精度的边缘提取,这里选择'canny'算法)
edges_sub_pix(GrayImage, Edges, 'canny', 1, 20, 40)
* 2. 阈值分割,将图像二值化,以便后续提取轮廓(这里阈值设置为简单示例,实际可调整)
threshold(GrayImage, Region, 128, 255)
* 3. 从二值化区域提取边界轮廓
boundary(Region, Boundary)
* 4. 轮廓处理 - 对提取的轮廓进行平滑处理(使用'smooth_contours_xld',采用高斯平滑,平滑强度为3)
smooth_contours_xld(Boundary, SmoothedBoundary, 'gaussian', 3)
* 5. 根据形状特征选择轮廓(这里选择面积大于1000的轮廓,可根据实际物体特征修改筛选条件)
select_shape(SmoothedBoundary, SelectedBoundary, ['area', '>'], [1000])
* 6. 计算选中轮廓的一些几何属性(这里以计算轮廓的面积和周长为例)
area_center(SelectedBoundary, Area, Row, Column)
length_xld(SelectedBoundary, Perimeter)
* 打开窗口用于显示结果
dev_open_window(0, 0, 512, 512, 'black', WindowID)
* 显示原始图像
dev_display(Image)
* 显示提取并处理后的轮廓(用红色显示)
dev_set_color('red')
dev_display(SelectedBoundary)
* 在窗口中显示轮廓的面积和周长信息
Message := 'Area: ' + Area$'.2' + ', Perimeter: ' + Perimeter$'.2'
dev_disp_text(Message, 'window', 12, 12, 'white', [], [])
* 重新开启窗口显示更新(如果之前关闭了)
dev_update_on ()
上述代码的详细步骤解释如下:
- 关闭窗口显示更新(可选步骤):
dev_update_off ()
语句用于关闭窗口显示更新,这样在处理图像和进行一系列操作时可以加快速度,因为不需要实时显示每一步操作的结果。如果希望实时看到每一步的操作效果,可以不添加这一行或者在最后使用dev_update_on ()
重新开启显示更新。 - 图像读取与灰度转换:
read_image(Image, 'test_image.jpg')
读取指定路径下名为test_image.jpg
的图像到变量Image
中。rgb1_to_gray(Image, GrayImage)
将彩色图像Image
转换为灰度图像GrayImage
,因为后续很多操作(如阈值分割、边缘提取等)在灰度图像上进行更为方便和常见。
- 边缘提取:
edges_sub_pix(GrayImage, Edges, 'canny', 1, 20, 40)
使用edges_sub_pix
算子以亚像素精度提取边缘。这里选择'canny'
作为边缘检测算法,第一个参数1
表示使用默认的滤波设置(可以根据图像噪声情况调整),20
和40
分别是低阈值和高阈值(可根据图像内容和边缘特征调整这两个阈值来获取合适的边缘效果),提取的边缘存放在Edges
变量中。 - 阈值分割:
threshold(GrayImage, Region, 128, 255)
对灰度图像GrayImage
进行阈值分割,将像素灰度值大于等于128
且小于等于255
的像素设置为前景(值为255
,白色),其余为背景(值为0
,黑色),分割得到的二值化区域存放在Region
变量中。这里的阈值128
和255
只是简单示例,实际应用中通常需要根据图像直方图等方式来确定合适的阈值。 - 轮廓提取:
boundary(Region, Boundary)
从二值化区域Region
中提取边界轮廓,提取的轮廓以链码等形式表示,存放在Boundary
变量中。 - 轮廓处理 - 平滑轮廓:
smooth_contours_xld(Boundary, SmoothedBoundary, 'gaussian', 3)
对提取到的原始轮廓Boundary
进行平滑处理,采用高斯平滑方法('gaussian'
),平滑强度设置为3
(这个值可以根据轮廓的平滑需求和实际效果进行调整),平滑后的轮廓存放在SmoothedBoundary
变量中。 - 轮廓筛选:
select_shape(SmoothedBoundary, SelectedBoundary, ['area', '>'], [1000])
根据形状特征选择轮廓,这里筛选条件是选择面积大于1000
(像素单位,根据图像分辨率和实际物体大小等因素决定实际含义)的轮廓,将符合条件的轮廓存放在SelectedBoundary
变量中。 - 几何属性计算:
area_center(SelectedBoundary, Area, Row, Column)
计算选中轮廓SelectedBoundary
的面积以及重心的行坐标Row
和列坐标Column
,面积值存放在Area
变量中。length_xld(SelectedBoundary, Perimeter)
计算选中轮廓的周长,结果存放在Perimeter
变量中。
- 结果显示:
dev_open_window(0, 0, 512, 512, 'black', WindowID)
打开一个大小为512×512
像素,背景色为黑色的窗口用于显示图像和处理结果,窗口的标识存放在WindowID
变量中。dev_display(Image)
在打开的窗口中显示原始图像,方便对比查看。dev_set_color('red')
设置后续显示的颜色为红色,然后dev_display(SelectedBoundary)
在窗口中显示提取并处理后的轮廓,使其以红色显示便于区分。- 通过
Message := 'Area: ' + Area$'.2' + ', Perimeter: ' + Perimeter$'.2'
构建包含轮廓面积和周长信息且保留两位小数的文本消息,再使用dev_disp_text(Message, 'window', 12, 12, 'white', [], [])
将该消息显示在窗口的指定位置(这里是窗口坐标(12, 12)
处,颜色为白色)。
- 重新开启窗口显示更新(可选步骤):如果之前关闭了窗口显示更新,使用
dev_update_on ()
重新开启,这样后续的操作如果涉及窗口显示相关的内容会正常更新显示。
请注意,在实际使用时,你需要将test_image.jpg
替换为真实存在的图像文件路径及文件名,并且根据具体的应用场景和图像内容对算子的参数(如阈值、边缘检测算法参数、轮廓筛选条件等)进行适当的调整优化,以达到最佳的轮廓检测和处理效果。
标签:场景,提取,阈值,图像,Halcon,边缘,算子,轮廓 From: https://blog.csdn.net/m0_44975814/article/details/144338413