尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

HALCON与C#联合编程:CAD图纸读取与显示实战指南

HALCON与C#联合编程:CAD图纸读取与显示实战指南 简介一个完整的HALCON与C#联合编程示例面向机器视觉初学者和C#桌面应用开发者演示如何读取CAD文件并在界面中显示。工程采用相对路径引用测试图纸将下载后的文件夹放到桌面即可运行若halcondotnet.dll版本不匹配也可参照提示手动添加本机相应引用有助于理解DLL配置与联合编译流程。压缩包为rar格式共34个文件、452KB核心内容包括9个C#源码文件、Visual Studio解决方案与工程配置sln/csproj/config、可直接运行的exe、DXF测试图纸以及halcondotnet.dll引用等结构完整适合直接打开调试。该示例已有2132人学习下载。读者可以从中掌握HALCON与C#的基本交互方式熟悉CAD文件加载、图像显示、引用管理与路径设置等常用环节并可将这套工程作为模板扩展到实际视觉项目中。 做机器视觉上位机这几年HALCON 和 C# 联合编程是我日常用得最多的组合。很多同行一提到“读取一个 CAD 并显示”第一反应是“不就是调一个算子吗”但真到自己动手从 DXF 文件怎么读、读出来为什么不显示、为什么跟 CAD 里看的方向不一样到坐标系怎么转、窗口怎么自适应坑其实不少。这篇文章就把我实际项目里读 CAD 图纸并在 HALCON 窗口显示这套方案完整拆开讲适合正在做视觉引导、离线生成检测 ROI、或者需要把工程图纸落到上位机界面上的工程师参考能帮你少走至少一晚上的弯路。1. 为什么要把 CAD 图纸读进视觉程序1.1 最有价值的三个应用场景读 CAD 图纸这件事表面看只是“显示一个图形”但放到视觉项目里它解决的是三类非常实际的需求。第一类是视觉引导定位。比如机器人抓取工位工件外形有几十种规格每种规格的抓取点、轮廓边界都存在 CAD 图里。程序运行前先加载对应型号的 DXF把轮廓叠加到相机实时画面上操作员能直接看到“图纸轮廓”和“实际工件”之间的偏差比纯看坐标数字直观太多。第二类是离线生成检测区域。电路板、结构件检测时检测 ROI、屏蔽区域往往能从图纸里精确拿到。直接在图像上任鼠标框选效率低、容易偏而且换型号就得重画。把 CAD 里画好的区域轮廓读进来转成 Region 后配合reduce_domain缩小处理范围一套代码管所有型号。第三类是路径和测量辅助。AGV、点胶机这类设备需要离线规划运动轨迹图纸里的直线、圆弧就是现成的路径点数据读进 HALCON 转成 XLD 轮廓后既能显示也能通过get_contour_xld把点坐标取出来下发到运动控制卡。1.2 方案选型自己解析 DXF 不如交给 HALCON我最早想过自己写 DXF 解析器后来在项目里试了一版才发现这条路看着简单实际是给自己挖坑。DXF 的实体类型实在太多LINE、ARC、CIRCLE、POLYLINE、LWPOLYLINE、SPLINE、ELLIPSE、INSERT 块引用还有各种扩展数据。自己解析时光是把块Block里嵌套的实体炸开、处理好图层开关、再换算圆和弧的凸度参数就是一个完整的小型 CAD 引擎。而且解析出来的顶点数据要自己维护结构体显示还得自己用 GDI 或 OpenGL 画交互缩放平移也要重新造轮子。HALCON 本身擅长处理轮廓数据。读 CAD 可以用read_contour_dxf直接拿到 XLD 类型的轮廓对象XLD 是 HALCON 的“亲儿子”类型后续无论显示、转 Region、变换坐标还是做距离测量全都无缝衔接。显示方面还有现成的HWindowControl控件缩放、平移、反色显示都自带省掉一大半 UI 工作量。1.3 联合编程的分工边界C# 和 HALCON 联合编程我的习惯是C# 管逻辑HALCON 管数据和渲染。C# 负责文件对话框、工单解析、数据库查型号、日志记录、用户权限这些上位机该干的事HALCON 负责把 DXF 读成 XLD、把 XLD 显示到窗口、以及后续的标定变换和图像处理。这样分工的好处是调试时边界非常清晰——界面卡了查 C#显示不对查 HALCON 算子两边不用互相甩锅。2. 动手前的环境准备和核心算子2.1 C# 工程里接好 HALCON 运行环境先解决引用问题。安装 HALCON 后在 Visual Studio 里新建 WinForms 项目需要添加两个东西HalconDotNet.dll引用一般位于 HALCON 安装目录的bin\dotnet35或bin\dotnet20下。工具箱中添加HWindowControl控件拖到窗体上它就是后面的显示画布。这里有个很关键却经常被忽略的设置VS 的“目标平台”必须和 HALCON 版本位数一致。装的是 64 位 HALCON就把项目的Platform target改成x64装的是 32 位就改成x86。很多项目一编译就报 “Mixed mode assembly is built against version...”或者运行时报HALCON error #HALOCN之类十有八九是 AnyCPU 和位数不匹配导致的。如果运行时报许可证错误检查环境变量HALCONROOT和HALCON_LICENSE_FILE是否指向正确的安装路径和许可文件开发环境配好后基本不用再动。2.2 read_contour_dxf 一行代码背后的逻辑读取 DXF 的核心算子就一个HOperatorSet.ReadContourDxf(out HObject contours, dxfPath, out HTuple dxfStatus);两个输出参数里contours是一个 XLD 轮廓对象存放图纸里所有能转换的几何图元dxfStatus是状态信息列表HALCON 会把无法转换的实体类型、被跳过的图层提示信息放到这里。实际开发时dxfStatus一定要打印出来看一眼它能帮你判断是图纸本身的问题还是文件路径的问题。这个算子背后的处理逻辑是读取 DXF 的实体段把 LINE、ARC、CIRCLE、POLYLINE 等基础图元转成 XLD 轮廓遇到不支持的实体就跳过并写入dxfStatus。文本标注、填充剖面线这类对象通常要么被忽略要么转换效果很差所以源图纸最好清理掉不必要的文字和填充只留几何轮廓。2.3 DXF 实体、坐标单位和显示坐标的关系新手最容易懵的是坐标体系。CAD 图纸里的坐标系单位一般是毫米原点通常在图框左下角Y 轴向上而 HALCON 的窗口显示坐标是图像坐标原点在左上角Y 轴向下。所以读进来的轮廓坐标在数值上可能是几百甚至几千。这带来两个后果不做任何处理直接DispObj图形可能出现在窗口左上角一个不起眼的位置或者因为坐标太大跑到画面外看起来就像“什么都没读出来”。上下方向跟 CAD 里看可能相反因为两个坐标系的 Y 轴方向默认相反。理解了这两点再看到后面显示异常就不会慌。3. 读取 CAD 并显示到窗口的完整实现3.1 最简单版本先保证能读出来先写一个最小可用版本把 DXF 读出来直接显示到HWindowControl上private void LoadDxfAndShow(string dxfPath) { HObject contours; HTuple dxfStatus; // 读取 DXF得到 XLD 轮廓 HOperatorSet.ReadContourDxf(out contours, dxfPath, out dxfStatus); // 获取显示的窗口对象 HWindow window hWindowControl1.HalconWindow; // 清空窗口设置显示颜色和线宽 window.ClearWindow(); window.SetColor(green); window.SetLineWidth(2); // 显示轮廓 window.DispObj(contours); }这段代码能跑通但一般只适用于坐标范围恰好和窗口显示范围接近的情况。对大多数真实图纸来说这里只是验证“能不能读”离“好用”还差一步。另外注意上面代码里contours没释放实际项目里建议把它保存成一个窗体级字段等下次重绘时再Dispose掉重新读取避免内存持续增长。3.2 进阶版让图形自动适配窗口范围解决“读出来但看不到”的核心方法是根据轮廓的包围盒动态设置窗口显示范围。HALCON 里用SmallestRectangle1Xld获取轮廓外接矩形再把这个矩形映射到窗口客户区大小换算出一组行列范围传给SetPart。private void ShowDxfWithFit(string dxfPath) { HObject contours; HTuple dxfStatus; HOperatorSet.ReadContourDxf(out contours, dxfPath, out dxfStatus); // 获取轮廓包围盒 HTuple r1, c1, r2, c2; HOperatorSet.SmallestRectangle1Xld(contours, out r1, out c1, out r2, out c2); double centerRow (r1.D r2.D) / 2.0; double centerCol (c1.D c2.D) / 2.0; double objHeight r2.D - r1.D; double objWidth c2.D - c1.D; if (objWidth 1) objWidth 1; if (objHeight 1) objHeight 1; double winWidth hWindowControl1.Size.Width; double winHeight hWindowControl1.Size.Height; // 计算适合的缩放比例留 10% 边距 double scale Math.Min(winWidth / objWidth, winHeight / objHeight) * 0.9; double halfWidth winWidth / (2 * scale); double halfHeight winHeight / (2 * scale); // 设置窗口显示范围行列范围 hWindowControl1.HalconWindow.SetPart( new HTuple(centerRow - halfHeight), new HTuple(centerCol - halfWidth), new HTuple(centerRow halfHeight), new HTuple(centerCol halfWidth)); HWindow window hWindowControl1.HalconWindow; window.ClearWindow(); window.SetColor(green); window.SetLineWidth(2); window.DispObj(contours); }这段代码的关键逻辑在SetPart的四个参数前两个是显示区域左上角在“轮廓坐标”里的行列位置后两个是右下角位置。它做的事情相当于把轮廓坐标中的一小块矩形区域放大到整个窗口从而实现“自动套准”。这里要特别注意参数顺序SetPart(row1, col1, row2, col2)第一个是行row对应 Y第二个是列col对应 X。搞反了的话图形会发生奇怪的旋转和拉伸。3.3 显示效果优化图层配色和交互细节SetColor(green)和SetLineWidth(2)是最基础的显示设置。如果 DXF 里有多组轮廓需要区分不同图层实体比如外层边框用一种颜色内部特征用另一种颜色可以通过dev_set_colored或者手动遍历轮廓对象设置颜色。HWindowControl 控件自带鼠标缩放的交互逻辑的底子但如果你发现鼠标滚轮缩放不好用或者拖动不顺畅可以考虑关闭控件默认事件自己用HMouseWheel、HMouseDown事件配合SetPart实现定制的缩放平移。实际项目里我更推荐自己做一套因为可以同时维护一个“当前放大倍数”的状态方便叠加显示坐标和测量辅助线。另外显示 CAD 的窗口底色我习惯在初始化时设成白色或黑色看场景。检测项目里为了跟相机图像叠加时看得清楚通常用深色底 亮色轮廓如果是给操作员看工程图浅色底更符合看图纸的习惯。用window.SetWindowParam(background_color, white)这类参数设置即可。4. 高频问题与排查思路4.1 DXF 读不出来或者实体丢失最常见的情况是 HALCON 读一个 DXF 文件时dxfStatus里刷出一堆警告图形只显示了一半。排除路径和权限问题后大概率是图纸本身的原因。我去现场排查遇到过几类典型情况图纸版本太新比如用最新版 AutoCAD 保存的高版本 DXFHALCON 不一定完整支持。图元太复杂里面有大量文字、尺寸标注、填充剖面线这些实体转换成 XLD 后很难看而且拖慢读取速度。块没有炸开图中大量对象是 Block 引用HALCON 对块引用的支持有限导致部分图元“消失”。处理办法很朴素拿到用户提供的图纸后先用 AutoCAD 或 DraftSight 打开EXPLODE炸开所有块删掉尺寸标注和文字图层再SAVEAS另存为 Auto CAD 2000/2004 版本的 DXF。这条流程我在多个项目里验证过基本能解决 90% 的读取不完整问题。4.2 图形方向、比例和显示范围不对图纸读进来了但图形是倒的或者跟现场实物对不上问题基本出在坐标系和单位理解上。HALCON 的坐标行向下为正所以直接读出来的图形大概率会跟 CAD 里上下颠倒。如果项目里需要和原始图纸方向一致可以用仿射变换把行坐标翻转一下再通过 SetPart 调整显示范围HObject flipped; HTuple homMat2D; HOperatorSet.HomMat2dIdentity(out homMat2D); HOperatorSet.HomMat2dScale(homMat2D, 1.0, -1.0, 0, 0, out homMat2D); HOperatorSet.AffineTransContourXld(contours, out flipped, homMat2D);这个变换的语义是“列坐标不变行坐标取反”相当于把图形以水平线为轴翻转到屏幕坐标系。翻转完行坐标可能出现负值不需要担心因为 SetPart 和显示缩放会重新确定可视范围。比例问题更隐蔽。有些图纸绘制时用的是英制单位或者 CAD 里用了不同比例缩放读出来的轮廓数值和实际工件毫米尺寸对不上。我的习惯是在读图后先用SmallestRectangle1Xld输出外接矩形长宽和图纸标注的尺寸对比一下确认比例系数后面做视觉引导时心里有数。4.3 License、平台位数和控件异常运行时报 HALCON 错误先区分是开发环境还是部署环境。开发环境常见的是许可证路径配置错误检查HALCON_LICENSE_FILE环境变量确认指向的许可证文件存在且没有过期。部署到客户现场时要把 HALCON Runtime 一并安装并且把许可文件路径配置到目标机器的环境变量里。平台位数的问题前面提过再强调一次HALCON 是原生 C/C 写的底层库C# 是托管代码两边位数不一致就会在调用算子时炸出莫名其妙的异常。先确认装的 HALCON 是 x64 还是 x86再改 VS 项目平台目标这是万能第一步。HWindowControl 控件异常常见于在后台线程里调用显示。WinForms 的 UI 控件只能在主线程访问如果你用一个Task.Run去读 DXF 然后直接去操作 HWindowControl大概率会碰到跨线程问题。解决方法是把显示逻辑放到 UI 线程或者用Invoke回到主线程再显示。5. 从“显示 CAD”到“用 CAD”几个扩展方向5.1 坐标标定后的轮廓叠加读 CAD 显示只是第一步真正体现价值的是把 CAD 轮廓坐标和相机图像坐标统一起来。简单场景下如果相机垂直安装且固定高度像素当量是固定的做一个缩放和平移仿射变换就能把图纸轮廓叠加到实时图像上HTuple homMat2D; HOperatorSet.HomMat2dIdentity(out homMat2D); // 先把图纸坐标缩放到像素坐标 HOperatorSet.HomMat2dScale(homMat2D, sY, sX, 0, 0, out homMat2D); // 再平移到图像上的参考点 HOperatorSet.HomMat2dTranslate(homMat2D, tRow, tCol, out homMat2D); HObject contourImage; HOperatorSet.AffineTransContourXld(contours, out contourImage, homMat2D); hWindowControl1.HalconWindow.DispObj(contourImage);如果是做手眼标定更标准的做法是把手眼矩阵求出来的HomMat2D直接用在这个变换里。这样操作员在界面上看到的就是“图纸上的抓取位置”和“实际工件位置”的偏差调机效率会高非常多。5.2 轮廓转 Region 与掩膜CAD 里的封闭轮廓不仅能显示还能转成 Region 当 ROI 用。常用算子有两个gen_region_contour_xld把 XLD 轮廓填充成 Region适合形状不规则的封闭区域。read_region_dxf直接读 DXF 生成 Region适合图纸里本来就画好了填充区域的情况。我做电路板检测项目时会把禁布区、螺丝孔位这些区域从 CAD 里读出来转成 Region然后和相机图像求交集、排除干扰点效果比手动框选稳定得多而且换型号只需要换图纸不用重新标定 ROI。5.3 同类型方案如果用 C/Qt 或 VisionPro后台时不时有人问“Qt 怎么调用 HALCON”原理和 C# 是一样的。HALCON 提供 C 接口读取轮廓后可以用HWindow的DispObj显示到 HALCON 自带窗口也可以把 XLD 的坐标点取出来用 QPainter 在自定义控件里画。区别在于自己画的话缩放、平移、抗锯齿都要自己实现而 HALCON 窗口组件已经把这些做完了。所以我的建议是能用 HALCON 自带的显示控件就别自己造轮子把精力留给业务逻辑。如果用 VisionPro 做联合编程思路也类似它也有读取 CAD 轮廓的 QuickBuild 工具但 CAD 数据落地到算法层的灵活性和 HALCON 的 XLD 体系没法比尤其做自定义标定和轮廓变换的时候HALCON 的优势非常明显。最后再分享一个我实际踩过的坑第一次在项目里读 CAD 时为了省事直接用了 3D 建模软件导出的 DXF结果 HALCON 读出来的轮廓断成一截一截怎么调都补不齐。后来老老实实让机械工程师用二维 CAD 重新整理、删掉多余标注、统一图层再导出 DXF 2000 格式问题立刻消失。所以遇到读取异常先不要怀疑 HALCON回头看一下图纸本身干不干净这比调试代码效率高得多。这套读 CAD 再显示的操作算是 HALCON 和 C# 联合编程里最基础也最实用的能力之一。你把这套流程跑通之后后面无论是做视觉引导、区域生成还是路径规划都会顺手很多。本文还有配套的精品资源点击获取
返回列表