原文作者:aircraft

原文链接:halcon 入门教程(三) 边缘检测

有兴趣可以多看其他的halcon教程

halcon 学习教程目录

  本篇讲一下边缘检测(边缘提取),因为这个我发现也是比较常用的,放在入门教程(三)会比较好,在入门教程(一)(二)学完了形态学,和Blob分析,再来学边缘检测并且结合案例感觉会掌握学习的很快。跟openCV一样主流的还是那几个检测算子Sobel、Canny、Laplacian等等。

一.边缘检测简介

1. 边缘检测的基本原理

边缘是图像中灰度、颜色或纹理发生显著变化的区域,通常对应物体的边界。边缘检测的目标是定位这些变化的区域,方法可分为:

  • 基于梯度:通过计算像素的梯度幅值和方向(如Sobel、Canny)。
  • 基于二阶导数:利用拉普拉斯算子检测过零点(如Laplacian)。
  • 基于模板匹配:使用预定义的边缘模板进行卷积。

2. Halcon边缘检测的核心算法

​**(1) 一阶梯度法(Sobel, Prewitt)​**

  • 原理:通过卷积核计算像素在水*和垂直方向的梯度(Gx​和Gy​),合成梯度幅值和方向。

halcon示例:

sobel_amp(Image, EdgeAmplitude, 'sum_abs', 3)  // Sobel算子,3x3卷积核
edges_image(Image, ImaAmp, ImaDir, 'canny', 1, 'nms') // 综合梯度计算

(2) Canny边缘检测**

  • 步骤
    1. 高斯滤波:去噪。
    2. 梯度计算:类似Sobel。
    3. 非极大值抑制(NMS)​:保留梯度方向上的局部最大值,细化边缘。
    4. 滞后阈值:使用高低阈值(LowThreshold, HighThreshold)连接边缘。

halcon示例:

edges_sub_pix(Image, Edges, 'canny', 1.5, 20, 40)  // Canny算法,亚像素精度

(3) 亚像素边缘检测**

  • 原理:在像素级边缘检测的基础上,通过插值梯度模型拟合​(如高斯函数、多项式)将精度提升到亚像素级别(精度可达0.1像素)。

halcon 示例:

edges_sub_pix(Image, Edges, 'canny', 1.5, 20, 40)  // 直接输出亚像素边缘轮廓

3. Halcon边缘检测的关键技术

​**(1) 高斯滤波与尺度控制**

  • 作用:通过调节高斯滤波的Sigma参数控制边缘检测的灵敏度。​示例

    • 大Sigma:检测粗边缘,抗噪能力强。
    • 小Sigma:检测细边缘,但易受噪声干扰。
edges_sub_pix(Image, Edges, 'canny', Sigma, LowThresh, HighThresh)

(2) 非极大值抑制(NMS)​**

  • 作用:在梯度方向上仅保留局部最大值的像素,消除边缘的“宽线”现象。
  • Halcon参数
edges_image(Image, ImaAmp, ImaDir, 'canny', 1, 'nms')  // 使用NMS

(3) 滞后阈值(双阈值)​**

  • 原理:​参数示例

    • 高阈值:强边缘必须超过此值。
    • 低阈值:弱边缘若与强边缘连接则保留。
edges_sub_pix(Image, Edges, 'canny', 1.5, 20, 40)  // Low=20, High=40

4. Halcon边缘检测的优势

  1. 亚像素精度:通过模型拟合实现超像素级边缘定位,适合高精度测量。
  2. 灵活性:支持多种算法(Canny、Sobel、Lanser等)和参数调节。
  3. 抗噪能力:高斯滤波和滞后阈值有效抑制噪声。
  4. 实时性:高度优化的算法实现,适用于工业实时检测。

5. 总结

Halcon的边缘检测通过梯度计算非极大值抑制双阈值分割亚像素优化,实现了高精度和强鲁棒性的边缘提取。其核心在于*衡噪声抑制与细节保留,广泛应用于工业检测、自动驾驶、医学成像等领域。实际使用时需根据场景特点调整算法参数,并结合形态学操作(如膨胀、填充)优化结果。

二.算子与案例学习

  这里正常我是想让大家先学习相关的算子函数的,但是因为我自己也学习过,我们学习的心态都是不见兔子不撒鹰,没有看到一些效果之前,我们都难以产生比较大的学习热情,所以这里先上一个车道线提取的案例学习,注释都会详细打清楚。在大一上学期的时候自己买了本单片机来学,发现学的太枯燥了,后来就放弃的硬件的路,后面偶然得到了个c语言的学习视频,然后跟着视频学,大一就把c语言c++,MFC那些东西都自学完了。对于初学的人没有能直观看到效果的学习,都是没有太大兴趣的。书本和文字冷冰冰的,怎么让初学者去学!!!

1.案例:车道线检测(autobahn.hdev)

老规矩,先上图,我们的目的是把一定距离内的车道的车道线给提取出来

实例代码:autobahn.hdev

* autobahn.hdev: Fast detection of lane markers
*
dev_update_window ('off')
* 关闭窗口自动更新,避免频繁刷新提升执行速度
dev_close_window ()
* 关闭所有已打开的图形窗口
dev_open_window (0, 0, 768, 575, 'black', WindowID)
* 打开新窗口,位置(0,0),尺寸768x575,背景黑色
MinSize := 30
* 定义形态学膨胀的核大小(30x30矩形)
get_system ('init_new_image', Information)
* 获取系统默认的'init_new_image'参数值
set_system ('init_new_image', 'false')
* 禁止系统自动初始化新图像,避免覆盖已有图像 * 生成网格区域,用于限制后续处理的ROI(感兴趣区域) 注意这里只是提取宽度为30像素的网格线区域出来
gen_grid_region (Grid, MinSize, MinSize, 'lines', 512, 512)
* 参数说明:
* Grid : 输出网格区域
* MinSize : 网格线间距(水*和垂直均为30像素)
* 'lines' : 生成线型网格(非矩形块)
* 512, 512 : 网格覆盖的原始图像尺寸(此处可能与实际图像尺寸不一致,后续通过裁剪修正) * 裁剪网格区域,仅保留道路部分(坐标范围:行130~450,列10~502)
clip_region (Grid, StreetGrid, 130, 10, 450, 502) dev_set_line_width (3)
* 设置显示线宽为3(用于网格和边缘的高亮显示)
dev_set_color ('green')
* 设置显示颜色为绿色(用于网格)
read_image (ActualImage, 'autobahn/scene_00')
* 读取第一帧图像(scene_00)
dev_display (ActualImage)
* 显示图像
stop ()
* 暂停程序,等待用户按F5继续
dev_display (StreetGrid)
* 在图像上叠加显示裁剪后的网格区域(绿色)
stop ()
* 再次暂停 for i := 0 to 28 by 1
* 读取当前帧图像(例如:scene_00, scene_01,..., scene_28)
read_image (ActualImage, 'autobahn/scene_' + (i$'02'))
* i$'02'表示两位数字补零 * 将处理区域限制到StreetGrid网格内
reduce_domain (ActualImage, StreetGrid, Mask)
* 作用:生成一个掩膜图像Mask,仅保留StreetGrid区域内的像素 * Sobel边缘检测(梯度幅值计算)
sobel_amp (Mask, Gradient, 'sum_abs', 3)
* 参数说明:
* 'sum_abs' : 梯度计算方法(水*与垂直方向绝对值之和)
* 3 : Sobel算子尺寸(3x3核) * 初次阈值分割提取边缘点 Gradient这个是得到的梯度图,只有在边缘区域(也就是道路和道路线交汇的区域)才会有较高的灰度值存在
threshold (Gradient, Points, 20, 255)
* 提取梯度值在[20, 255]之间的区域(初步筛选车道线边缘) * 形态学膨胀(连接离散边缘点)
dilation_rectangle1 (Points, RegionDilation, MinSize, MinSize)
* 使用30x30矩形核对边缘点进行膨胀,连接相邻点形成连续区域 * 限制处理区域到膨胀后的区域
reduce_domain (ActualImage, RegionDilation, StripGray)
* StripGray为仅包含RegionDilation区域的灰度图像 * 高亮度区域提取(车道线通常为白色/黄色)
threshold (StripGray, Strip, 190, 255)
* 提取灰度值在[190, 255]之间的区域(高亮度车道线) * 填充区域内的孔洞
fill_up (Strip, RegionFillUp)
* 确保车道线区域连续无断裂 * 显示处理结果
dev_display (ActualImage)
* 显示原始图像
dev_display (RegionFillUp)
* 叠加显示检测到的车道线区域(默认颜色)
endfor dev_set_line_width (1)
* 恢复默认线宽为1
dev_update_window ('on')
* 重新启用窗口自动更新
set_system ('init_new_image', Information)
* 恢复系统参数'init_new_image'的默认值

关键步骤总结

  1. ROI限制:通过网格裁剪 (clip_region) 和域缩减 (reduce_domain) 聚焦道路区域,减少计算量。
  2. 边缘检测:Sobel算子提取梯度,阈值分割初步筛选边缘点。
  3. 形态学处理:膨胀操作连接离散点,填充操作确保车道线连续。
  4. 亮度阈值:假设车道线高亮,通过二次阈值分割精确定位。

效果图:

  第一个案例有我的注释在理解起来应该还是比较简单的,也发现了里面开始运用到了一些边缘检测的算子,接下来我们就学习一下几个常用的边缘检测的算子。

1.sobel算子sobel_amp(Image : EdgeAmplitude : FilterTypeSize : )详解:

函数原型:

sobel_amp(Image : EdgeAmplitude : FilterType, Size : )
  • 功能:通过 Sobel 算子计算图像的梯度幅值,用于边缘检测。
  • 输入/输出
    • Image:输入图像(单通道灰度图像)。
    • EdgeAmplitude:输出图像,表示梯度幅值(边缘强度)。
    • FilterType:梯度计算方法(如 'sum_abs')。
    • Size:Sobel 核的大小(3, 5, 7, 9, 11 等奇数)。

1. ​**FilterType参数(梯度计算方式)​**

控制梯度幅值的计算方法,常见选项如下:

  • ​**'sum_abs'**​(默认):

    • 计算水*和垂直方向梯度的绝对值之和:

    • 计算速度快,适用于实时性要求高的场景。
  • ​**'thin_sum_abs'**:

    • 类似 'sum_abs',但使用更小的卷积核(仅适用于 Size=3)。
  • ​**'x'** 或 ​**'y'**:

    • 仅计算水*方向('x')或垂直方向('y')的梯度。
  • ​**'frei_chen'**:

    • 使用 Frei-Chen 算子,增强对角边缘的响应。
    • 适用于复杂纹理或对角边缘检测。
  • ​**'sobel'**:

    • 计算欧几里得距离(*方和开根号):

  • 更接*理论梯度,但计算量较大。

2. ​**Size(卷积核大小)​**

  • 取值范围:3, 5, 7, 9, 11 等奇数。
  • 影响
    • 小尺寸(如 3)​:检测细边缘,但对噪声敏感。
    • 大尺寸(如 5)​:检测粗边缘,抗噪能力强,但可能丢失细节。
  • 典型选择
    • 大多数场景:Size=3
    • 高噪声图像:Size=57

使用示例

示例 1:基本边缘检测

read_image(Image, 'part.png')
sobel_amp(Image, EdgeAmplitude, 'sum_abs', 3)
threshold(EdgeAmplitude, Edges, 20, 255) // 阈值分割提取边缘

应用场景

  1. 工业检测

    • 检测零件轮廓、缺陷边缘。
    • 参数建议:FilterType='sum_abs', Size=3
  2. 车道线检测(如 autobahn.hdev)​

    • 提取车道线边缘,需*衡噪声抑制和边缘连续性。
    • 参数建议:FilterType='sum_abs', Size=3
  3. 医学图像处理

    • 检测组织边界或血管。
    • 参数建议:FilterType='frei_chen', Size=5(增强复杂边缘)。

参数选择建议

场景需求 推荐参数
实时性要求高 FilterType='sum_abs', Size=3
高精度边缘定位 FilterType='sobel', Size=3
抗噪需求强 Size=57
检测对角边缘 FilterType='frei_chen'

与其他算子的对比

算子 特点 适用场景
sobel_amp 灵活调节核大小,多种梯度计算方式 通用边缘检测
edges_image 集成非极大值抑制(NMS)和亚像素精度 高精度边缘(如测量)
canny 双阈值和NMS,抗噪能力强但计算量大 复杂背景下的弱边缘检测

2.亚像素精度边缘提取算子(常用)edges_sub_pix(Image : Edges : FilterAlphaLowHigh : )详解:

函数原型:

edges_sub_pix(Image : Edges : Filter, Alpha, Low, High : )
  • 功能:​亚像素级精度的边缘检测,输出连续的边缘轮廓(XLD格式)。
  • 输入/输出
    • Image:输入图像(单通道灰度图像)。
    • Edges:输出的亚像素边缘轮廓(XLD对象)。
    • Filter:边缘检测滤波器类型(如 'canny', 'lanser2', 'deriche1')。
    • Alpha:滤波器的*滑参数(控制边缘锐度与抗噪性)。
    • Low, High:滞后阈值(用于边缘连接)。

参数详解

1. ​**Filter(滤波器类型)​**

不同滤波器对应不同的边缘检测算法:

  • ​**'canny'**​(默认):

    • 基于高斯导数,支持亚像素精度。
    • 适用于通用场景,计算效率高。
    • Alpha:高斯滤波器的标准差(推荐值:1.0~3.0)。
  • ​**'lanser2'**:

    • 使用 Lanser 滤波器,边缘定位更精确。
    • 适用于高精度测量,但计算量较大。
    • Alpha:*滑参数(推荐值:0.3~0.7)。
  • ​**'deriche1'** 和 ​**'deriche2'**:

    • 基于递归滤波器,适合实时处理。
    • Alpha:控制*滑程度(值越大,*滑越强)。

2. ​**Alpha(*滑参数)​**

  • 作用:*衡边缘锐度与噪声抑制。

    • 小Alpha​(如 0.5):保留细节,但易受噪声干扰。
    • 大Alpha​(如 3.0):强*滑,适合高噪声图像。
  • 典型值
    • 'canny':1.0~3.0。
    • 'lanser2':0.3~0.7。

3. ​**LowHigh(滞后阈值)​**

  • 作用:​经验规则High ≈ 2 * Low

    • High:边缘强度的最低阈值,高于此值的边缘被保留。
    • Low:低于此值的边缘被忽略;介于两者之间的边缘需与高阈值边缘连接。
  • 示例
    • 若图像对比度低,设置 Low=10, High=20
    • 若对比度高,设置 Low=30, High=60

使用示例

示例 1:Canny 边缘检测

read_image(Image, 'part.png')
edges_sub_pix(Image, Edges, 'canny', 1.5, 25, 50)
dev_display(Edges) * 显示亚像素边缘

示例 2:Lanser 滤波器(高精度)

edges_sub_pix(Image, Edges, 'lanser2', 0.5, 20, 40)

应用场景

  1. 工业测量

    • 检测零件边缘,用于尺寸测量。
    • 参数建议:Filter='lanser2', Alpha=0.5, Low=20, High=40
  2. 车道线检测

    • 提取车道线轮廓,结合形态学处理。
    • 参数建议:Filter='canny', Alpha=1.5, Low=15, High=30
  3. 医学图像分析

    • 定位组织或器官边界。
    • 参数建议:Filter='canny', Alpha=2.0, Low=10, High=20

参数调优策略

问题现象 解决方案
边缘断裂 降低 Low 或增大 Alpha
噪声过多 增大 Alpha 或提高 Low/High
边缘模糊 减小 Alpha
漏检弱边缘 降低 HighLow

对比其他边缘检测算子

算子 精度 抗噪性 速度 适用场景
edges_sub_pix 亚像素 高精度测量
sobel_amp 像素级 快速边缘检测
canny 像素级 复杂背景下的边缘

总结

edges_sub_pix 是 Halcon 中实现亚像素边缘检测的核心算子,通过合理选择滤波器类型(Filter)、*滑参数(Alpha)和阈值(Low, High),可在噪声抑制与细节保留之间取得*衡。典型场景包括工业零件测量、车道线识别和医学图像分析。实际应用中需结合后处理操作(如边缘连接和拟合)以提升结果质量。

3.像素精度边缘提取算子edges_image(Image : ImaAmpImaDir : FilterAlphaNMSLowHigh : )详解:

函数原型:

edges_image(Image : ImaAmp, ImaDir : Filter, Alpha, NMS, Low, High : )
  • 功能:执行像素级边缘检测,输出梯度幅值图像(ImaAmp)和方向图像(ImaDir),支持多种滤波器和非极大值抑制(NMS)。
  • 输入/输出
    • Image:输入图像(单通道灰度图像)。
    • ImaAmp:输出梯度幅值图像(灰度图,高值对应边缘)。
    • ImaDir:输出梯度方向图像(角度图,范围0~180°)。
    • Filter:边缘检测滤波器类型(如 'canny', 'sobel_fast')。
    • Alpha:滤波器*滑参数。
    • NMS:非极大值抑制模式('none', 'nms', 'thin')。
    • Low, High:滞后阈值(用于边缘连接)。

参数详解

1. ​**Filter(滤波器类型)​**

  • ​**'canny'**:

    基于高斯导数的Canny算法,支持亚像素级精度。

    • Alpha:高斯滤波的标准差(推荐值1.0~3.0)。
    • 特点:抗噪能力强,适用于复杂场景。
  • ​**'sobel_fast'**:

    优化的Sobel算子,计算速度快。

    • Alpha:无意义(可设为任意值)。
    • 特点:适合实时处理,但精度较低。
  • ​**'lanser2'** 或 ​**'deriche2'**:

    高精度滤波器,适合测量任务。

    • Alpha:控制*滑强度(参考值0.3~0.7)。

2. ​**Alpha(*滑参数)​**

  • 作用:控制滤波器的*滑程度。

    • 小Alpha​(如0.5):保留细节,适合清晰边缘。
    • 大Alpha​(如3.0):强*滑,适合高噪声图像。

3. ​**NMS(非极大值抑制模式)​**

  • ​**'none'**:不进行非极大值抑制,输出宽边缘。
  • ​**'nms'**:标准非极大值抑制,细化边缘至单像素宽。
  • ​**'thin'**:优化细化模式,适合高精度测量。

4. ​**LowHigh(滞后阈值)​**

  • 作用:​经验规则High ≈ 2 * Low

    • High:边缘强度的最低阈值,高于此值的像素被保留为强边缘。
    • Low:低于此值的像素被忽略;介于两者之间的像素需与强边缘连接。
  • 示例
    • 低对比度图像:Low=10, High=20
    • 高对比度图像:Low=30, High=60

使用示例

示例1:Canny边缘检测(带NMS)

read_image(Image, 'part.png')
edges_image(Image, Amp, Dir, 'canny', 1.5, 'nms', 20, 40)
threshold(Amp, Edges, 1, 255) // 二值化边缘

示例2:Sobel快速检测(无NMS)

edges_image(Image, Amp, Dir, 'sobel_fast', 0, 'none', 10, 20)

应用场景

  1. 工业零件检测

    • 参数Filter='canny', Alpha=1.5, NMS='nms', Low=20, High=40
    • 效果:高精度定位边缘,用于尺寸测量。
  2. 实时视频处理(如车道线检测)​

    • 参数Filter='sobel_fast', NMS='none', Low=15, High=30
    • 特点:牺牲精度换速度,适合嵌入式设备。
  3. 医学图像分析(如血管分割)​

    • 参数Filter='lanser2', Alpha=0.5, NMS='thin', Low=10, High=20
    • 效果:增强弱边缘检测能力。

参数调优策略

问题现象 解决方案
边缘过宽 启用 NMS='nms'NMS='thin'
噪声过多 增大 Alpha 或提高 Low/High
弱边缘漏检 降低 LowHigh
计算速度慢 改用 Filter='sobel_fast'

与其他算子的对比

算子 精度 抗噪性 输出类型 适用场景
edges_image 像素级 梯度幅值+方向 通用边缘检测
edges_sub_pix 亚像素 XLD轮廓 高精度测量
sobel_amp 像素级 梯度幅值 快速边缘检测

总结

edges_image 是 Halcon 中灵活的边缘检测算子,支持多种滤波器和非极大值抑制模式。其核心优势在于:

  1. 灵活性:通过 FilterNMS 适配不同场景(速度、精度、抗噪性)。
  2. 可调性:通过 Alpha 和阈值*衡噪声抑制与细节保留。
  3. 输出丰富:梯度幅值和方向信息可用于后续处理(如边缘跟踪或方向分析)。

典型应用包括工业检测、医学图像处理和实时视频分析。实际使用中需根据具体需求调整参数,并配合阈值分割或形态学操作优化结果。

 
 
 
 
   写到这里我想的是边缘检测都学了,霍夫变换也可以了解学习一下,反正基本都是可以配合起来一起使用的:

霍夫变换的基本原理

  Halcon 中的霍夫变换(Hough Transform)是一种强大的工具,主要用于从图像中检测几何形状(如直线、圆、椭圆等)

霍夫变换通过将图像空间中的点映射到参数空间(极坐标系),利用投票机制检测几何形状。

对于直线检测,每个边缘点 (x,y) 对应极坐标中的一条正弦曲线:

  • r:直线到原点的距离(像素)
  • θ:直线与图像x轴的夹角(弧度,范围:-π / 2 ~ π / 2)

关键步骤

    1. 参数空间量化:将 θ 和 r 离散化为有限区间。
    2. 累加器投票:每个边缘点在参数空间中对应的曲线经过的区间投票计数。
    3. 峰值检测:累加器值超过阈值的区间视为检测到的直线参数。
 
 霍夫变换在halcon中的算子有:hough_lines(),hough_circles(),hough_line_trans(),hough_circle_trans()等等。然后继续我们的算子学习正题:
 
 
 
 
 
4.霍夫变换直线检测算子hough_lines(RegionIn : : AngleResolutionThresholdAngleGapDistGap : AngleDist)详解(像刚才的车道线的提取就可以用这个函数来实现):
 

示例1:基础直线检测

* 读取图像并提取边缘
read_image(Image, 'road.png')
edges_sub_pix(Image, Edges, 'canny', 1.5, 20, 40)
threshold(Edges, RegionEdges, 1, 255) * 霍夫变换检测直线
hough_lines(RegionEdges, 0.02, 50, 0.1, 10, Angle, Dist) * 绘制检测到的直线
gen_region_hline(RegionLines, Angle, Dist)
dev_display(Image)
dev_display(RegionLines)

函数原型:

hough_lines(RegionIn : : AngleResolution, Threshold, AngleGap, DistGap : Angle, Dist)
  • 功能:使用霍夫变换(Hough Transform)从二值区域中检测直线,返回直线的角度和距离参数。
  • 输入/输出
    • 输入

      • RegionIn:输入区域(通常为边缘检测后的二值图像)。
    • 参数
      • AngleResolution:角度分辨率(控制角度检测精度)。
      • Threshold:累加器阈值(决定直线的最小支持点数)。
      • AngleGap:角度合并阈值(合并相*角度的直线)。
      • DistGap:距离合并阈值(合并相*距离的直线)。
    • 输出
      • Angle:检测到的直线的角度(弧度制,范围:-π/2 ~ π/2)。
      • Dist:直线到原点的距离(像素单位,基于极坐标公式:r = x*cosθ + y*sinθ)。

参数详解

1. ​**AngleResolution(角度分辨率)​**

  • 作用:定义霍夫空间中角度θ的步长(分辨率)。
  • 取值范围:通常为 0.01 ~ 1.0(弧度)。
  • 影响
    • 小值​(如 0.01):角度划分精细,检测精度高,但计算量大。
    • 大值​(如 0.1):角度划分粗糙,计算速度快,可能漏检细节。

2. ​**Threshold(累加器阈值)​**

  • 作用:直线在霍夫空间中的累加器值需超过此阈值才被保留。
  • 示例:​调优建议:根据图像中边缘点密度调整,避免漏检或噪声干扰。
    • Threshold=50:直线至少需要50个边缘点支持。

3. ​**AngleGap(角度合并阈值)​**

  • 作用:合并角度差小于此值的相邻直线。
  • 单位:弧度。
  • 示例
    • AngleGap=0.05(约2.86°):若两条直线角度差小于0.05弧度,视为同一方向。

4. ​**DistGap(距离合并阈值)​**

  • 作用:合并距离差小于此值的相邻直线。
  • 单位:像素。
  • 示例
    • DistGap=10:若两条直线距离差小于10像素,视为同一位置。

示例2:合并相*直线

* 合并角度差<5°、距离差<20像素的直线
AngleGap := radians(5) * 5度转弧度
DistGap := 20
hough_lines(RegionEdges, 0.02, 30, AngleGap, DistGap, Angle, Dist)
  1. 车道线检测​(如 autobahn.hdev):

    • 参数建议AngleResolution=0.02, Threshold=50, AngleGap=0.1, DistGap=15
    • 说明:合并相*的水*和倾斜车道线。
  2. 工业零件几何检测

    • 参数建议AngleResolution=0.01, Threshold=100, AngleGap=0.05, DistGap=5
    • 说明:高精度检测零件边缘的直线特征。
  3. 文档表格线提取

    • 参数建议AngleResolution=0.05, Threshold=30, AngleGap=0.2, DistGap=10
    • 说明:快速提取水*和垂直线。

参数调优策略

问题现象 解决方案
检测到过多短线段 提高 Threshold,减少噪声影响
漏检长直线 降低 Threshold,增大 AngleGap
直线断裂 合并参数(AngleGapDistGap)设置过小,适当增大
计算速度慢 增大 AngleResolution,降低精度以换取速度

关键注意事项

  1. 输入区域预处理

    • 输入 RegionIn 应为二值化的边缘区域,建议先用 edges_sub_pixsobel_amp 提取边缘。
  2. 极坐标系原点

    • 原点默认为图像左上角(Halcon坐标系),距离 Dist 是直线到原点的极坐标距离。
  3. 角度范围

    • 输出角度 Angle 范围为 -π/2π/2,对应直线方向(与x轴夹角)。

与其他直线检测方法的对比

方法 优点 缺点
hough_lines 直接输出参数,支持合并相*直线 计算量较大,需精细调参
fit_line_contour_xld 基于轮廓拟合,精度高 需先提取边缘轮廓,无法合并直线
深度学习(如HoughNet) 鲁棒性强,适应复杂场景 需要大量训练数据和算力

总结

hough_lines 是 Halcon 中基于霍夫变换的经典直线检测算子,通过调节角度分辨率、阈值和合并参数,可适应不同场景的直线检测需求。其核心优势在于直接输出直线的极坐标参数,便于后续几何分析。实际应用中需结合预处理(边缘检测)和后处理(参数合并)以优化结果,适用于工业检测、自动驾驶和文档分析等领域。

OK,接下来在看个案例道路图像的边缘提取edge_segments.hdev:

图像:

效果图:

实例代码:

* 关闭窗口自动更新以提升执行速度
dev_update_off () * 关闭所有已打开的图形窗口
dev_close_window () * ​****************************
* 步骤1: 读取图像并初始化窗口
* ​****************************
* 读取图像文件'mreut'
read_image (Image, 'mreut') * 获取图像尺寸
get_image_size (Image, Width, Height) * 根据图像尺寸自适应打开显示窗口
dev_open_window_fit_image (Image, 0, 0, Width, Height, WindowID) * 设置窗口字体为等宽字体,字号12
set_display_font (WindowID, 12, 'mono', 'true', 'false') * 设置绘图模式为仅绘制区域边界(不填充)
dev_set_draw ('margin') * 设置绘图线宽为3像素
dev_set_line_width (3) * 显示原始图像
dev_display (Image) * 显示继续提示信息(黑底白字)
disp_continue_message (WindowID, 'black', 'true') * 暂停执行,等待用户按键
stop () * ​****************************
* 步骤2: 边缘检测与滤波处理
* ​****************************
* 使用Lanser2滤波器进行边缘检测
* 参数说明:
* 'lanser2' : 滤波器类型(*衡精度与抗噪性)
* 0.5 : *滑系数(Alpha值)
* 'nms' : 非极大值抑制
* 20, 40 : 滞后阈值(Low=20, High=40)
edges_image (Image, ImaAmp, ImaDir, 'lanser2', 0.5, 'nms', 20, 40) * 显示梯度幅值图像
dev_display (ImaAmp) * 显示继续提示信息
disp_continue_message (WindowID, 'black', 'true') * 暂停执行
stop () * ​****************************
* 步骤3: 阈值分割与连通域提取
* ​****************************
* 对梯度幅值图像进行阈值分割(保留所有非零像素)
threshold (ImaAmp, Region, 1, 255) * 分割连通域(每个边缘段为一个独立区域)
connection (Region, ConnectedRegions) * 清空窗口并设置彩色显示模式
dev_clear_window ()
dev_set_colored (12) * 显示所有连通域(不同颜色区分)
dev_display (ConnectedRegions) * 显示继续提示信息
disp_continue_message (WindowID, 'black', 'true') * 暂停执行
stop () * ​****************************
* 步骤4: 边缘分段处理与XLD生成
* ​****************************
* 清空窗口准备显示最终结果
dev_clear_window () * 计算连通域总数
count_obj (ConnectedRegions, Number) * 创建空对象容器存储XLD轮廓
gen_empty_obj (XLDContours) * 遍历所有连通域
for i := 1 to Number by 1
* 选择第i个连通域
select_obj (ConnectedRegions, SingleEdgeObject, i) * 将骨架线分割为独立线段
* 参数说明:
* 2 : 最小线段长度(短于2像素的线段被丢弃)
split_skeleton_lines (SingleEdgeObject, 2, BeginRow, BeginCol, EndRow, EndCol) * 遍历当前连通域分割出的所有线段
for k := 0 to |BeginRow| - 1 by 1
* 根据起点和终点坐标生成XLD线段
gen_contour_polygon_xld (Contour, [BeginRow[k],EndRow[k]], [BeginCol[k],EndCol[k]]) * 将线段添加到容器中
concat_obj (XLDContours, Contour, XLDContours)
endfor
endfor * 显示最终生成的XLD轮廓集合
dev_display (XLDContours)

上面传统的主要的边缘提取都在halcon的官方示例里了,有兴趣的话还可以学习一下halcon深度学习示例里面的边缘提取segment_edges_deep_learning.hdev(把ROI区域设置好,提取参数设置好的话,提取起来也不错的):

原图提取边缘:

添加噪声干扰图后再提取边缘:

halcon 入门教程(三) 边缘检测的更多相关文章

  1. 《zw版·Halcon入门教程与内置demo》

    <zw版·Halcon入门教程与内置demo> halcon系统的中文教程很不好找,而且大部分是v10以前的版本. 例如,QQ群: 247994767(Delphi与halcon), 共享 ...

  2. 无废话ExtJs 入门教程三[窗体:Window组件]

    无废话ExtJs 入门教程三[窗体:Window组件] extjs技术交流,欢迎加群(201926085) 1.代码如下: 1 <!DOCTYPE html PUBLIC "-//W3 ...

  3. PySide——Python图形化界面入门教程(三)

    PySide——Python图形化界面入门教程(三) ——使用内建新号和槽 ——Using Built-In Signals and Slots 上一个教程中,我们学习了如何创建和建立交互widget ...

  4. Elasticsearch入门教程(三):Elasticsearch索引&映射

    原文:Elasticsearch入门教程(三):Elasticsearch索引&映射 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文 ...

  5. RabbitMQ入门教程(三):Hello World

    原文:RabbitMQ入门教程(三):Hello World 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog. ...

  6. JasperReports入门教程(三):Paramters,Fields和Detail基本组件介绍

    JasperReports入门教程(三):Paramter,Field和Detail基本组件介绍 前言 前两篇博客带领大家进行了入门,做出了第一个例子.也解决了中文打印的问题.大家跟着例子也做出了de ...

  7. WebGL入门教程(三)-webgl动画

    前面文章: WebGL入门教程(一)-初识webgl WebGL入门教程(二)-webgl绘制三角形 WebGL动画有移动.旋转和缩放,我们将移动.旋转和缩放图形,然后将其绘制到屏幕上,称为变换(tr ...

  8. 无废话SharePoint入门教程三[创建网站集和网站]

    一.前言 前两篇文章讲解了什么是SharePoint,并且介绍了在SharePoint中一些常用的概念.但概念终究是概念,我们还是要脚踏实地的去动手实践.下面的文章对于了解SharePoint的人来说 ...

  9. Spring Cloud 入门教程(三): 配置自动刷新

    之前讲的配置管理, 只有在应用启动时会读取到GIT的内容, 之后只要应用不重启,GIT中文件的修改,应用无法感知, 即使重启Config Server也不行. 比如上一单元(Spring Cloud ...

  10. MVC5 + EF6 完整入门教程三

    期待已久的EF终于来了. 学完本篇文章,你将会掌握基于EF数据模型的完整开发流程. 本次将会完成EF数据模型的搭建和使用. 基于这个模型,将之前的示例添加数据库查询验证功能. 文章提纲 概述 & ...

随机推荐

  1. 双指针习题:Binary Deque

    14.Binary Deque 题面翻译 Binary Deque - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 有多组数据. 每组数据给出 \(n\) 个数,每个数为 \(0\) ...

  2. java加密算法入门(四)-加密算法汇总

    如基本的单向加密算法: BASE64 严格地说,属于编码格式,而非加密算法 MD5(Message Digest algorithm 5,信息摘要算法) SHA(Secure Hash Algorit ...

  3. 「youlai-boot」入门篇:从0到1搭建 Java、Spring Boot、Spring Security 企业级权限管理系统

    作者主页: 有来技术 开源项目: youlai-mall︱vue3-element-admin︱youlai-boot︱vue-uniapp-template 仓库主页: GitCode︱ Gitee ...

  4. dart变量类型详解

    1==> 三个单引号的作用 String Str = ''' qijqowjdo 哈哈嘿嘿黑 '''; print(Str); 这样使用三个单引号,输出来换行:方便我们观看而已哈 2==> ...

  5. react中类似vue的插槽this.props.children的用法

    父组件 <TestHanderClick bg="blue"> <p> 如果我要显示的话,父组件是双标签,子组件中有this.props.children& ...

  6. Q:Oracle表空间使用权限错误:ORA-01950

    使用A用户账号(默认表空间tablespace_A),A用户表中插入数据报错ORA-01950 报错处理方法: 方法1:授予用户A unlimited tablespace权限 grant unlim ...

  7. Kyuubi支持Iceberg配置

    一.简述 Kyuubi调用Spark来查询iceberg表,修改Spark配置信息即可. 二.服务配置 1.上传jar包到Kyuubi server节点 可以选择emr spark组件后,按照配置组( ...

  8. 多线程之lamda表达式

    代码简化过程  public class TestLambda1 { ​     //3.静态内部类     static class Like2 implements ILike{          ...

  9. SHA1字符串加密

    使用SHA1算法,生成某个字符串的hash值作为该字符串所代表对象的唯一标识: Demo: using System; using System.Collections.Generic; using ...

  10. MarkDown学习使用图片

    学习MarkDown使用