前言图像分割是计算机视觉的核心任务之一也是Halcon工业检测中最基础的环节。本文系统梳理Halcon中四类主流分割方法——阈值分割、边缘检测、区域生长、分水岭——附带完整可运行代码和参数说明适合从入门到工程落地。一、图像分割概述图像分割Image Segmentation的目的是将一幅图像分成若干个有意义的区域以便后续进行特征提取和目标识别。在工业视觉检测中图像分割是几乎所有检测流程的基础步骤。图像分割的本质是将图像中的像素按照某种规则灰度值、颜色、纹理、边缘等划分为不同的区域使得同一区域内的像素具有相似的属性不同区域之间具有明显的差异。Halcon 提供了极为丰富的图像分割算子主要分为以下几大类阈值分割、边缘检测分割、区域生长分割、分水岭分割。实际工程中往往需要组合多种方法才能获得最佳效果。二、阈值分割2.1 全局阈值分割 — threshold全局阈值是最基础的图像分割方法凡灰度值在[MinGray, MaxGray]范围内的像素都归为前景区域。算子原型threshold(Image : Region : MinGray, MaxGray : )参数说明参数说明Image输入图像Region输出满足阈值条件的区域MinGray最小灰度值含MaxGray最大灰度值含通常设为 255示例代码* 全局阈值分割示例 read_image(Image, pellets) * 提取灰度值在 128~255 之间的亮区域 threshold(Image, Region, 128, 255) * 断开相互连接的联通域 connection(Region, ConnectedRegions) * 面积筛选 select_shape(ConnectedRegions, SelectedRegions, area, and, 500, 99999) count_obj(SelectedRegions, Number) dev_display(Image) dev_set_colored(12) dev_display(SelectedRegions)注意全局阈值适用于背景与前景灰度差异明显、光照均匀的场景。若光照不均匀建议改用动态阈值dyn_threshold。2.2 自动阈值 — binary_threshold当不确定合适的灰度阈值时可以让 Halcon 自动计算最优分割阈值支持暗区和亮区两种模式。binary_threshold(Image : Region : Method, LightDark : UsedThreshold)参数说明Method算法max_separability最大可分性即 Otsu 法LightDarklight提取亮区dark提取暗区UsedThreshold输出实际使用的阈值示例代码* 自动阈值分割示例Otsu法 dev_close_window () dev_open_window (0, 0, 512, 512, black, WindowHandle1) read_image(Image, particle) binary_threshold(Image, LightRegion, max_separability, light, UsedThreshold) dev_display(Image) dev_set_color(red) dev_display(LightRegion) * 打印实际使用的阈值 write_string(WindowHandle1, Threshold UsedThreshold)2.3 动态阈值分割 — dyn_threshold动态阈值局部阈值先对图像进行均值滤波得到背景图再将原图与背景图的差值与偏移量Offset比较从而自适应地分割出局部亮/暗区域。适用于光照不均匀的场景。dyn_threshold(OrigImage, ThresholdImage : RegionDynThresh : Offset, LightDark : )参数说明OrigImage原始图像ThresholdImage背景参考图通常为均值滤波结果Offset偏移量像素值差超过此值则被分割LightDarklight/dark/equal示例代码* 动态阈值分割示例 read_image(Image, food/cocoa_packages_01) * 对原图进行均值滤波得到背景图 mean_image(Image, MeanImage, 30, 30) * 动态阈值原图中比背景图亮5个灰度单位以上的区域 dyn_threshold(Image, MeanImage, RegionDynThresh, 5, light) connection(RegionDynThresh, ConnectedRegions) select_shape(ConnectedRegions, SelectedDefects, area, and, 20, 5000) count_obj(SelectedDefects, NumDefects) dev_display(Image) dev_set_color(red) dev_set_draw(margin) dev_display(SelectedDefects)核心思路dyn_threshold判断原图 - 参考图 Offset则为 light 区域。Offset 越小越敏感越大越严格。2.4 基于直方图的阈值分割通过分析灰度直方图找到谷底波谷作为分割阈值适用于图像灰度分布呈明显双峰的场景。*获取图像 read_image (Image, D:/Program Files/MVTec/HALCON-22.05-Progress/examples/images/pill/ginseng/contamination/pill_ginseng_contamination_045.png) *自动阈值分割 auto_threshold (Image, Regions, 5) *显示分割区域 dev_display (Regions)三、边缘检测分割边缘是图像中灰度值发生突变的区域。通过检测边缘可以找到目标的轮廓从而实现分割。Halcon 提供了多种边缘检测算子涵盖像素级与亚像素级精度。3.1 Sobel 边缘检测 — edges_imageSobel 算子通过计算图像梯度来检测边缘是最经典的边缘检测算子之一。edges_image(Image : ImaAmp, ImaDir : Filter, Alpha : )参数说明ImaAmp输出边缘幅度图像梯度强度ImaDir输出边缘方向图像Filter滤波器类型sobel、prewitt、kirsch、canny等Alpha平滑参数仅 Canny 有效* Sobel 边缘检测 read_image(Image,fabrik) edges_image(Image,Amp,Dir,lanser2,0.5,none,-1,-1) * 对边缘幅度图像进行阈值处理得到边缘区域 threshold(Amp, EdgeRegion, 20, 255)3.2 Canny 边缘检测推荐Canny 是综合效果最好的边缘检测算子具有低误检率、高定位精度和单边缘响应等特点。* Canny 边缘检测通过 edges_image 算子 read_image(Image, fabrik) edges_image(Image,Amp,Dir,lanser2,0.5,none,-1,-1) hysteresis_threshold(Amp, EdgeRegion, 20, 40, 10) dev_display(Image) dev_set_color(red) dev_display(EdgeRegion)3.3 亚像素级边缘检测 — edges_sub_pix当需要高精度定位亚像素级别时使用edges_sub_pix输出为XLD 轮廓不是区域精度可达 0.1 像素以内。edges_sub_pix(Image : Edges : Filter, Alpha, Low, High : )参数说明Edges输出XLD 亚像素轮廓Filtercanny、sobel、lanser2等Alpha高斯平滑程度越大越平滑推荐 0.5~2.0Low, High磁滞阈值Low 为弱边缘阈值High 为强边缘阈值dev_close_window() dev_open_window (0, 0, 512, 512, black, WindowHandle1) * 亚像素边缘检测示例 read_image(Image, fabrik) rgb1_to_gray(Image, GrayImage) * canny 算子 亚像素精度 edges_sub_pix(GrayImage, Edges, canny, 1.0, 20, 40) dev_display(GrayImage) dev_set_colored(12) dev_set_line_width(2) dev_display(Edges) * 显示轮廓数量 count_obj(Edges, NumEdges) write_string(WindowHandle1, Edges: NumEdges)XLD扩展线描述符是 Halcon 中表示亚像素精度轮廓的数据类型区别于普通的区域Region。XLD 可用于测量、拟合直线/圆弧等精密测量场景。四、区域生长分割区域生长法从一个或多个种子点出发根据像素间的相似性灰度差、颜色差等逐渐向外扩展将相邻的相似像素合并到同一区域直到没有满足条件的像素为止。4.1 regiongrowing 算子regiongrowing(Image : Regions : Row, Column, Tolerance, MinSize : )参数说明Row, Column种子点之间的步长像素控制种子点密度Tolerance灰度容差相邻像素灰度差小于此值则合并MinSize最小区域面积小于此值的区域被丢弃* 区域生长分割示例 read_image(Image, mreut) * 种子步长3, 容差8, 最小区域面积100 regiongrowing(Image, Regions, 3, 3, 8, 100) dev_display(Image) dev_set_colored(12) dev_display(Regions) count_obj(Regions, NumRegions) write_string(WindowHandle, Regions: NumRegions)4.2 regiongrowing_mean 算子改进版区域生长以区域内的平均灰度值作为合并判据比regiongrowing更稳健。read_image (Image, fabrik) * 读取 fabrik 图像Halcon自带示例图工厂场景 dev_close_window () get_image_size (Image, Width, Height) dev_open_window (0, 0, Width, Height, white, WindowID) * 关闭旧窗口按图像尺寸打开新窗口背景白色 * 第一阶段中值滤波 粗区域生长目的是定位种子点 median_image (Image, ImageMedian, circle, 2, mirrored) * 中值滤波去噪圆形掩模半径2边界镜像处理 * 这一步很关键区域生长对噪声敏感先平滑才能避免过分割 regiongrowing (ImageMedian, Regions, 1, 1, 2, 5000) * 粗区域生长步长Row1,Column1每个像素都是种子点 * 容差Tolerance2灰度差≤2就合并最小面积MinSize5000 * → 得到大面积的粗分割区域 shape_trans (Regions, Centers, inner_center) * 对每个粗区域取内中心点——即区域质心附近的一个点 * 把大面积区域压缩成一个个种子点 connection (Centers, SingleCenters) * 断开连通域确保每个种子点是独立的 area_center (SingleCenters, Area, Row, Column) * 获取每个种子点的坐标(Row, Column) —— 这就是传给下一步的关键参数 * 第二阶段以精确种子点做均值区域生长 regiongrowing_mean (ImageMedian, RegionsMean, Row, Column, 25, 100) * ↑ 核心Row/Column 是上一步算出的种子点坐标不是步长 * Tolerance25容差更大因为有了精确种子点不怕误合并 * MinSize100最小面积更小保留细节区域 dev_clear_window () dev_set_draw (fill) dev_set_colored (12) dev_display (RegionsMean) * 填充模式彩色显示结果 dev_set_color (black) dev_set_draw (margin) dev_display (RegionsMean) * 再用黑色边框描边显示方便看区域边界五、分水岭分割分水岭算法将灰度图像看作地形图灰度值越高代表山峰越高。通过模拟注水过程水从低处灰度谷底积聚当来自不同谷底的水即将汇合时在汇合处建立分水岭从而将图像分割成不同的盆地连通区域。分水岭分割特别适合分离相互黏连的目标物体例如相互挤靠在一起的圆形颗粒、细胞等。5.1 watersheds 算子watersheds(Image : Basins, Watersheds : )输出参数说明Basins各个盆地区域分割结果Watersheds分水岭本身边界线区域* 基础分水岭分割 read_image(Image, particle) rgb1_to_gray(Image, GrayImage) * 高斯平滑避免过分割 gauss_image(GrayImage, GaussImage, 3) * 执行分水岭分割 watersheds(GaussImage, Basins, Watersheds) dev_display(GaussImage) dev_set_colored(12) dev_display(Basins)5.2 watersheds_threshold 算子带阈值推荐原始watersheds对噪声极为敏感容易产生过分割分割出大量细小无意义区域。watersheds_threshold通过合并灰度差小于阈值Threshold的相邻盆地来解决此问题。watersheds_threshold(Image : Basins : Threshold : )完整工业案例配合距离变换分离黏连目标* 带阈值的分水岭分割完整工业案例 read_image(Image, 素材/4-6 4-7.jpg) rgb1_to_gray(Image, GrayImage) * 高斯平滑去噪 gauss_image(GrayImage, SmoothedImage, 3) * 距离变换用于分离黏连目标 * 先二值化 threshold(SmoothedImage, BrightRegion, 100, 255) * 计算距离变换图像 distance_transform(BrightRegion, DistanceImage, octagonal, true, Width, Height) convert_image_type(DistanceImage, ImageConverted, byte) * 图像取反距离变换后取反使中心变为山谷 invert_image(ImageConverted, ImageInvert) * 按比例增强对比度 scale_image_max(ImageInvert, ImageScaleMax) * 带阈值的分水岭分割合并高度差30的相邻区域 watersheds_threshold(ImageScaleMax, Basins, 30) * 筛选合理面积的区域 select_shape(Basins, SelectedBasins, area, and, 500, 50000) * 显示结果 dev_display(GrayImage) dev_set_colored(12) dev_set_draw(margin) dev_set_line_width(2) dev_display(SelectedBasins) count_obj(SelectedBasins, Number) dev_set_color(green) set_display_font(WindowHandle, 28, mono, true, false) set_tposition(WindowHandle, 15, 15) write_string(WindowHandle, Count Number)六、Hough变换分割Hough变换是一种用于检测图像中几何形状直线、圆、椭圆等的经典算法常用于检测工业零件中的圆孔、直线边缘等规则形状。6.1 直线检测 — hough_lines* Hough 直线检测 read_image(Image, fabrik) rgb1_to_gray(Image, GrayImage) edges_sub_pix(GrayImage, Edges, canny, 1.0, 20, 40) * 生成二值化边缘图 gen_region_contour_xld(Edges, EdgeRegion, filled) * Hough 直线检测 hough_lines(EdgeRegion, HoughImage, Lines, AngleResolution, DistanceResolution, Threshold, AngleGap, DistGap) dev_display(GrayImage) dev_set_color(red) dev_set_line_width(2) dev_display(Lines)6.2 圆检测 — 最小外接圆 圆度筛选* 圆检测示例形态学 圆度筛选 read_image(Image, rings_and_nuts) rgb1_to_gray(Image, GrayImage) threshold(GrayImage, Region, 0, 128) connection(Region, ConnectedRegions) select_shape(ConnectedRegions, SelectedRegions, circularity, and, 0.8, 1.0) * 计算圆的最小外接圆 smallest_circle(SelectedRegions, Row, Column, Radius) dev_display(GrayImage) dev_set_color(green) disp_circle(WindowHandle, Row, Column, Radius)七、分割方法对比总结分割方法适用场景优点缺点常用算子全局阈值高对比度、光照均匀简单、快速不适合光照不均threshold自动阈值双峰灰度分布无需手动调参仅适合双峰分布binary_threshold动态阈值光照不均匀自适应局部背景参数选取有技巧dyn_threshold边缘检测边界明显的目标定位精度高亚像素对噪声敏感edges_sub_pix区域生长均匀灰度区域区域完整、连通对种子选择敏感regiongrowing分水岭黏连目标分离能分离相互接触目标过分割需配合阈值watersheds_thresholdHough变换规则形状检测抗噪声、不依赖连通性计算量大形状固定hough_lines/smallest_circle八、综合实战案例 — 芯片焊点检测结合多种分割方法实现对 PCB 板上焊点的自动检测与计数* 芯片焊点检测完整流程 dev_update_off() dev_close_window() read_image(Image, die/die_03) get_image_size(Image, Width, Height) dev_open_window(0, 0, Width, Height, black, WindowHandle) dev_set_part(0, 0, Height-1, Width-1) set_display_font(WindowHandle, 16, mono, true, false) dev_display(Image) stop() * 第1步分割芯片主体区域 * 二值化提取亮区 threshold(Image, Bright, 100, 255) * 形状变换用最小外接矩形定位芯片位置 shape_trans(Bright, Die, rectangle2) dev_set_color(green) dev_set_draw(margin) dev_display(Die) stop() * 第2步在 ROI 内定位焊点 * 限定 ROI 到芯片区域 reduce_domain(Image, Die, DieGrey) * 二值化提取暗焊点 threshold(DieGrey, Wires, 0, 50) * 填充小孔面积1~100的孔洞 fill_up_shape(Wires, WiresFilled, area, 1, 100) dev_set_draw(fill) dev_set_color(red) dev_display(WiresFilled) stop() * 第3步形态学开运算分离焊点 * 圆形结构元素开运算半径15.5像素 opening_circle(WiresFilled, Balls, 15.5) * 第4步连通区域分析 connection(Balls, SingleBalls) * 按圆度筛选0.85~1.0为圆形 select_shape(SingleBalls, IntermediateBalls, circularity, and, 0.85, 1.0) * 按列方向排序 sort_region(IntermediateBalls, FinalBalls, first_point, true, column) * 第5步计算并显示结果 dev_display(Image) dev_set_colored(12) dev_display(FinalBalls) smallest_circle(FinalBalls, Row, Column, Radius) NumBalls : |Radius| Diameter : 2 * Radius meanDiameter : mean(Diameter) dev_set_color(white) disp_circle(WindowHandle, Row, Column, Radius) disp_message(WindowHandle, D: Diameter$.3, image, Row - 2*Radius, Column, white, false) set_tposition(WindowHandle, 15, Width / 2) write_string(WindowHandle, Total Balls NumBalls MeanDia meanDiameter$.2f) dev_update_window(on)流程解析分割主体区域→thresholdshape_trans定位芯片位置ROI内定位焊点→reduce_domain限定区域 threshold提取暗焊点 fill_up_shape填充孔洞形态学分离→opening_circle圆形开运算分离黏连焊点连通分析→connectionselect_shape按圆度筛选结果展示→smallest_circle计算外接圆 disp_message显示直径与数量九、常用算子速查算子功能关键参数threshold全局阈值分割MinGray, MaxGraybinary_threshold自动阈值OtsuMethod, LightDarkdyn_threshold动态局部阈值Offset, LightDarkgray_histo_abs计算绝对灰度直方图BinSizehisto_to_thresh直方图自动求阈值-edges_image边缘检测像素级Filter, Alphaedges_sub_pix亚像素边缘检测Filter, Alpha, Low, Highhysteresis_threshold双阈值磁滞滤波Low, High, MaxLengthregiongrowing区域生长Row, Column, Tolerance, MinSizeregiongrowing_mean均值区域生长Tolerance, MinSizewatersheds分水岭分割-watersheds_threshold带阈值分水岭推荐Thresholddistance_transform距离变换配合分水岭Metricinvert_image图像取反-scale_image_max图像灰度拉伸-fill_up_shape按形状特征填充区域Feature, Min, Maxselect_shape按形状特征筛选区域Feature, Operation, Min, Maxconnection断开联通区域-opening_circle圆形结构开运算Radiussmallest_circle计算最小外接圆-