二.HALCON与C#混合编程的方法
1. HALCON软件的特点
HALCON是德国MVtec公司开发的一套完善的机器视觉算法包,拥有灵活的机器视觉集成开发环境,用户可快速完成图像处理与分析的开发工作。在欧洲以及日本工业界公认HALCON软件是最佳机器视觉软件。
HALCON软件有一千多个独立的函数,其中包含了各类滤波、几何转换、形态学计算分析、校正、分类辨识、形状搜寻等功能,应用范围涵盖工业监控、自动化检测、医学检测、遥感探测等领域。
HALCON软件支持Windows、Linux和Mac OS X操作环境。整个函数库可以用C、C++、C#、Visual basic和Delphi等多种编程语言调用。HALCON软件为百余种工业相机和图像采集卡提供了接口。
HALCON软件提供了一套交互式程序开发工具HDevelop,可在其中以HALCON程序代码直接编写、修改、执行程序,并且可以查看计算过程中的所有变量。设计、调试完成后,可以直接输出C、C++、VB、C#等程序代码,嵌入用户的程序中。
HDevelop提供了数百个例程。可以根据应用范围、应用领域、函数类型3个途径检索到合适的例程。此外,HDevelop还配有以问题为导向的手册和在线帮忙功能。
2. 一个完整的HALCON程序
HALCON程序和BASIC语言类似,函数名直接反映函数功能,容易理解。下面的程序是用大恒相机循环抓取图像并显示。星号后的文字是注释。
* 关闭所有图像抓取设备:
close_all_framegrabbers()
* 以默认设置参数打开相机:
open_framegrabber
('DahengCAM', 1, 1, 0, 0, 0, 0, 'default', -1, 'default', -1, 'default', 'default', 'default', -1, -1, AcqHandle)
* 关闭窗体:
dev_close_window ()
* 新建一个窗体:
dev_open_window (0, 0,427, 341, 'black', WindowID)
*循环体开始:
while(1)
* 由相机抓取一幅图像
grab_image (Image, AcqHandle)
* 获取图像尺寸
get_image_size(Image,Width, Height)
* 调整图像大小以适应窗体
dev_set_part(0,0, Height-1,Width-1)
* 在窗体中显示图像
dev_display(Image)
* 循环体结束
Endwhile
* 关闭指定相机:
close_framegrabber (AcqHandle)
图9 HDevelop界面、HALCON程序和图像显示窗体
3. 导出C#代码
在HDevelop界面中点击“文件”->“导出”。 参数配置最好如图10所示。
图10 “导出”界面
导出的C#程序代码如下:
//
// File generated by HDevelop for HALCON/DOTNET (C#) Version 10.0
//
// This file is intended to be used with the HDevelopTemplate or
// HDevelopTemplateWPF projects located under %HALCONEXAMPLES%\c#
using System;
using HalconDotNet;
public partial
class HDevelopExport
{
public HTuple hv_ExpDefaultWinHandle;
// Main procedure
private void action()
{
// Local iconic variables
HObject ho_Image=null;
// Local control variables
HTuple hv_AcqHandle, hv_Width=new HTuple();
HTuple hv_Height=new HTuple();
// Initialize local and output iconic variables
HOperatorSet.GenEmptyObj(out ho_Image);
//Close all image acquisition devices:
HOperatorSet.CloseAllFramegrabbers();
//open camera with default settings:
HOperatorSet.OpenFramegrabber("DahengCAM", 1, 1, 0, 0, 0, 0,"default", -1, "default", -1, "default","default", "default", -1, -1, out hv_AcqHandle);
//Close the active graphics window:
//dev_close_window(...);
//Open a new graphics window:
//dev_open_window(...);
//Starts a loop block:
while ((int)(1) != 0)
{
//Grab an image from the specified image acquisition device:
ho_Image.Dispose();
HOperatorSet.GrabImage(out ho_Image, hv_AcqHandle);
//Return the size of an image:
HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height);
//Modify the displayed image part:
HOperatorSet.SetPart(hv_ExpDefaultWinHandle, 0, 0, hv_Height-1,hv_Width-1);
//Displays image objects in the current graphics window:
HOperatorSet.DispObj(ho_Image, hv_ExpDefaultWinHandle);
//End of while loop
}
//Close specified image acquisition device:
HOperatorSet.CloseFramegrabber(hv_AcqHandle);
ho_Image.Dispose();
}
public void InitHalcon()
{
// Default settings used in HDevelop
HOperatorSet.SetSystem("do_low_error", "false");
}
public void RunHalcon(HTuple Window)
{
hv_ExpDefaultWinHandle = Window;
action();
}
}
注意:
HALCON程序中的关闭窗体、打开窗体的函数dev_close_window ()和dev_open_window (),并没有直接翻译成C#语句。
和窗体相关的C#语句是程序倒数第2行的hv_ExpDefaultWinHandle = Window;
4. C#编程
从HALCON导出的C#程序并不能直接使用,需要自己调整、修改。下面给出在C#中调用HALCON函数的详细步骤。
1)打开VS2010,新建项目®windows窗体应用程序。
2)在设计界面的左边,将工具箱拉到最后,在常规选项卡空白处点右键,然后点“选择项”,在.NET
Framework处点浏览,找到Halcon的安装目录,选\Bin\dotnet35\halcondotnet.dll,点“打开”,然后点“确定”。如图11所示。
图11 添加halcon的动态链接库
3)将HWindowControl控件拖进窗体,这就是Halcon的图像显示框。窗体的长宽比例要为5:4,和摄像头拍摄的图像比例相同。然后再拖入2个按键控件、1个定时器。如图12所示。
图12 设计Form,添加halcon图像显示框
4)将导出的C#代码中的using
HalconDotNet; 拷贝至Program.cs中的using System
5)将导出的C#代码中的类HDevelopExport和变量的定义拷贝至命名空间中。
public partial class HDevelopExport
{
public HTuple hv_ExpDefaultWinHandle;
// Local iconic variables
HObject ho_Image=null;
// Local control variables
HTuple hv_AcqHandle, hv_Width, hv_Height;
}
6)将导出的C#代码分解为几个功能独立的方法,并拷贝至HDevelopExport类中。
public void InitHalcon() // 初始化Halcon
{
// Default settings used in HDevelop
HOperatorSet.SetSystem("do_low_error", "false");
}
public void InitCamera(HTuple Window) // 摄像头初始化
{
hv_ExpDefaultWinHandle = Window;
// Initialize local and output iconic variables
HOperatorSet.GenEmptyObj(out ho_Image); // 生成ho_Image数据区
HOperatorSet.CloseAllFramegrabbers();
//open camera with default settings:
HOperatorSet.OpenFramegrabber("DahengCAM", 1, 1, 0, 0, 0, 0, "default", -1, "default", -1, "default", "default", "default", -1, -1, out hv_AcqHandle);
}
public void GrabAndDisplay() // 图像抓取与显示
{
// Grabbing images from a Daheng USB 2.0 camera
ho_Image.Dispose(); // 清除ho_Image中的数据
HOperatorSet.GrabImage(out ho_Image, hv_AcqHandle); // 采集图像
HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height);
// 获取图像的尺寸
HOperatorSet.SetPart(hv_ExpDefaultWinHandle, 0, 0, hv_Height - 1, hv_Width - 1);
// 调整图像的大小
HOperatorSet.DispObj(ho_Image, hv_ExpDefaultWinHandle); // 显示图像
}
public void CloseCamera() // 关闭相机
{
HOperatorSet.CloseFramegrabber(hv_AcqHandle);
ho_Image.Dispose();
}
7)在Form1.cs中实例化HDevelopExport类。
public partial class Form1 : Form
{
HDevelopExport hd = new
HDevelopExport(); // 实例化HDevelopExport
public Form1()
{
..........
8)在按键和定时器的事件中调用HDevelopExport类的过程。
private void button1_Click(object sender, EventArgs e)
{
hd.InitCamera(hWindowControl1.HalconWindow);// 摄像头初始化
timer1.Enabled = true; // 开始定时拍照显示
}
private void button2_Click(object sender, EventArgs e)
{
timer1.Enabled = false; // 停止拍照
hd.CloseCamera();
}
private void timer1_Tick(object sender, EventArgs e)
{
hd.GrabAndDisplay(); // 定时拍照、显示
}
定时器时间间隔设置为50ms。
9)完整代码和运行结果如下:
Program.cs代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using HalconDotNet;
namespace GrabImage
{
public partial class HDevelopExport
{
public HTuple hv_ExpDefaultWinHandle;
// Local iconic variables
HObject ho_Image = null;
// Local control variables
HTuple hv_AcqHandle, hv_Width, hv_Height;
public void InitHalcon() // 初始化Halcon
{
// Default settings used in HDevelop
HOperatorSet.SetSystem("do_low_error", "false");
}
public void InitCamera(HTuple Window) //摄像头初始化
{
hv_ExpDefaultWinHandle = Window;
//Initialize local and output iconic variables
HOperatorSet.GenEmptyObj(out ho_Image); // 生成ho_Image数据区
HOperatorSet.CloseAllFramegrabbers();
//open camera with default settings:
HOperatorSet.OpenFramegrabber("DahengCAM", 1, 1, 0, 0, 0, 0, "default", -1, default",
-1, "default", "default", "default", -1, -1, out hv_AcqHandle);
}
public void GrabAndDisplay() // 图像抓取与显示
{
// Grabbing images from a Daheng USB 2.0 camera
ho_Image.Dispose(); //清除yho_Image中的数据
HOperatorSet.GrabImage(out ho_Image, hv_AcqHandle); // 采集图像
HOperatorSet.GetImageSize(ho_Image,out hv_Width, out hv_Height);
// 获取图像的尺寸
HOperatorSet.SetPart(hv_ExpDefaultWinHandle, 0, 0, hv_Height - 1, hv_Width - 1);
// 调整图像的大小
HOperatorSet.DispObj(ho_Image, hv_ExpDefaultWinHandle); // 显示图像
}
public void CloseCamera() // 关闭相机
{
HOperatorSet.CloseFramegrabber(hv_AcqHandle);
ho_Image.Dispose();
}
}
static class Program
{
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
Form1.cs的代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace GrabImage
{
public partial class Form1 : Form
{
HDevelopExport hd = new HDevelopExport();
public Form1()
{
InitializeComponent();
}
private void CameraOn _Click(object sender, EventArgs e)
{
hd.InitCamera(hWindowControl1.HalconWindow); //摄像头初始化
timer1.Enabled = true; // 开始定时拍照、显示
}
private void CameraOff _Click(object sender, EventArgs e)
{
timer1.Enabled = false; // 停止拍照
hd.CloseCamera();
}
private void timer1_Tick(object sender, EventArgs e)
{
hd.GrabAndDisplay(); // 定时拍照、显示
}
}
}
Form设计参见图12,程序运行结果如图13所示。
图13 Grab Image程序运行结果