文中内容参考的学习课程为超人视频:启蒙续集之Halcon联合C#以及手眼标定
实时采集方法一共有四种:循环采集、定时器、多线程、回调函数
本文在上一次的代码上进行完善,于是复制了一份上次的代码,再次打开找不到这个界面:
打开C#设计窗口的方法:
完善过程:
1.halcon部分
halcon中打开采集助手,自动检测接口,连接,实时,插入代码
Halcon部分代码为:
* Image Acquisition 01: Code generated by Image Acquisition 01
open_framegrabber ('GigEVision2', 0, 0, 0, 0, 0, 0, 'progressive', 8, 'rgb', -1, 'false', 'default', '0030532361ef_Basler_acA160020gc', 0, -1, AcqHandle)
grab_image_start (AcqHandle, -1)
while (true)
grab_image_async (Image, AcqHandle, -1)
get_image_size (Image, Width, Height)
dev_set_part (0, 0, Height, Width)
endwhile
close_framegrabber (AcqHandle)
2.C#部分
配置如上篇文章所示,我是直接用上次代码改的所以没有重新配置。
添加控件timer,属性栏如下。定时器法是不准确的,间隔时间越长越不准。点击闪电标志,Interval更改为40ms,40ms到了之后执行事件。定时器打开之后,不采集了要关闭,否则会出现错误 :HALCON error #2454: HALCON handle was already cleared in operator grab_image_async
接下来就是双击不同的控件,然后在里面将halcon导出的代码复制粘贴到对应位置。
Halcon导出的C#代码中,只需关注action函数中的代码:
// Local iconic variables
HObject ho_Image=null;
// Local control variables
HTuple hv_AcqHandle = new HTuple(), hv_Width = new HTuple();
HTuple hv_Height = new HTuple();
// Initialize local and output iconic variables
HOperatorSet.GenEmptyObj(out ho_Image);
//Image Acquisition 01: Code generated by Image Acquisition 01
hv_AcqHandle.Dispose();
HOperatorSet.OpenFramegrabber("GigEVision2", 0, 0, 0, 0, 0, 0, "progressive",
8, "rgb", -1, "false", "default", "0030532361ef_Basler_acA160020gc", 0, -1,
out hv_AcqHandle);
HOperatorSet.GrabImageStart(hv_AcqHandle, -1);
while ((int)(1) != 0)
{
ho_Image.Dispose();
HOperatorSet.GrabImageAsync(out ho_Image, hv_AcqHandle, -1);
hv_Width.Dispose();hv_Height.Dispose();
HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height);
if (HDevWindowStack.IsOpen())
{
HOperatorSet.SetPart(HDevWindowStack.GetActive(), 0, 0, hv_Height, hv_Width);
}
}
HOperatorSet.CloseFramegrabber(hv_AcqHandle);
ho_Image.Dispose();
hv_AcqHandle.Dispose();
hv_Width.Dispose();
hv_Height.Dispose();
打开相机部分的代码:
#region 打开相机
private void button3_Click(object sender, EventArgs e)
{
//清空、打开、初始化相机
// Initialize local and output iconic variables
HOperatorSet.GenEmptyObj(out ho_Timg);
//Image Acquisition 01: Code generated by Image Acquisition 01
hv_AcqHandle.Dispose();
HOperatorSet.OpenFramegrabber("GigEVision2", 0, 0, 0, 0, 0, 0, "progressive",
8, "rgb", -1, "false", "default", "0030532361ef_Basler_acA160020gc", 0, -1,
out hv_AcqHandle);
HOperatorSet.GrabImageStart(hv_AcqHandle, -1);
textBox1.Text = "相机已打开!";
}
#endregion
采集显示部分的代码:
注意:如果显示的图像只是halcon中可以看到的一部分,则说明halcon中没有使用dev_set_part()函数
#region 采集显示
/// <summary>
/// 此部分包含定时器的触发
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button4_Click(object sender, EventArgs e)
{
timer1.Enabled = true;
//打开窗口显示图片
HOperatorSet.OpenWindow(0, 0, hWindowControl1.Width, hWindowControl1.Height, hWindowControl1.HalconWindow, "visible", "", out hv_WindowHandle);
HDevWindowStack.Push(hv_WindowHandle);
}
private void timer1_Tick(object sender, EventArgs e)
{
ho_Timg.Dispose();
//获取图片
HOperatorSet.GrabImageAsync(out ho_Timg, hv_AcqHandle, -1);
//获取图片长宽
hv_Width.Dispose(); hv_Height.Dispose();
HOperatorSet.GetImageSize(ho_Timg, out hv_Width, out hv_Height);
//设置获取的图片在窗口中显示大小(此部分如果没有,则只能显示采集到的一部分图像)
if (HDevWindowStack.IsOpen())
{
HOperatorSet.SetPart(HDevWindowStack.GetActive(), 0, 0, hv_Height, hv_Width);
}
//如果窗口打开,显示图片
if (HDevWindowStack.IsOpen())
{
HOperatorSet.DispObj(ho_Timg, HDevWindowStack.GetActive());
textBox1.Text = "实时录像成功!";
}
}
#endregion
关闭相机部分的代码:
#region 关闭相机
private void button5_Click(object sender, EventArgs e)
{
//关闭定时器这步十分重要,不能少了
timer1.Enabled = false;
HOperatorSet.CloseFramegrabber(hv_AcqHandle);
ho_Timg.Dispose();
textBox1.Text = "关闭相机成功!";
}
#endregion