1、添加Halcon控件,创建WPF项目

在VS2013中创建一个WPF工程,然后添加halcon的控件和工具包,参见:

HSmartWindowControl之安装篇 (Visual Studio 2013 & Halcon 18)

在WPF工程中添加好HSmartWindowControlWPF控件后,将其拖入主窗体即可。

2、生成摄像头实时显示的halcon代码

使用Image Acquisition 连接笔记本自带的摄像头,然后生成实时显示的代码即可:

* Image Acquisition 01: Code generated by Image Acquisition 01
open_framegrabber ('DirectShow', 1, 1, 0, 0, 0, 0, 'default', 8, 'rgb', -1, 'false', 'default', '[0] Integrated Camera', 0, -1, AcqHandle)
grab_image_start (AcqHandle, -1)
while (true)
grab_image_async (Image, AcqHandle, -1)
* Image Acquisition 01: Do something
endwhile

3、导出C#代码

这里主要关注action函数:

// Main procedure
private void action()
{
// Local iconic variables
HObject ho_Image=null;
// Local control variables
HTuple hv_AcqHandle = new HTuple();
// Initialize local and output iconic variables
HOperatorSet.GenEmptyObj(out ho_Image);
//Image Acquisition 01: Code generated by Image Acquisition 01
//Image Acquisition 01: Attention: The initialization may fail in case parameters need to
//Image Acquisition 01: be set in a specific order (e.g., image resolution vs. offset).
hv_AcqHandle.Dispose();
HOperatorSet.OpenFramegrabber("DirectShow", 1, 1, 0, 0, 0, 0, "default", 8, "rgb",
-1, "false", "default", "[0] Integrated Camera", 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);
//Image Acquisition 01: Do something
}
ho_Image.Dispose(); hv_AcqHandle.Dispose(); }

这段代码只是实现了采集图像,没有在界面上显示。

4、向VS项目添加halcon导出的c#代码

向action()的代码中添加在窗口上显示图像的代码,即使用DispObj函数。然后把action添加到按钮响应中执行。

这样点击按钮之后就会进入死循环不停的GrabImage和DispObj,但是实际操作时界面会停止响应,而且图像并不会在窗口内刷新。

5、添加实时显示子线程

主线程中运行循环无法实时显示,必须创建子线程。

这里使用了工作者线程,点击按钮后,启动线程并执行一个循环显示采集的图像;再次点击按钮时,跳出循环结束worker线程。然后继续点击按钮又可以进入子线程开启实时显示,实现随意启停。

private void Button1_Click(object sender, RoutedEventArgs e)
{
if (isCameraOpened == false)
{
Button1.Content = "关闭实时显示";
isCameraOpened = true;
play_Thread = new Thread(action);
play_Thread.Start();
}
else
{
Button1.Content = "开启实时显示";
isCameraOpened = false;
}
}

注意调用线程需添加引用:

using System.Threading;//多线程

需要注意的是,为了防止在实时显示过程中突然关闭窗体导致程序崩溃,在窗体的Un_load事件中加入强行停止子线程的代码。

private void Window_Unloaded(object sender, RoutedEventArgs e)
{
if(play_Thread.IsAlive)
{
play_Thread.Abort();
}
}

6、调整图像尺寸以适应halconwindow窗口

(1)使用HSmartWindowControlWPF控件时,无需再添加鼠标滚轮的响应函数便可使用鼠标滚轮控制图像缩放。

(2)显示单张图像时,可以直接向HSmartWindowControlWPF控件的HDisplayCurrentObject属性赋HObject类型的图像即可自动调整图像尺寸来适应窗口大小。

hSmartWindowControl1.HDisplayCurrentObject = new HImage("girl.png");

但是这个方式不能适用于动态捕获的图像,所以动态捕获的图像还需要手动判断来进行缩放。调整的方式比较简单,就是获取窗口尺寸和图像尺寸进行对比,根据图像过宽还是过高来缩放。

7、源代码

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.Threading;//多线程 namespace HalconWindowWPFDemo
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
#region 全局变量
private static MainWindow mainWindow = new MainWindow();
private static HWindow hwindow; //全局窗口变量
Thread play_Thread; //实时显示线程
private static bool isCameraOpened; //是否正在实时显示
private static double halconWindowHeight; //halcon窗口高度
private static double halconWindowWidth; ////halcon窗口宽度
#endregion #region 初始化
public MainWindow()
{
InitializeComponent();
} private void Window_Loaded(object sender, RoutedEventArgs e)
{
hwindow = hSmartWindowControl1.HalconWindow;//初始化窗口变量
isCameraOpened = false;
//获取halcon窗口大小
halconWindowHeight = mainWindow.hSmartWindowControl1.WindowSize.Width;
halconWindowWidth = mainWindow.hSmartWindowControl1.WindowSize.Height;
}
#endregion #region 界面响应
/// <summary>
/// 开启和关闭实时显示按钮
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Button1_Click(object sender, RoutedEventArgs e)
{
if (isCameraOpened == false)
{
Button1.Content = "关闭实时显示";
isCameraOpened = true;
play_Thread = new Thread(action);
play_Thread.Start();
}
else
{
Button1.Content = "开启实时显示";
isCameraOpened = false;
} }
/// <summary>
/// 显示一张图片
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Button2_Click(object sender, RoutedEventArgs e)
{
hSmartWindowControl1.HDisplayCurrentObject = new HImage("girl.png");
}
#endregion #region 实时显示用函数
/// <summary>
/// 摄像头实时显示
/// </summary>
private static void action()
{
// Local iconic variables
HObject ho_Image = null;
// Local control variables
HTuple hv_AcqHandle = new HTuple();
// Initialize local and output iconic variables
HOperatorSet.GenEmptyObj(out ho_Image);
ho_Image.Dispose();
hv_AcqHandle.Dispose();
//Image Acquisition 01: Code generated by Image Acquisition 01
HOperatorSet.OpenFramegrabber("DirectShow", 1, 1, 0, 0, 0, 0, "default", 8, "rgb",
-1, "false", "default", "[0] Integrated Camera", 0, -1, out hv_AcqHandle);
HOperatorSet.GrabImageStart(hv_AcqHandle, -1); while (isCameraOpened)
{
HOperatorSet.GrabImageAsync(out ho_Image, hv_AcqHandle, -1);
if (!mainWindow.ShowHalconImage(ho_Image)) break;
}
ho_Image.Dispose();
hv_AcqHandle.Dispose();
}
/// <summary>
/// 显示图像
/// </summary>
/// <param name="image"></param>
/// <returns></returns>
private bool ShowHalconImage(HObject ho_Image)
{
#region 缩放图像,适应窗口
//获取图像大小及纵横比
HTuple hv_Width = new HTuple(), hv_Height = new HTuple();
HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height);
int im_width = int.Parse(hv_Width.ToString());
int im_height = int.Parse(hv_Height.ToString());
double im_AspectRatio = (double)(im_width) / (double)(im_height);
//获取窗口大小及纵横比
double w_AspectRatio = halconWindowWidth / halconWindowHeight; HOperatorSet.SetSystem("int_zooming", "false");//图像缩放之前最好将此参数设置为false.
HTuple para = new HTuple("constant");
HObject ho_zoomImage;
HOperatorSet.GenEmptyObj(out ho_zoomImage); ho_zoomImage.Dispose();
if (halconWindowWidth < im_width && im_AspectRatio > w_AspectRatio)
{
//超宽图像
HOperatorSet.ZoomImageSize(ho_Image, out ho_zoomImage, halconWindowWidth, halconWindowWidth / im_AspectRatio, "constant");
}
else if (halconWindowHeight < im_height && im_AspectRatio < w_AspectRatio)
{
//超高图像
HOperatorSet.ZoomImageSize(ho_Image, out ho_zoomImage, halconWindowHeight * im_AspectRatio, halconWindowHeight, para);
}
#endregion #region 显示图像
try
{
hwindow.SetPart(0, 0, -2, -2);
hwindow.DispObj(ho_zoomImage);
}
catch (Exception exp)
{
//MessageBox.Show(exp.ToString());
return false;
}
#endregion
return true;
}
#endregion #region 析构函数
/// <summary>
/// 关闭窗体时推出子线程,防止崩溃
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Window_Unloaded(object sender, RoutedEventArgs e)
{
if(play_Thread.IsAlive)
{
play_Thread.Abort();
}
}
#endregion
}
}

最新文章

  1. 如何让ASP.NET Web API的Action方法在希望的Culture下执行
  2. Android 自定义Activity基类与TitleBar
  3. SpringRMI解析1-使用示例
  4. Android 开发必备
  5. sql2008连接数据库问题
  6. MyBatis(3.2.3) - Passing multiple input parameters
  7. 第十一章、认识与学习 BASH 管线命令 (pipe)
  8. 9.MVC框架开发(关于ActionResult的处理)
  9. chmod 命令 set uid ,set gid,sticky bit 说明
  10. c# 配置连接 mysql
  11. 《决战大数据:驾驭未来商业的利器》【PDF】下载
  12. ABP官方文档翻译 2.2 ABP会话
  13. springcloud-app
  14. 通过__block的作用深入研究block
  15. [uboot] (第五章)uboot流程——uboot启动流程
  16. 【一】php 基础知识
  17. 为什么家里的宽带的IP显示的是外地?
  18. Cesium中Homebutton改变默认跳转位置 【转】
  19. GP开发示例:数据库去重
  20. ThinkPHP之文件上传

热门文章

  1. List&lt;? extends T&gt;和List&lt;? super T&gt;之间有什么区别?
  2. About how fast is fast enough for a web application?
  3. 通过代理上网时,qq等应用程序连网出错
  4. js实现多标签页效果
  5. 好像leeceode题目我的博客太长了,需要重新建立一个. leecode刷题第二个
  6. Ajax(6) Ajax向servlet请求数据库操作 并显示到当前页面 这个未经测试
  7. 【Linux】DNS服务-BIND基础配置(二)
  8. Peter的烟(水题测试2017082401&洛谷1150)
  9. JS高级-String-正则表达式:
  10. MZOJ 1345 hero