本文使用dispatcherTimer计时器,指定间隔时间,完成一次相机图片实时采集。在halcon18和WPF .Net Framwork4.7.2实测有效。
首先完成halcon在wpf中的配置halcon联合c#、WPF学习笔记一(WPF配置halcon)
加入命名空间using HalconDotNet;
一、在halcon中编写相机采集的程序
* Image Acquisition 02: Code generated by Image Acquisition 02 *获取相机 open_framegrabber ('DirectShow', 1, 1, 0, 0, 0, 0, 'default', 8, 'rgb', -1, 'false', 'default', '[0] ', 0, -1, AcqHandle) *设置相机参数 set_framegrabber_param (AcqHandle, 'grab_timeout', 2000) *启动相机 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) *展示图片 dev_display (Image) * Image Acquisition 02: Do something endwhile *关闭相机 close_framegrabber (AcqHandle)
然后导出成c#
二、WPF界面
在主窗口中,放一个HWindowControlWPF和三个Button
并将HWindowControlWPF 的Name取为Name=“halconVideo”, 后续需要和窗体绑定
三、打开相机
先在类中定义一些变量
DispatcherTimer dispatcherTimer = null; HObject ho_Image = null;//从相机中采集的图 HTuple hv_AcqHandle = null;//相机句柄 HTuple hv_WindowHandle = new HTuple();//窗口句柄 HTuple hv_Width = new HTuple();//图片的宽 HTuple hv_Height = new HTuple();//图片的高
点击按钮 打开相机,将执行以下部分。
这部分直接从生成的c#代码中拷贝即可。
//打开相机 private void Button_Click(object sender, RoutedEventArgs e) { HOperatorSet.GenEmptyObj(out ho_Image); hv_AcqHandle = new HTuple(); //Image Acquisition 01: Code generated by Image Acquisition 01 hv_AcqHandle.Dispose(); HOperatorSet.OpenFramegrabber("DirectShow", 1, 1, 0, 0, 0, 0, "default", 8, "rgb", -1, "false", "default", "[0] ", 0, -1, out hv_AcqHandle); HOperatorSet.SetFramegrabberParam(hv_AcqHandle, "grab_timeout", 2000);//设置相机参数 HOperatorSet.GrabImageStart(hv_AcqHandle, -1);//打开相机句柄 }
四、采集显示
单击按钮 采集显示 将会执行以下内容
1.打开定时器(每间隔一段时间就执行事件(从相机中采集图片))
2.打开窗口
使用dispatcherTimer前记得加入命名空间using System.Windows.Threading;
private void Button_Click_1(object sender, RoutedEventArgs e) { //启动定时器 dispatcherTimer = new DispatcherTimer(); dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);//添加事件(到达时间间隔后会自动调用) dispatcherTimer.Interval = new TimeSpan(0, 0, 1);//设置时间间隔为1秒 dispatcherTimer.Start();//启动定时器 //打开窗口(关联控件) HOperatorSet.OpenWindow(0, 0, halconVideo.Width, halconVideo.Height, halconVideo.HalconWindow, "visible", "", out hv_WindowHandle); HDevWindowStack.Push(hv_WindowHandle); }
定义事件(采集图片)
直接从导出的c#中拷贝
//计时器时间(从相机中采图并显示) private void dispatcherTimer_Tick(object sender, EventArgs e)//计时执行的程序 { ho_Image.Dispose(); HOperatorSet.GrabImageAsync(out ho_Image, hv_AcqHandle, -1);//获取图片 HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height);//获取图片的宽和高 if (HDevWindowStack.IsOpen()) { HOperatorSet.SetPart(HDevWindowStack.GetActive(), 0, 0, hv_Height, hv_Width);//设置显示的范围 HOperatorSet.DispObj(ho_Image, HDevWindowStack.GetActive());//显示图片 } }
注意这两个句柄的区别:
hv_WindowHandle 窗口句柄 (绑定HWindowControlWPF控件,并放入HDevWindowStack堆栈中)
hv_AcqHandle 相机 (从相机采图)
最后将采集来的图,通过HDevWindowStack的栈顶的窗体(hv_WindowHandle),显示从相机采集来的图
五、关闭相机
直接从导出的C#代码拷贝
private void Button_Click_2(object sender, RoutedEventArgs e) { HOperatorSet.CloseFramegrabber(hv_AcqHandle); ho_Image.Dispose(); }
六、完整代码
MainWindow.xaml
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:test02" xmlns:HalconDotNet="clr-namespace:HalconDotNet;assembly=halcondotnet" x:Class="test02.MainWindow" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Grid> <HalconDotNet:HWindowControlWPF Name="halconVideo" HorizontalAlignment="Left" Height="241" Margin="79,86,0,0" VerticalAlignment="Top" Width="407"/> <Button Content="打开相机" HorizontalAlignment="Left" Height="62" Margin="554,86,0,0" VerticalAlignment="Top" Width="180" Click="Button_Click"/> <Button Content="采集显示" HorizontalAlignment="Left" Height="59" Margin="554,177,0,0" VerticalAlignment="Top" Width="180" Click="Button_Click_1"/> <Button Content="关闭相机" HorizontalAlignment="Left" Height="53" Margin="554,256,0,0" VerticalAlignment="Top" Width="180" Click="Button_Click_2"/> </Grid> </Window>
MainWindow.xaml.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using HalconDotNet; using System.Windows.Threading; namespace test02 { /// <summary> /// MainWindow.xaml 的交互逻辑 /// </summary> public partial class MainWindow : Window { DispatcherTimer dispatcherTimer = null; HObject ho_Image = null;//从相机中采集的图 HTuple hv_AcqHandle = null;//相机句柄 HTuple hv_WindowHandle = new HTuple();//窗口句柄 HTuple hv_Width = new HTuple();//图片的宽 HTuple hv_Height = new HTuple();//图片的高 public MainWindow() { InitializeComponent(); } //打开相机 private void Button_Click(object sender, RoutedEventArgs e) { HOperatorSet.GenEmptyObj(out ho_Image); hv_AcqHandle = new HTuple(); //Image Acquisition 01: Code generated by Image Acquisition 01 hv_AcqHandle.Dispose(); HOperatorSet.OpenFramegrabber("DirectShow", 1, 1, 0, 0, 0, 0, "default", 8, "rgb", -1, "false", "default", "[0] ", 0, -1, out hv_AcqHandle); HOperatorSet.SetFramegrabberParam(hv_AcqHandle, "grab_timeout", 2000);//设置相机参数 HOperatorSet.GrabImageStart(hv_AcqHandle, -1);//打开相机句柄 } //采集显示 private void Button_Click_1(object sender, RoutedEventArgs e) { //启动定时器 dispatcherTimer = new DispatcherTimer(); dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);//添加事件(到达时间间隔后会自动调用) dispatcherTimer.Interval = new TimeSpan(0, 0, 1);//设置时间间隔为1秒 dispatcherTimer.Start();//启动定时器 //打开窗口 HOperatorSet.OpenWindow(0, 0, halconVideo.Width, halconVideo.Height, halconVideo.HalconWindow, "visible", "", out hv_WindowHandle); HDevWindowStack.Push(hv_WindowHandle); } //计时器时间(从相机中采图并显示) private void dispatcherTimer_Tick(object sender, EventArgs e)//计时执行的程序 { ho_Image.Dispose(); HOperatorSet.GrabImageAsync(out ho_Image, hv_AcqHandle, -1);//获取图片 HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height);//获取图片的宽和高 if (HDevWindowStack.IsOpen()) { HOperatorSet.SetPart(HDevWindowStack.GetActive(), 0, 0, hv_Height, hv_Width);//设置显示的范围 HOperatorSet.DispObj(ho_Image, HDevWindowStack.GetActive());//显示图片 } } //关闭相机 private void Button_Click_2(object sender, RoutedEventArgs e) { HOperatorSet.CloseFramegrabber(hv_AcqHandle); ho_Image.Dispose(); } } }