基于Halcon+C#的机器视觉入门实战——002图像处理基础

张开发
2026/4/17 6:26:49 15 分钟阅读

分享文章

基于Halcon+C#的机器视觉入门实战——002图像处理基础
1. 图像处理基础概念第一次接触机器视觉时很多人会被各种专业术语搞得晕头转向。其实图像处理就像我们平时修照片一样简单直观。举个例子当你用手机美颜软件磨皮时实际上就是在做图像处理中的平滑操作调整亮度对比度就是在做灰度变换。Halcon把这些常见的图像处理操作封装成了简单易用的函数让我们用几行代码就能实现专业级的效果。在工业领域图像处理通常要完成四个核心任务增强图像质量比如去除反光、提取目标特征比如识别零件上的二维码、测量尺寸比如检测螺丝直径是否合格、定位对象位置比如引导机械臂抓取。Halcon针对这些需求提供了丰富的算子库从简单的阈值分割到复杂的3D匹配一应俱全。与OpenCV等开源库相比Halcon最大的优势在于工业场景的适配性。我做过一个对比测试同样实现PCB板上的元件检测Halcon的识别速度比OpenCV快了近3倍而且误检率更低。这得益于它针对工业图像优化的底层算法比如专利的亚像素边缘检测技术。2. 开发环境准备工欲善其事必先利其器我们先来搭建开发环境。建议使用Visual Studio 2022社区版完全免费搭配Halcon 17以上版本。这里有个小技巧安装Halcon时一定要勾选.NET支持选项否则后面C#调用会出问题。我当初就因为这个漏选调试了一整天找不到原因。配置环境变量是关键步骤很多新手在这里踩坑。需要设置两个路径一是Halcon安装目录下的bin文件夹比如C:\Program Files\MVTec\HALCON-17.12\bin\x64-win64二是dotnet文件夹。配置完成后可以在VS中新建一个Windows窗体应用通过NuGet添加HalconDotNet包或者直接引用halcondotnet.dll。测试环境是否配置成功有个简单方法在代码里输入using HalconDotNet;如果不报错说明基础环境OK。再写个最简单的图像显示代码HObject image new HObject(); HOperatorSet.ReadImage(out image, printer_chip/printer_chip_01.png); HTuple window hWindowControl1.HalconWindow; HOperatorSet.DispObj(image, window);如果能正常显示图像恭喜你环境搭建完成3. 图像读取与显示实战读取图像看似简单但实际项目中会遇到各种问题。Halcon支持20种图像格式从常见的jpg/png到工业相机专用的tiff/raw都能处理。这里分享几个实用技巧路径处理最好用相对路径比如把图片放在项目下的images文件夹这样代码迁移时不会出错。读取时可以这样写string imagePath Path.Combine(Application.StartupPath, images/test.png); HOperatorSet.ReadImage(out ho_Image, imagePath);批量读取连续编号的图像有个小窍门使用read_sequence算子HOperatorSet.ReadSequence(out ho_Image, frame_###.png, 1, 1, 0, 0, 500, 500);显示图像时建议使用hWindowControl控件而不是新建窗口。这样可以直接在窗体上做交互比如添加鼠标滚轮缩放功能hWindowControl1.HMouseWheel (sender, e) { HTuple zoom e.Delta 0 ? 1.2 : 0.8; HOperatorSet.ZoomWindowFactor(hWindowControl1.HalconWindow, zoom, zoom, 0, 0); };遇到过最头疼的问题是图像显示为纯色块这通常是数据类型不匹配导致的。工业相机经常输出12bit图像而普通显示器只能显示8bit。解决方法是用convert_image_type转换HOperatorSet.ConvertImageType(ho_Image, out ho_Image, byte);4. 基础图像处理操作4.1 灰度变换调整图像亮度和对比度是最常用的操作。Halcon提供了scale_image算子比PS的曲线调整还方便HOperatorSet.ScaleImage(ho_Image, out ho_ImageScaled, 1.5, 30); // 1.5倍对比度亮度30对于光照不均的情况可以用illuminate算子进行局部增强HOperatorSet.Illuminate(ho_Image, out ho_ImageEnhanced, 60, 60, 0.7);4.2 图像滤波噪声是工业图像的大敌Halcon的滤波算子多到让人选择困难。经过大量测试我总结出几个最实用的高斯滤波(gauss_filter)适合轻微噪声保留边缘效果好中值滤波(median_image)对椒盐噪声特别有效均值滤波(mean_image)处理均匀噪声速度快有个实际案例在检测金属表面划痕时原图有很多加工纹理干扰。最终采用median_rect滤波器参数设为7x7完美保留了划痕特征的同时去除了纹理噪声。4.3 阈值分割这是将目标对象从背景中分离的关键步骤。新手常犯的错误是直接用threshold固定阈值实际项目中应该用动态阈值法HOperatorSet.DynThreshold(ho_Image, ho_ImageSmoothed, out ho_Region, 15, light);对于复杂背景var_threshold效果更好它能根据局部对比度自动调整阈值HOperatorSet.VarThreshold(ho_Image, out ho_Region, 20, 20, 0.2, 2, dark);5. 实战案例零件尺寸测量我们通过一个完整案例把前面知识串起来。假设要测量下图中的金属垫片内径首先读取并增强图像HOperatorSet.ReadImage(out ho_Image, washer.png); HOperatorSet.Emphasize(ho_Image, out ho_ImageEnhanced, 7, 7, 1);提取边缘区域HOperatorSet.EdgesSubPix(ho_ImageEnhanced, out ho_Edges, canny, 1, 20, 40); HOperatorSet.SelectShape(ho_Edges, out ho_SelectedEdges, contlength, and, 50, 999);拟合圆并测量直径HOperatorSet.FitCircleContourXld(ho_SelectedEdges, algebraic, -1, 0, 0, 3, 2, out hv_Row, out hv_Column, out hv_Radius, out hv_StartPhi, out hv_EndPhi, out hv_PointOrder); HTuple diameter hv_Radius * 2;在界面上显示结果labelResult.Text $内径测量结果{diameter.TupleString(0.2f)}像素; HOperatorSet.DispCircle(hWindowControl1.HalconWindow, hv_Row, hv_Column, hv_Radius);这个案例虽然简单但包含了图像处理的完整流程。在实际项目中还需要考虑光照稳定性、相机标定、单位换算等问题。建议初学者先用Halcon的HDevelop工具快速验证算法再移植到C#项目中这样效率能提高好几倍。

更多文章