halcon 入门教程(一) 预处理图像 (图像平滑,图像增强,二值化,形态学分析)
原文作者:aircraft
原文链接:https://www.cnblogs.com/DOMLX/p/18779326
有兴趣可以多看其他的halcon教程
本来今天想写一下halcon深度学习教程(三)目标检测的,不过今天有显卡的那台电脑连不上,干脆总结一下halcon的学习入门中的一些知识好了,如果你想入门halcon图像处理,那么看完我这篇至少大概了解一些halcon的图像处理知识了,语法这里就不会写了。halcon的入门教程主要的已经写了七七八八了,应该会对大家有帮助,因为我也是大学时期自己自学过来的,网上很少有halcon的入门教程!!!
因为学习这个之前你肯定有编程基础的比如c#.c++什么的,看到halcon的语句和例子自然就会使用了它的语法了,或者可以单独百度一下halcon语法。好多时候都是用halcon来测试算法,测试完自己在去转为c#或者c++语言编写一遍,通过halcon直接转换的数量少还好,数量一多,可读性和维护性就很差,毕竟也不是你的编程习惯写出来的,放一段时间你看的都懵逼。
一.halcon简介
Blob分析的步骤
- 
预处理: - 去噪(如高斯滤波、中值滤波)。
- 增强对比度或调整光照不均。
 
- 
二值化: - 将图像转换为黑白二值图(例如通过阈值分割),使目标区域(Blob)与背景分离。
 
- 
连通区域标记: - 扫描图像,为每个连通区域分配唯一标签(如使用种子填充法或两次扫描算法)。
 
- 
特征提取: - 计算每个Blob的特征,例如:
- 几何特征:面积、周长、质心、外接矩形、长宽比、圆形度。
- 灰度/颜色特征:平均灰度、颜色分布。
- 高阶特征:方向(主轴)、矩(用于形状描述)。
 
 
- 计算每个Blob的特征,例如:
- 
筛选与分析: - 根据特征过滤无关区域(例如排除面积过小的噪声点)。
- 分类或统计目标Blob的数量、位置、形状等。
 

接下来进入正文。
mean_image(Image : ImageMean : MaskWidth, MaskHeight : ):- 输入参数:
- Image:输入图像(单通道灰度图像)。
- MaskWidth,- MaskHeight:滤波掩模的宽度和高度(需为奇数,如 3, 5, 7 等)。
 
- 输出参数:
- ImageMean:输出图像,滤波后的结果。
 
功能与原理
- 
均值滤波: - 对图像中每个像素,取其周围 MaskWidth × MaskHeight邻域内的所有像素灰度值,计算平均值后替换原像素值。通俗的话来讲就是把图像想象成一个二维的数组,你拿着一个5*5的矩形框在数组上滑动,滑动到哪颗像素,就把这个像素在框内的周边像素的值全部加起来做个除法均值,在把均值放回这颗像素里作为他的值。
 
- 对图像中每个像素,取其周围 
- 
作用: - 平滑图像:抑制高频噪声(如高斯噪声、椒盐噪声)。
- 模糊细节:可用于预处理中降低纹理干扰(如 Blob 分析前去除细小噪声)。
 
* 读取图像
read_image(Image, 'particle.jpg')
* 均值滤波(使用5×5掩模)
mean_image(Image, ImageMean, 5, 5)
* 显示结果
dev_display(ImageMean)

2.图像平滑之高斯滤波算子:gauss_filter(Image : ImageGauss : Size : ):
- 输入参数:
- Image:输入图像(单通道灰度图像)。
- Size:高斯核的尺寸(通常为奇数值,如 3, 5, 7 等)。
 
- 输出参数:
- ImageGauss:滤波后的输出图像。
 
高斯滤波原理:
- 
高斯核: - 高斯滤波通过定义一个二维高斯函数(钟形曲线)作为卷积核,对图像进行加权平均。
- 高斯函数公式:
- 
![]() 
- 其中 σ 是标准差,控制滤波的平滑强度。
 
- 
滤波过程: - 对图像中每个像素,用高斯核覆盖其邻域,计算邻域内像素的加权平均值,权重由高斯函数决定。
- 特点:
- 中心权重高,边缘权重低,保留更多边缘信息。
- 核尺寸(Size)越大或 σ 越大,平滑效果越强。
 
 
与均值滤波的对比
| 特性 | 高斯滤波 | 均值滤波 | 
|---|---|---|
| 权重分配 | 中心高,边缘低(符合高斯分布) | 邻域内均匀权重 | 
| 边缘保留 | 较好(边缘模糊程度低) | 较差 | 
| 抗噪能力 | 对高斯噪声更有效 | 对均匀噪声有效 | 
| 计算速度 | 较慢(需计算高斯核) | 快 | 
* 读取图像
read_image(Image, 'defect.jpg')
* 高斯滤波(核尺寸5×5,σ自动计算)
gauss_filter(Image, ImageGauss, 5)
* 显示结果
dev_display(ImageGauss)


3.图像平滑之中值滤波算子:median_rect(Image : ImageMedian :MaskWidth,MaskHeight:)
- 输入参数:
- Image:输入图像(单通道灰度图像)。
- MaskWidth,- MaskHeight:矩形掩模的宽度和高度(需为奇数,如 3, 5, 7 等)。
 
- 输出参数:
- ImageMedian:滤波后的输出图像。
 
中值滤波原理
- 
核心操作: - 对图像中每个像素,取以该像素为中心的 MaskWidth × MaskHeight邻域内所有像素的灰度值。
- 将邻域内的像素值排序,取中间值(中位数)作为当前像素的新值。
 
- 对图像中每个像素,取以该像素为中心的 
- 
处理过程:参考均值滤波,说白了就是把矩形框内所有像素值排序取中间值填入像素。 
- 
特点: - 非线性滤波:不依赖线性运算,对极端噪声(如椒盐噪声)鲁棒。
- 边缘保留:中位数对局部极值不敏感,能有效保护边缘信息。
 
功能与作用
- 
噪声去除: - 特别适用于椒盐噪声(随机出现的黑白点)或脉冲噪声。
- 对小面积孤立噪声效果显著,但对高斯噪声效果有限。
 
- 
细节保留: - 相比均值滤波或高斯滤波,中值滤波在平滑噪声的同时,能更好地保留图像边缘和纹理。
 
- 
应用场景: - 工业检测:去除金属表面划痕检测中的噪声。
- 医学成像:消除 X 光或显微镜图像中的随机噪声。
- 文档处理:清理扫描文件中的斑点。
 
* 读取图像
read_image(Image, 'noisy_parts.jpg')
* 中值滤波(使用3×5矩形掩模)
median_rect(Image, ImageMedian, 3, 5)
* 显示结果
dev_display(ImageMedian)

4.图像增强之增强对比度算子:emphasize(Image : ImageEmphasize : MaskWidth, MaskHeight, Factor : )主要用于增强边缘和细节
- 输入参数:
- Image:输入图像(单通道灰度图像)。
- MaskWidth,- MaskHeight:定义局部邻域大小的掩模尺寸(需为奇数,如 3, 5, 7 等)。
- Factor:增强因子,控制细节增强的强度(通常 ≥ 0)。
 
- 输出参数:
- ImageEmphasize:处理后的输出图像。
 
核心原理
emphasize 的实现基于 高频增强算法,核心步骤如下:

通俗的讲就是
1.使用 宽为 MaskWidth,高为MaskHeight的 mean_image (均值滤波器) 进行均值滤波。滤波后的图像灰度记为 mean, 滤波前的灰度记为 orig
2.将图像按如下公式进行计算得到结果图像
res := round((orig - mean) * Factor) + orig
功能与作用
- 边缘增强:
- 锐化图像中的边缘和纹理,提升目标与背景的对比度。
 
- 细节突出:
- 增强微小结构(如划痕、文字、细胞边界)的可见性。
 
- 适用场景:
- 工业检测:强化产品表面缺陷(裂纹、凹陷)。
- 医学成像:突出血管、组织边界。
- 文档处理:改善低对比度文本的清晰度。
 
* 读取图像
read_image(Image, 'scratched_surface.jpg')
* 增强处理(掩模5×5,Factor=1.5)
emphasize(Image, ImageEmphasize, 5, 5, 1.5)
* 显示结果
dev_display(ImageEmphasize)

- 输入参数:
- Image:输入图像(单通道灰度图像)。
 
- 输出参数:
- ImageEquHisto:直方图均衡化后的输出图像。
 
核心原理
直方图均衡化的目标是拉伸图像的灰度分布,使其覆盖更广的动态范围,从而增强对比度。具体步骤如下:

说白了就是统计图像中的灰度出现的次数作为直方图,然后将主要的各个直方图的灰度区域和领域的区别增大增亮,让你可以清晰的看到各个灰度分布的成像
功能与作用
- 对比度增强:
- 扩展图像的灰度范围,使暗区更亮、亮区更暗,提升整体对比度。
 
- 细节突出:
- 增强隐藏在高光或阴影中的细节(如医学图像中的组织、工业图像中的缺陷)。
 
- 适用场景:
- 低对比度图像(如背光拍摄、雾天图像)。
- 医学成像(X光、MRI图像增强)。
- 工业检测(表面缺陷的视觉增强)。
 
* 读取图像
read_image(Image, 'low_contrast.jpg')
* 直方图均衡化
equ_histo_image(Image, ImageEquHisto)
* 显示结果
dev_display(ImageEquHisto)

scale_image_max(Image : ImageScaleMax : : )- 输入参数:
- Image:输入图像(单通道灰度图像,支持8位、16位等数据类型)。
 
- 输出参数:
- ImageScaleMax:输出图像,灰度范围被拉伸到当前数据类型允许的最大值(如8位图像为0-255)。
 

功能与作用
- 对比度拉伸:
- 将狭窄的灰度范围扩展到全动态范围,增强图像的整体对比度。
 
- 适用场景:
- 低对比度图像(如背光拍摄、医学成像)。
- 灰度范围未被充分利用的图像(例如传感器采集的原始数据)。
 
- 优势:
- 计算速度快,无需手动设置参数。
- 保留像素值的相对分布,不改变直方图形状(仅拉伸)。
 
与直方图均衡化的对比
| 特性 | scale_image_max | equ_histo_image(直方图均衡化) | 
|---|---|---|
| 原理 | 线性拉伸灰度范围 | 非线性重分布直方图 | 
| 对比度增强 | 全局均匀拉伸 | 局部自适应增强 | 
| 直方图形状 | 保持原分布形状 | 近似均匀分布 | 
| 噪声影响 | 可能放大噪声 | 可能增强噪声或产生伪影 | 
| 适用场景 | 灰度范围狭窄的图像 | 直方图分布不均的图像 | 
* 读取低对比度图像
read_image(Image, 'dark_surface.jpg')
* 自动拉伸灰度范围
scale_image_max(Image, ImageScaleMax)
* 显示结果
dev_display(ImageScaleMax)
而有时候常用的反而是自己调参的scale_image(Image : ImageScaled : Mult, Add : )算子,缩放图像的灰度值,基本是让亮的区域更亮,暗的区域更暗来增强图像对比度。
公式截图放大点好看点

- 输入参数:
- Image1,- Image2:输入图像(需尺寸相同且数据类型一致,如均为- byte、- uint2或- real)。
- Mult:乘法因子(缩放系数)。
- Add:加法因子(偏移量)。
 
- 输出参数:
- ImageResult:输出图像,计算公式为:
 

核心功能
- 像素级运算:
- 对两幅图像的每个像素进行乘法和加法操作,生成新图像。
 
- 应用场景:
- 图像融合:通过乘法叠加掩模(如 ROI 区域提取)。
- 对比度增强:结合乘法(调整对比度)和加法(调整亮度)。
- 传感器校准:校正非线性响应或添加固定偏移量。
 
参数说明
| 参数 | 作用 | 
|---|---|
| Mult | 控制乘积结果的幅度, Mult > 1放大对比度,0 < Mult < 1降低对比度。 | 
| Add | 调整输出图像的全局亮度,正值增亮,负值减暗。 | 
与其他算子的对比
| 算子 | 公式 | 适用场景 | 
|---|---|---|
| mult_image | I1×I2×M+A | 图像融合、对比度与亮度调整 | 
| add_image | I1+I2 | 图像叠加、亮度叠加 | 
| scale_image | I×M+A | 单图像对比度/亮度调整 | 
* 读取两幅图像(假设尺寸相同)
read_image(Image1, 'part1.jpg')
read_image(Image2, 'mask.jpg')
* 图像乘法与加法:ImageResult = (Image1 * Image2) * 0.5 + 50
mult_image(Image1, Image2, ImageResult, 0.5, 50)
* 显示结果
dev_display(ImageResult)

rgb1_to_gray (Image, GrayImage),如果本身就是单通道图像就不用了。灰度图就是灰度值分布在0-255之间的图像,而二值化就是将图像中的灰度变成0和255,比如大于100以上的你就变成255,以下的就是0,这样的黑白分明了。主要用于分割图像的时候。- 输入参数:
- Image:输入图像(单通道灰度图像)。
- MinGray,- MaxGray:灰度阈值范围,闭区间- [MinGray, MaxGray]。
 
- 输出参数:
- Region:输出区域,包含所有灰度值在阈值范围内的像素。白话将就是提取灰度在- MinGray到- MaxGray之间的像素区域
 
* 读取图像
read_image(Image, 'metal_part.jpg')
* 设定阈值范围(假设目标灰度在120-220之间)
threshold(Image, Region, 120, 220)
* 显示分割结果
dev_display(Image)
dev_display(Region)
- 输入参数:
- OrigImage:原始输入图像(单通道灰度图像)。
- ThresholdImage:参考图像(通常为模糊后的图像,如高斯滤波或均值滤波结果)。
- Offset:阈值偏移量(用于放宽或收紧比较条件)。
- LightDark:比较模式,可选- 'light'、- 'dark'或- 'equal'。
 
- 输出参数:
- RegionDynThresh:满足条件的区域。
 

LightDark参数为'light'时意思就是:提取原图中相对于均值图像灰度值还要大Offset的灰度值像素区域。LightDark参数为'dark'时意思就是:提取原图中相对于均值图像灰度值还要小Offset的灰度值像素区域。LightDark参数为'equal'时意思就是:提取原图中相对于均值图像灰度值灰度差值在Offset范围内的灰度值像素区域。read_image(OrigImage, 'scratched_metal.jpg')
* 生成参考图像(高斯模糊)
gauss_filter(OrigImage, ThresholdImage, 15)
* 动态阈值分割(提取暗缺陷)
dyn_threshold(OrigImage, ThresholdImage, Scratches, 10, 'dark')
* 显示结果
dev_display(OrigImage)
dev_display(Scratches)
2、auto_threshold:直方图阈值分割算子。它通过分析图像的直方图,自动确定一个或多个阈值来进行分割。这种方法对于具有明显双峰或多峰的直方图图像效果较好。
3、bin_threshold:已过时的算子,建议使用binary_threshold替代。它使用自动确定的阈值分割单通道的灰度图像。首先确定输入图像的相对直方图,然后从直方图中提取相关的最小值作为阈值操作的参数。
4、binary_threshold:二值阈值分割算子。它使用自动确定的全局阈值分割单通道图像,并在输出区域中返回分割后的结果。适用于在均匀照明的背景下分割字符等对象。
5、dyn_threshold:局部阈值分割算子。它根据图像的局部特征来确定阈值,因此可以处理灰度分布不均匀的图像。通常,阈值图像是原始图像的平滑版本,通过比较原始图像和阈值图像来确定分割区域,该算子使用前一般会先使用平滑算子将图像平滑。
6、fast_threshold:fast_threshold从输入图像中选取灰度值g满足以下条件的像素:MinGray<= G <=MaxGray,为了减少处理时间,选择分为两个步骤:首先,处理位于选定水平线上的所有点,这些点由它们的距离MinSize指定。在下一步中,处理所有先前选择点的邻域(size (2*MinSize+1) x (2*MinSize+1))。在支持SSE2指令集的多核计算机上,threshold很可能比fast_threshold更快。只有在这些特性不可用的情况下(例如在嵌入式平台上),才可能首选fast_threshold而不是threshold。
7、var_threshold:可变阈值分割算子。它允许在每个像素位置使用不同的阈值进行分割,因此可以处理更复杂的图像。这种方法通常需要根据图像的局部特征来动态计算阈值。
8、hysteresis_threshold:滞后阈值分割算子。它使用两个阈值(高阈值和低阈值)来进行分割。像素值高于高阈值的被确定为前景,像素值低于低阈值的被确定为背景,而位于两者之间的像素则根据邻域关系来确定其归属。
9、local_threshold:按照官方文档介绍,本算子适合文本二值化。且经过验证,该算子对光照不均匀的图像分割有较好效果。
10、histo_to_thresh:原理基于直方图统计方法,根据预设的阈值将直方图分为两部分,一部分为前景一部分为背景。为了确定最佳阈值,算法通常采用Otsu来自动选择阈值。
11、char_threshold:算子在HALCON中用于实现基于阈值的字符分割。它通过设定一个阈值来确定图像中的字符,并将其转变为二值图像。其基本原理是通过计算图像的灰度值,并将其与设定的阈值进行比较,以此来决定每个像素的新灰度值。
12、dual_threshold:算子将图像转换为两个区域,一个是低于DarkThreshold(参数)的区域(RegionDark),另一个是高于BrightThreshold(参数)的区域(RegionBright)。这种操作常用于图像的自适应阈值分割,特别是在图像的亮度变化较大的场景中。
13、watersheds_threshold:这个算子分为两步,第1步:通过分水岭算法watersheds()获取图像的盆地。第2步:根据第一步分水岭算法分离结果,若盆地部分的灰度**< threshold**,则被合并到一起。设B1和B2分别为相邻盆地的最小灰度值,W为将盆地分割为两个盆地的最小灰度值
dilation_circle(Region : RegionDilation : Radius : ):- 输入参数:
- Region:输入区域(待处理的二值化区域)。
- Radius:圆形结构元素的半径(单位:像素)。
 
- 输出参数:
- RegionDilation:膨胀后的区域。
 

说白了就是你的一个滤波核这里是个半径为R的圆形滤波核,你在对一个矩形区域进行膨胀的时候就是滤波核在这个二维的区域数组中滑动遍历,内部的时候没有变化,到边缘的时候你的圆形区域中心在矩形边界的时候,一半的圆形都会在矩形外,然后把矩形外填充上像素,不断滑动不断填充。后面的腐蚀也是一样的原理

功能与作用
- 填充孔洞:
- 扩大区域以覆盖小孔或裂缝(如金属表面的微小缺陷)。
 
- 连接邻近区域:
- 使分离的相邻区域合并(需调整半径避免过度膨胀)。
 
- 边缘平滑:
- 平滑区域的锯齿状边缘,使其更接近圆形。
 
- 应用场景:
- 工业检测:增强目标区域的连通性。
- 医学图像:连接断裂的血管或组织区域。
- 文档处理:修复字符断裂。
 
与其他膨胀操作的对比
| 操作 | 结构元素 | 适用场景 | 
|---|---|---|
| dilation_circle | 圆形 | 各向同性扩展(无方向偏好) | 
| dilation_rectangle1 | 矩形 | 水平/垂直方向扩展 | 
| dilation2 | 自定义结构元素 | 复杂形状或非对称扩展 | 
read_image(Image, 'metal_part.jpg')
* 二值化分割目标区域
threshold(Image, Region, 120, 255)
* 膨胀处理(半径3像素)
dilation_circle(Region, RegionDilation, 3)
* 显示结果
dev_display(Image)
dev_display(RegionDilation)
erosion_circle(Region : RegionErosion : Radius : )算子:
- 输入参数:
- Region:输入区域(待处理的二值化区域)。
- Radius:圆形结构元素的半径(单位:像素)。
 
- 输出参数:
- RegionErosion:腐蚀后的区域。
 


功能与作用
- 去除细小噪声:
- 消除孤立的噪点或小区域(如金属表面的灰尘斑点)。
 
- 分离粘连区域:
- 收缩目标边界,使轻微粘连的物体分离(如细胞或工业零件)。
 
- 边缘平滑:
- 去除区域边缘的毛刺,使形状更规则。
 
- 应用场景:
- 工业检测:去除微小干扰,保留主要目标。
- 医学成像:分离重叠的细胞或组织。
- 文档处理:细化字符笔画。
 
与其他腐蚀操作的对比
| 操作 | 结构元素 | 适用场景 | 
|---|---|---|
| erosion_circle | 圆形 | 各向同性收缩(无方向偏好) | 
| erosion_rectangle1 | 矩形 | 水平/垂直方向收缩 | 
| erosion2 | 自定义结构元素 | 复杂形状或非对称收缩 | 
read_image(Image, 'noisy_parts.jpg')
* 二值化分割目标区域
threshold(Image, Region, 200, 255)
* 腐蚀处理(半径2像素)
erosion_circle(Region, RegionErosion, 2)
* 显示结果
dev_display(Image)
dev_display(RegionErosion)
- 输入参数:
- Region:输入区域(待处理的二值化区域)。
- Radius:圆形结构元素的半径(单位:像素)。
 
- 输出参数:
- RegionOpening:开运算处理后的区域。
 

功能与作用
- 去噪与平滑:
- 消除小面积噪声(如灰尘、像素级干扰)。
- 平滑目标边界,去除锯齿或毛刺。
 
- 保留主结构:
- 仅移除比结构元素小的干扰,保持目标主体形状和尺寸。
 
- 应用场景:
- 工业检测:去除金属表面的微小划痕或杂质。
- 医学成像:消除细胞图像中的噪点。
- 文档处理:清理扫描文件中的孤立黑点。
 
与其他开运算算子的对比
| 操作 | 结构元素 | 适用场景 | 
|---|---|---|
| opening_circle | 圆形 | 各向同性处理,均匀去噪 | 
| opening_rectangle1 | 矩形 | 水平/垂直方向去噪或分离目标 | 
| opening | 自定义结构元素 | 复杂形状或非对称处理 | 
read_image(Image, 'noisy_objects.jpg')
* 阈值分割提取目标
threshold(Image, Region, 100, 255)
* 开运算去噪(半径2像素)
opening_circle(Region, RegionOpening, 2)
* 显示结果
dev_display(Image)
dev_display(RegionOpening)

- 输入参数:
- Region:输入区域(待处理的二值化区域)。
- Radius:圆形结构元素的半径(单位:像素)。
 
- 输出参数:
- RegionClosing:闭运算处理后的区域。
 


功能与作用
- 填充孔洞:
- 闭合目标内部的微小孔洞(如金属表面的气孔、医学图像中的组织间隙)。
 
- 连接邻近区域:
- 桥接相邻的断裂区域(如断裂的字符笔画或零件边缘)。
 
- 平滑边界:
- 使锯齿状边缘更平滑,同时保持目标面积。
 
- 应用场景:
- 工业检测:填充零件内部孔洞,确保面积测量准确。
- 医学成像:连接断裂的血管或组织区域。
- 文档处理:修复断裂的印刷字符。
 
与其他闭运算算子的对比
| 操作 | 结构元素 | 适用场景 | 
|---|---|---|
| closing_circle | 圆形 | 各向同性处理,均匀填充孔洞 | 
| closing_rectangle1 | 矩形 | 水平/垂直方向连接断裂区域 | 
| closing | 自定义结构元素 | 复杂形状或非对称处理 | 
read_image(Image, 'defective_part.jpg')
* 阈值分割提取目标
threshold(Image, Region, 80, 255)
* 闭运算填充孔洞(半径3像素)
closing_circle(Region, RegionClosing, 3)
* 显示结果
dev_display(Image)
dev_display(RegionClosing)
 
                     
                    
                 
                    
                

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号