文中内容参考的学习课程为超人视频:启蒙续集之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
