news 2026/9/24 7:07:31

C# + Halcon 实现类 VisionPro 的开源机器视觉平台

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C# + Halcon 实现类 VisionPro 的开源机器视觉平台

前言

工业自动化和智能制造快速,机器视觉软件已成为产线检测、定位引导、缺陷识别等关键环节的核心工具。然而,市面上成熟的商业视觉平台往往价格昂贵、封闭性强,而开源方案又常常功能零散、缺乏工程化整合。

本文推荐一个仿照 VisionPro 风格、基于 Halcon 引擎的国产化机器视觉软件项目。它不追求大而全,而是聚焦于开发一个可扩展、模块化、贴近工程师实际工作流的开发与运行环境。

项目介绍

项目是一个基于 .NET Framework 的 Windows 桌面级机器视觉集成开发环境,核心图像处理能力依托 Halcon 12.0,界面架构采用 DockPanelSuite 实现多窗口自由布局,数据持久化则通过 Newtonsoft.Json 完成。

目前项目已实现基础框架搭建,并完成了图像读取、缩放、ROI 管理等核心功能。

项目功能

1、支持本地或相机图像读取,并通过 Halcon 进行高效处理;

2、提供 ROI(感兴趣区域)的添加、编辑与管理,支持多 ROI 并存;

3、内置图像缩放、显示等基础工具,满足常规预处理需求;

4、采用 Job 机制组织视觉流程,每个 Job 对应一个独立图像窗口,便于多任务并行开发;

5、开发模板匹配与定位工具,未来将支持亚像素级定位与复杂场景匹配。

项目特点

  • 通过 Dock 布局实现工具箱、任务树、图像窗口的自由组合;所有窗体状态可序列化保存,下次打开自动还原;

  • Job 与图像窗口一一绑定,避免混乱;界面配色随主题自适应,提升长时间使用的舒适度。

  • 另外,项目采用单例模式管理主窗体与各子窗体,确保资源不重复创建,结构清晰且易于维护。

项目技术

1、界面布局依赖 DockPanelSuite 3.0.6,实现类似 Visual Studio 的可停靠窗体体验;

2、数据存储与加载采用 Newtonsoft.Json 12.0.3,保证配置信息的跨版本兼容性;

3、图像处理完全交由 Halcon 12.0 引擎完成,发挥其在工业视觉领域的高性能优势。

4、整个系统采用模块化设计,Tool(工具)、Job(任务)、Window(显示)三层解耦,新增工具只需继承基类并注册到工具箱,无需改动主框架。

项目代码

画Treeview控件两个节点之间的连线

/// <summary> /// 画Treeview控件两个节点之间的连线 /// </summary> /// <param name="treeView">要画连线的Treeview</param> /// <param name="startNode">结束节点</param> /// <param name="endNode">开始节点</param> private static void CreateLine(TreeView treeView, TreeNode endNode, TreeNode startNode) { treeView.BeginInvoke((Action)delegate { //得到起始与结束节点之间所有节点的最大长度 ,保证画线不穿过节点 var startNodeParantIndex = startNode.Parent.Index; var endNodeParantIndex = endNode.Parent.Index; var startNodeIndex = startNode.Index; var max = 0; if (!startNode.Parent.IsExpanded) { max = startNode.Parent.Bounds.X + startNode.Parent.Bounds.Width; } else { for (var i = startNodeIndex; i < startNode.Parent.Nodes.Count - 1; i++) { if (max < treeView.Nodes[startNodeParantIndex].Nodes[i].Bounds.X + treeView.Nodes[startNodeParantIndex].Nodes[i].Bounds.Width) max = treeView.Nodes[startNodeParantIndex].Nodes[i].Bounds.X + treeView.Nodes[startNodeParantIndex].Nodes[i].Bounds.Width; } } for (var i = startNodeParantIndex + 1; i < endNodeParantIndex; i++) { if (!treeView.Nodes[i].IsExpanded) { if (max < treeView.Nodes[i].Bounds.X + treeView.Nodes[i].Bounds.Width) max = treeView.Nodes[i].Bounds.X + treeView.Nodes[i].Bounds.Width; } else { for (var j = 0; j < treeView.Nodes[i].Nodes.Count; j++) { if (max < treeView.Nodes[i].Nodes[j].Bounds.X + treeView.Nodes[i].Nodes[j].Bounds.Width) max = treeView.Nodes[i].Nodes[j].Bounds.X + treeView.Nodes[i].Nodes[j].Bounds.Width; } } } if (!endNode.Parent.IsExpanded) { if (max < endNode.Parent.Bounds.X + endNode.Parent.Bounds.Width) max = endNode.Parent.Bounds.X + endNode.Parent.Bounds.Width; } else { for (var i = 0; i < endNode.Index; i++) { if (max < treeView.Nodes[endNodeParantIndex].Nodes[i].Bounds.X + treeView.Nodes[endNodeParantIndex].Nodes[i].Bounds.Width) max = treeView.Nodes[endNodeParantIndex].Nodes[i].Bounds.X + treeView.Nodes[endNodeParantIndex].Nodes[i].Bounds.Width; } } max += 20; //箭头不能连着 节点, if (!startNode.Parent.IsExpanded) startNode = startNode.Parent; if (!endNode.Parent.IsExpanded) endNode = endNode.Parent; if (endNode.Bounds.X + endNode.Bounds.Width + 20 > max) max = endNode.Bounds.X + endNode.Bounds.Width + 20; if (startNode.Bounds.X + startNode.Bounds.Width + 20 > max) max = startNode.Bounds.X + startNode.Bounds.Width + 20; //判断是否可以在当前处划线 foreach (var item infrom item in Dictionary where Math.Abs(max - item.Key) < 15 from item1 in item.Value where startNode != item1.Value where (item1.Value.Bounds.X < _maxLength && item1.Key.Bounds.X < _maxLength) || (item1.Value.Bounds.X < _maxLength && item1.Key.Bounds.X < _maxLength) select item) { max += (15 - Math.Abs(max - item.Key)); } var temp = new Dictionary<TreeNode, TreeNode> { { endNode, startNode } }; if (Dictionary.ContainsKey(max)) if (Dictionary[max].ContainsKey(endNode)) Dictionary[max][endNode] = startNode; else Dictionary[max].Add(endNode, startNode); else Dictionary.Add(max, temp); if (!StartNodeAndColor.ContainsKey(startNode)) StartNodeAndColor.Add(startNode, Color[StartNodeAndColor.Count]); var pen = new Pen(StartNodeAndColor[startNode], 1); //如果选中就边粗 if (endNode == treeView.SelectedNode || startNode == treeView.SelectedNode) { pen.Width = 2; } Brush brush = new SolidBrush(StartNodeAndColor[startNode]); _graphics.DrawLine(pen, startNode.Bounds.X + startNode.Bounds.Width, startNode.Bounds.Y + startNode.Bounds.Height / 2, max, startNode.Bounds.Y + startNode.Bounds.Height / 2); _graphics.DrawLine(pen, max, startNode.Bounds.Y + startNode.Bounds.Height / 2, max, endNode.Bounds.Y + endNode.Bounds.Height / 2); _graphics.DrawLine(pen, max, endNode.Bounds.Y + endNode.Bounds.Height / 2, endNode.Bounds.X + endNode.Bounds.Width, endNode.Bounds.Y + endNode.Bounds.Height / 2); _graphics.DrawString("<", new Font("微软雅黑", 12F), brush, endNode.Bounds.X + endNode.Bounds.Width - 5, endNode.Bounds.Y + endNode.Bounds.Height / 2 - 12); }); }

项目效果

可通过图形界面创建多个 Job,分别加载不同图像,设置 ROI 区域,并实时查看处理结果。每个 Job 的执行流程清晰可见,图像窗口可自由拖拽、停靠或浮动,符合大家日常操作习惯。

项目源码

项目源码采用标准 C# 结构,主窗体 FormMain 负责协调 Job 加载、窗体管理与事件分发。关键逻辑包括:Job 创建时自动关联图像窗口、Dock 面板状态的 XML 序列化/反序列化、窗体拖拽与自定义标题栏交互等。

代码中大量使用静态实例(如 FormJobs.Instance)确保全局唯一性,同时通过事件机制(如 EventAddJob)实现模块间松耦合通信。

大家可基于现有 Tool 基类快速扩展新功能,例如新增一个"边缘检测工具"只需实现 Run() 方法并注册到工具面板即可。

为了防止丢失,后台回复关键字「视觉软件」,即可获取完整源码地址。

总结

项目并不是一个炫技型的 AI 视觉平台,而是一个脚踏实地、面向工业现场的实用工具。它没有堆砌前沿模型,而是回归机器视觉的本质——稳定、可靠、可配置。通过借鉴 VisionPro 的流程化思想,结合 Halcon 的强大算力与 .NET 的开发效率,该项目为中小型制造企业或自动化集成商提供了一条低成本、高可控性的视觉软件自研路径。

关键词

#机器视觉、#Halcon、#VisionPro、#模板匹配、#ROI管理、#WinForms、#DockPanel、#Job流程、C#、#工业自动化

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/20 20:11:33

Unity游戏本地化终极解决方案:专业级自动翻译插件完全指南

Unity游戏本地化终极解决方案&#xff1a;专业级自动翻译插件完全指南 【免费下载链接】XUnity.AutoTranslator 项目地址: https://gitcode.com/gh_mirrors/xu/XUnity.AutoTranslator 在全球化浪潮下&#xff0c;Unity游戏本地化已成为开发者必须面对的关键挑战。XUnit…

作者头像 李华
网站建设 2026/9/24 6:26:52

基于大数据技术的大学生成长与发展智能评价系统设计与实现

文章目录 前言一、详细操作演示视频二、具体实现截图三、技术栈1.前端-Vue.js2.后端-SpringBoot3.数据库-MySQL4.系统架构-B/S 四、系统测试1.系统测试概述2.系统功能测试3.系统测试结论 五、项目代码参考六、数据库代码参考七、项目论文示例结语 前言 &#x1f49b;博主介绍&a…

作者头像 李华
网站建设 2026/9/22 23:05:51

强烈安利9个AI论文工具,本科生轻松搞定毕业论文!

强烈安利9个AI论文工具&#xff0c;本科生轻松搞定毕业论文&#xff01; AI 工具如何让论文写作变得轻松高效 在如今的学术环境中&#xff0c;越来越多的本科生开始借助 AI 工具来辅助完成毕业论文。这些工具不仅能够帮助学生节省大量时间&#xff0c;还能有效降低 AIGC&#x…

作者头像 李华
网站建设 2026/9/22 9:26:31

亲测降至5%以下!10款亲测有效的降AI率工具推荐(2026最新有效版)

最近后台问我最多的问题&#xff0c;已经从“怎么降重”变成了“怎么降AI率”。 确实&#xff0c;论文AIGC检测现在是每个毕业生的新噩梦。用AI写一时爽&#xff0c;AIGC率动不动就标红&#xff0c;导师和学校系统那关根本过不去。自己改吧&#xff0c;费时费力&#xff0c;还…

作者头像 李华
网站建设 2026/9/22 11:12:27

还有免费ai查重!10款亲测有效的降AI率工具推荐(2026最新福利版)

最近后台问我最多的问题&#xff0c;已经从“怎么降重”变成了“怎么降AI率”。 确实&#xff0c;论文AIGC检测现在是每个毕业生的新噩梦。用AI写一时爽&#xff0c;AIGC率动不动就标红&#xff0c;导师和学校系统那关根本过不去。自己改吧&#xff0c;费时费力&#xff0c;还…

作者头像 李华
网站建设 2026/9/20 20:16:31

Ranger部署

最近要使用ranger来负责Hadoop-HDFS的路径权限,在此分享记录一下从源码编译开始的部署方式 一、Ranger的安装需要从源码开始编译,因此你需要在Linux上准备好下面的东西 maven3 我本地编译ranger26用的3.9.9的 git python3 这里有个大坑,编译时要py3,但是后面初始化脚本又…

作者头像 李华