0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

C#使用Halcon开发视觉检测程序

新机器视觉 来源:博客园-二次元攻城狮 2023-01-11 09:53 次阅读

简介

本文的初衷是希望帮助那些有其它平台视觉算法开发经验的人能快速转入Halcon平台下,通过文中的示例开发者能快速了解一个Halcon项目开发的基本步骤,让开发者能把精力完全集中到算法的开发上面。

首先,你需要安装Halcon,HALCON 18.11.0.1的安装包会放在文章末尾。安装包分开发和运行时两个版本,运行时版本一般用于生产环境。

注:开发版本自带运行时可替代运行时版本,但安装的东西会比较多。

然后,你需要学会查看Halcon的帮助手册,这是很重要的一件事

本文涉及到帮助文档的主要章节如下:

原文 HALCON 18.11.0.1 / Programmer's Guide / Programming With HALCON/.NET
翻译 HALCON 18.11.0.1/程序员指南/使用 HALCON/.NET 编程

原文 HALCON 18.11.0.1 / HALCON Operator Reference
翻译 HALCON 18.11.0.1/ HALCON 运算符参考

文中的示例是我第一次接触Halcon时的学习测试用例,在电脑里面躺了一年,最近才有时间整理一下发出来,希望能对你有所帮助。

注:运行本文示例程序前至少安装Halcon的运行时,否则Halcon的dll无法正常使用

将 HALCON/.NET 添加到应用程序

添加控件

右键单击工具箱,然后选择“选择项”,弹出的对话框选择“**.NET Framework组件”,单击下面的“浏览”,导航到HALCON安装目录下的indotnet35(VS2008以下版本的选择dotnet20) ,然后选择halcondotnet.dll**。

完成上述操作后,HSmartWindowControl和HWindowControl控件就会出现在工具箱中,其中HWindowControl控件已经过时官方不再推荐使用。

与HWindowControl相比,HSmartWindowControl控件具有以下几个优点:

可以像任何其他控件一样使用

提供预定义的鼠标交互(移动窗口内容并使用鼠标滚轮进行缩放), 可以通过双击窗口来重置视图

控件会自动重新缩放,而不会闪烁

注:与HSmartWindowControlWPF 相反,HSmartWindowControl需要一个回调才能使用鼠标滚轮进行缩放

引用dll

在HALCON安装目录下的**indotnet35**中,引用以下dll:

hdevenginedotnet.dll

halcondotnet.dll

注:使用HALCON XL开发应用程序时,必须选择以xl结尾的dll,hhdevelop xl适用于大分辨率的图像(大于 32k x 32k )。

引用以下命名空间:

HalconDotNet:控件所在的命名空间

HalconTypeLineRectangle2等数据类型所在的命名空间

调用Halcon算子

ReadImage操作为例,函数原型如下:

staticvoidHOperatorSet.ReadImage(outHObjectimage,HTuplefileName)

publicHImage(HTuplefileName)

publicHImage(stringfileName)

voidHImage.ReadImage(HTuplefileName)

voidHImage.ReadImage(stringfileName)

注:这些内容帮助手册上都有,在文章开头列出来的章节。

C#调用HALCON 算子有两种选择:函数式对象式,前值通过HOperatorSet调用算子并通过out关键字传入关键对象,后者直接在关键对象上调用对应的方法。两种方法完全等价,C#是一门面向对象的语言,建议使用对象式的方式调用算子会好一点。

程序示例

本示例只实现下面几种关键功能:

加载、保存图片

画线、框并保存

抓边算法、测宽算法

先新建一个Winform项目,界面设计如下:

c8ca887a-911b-11ed-bfe3-dac502259ad0.png

注:项目的解决方案平台不能使用AnyCPU,只能根据安装的Halcon位数选择x64x86,我使用的是x64平台。

HSmartWindowControl控件使用

将HSmartWindowControl控件拖入主界面即可,在窗体类里面定义一个HWindow类型的成员引用控件内部的窗体,同时设置控件的回调函数(WPF则不需要)。

代码如下:

//窗口实例
privateHWindowhwindow;

publicForm1()
{
InitializeComponent();
hwindow=hSmartWindowControl1.HalconWindow;//初始化窗口变量
hSmartWindowControl1.MouseWheel+=HSmartWindow_MouseWheel;
}

//鼠标滚轮回调
privatevoidHSmartWindow_MouseWheel(objectsender,MouseEventArgse)
{
Pointpt=this.Location;
MouseEventArgsnewe=newMouseEventArgs(e.Button,e.Clicks,e.X-pt.X,e.Y-pt.Y,e.Delta);
hSmartWindowControl1.HSmartWindowControl_MouseWheel(sender,newe);
}

加载、保存图像

加载、保存图像也比较简单,我们需要先定义一个HImage实例,然后按钮单击事件在该实例上调用对应的算子,代码如下:

//图片变量
privateHImageimage=newHImage();
//加载图片
privatevoidbutton_ReadImage_Click(objectsender,EventArgse)
{
stringimagePath="TestRead.bmp";
image.ReadImage(imagePath);
hwindow.DispImage(image);
//自动适应图片(相当于控件上面的双击操作)
hwindow.SetPart(0,0,-2,-2);
}
//保存图片
privatevoidbutton_WriteImage_Click(objectsender,EventArgse)
{
stringimagePath="TestWrite.bmp";
image.WriteImage("bmp",0,imagePath);
hwindow.DispImage(image);
}

上面代码是从程序启动目下加载TestRead.bmp图片,保存图片到程序启动目下的TestWrite.bmp,实际路径可以根据项目情况自己定义。

上面的图片是自己生成的,不是生产环境下的产品图片,仅用于程序演示。

扩展:加载相机图像

大部分项目都是从相机加载图片,但这涉及到相机驱动的一些知识,全部介绍一边会偏移文章主题。简单来说,加载相机图像分两步:

将相机图像保存到内存

将内存中的图像传入Halcon

将相机图像保存到内存是相机驱动的工作,下面只讨论怎么将内存中的图像传入Halcon,代码如下:

privatevoidGenImageByPtr()
{
//这三个参数都可以通过相机驱动得到
byte[]imageBuf=null;//图像缓存数组
intwidth=0;//图像宽度
intheigth=0;//图像高度
//获取内存图像中间的指针
IntPtrptr=Marshal.UnsafeAddrOfPinnedArrayElement(imageBuf,0);
//加载内存中的图像
image.GenImage1("byte",width,heigth,ptr);
hwindow.DispImage(image);
}

这里只列一个简单的示例,类似的算子还有copy_imagegen_image3等。

画线、画框并保存

在图像上画线、框是机器视觉里面常见的需求,根据线、框确定算法搜索的区域和特征。

在窗体类中定义一个HDrawingObject对象并附加到现有窗口用于交互,同时定义好Line对象、Rectangle2对象用于保存绘图的结果。

先在图像窗口上面画出线和框,然后再用鼠标手动调整大小、位置,代码如下:

//绘图对象
privateHDrawingObjectdrawingObject=newHDrawingObject();
//线ROI
privateLineline=newLine();
//框ROI
privateRectangle2rectangle2=newRectangle2();

privatevoidbutton_DrawLine_Click(objectsender,EventArgse)
{
drawingObject.CreateDrawingObjectLine(100,100,200,200);
//将绘图对象关联到Halcon窗口
hwindow.AttachDrawingObjectToWindow(drawingObject);
}
privatevoidbutton_SaveLine_Click(objectsender,EventArgse)
{
HTupleparamName,param;
paramName=newHTuple(newstring[]{"row1","column1","row2","column2"});
param=drawingObject.GetDrawingObjectParams(paramName);
//保存参数
line.SetValue(param.ToDArr());
paramName.Dispose();
param.Dispose();
//清除绘图内容
drawingObject.ClearDrawingObject();
}
privatevoidbutton_DrawRect_Click(objectsender,EventArgse)
{
drawingObject.CreateDrawingObjectRectangle2(300,400,0,300,200);
//将绘图对象关联到Halcon窗口
hwindow.AttachDrawingObjectToWindow(drawingObject);
}
privatevoidbutton_SaveRect_Click(objectsender,EventArgse)
{
HTupleparamName,param;
paramName=newHTuple(newstring[]{"row","column","phi","length1","length2"});
param=drawingObject.GetDrawingObjectParams(paramName);
//保存参数
rectangle2.SetValue(param.ToDArr());
paramName.Dispose();
param.Dispose();
//清除绘图内容
drawingObject.ClearDrawingObject();
}

上面的paramName可以取以下值,里面包含了LineRectangle2类属性名:

"color","column","column1","column2","end_angle","font","length1","length2","line_style",
"line_width","phi","radius","radius1","radius2","row","row1","row2","start_angle","string","type"

检测算法

用Halcon开发检测算法一般有两种方法:

根据直接调用Halcon在对应语言平台下的算子接口

用Halcon自带的脚本语言开发算法然后转成C#类

第一种自由度比较高,代码看起来也比较简洁易懂,但上手比较困难。第二种更简单,但生成的类很难看,而且与程序集成的时候需要做一些改动。两种方法并不是绝对对立的,一般会先用Halcon验证算法,然后参考导出的C#类实现自己的检测算法。

抓边算法

c8d3b2ba-911b-11ed-bfe3-dac502259ad0.png

2D测量模型

简述一下2D 测量的使用步骤:

创建测量模型并指定图像大小:首先必须使用create_metrology_model创建测量模型,然后使用set_metrology_model_image_size指定测量结果所在的图像的大小。

提供近似值:将测量对象添加到测量模型中,每个测量对象由图像中相应对象的近似形状参数控制测量的参数组成,控制测量的参数包括例如指定测量区域的尺寸和分布的参数,测量对象有以下几种:

:add_metrology_object_circle_measure

椭圆:add_metrology_object_ellipse_measure

矩形:add_metrology_object_rectangle2_measure

线:add_metrology_object_line_measure

使用一个运算符创建不同形状:add_metrology_object_generic

要直观检查定义的度量对象,可以使用运算符get_metrology_object_model_contour访问其XLD轮廓。要直观检查创建的测量区域,可以使用运算符get_metrology_object_measures访问其XLD轮廓。

修改模型参数:如果已执行相机校准,则可以使用set_metrology_model_param,没有就忽略(本示例没有使用)。

修改对象参数:当将测量对象添加到测量模型时,可以设置许多参数,之后还可以使用运算符set_metrology_object_param修改其中的一些(本示例是在添加时设置的参数,所以没有此步骤)。

调整测量模型:在执行下一次测量之前平移和旋转测量模型,可以使用操作员align_metrology_model。通常使用基于形状的匹配来获得对准参数,相当于测量前的位置就纠偏(本示例比较简单没有此步骤)。

应用测量:使用apply_metrology_model执行测量过程。

访问结果:测量后,可以使用get_metrology_object_result访问结果,也可以使用get_metrology_object_measures获取定位边的行坐标和列坐标再进一步处理(本示例使用前者)。

代码实现

抓变算法的C#代码如下:

privatevoidbutton_FindEdge_Click(objectsender,EventArgse)
{
//创建测量对象
HMetrologyModelhMetrologyModely=newHMetrologyModel();
//设置图片大小
image.GetImageSize(outintwidth,outintheight);
hMetrologyModely.SetMetrologyModelImageSize(width,height);
//添加直线测量
doublemeasureLength1=30,measureLength2=30,measureSigma=1,measureThreshold=30;
HTuplegenParamName=newHTuple(),genParamValue=newHTuple();
hMetrologyModely.AddMetrologyObjectLineMeasure(line.Row1,line.Column1,line.Row2,line.Column2,measureLength1,measureLength2,measureSigma,measureThreshold,genParamName,genParamValue);
//执行并获取结果
hMetrologyModely.ApplyMetrologyModel(image);
//获取测量区域
HTuplemRow=newHTuple(),mCol=newHTuple();
HXLDContmContours=hMetrologyModely.GetMetrologyObjectMeasures("all","all",outmRow,outmCol);//检测区域轮廓
HXLDContmmContours=hMetrologyModely.GetMetrologyObjectModelContour("all",1);//测量对象轮廓
//参数顺序["row_begin","column_begin","row_end","column_end"]
HTuplelineRet=hMetrologyModely.GetMetrologyObjectResult("all","all","result_type","all_param");
double[]retAry=lineRet.DArr;
//打印结果
hwindow.SetLineWidth(2);
hwindow.SetColor("green");
hwindow.DispLine(retAry[0],retAry[1],retAry[2],retAry[3]);
hwindow.SetColor("blue");
hwindow.DispXld(mContours);
hwindow.SetColor("yellow");
hwindow.DispXld(mmContours);
//清空测量对象
hMetrologyModely.ClearMetrologyModel();
//清理对象
hMetrologyModely?.Dispose();
genParamName?.Dispose();
genParamValue?.Dispose();
mRow.Dispose();
mCol.Dispose();
mContours.Dispose();
mmContours.Dispose();
}

Halcon的代码如下:

*读取图片
read_image (Image, 'D:/test.bmp')
dev_get_window (WindowHandle)

*画线
Row1:=1218.79
Column1:=1002.95
Row2:=1242.07
Column2:=2786.18
*draw_line (WindowHandle, Row1, Column1, Row2, Column2)
*gen_region_line (RegionLines, Row1, Column1, Row2, Column2)

*创建测量几何形状所需的数据结构
create_metrology_model (MetrologyHandle)
get_image_size (Image, Width, Height)
set_metrology_model_image_size (MetrologyHandle, Width, Height)  
add_metrology_object_line_measure (MetrologyHandle, Row1, Column1, Row2, Column2, 100, 50, 1, 30, [], [], Index)

apply_metrology_model (Image, MetrologyHandle)

get_metrology_object_result (MetrologyHandle, 'all', 'all', 'result_type','all_param', Parameter)

get_metrology_object_measures(Contours, MetrologyHandle, 'all', 'all', Row, Column)

get_metrology_object_model_contour (Contour, MetrologyHandle, 0, 1.5)

*清空测量对象,否则会导致内存泄露
clear_metrology_model (MetrologyHandle)

*可视化
dev_clear_window ()
dev_display(Image)
dev_set_color('green')
dev_set_line_width(1)
disp_line (WindowHandle, Parameter[0], Parameter[1], Parameter[2], Parameter[3])
dev_display (Contours)
dev_display (Contour)

使用方法

直接在界面上点击“打开图片”->“画线ROI”(默认位置我都调好了,你也可以自己调整大小、位置)->“抓边”,过程如下:c8dbc162-911b-11ed-bfe3-dac502259ad0.png

c8ea02c2-911b-11ed-bfe3-dac502259ad0.png

测宽算法

测宽算法使用一维测量中的measure_pairs算子提取直边对,然后计算两个直边的距离。代码太长这里就不贴了,完整的项目源码会在文章末尾给出。

需要注意,measure_pairs算子的搜索框必须和目标边缘完全垂直,否则宽度数据会不准确,算子原理如下:

c8f03318-911b-11ed-bfe3-dac502259ad0.png

直接在界面上点击“打开图片”->“画框ROI”(默认位置我都调好了,你也可以自己调整大小、位置)->“测宽”,过程如下:

c8f7ae68-911b-11ed-bfe3-dac502259ad0.pngc8fd0db8-911b-11ed-bfe3-dac502259ad0.png

上面的箭头就是框的方向,测量边必须与框的方向接近垂直否则会运算失败,实际项目中还是建议用2D测量单独抓两个边来测宽度。

源码里面显示边缘的DispEdgeMarker方法,是直接从measure_pairs算子示例里面导出转C#的,所以风格会比较奇怪。

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 程序
    +关注

    关注

    114

    文章

    3630

    浏览量

    79535
  • 应用程序
    +关注

    关注

    37

    文章

    3133

    浏览量

    56373
  • 视觉检测
    +关注

    关注

    2

    文章

    327

    浏览量

    18951
  • HALCON
    +关注

    关注

    16

    文章

    63

    浏览量

    27001

原文标题:C# 使用Halcon开发视觉检测程序

文章出处:【微信号:vision263com,微信公众号:新机器视觉】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    如何选择Halcon算法库应用软件集成开发环境

    大多数HALCON解决方案都必须嵌入到PC端的应用程序中(例如,提供图形用户界面),然后大多数机器视觉应用程序使用C ++或C#实现。这是我
    发表于 06-25 11:07 293次阅读

    《Visual C# 2005开发技术》C#程序设计基础.pdf

    《Visual C# 2005开发技术》C#程序设计基础.pdf[hide][/hide]
    发表于 06-24 19:49

    LABVIEW通过C#调用halcon算子

    本人看过不少LABVIEW直接调用HALCON的例子,感觉不如调用C#速度快,方便简洁。今天就把本人的经验分享一下。第一次发帖。。。。首先打开HALCON 例如:我们要把下面的算子转换
    发表于 02-18 10:54

    Labview调用Halcon直接调用dll

    文件,此法好像只能取数据不能传数据,不能参数调整但也可以用第三种方法三、把halcon程序导出C#程序,在VS中生成dll,然后在Labview中调用生成的dll,
    发表于 06-14 14:24

    Labview 调用C#封装halcon

    Labview 调用C#封装halcon库,内存释放能做到最好
    发表于 08-30 15:37

    LabVIEW调用Halcon程序的操作步骤

    机会开始接触Haclcon,发现这软件做视觉真的是方便,后来就想着怎么跟LabVIEW做联动,调用其中的程序,在论坛找到了几个例子,但是对基础户稍微差点的朋友不是很好理解,所以这里贴一下我这里的过程
    发表于 07-30 10:59

    《Visual C# 2005开发技术》C#程序设计基础

    《Visual C# 2005开发技术》C#程序设计基础
    发表于 02-07 15:11 0次下载

    LABVIEW视觉halcon案例免费下载

    LABVIEW视觉halcon案例免费下载
    发表于 12-08 17:48 188次下载
    LABVIEW<b class='flag-5'>视觉</b><b class='flag-5'>halcon</b>案例免费下载

    HALCON项目应使用哪种编程语言

    来源:机器视觉算法与应用 大多数HALCON解决方案都必须嵌入到PC端的应用程序中(例如,提供图形用户界面),然后大多数机器视觉应用程序使用
    的头像 发表于 08-18 10:36 6448次阅读

    HALCON机器视觉软件有哪些优点?

    最近一直在使用机器人与上位机进行视觉抓取技术的调试,对C# 也稍有了解,就这样我开始接触到了HALCON. HALCON是德国MVtec公司开发
    的头像 发表于 08-25 16:03 1w次阅读

    HALCON机器视觉算法包解析

    最近一直在使用机器人与上位机进行视觉抓取技术的调试,对C# 也稍有了解,就这样我开始接触到了HALCON.
    的头像 发表于 02-01 09:24 1607次阅读

    如何用halconC#进行联合开发

      导出文件  如需与其他语言进行联合编程,可以在文件--->导出中导出所需要的相应语言。  导出的函数文件可以被C# 调用.  视觉计算程序+通讯程序+机器人控制
    的头像 发表于 05-22 14:52 5384次阅读
    如何用<b class='flag-5'>halcon</b>和<b class='flag-5'>C#</b>进行联合<b class='flag-5'>开发</b>

    HALCON项目应该使用哪种主机语言

    大多数HALCON解决方案必须嵌入到主应用程序中(例如,提供图形用户界面),然后大多数机器视觉应用程序都是用c++或c#实现的。
    发表于 06-25 09:30 343次阅读

    史上最全VisionPro和Halcon 的详细对比

    MVTec MERLIC & HALCON – Mvtec公司宣布了一个基于Halcon库的新的视觉产品-MERLIC,Merlic增加了极其简单易用的机器视觉应用并且能够让一个有经验
    的头像 发表于 06-26 11:40 2007次阅读

    HalconC#二次开发及经验分享

    使用C#的语法方式逐句改写Halcon代码
    的头像 发表于 06-27 14:51 2012次阅读